Improve download

This commit is contained in:
seven332 committed 2015-08-22 23:51:57 +08:00
1 parent 9b7ebdff61
commit 4d6bcd8b79
36 files changed
+1246 -138

No files matched your search

@@ -31,7 +31,8 @@ public final class Constants {
public static final int MESSENGER_ID_UPDATE_QUICK_SEARCH;
public static final int MESSENGER_ID_UPDATE_QUICK_SEARCH_NAME;
public static final int MESSENGER_ID_UPDATE_DOWNLOAD;
public static final int MESSENGER_ID_UPDATE_DOWNLOAD_TAG;
public static final int MESSENGER_ID_MODIFY_DOWNLOAD_LABEL_FROM_MANAGER;
public static final int MESSENGER_ID_MODIFY_DOWNLOAD_LABEL_FROM_SCENE;
static {
Messenger messenger = Messenger.getInstance();
@@ -46,6 +47,7 @@ public final class Constants {
MESSENGER_ID_UPDATE_QUICK_SEARCH = messenger.newId();
MESSENGER_ID_UPDATE_QUICK_SEARCH_NAME = messenger.newId();
MESSENGER_ID_UPDATE_DOWNLOAD = messenger.newId();
MESSENGER_ID_UPDATE_DOWNLOAD_TAG = messenger.newId();
MESSENGER_ID_MODIFY_DOWNLOAD_LABEL_FROM_MANAGER = messenger.newId();
MESSENGER_ID_MODIFY_DOWNLOAD_LABEL_FROM_SCENE = messenger.newId();
}
}
@@ -26,7 +26,7 @@ public class DownloadInfo {
public static final int STATE_DOWNLOAD = 0x2;
public static final int STATE_FINISH = 0x3;
public String tag;
public String label;
public GalleryBase galleryBase;
public int state = STATE_NONE;
// byte/second, -1 for can't get speed now
@@ -38,14 +38,17 @@ public class DownloadInfo {
// Integer.MAX_VALUE for unknown
public int legacy = Integer.MAX_VALUE;
public long time;
public static DownloadInfo fromDownloadInfoObj(DownloadInfoObj obj) {
GalleryBase galleryBase = DBUtils.getGalleryBase((int) (long) obj.getGid());
if (galleryBase != null) {
DownloadInfo downloadInfo = new DownloadInfo();
downloadInfo.galleryBase = galleryBase;
downloadInfo.tag = obj.getTag();
downloadInfo.label = obj.getLabel();
downloadInfo.state = obj.getState();
downloadInfo.legacy = obj.getLegacy();
downloadInfo.time = obj.getTime();
return downloadInfo;
} else {
return null;
@@ -0,0 +1,33 @@
/*
* 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.ehviewer.client.data;
public class DownloadLabel implements Cloneable {
public long id;
public String label;
public long time;
@Override
public DownloadLabel clone() {
try {
return (DownloadLabel) super.clone();
} catch (CloneNotSupportedException e) {
throw new IllegalStateException(e);
}
}
}
@@ -19,21 +19,24 @@ package com.hippo.ehviewer.service;
import android.os.SystemClock;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.util.Log;
import com.hippo.ehviewer.Constants;
import com.hippo.ehviewer.client.data.DownloadInfo;
import com.hippo.ehviewer.client.data.DownloadLabel;
import com.hippo.ehviewer.client.data.GalleryBase;
import com.hippo.ehviewer.gallery.GallerySpider;
import com.hippo.ehviewer.gallery.ImageHandler;
import com.hippo.ehviewer.gallery.SpiderQueen;
import com.hippo.ehviewer.util.DBUtils;
import com.hippo.ehviewer.util.EhUtils;
import com.hippo.yorozuya.AssertUtils;
import com.hippo.yorozuya.Messenger;
import com.hippo.yorozuya.SimpleHandler;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
@@ -64,6 +67,17 @@ public class DownloadManager {
return (gid & ~OPS_MASK) | (ops & OPS_MASK);
}
public static Comparator<DownloadInfo> TIME_ASC_COMPARATOR = new Comparator<DownloadInfo>() {
@Override
public int compare(DownloadInfo lhs, DownloadInfo rhs) {
return lhs.time > rhs.time ? 1 : lhs.time < rhs.time ? -1 : 0;
//return (int) (lhs.time - rhs.time);
}
};
private List<DownloadInfo> mDownloadInfos;
private Map<String, List<DownloadInfo>> mDownloadInfoMap;
private List<DownloadInfo> mDefaultDownloadInfos;
@@ -84,19 +98,75 @@ public class DownloadManager {
sInstance = new DownloadManager();
}
private Messenger.Receiver mReceiver = new Messenger.Receiver() {
@Override
public void onReceive(int id, Object obj) {
AssertUtils.assertInstanceof("Messenger obj must be DownloadLabelOps", obj, DownloadLabelModify.class);
DownloadLabelModify modify = (DownloadLabelModify) obj;
List<DownloadInfo> list;
switch (modify.ops) {
case DownloadLabelModify.OPS_ADD:
// Add new label download info list
mDownloadInfoMap.put(modify.value, new ArrayList<DownloadInfo>());
// Save label to DB
DBUtils.addDownloadLabel(modify.value);
break;
case DownloadLabelModify.OPS_REMOVE:
// Add target label download info to default list
list = mDownloadInfoMap.remove(modify.label.label);
if (list != null) {
// Remove label in download info
for (DownloadInfo info : list) {
info.label = null;
// Update in DB
DBUtils.updateDownloadInfo(info);
}
mDefaultDownloadInfos.addAll(list);
Collections.sort(mDefaultDownloadInfos, TIME_ASC_COMPARATOR);
}
// Remove label from DB
DBUtils.removeDownloadLabel(modify.label.id);
break;
case DownloadLabelModify.OPS_MOVE:
// Only need to move in DB
DBUtils.moveDownloadLabel(modify.label.id, modify.label2.id);
break;
case DownloadLabelModify.OPS_CHANGE:
list = mDownloadInfoMap.remove(modify.label.label);
if (list != null) {
for (DownloadInfo info : list) {
info.label = modify.value;
// Update in DB
DBUtils.updateDownloadInfo(info);
}
// Use new key
mDownloadInfoMap.put(modify.value, list);
}
// Update in DB
DownloadLabel label = modify.label.clone();
label.label = modify.value;
DBUtils.updateDownloadLabel(label);
break;
default:
throw new IllegalStateException("Unknown download label ops");
}
}
};
public static DownloadManager getInstance() {
return sInstance;
}
public DownloadManager() {
List<String> tags = DBUtils.getAllDownloadTag();
List<String> labels = DBUtils.getAllDownloadLabel();
List<DownloadInfo> downloadInfos = DBUtils.getAllDownloadInfo();
mDownloadInfos = downloadInfos;
mDownloadInfoMap = new HashMap<>();
// Create list for each tag
for (String tag : tags) {
mDownloadInfoMap.put(tag, new ArrayList<DownloadInfo>());
// Create list for each label
for (String label : labels) {
mDownloadInfoMap.put(label, new ArrayList<DownloadInfo>());
}
// Create default for non tag
mDefaultDownloadInfos = new ArrayList<>();
@@ -109,10 +179,10 @@ public class DownloadManager {
}
List<DownloadInfo> list;
if (TextUtils.isEmpty(info.tag)) {
if (TextUtils.isEmpty(info.label)) {
list = mDefaultDownloadInfos;
} else {
list = mDownloadInfoMap.get(info.tag);
list = mDownloadInfoMap.get(info.label);
}
if (list == null) {
@@ -126,28 +196,37 @@ public class DownloadManager {
mSpeedReminder = new SpeedReminder();
mDownloadSpiderListener = new DownloadSpiderListener();
mUpdateInfo = new DownloadUpdateInfo();
Messenger.getInstance().register(Constants.MESSENGER_ID_MODIFY_DOWNLOAD_LABEL_FROM_SCENE, mReceiver);
}
public void setDownloadUpdateListener(@Nullable DownloadUpdateListener listener) {
mDownloadUpdateListener = listener;
}
public List<DownloadInfo> getDownloadList(String tag) {
return getDownloadListInternal(tag, false);
public List<DownloadInfo> getAllDownloadList() {
return mDownloadInfos;
}
private List<DownloadInfo> getDownloadListInternal(String tag, boolean create) {
if (TextUtils.isEmpty(tag)) {
public List<DownloadInfo> getDownloadList(String label) {
return getDownloadListInternal(label, false);
}
private List<DownloadInfo> getDownloadListInternal(String label, boolean create) {
if (TextUtils.isEmpty(label)) {
return mDefaultDownloadInfos;
} else {
List<DownloadInfo> list = mDownloadInfoMap.get(tag);
List<DownloadInfo> list = mDownloadInfoMap.get(label);
if (list == null && create) {
list = new ArrayList<>();
mDownloadInfoMap.put(tag, list);
mDownloadInfoMap.put(label, list);
// Save label to DB
DBUtils.addDownloadLabel(label);
// notify
Messenger.getInstance().notify(Constants.MESSENGER_ID_UPDATE_DOWNLOAD_TAG, null);
// Save tag to DB
DBUtils.addDownloadTag(tag);
DownloadManager.DownloadLabelModify modify = new DownloadManager.DownloadLabelModify();
modify.ops = DownloadManager.DownloadLabelModify.OPS_ADD;
modify.value = label;
Messenger.getInstance().notify(Constants.MESSENGER_ID_MODIFY_DOWNLOAD_LABEL_FROM_MANAGER, modify);
}
return list;
}
@@ -169,8 +248,6 @@ public class DownloadManager {
return;
}
Log.v(TAG, "ensureDownload");
// get download from wait list
if (!mWaitList.isEmpty()) {
DownloadInfo info = mWaitList.remove(0);
@@ -241,19 +318,19 @@ public class DownloadManager {
}
/**
* @param tag null for default
* @param label null for default
*/
public void startDownload(GalleryBase galleryBase, @Nullable String tag) {
void startDownload(GalleryBase galleryBase, @Nullable String label) {
try {
if (mCurrentTask != null && mCurrentTask.galleryBase.gid == galleryBase.gid) {
Log.v(TAG, "It is current task");
// It is current task
return;
}
// Check in download list
for (DownloadInfo info: mDownloadInfos) {
if (info.galleryBase.gid == galleryBase.gid) {
Log.v(TAG, "It is in download list");
// It is in download list
if (info.state == DownloadInfo.STATE_FINISH || info.state == DownloadInfo.STATE_NONE) {
info.state = DownloadInfo.STATE_WAIT;
// Add to wait list
@@ -270,15 +347,14 @@ public class DownloadManager {
}
}
Log.v(TAG, "It is not in download list");
// It is new download info
DownloadInfo downloadInfo = new DownloadInfo();
downloadInfo.galleryBase = galleryBase;
downloadInfo.tag = tag;
downloadInfo.label = label;
downloadInfo.state = DownloadInfo.STATE_WAIT;
downloadInfo.time = System.currentTimeMillis();
List<DownloadInfo> list = getDownloadListInternal(tag, true);
List<DownloadInfo> list = getDownloadListInternal(label, true);
list.add(downloadInfo);
mDownloadInfos.add(downloadInfo);
@@ -294,7 +370,7 @@ public class DownloadManager {
}
}
public void startAllDownload() {
void startAllDownload() {
for (DownloadInfo info : mDownloadInfos) {
if (info.state == DownloadInfo.STATE_NONE ||
(info.state == DownloadInfo.STATE_FINISH && info.legacy != 0)) {
@@ -468,6 +544,9 @@ public class DownloadManager {
// Release
releaseCurrent();
// Continue
ensureDownload();
}
@Override
@@ -593,7 +672,7 @@ public class DownloadManager {
void onCancel(DownloadUpdateInfo info);
}
public class DownloadUpdateInfo {
public static class DownloadUpdateInfo {
public int gid;
public String title;
public int pages;
@@ -601,4 +680,20 @@ public class DownloadManager {
public long speed;
public int legacy;
}
public static class DownloadLabelModify {
public static final int OPS_ADD = 0;
public static final int OPS_REMOVE = 1;
public static final int OPS_MOVE = 2;
public static final int OPS_CHANGE = 3;
public int ops;
// for remove and change
public DownloadLabel label;
// for add and change
public String value;
// for move
public DownloadLabel label2;
}
}
@@ -31,6 +31,7 @@ import com.hippo.ehviewer.ui.ContentActivity;
import com.hippo.ehviewer.ui.scene.DownloadScene;
import com.hippo.yorozuya.FileUtils;
// TODO Avoid frequent notification
public class DownloadService extends Service implements DownloadManager.DownloadUpdateListener {
private static final String TAG = DownloadService.class.getSimpleName();
@@ -0,0 +1,199 @@
/*
* 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.ehviewer.ui.scene;
import android.text.TextUtils;
import android.view.KeyEvent;
import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import com.hippo.ehviewer.Constants;
import com.hippo.ehviewer.R;
import com.hippo.ehviewer.client.data.DownloadLabel;
import com.hippo.ehviewer.service.DownloadManager;
import com.hippo.ehviewer.util.DBUtils;
import com.hippo.scene.AppbarScene;
import com.hippo.scene.SimpleDialog;
import com.hippo.widget.FloatLabelEditText;
import com.hippo.widget.recyclerview.EasyRecyclerView;
import com.hippo.yorozuya.Messenger;
import java.util.List;
public class DownloadLabelScene extends AbsDragSortScene implements AppbarScene.OnClickActionListener {
private List<DownloadLabel> mDownloadLabels;
private boolean mChanged = false;
private static final int POSITION_ADD = 0;
@Override
protected void onCreate(boolean rebirth) {
super.onCreate(rebirth);
addAction(R.drawable.ic_plus_dark_x24);
setOnClickActionListener(this);
}
@Override
protected void onDestroy(boolean die) {
super.onDestroy(die);
// notify update
if (mChanged) {
//Messenger.getInstance().notify(Constants.MESSENGER_ID_UPDATE_DOWNLOAD_LABEL, null);
mChanged = false;
}
}
@Override
protected String getTitle() {
return "Download label"; // TODO hardcode
}
@Override
protected SortAdapter getAdapter() {
mDownloadLabels = DBUtils.getAllDownloadLabelWithId();
return new DownloadTagAdapter(mDownloadLabels);
}
private class AddDownloadTagHelper implements SimpleDialog.OnCreateCustomViewListener,
SimpleDialog.OnClickListener {
private EditText mEditText;
@Override
public void onCreateCustomView(final SimpleDialog dialog, View view) {
FloatLabelEditText floatLabelEditText = (FloatLabelEditText) view.findViewById(R.id.float_label_edit_text);
floatLabelEditText.setHint("Download label"); // TODO hardcode
mEditText = (EditText) view.findViewById(R.id.edit_text);
mEditText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_DONE || actionId == EditorInfo.IME_NULL) {
dialog.pressPositiveButton();
return true;
} else {
return false;
}
}
});
}
private boolean containLabel(String label) {
for (DownloadLabel downloadLabel : mDownloadLabels) {
if (downloadLabel.label.equals(label)) {
return true;
}
}
return false;
}
@Override
public boolean onClick(SimpleDialog dialog, int which) {
if (which == SimpleDialog.POSITIVE) {
String label = mEditText.getText().toString().trim();
if (TextUtils.isEmpty(label)) {
Toast.makeText(getStageActivity(), "Empty label", Toast.LENGTH_SHORT).show(); // TODO hardcode
return false;
} else if (containLabel(label)) {
Toast.makeText(getStageActivity(), "The label already exists", Toast.LENGTH_SHORT).show(); // TODO hardcode
return false;
} else {
// Tell DownloadManager
DownloadManager.DownloadLabelModify modify = new DownloadManager.DownloadLabelModify();
modify.ops = DownloadManager.DownloadLabelModify.OPS_ADD;
modify.value = label;
Messenger.getInstance().notifyAtOnce(Constants.MESSENGER_ID_MODIFY_DOWNLOAD_LABEL_FROM_SCENE, modify);
// Update data
mDownloadLabels.clear();
mDownloadLabels.addAll(DBUtils.getAllDownloadLabelWithId());
notifyDataSetChanged();
mChanged = true;
return true;
}
} else {
return true;
}
}
}
@Override
public void onClickAction(int index) {
switch (index) {
case POSITION_ADD:
AddDownloadTagHelper helper = new AddDownloadTagHelper();
new SimpleDialog.Builder(getContext()).setTitle("Add download tag")
.setCustomView(R.layout.dialog_edit_text, helper)
.setPositiveButton(android.R.string.ok)
.setOnButtonClickListener(helper).show(this);
break;
}
}
private class DownloadTagAdapter extends SortAdapter<DownloadLabel> {
public DownloadTagAdapter(List<DownloadLabel> list) {
super(list);
}
@Override
public String getString(DownloadLabel downloadLabel, int position) {
return downloadLabel.label;
}
@Override
public long getId(DownloadLabel downloadLabel) {
return downloadLabel.id;
}
@Override
protected void onMove(int fromPosition, int toPosition) {
DownloadManager.DownloadLabelModify modify = new DownloadManager.DownloadLabelModify();
modify.ops = DownloadManager.DownloadLabelModify.OPS_MOVE;
modify.label = getData(fromPosition);
modify.label2 = getData(toPosition);
Messenger.getInstance().notify(Constants.MESSENGER_ID_MODIFY_DOWNLOAD_LABEL_FROM_SCENE, modify);
mChanged = true;
}
@Override
protected void onRemove(int position) {
DownloadManager.DownloadLabelModify modify = new DownloadManager.DownloadLabelModify();
modify.ops = DownloadManager.DownloadLabelModify.OPS_REMOVE;
modify.label = getData(position);
Messenger.getInstance().notify(Constants.MESSENGER_ID_MODIFY_DOWNLOAD_LABEL_FROM_SCENE, modify);
mChanged = true;
}
@Override
public boolean onItemClick(EasyRecyclerView parent, View view, int position, long id) {
// TODO
return false;
}
}
}
@@ -16,14 +16,20 @@
package com.hippo.ehviewer.ui.scene;
import android.animation.Animator;
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.content.Intent;
import android.content.res.Resources;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.SparseBooleanArray;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ProgressBar;
import android.widget.TextView;
import com.hippo.animation.SimpleAnimatorListener;
import com.hippo.conaco.Conaco;
import com.hippo.ehviewer.Constants;
import com.hippo.ehviewer.EhApplication;
@@ -42,16 +48,33 @@ import com.hippo.ehviewer.widget.SimpleRatingView;
import com.hippo.rippleold.RippleSalon;
import com.hippo.scene.Announcer;
import com.hippo.scene.Scene;
import com.hippo.widget.FabLayout;
import com.hippo.widget.recyclerview.EasyRecyclerView;
import com.hippo.yorozuya.AssertUtils;
import com.hippo.yorozuya.FileUtils;
import com.hippo.yorozuya.Messenger;
import java.util.List;
public class DownloadScene extends Scene implements DrawerProvider,
EasyRecyclerView.OnItemClickListener, Messenger.Receiver {
EasyRecyclerView.OnItemClickListener, Messenger.Receiver, View.OnClickListener,
AppbarRecyclerView.Helper {
private static String LABEL_ALL = null;
private static String LABEL_DEFAULT = "";
private static int INDEX_ALL = 0;
private static int INDEX_DEFAULT = 1;
private static long ANIMATE_TIME = 300l;
private EasyRecyclerView mRecyclerView;
private FabLayout mFabLayout;
private View mStart;
private View mStop;
private View mDelete;
private View mCheckAll;
private View mMainFab;
private DownloadAdapter mAdapter;
@@ -59,40 +82,42 @@ public class DownloadScene extends Scene implements DrawerProvider,
private GidPositionMap mGidPositionMap;
private int mOriginalPaddingBottom;
private int mOriginalRecyclerViewPaddingBottom;
private int mOriginalFabLayoutPaddingBottom;
private int mLastUpdateSize = -1;
private AppbarRecyclerView mRightDrawerView;
private DownloadTagAdapter mDownloadTagAdapter;
private List<String> mTags;
private DownloadLabelAdapter mDownloadLabelAdapter;
private List<String> mLabels;
private String mActivatedLabel;
private int mActivatedLabelPosition;
@Override
public int getLaunchMode() {
return LAUNCH_MODE_SINGLE_TOP;
}
protected List<String> getTags() {
mTags = DBUtils.getAllDownloadTag();
mTags.add(0, "Default");
mTags.add(0, "All");
if (mDownloadTagAdapter != null) {
mDownloadTagAdapter.notifyDataSetChanged();
}
return mTags;
private void initLabels() {
Resources resources = getContext().getResources();
mLabels = DBUtils.getAllDownloadLabel();
mLabels.add(0, resources.getString(R.string.download_tag_default));
mLabels.add(0, resources.getString(R.string.download_tag_all));
}
@Override
protected void onInit() {
super.onInit();
mActivatedLabel = LABEL_DEFAULT;
mActivatedLabelPosition = INDEX_DEFAULT;
mDownloadInfos = DownloadManager.getInstance().getDownloadList(null);
mGidPositionMap = new GidPositionMap();
Messenger.getInstance().register(Constants.MESSENGER_ID_UPDATE_DOWNLOAD, this);
mTags = getTags();
Messenger.getInstance().register(Constants.MESSENGER_ID_MODIFY_DOWNLOAD_LABEL_FROM_SCENE, this);
Messenger.getInstance().register(Constants.MESSENGER_ID_MODIFY_DOWNLOAD_LABEL_FROM_MANAGER, this);
}
@Override
@@ -100,6 +125,8 @@ public class DownloadScene extends Scene implements DrawerProvider,
super.onDie();
Messenger.getInstance().unregister(Constants.MESSENGER_ID_UPDATE_DOWNLOAD, this);
Messenger.getInstance().unregister(Constants.MESSENGER_ID_MODIFY_DOWNLOAD_LABEL_FROM_SCENE, this);
Messenger.getInstance().unregister(Constants.MESSENGER_ID_MODIFY_DOWNLOAD_LABEL_FROM_MANAGER, this);
}
@Override
@@ -109,7 +136,15 @@ public class DownloadScene extends Scene implements DrawerProvider,
((ContentActivity) getStageActivity()).setDrawerListActivatedPosition(ContentActivity.DRAWER_LIST_DOWNLOAD);
initLabels();
mRecyclerView = (EasyRecyclerView) findViewById(R.id.recycler_view);
mFabLayout = (FabLayout) findViewById(R.id.fab_layout);
mMainFab = mFabLayout.getPrimaryFab();
mStart = mFabLayout.getSecondaryFabAt(0);
mStop = mFabLayout.getSecondaryFabAt(1);
mDelete = mFabLayout.getSecondaryFabAt(2);
mCheckAll = mFabLayout.getSecondaryFabAt(3);
mAdapter = new DownloadAdapter();
mAdapter.setHasStableIds(true);
@@ -120,12 +155,26 @@ public class DownloadScene extends Scene implements DrawerProvider,
mRecyclerView.setChoiceMode(EasyRecyclerView.CHOICE_MODE_MULTIPLE_CUSTOM);
mRecyclerView.setCustomCheckedListener(new DownloadChoiceListener());
mOriginalPaddingBottom = mRecyclerView.getPaddingBottom();
mFabLayout.setAutoCancel(false);
mFabLayout.setExpanded(false, false);
mFabLayout.setVisibility(View.INVISIBLE);
mMainFab.setOnClickListener(this);
mStart.setOnClickListener(this);
mStop.setOnClickListener(this);
mDelete.setOnClickListener(this);
mCheckAll.setOnClickListener(this);
mOriginalRecyclerViewPaddingBottom = mRecyclerView.getPaddingBottom();
mOriginalFabLayoutPaddingBottom = mFabLayout.getPaddingBottom();
mRightDrawerView = new AppbarRecyclerView(getStageActivity());
mRightDrawerView.setTitle("TAG");
mDownloadTagAdapter = new DownloadTagAdapter();
mRightDrawerView.setAdapter(mDownloadTagAdapter);
mRightDrawerView.setTitle("TAG"); // TODO hardcode
mDownloadLabelAdapter = new DownloadLabelAdapter();
mRightDrawerView.setAdapter(mDownloadLabelAdapter);
mRightDrawerView.setOnItemClickListener(new DownloadTagClickListener());
mRightDrawerView.setPlusVisibility(View.GONE);
mRightDrawerView.setHelper(this);
}
@Override
@@ -149,7 +198,9 @@ public class DownloadScene extends Scene implements DrawerProvider,
super.onGetFitPaddingBottom(b);
mRecyclerView.setPadding(mRecyclerView.getPaddingLeft(), mRecyclerView.getPaddingTop(),
mRecyclerView.getPaddingRight(), b + mOriginalPaddingBottom);
mRecyclerView.getPaddingRight(), b + mOriginalRecyclerViewPaddingBottom);
mFabLayout.setPadding(mFabLayout.getPaddingLeft(), mFabLayout.getPaddingTop(),
mFabLayout.getPaddingRight(), b + mOriginalFabLayoutPaddingBottom);
}
@Override
@@ -261,11 +312,7 @@ public class DownloadScene extends Scene implements DrawerProvider,
// Add to cache
DownloadInfo info = mDownloadInfos.get(position);
mGidPositionMap.add(info.galleryBase.gid, position);
Intent intent = new Intent(getStageActivity(), DownloadService.class);
intent.setAction(DownloadService.ACTION_STOP);
intent.putExtra(DownloadService.KEY_GID, info.galleryBase.gid);
getStageActivity().startService(intent);
DownloadManager.getInstance().stopDownload(info.galleryBase.gid);
}
}
};
@@ -338,31 +385,138 @@ public class DownloadScene extends Scene implements DrawerProvider,
int ops = DownloadManager.getOps(mix);
int gid = DownloadManager.getGid(mix);
if (ops == DownloadManager.OPS_ALL_CHANGE) {
if (ops == DownloadManager.OPS_ALL_CHANGE ||
ops == DownloadManager.OPS_REMOVE) {
// OPS_REMOVE can't find position by gid, just notifyDataSetChanged
mGidPositionMap.clear();
mAdapter.notifyDataSetChanged();
return;
} else if (ops == DownloadManager.OPS_ADD) {
// Add break list, need clean gid position map
mGidPositionMap.clear();
}
int position = getPositionForGid(gid);
if (position == -1 && mLastUpdateSize != mAdapter.getItemCount()) {
// Can't get position, notifyDataSetChanged for safe
mAdapter.notifyDataSetChanged();
if (position == -1) {
if (mLastUpdateSize != mAdapter.getItemCount()) {
// Can't get position, notifyDataSetChanged for safe
mAdapter.notifyDataSetChanged();
}
return;
}
if (ops == DownloadManager.OPS_ADD) {
mAdapter.notifyItemInserted(position);
} else if (ops == DownloadManager.OPS_REMOVE) {
mAdapter.notifyItemRemoved(position);
} else if (ops == DownloadManager.OPS_UPDATE) {
RecyclerView.ViewHolder holder = mRecyclerView.findViewHolderForAdapterPosition(position);
if (holder != null) {
bindHolder((DownloadHolder) holder, mDownloadInfos.get(position));
}
}
} else if (id == Constants.MESSENGER_ID_MODIFY_DOWNLOAD_LABEL_FROM_SCENE ||
id == Constants.MESSENGER_ID_MODIFY_DOWNLOAD_LABEL_FROM_MANAGER) {
AssertUtils.assertInstanceof("Messenger obj must be DownloadLabelOps", obj, DownloadManager.DownloadLabelModify.class);
DownloadManager.DownloadLabelModify modify = (DownloadManager.DownloadLabelModify) obj;
switch (modify.ops) {
case DownloadManager.DownloadLabelModify.OPS_ADD:
mLabels.add(modify.value);
mDownloadLabelAdapter.notifyDataSetChanged();
break;
case DownloadManager.DownloadLabelModify.OPS_REMOVE:
mLabels.remove(modify.label.label);
mDownloadLabelAdapter.notifyDataSetChanged();
// Update activated info or maybe download info list
if (modify.label.label.equals(mActivatedLabel)) {
// Select default
mActivatedLabel = LABEL_DEFAULT;
mActivatedLabelPosition = INDEX_DEFAULT;
mDownloadInfos = DownloadManager.getInstance().getDownloadList(null);
mGidPositionMap.clear();
mAdapter.notifyDataSetChanged();
mRecyclerView.scrollToPosition(0);
}
// TODO
break;
case DownloadManager.DownloadLabelModify.OPS_MOVE:
int fromPosition = mLabels.indexOf(modify.label.label);
int toPosition = mLabels.indexOf(modify.label.label);
if (fromPosition >= 0 && toPosition >= 0) {
mLabels.add(toPosition, mLabels.remove(fromPosition));
mDownloadLabelAdapter.notifyDataSetChanged();
// Update activated info
if (fromPosition == mActivatedLabelPosition) {
mActivatedLabelPosition = toPosition;
}
}
break;
case DownloadManager.DownloadLabelModify.OPS_CHANGE:
int position = mLabels.indexOf(modify.label.label);
if (position >= 0) {
mLabels.set(position, modify.value);
mDownloadLabelAdapter.notifyDataSetChanged();
// Update activated info
if (position == mActivatedLabelPosition) {
mActivatedLabel = modify.value;
}
}
break;
default:
throw new IllegalStateException("Unknown download label ops");
}
}
}
@Override
public void onClick(View v) {
if (mMainFab == v) {
mRecyclerView.outOfCustomChoiceMode();
} else if (mStart == v) {
SparseBooleanArray checkedState = mRecyclerView.getCheckedItemPositions();
for (int i = 0, n = checkedState.size(); i < n; i++) {
if (checkedState.valueAt(i)) {
int position = checkedState.keyAt(i);
DownloadInfo info = mDownloadInfos.get(position);
Intent intent = new Intent(getStageActivity(), DownloadService.class);
intent.setAction(DownloadService.ACTION_START);
intent.putExtra(DownloadService.KEY_GALLERY_BASE, info.galleryBase);
getStageActivity().startService(intent);
}
}
} else if (mStop == v) {
DownloadManager manager = DownloadManager.getInstance();
SparseBooleanArray checkedState = mRecyclerView.getCheckedItemPositions();
for (int i = 0, n = checkedState.size(); i < n; i++) {
if (checkedState.valueAt(i)) {
int position = checkedState.keyAt(i);
manager.stopDownload(mDownloadInfos.get(position).galleryBase.gid);
}
}
} else if (mDelete == v) {
// TODO
} else if (mCheckAll == v) {
SparseBooleanArray checkedState = mRecyclerView.getCheckedItemPositions();
for (int i = 0, n = mAdapter.getItemCount(); i < n; i++) {
if (!checkedState.get(i, false)) {
mRecyclerView.setItemChecked(i, true);
}
}
}
}
@Override
public void onClickPlusListener() {
}
@Override
public void onClickSettingsListener() {
startScene(DownloadLabelScene.class);
}
private class DownloadHolder extends RecyclerView.ViewHolder {
public LoadImageView thumb;
@@ -547,14 +701,42 @@ public class DownloadScene extends Scene implements DrawerProvider,
}
}
public void openFabLayout() {
mFabLayout.setVisibility(View.VISIBLE);
mFabLayout.setExpanded(true);
PropertyValuesHolder scaleXPvh = PropertyValuesHolder.ofFloat("scaleX", 0f, 1f);
PropertyValuesHolder scaleYPvh = PropertyValuesHolder.ofFloat("scaleY", 0f, 1f);
ObjectAnimator oa = ObjectAnimator.ofPropertyValuesHolder(mMainFab, scaleXPvh, scaleYPvh);
oa.setDuration(ANIMATE_TIME);
oa.start();
}
public void closeFabLayout() {
mFabLayout.setExpanded(false);
PropertyValuesHolder scaleXPvh = PropertyValuesHolder.ofFloat("scaleX", 1f, 0f);
PropertyValuesHolder scaleYPvh = PropertyValuesHolder.ofFloat("scaleY", 1f, 0f);
ObjectAnimator oa = ObjectAnimator.ofPropertyValuesHolder(mMainFab, scaleXPvh, scaleYPvh);
oa.setDuration(ANIMATE_TIME);
oa.addListener(new SimpleAnimatorListener() {
@Override
public void onAnimationEnd(Animator animation) {
mFabLayout.setVisibility(View.INVISIBLE);
}
});
oa.start();
}
public class DownloadChoiceListener implements EasyRecyclerView.CustomChoiceListener {
@Override
public void onIntoCustomChoice(EasyRecyclerView view) {
openFabLayout();
}
@Override
public void onOutOfCustomChoice(EasyRecyclerView view) {
closeFabLayout();
}
@Override
@@ -565,6 +747,33 @@ public class DownloadScene extends Scene implements DrawerProvider,
}
}
public class DownloadTagClickListener implements EasyRecyclerView.OnItemClickListener {
@Override
public boolean onItemClick(EasyRecyclerView parent, View view, int position, long id) {
if (mActivatedLabelPosition != position) {
mActivatedLabelPosition = position;
if (position == 0) {
mActivatedLabel = LABEL_ALL;
mDownloadInfos = DownloadManager.getInstance().getAllDownloadList();
} else if (position == 1) {
mActivatedLabel = LABEL_DEFAULT;
mDownloadInfos = DownloadManager.getInstance().getDownloadList(null);
} else {
mActivatedLabel = mLabels.get(position);
mDownloadInfos = DownloadManager.getInstance().getDownloadList(mActivatedLabel);
}
mGidPositionMap.clear();
mAdapter.notifyDataSetChanged();
mRecyclerView.scrollToPosition(0);
((ContentActivity) getStageActivity()).closeDrawers();
}
return true;
}
}
private class SimpleHolder extends RecyclerView.ViewHolder {
public SimpleHolder(View itemView) {
@@ -572,22 +781,22 @@ public class DownloadScene extends Scene implements DrawerProvider,
}
}
public class DownloadTagAdapter extends RecyclerView.Adapter<SimpleHolder> {
public class DownloadLabelAdapter extends RecyclerView.Adapter<SimpleHolder> {
@Override
public SimpleHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new SimpleHolder(getStageActivity().getLayoutInflater().inflate(
R.layout.item_quick_search, parent, false));
R.layout.item_appbar_recycler_view, parent, false));
}
@Override
public void onBindViewHolder(SimpleHolder holder, int position) {
((TextView) holder.itemView).setText(mTags.get(position));
((TextView) holder.itemView).setText(mLabels.get(position));
}
@Override
public int getItemCount() {
return mTags == null ? 0 : mTags.size();
return mLabels == null ? 0 : mLabels.size();
}
}
}
@@ -24,6 +24,7 @@ import android.graphics.drawable.Drawable;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.Html;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -49,6 +50,7 @@ import com.hippo.ehviewer.client.data.TagGroup;
import com.hippo.ehviewer.service.DownloadService;
import com.hippo.ehviewer.ui.ContentActivity;
import com.hippo.ehviewer.ui.GalleryActivity;
import com.hippo.ehviewer.util.DBUtils;
import com.hippo.ehviewer.util.EhUtils;
import com.hippo.ehviewer.util.Settings;
import com.hippo.ehviewer.widget.LoadImageView;
@@ -547,6 +549,40 @@ public class GalleryDetailScene extends Scene implements View.OnClickListener,
}
}
private class DownloadLabelHelper implements SimpleDialog.OnClickListener, SimpleDialog.OnCloseListener {
private String[] mLabels;
public DownloadLabelHelper() {
mLabels = getLabels();
}
private String[] getLabels() {
List<String> labels = DBUtils.getAllDownloadLabel();
labels.add(0, getContext().getResources().getString(R.string.download_tag_default));
return labels.toArray(new String[labels.size()]);
}
@Override
public boolean onClick(SimpleDialog dialog, int which) {
Intent intent = new Intent(getStageActivity(), DownloadService.class);
intent.setAction(DownloadService.ACTION_START);
intent.putExtra(DownloadService.KEY_GALLERY_BASE, mGalleryDetail);
if (which > 0) {
intent.putExtra(DownloadService.KEY_TAG, mLabels[which]);
}
getStageActivity().startService(intent);
dialog.finish();
return true;
}
@Override
public void onClose(SimpleDialog dialog, boolean cancel) {
boolean checked = ((ListViewCheckBoxDialog) dialog).isCheckBoxChecked();
Log.d("TAG", "checked = " + checked);
}
}
@Override
public void onClick(View v) {
if (mFailedView == v) {
@@ -559,10 +595,13 @@ public class GalleryDetailScene extends Scene implements View.OnClickListener,
requestGalleryDetail(mGid, mToken);
}
} else if (mDownload == v) {
Intent intent = new Intent(getStageActivity(), DownloadService.class);
intent.setAction(DownloadService.ACTION_START);
intent.putExtra(DownloadService.KEY_GALLERY_BASE, mGalleryDetail);
getStageActivity().startService(intent);
DownloadLabelHelper helper = new DownloadLabelHelper();
new ListViewCheckBoxDialog.Builder(getContext())
.setListItems(helper.mLabels, helper)
.setCheckBoxText("Remeber") // TODO hardcode
.setTitle("Choose label") // TODO hardcode
.setOnCloseListener(helper)
.show(this);
} else if (mRead == v) {
GalleryBase galleryBase = mGalleryDetail;
if (galleryBase == null) {
@@ -72,6 +72,7 @@ import com.hippo.scene.Scene;
import com.hippo.scene.SimpleDialog;
import com.hippo.util.AnimationUtils;
import com.hippo.widget.FabLayout;
import com.hippo.widget.FloatLabelEditText;
import com.hippo.widget.FloatingActionButton;
import com.hippo.widget.recyclerview.EasyRecyclerView;
import com.hippo.yorozuya.AssertUtils;
@@ -87,9 +88,8 @@ import java.util.List;
// TODO disable click action when animating
// TODO Dim when expand search list
public final class GalleryListScene extends Scene implements ListSearchBar.Helper,
View.OnClickListener, FabLayout.OnCancelListener,
SearchLayout.SearhLayoutHelper, EasyRecyclerView.OnItemClickListener,
Messenger.Receiver, DrawerProvider, AppbarRecyclerView.Helper {
View.OnClickListener, SearchLayout.SearhLayoutHelper, EasyRecyclerView.OnItemClickListener,
Messenger.Receiver, DrawerProvider, AppbarRecyclerView.Helper, FabLayout.OnExpandListener {
public static final String KEY_MODE = "mode";
@@ -149,6 +149,9 @@ public final class GalleryListScene extends Scene implements ListSearchBar.Helpe
private QuickSearchAdapter mQuickSearchAdapter;
private List<QuickSearch> mQuickSearches;
private boolean mLockLeft = false;
private boolean mLockRight = false;
private SimpleDialog.OnCreateCustomViewListener mGoToCreateCustomViewListener =
new SimpleDialog.OnCreateCustomViewListener() {
@Override
@@ -310,7 +313,7 @@ public final class GalleryListScene extends Scene implements ListSearchBar.Helpe
mContentRecyclerView.setOnItemClickListener(this);
// Fab Layout
mFabLayout.setOnCancelListener(this);
mFabLayout.setOnExpandListener(this);
// Secondary Fab
mRefreshFab.setOnClickListener(this);
@@ -390,12 +393,17 @@ public final class GalleryListScene extends Scene implements ListSearchBar.Helpe
@Override
public boolean showLeftDrawer() {
return true;
return !mLockLeft;
}
@Override
public void bindRightDrawer(ContentActivity activity) {
activity.setRightDrawerView(mRightDrawerView);
if (mLockRight) {
activity.lockRightDrawer();
} else {
activity.unlockRightDrawer();
}
}
private void setFabState(int fabState, boolean animation) {
@@ -531,7 +539,6 @@ public final class GalleryListScene extends Scene implements ListSearchBar.Helpe
public void onBackPressed() {
if (mFabLayout.isExpanded()) {
mFabLayout.setExpanded(false);
mAddDeleteDrawable.setShape(false, ANIMATE_TIME);
} else {
switch (mState) {
case STATE_NORMAL:
@@ -557,11 +564,6 @@ public final class GalleryListScene extends Scene implements ListSearchBar.Helpe
}
}
private void toggleFabLayout() {
mFabLayout.toggle();
mAddDeleteDrawable.setShape(mFabLayout.isExpanded(), ANIMATE_TIME);
}
public void showGoToDialog() {
int[] center = new int[2];
ViewUtils.getCenterInAncestor(mGoToFab, center, R.id.stage);
@@ -576,15 +578,15 @@ public final class GalleryListScene extends Scene implements ListSearchBar.Helpe
public void onClick(View v) {
if (v == mCornerFab) {
if (mFabState == FAB_STATE_NORMAL) {
toggleFabLayout();
mFabLayout.toggle();
} else if (mFabState == FAB_STATE_SEARCH) {
onApplySearch(mSearchBar.getText());
}
} else if (v == mRefreshFab) {
toggleFabLayout();
mFabLayout.toggle();
mGalleryListHelper.refreshWithSameSearch();
} else if (v == mGoToFab) {
toggleFabLayout();
mFabLayout.toggle();
if (mGalleryListHelper.canGoTo()) {
showGoToDialog();
}
@@ -598,7 +600,7 @@ public final class GalleryListScene extends Scene implements ListSearchBar.Helpe
mode == ListUrlBuilder.MODE_TAG) {
AddToQuickSearchHelper helper = new AddToQuickSearchHelper(mListUrlBuilder.clone());
new SimpleDialog.Builder(getStageActivity()).setTitle("Add to quick search") // TODO hardcode
.setCustomView(R.layout.dialog_add_to_quick_search, helper)
.setCustomView(R.layout.dialog_edit_text, helper)
.setPositiveButton(android.R.string.ok)
.setOnButtonClickListener(helper).show(this);
} else {
@@ -612,8 +614,20 @@ public final class GalleryListScene extends Scene implements ListSearchBar.Helpe
}
@Override
public void onCancel(FabLayout fabLayout) {
mAddDeleteDrawable.setAdd(ANIMATE_TIME);
public void onExpand(boolean expanded) {
ContentActivity contentActivity = (ContentActivity) getStageActivity();
if (expanded) {
contentActivity.lockLeftDrawer();
contentActivity.lockRightDrawer();
mLockLeft = true;
mLockRight = true;
} else {
contentActivity.unlockLeftDrawer();
contentActivity.unlockRightDrawer();
mLockLeft = false;
mLockRight = false;
}
mAddDeleteDrawable.setShape(mFabLayout.isExpanded(), ANIMATE_TIME);
}
@Override
@@ -818,6 +832,8 @@ public final class GalleryListScene extends Scene implements ListSearchBar.Helpe
@Override
public void onCreateCustomView(final SimpleDialog dialog, View view) {
FloatLabelEditText floatLabelEditText = (FloatLabelEditText) view.findViewById(R.id.float_label_edit_text);
floatLabelEditText.setHint(getStageActivity().getString(R.string.displayname));
mEditText = (EditText) view.findViewById(R.id.edit_text);
mEditText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@Override
@@ -860,7 +876,7 @@ public final class GalleryListScene extends Scene implements ListSearchBar.Helpe
builder.setKeyword(mSearchBar.getText());
AddToQuickSearchHelper helper = new AddToQuickSearchHelper(builder);
new SimpleDialog.Builder(getStageActivity()).setTitle("Add to quick search") // TODO hardcode
.setCustomView(R.layout.dialog_add_to_quick_search, helper)
.setCustomView(R.layout.dialog_edit_text, helper)
.setPositiveButton(android.R.string.ok)
.setOnButtonClickListener(helper).show(this);
}
@@ -1242,7 +1258,7 @@ public final class GalleryListScene extends Scene implements ListSearchBar.Helpe
@Override
public SimpleHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new SimpleHolder(getStageActivity().getLayoutInflater().inflate(
R.layout.item_quick_search, parent, false));
R.layout.item_appbar_recycler_view, parent, false));
}
@Override
@@ -0,0 +1,92 @@
/*
* 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.ehviewer.ui.scene;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.ListView;
import com.hippo.ehviewer.R;
import com.hippo.scene.SimpleDialog;
public class ListViewCheckBoxDialog extends SimpleDialog {
private ListView mListView;
private CheckBox mCheckBox;
@Override
protected void onCreate(boolean rebirth) {
super.onCreate(rebirth);
ViewGroup customView = getCustomView();
mListView = (ListView) customView.findViewById(R.id.list);
mCheckBox = (CheckBox) customView.findViewById(R.id.check_box);
Builder builder = (Builder) getBuilder();
mListView.setAdapter(new ArrayAdapter<>(getStageActivity(),
builder.mListItemLayoutResId, android.R.id.text1, builder.mListeItems));
mListView.setOnItemClickListener(new ListItemClickListener());
mCheckBox.setText(builder.mCheckBoxText);
}
public boolean isCheckBoxChecked() {
return mCheckBox.isChecked();
}
public class ListItemClickListener implements ListView.OnItemClickListener {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
((Builder) getBuilder()).mOnListItemClickListener.onClick(ListViewCheckBoxDialog.this, position);
}
}
public static class Builder extends SimpleDialog.Builder {
private CharSequence[] mListeItems;
private int mListItemLayoutResId;
private OnClickListener mOnListItemClickListener;
private CharSequence mCheckBoxText;
public Builder(Context context) {
super(context);
setCustomView(R.layout.dialog_list_view_check_box, null);
}
public Builder setListItems(CharSequence[] items, final OnClickListener listener) {
mListeItems = items;
mListItemLayoutResId = R.layout.select_dialog_item;
mOnListItemClickListener = listener;
return this;
}
public Builder setCheckBoxText(CharSequence text) {
mCheckBoxText = text;
return this;
}
@Override
public Class getDialogClass() {
return ListViewCheckBoxDialog.class;
}
}
}
@@ -180,7 +180,7 @@ public class ModifyQuickSearchScene extends AppbarScene implements SearchLayout.
public void onAction1() {
RenameHelper helper = new RenameHelper();
new SimpleDialog.Builder(getStageActivity()).setTitle(R.string.rename)
.setCustomView(R.layout.dialog_add_to_quick_search, helper)
.setCustomView(R.layout.dialog_edit_text, helper)
.setPositiveButton(android.R.string.ok)
.setOnButtonClickListener(helper).show(this);
}
@@ -53,6 +53,7 @@ public class QuickSearchScene extends AbsDragSortScene implements Messenger.Rece
// notify update
if (mChanged) {
Messenger.getInstance().notify(Constants.MESSENGER_ID_UPDATE_QUICK_SEARCH, null);
mChanged = false;
}
}
@@ -21,6 +21,7 @@ import android.database.sqlite.SQLiteDatabase;
import android.text.TextUtils;
import com.hippo.ehviewer.client.data.DownloadInfo;
import com.hippo.ehviewer.client.data.DownloadLabel;
import com.hippo.ehviewer.client.data.GalleryBase;
import com.hippo.ehviewer.client.data.ListUrlBuilder;
import com.hippo.ehviewer.client.data.QuickSearch;
@@ -30,8 +31,8 @@ import com.hippo.ehviewer.dao.DirnameObj;
import com.hippo.ehviewer.dao.DirnameObjDao;
import com.hippo.ehviewer.dao.DownloadInfoObj;
import com.hippo.ehviewer.dao.DownloadInfoObjDao;
import com.hippo.ehviewer.dao.DownloadTagObj;
import com.hippo.ehviewer.dao.DownloadTagObjDao;
import com.hippo.ehviewer.dao.DownloadLabelObj;
import com.hippo.ehviewer.dao.DownloadLabelObjDao;
import com.hippo.ehviewer.dao.GalleryBaseObj;
import com.hippo.ehviewer.dao.GalleryBaseObjDao;
import com.hippo.ehviewer.dao.QuickSearchObj;
@@ -198,8 +199,6 @@ public class DBUtils {
return result;
}
public static List<DownloadInfo> getAllDownloadInfo() {
DownloadInfoObjDao dao = sDaoSession.getDownloadInfoObjDao();
List<DownloadInfoObj> list = dao.queryBuilder().orderAsc(DownloadInfoObjDao.Properties.Time).list();
@@ -213,10 +212,10 @@ public class DBUtils {
public static void addDownloadInfo(DownloadInfo downloadInfo) {
DownloadInfoObj obj = new DownloadInfoObj();
obj.setGid((long) downloadInfo.galleryBase.gid);
obj.setTag(downloadInfo.tag);
obj.setLabel(downloadInfo.label);
obj.setState(downloadInfo.state);
obj.setLegacy(downloadInfo.legacy);
obj.setTime(System.currentTimeMillis());
obj.setTime(downloadInfo.time);
sDaoSession.getDownloadInfoObjDao().insert(obj);
addGalleryBase(downloadInfo.galleryBase);
}
@@ -226,22 +225,81 @@ public class DBUtils {
DownloadInfoObj obj = dao.load((long) downloadInfo.galleryBase.gid);
obj.setState(downloadInfo.state);
obj.setLegacy(downloadInfo.legacy);
obj.setLabel(downloadInfo.label);
dao.update(obj);
}
public static List<String> getAllDownloadTag() {
DownloadTagObjDao dao = sDaoSession.getDownloadTagObjDao();
List<DownloadTagObj> list = dao.queryBuilder().list();
public static List<String> getAllDownloadLabel() {
DownloadLabelObjDao dao = sDaoSession.getDownloadLabelObjDao();
List<DownloadLabelObj> list = dao.queryBuilder().orderAsc(DownloadLabelObjDao.Properties.Time).list();
List<String> result = new ArrayList<>(list.size());
for (DownloadTagObj obj : list) {
result.add(obj.getTag());
for (DownloadLabelObj obj : list) {
result.add(obj.getLabel());
}
return result;
}
public static void addDownloadTag(String tag) {
DownloadTagObj obj = new DownloadTagObj();
obj.setTag(tag);
sDaoSession.getDownloadTagObjDao().insert(obj);
public static List<DownloadLabel> getAllDownloadLabelWithId() {
DownloadLabelObjDao dao = sDaoSession.getDownloadLabelObjDao();
List<DownloadLabelObj> list = dao.queryBuilder().orderAsc(DownloadLabelObjDao.Properties.Time).list();
List<DownloadLabel> result = new ArrayList<>(list.size());
for (DownloadLabelObj obj : list) {
DownloadLabel tag = new DownloadLabel();
tag.id = obj.getId();
tag.label = obj.getLabel();
tag.time = obj.getTime();
result.add(tag);
}
return result;
}
public static void addDownloadLabel(String label) {
if (TextUtils.isEmpty(label)) {
return;
}
DownloadLabelObj obj = new DownloadLabelObj();
obj.setLabel(label);
obj.setTime(System.currentTimeMillis());
sDaoSession.getDownloadLabelObjDao().insert(obj);
}
public static void moveDownloadLabel(long fromId, long toId) {
DownloadLabelObjDao dao = sDaoSession.getDownloadLabelObjDao();
DownloadLabelObj from = dao.load(fromId);
DownloadLabelObj to = dao.load(toId);
long fromTime = from.getTime();
long toTime = to.getTime();
from.setTime(toTime);
to.setTime(fromTime);
dao.update(from);
dao.update(to);
}
public static void updateDownloadLabel(DownloadLabel label) {
DownloadLabelObjDao dao = sDaoSession.getDownloadLabelObjDao();
DownloadLabelObj obj = dao.load(label.id);
obj.setId(label.id);
obj.setLabel(label.label);
obj.setTime(label.time);
dao.update(obj);
}
public static void removeDownloadLabel(long id) {
sDaoSession.getDownloadLabelObjDao().deleteByKey(id);
}
public static void removeDownloadLabel(String label) {
DownloadLabelObjDao dao = sDaoSession.getDownloadLabelObjDao();
List<DownloadLabelObj> list = dao.queryBuilder()
.where(DownloadLabelObjDao.Properties.Label.eq(label)).list();
for (DownloadLabelObj obj : list) {
dao.delete(obj);
}
}
public static boolean containDownloadLabel(String label) {
return sDaoSession.getDownloadLabelObjDao().queryBuilder()
.where(DownloadLabelObjDao.Properties.Label.eq(label)).count() != 0;
}
}
@@ -28,12 +28,40 @@ import com.hippo.ehviewer.R;
import com.hippo.rippleold.RippleSalon;
import com.hippo.widget.SimpleImageView;
public class AppbarScene extends Scene {
import java.util.ArrayList;
import java.util.List;
public abstract class AppbarScene extends Scene {
private ViewGroup mAppbar;
private SimpleImageView mIcon;
private TextView mTitle;
private FrameLayout mContent;
private OnClickActionListener mOnClickActionListener;
private List<SimpleImageView> mActions;
private View.OnClickListener mOnClickListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mIcon == v) {
onIconClick();
} else {
int index = -1;
for (int i = 0, n = mActions.size(); i < n; i++) {
if (mActions.get(i) == v) {
index = i;
break;
}
}
if (index >= 0 && mOnClickActionListener != null) {
mOnClickActionListener.onClickAction(index);
}
}
}
};
@Override
protected void setContentView(int resId) {
getStageActivity().getLayoutInflater().inflate(resId, mContent);
@@ -54,17 +82,29 @@ public class AppbarScene extends Scene {
super.onCreate(rebirth);
super.setContentView(R.layout.scene_appbar);
mAppbar = (ViewGroup) super.findViewById(R.id.appbar);
mIcon = (SimpleImageView) super.findViewById(R.id.appbar_icon);
mTitle = (TextView) super.findViewById(R.id.appbar_title);
mContent = (FrameLayout) super.findViewById(R.id.appbar_content);
RippleSalon.addRipple(mIcon, true);
mIcon.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
onIconClick();
}
});
mIcon.setOnClickListener(mOnClickListener);
mActions = new ArrayList<>();
}
public void setOnClickActionListener(OnClickActionListener listener) {
mOnClickActionListener = listener;
}
public void addAction(@DrawableRes int drawableRes) {
int index = mAppbar.getChildCount();
getStageActivity().getLayoutInflater().inflate(R.layout.item_appbar_action, mAppbar);
SimpleImageView action = (SimpleImageView) mAppbar.getChildAt(index);
action.setDrawable(drawableRes);
action.setOnClickListener(mOnClickListener);
RippleSalon.addRipple(action, true);
mActions.add(action);
}
public void onIconClick() {
@@ -87,4 +127,9 @@ public class AppbarScene extends Scene {
public void setTitle(String title) {
mTitle.setText(title);
}
public interface OnClickActionListener {
void onClickAction(int index);
}
}
@@ -69,6 +69,10 @@ public class SimpleDialog extends SceneDialog implements View.OnClickListener,
mBuilder = builder;
}
protected Builder getBuilder() {
return mBuilder;
}
@Override
protected void onCreate(boolean rebirth) {
super.onCreate(rebirth);
@@ -197,6 +201,10 @@ public class SimpleDialog extends SceneDialog implements View.OnClickListener,
mLayout.setFitPaddingBottom(b);
}
protected FrameLayout getCustomView() {
return mCustom;
}
public ViewGroup getLayout() {
return mLayout;
}
@@ -427,11 +435,15 @@ public class SimpleDialog extends SceneDialog implements View.OnClickListener,
return this;
}
public Class getDialogClass() {
return SimpleDialog.class;
}
public @NonNull SimpleDialog show(Scene scene) {
// Avoid memory leak
mContext = null;
SimpleDialog dialog = (SimpleDialog) SceneDialog.createSceneDialog(scene, SimpleDialog.class);
SimpleDialog dialog = (SimpleDialog) SceneDialog.createSceneDialog(scene, getDialogClass());
dialog.setBuilder(this);
dialog.show(new SimpleDialogCurtain(mStartX, mStartY));
@@ -48,7 +48,7 @@ public class FabLayout extends ViewGroup implements View.OnClickListener {
private boolean mAutoCancel = true;
private float mMainFabCenterY = -1f;
private OnCancelListener mOnCancelListener;
private OnExpandListener mOnExpandListener;
public FabLayout(Context context) {
super(context);
@@ -196,8 +196,8 @@ public class FabLayout extends ViewGroup implements View.OnClickListener {
}
}
public void setOnCancelListener(OnCancelListener listener) {
mOnCancelListener = listener;
public void setOnExpandListener(OnExpandListener listener) {
mOnExpandListener = listener;
}
public void setAutoCancel(boolean autoCancel) {
@@ -258,6 +258,10 @@ public class FabLayout extends ViewGroup implements View.OnClickListener {
}
}
}
if (mOnExpandListener != null) {
mOnExpandListener.onExpand(expanded);
}
}
}
@@ -314,9 +318,6 @@ public class FabLayout extends ViewGroup implements View.OnClickListener {
@Override
public void onClick(View v) {
setExpanded(false);
if (mOnCancelListener != null) {
mOnCancelListener.onCancel(this);
}
}
@Override
@@ -343,7 +344,7 @@ public class FabLayout extends ViewGroup implements View.OnClickListener {
}
}
public interface OnCancelListener {
void onCancel(FabLayout fabLayout);
public interface OnExpandListener {
void onExpand(boolean expanded);
}
}
@@ -121,7 +121,7 @@ public class FloatLabelEditText extends FrameLayout {
// If we do not have a valid hint, try and retrieve it from the EditText
if (TextUtils.isEmpty(mHint)) {
setHint(mEditText.getHint());
setHintInternal(mEditText.getHint());
}
// Align with label and edittext
@@ -133,6 +133,11 @@ public class FloatLabelEditText extends FrameLayout {
}
public void setHint(CharSequence hint) {
mEditText.setHint(hint);
setHintInternal(hint);
}
private void setHintInternal(CharSequence hint) {
mHint = hint;
mLabel.setText(hint);
}
@@ -106,6 +106,8 @@ public class EasyRecyclerView extends RecyclerView {
private boolean mCustomChoice = false;
private boolean mOutOfCustomChoiceModing = false;
private SparseBooleanArray mTempCheckStates;
private FixCheckedHelper mFixCheckedHelper;
@@ -520,7 +522,8 @@ public class EasyRecyclerView extends RecyclerView {
}
public void outOfCustomChoiceMode() {
if (mChoiceMode == CHOICE_MODE_MULTIPLE_CUSTOM && mCustomChoice) {
if (mChoiceMode == CHOICE_MODE_MULTIPLE_CUSTOM && mCustomChoice && !mOutOfCustomChoiceModing) {
mOutOfCustomChoiceModing = true;
// Copy mCheckStates
mTempCheckStates.clear();
@@ -536,6 +539,8 @@ public class EasyRecyclerView extends RecyclerView {
mCustomChoice = false;
mCustomChoiceListener.onOutOfCustomChoice(this);
mOutOfCustomChoiceModing = false;
}
}