From c5c907c8dcb40e3f2d093d380cc058b9c6b7f1b5 Mon Sep 17 00:00:00 2001 From: Koitharu Date: Wed, 2 Aug 2023 16:45:01 +0300 Subject: [PATCH] UI improvements --- .../kotatsu/details/ui/DetailsActivity.kt | 48 ++++++++------ .../kotatsu/details/ui/DetailsMenuProvider.kt | 4 +- .../explore/ui/model/RecommendationsItem.kt | 16 +---- ...teCategoriesSheet.kt => FavouriteSheet.kt} | 6 +- .../select/MangaCategoriesViewModel.kt | 5 +- .../select/adapter/MangaCategoryAD.kt | 15 +++-- .../select/model/MangaCategoryItem.kt | 26 ++------ .../kotatsu/list/ui/MangaListFragment.kt | 4 +- .../search/ui/multi/MultiSearchActivity.kt | 4 +- app/src/main/res/drawable/ic_notification.xml | 2 +- .../res/layout/item_category_checkable.xml | 66 +++++++++++++++++++ .../main/res/layout/item_header_button.xml | 4 +- app/src/main/res/values/styles.xml | 6 ++ 13 files changed, 128 insertions(+), 78 deletions(-) rename app/src/main/kotlin/org/koitharu/kotatsu/favourites/ui/categories/select/{FavouriteCategoriesSheet.kt => FavouriteSheet.kt} (95%) create mode 100644 app/src/main/res/layout/item_category_checkable.xml diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/DetailsActivity.kt b/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/DetailsActivity.kt index c828e93a4..b03b19521 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/DetailsActivity.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/DetailsActivity.kt @@ -1,13 +1,16 @@ package org.koitharu.kotatsu.details.ui import android.content.Context -import android.content.DialogInterface import android.content.Intent +import android.graphics.Color import android.os.Bundle +import android.text.style.ForegroundColorSpan +import android.text.style.RelativeSizeSpan import android.transition.AutoTransition import android.transition.Slide import android.transition.TransitionManager import android.view.Gravity +import android.view.Menu import android.view.MenuItem import android.view.View import android.view.ViewGroup @@ -17,6 +20,8 @@ import android.widget.Toast import androidx.activity.viewModels import androidx.appcompat.widget.PopupMenu import androidx.core.graphics.Insets +import androidx.core.text.buildSpannedString +import androidx.core.text.inSpans import androidx.core.view.isGone import androidx.core.view.isVisible import androidx.core.view.updateLayoutParams @@ -33,12 +38,11 @@ import org.koitharu.kotatsu.core.model.parcelable.ParcelableManga import org.koitharu.kotatsu.core.os.AppShortcutManager import org.koitharu.kotatsu.core.parser.MangaIntent import org.koitharu.kotatsu.core.ui.BaseActivity -import org.koitharu.kotatsu.core.ui.dialog.RecyclerViewAlertDialog -import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener import org.koitharu.kotatsu.core.ui.util.MenuInvalidator import org.koitharu.kotatsu.core.util.ViewBadge import org.koitharu.kotatsu.core.util.ext.doOnExpansionsChanged import org.koitharu.kotatsu.core.util.ext.getAnimationDuration +import org.koitharu.kotatsu.core.util.ext.getThemeColor import org.koitharu.kotatsu.core.util.ext.isAnimationsEnabled import org.koitharu.kotatsu.core.util.ext.measureHeight import org.koitharu.kotatsu.core.util.ext.observe @@ -48,10 +52,8 @@ import org.koitharu.kotatsu.core.util.ext.setNavigationIconSafe import org.koitharu.kotatsu.core.util.ext.textAndVisible import org.koitharu.kotatsu.databinding.ActivityDetailsBinding import org.koitharu.kotatsu.details.service.MangaPrefetchService -import org.koitharu.kotatsu.details.ui.adapter.branchAD import org.koitharu.kotatsu.details.ui.model.ChapterListItem import org.koitharu.kotatsu.details.ui.model.HistoryInfo -import org.koitharu.kotatsu.details.ui.model.MangaBranch import org.koitharu.kotatsu.download.ui.worker.DownloadStartedObserver import org.koitharu.kotatsu.main.ui.owners.NoModalBottomSheetOwner import org.koitharu.kotatsu.parsers.model.Manga @@ -157,7 +159,7 @@ class DetailsActivity : override fun onClick(v: View) { when (v.id) { R.id.button_read -> openReader(isIncognitoMode = false) - R.id.button_dropdown -> showBranchPopupMenu() + R.id.button_dropdown -> showBranchPopupMenu(v) } } @@ -275,20 +277,28 @@ class DetailsActivity : viewBadge.counter = newChapters } - private fun showBranchPopupMenu() { - var dialog: DialogInterface? = null - val listener = OnListItemClickListener { item, _ -> - viewModel.setSelectedBranch(item.name) - dialog?.dismiss() + private fun showBranchPopupMenu(v: View) { + val menu = PopupMenu(v.context, v) + val branches = viewModel.branches.value + for ((i, branch) in branches.withIndex()) { + val title = buildSpannedString { + append(branch.name ?: getString(R.string.system_default)) + append(' ') + append(' ') + inSpans( + ForegroundColorSpan(v.context.getThemeColor(android.R.attr.textColorSecondary, Color.LTGRAY)), + RelativeSizeSpan(0.74f), + ) { + append(branch.count.toString()) + } + } + menu.menu.add(Menu.NONE, Menu.NONE, i, title) } - dialog = RecyclerViewAlertDialog.Builder(this) - .addAdapterDelegate(branchAD(listener)) - .setCancelable(true) - .setNegativeButton(android.R.string.cancel, null) - .setTitle(R.string.translations) - .setItems(viewModel.branches.value) - .create() - .also { it.show() } + menu.setOnMenuItemClickListener { + viewModel.setSelectedBranch(branches.getOrNull(it.order)?.name) + true + } + menu.show() } private fun openReader(isIncognitoMode: Boolean) { diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/DetailsMenuProvider.kt b/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/DetailsMenuProvider.kt index 4832e24a7..b18df6945 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/DetailsMenuProvider.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/DetailsMenuProvider.kt @@ -19,7 +19,7 @@ import org.koitharu.kotatsu.core.os.AppShortcutManager import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener import org.koitharu.kotatsu.core.util.ShareHelper import org.koitharu.kotatsu.download.ui.dialog.DownloadOption -import org.koitharu.kotatsu.favourites.ui.categories.select.FavouriteCategoriesSheet +import org.koitharu.kotatsu.favourites.ui.categories.select.FavouriteSheet import org.koitharu.kotatsu.parsers.model.MangaSource import org.koitharu.kotatsu.scrobbling.common.ui.selector.ScrobblingSelectorSheet import org.koitharu.kotatsu.search.ui.multi.MultiSearchActivity @@ -62,7 +62,7 @@ class DetailsMenuProvider( R.id.action_favourite -> { viewModel.manga.value?.let { - FavouriteCategoriesSheet.show(activity.supportFragmentManager, it) + FavouriteSheet.show(activity.supportFragmentManager, it) } } diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/explore/ui/model/RecommendationsItem.kt b/app/src/main/kotlin/org/koitharu/kotatsu/explore/ui/model/RecommendationsItem.kt index c43ba785d..9876def1f 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/explore/ui/model/RecommendationsItem.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/explore/ui/model/RecommendationsItem.kt @@ -3,7 +3,7 @@ package org.koitharu.kotatsu.explore.ui.model import org.koitharu.kotatsu.list.ui.model.ListModel import org.koitharu.kotatsu.parsers.model.Manga -class RecommendationsItem( +data class RecommendationsItem( val manga: Manga ) : ListModel { @@ -12,18 +12,4 @@ class RecommendationsItem( override fun areItemsTheSame(other: ListModel): Boolean { return other is RecommendationsItem } - - override fun equals(other: Any?): Boolean { - if (this === other) return true - if (javaClass != other?.javaClass) return false - - other as RecommendationsItem - - return manga == other.manga - } - - override fun hashCode(): Int { - return 31 * manga.hashCode() - } - } diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/favourites/ui/categories/select/FavouriteCategoriesSheet.kt b/app/src/main/kotlin/org/koitharu/kotatsu/favourites/ui/categories/select/FavouriteSheet.kt similarity index 95% rename from app/src/main/kotlin/org/koitharu/kotatsu/favourites/ui/categories/select/FavouriteCategoriesSheet.kt rename to app/src/main/kotlin/org/koitharu/kotatsu/favourites/ui/categories/select/FavouriteSheet.kt index 102abab0d..e79f9fcf7 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/favourites/ui/categories/select/FavouriteCategoriesSheet.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/favourites/ui/categories/select/FavouriteSheet.kt @@ -23,7 +23,7 @@ import org.koitharu.kotatsu.list.ui.model.ListModel import org.koitharu.kotatsu.parsers.model.Manga @AndroidEntryPoint -class FavouriteCategoriesSheet : +class FavouriteSheet : BaseAdaptiveSheet(), OnListItemClickListener { @@ -53,7 +53,7 @@ class FavouriteCategoriesSheet : } override fun onItemClick(item: MangaCategoryItem, view: View) { - viewModel.setChecked(item.id, !item.isChecked) + viewModel.setChecked(item.category.id, !item.isChecked) } private fun onContentChanged(categories: List) { @@ -72,7 +72,7 @@ class FavouriteCategoriesSheet : fun show(fm: FragmentManager, manga: Manga) = Companion.show(fm, listOf(manga)) fun show(fm: FragmentManager, manga: Collection) = - FavouriteCategoriesSheet().withArgs(1) { + FavouriteSheet().withArgs(1) { putParcelableArrayList( KEY_MANGA_LIST, manga.mapTo(ArrayList(manga.size)) { diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/favourites/ui/categories/select/MangaCategoriesViewModel.kt b/app/src/main/kotlin/org/koitharu/kotatsu/favourites/ui/categories/select/MangaCategoriesViewModel.kt index 5f6566ceb..2603d5fbe 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/favourites/ui/categories/select/MangaCategoriesViewModel.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/favourites/ui/categories/select/MangaCategoriesViewModel.kt @@ -14,7 +14,7 @@ import org.koitharu.kotatsu.core.model.parcelable.ParcelableManga import org.koitharu.kotatsu.core.ui.BaseViewModel import org.koitharu.kotatsu.core.util.ext.require import org.koitharu.kotatsu.favourites.domain.FavouritesRepository -import org.koitharu.kotatsu.favourites.ui.categories.select.FavouriteCategoriesSheet.Companion.KEY_MANGA_LIST +import org.koitharu.kotatsu.favourites.ui.categories.select.FavouriteSheet.Companion.KEY_MANGA_LIST import org.koitharu.kotatsu.favourites.ui.categories.select.model.CategoriesHeaderItem import org.koitharu.kotatsu.favourites.ui.categories.select.model.MangaCategoryItem import org.koitharu.kotatsu.list.ui.model.ListModel @@ -37,8 +37,7 @@ class MangaCategoriesViewModel @Inject constructor( add(header) all.mapTo(this) { MangaCategoryItem( - id = it.id, - name = it.title, + category = it, isChecked = it.id in checked, ) } diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/favourites/ui/categories/select/adapter/MangaCategoryAD.kt b/app/src/main/kotlin/org/koitharu/kotatsu/favourites/ui/categories/select/adapter/MangaCategoryAD.kt index aaf5b358d..cb21837a6 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/favourites/ui/categories/select/adapter/MangaCategoryAD.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/favourites/ui/categories/select/adapter/MangaCategoryAD.kt @@ -1,17 +1,18 @@ package org.koitharu.kotatsu.favourites.ui.categories.select.adapter +import androidx.core.view.isVisible import com.hannesdorfmann.adapterdelegates4.dsl.adapterDelegateViewBinding import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener import org.koitharu.kotatsu.core.util.ext.setChecked -import org.koitharu.kotatsu.databinding.ItemCheckableNewBinding +import org.koitharu.kotatsu.databinding.ItemCategoryCheckableBinding import org.koitharu.kotatsu.favourites.ui.categories.select.model.MangaCategoryItem import org.koitharu.kotatsu.list.ui.ListModelDiffCallback import org.koitharu.kotatsu.list.ui.model.ListModel fun mangaCategoryAD( clickListener: OnListItemClickListener, -) = adapterDelegateViewBinding( - { inflater, parent -> ItemCheckableNewBinding.inflate(inflater, parent, false) }, +) = adapterDelegateViewBinding( + { inflater, parent -> ItemCategoryCheckableBinding.inflate(inflater, parent, false) }, ) { itemView.setOnClickListener { @@ -19,9 +20,9 @@ fun mangaCategoryAD( } bind { payloads -> - with(binding.root) { - text = item.name - setChecked(item.isChecked, ListModelDiffCallback.PAYLOAD_CHECKED_CHANGED in payloads) - } + binding.checkableImageView.setChecked(item.isChecked, ListModelDiffCallback.PAYLOAD_CHECKED_CHANGED !in payloads) + binding.textViewTitle.text = item.category.title + binding.imageViewTracker.isVisible = item.category.isTrackingEnabled + binding.imageViewVisible.isVisible = item.category.isVisibleInLibrary } } diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/favourites/ui/categories/select/model/MangaCategoryItem.kt b/app/src/main/kotlin/org/koitharu/kotatsu/favourites/ui/categories/select/model/MangaCategoryItem.kt index d75fbad8a..29c78a142 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/favourites/ui/categories/select/model/MangaCategoryItem.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/favourites/ui/categories/select/model/MangaCategoryItem.kt @@ -1,16 +1,16 @@ package org.koitharu.kotatsu.favourites.ui.categories.select.model +import org.koitharu.kotatsu.core.model.FavouriteCategory import org.koitharu.kotatsu.list.ui.ListModelDiffCallback import org.koitharu.kotatsu.list.ui.model.ListModel -class MangaCategoryItem( - val id: Long, - val name: String, +data class MangaCategoryItem( + val category: FavouriteCategory, val isChecked: Boolean, ) : ListModel { override fun areItemsTheSame(other: ListModel): Boolean { - return other is MangaCategoryItem && other.id == id + return other is MangaCategoryItem && other.category.id == category.id } override fun getChangePayload(previousState: ListModel): Any? { @@ -20,22 +20,4 @@ class MangaCategoryItem( super.getChangePayload(previousState) } } - - override fun equals(other: Any?): Boolean { - if (this === other) return true - if (javaClass != other?.javaClass) return false - - other as MangaCategoryItem - - if (id != other.id) return false - if (name != other.name) return false - return isChecked == other.isChecked - } - - override fun hashCode(): Int { - var result = id.hashCode() - result = 31 * result + name.hashCode() - result = 31 * result + isChecked.hashCode() - return result - } } diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/list/ui/MangaListFragment.kt b/app/src/main/kotlin/org/koitharu/kotatsu/list/ui/MangaListFragment.kt index 39b7f03be..bb65f865a 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/list/ui/MangaListFragment.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/list/ui/MangaListFragment.kt @@ -41,7 +41,7 @@ import org.koitharu.kotatsu.core.util.ext.viewLifecycleScope import org.koitharu.kotatsu.databinding.FragmentListBinding import org.koitharu.kotatsu.details.ui.DetailsActivity import org.koitharu.kotatsu.download.ui.worker.DownloadStartedObserver -import org.koitharu.kotatsu.favourites.ui.categories.select.FavouriteCategoriesSheet +import org.koitharu.kotatsu.favourites.ui.categories.select.FavouriteSheet import org.koitharu.kotatsu.list.ui.adapter.ListItemType import org.koitharu.kotatsu.list.ui.adapter.MangaListAdapter import org.koitharu.kotatsu.list.ui.adapter.MangaListListener @@ -283,7 +283,7 @@ abstract class MangaListFragment : } R.id.action_favourite -> { - FavouriteCategoriesSheet.show(childFragmentManager, selectedItems) + FavouriteSheet.show(childFragmentManager, selectedItems) mode.finish() true } diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/search/ui/multi/MultiSearchActivity.kt b/app/src/main/kotlin/org/koitharu/kotatsu/search/ui/multi/MultiSearchActivity.kt index 3e1ca30ab..0f230118a 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/search/ui/multi/MultiSearchActivity.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/search/ui/multi/MultiSearchActivity.kt @@ -27,7 +27,7 @@ import org.koitharu.kotatsu.core.util.ext.scaleUpActivityOptionsOf import org.koitharu.kotatsu.databinding.ActivitySearchMultiBinding import org.koitharu.kotatsu.details.ui.DetailsActivity import org.koitharu.kotatsu.download.ui.worker.DownloadStartedObserver -import org.koitharu.kotatsu.favourites.ui.categories.select.FavouriteCategoriesSheet +import org.koitharu.kotatsu.favourites.ui.categories.select.FavouriteSheet import org.koitharu.kotatsu.list.ui.MangaSelectionDecoration import org.koitharu.kotatsu.list.ui.adapter.MangaListListener import org.koitharu.kotatsu.list.ui.model.ListHeader @@ -159,7 +159,7 @@ class MultiSearchActivity : } R.id.action_favourite -> { - FavouriteCategoriesSheet.show(supportFragmentManager, collectSelectedItems()) + FavouriteSheet.show(supportFragmentManager, collectSelectedItems()) mode.finish() true } diff --git a/app/src/main/res/drawable/ic_notification.xml b/app/src/main/res/drawable/ic_notification.xml index 1bbf44939..d0a13e6d2 100644 --- a/app/src/main/res/drawable/ic_notification.xml +++ b/app/src/main/res/drawable/ic_notification.xml @@ -2,7 +2,7 @@ xmlns:android="http://schemas.android.com/apk/res/android" android:width="24dp" android:height="24dp" - android:tint="#000000" + android:tint="?colorControlNormal" android:viewportWidth="24" android:viewportHeight="24"> + + + + + + + + + + + diff --git a/app/src/main/res/layout/item_header_button.xml b/app/src/main/res/layout/item_header_button.xml index 3dab28955..cddfe3ac7 100644 --- a/app/src/main/res/layout/item_header_button.xml +++ b/app/src/main/res/layout/item_header_button.xml @@ -18,9 +18,9 @@ android:textAppearance="@style/TextAppearance.Kotatsu.SectionHeader" tools:text="@tools:sample/lorem[2]" /> -