From bfec83440c47f2bd6d581bbbffe86d842fdb397a Mon Sep 17 00:00:00 2001 From: Jay Date: Sat, 22 Feb 2020 15:20:11 -0800 Subject: [PATCH] Restored Select all functionality for single list and pager mode Mat white theme is now the default theme --- .../data/preference/PreferencesHelper.kt | 2 +- .../ui/library/LibraryCategoryAdapter.kt | 8 ++++ .../ui/library/LibraryCategoryView.kt | 8 ++-- .../tachiyomi/ui/library/LibraryController.kt | 8 ++-- .../tachiyomi/ui/library/LibraryHeaderItem.kt | 32 +++++++++++++++ .../ui/library/LibraryListController.kt | 40 ++++++++++++++----- .../tachiyomi/ui/library/LibraryPresenter.kt | 4 ++ .../drawable/ic_check_circle_white_24dp.xml | 5 +++ .../ic_radio_button_unchecked_white_24dp.xml | 5 +++ .../main/res/layout/filter_bottom_sheet.xml | 5 ++- .../layout/library_category_header_item.xml | 20 +++++++++- app/src/main/res/values/strings.xml | 2 +- 12 files changed, 116 insertions(+), 23 deletions(-) create mode 100644 app/src/main/res/drawable/ic_check_circle_white_24dp.xml create mode 100644 app/src/main/res/drawable/ic_radio_button_unchecked_white_24dp.xml diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt index f6840c9a30..008b7e0905 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt @@ -55,7 +55,7 @@ class PreferencesHelper(val context: Context) { fun clear() = prefs.edit().clear().apply() - fun theme() = prefs.getInt(Keys.theme, 5) + fun theme() = prefs.getInt(Keys.theme, 9) fun rotation() = rxPrefs.getInteger(Keys.rotation, 1) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryCategoryAdapter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryCategoryAdapter.kt index 1802ff5f22..7362b1e743 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryCategoryAdapter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryCategoryAdapter.kt @@ -67,6 +67,12 @@ class LibraryCategoryAdapter(val libraryListener: LibraryListener) : else false } } + fun getHeaderPositions(): List { + return currentItems.mapIndexedNotNull { index, it -> + if (it is LibraryHeaderItem) index + else null } + } + /** * Returns the position in the adapter for the given manga. * @@ -173,5 +179,7 @@ class LibraryCategoryAdapter(val libraryListener: LibraryListener) : fun canDrag(): Boolean fun updateCategory(catId: Int): Boolean fun sortCategory(catId: Int, sortBy: Int) + fun selectAll(position: Int) + fun allSelected(position: Int): Boolean } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryCategoryView.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryCategoryView.kt index 8cfdad1e14..34f6ddaa82 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryCategoryView.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryCategoryView.kt @@ -389,9 +389,9 @@ class LibraryCategoryView @JvmOverloads constructor(context: Context, attrs: Att controller.invalidateActionMode() } - override fun updateCategory(catId: Int): Boolean { - return true - } - + // unused for this view + override fun updateCategory(catId: Int): Boolean = true override fun sortCategory(catId: Int, sortBy: Int) { } + override fun selectAll(position: Int) { } + override fun allSelected(position: Int): Boolean = false } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt index 9c00b41f16..8e471f4e55 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt @@ -535,6 +535,8 @@ open class LibraryController( override fun onCreateActionMode(mode: ActionMode, menu: Menu): Boolean { mode.menuInflater.inflate(R.menu.library_selection, menu) + val selectItem = menu.findItem(R.id.action_select_all) + selectItem.isVisible = !preferences.libraryAsSingleList().getOrDefault() return true } @@ -568,11 +570,11 @@ open class LibraryController( .negativeButton(android.R.string.no) .show() } - /*R.id.action_select_all -> { - adapter?.categories?.getOrNull(library_pager.currentItem)?.id?.let { + R.id.action_select_all -> { + pagerAdapter?.categories?.getOrNull(library_pager.currentItem)?.id?.let { selectAllRelay.call(it) } - }*/ + } R.id.action_migrate -> { router.pushController( if (preferences.skipPreMigration().getOrDefault()) { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryHeaderItem.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryHeaderItem.kt index 5142554d8c..eedb5e6aa0 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryHeaderItem.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryHeaderItem.kt @@ -2,6 +2,7 @@ package eu.kanade.tachiyomi.ui.library import android.graphics.drawable.Drawable import android.view.View +import android.widget.ImageView import android.widget.ProgressBar import android.widget.TextView import androidx.appcompat.view.menu.MenuBuilder @@ -10,6 +11,7 @@ import androidx.core.content.ContextCompat import androidx.recyclerview.widget.RecyclerView import com.google.android.material.button.MaterialButton import eu.davidea.flexibleadapter.FlexibleAdapter +import eu.davidea.flexibleadapter.SelectableAdapter import eu.davidea.flexibleadapter.items.AbstractHeaderItem import eu.davidea.flexibleadapter.items.IFlexible import eu.davidea.viewholders.FlexibleViewHolder @@ -76,10 +78,12 @@ class LibraryHeaderItem(private val categoryF: (Int) -> Category, val catId: Int private val sortText: TextView = view.findViewById(R.id.category_sort) private val updateButton: MaterialButton = view.findViewById(R.id.update_button) private val catProgress: ProgressBar = view.findViewById(R.id.cat_progress) + private val checkboxImage: ImageView = view.findViewById(R.id.checkbox) init { updateButton.setOnClickListener { addCategoryToUpdate() } sortText.setOnClickListener { showCatSortOptions() } + checkboxImage.setOnClickListener { selectAll() } } fun bind(category: Category) { @@ -97,15 +101,24 @@ class LibraryHeaderItem(private val categoryF: (Int) -> Category, val catId: Int ) when { + adapter.mode == SelectableAdapter.Mode.MULTI -> { + checkboxImage.visible() + catProgress.gone() + updateButton.invisible() + setSelection() + } category.id == -1 -> { + checkboxImage.gone() catProgress.gone() updateButton.invisible() } LibraryUpdateService.categoryInQueue(category.id) -> { + checkboxImage.gone() catProgress.visible() updateButton.invisible() } else -> { + checkboxImage.gone() catProgress.gone() updateButton.visible() } @@ -195,5 +208,24 @@ class LibraryHeaderItem(private val categoryF: (Int) -> Category, val catId: Int } adapter.libraryListener.sortCategory(category.id!!, modType) } + + private fun selectAll() { + adapter.libraryListener.selectAll(adapterPosition) + } + + fun setSelection() { + val allSelected = adapter.libraryListener.allSelected(adapterPosition) + val drawable = + ContextCompat.getDrawable(contentView.context, + if (allSelected) R.drawable.ic_check_circle_white_24dp else + R.drawable.ic_radio_button_unchecked_white_24dp) + val tintedDrawable = drawable?.mutate() + tintedDrawable?.setTint(ContextCompat.getColor(contentView.context, + if (allSelected) R.color.colorAccent + else R.color.gray_button)) + checkboxImage.setImageDrawable(tintedDrawable) + } + + } } \ No newline at end of file diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryListController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryListController.kt index 8380233421..9a741b26ff 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryListController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryListController.kt @@ -177,6 +177,7 @@ class LibraryListController(bundle: Bundle? = null) : LibraryController(bundle), override fun onNextLibraryUpdate(mangaMap: List, freshStart: Boolean) { val recyclerLayout = recycler_layout ?: return + destroyActionModeIfNeeded() if (mangaMap.isNotEmpty()) { empty_view?.hide() } else { @@ -193,18 +194,22 @@ class LibraryListController(bundle: Bundle? = null) : LibraryController(bundle), spinner.setSelection(min(presenter.categories.size - 1, activeCategory + 1)) + updateScroll = false if (!freshStart) { justStarted = false if (recyclerLayout.alpha == 0f) recyclerLayout.animate().alpha(1f).setDuration(500).start() - }else { + } else if (justStarted) { val position = if (freshStart) adapter.indexOf(activeCategory) else null if (position != null) (recycler.layoutManager as LinearLayoutManager) .scrollToPositionWithOffset(position, (-30).dpToPx) } + else { + updateScroll = true + } adapter.isLongPressDragEnabled = canDrag() tabsVisibilityRelay.call(false) @@ -212,7 +217,6 @@ class LibraryListController(bundle: Bundle? = null) : LibraryController(bundle), activeCategory, 0, presenter.categories.size - 1 )] bottom_sheet.updateTitle() - updateScroll = false spinner.onItemSelectedListener = IgnoreFirstSpinnerListener { pos -> if (updateScroll) { updateScroll = false @@ -288,6 +292,14 @@ class LibraryListController(bundle: Bundle? = null) : LibraryController(bundle), } } } + updateHeaders() + } + + fun updateHeaders() { + val headerPositions = adapter.getHeaderPositions() + headerPositions.forEach { + adapter.notifyItemChanged(it) + } } override fun startReading(position: Int) { @@ -375,18 +387,12 @@ class LibraryListController(bundle: Bundle? = null) : LibraryController(bundle), else super.onUpdateManga(manga) } - /** - * Tells the presenter to set the selection for the given position. - * - * @param position the position to toggle. - */ - private fun setSelection(position: Int) { + private fun setSelection(position: Int, selected: Boolean = true) { val item = adapter.getItem(position) as? LibraryItem ?: return - setSelection(item.manga, true) + setSelection(item.manga, selected) invalidateActionMode() } - override fun onItemMove(fromPosition: Int, toPosition: Int) { if (lastItemPosition == toPosition) lastItemPosition = null @@ -480,4 +486,18 @@ class LibraryListController(bundle: Bundle? = null) : LibraryController(bundle), override fun sortCategory(catId: Int, sortBy: Int) { presenter.sortCategory(catId, sortBy) } + + override fun selectAll(position: Int) { + val header = adapter.getSectionHeader(position) ?: return + val items = adapter.getSectionItemPositions(header) + val allSelected = allSelected(position) + for (i in items) + setSelection(i, !allSelected) + } + + override fun allSelected(position: Int): Boolean { + val header = adapter.getSectionHeader(position) ?: return false + val items = adapter.getSectionItemPositions(header) + return items.all { adapter.isSelected(it) } + } } \ No newline at end of file diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryPresenter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryPresenter.kt index 69d8869b03..2758280af0 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryPresenter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryPresenter.kt @@ -1,5 +1,6 @@ package eu.kanade.tachiyomi.ui.library +import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.cache.CoverCache import eu.kanade.tachiyomi.data.database.DatabaseHelper import eu.kanade.tachiyomi.data.database.models.Category @@ -469,6 +470,9 @@ class LibraryPresenter( if (libraryMap.containsKey(0)) categories.add(0, createDefaultCategory()) + if (categories.size == 1 && showCategories) + categories.first().name = context.getString(R.string.label_library) + this.allCategories = categories this.categories = if (!showCategories) arrayListOf(categoryAll) else categories diff --git a/app/src/main/res/drawable/ic_check_circle_white_24dp.xml b/app/src/main/res/drawable/ic_check_circle_white_24dp.xml new file mode 100644 index 0000000000..7cdc15de00 --- /dev/null +++ b/app/src/main/res/drawable/ic_check_circle_white_24dp.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/drawable/ic_radio_button_unchecked_white_24dp.xml b/app/src/main/res/drawable/ic_radio_button_unchecked_white_24dp.xml new file mode 100644 index 0000000000..8d1f811530 --- /dev/null +++ b/app/src/main/res/drawable/ic_radio_button_unchecked_white_24dp.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/layout/filter_bottom_sheet.xml b/app/src/main/res/layout/filter_bottom_sheet.xml index 9dd3d29731..6860d7af16 100644 --- a/app/src/main/res/layout/filter_bottom_sheet.xml +++ b/app/src/main/res/layout/filter_bottom_sheet.xml @@ -32,6 +32,7 @@ android:clipToPadding="false" android:paddingStart="20dp" android:paddingTop="10dp" + android:paddingBottom="18dp" android:paddingEnd="20dp" android:scrollbars="none"> @@ -63,7 +64,7 @@ android:id="@+id/side_layout" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginTop="16dp" + android:layout_marginTop="0dp" android:paddingStart="23dp" android:paddingEnd="20dp" android:baselineAligned="true" @@ -189,7 +190,7 @@ android:id="@+id/top_bar" android:layout_width="match_parent" android:layout_height="wrap_content" - tools:visibility="visible" + tools:visibility="gone" android:background="@drawable/bg_bottom_sheet_primary" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" diff --git a/app/src/main/res/layout/library_category_header_item.xml b/app/src/main/res/layout/library_category_header_item.xml index ae41ccb0fa..20e81e0b75 100644 --- a/app/src/main/res/layout/library_category_header_item.xml +++ b/app/src/main/res/layout/library_category_header_item.xml @@ -31,7 +31,6 @@ android:layout_height="wrap_content" android:layout_marginEnd="10dp" android:layout_marginBottom="4dp" - android:background="@drawable/square_ripple" android:clickable="true" android:drawableEnd="@drawable/ic_sort_white_24dp" android:drawablePadding="6dp" @@ -51,7 +50,7 @@ app:layout_constraintHorizontal_bias="1.0" app:layout_constraintStart_toEndOf="@id/space" app:layout_constraintWidth_min="20dp" - tools:text="Drag wddf Drop" /> + tools:text="Drag and Drop" /> + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 3e784d4eb9..28076c7a04 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -200,7 +200,7 @@ Sync chapters after reading Sort by ignoring articles Show library as a single list - Show all categories under a single + Show all categories under a single, sectioned list When sorting alphabetically, sort ignoring articles (a, an, the) at the start of manga titles