diff --git a/app/src/main/java/com/hippo/ehviewer/EhDB.java b/app/src/main/java/com/hippo/ehviewer/EhDB.java index 939b759a6..40e563de9 100644 --- a/app/src/main/java/com/hippo/ehviewer/EhDB.java +++ b/app/src/main/java/com/hippo/ehviewer/EhDB.java @@ -418,6 +418,11 @@ public class EhDB { return raw; } + public static synchronized void updateDownloadLabel(DownloadLabelRaw raw) { + DownloadLabelDao dao = sDaoSession.getDownloadLabelDao(); + dao.update(raw); + } + public static synchronized void moveDownloadLabel(int fromPosition, int toPosition) { if (fromPosition == toPosition) { return; @@ -442,4 +447,9 @@ public class EhDB { dao.updateInTx(list); } + + public static synchronized void removeDownloadLabel(DownloadLabelRaw raw) { + DownloadLabelDao dao = sDaoSession.getDownloadLabelDao(); + dao.delete(raw); + } } diff --git a/app/src/main/java/com/hippo/ehviewer/download/DownloadManager.java b/app/src/main/java/com/hippo/ehviewer/download/DownloadManager.java index 1c4b3a10e..e169a37e2 100644 --- a/app/src/main/java/com/hippo/ehviewer/download/DownloadManager.java +++ b/app/src/main/java/com/hippo/ehviewer/download/DownloadManager.java @@ -617,6 +617,80 @@ public class DownloadManager implements SpiderQueen.OnSpiderListener { } } + public void renameLabel(@NonNull String from, @NonNull String to) { + // Find in label list + boolean found = false; + for (DownloadLabelRaw raw: mLabelList) { + if (from.equals(raw.getLabel())) { + found = true; + raw.setLabel(to); + // Update in DB + EhDB.updateDownloadLabel(raw); + break; + } + } + if (!found) { + return; + } + + LinkedList list = mMap.remove(from); + if (list == null) { + return; + } + + // Update info label + for (DownloadInfo info: list) { + info.label = to; + // Update in DB + EhDB.updateDownloadInfo(info); + } + // Put list back with new label + mMap.put(to, list); + + // Notify listener + if (mDownloadInfoListener != null) { + mDownloadInfoListener.onRenameLabel(from, to); + } + } + + public void deleteLabel(@NonNull String label) { + // Find in label list and remove + boolean found = false; + for (Iterator iterator = mLabelList.iterator(); iterator.hasNext();) { + DownloadLabelRaw raw = iterator.next(); + if (label.equals(raw.getLabel())) { + found = true; + iterator.remove(); + EhDB.removeDownloadLabel(raw); + break; + } + } + if (!found) { + return; + } + + LinkedList list = mMap.remove(label); + if (list == null) { + return; + } + + // Update info label + for (DownloadInfo info: list) { + info.label = null; + // Update in DB + EhDB.updateDownloadInfo(info); + mDefaultInfoList.add(info); + } + + // Sort + Collections.sort(mDefaultInfoList, sDateAscComparator); + + // Notify listener + if (mDownloadInfoListener != null) { + mDownloadInfoListener.onChange(); + } + } + boolean isIdle() { return mCurrentTask == null && mWaitList.isEmpty(); } @@ -929,10 +1003,15 @@ public class DownloadManager implements SpiderQueen.OnSpiderListener { void onReload(); /** - * The list is gone + * The list is gone, use default list please */ void onChange(); + /** + * Rename label + */ + void onRenameLabel(String from, String to); + /** * Remove the special info from the special position */ diff --git a/app/src/main/java/com/hippo/ehviewer/ui/scene/DownloadLabelScene.java b/app/src/main/java/com/hippo/ehviewer/ui/scene/DownloadLabelScene.java index a9a31c95d..5c94955d8 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/scene/DownloadLabelScene.java +++ b/app/src/main/java/com/hippo/ehviewer/ui/scene/DownloadLabelScene.java @@ -19,6 +19,7 @@ package com.hippo.ehviewer.ui.scene; import android.content.DialogInterface; import android.graphics.drawable.NinePatchDrawable; import android.os.Bundle; +import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.v7.app.AlertDialog; import android.support.v7.widget.LinearLayoutManager; @@ -40,6 +41,8 @@ import com.h6ah4i.android.widget.advrecyclerview.swipeable.RecyclerViewSwipeMana import com.h6ah4i.android.widget.advrecyclerview.swipeable.SwipeableItemAdapter; import com.h6ah4i.android.widget.advrecyclerview.swipeable.SwipeableItemConstants; import com.h6ah4i.android.widget.advrecyclerview.swipeable.action.SwipeResultAction; +import com.h6ah4i.android.widget.advrecyclerview.swipeable.action.SwipeResultActionDefault; +import com.h6ah4i.android.widget.advrecyclerview.swipeable.action.SwipeResultActionMoveToSwipedDirection; import com.h6ah4i.android.widget.advrecyclerview.touchguard.RecyclerViewTouchActionGuardManager; import com.h6ah4i.android.widget.advrecyclerview.utils.AbstractDraggableSwipeableItemViewHolder; import com.hippo.app.EditTextDialogBuilder; @@ -53,7 +56,9 @@ import com.hippo.view.ViewTransition; import com.hippo.widget.SimpleImageView; import com.hippo.yorozuya.ViewUtils; +import java.util.HashMap; import java.util.List; +import java.util.Map; public class DownloadLabelScene extends ToolbarScene { @@ -68,6 +73,9 @@ public class DownloadLabelScene extends ToolbarScene { @Nullable public List mList = null; + @NonNull + public final Map mPinState = new HashMap<>(); + @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -179,6 +187,55 @@ public class DownloadLabelScene extends ToolbarScene { } } + private boolean isPinned(int position) { + if (mList != null) { + Boolean pinned = mPinState.get(mList.get(position)); + if (pinned != null) { + return pinned; + } + } + return false; + } + + private void setPinned(int position, boolean pinned) { + if (mList != null) { + mPinState.put(mList.get(position), pinned); + } + } + + private class DeleteLabelDialogHelper implements DialogInterface.OnClickListener { + + private final int mIndex; + + public DeleteLabelDialogHelper(int index) { + mIndex = index; + } + + @Override + public void onClick(DialogInterface dialog, int which) { + if (which != DialogInterface.BUTTON_POSITIVE) { + return; + } + if (mList == null) { + return; + } + + DownloadLabelRaw raw = mList.get(mIndex); + EhApplication.getDownloadManager(getContext()).deleteLabel(raw.getLabel()); + mPinState.remove(raw); + if (mAdapter != null) { + mAdapter.notifyItemRemoved(mIndex); + } + if (mViewTransition != null) { + if (mList != null && mList.size() > 0) { + mViewTransition.showView(0); + } else { + mViewTransition.showView(1); + } + } + } + } + private class NewLabelDialogHelper implements View.OnClickListener { private final EditTextDialogBuilder mBuilder; @@ -220,9 +277,49 @@ public class DownloadLabelScene extends ToolbarScene { } } + private class RenameLabelDialogHelper implements View.OnClickListener { + + private final EditTextDialogBuilder mBuilder; + private final AlertDialog mDialog; + private final String mOriginalLabel; + private final int mPosition; + + public RenameLabelDialogHelper(EditTextDialogBuilder builder, AlertDialog dialog, + String originalLabel, int position) { + mBuilder = builder; + mDialog = dialog; + mOriginalLabel = originalLabel; + mPosition = position; + Button button = dialog.getButton(DialogInterface.BUTTON_POSITIVE); + if (button != null) { + button.setOnClickListener(this); + } + } + + @Override + public void onClick(View v) { + String text = mBuilder.getText(); + if (TextUtils.isEmpty(text)) { + mBuilder.setError(getString(R.string.label_text_is_empty)); + } else if (getString(R.string.default_download_label_name).equals(text)) { + mBuilder.setError(getString(R.string.label_text_is_invalid)); + } else if (EhApplication.getDownloadManager(getContext()).containLabel(text)) { + mBuilder.setError(getString(R.string.label_text_exist)); + } else { + mBuilder.setError(null); + mDialog.dismiss(); + EhApplication.getDownloadManager(getContext()).renameLabel(mOriginalLabel, text); + if (mAdapter != null) { + mAdapter.notifyItemChanged(mPosition); + } + } + } + } + private class LabelHolder extends AbstractDraggableSwipeableItemViewHolder implements View.OnClickListener { + public final View delete; public final View swipeHandler; public final TextView label; public final View dragHandler; @@ -230,16 +327,42 @@ public class DownloadLabelScene extends ToolbarScene { public LabelHolder(View itemView) { super(itemView); + delete = itemView.findViewById(R.id.delete); swipeHandler = itemView.findViewById(R.id.swipe_handler); label = (TextView) itemView.findViewById(R.id.label); dragHandler = itemView.findViewById(R.id.drag_handler); + delete.setOnClickListener(this); label.setOnClickListener(this); } @Override public void onClick(View v) { - // TODO + if (mList == null || mRecyclerView == null) { + return; + } + + int index = mRecyclerView.getChildAdapterPosition(itemView); + if (index < 0 || index >= mList.size()) { + return; + } + + if (delete == v) { + DeleteLabelDialogHelper helper = new DeleteLabelDialogHelper(index); + new AlertDialog.Builder(getContext()) + .setTitle(R.string.delete_label_title) + .setMessage(getString(R.string.delete_label_text, mList.get(index).getLabel())) + .setPositiveButton(android.R.string.ok, helper) + .show(); + } else if (label == v) { + DownloadLabelRaw raw = mList.get(index); + EditTextDialogBuilder builder = new EditTextDialogBuilder( + getContext(), raw.getLabel(), getString(R.string.label)); + builder.setTitle(R.string.rename_label_title); + builder.setPositiveButton(android.R.string.ok, null); + AlertDialog dialog = builder.show(); + new RenameLabelDialogHelper(builder, dialog, raw.getLabel(), index); + } } @Override @@ -252,7 +375,6 @@ public class DownloadLabelScene extends ToolbarScene { implements DraggableItemAdapter, SwipeableItemAdapter { - @Override public LabelHolder onCreateViewHolder(ViewGroup parent, int viewType) { return new LabelHolder(getActivity().getLayoutInflater() @@ -264,6 +386,11 @@ public class DownloadLabelScene extends ToolbarScene { if (mList != null) { holder.label.setText(mList.get(position).getLabel()); } + + // set swiping properties + holder.setMaxLeftSwipeAmount(-0.5f); + holder.setMaxRightSwipeAmount(0); + holder.setSwipeItemHorizontalSlideAmount(isPinned(position) ? -0.5f : 0); } @Override @@ -300,7 +427,11 @@ public class DownloadLabelScene extends ToolbarScene { @Override public int onGetSwipeReactionType(LabelHolder holder, int position, int x, int y) { - return SwipeableItemConstants.REACTION_CAN_SWIPE_BOTH_H; + if (ViewUtils.isViewUnder(holder.getSwipeableContainerView(), x, y, 0)) { + return SwipeableItemConstants.REACTION_CAN_SWIPE_BOTH_H; + } else { + return SwipeableItemConstants.REACTION_CAN_NOT_SWIPE_BOTH_H; + } } @Override @@ -311,13 +442,62 @@ public class DownloadLabelScene extends ToolbarScene { @Override public SwipeResultAction onSwipeItem(LabelHolder holder, int position, int result) { switch (result) { - // swipe right - case SwipeableItemConstants.RESULT_SWIPED_RIGHT: + // swipe left --- pin case SwipeableItemConstants.RESULT_SWIPED_LEFT: - return null; + return new SwipeLeftResultAction(position); + // other --- do nothing + case SwipeableItemConstants.RESULT_SWIPED_RIGHT: case SwipeableItemConstants.RESULT_CANCELED: default: - return null; + if (position >= 0) { + return new UnpinResultAction(position); + } else { + return null; + } + } + } + } + + private class SwipeLeftResultAction extends SwipeResultActionMoveToSwipedDirection { + + private final int mPosition; + + public SwipeLeftResultAction(int position) { + mPosition = position; + } + + @Override + protected void onPerformAction() { + super.onPerformAction(); + + if (!isPinned(mPosition)) { + setPinned(mPosition, true); + + if (mAdapter != null) { + mAdapter.notifyItemChanged(mPosition); + } + } + } + } + + private class UnpinResultAction extends SwipeResultActionDefault { + + private final int mPosition; + + public UnpinResultAction(int position) { + mPosition = position; + } + + @Override + protected void onPerformAction() { + super.onPerformAction(); + + if (isPinned(mPosition)) { + setPinned(mPosition, false); + + if (mAdapter != null) { + mAdapter.notifyItemChanged(mPosition); + } } } } diff --git a/app/src/main/java/com/hippo/ehviewer/ui/scene/DownloadScene.java b/app/src/main/java/com/hippo/ehviewer/ui/scene/DownloadScene.java index c0e0841e8..d0cec53f8 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/scene/DownloadScene.java +++ b/app/src/main/java/com/hippo/ehviewer/ui/scene/DownloadScene.java @@ -559,6 +559,23 @@ public class DownloadScene extends ToolbarScene } } + @Override + public void onRenameLabel(String from, String to) { + if (!ObjectUtils.equal(mLabel, from)) { + return; + } + + mLabel = to; + updateForLabel(); + if (mViewTransition != null) { + if (mList == null || mList.size() == 0) { + mViewTransition.showView(1); + } else { + mViewTransition.showView(0); + } + } + } + @Override public void onRemove(@NonNull DownloadInfo info, @NonNull List list, int position) { if (mList != list) { diff --git a/app/src/main/res/drawable-hdpi/ic_delete_red_x24.png b/app/src/main/res/drawable-hdpi/ic_delete_red_x24.png new file mode 100644 index 000000000..11416cd46 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_delete_red_x24.png differ diff --git a/app/src/main/res/drawable-mdpi/ic_delete_red_x24.png b/app/src/main/res/drawable-mdpi/ic_delete_red_x24.png new file mode 100644 index 000000000..f0ee9e8d9 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_delete_red_x24.png differ diff --git a/app/src/main/res/drawable-xhdpi/ic_delete_red_x24.png b/app/src/main/res/drawable-xhdpi/ic_delete_red_x24.png new file mode 100644 index 000000000..6753cf8f6 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_delete_red_x24.png differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_delete_red_x24.png b/app/src/main/res/drawable-xxhdpi/ic_delete_red_x24.png new file mode 100644 index 000000000..6b303db50 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_delete_red_x24.png differ diff --git a/app/src/main/res/layout/item_download_label.xml b/app/src/main/res/layout/item_download_label.xml index b2ced5f02..ffe4edbc5 100644 --- a/app/src/main/res/layout/item_download_label.xml +++ b/app/src/main/res/layout/item_download_label.xml @@ -21,6 +21,24 @@ android:layout_height="wrap_content" android:clipChildren="false"> + + + + + + + + + android:textSize="@dimen/text_little_small" + android:textColor="@color/primary_text_light"/> 全部停止 标签 默认 + 移动 标签 + + 无标签 + 添加 + 新标签 + 标签文本为空 + “默认”是无效标签 + 标签已存在 + 重命名标签 + 删除标签 + 删除标签“%s” + 第 %d 页 @string/refresh diff --git a/app/src/main/res/values-zh-rHK/strings.xml b/app/src/main/res/values-zh-rHK/strings.xml index 70d7ebedf..450552a23 100644 --- a/app/src/main/res/values-zh-rHK/strings.xml +++ b/app/src/main/res/values-zh-rHK/strings.xml @@ -197,6 +197,19 @@ 全部停止 標籤 默認 + 移動 + 標籤 + + + 無標籤 + 添加 + 新標籤 + 標籤文本為空 + “默認”是無效標籤 + 標籤已存在 + 重命名標籤 + 刪除標籤 + 刪除標籤“%s” 第 %d 頁 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 2660d2aa4..c84f31775 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -197,6 +197,19 @@ 全部停止 標籤 預設 + 移動 + 標籤 + + + 無標籤 + 新增 + 新標籤 + 標籤文字為空 + “預設”是無效標籤 + 標籤已存在 + 重新命名標籤 + 刪除標籤 + 刪除標籤“%s” 第 %d 頁 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 419a79f37..34b239a06 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -246,7 +246,10 @@ New label Label text is empty \"Default\" is an invalid label - Label text exists + Label exists + Rename label + Delete label + Delete label \"%s\" Page %d