From a55b5a84d513e1126df045f35a36157be9e617ec Mon Sep 17 00:00:00 2001 From: seven332 Date: Mon, 29 Feb 2016 00:38:30 +0800 Subject: [PATCH] Add download label scene --- app/build.gradle | 1 + .../com/hippo/app/EditTextDialogBuilder.java | 77 +++++ .../main/java/com/hippo/ehviewer/EhDB.java | 25 ++ .../ehviewer/download/DownloadManager.java | 30 +- .../ehviewer/ui/scene/DownloadLabelScene.java | 324 ++++++++++++++++++ .../ehviewer/ui/scene/DownloadScene.java | 31 +- .../com/hippo/widget/ShadowLinearLayout.java | 96 ++++++ .../res/drawable-hdpi/ic_add_dark_x24.png | Bin 0 -> 124 bytes .../res/drawable-mdpi/ic_add_dark_x24.png | Bin 0 -> 93 bytes .../res/drawable-xhdpi/ic_add_dark_x24.png | Bin 0 -> 97 bytes .../res/drawable-xxhdpi/ic_add_dark_x24.png | Bin 0 -> 97 bytes .../main/res/drawable-xxhdpi/shadow_2dp.9.png | Bin 0 -> 258 bytes .../main/res/drawable-xxhdpi/shadow_8dp.9.png | Bin 0 -> 981 bytes .../res/layout/dialog_edittext_builder.xml | 35 ++ .../main/res/layout/item_download_label.xml | 62 ++++ .../main/res/layout/scene_download_label.xml | 55 +++ app/src/main/res/layout/scene_login.xml | 4 +- .../main/res/menu/scene_download_label.xml | 28 ++ app/src/main/res/values/strings.xml | 8 + 19 files changed, 764 insertions(+), 12 deletions(-) create mode 100644 app/src/main/java/com/hippo/app/EditTextDialogBuilder.java create mode 100644 app/src/main/java/com/hippo/ehviewer/ui/scene/DownloadLabelScene.java create mode 100644 app/src/main/java/com/hippo/widget/ShadowLinearLayout.java create mode 100644 app/src/main/res/drawable-hdpi/ic_add_dark_x24.png create mode 100644 app/src/main/res/drawable-mdpi/ic_add_dark_x24.png create mode 100644 app/src/main/res/drawable-xhdpi/ic_add_dark_x24.png create mode 100644 app/src/main/res/drawable-xxhdpi/ic_add_dark_x24.png create mode 100644 app/src/main/res/drawable-xxhdpi/shadow_2dp.9.png create mode 100644 app/src/main/res/drawable-xxhdpi/shadow_8dp.9.png create mode 100644 app/src/main/res/layout/dialog_edittext_builder.xml create mode 100644 app/src/main/res/layout/item_download_label.xml create mode 100644 app/src/main/res/layout/scene_download_label.xml create mode 100644 app/src/main/res/menu/scene_download_label.xml diff --git a/app/build.gradle b/app/build.gradle index 0a6cf3e8d..ad2de1ea3 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -73,6 +73,7 @@ dependencies { compile 'com.android.support:appcompat-v7:23.2.0' compile 'com.android.support:customtabs:23.2.0' compile 'com.android.support:design:23.2.0' + compile 'com.h6ah4i.android.widget.advrecyclerview:advrecyclerview:0.8.6' compile 'de.greenrobot:greendao:2.0.0' compile 'org.ccil.cowan.tagsoup:tagsoup:1.2.1' } diff --git a/app/src/main/java/com/hippo/app/EditTextDialogBuilder.java b/app/src/main/java/com/hippo/app/EditTextDialogBuilder.java new file mode 100644 index 000000000..71a302184 --- /dev/null +++ b/app/src/main/java/com/hippo/app/EditTextDialogBuilder.java @@ -0,0 +1,77 @@ +/* + * 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.annotation.SuppressLint; +import android.content.Context; +import android.content.DialogInterface; +import android.support.design.widget.TextInputLayout; +import android.support.v7.app.AlertDialog; +import android.view.KeyEvent; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.Button; +import android.widget.EditText; +import android.widget.TextView; + +import com.hippo.ehviewer.R; + +public class EditTextDialogBuilder extends AlertDialog.Builder implements EditText.OnEditorActionListener { + + private final TextInputLayout mTextInputLayout; + private final EditText mEditText; + private AlertDialog mDialog; + + @SuppressLint("InflateParams") + public EditTextDialogBuilder(Context context, String text, String hint) { + super(context); + View view = LayoutInflater.from(context).inflate(R.layout.dialog_edittext_builder, null); + setView(view); + mTextInputLayout = (TextInputLayout) view; + mEditText = (EditText) view.findViewById(R.id.edit_text); + mEditText.setText(text); + mEditText.setOnEditorActionListener(this); + mTextInputLayout.setHint(hint); + } + + public String getText() { + return mEditText.getText().toString(); + } + + public void setError(CharSequence error) { + mTextInputLayout.setError(error); + } + + @Override + public AlertDialog create() { + mDialog = super.create(); + return mDialog; + } + + @Override + public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { + if (mDialog != null) { + Button button = mDialog.getButton(DialogInterface.BUTTON_POSITIVE); + if (button != null) { + button.performClick(); + } + return true; + } else { + return false; + } + } +} diff --git a/app/src/main/java/com/hippo/ehviewer/EhDB.java b/app/src/main/java/com/hippo/ehviewer/EhDB.java index 9b2a4f79d..939b759a6 100644 --- a/app/src/main/java/com/hippo/ehviewer/EhDB.java +++ b/app/src/main/java/com/hippo/ehviewer/EhDB.java @@ -417,4 +417,29 @@ public class EhDB { raw.setId(dao.insert(raw)); return raw; } + + public static synchronized void moveDownloadLabel(int fromPosition, int toPosition) { + if (fromPosition == toPosition) { + return; + } + + boolean reverse = fromPosition > toPosition; + int offset = reverse ? toPosition : fromPosition; + int limit = reverse ? fromPosition - toPosition + 1 : toPosition - fromPosition + 1; + + DownloadLabelDao dao = sDaoSession.getDownloadLabelDao(); + List list = dao.queryBuilder().orderAsc(DownloadLabelDao.Properties.Time) + .offset(offset).limit(limit).list(); + + int step = reverse ? 1 : -1; + int start = reverse ? limit - 1 : 0; + int end = reverse ? 0 : limit - 1; + long toTime = list.get(end).getTime(); + for (int i = end; reverse ? i < start : i > start; i += step) { + list.get(i).setTime(list.get(i + step).getTime()); + } + list.get(start).setTime(toTime); + + dao.updateInTx(list); + } } 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 72620d4fe..1c4b3a10e 100644 --- a/app/src/main/java/com/hippo/ehviewer/download/DownloadManager.java +++ b/app/src/main/java/com/hippo/ehviewer/download/DownloadManager.java @@ -594,6 +594,29 @@ public class DownloadManager implements SpiderQueen.OnSpiderListener { } } + public void addLabel(String label) { + if (label == null || containLabel(label)) { + return; + } + + mLabelList.add(EhDB.addDownloadLabel(label)); + mMap.put(label, new LinkedList()); + + if (mDownloadInfoListener != null) { + mDownloadInfoListener.onUpdateLabels(); + } + } + + public void moveLabel(int fromPosition, int toPosition) { + final DownloadLabelRaw item = mLabelList.remove(fromPosition); + mLabelList.add(toPosition, item); + EhDB.moveDownloadLabel(fromPosition, toPosition); + + if (mDownloadInfoListener != null) { + mDownloadInfoListener.onUpdateLabels(); + } + } + boolean isIdle() { return mCurrentTask == null && mWaitList.isEmpty(); } @@ -901,10 +924,15 @@ public class DownloadManager implements SpiderQueen.OnSpiderListener { void onUpdateAll(); /** - * Maybe all data is changed, maybe size is changed + * Maybe all data is changed, maybe list is changed */ void onReload(); + /** + * The list is gone + */ + void onChange(); + /** * 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 new file mode 100644 index 000000000..a9a31c95d --- /dev/null +++ b/app/src/main/java/com/hippo/ehviewer/ui/scene/DownloadLabelScene.java @@ -0,0 +1,324 @@ +/* + * 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.scene; + +import android.content.DialogInterface; +import android.graphics.drawable.NinePatchDrawable; +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v7.app.AlertDialog; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.text.TextUtils; +import android.view.LayoutInflater; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; +import android.widget.TextView; + +import com.h6ah4i.android.widget.advrecyclerview.animator.GeneralItemAnimator; +import com.h6ah4i.android.widget.advrecyclerview.animator.SwipeDismissItemAnimator; +import com.h6ah4i.android.widget.advrecyclerview.draggable.DraggableItemAdapter; +import com.h6ah4i.android.widget.advrecyclerview.draggable.ItemDraggableRange; +import com.h6ah4i.android.widget.advrecyclerview.draggable.RecyclerViewDragDropManager; +import com.h6ah4i.android.widget.advrecyclerview.swipeable.RecyclerViewSwipeManager; +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.touchguard.RecyclerViewTouchActionGuardManager; +import com.h6ah4i.android.widget.advrecyclerview.utils.AbstractDraggableSwipeableItemViewHolder; +import com.hippo.app.EditTextDialogBuilder; +import com.hippo.easyrecyclerview.EasyRecyclerView; +import com.hippo.ehviewer.EhApplication; +import com.hippo.ehviewer.R; +import com.hippo.ehviewer.dao.DownloadLabelRaw; +import com.hippo.util.ActivityHelper; +import com.hippo.vector.VectorDrawable; +import com.hippo.view.ViewTransition; +import com.hippo.widget.SimpleImageView; +import com.hippo.yorozuya.ViewUtils; + +import java.util.List; + +public class DownloadLabelScene extends ToolbarScene { + + @Nullable + private EasyRecyclerView mRecyclerView; + @Nullable + private ViewTransition mViewTransition; + + @Nullable + private RecyclerView.Adapter mAdapter; + + @Nullable + public List mList = null; + + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + mList = EhApplication.getDownloadManager(getContext()).getLabelList(); + } + + @Override + public void onDestroy() { + super.onDestroy(); + mList = null; + } + + @SuppressWarnings("deprecation") + @Nullable + @Override + public View onCreateView2(LayoutInflater inflater, + @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.scene_download_label, container, false); + + mRecyclerView = (EasyRecyclerView) view.findViewById(R.id.recycler_view); + View tip = view.findViewById(R.id.tip); + SimpleImageView tipImage = (SimpleImageView) tip.findViewById(R.id.tip_image); + tipImage.setDrawable(VectorDrawable.create(getContext(), R.xml.sadpanda_head)); + mViewTransition = new ViewTransition(mRecyclerView, tip); + + if (mRecyclerView != null) { + // touch guard manager (this class is required to suppress scrolling while swipe-dismiss animation is running) + RecyclerViewTouchActionGuardManager guardManager = new RecyclerViewTouchActionGuardManager(); + guardManager.setInterceptVerticalScrollingWhileAnimationRunning(true); + guardManager.setEnabled(true); + + // drag & drop manager + RecyclerViewDragDropManager dragDropManager = new RecyclerViewDragDropManager(); + dragDropManager.setDraggingItemShadowDrawable( + (NinePatchDrawable) getResources().getDrawable(R.drawable.shadow_8dp)); + + // swipe manager + RecyclerViewSwipeManager swipeManager = new RecyclerViewSwipeManager(); + + RecyclerView.Adapter adapter = new LabelAdapter(); + adapter.setHasStableIds(true); + adapter = dragDropManager.createWrappedAdapter(adapter); // wrap for dragging + adapter = swipeManager.createWrappedAdapter(adapter); // wrap for swiping + mAdapter = adapter; + + final GeneralItemAnimator animator = new SwipeDismissItemAnimator(); + animator.setSupportsChangeAnimations(false); + + mRecyclerView.hasFixedSize(); + mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext())); + mRecyclerView.setAdapter(adapter); + mRecyclerView.setItemAnimator(animator); + + guardManager.attachRecyclerView(mRecyclerView); + swipeManager.attachRecyclerView(mRecyclerView); + dragDropManager.attachRecyclerView(mRecyclerView); + } + + updateView(); + + return view; + } + + @Override + public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + setTitle(R.string.label); + setNavigationIcon(VectorDrawable.create(getContext(), R.xml.ic_arrow_left_dark_x24)); + + // Clear nav checked item + setNavCheckedItem(0); + + // Hide IME + ActivityHelper.hideSoftInput(getActivity()); + } + + @Override + public void onNavigationClick() { + onBackPressed(); + } + + @Override + public int getMenuResId() { + return R.menu.scene_download_label; + } + + @Override + public boolean onMenuItemClick(MenuItem item) { + int id = item.getItemId(); + switch (id) { + case R.id.action_add: { + EditTextDialogBuilder builder = new EditTextDialogBuilder(getContext(), null, getString(R.string.label)); + builder.setTitle(R.string.new_label_title); + builder.setPositiveButton(android.R.string.ok, null); + AlertDialog dialog = builder.show(); + new NewLabelDialogHelper(builder, dialog); + } + } + return false; + } + + private void updateView() { + 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; + private final AlertDialog mDialog; + + public NewLabelDialogHelper(EditTextDialogBuilder builder, AlertDialog dialog) { + mBuilder = builder; + mDialog = dialog; + 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()).addLabel(text); + if (mAdapter != null && mList != null) { + mAdapter.notifyItemInserted(mList.size() - 1); + } + if (mViewTransition != null) { + if (mList != null && mList.size() > 0) { + mViewTransition.showView(0); + } else { + mViewTransition.showView(1); + } + } + } + } + } + + private class LabelHolder extends AbstractDraggableSwipeableItemViewHolder + implements View.OnClickListener { + + public final View swipeHandler; + public final TextView label; + public final View dragHandler; + + public LabelHolder(View itemView) { + super(itemView); + + swipeHandler = itemView.findViewById(R.id.swipe_handler); + label = (TextView) itemView.findViewById(R.id.label); + dragHandler = itemView.findViewById(R.id.drag_handler); + + label.setOnClickListener(this); + } + + @Override + public void onClick(View v) { + // TODO + } + + @Override + public View getSwipeableContainerView() { + return swipeHandler; + } + } + + private class LabelAdapter extends RecyclerView.Adapter + implements DraggableItemAdapter, + SwipeableItemAdapter { + + + @Override + public LabelHolder onCreateViewHolder(ViewGroup parent, int viewType) { + return new LabelHolder(getActivity().getLayoutInflater() + .inflate(R.layout.item_download_label, parent, false)); + } + + @Override + public void onBindViewHolder(LabelHolder holder, int position) { + if (mList != null) { + holder.label.setText(mList.get(position).getLabel()); + } + } + + @Override + public long getItemId(int position) { + return mList != null ? mList.get(position).getId() : 0; + } + + @Override + public int getItemCount() { + return mList != null ? mList.size() : 0; + } + + @Override + public boolean onCheckCanStartDrag(LabelHolder holder, int position, int x, int y) { + return ViewUtils.isViewUnder(holder.dragHandler, x, y, 0); + } + + @Override + public ItemDraggableRange onGetItemDraggableRange(LabelHolder holder, int position) { + return null; + } + + @Override + public void onMoveItem(int fromPosition, int toPosition) { + if (fromPosition == toPosition) { + return; + } + + EhApplication.getDownloadManager(getContext()).moveLabel(fromPosition, toPosition); + if (mAdapter != null && mList != null) { + notifyItemMoved(fromPosition, toPosition); + } + } + + @Override + public int onGetSwipeReactionType(LabelHolder holder, int position, int x, int y) { + return SwipeableItemConstants.REACTION_CAN_SWIPE_BOTH_H; + } + + @Override + public void onSetSwipeBackground(LabelHolder holder, int position, int type) { + // Empty + } + + @Override + public SwipeResultAction onSwipeItem(LabelHolder holder, int position, int result) { + switch (result) { + // swipe right + case SwipeableItemConstants.RESULT_SWIPED_RIGHT: + case SwipeableItemConstants.RESULT_SWIPED_LEFT: + return null; + case SwipeableItemConstants.RESULT_CANCELED: + default: + return null; + } + } + } +} 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 4175852f0..c0e0841e8 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 @@ -125,6 +125,14 @@ public class DownloadScene extends ToolbarScene } } + @Override + public void onDestroy() { + super.onDestroy(); + mList = null; + DownloadManager manager = EhApplication.getDownloadManager(getContext()); + manager.setDownloadInfoListener(null); + } + private void updateForLabel() { DownloadManager manager = EhApplication.getDownloadManager(getContext()); if (mLabel == null) { @@ -271,8 +279,6 @@ public class DownloadScene extends ToolbarScene public void onDestroyView() { super.onDestroyView(); - DownloadManager manager = EhApplication.getDownloadManager(getContext()); - manager.setDownloadInfoListener(null); mRecyclerView = null; mFabLayout = null; mViewTransition = null; @@ -293,7 +299,7 @@ public class DownloadScene extends ToolbarScene int id = item.getItemId(); switch (id) { case R.id.action_settings: - // TODO + startScene(new Announcer(DownloadLabelScene.class)); return true; } return false; @@ -338,12 +344,6 @@ public class DownloadScene extends ToolbarScene return view; } - @Override - public void onDestroy() { - super.onDestroy(); - mList = null; - } - @Override public void onBackPressed() { if (mRecyclerView != null && mRecyclerView.isInCustomChoice()) { @@ -546,6 +546,19 @@ public class DownloadScene extends ToolbarScene } } + @Override + public void onChange() { + mLabel = null; + 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/java/com/hippo/widget/ShadowLinearLayout.java b/app/src/main/java/com/hippo/widget/ShadowLinearLayout.java new file mode 100644 index 000000000..8db7a9f85 --- /dev/null +++ b/app/src/main/java/com/hippo/widget/ShadowLinearLayout.java @@ -0,0 +1,96 @@ +/* + * 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.widget; + +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Rect; +import android.graphics.drawable.NinePatchDrawable; +import android.os.Build; +import android.support.annotation.NonNull; +import android.util.AttributeSet; +import android.view.ViewOutlineProvider; +import android.widget.LinearLayout; + +import com.hippo.ehviewer.R; +import com.hippo.yorozuya.LayoutUtils; + +public class ShadowLinearLayout extends LinearLayout { + + private NinePatchDrawable mShadow; + private final Rect mShadowPaddings = new Rect(); + + public ShadowLinearLayout(Context context) { + super(context); + init(context); + } + + public ShadowLinearLayout(Context context, AttributeSet attrs) { + super(context, attrs); + init(context); + } + + public ShadowLinearLayout(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + init(context); + } + + private void init(Context context) { + // TODO not only 2dp + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + setOutlineProvider(ViewOutlineProvider.BOUNDS); + setElevation(LayoutUtils.dp2pix(context, 2)); + } else { + setShadow((NinePatchDrawable) context.getResources().getDrawable(R.drawable.shadow_2dp)); // TODO draktheme + } + } + + private void setShadow(NinePatchDrawable shadow) { + mShadow = shadow; + mShadow.getPadding(mShadowPaddings); + updateShadowBounds(); + setWillNotDraw(false); + } + + private void updateShadowBounds() { + NinePatchDrawable shadow = mShadow; + if (shadow == null) { + return; + } + + int width = getWidth(); + int height = getHeight(); + Rect paddings = mShadowPaddings; + if (width != 0 && height != 0) { + shadow.setBounds(-paddings.left, -paddings.top, width + paddings.right, height + paddings.bottom); + } + } + + @Override + protected void onLayout(boolean changed, int left, int top, int right, int bottom) { + super.onLayout(changed, left, top, right, bottom); + updateShadowBounds(); + } + + @Override + public void draw(@NonNull Canvas canvas) { + if (mShadow != null) { + mShadow.draw(canvas); + } + super.draw(canvas); + } +} diff --git a/app/src/main/res/drawable-hdpi/ic_add_dark_x24.png b/app/src/main/res/drawable-hdpi/ic_add_dark_x24.png new file mode 100644 index 0000000000000000000000000000000000000000..1da3b2146b09beb9719cf31622bb1745390ccecc GIT binary patch literal 124 zcmeAS@N?(olHy`uVBq!ia0vp^Dj>|k0wldT1B8K;v!{z=NCji^0cN*@8b98D*w4rz zt6|2G!NFnDBW02$ka?1y_Z_?R7J278jT8PJX=0lt?XvT_+hsvVgDe4CuK$4sTnssf WMHC{w=Q#n5WAJqKb6Mw<&;$T2cOt6* literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-mdpi/ic_add_dark_x24.png b/app/src/main/res/drawable-mdpi/ic_add_dark_x24.png new file mode 100644 index 0000000000000000000000000000000000000000..877dc286ae0ee27446ee00ad31208e7da06dada2 GIT binary patch literal 93 zcmeAS@N?(olHy`uVBq!ia0vp^5+KY7Bp6QcFoXgrrjj7PUFVdQ&MBb@07vc`*Z=?k literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxhdpi/shadow_2dp.9.png b/app/src/main/res/drawable-xxhdpi/shadow_2dp.9.png new file mode 100644 index 0000000000000000000000000000000000000000..0592d8ee6e01f1e11ea4e8425f09b3fbc317690d GIT binary patch literal 258 zcmV+d0sa1oP)x?7#z{Zx1S})fEr13CyCnstU=xwoAP1=}n_gz%5RvyRUA1zxg{*Px%TS-~~S94W8f*PL?d}X;+-48QP7(Ej5Q_uCm~?9XaO`n1G$f7Oa>+`?BK4 zf@RG+D48JRk~r&W`WSOfyU-LB*VB0z3IC`9q!eZ74gbP9U#>zKGdOVHxBvhE07*qo IM6N<$f@5fDzW@LL literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxhdpi/shadow_8dp.9.png b/app/src/main/res/drawable-xxhdpi/shadow_8dp.9.png new file mode 100644 index 0000000000000000000000000000000000000000..dd7755211b48454e71faf937f5f8eabdf4ab1afa GIT binary patch literal 981 zcmV;`11kK9P)u$m@423DD+ts!LIiwGdjV4A>fu^Jh{XPVD+1bjja>zL+5pqf(Go!hOW&q5v zeMo_zj*xfhr5tW{@d>anT6$;!uwxoq2q@ScaO z51&%RZVt%_gnWKHHOd^IDGg>xQHUS~1^{bw_2E-5G2~N%OaSuBXzKvo&|p@O0ui{{ z2T%?6A!&nxSO`TSZ})#huF$&+?ocx)RI} z=@-O*V_41Ag_u-**8<=Q`y9f~xq0>kWmpNCL8;Pe>W8*j36xcc*Yrr_=ME;(4M2Yt z{fO|NVfIVVkpkNG1s#K?G z3OVXC^SwZ2Y2qS(2GDOMFLB17p_cMw!WF7EP&w-lFrjWrnL@}5Or$Nn1IttGplh*o z@~VWecLh?0J%fVZ7$`2E9Datq0-%J%u&0(SUn8I#{v$cdz!v~S$Q;7HZUS^FcJmpz z!r_;&tP^ZT_TXj)tI`~n&`RZrSEksqS(dO;42f>0Fp;z~lsBkcLMH?|7vV?PoPabj zB)Z9Ak6}+bEVG1ao073|1VPvh084ExkO>?|tVQvodXMap0gx)5&4 zusgSTw(z5?oB|0PNf_9sH5`{UNOZI3)048fs=>}6XR!gX62j&KhdYLj$;jbm;5yHD z#JOn*u$%_5Xy+sr%>gh1ClRuAhtGBrMOe<+DKx@jha#m>HgtsC30egEDS+8wm&V{? zD0-!(A$_{b8nCNJ8VU!C8oH$$Wv*6um2Pw2(jtGkN9wv<@af%aef&l)9c_g7(B0s={700000NkvXXu0mjf D0o$_4 literal 0 HcmV?d00001 diff --git a/app/src/main/res/layout/dialog_edittext_builder.xml b/app/src/main/res/layout/dialog_edittext_builder.xml new file mode 100644 index 000000000..6f563bb9a --- /dev/null +++ b/app/src/main/res/layout/dialog_edittext_builder.xml @@ -0,0 +1,35 @@ + + + + + + + + diff --git a/app/src/main/res/layout/item_download_label.xml b/app/src/main/res/layout/item_download_label.xml new file mode 100644 index 000000000..b2ced5f02 --- /dev/null +++ b/app/src/main/res/layout/item_download_label.xml @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/scene_download_label.xml b/app/src/main/res/layout/scene_download_label.xml new file mode 100644 index 000000000..b495bbb20 --- /dev/null +++ b/app/src/main/res/layout/scene_download_label.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/scene_login.xml b/app/src/main/res/layout/scene_login.xml index 41a7a3b19..e1bd80899 100644 --- a/app/src/main/res/layout/scene_login.xml +++ b/app/src/main/res/layout/scene_login.xml @@ -48,7 +48,7 @@ android:layout_gravity="center_horizontal" android:minWidth="@dimen/single_max_width"> - - + + + + + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 0cc105e73..419a79f37 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -240,6 +240,14 @@ Move Label + + No labels + Add + New label + Label text is empty + \"Default\" is an invalid label + Label text exists + Page %d @string/refresh