Add get gallery jpn title

This commit is contained in:
seven332 committed 2016-02-05 23:47:04 +08:00
1 parent a61eb49b27
commit a4568d811e
28 files changed
+1313 -30

No files matched your search

@@ -0,0 +1,386 @@
/*
* Copyright 2016 Hippo Seven
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hippo.app;
import android.content.Intent;
import android.content.res.Configuration;
import android.os.Bundle;
import android.preference.PreferenceActivity;
import android.support.annotation.CallSuper;
import android.support.annotation.LayoutRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.NavUtils;
import android.support.v4.app.TaskStackBuilder;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatCallback;
import android.support.v7.app.AppCompatDelegate;
import android.support.v7.view.ActionMode;
import android.support.v7.widget.Toolbar;
import android.view.MenuInflater;
import android.view.View;
import android.view.ViewGroup;
public class AppCompatPreferenceActivity extends PreferenceActivity implements AppCompatCallback,
TaskStackBuilder.SupportParentable, ActionBarDrawerToggle.DelegateProvider {
private AppCompatDelegate mDelegate;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
getDelegate().installViewFactory();
getDelegate().onCreate(savedInstanceState);
super.onCreate(savedInstanceState);
}
@Override
protected void onPostCreate(@Nullable Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
getDelegate().onPostCreate(savedInstanceState);
}
/**
* Support library version of {@link android.app.Activity#getActionBar}.
*
* <p>Retrieve a reference to this activity's ActionBar.
*
* @return The Activity's ActionBar, or null if it does not have one.
*/
@Nullable
public ActionBar getSupportActionBar() {
return getDelegate().getSupportActionBar();
}
/**
* Set a {@link android.widget.Toolbar Toolbar} to act as the {@link android.support.v7.app.ActionBar} for this
* Activity window.
*
* <p>When set to a non-null value the {@link #getActionBar()} method will return
* an {@link android.support.v7.app.ActionBar} object that can be used to control the given toolbar as if it were
* a traditional window decor action bar. The toolbar's menu will be populated with the
* Activity's options menu and the navigation button will be wired through the standard
* {@link android.R.id#home home} menu select action.</p>
*
* <p>In order to use a Toolbar within the Activity's window content the application
* must not request the window feature
* {@link android.view.Window#FEATURE_ACTION_BAR FEATURE_SUPPORT_ACTION_BAR}.</p>
*
* @param toolbar Toolbar to set as the Activity's action bar
*/
public void setSupportActionBar(@Nullable Toolbar toolbar) {
getDelegate().setSupportActionBar(toolbar);
}
@NonNull
@Override
public MenuInflater getMenuInflater() {
return getDelegate().getMenuInflater();
}
@Override
public void setContentView(@LayoutRes int layoutResID) {
getDelegate().setContentView(layoutResID);
}
@Override
public void setContentView(View view) {
getDelegate().setContentView(view);
}
@Override
public void setContentView(View view, ViewGroup.LayoutParams params) {
getDelegate().setContentView(view, params);
}
@Override
public void addContentView(View view, ViewGroup.LayoutParams params) {
getDelegate().addContentView(view, params);
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
getDelegate().onConfigurationChanged(newConfig);
}
@Override
protected void onStop() {
super.onStop();
getDelegate().onStop();
}
@Override
protected void onPostResume() {
super.onPostResume();
getDelegate().onPostResume();
}
@Override
public final boolean onMenuItemSelected(int featureId, android.view.MenuItem item) {
if (super.onMenuItemSelected(featureId, item)) {
return true;
}
final ActionBar ab = getSupportActionBar();
if (item.getItemId() == android.R.id.home && ab != null &&
(ab.getDisplayOptions() & ActionBar.DISPLAY_HOME_AS_UP) != 0) {
return onSupportNavigateUp();
}
return false;
}
@Override
protected void onDestroy() {
super.onDestroy();
getDelegate().onDestroy();
}
@Override
protected void onTitleChanged(CharSequence title, int color) {
super.onTitleChanged(title, color);
getDelegate().setTitle(title);
}
/**
* Enable extended support library window features.
* <p>
* This is a convenience for calling
* {@link android.view.Window#requestFeature getWindow().requestFeature()}.
* </p>
*
* @param featureId The desired feature as defined in
* {@link android.view.Window} or {@link android.support.v4.view.WindowCompat}.
* @return Returns true if the requested feature is supported and now enabled.
*
* @see android.app.Activity#requestWindowFeature
* @see android.view.Window#requestFeature
*/
public boolean supportRequestWindowFeature(int featureId) {
return getDelegate().requestWindowFeature(featureId);
}
public void supportInvalidateOptionsMenu() {
getDelegate().invalidateOptionsMenu();
}
@Override
public void invalidateOptionsMenu() {
getDelegate().invalidateOptionsMenu();
}
/**
* Notifies the Activity that a support action mode has been started.
* Activity subclasses overriding this method should call the superclass implementation.
*
* @param mode The new action mode.
*/
@Override
@CallSuper
public void onSupportActionModeStarted(ActionMode mode) {
}
/**
* Notifies the activity that a support action mode has finished.
* Activity subclasses overriding this method should call the superclass implementation.
*
* @param mode The action mode that just finished.
*/
@Override
@CallSuper
public void onSupportActionModeFinished(ActionMode mode) {
}
/**
* Called when a support action mode is being started for this window. Gives the
* callback an opportunity to handle the action mode in its own unique and
* beautiful way. If this method returns null the system can choose a way
* to present the mode or choose not to start the mode at all.
*
* @param callback Callback to control the lifecycle of this action mode
* @return The ActionMode that was started, or null if the system should present it
*/
@Nullable
@Override
public ActionMode onWindowStartingSupportActionMode(ActionMode.Callback callback) {
return null;
}
public ActionMode startSupportActionMode(ActionMode.Callback callback) {
return getDelegate().startSupportActionMode(callback);
}
/**
* Support version of {@link #onCreateNavigateUpTaskStack(android.app.TaskStackBuilder)}.
* This method will be called on all platform versions.
*
* Define the synthetic task stack that will be generated during Up navigation from
* a different task.
*
* <p>The default implementation of this method adds the parent chain of this activity
* as specified in the manifest to the supplied {@link android.support.v4.app.TaskStackBuilder}. Applications
* may choose to override this method to construct the desired task stack in a different
* way.</p>
*
* <p>This method will be invoked by the default implementation of {@link #onNavigateUp()}
* if {@link #shouldUpRecreateTask(android.content.Intent)} returns true when supplied with the intent
* returned by {@link #getParentActivityIntent()}.</p>
*
* <p>Applications that wish to supply extra Intent parameters to the parent stack defined
* by the manifest should override
* {@link #onPrepareSupportNavigateUpTaskStack(android.support.v4.app.TaskStackBuilder)}.</p>
*
* @param builder An empty TaskStackBuilder - the application should add intents representing
* the desired task stack
*/
public void onCreateSupportNavigateUpTaskStack(TaskStackBuilder builder) {
builder.addParentStack(this);
}
/**
* Support version of {@link #onPrepareNavigateUpTaskStack(android.app.TaskStackBuilder)}.
* This method will be called on all platform versions.
*
* Prepare the synthetic task stack that will be generated during Up navigation
* from a different task.
*
* <p>This method receives the {@link android.support.v4.app.TaskStackBuilder} with the constructed series of
* Intents as generated by {@link #onCreateSupportNavigateUpTaskStack(android.support.v4.app.TaskStackBuilder)}.
* If any extra data should be added to these intents before launching the new task,
* the application should override this method and add that data here.</p>
*
* @param builder A TaskStackBuilder that has been populated with Intents by
* onCreateNavigateUpTaskStack.
*/
public void onPrepareSupportNavigateUpTaskStack(TaskStackBuilder builder) {
}
/**
* This method is called whenever the user chooses to navigate Up within your application's
* activity hierarchy from the action bar.
*
* <p>If a parent was specified in the manifest for this activity or an activity-alias to it,
* default Up navigation will be handled automatically. See
* {@link #getSupportParentActivityIntent()} for how to specify the parent. If any activity
* along the parent chain requires extra Intent arguments, the Activity subclass
* should override the method {@link #onPrepareSupportNavigateUpTaskStack(android.support.v4.app.TaskStackBuilder)}
* to supply those arguments.</p>
*
* <p>See <a href="{@docRoot}guide/topics/fundamentals/tasks-and-back-stack.html">Tasks and
* Back Stack</a> from the developer guide and
* <a href="{@docRoot}design/patterns/navigation.html">Navigation</a> from the design guide
* for more information about navigating within your app.</p>
*
* <p>See the {@link android.support.v4.app.TaskStackBuilder} class and the Activity methods
* {@link #getSupportParentActivityIntent()}, {@link #supportShouldUpRecreateTask(android.content.Intent)}, and
* {@link #supportNavigateUpTo(android.content.Intent)} for help implementing custom Up navigation.</p>
*
* @return true if Up navigation completed successfully and this Activity was finished,
* false otherwise.
*/
public boolean onSupportNavigateUp() {
Intent upIntent = getSupportParentActivityIntent();
if (upIntent != null) {
if (supportShouldUpRecreateTask(upIntent)) {
TaskStackBuilder b = TaskStackBuilder.create(this);
onCreateSupportNavigateUpTaskStack(b);
onPrepareSupportNavigateUpTaskStack(b);
b.startActivities();
try {
ActivityCompat.finishAffinity(this);
} catch (IllegalStateException e) {
// This can only happen on 4.1+, when we don't have a parent or a result set.
// In that case we should just finish().
finish();
}
} else {
// This activity is part of the application's task, so simply
// navigate up to the hierarchical parent activity.
supportNavigateUpTo(upIntent);
}
return true;
}
return false;
}
/**
* Obtain an {@link android.content.Intent} that will launch an explicit target activity
* specified by sourceActivity's {@link android.support.v4.app.NavUtils#PARENT_ACTIVITY} &lt;meta-data&gt;
* element in the application's manifest. If the device is running
* Jellybean or newer, the android:parentActivityName attribute will be preferred
* if it is present.
*
* @return a new Intent targeting the defined parent activity of sourceActivity
*/
@Override
@Nullable
public Intent getSupportParentActivityIntent() {
return NavUtils.getParentActivityIntent(this);
}
/**
* Returns true if sourceActivity should recreate the task when navigating 'up'
* by using targetIntent.
*
* <p>If this method returns false the app can trivially call
* {@link #supportNavigateUpTo(android.content.Intent)} using the same parameters to correctly perform
* up navigation. If this method returns false, the app should synthesize a new task stack
* by using {@link android.support.v4.app.TaskStackBuilder} or another similar mechanism to perform up navigation.</p>
*
* @param targetIntent An intent representing the target destination for up navigation
* @return true if navigating up should recreate a new task stack, false if the same task
* should be used for the destination
*/
public boolean supportShouldUpRecreateTask(Intent targetIntent) {
return NavUtils.shouldUpRecreateTask(this, targetIntent);
}
/**
* Navigate from sourceActivity to the activity specified by upIntent, finishing sourceActivity
* in the process. upIntent will have the flag {@link android.content.Intent#FLAG_ACTIVITY_CLEAR_TOP} set
* by this method, along with any others required for proper up navigation as outlined
* in the Android Design Guide.
*
* <p>This method should be used when performing up navigation from within the same task
* as the destination. If up navigation should cross tasks in some cases, see
* {@link #supportShouldUpRecreateTask(android.content.Intent)}.</p>
*
* @param upIntent An intent representing the target destination for up navigation
*/
public void supportNavigateUpTo(Intent upIntent) {
NavUtils.navigateUpTo(this, upIntent);
}
@Nullable
@Override
public ActionBarDrawerToggle.Delegate getDrawerToggleDelegate() {
return getDelegate().getDrawerToggleDelegate();
}
/**
* @return The {@link AppCompatDelegate} being used by this Activity.
*/
public AppCompatDelegate getDelegate() {
if (mDelegate == null) {
mDelegate = AppCompatDelegate.create(this, this);
}
return mDelegate;
}
}
@@ -111,13 +111,14 @@ public class Settings {
putBoolean(KEY_SHOW_WARNING, value);
}
public static EhConfig getEhConfig() {
return sEhConfig;
}
private static final String KEY_SHOW_JPN_TITLE = "show_jpn_title";
private static final boolean DEFAULT_SHOW_JPN_TITLE = false;
public static boolean getShowJpnTitle() {
return getBoolean(KEY_SHOW_JPN_TITLE, DEFAULT_SHOW_JPN_TITLE);
}
}
@@ -124,7 +124,7 @@ public class EhClient {
Call call = EhEngine.prepareGetGalleryList(mOkHttpClient, ehConfig, (String) params[0]);
if (!mStop) {
mCall = call;
return EhEngine.doGetGalleryList(call);
return EhEngine.doGetGalleryList(call, (Boolean) params[1], mOkHttpClient);
} else {
throw new CancelledException();
}
@@ -21,18 +21,24 @@ import android.util.Log;
import android.util.Pair;
import com.hippo.ehviewer.client.data.GalleryDetail;
import com.hippo.ehviewer.client.data.GalleryInfo;
import com.hippo.ehviewer.client.data.LargePreviewSet;
import com.hippo.ehviewer.client.exception.CancelledException;
import com.hippo.ehviewer.client.exception.EhException;
import com.hippo.ehviewer.client.parser.GalleryDetailParser;
import com.hippo.ehviewer.client.parser.GalleryListParser;
import com.hippo.ehviewer.client.parser.ParserUtils;
import com.hippo.ehviewer.client.parser.RateGalleryParser;
import com.hippo.ehviewer.client.parser.SignInParser;
import com.hippo.network.StatusCodeException;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.List;
import okhttp3.Call;
import okhttp3.FormBody;
import okhttp3.Headers;
@@ -117,7 +123,62 @@ public class EhEngine {
return okHttpClient.newCall(request);
}
public static GalleryListParser.Result doGetGalleryList(Call call) throws Exception {
private static GalleryInfo getGalleryInfoByGid(List<GalleryInfo> galleryInfos, int gid) {
for (int i = 0, size = galleryInfos.size(); i < size; i++) {
GalleryInfo gi = galleryInfos.get(i);
if (gi.gid == gid) {
return gi;
}
}
return null;
}
private static void parseGalleryApi(String body, List<GalleryInfo> galleryInfos) throws JSONException {
JSONObject jo = new JSONObject(body);
JSONArray ja = jo.getJSONArray("gmetadata");
for (int i = 0, length = ja.length(); i < length; i++) {
JSONObject g = ja.getJSONObject(i);
int gid = g.getInt("gid");
GalleryInfo gi = getGalleryInfoByGid(galleryInfos, gid);
if (gi == null) {
continue;
}
gi.titleJpn = ParserUtils.trim(g.getString("title_jpn"));
// tags
JSONArray tagJa = g.getJSONArray("tags");
int tagLength = tagJa.length();
String[] tags = new String[tagLength];
for (int j = 0; j < tagLength; j++) {
tags[j] = tagJa.getString(j);
}
gi.simpleTags = tags;
}
}
private static void doRequestGalleryApi(List<GalleryInfo> galleryInfos, OkHttpClient okHttpClient)
throws Exception {
JSONObject json = new JSONObject();
json.put("method", "gdata");
JSONArray ja = new JSONArray();
for (int i = 0, size = galleryInfos.size(); i < size; i++) {
GalleryInfo gi = galleryInfos.get(i);
JSONArray g = new JSONArray();
g.put(gi.gid);
g.put(gi.token);
ja.put(g);
}
json.put("gidlist", ja);
json.put("namespace", 1);
String url = EhUrl.API_EX;
Log.d(TAG, url);
Request request = new EhRequestBuilder(url)
.post(RequestBody.create(JSON, json.toString()))
.build();
Call call = okHttpClient.newCall(request);
String body = null;
Headers headers = null;
int code = -1;
@@ -126,7 +187,41 @@ public class EhEngine {
code = response.code();
headers = response.headers();
body = response.body().string();
return GalleryListParser.parse(body);
parseGalleryApi(body, galleryInfos);
} catch (Exception e) {
throwException(call, code, headers, body, e);
throw e;
}
}
private static void requestGalleryApi(List<GalleryInfo> galleryInfos,
OkHttpClient okHttpClient) throws Exception {
final int MAX_REQUEST_SIZE = 25;
List<GalleryInfo> requestItems = new ArrayList<>(MAX_REQUEST_SIZE);
for (int i = 0, size = galleryInfos.size(); i < size; i++) {
requestItems.add(galleryInfos.get(i));
if (requestItems.size() == MAX_REQUEST_SIZE || i == size - 1) {
doRequestGalleryApi(requestItems, okHttpClient);
requestItems.clear();
}
}
}
public static GalleryListParser.Result doGetGalleryList(Call call, boolean callApi,
OkHttpClient okHttpClient) throws Exception {
String body = null;
Headers headers = null;
int code = -1;
try {
Response response = call.execute();
code = response.code();
headers = response.headers();
body = response.body().string();
GalleryListParser.Result result = GalleryListParser.parse(body);
if (callApi && result.galleryInfos.size() > 0) {
requestGalleryApi(result.galleryInfos, okHttpClient);
}
return result;
} catch (Exception e) {
throwException(call, code, headers, body, e);
throw e;
@@ -216,4 +311,6 @@ public class EhEngine {
throw e;
}
}
// TODO Add get gallery api info
}
@@ -121,10 +121,10 @@ public class EhUtils {
}
public static String getSuitableTitle(GalleryInfo gi) {
if (false) {//;Settings.getJpnTitle()) {
if (Settings.getShowJpnTitle()) {
return TextUtils.isEmpty(gi.titleJpn) ? gi.title : gi.titleJpn;
} else {
return gi.title;
return TextUtils.isEmpty(gi.title) ? gi.titleJpn : gi.title;
}
}
@@ -0,0 +1,98 @@
/*
* Copyright 2016 Hippo Seven
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hippo.ehviewer.client.data;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.annotation.Nullable;
public class GalleryApiInfo implements Parcelable {
public int gid;
public String token;
public String archiverKey;
public String title;
public String titleJpn;
public int category;
public String thumb;
public String uploader;
public long posted;
public int filecount;
public long filesize;
public boolean expunged;
public float rating;
public int torrentcount;
@Nullable
public String[] tags;
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(this.gid);
dest.writeString(this.token);
dest.writeString(this.archiverKey);
dest.writeString(this.title);
dest.writeString(this.titleJpn);
dest.writeInt(this.category);
dest.writeString(this.thumb);
dest.writeString(this.uploader);
dest.writeLong(this.posted);
dest.writeInt(this.filecount);
dest.writeLong(this.filesize);
dest.writeByte(expunged ? (byte) 1 : (byte) 0);
dest.writeFloat(this.rating);
dest.writeInt(this.torrentcount);
dest.writeStringArray(this.tags);
}
public GalleryApiInfo() {
}
protected GalleryApiInfo(Parcel in) {
this.gid = in.readInt();
this.token = in.readString();
this.archiverKey = in.readString();
this.title = in.readString();
this.titleJpn = in.readString();
this.category = in.readInt();
this.thumb = in.readString();
this.uploader = in.readString();
this.posted = in.readLong();
this.filecount = in.readInt();
this.filesize = in.readLong();
this.expunged = in.readByte() != 0;
this.rating = in.readFloat();
this.torrentcount = in.readInt();
this.tags = in.createStringArray();
}
public static final Parcelable.Creator<GalleryApiInfo> CREATOR = new Parcelable.Creator<GalleryApiInfo>() {
@Override
public GalleryApiInfo createFromParcel(Parcel source) {
return new GalleryApiInfo(source);
}
@Override
public GalleryApiInfo[] newArray(int size) {
return new GalleryApiInfo[size];
}
};
}
@@ -86,6 +86,7 @@ public class GalleryInfo implements Parcelable {
public String posted;
public String uploader;
public float rating;
public String[] simpleTags;
/**
* language from title
@@ -16,7 +16,9 @@
package com.hippo.ehviewer.ui;
import android.content.Intent;
import android.os.Bundle;
import android.os.PersistableBundle;
import android.support.annotation.IdRes;
import android.support.annotation.Nullable;
import android.support.design.widget.NavigationView;
@@ -36,8 +38,11 @@ import com.hippo.scene.StageActivity;
public final class MainActivity extends StageActivity
implements NavigationView.OnNavigationItemSelectedListener {
private static final String KEY_NAV_CHECKED_ITEM = "nav_checked_item";
private DrawerLayout mDrawerLayout;
private NavigationView mNavView;
private int mNavCheckedItem = 0;
@Override
public int getContainerViewId() {
@@ -56,9 +61,43 @@ public final class MainActivity extends StageActivity
if (savedInstanceState == null) {
onInit();
} else {
onRestore(savedInstanceState);
}
}
private void onInit() {
if (Settings.getShowWarning()) {
setDrawerLayoutEnable(false);
startScene(WarningScene.class);
} else if (!EhUtils.hasSignedIn(this)) {
setDrawerLayoutEnable(false);
startScene(LoginScene.class);
} else {
setDrawerLayoutEnable(true);
Bundle args = new Bundle();
args.putString(GalleryListScene.KEY_ACTION, GalleryListScene.ACTION_HOMEPAGE);
startScene(GalleryListScene.class, args);
}
}
private void onRestore(Bundle savedInstanceState) {
mNavCheckedItem = savedInstanceState.getInt(KEY_NAV_CHECKED_ITEM);
}
@Override
public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) {
super.onSaveInstanceState(outState, outPersistentState);
outState.putInt(KEY_NAV_CHECKED_ITEM, mNavCheckedItem);
}
@Override
protected void onResume() {
super.onResume();
setNavCheckedItem(mNavCheckedItem);
}
public void setDrawerLayoutEnable(boolean enable) {
if (enable) {
mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
@@ -76,6 +115,7 @@ public final class MainActivity extends StageActivity
}
public void setNavCheckedItem(@IdRes int resId) {
mNavCheckedItem = resId;
if (resId == 0) {
mNavView.setCheckedItem(R.id.nav_stub);
} else {
@@ -83,21 +123,6 @@ public final class MainActivity extends StageActivity
}
}
private void onInit() {
if (Settings.getShowWarning()) {
setDrawerLayoutEnable(false);
startScene(WarningScene.class);
} else if (!EhUtils.hasSignedIn(this)) {
setDrawerLayoutEnable(false);
startScene(LoginScene.class);
} else {
setDrawerLayoutEnable(true);
Bundle args = new Bundle();
args.putString(GalleryListScene.KEY_ACTION, GalleryListScene.ACTION_HOMEPAGE);
startScene(GalleryListScene.class, args);
}
}
@Override
public void onBackPressed() {
if (mDrawerLayout.isDrawerOpen(Gravity.LEFT) || mDrawerLayout.isDrawerOpen(Gravity.RIGHT)) {
@@ -109,7 +134,11 @@ public final class MainActivity extends StageActivity
@Override
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
// Don't select twice
if (item.isChecked()) {
return false;
}
int id = item.getItemId();
if (id == R.id.nav_homepage) {
@@ -125,7 +154,8 @@ public final class MainActivity extends StageActivity
} else if (id == R.id.nav_download) {
} else if (id == R.id.nav_settings) {
Intent intent = new Intent(this, SettingsActivity.class);
startActivity(intent);
}
if (id != R.id.nav_stub) {
@@ -0,0 +1,191 @@
/*
* Copyright 2016 Hippo Seven
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hippo.ehviewer.ui;
import android.app.Fragment;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.support.annotation.StringRes;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarDrawerToggle;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListAdapter;
import com.hippo.app.AppCompatPreferenceActivity;
import com.hippo.ehviewer.R;
import com.hippo.ehviewer.ui.fragment.EhFragment;
import com.hippo.vector.VectorDrawable;
import java.lang.reflect.Field;
import java.util.List;
public final class SettingsActivity extends AppCompatPreferenceActivity {
private static final int REQUEST_CODE_FRAGMENT = 0;
private static final String[] ENTRY_FRAGMENTS = {
EhFragment.class.getName(),
};
private class FakeLayoutInflater extends LayoutInflater {
private LayoutInflater mInflater;
protected FakeLayoutInflater(LayoutInflater inflater) {
super(null);
mInflater = inflater;
}
@Override
public LayoutInflater cloneInContext(Context newContext) {
return null;
}
@Override
public View inflate(int resource, ViewGroup root, boolean attachToRoot) {
return mInflater.inflate(R.layout.item_preference_header, root, attachToRoot);
}
}
@SuppressWarnings("TryWithIdenticalCatches")
private void replaceHeaderLayoutResId() {
try {
ListAdapter adapter = getListAdapter();
Class headerAdapterClazz = Class.forName("android.preference.PreferenceActivity$HeaderAdapter");
if (!headerAdapterClazz.isInstance(adapter)) {
return;
}
boolean ok = false;
// For lollipop and above this work
try {
Field field = headerAdapterClazz.getDeclaredField("mLayoutResId");
field.setAccessible(true);
field.setInt(adapter, R.layout.item_preference_header);
ok = true;
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
// For pre-lollipop this work
if (!ok) {
try {
Field field = headerAdapterClazz.getDeclaredField("mInflater");
field.setAccessible(true);
field.set(adapter, new FakeLayoutInflater((LayoutInflater) field.get(adapter)));
ok = true;
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (ClassCastException e) {
e.printStackTrace();
}
}
if (ok) {
getListView().setDivider(new ColorDrawable(Color.TRANSPARENT));
getListView().setDividerHeight(0);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
private void setActionBarUpIndicator(Drawable drawable) {
ActionBarDrawerToggle.Delegate delegate = getDrawerToggleDelegate();
if (delegate != null) {
delegate.setActionBarUpIndicator(drawable, 0);
}
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setHomeButtonEnabled(true);
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setActionBarUpIndicator(VectorDrawable.create(this, R.drawable.ic_arrow_left));
replaceHeaderLayoutResId();
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
finish();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
@Override
public void onBuildHeaders(List<Header> target) {
loadHeadersFromResource(R.xml.settings_headers, target);
}
@Override
public void startWithFragment(String fragmentName, Bundle args,
Fragment resultTo, int resultRequestCode, @StringRes int titleRes,
@StringRes int shortTitleRes) {
Intent intent = onBuildStartFragmentIntent(fragmentName, args, titleRes, shortTitleRes);
if (resultTo == null) {
startActivityForResult(intent, REQUEST_CODE_FRAGMENT);
} else {
resultTo.startActivityForResult(intent, resultRequestCode);
}
}
@Override
protected boolean isValidFragment(String fragmentName) {
for (String fragment : ENTRY_FRAGMENTS) {
if (fragment.equals(fragmentName)) {
return true;
}
}
return false;
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_CODE_FRAGMENT) {
if (resultCode == RESULT_OK) {
setResult(RESULT_OK, data);
}
} else {
super.onActivityResult(requestCode, resultCode, data);
}
}
}
@@ -0,0 +1,31 @@
/*
* Copyright 2016 Hippo Seven
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hippo.ehviewer.ui.fragment;
import android.os.Bundle;
import android.preference.PreferenceFragment;
import com.hippo.ehviewer.R;
public class EhFragment extends PreferenceFragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.eh_settings);
}
}
@@ -578,7 +578,7 @@ public class GalleryDetailScene extends BaseScene implements View.OnClickListene
if (ACTION_GALLERY_INFO.equals(mAction) && mGalleryInfo != null) {
GalleryInfo gi = mGalleryInfo;
mThumb.load(EhCacheKeyFactory.getThumbKey(gi.gid), gi.thumb, true);
mTitle.setText(gi.title);
mTitle.setText(EhUtils.getSuitableTitle(gi));
mUploader.setText(gi.uploader);
mCategory.setText(EhUtils.getCategory(gi.category));
mCategory.setTextColor(EhUtils.getCategoryColor(gi.category));
@@ -618,7 +618,7 @@ public class GalleryDetailScene extends BaseScene implements View.OnClickListene
if (TextUtils.isEmpty(mCategory.getText())) {
mThumb.load(EhCacheKeyFactory.getThumbKey(gd.gid), gd.thumb, true);
mTitle.setText(gd.title);
mTitle.setText(EhUtils.getSuitableTitle(gd));
mUploader.setText(gd.uploader);
mCategory.setText(EhUtils.getCategory(gd.category));
mCategory.setTextColor(EhUtils.getCategoryColor(gd.category));
@@ -53,6 +53,7 @@ import com.hippo.easyrecyclerview.EasyRecyclerView;
import com.hippo.easyrecyclerview.FastScroller;
import com.hippo.ehviewer.EhApplication;
import com.hippo.ehviewer.R;
import com.hippo.ehviewer.Settings;
import com.hippo.ehviewer.client.EhCacheKeyFactory;
import com.hippo.ehviewer.client.EhClient;
import com.hippo.ehviewer.client.EhRequest;
@@ -926,7 +927,7 @@ public final class GalleryListScene extends BaseScene
public void onBindViewHolder(GalleryListHolder holder, int position) {
GalleryInfo gi = mHelper.getDataAt(position);
holder.thumb.load(EhCacheKeyFactory.getThumbKey(gi.gid), gi.thumb, true);
holder.title.setText(gi.title);
holder.title.setText(EhUtils.getSuitableTitle(gi));
holder.uploader.setText(gi.uploader);
holder.rating.setRating(gi.rating);
TextView category = holder.category;
@@ -965,7 +966,7 @@ public final class GalleryListScene extends BaseScene
request.setMethod(EhClient.METHOD_GET_GALLERY_LIST);
request.setCallback(new GetGalleryListListener(getContext(),
((StageActivity) getActivity()).getStageId(), getTag(), taskId));
request.setArgs(url);
request.setArgs(url, Settings.getShowJpnTitle()); // TODO check tag filter
mClient.execute(request);
}
@@ -0,0 +1,190 @@
/*
* Copyright 2015 Hippo Seven
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hippo.preference;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.TypedArray;
import android.os.Build;
import android.preference.TwoStatePreference;
import android.support.annotation.StringRes;
import android.support.v7.widget.SwitchCompat;
import android.util.AttributeSet;
import android.view.View;
import android.widget.Checkable;
import android.widget.CompoundButton;
import com.hippo.ehviewer.R;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class FixedSwitchPreference extends TwoStatePreference {
private static Method sSyncSummaryViewMethod;
static {
try {
sSyncSummaryViewMethod = TwoStatePreference.class.getDeclaredMethod("syncSummaryView", View.class);
sSyncSummaryViewMethod.setAccessible(true);
} catch (NoSuchMethodException e) {
e.printStackTrace();
sSyncSummaryViewMethod = null;
}
}
// Switch text for on and off states
private CharSequence mSwitchOn;
private CharSequence mSwitchOff;
private final Listener mListener = new Listener();
private class Listener implements CompoundButton.OnCheckedChangeListener {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (!callChangeListener(isChecked)) {
// Listener didn't like it, change it back.
// CompoundButton will make sure we don't recurse.
buttonView.setChecked(!isChecked);
return;
}
FixedSwitchPreference.this.setChecked(isChecked);
}
}
public FixedSwitchPreference(Context context) {
super(context);
init(context, null, 0, 0);
}
public FixedSwitchPreference(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs, 0, 0);
}
public FixedSwitchPreference(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs, defStyleAttr, 0);
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public FixedSwitchPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init(context, attrs, defStyleAttr, defStyleRes);
}
public void init(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.FixedSwitchPreference, defStyleAttr, defStyleRes);
setSummaryOn(a.getString(R.styleable.FixedSwitchPreference_summaryOn));
setSummaryOff(a.getString(R.styleable.FixedSwitchPreference_summaryOff));
setSwitchTextOn(a.getString(R.styleable.FixedSwitchPreference_switchTextOn));
setSwitchTextOff(a.getString(R.styleable.FixedSwitchPreference_switchTextOff));
setDisableDependentsState(a.getBoolean(R.styleable.FixedSwitchPreference_disableDependentsState, false));
a.recycle();
}
@SuppressWarnings("TryWithIdenticalCatches")
@Override
protected void onBindView(View view) {
super.onBindView(view);
View checkableView = view.findViewById(R.id.switchWidget);
if (checkableView != null && checkableView instanceof Checkable) {
if (checkableView instanceof SwitchCompat) {
final SwitchCompat switchView = (SwitchCompat) checkableView;
switchView.setOnCheckedChangeListener(null);
}
((Checkable) checkableView).setChecked(isChecked());
if (checkableView instanceof SwitchCompat) {
final SwitchCompat switchView = (SwitchCompat) checkableView;
switchView.setTextOn(mSwitchOn);
switchView.setTextOff(mSwitchOff);
switchView.setOnCheckedChangeListener(mListener);
}
}
if (sSyncSummaryViewMethod != null) {
try {
sSyncSummaryViewMethod.invoke(this, view);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
/**
* Set the text displayed on the switch widget in the on state.
* This should be a very short string; one word if possible.
*
* @param onText Text to display in the on state
*/
public void setSwitchTextOn(CharSequence onText) {
mSwitchOn = onText;
notifyChanged();
}
/**
* Set the text displayed on the switch widget in the off state.
* This should be a very short string; one word if possible.
*
* @param offText Text to display in the off state
*/
public void setSwitchTextOff(CharSequence offText) {
mSwitchOff = offText;
notifyChanged();
}
/**
* Set the text displayed on the switch widget in the on state.
* This should be a very short string; one word if possible.
*
* @param resId The text as a string resource ID
*/
public void setSwitchTextOn(@StringRes int resId) {
setSwitchTextOn(getContext().getString(resId));
}
/**
* Set the text displayed on the switch widget in the off state.
* This should be a very short string; one word if possible.
*
* @param resId The text as a string resource ID
*/
public void setSwitchTextOff(@StringRes int resId) {
setSwitchTextOff(getContext().getString(resId));
}
/**
* @return The text that will be displayed on the switch widget in the on state
*/
public CharSequence getSwitchTextOn() {
return mSwitchOn;
}
/**
* @return The text that will be displayed on the switch widget in the off state
*/
public CharSequence getSwitchTextOff() {
return mSwitchOff;
}
}