From 94ef64c4b7b8143e7f68193f24d8b8710b1893a1 Mon Sep 17 00:00:00 2001 From: Koitharu Date: Sun, 11 May 2025 18:46:05 +0300 Subject: [PATCH] Improve mouse interaction --- .../kotatsu/details/ui/DetailsActivity.kt | 4 ++++ .../download/ui/dialog/DestinationsAdapter.kt | 2 +- .../ui/adapter/ExploreAdapterDelegates.kt | 16 +++++++++++++++- .../history/ui/util/ReadingProgressView.kt | 4 ++-- .../kotatsu/list/domain/ReadingProgress.kt | 6 ++++++ .../kotatsu/list/ui/adapter/MangaGridItemAD.kt | 2 ++ .../kotatsu/list/ui/adapter/MangaListItemAD.kt | 2 ++ .../kotatsu/list/ui/model/MangaListModel.kt | 16 ++++++++++++++++ .../kotatsu/reader/ui/ReaderActionsView.kt | 5 +++-- .../adapter/SearchSuggestionsMangaListAD.kt | 2 ++ .../storage/directories/DirectoryConfigAD.kt | 8 +++++--- app/src/main/res/layout/item_categories_all.xml | 2 +- app/src/main/res/layout/item_category.xml | 5 ++++- app/src/main/res/layout/item_storage_config.xml | 4 ++-- app/src/main/res/values/themes.xml | 1 - 15 files changed, 65 insertions(+), 14 deletions(-) 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 4fd4c0212..de58df8e5 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 @@ -9,9 +9,11 @@ import android.view.ViewGroup import android.view.ViewTreeObserver import android.widget.Toast import androidx.activity.viewModels +import androidx.appcompat.widget.TooltipCompat import androidx.core.text.buildSpannedString import androidx.core.text.inSpans import androidx.core.text.method.LinkMovementMethodCompat +import androidx.core.view.ViewCompat import androidx.core.view.WindowInsetsCompat import androidx.core.view.isGone import androidx.core.view.isVisible @@ -43,6 +45,7 @@ import org.koitharu.kotatsu.core.image.CoilMemoryCacheKey import org.koitharu.kotatsu.core.model.FavouriteCategory import org.koitharu.kotatsu.core.model.LocalMangaSource import org.koitharu.kotatsu.core.model.UnknownMangaSource +import org.koitharu.kotatsu.core.model.getSummary import org.koitharu.kotatsu.core.model.getTitle import org.koitharu.kotatsu.core.model.titleResId import org.koitharu.kotatsu.core.nav.ReaderIntent @@ -426,6 +429,7 @@ class DetailsActivity : textViewSourceLabel.isVisible = false } else { textViewSource.textAndVisible = manga.source.getTitle(this@DetailsActivity) + TooltipCompat.setTooltipText(textViewSource, manga.source.getSummary(this@DetailsActivity)) textViewSourceLabel.isVisible = textViewSource.isVisible == true } val faviconPlaceholderFactory = FaviconDrawable.Factory(R.style.FaviconDrawable_Chip) diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/download/ui/dialog/DestinationsAdapter.kt b/app/src/main/kotlin/org/koitharu/kotatsu/download/ui/dialog/DestinationsAdapter.kt index bb9a34b88..12b8b7578 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/download/ui/dialog/DestinationsAdapter.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/download/ui/dialog/DestinationsAdapter.kt @@ -33,7 +33,7 @@ class DestinationsAdapter(context: Context, dataset: List) : val item = getItem(position) ?: return view val binding = view.tag as? ItemStorageConfigBinding ?: ItemStorageConfigBinding.bind(view).also { view.tag = it } - binding.imageViewRemove.isVisible = false + binding.buttonRemove.isVisible = false binding.textViewTitle.text = item.title ?: view.context.getString(item.titleRes) binding.textViewSubtitle.textAndVisible = item.file?.path return view diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/explore/ui/adapter/ExploreAdapterDelegates.kt b/app/src/main/kotlin/org/koitharu/kotatsu/explore/ui/adapter/ExploreAdapterDelegates.kt index ae72de2a6..c55797c4a 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/explore/ui/adapter/ExploreAdapterDelegates.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/explore/ui/adapter/ExploreAdapterDelegates.kt @@ -1,7 +1,10 @@ package org.koitharu.kotatsu.explore.ui.adapter import android.view.View +import androidx.appcompat.widget.TooltipCompat import androidx.core.content.ContextCompat +import androidx.core.text.bold +import androidx.core.text.buildSpannedString import com.hannesdorfmann.adapterdelegates4.dsl.adapterDelegateViewBinding import org.koitharu.kotatsu.R import org.koitharu.kotatsu.core.model.getSummary @@ -122,7 +125,18 @@ fun exploreSourceGridItemAD( val iconPinned = ContextCompat.getDrawable(context, R.drawable.ic_pin_small) bind { - binding.textViewTitle.text = item.source.getTitle(context) + val title = item.source.getTitle(context) + TooltipCompat.setTooltipText( + itemView, + buildSpannedString { + bold { + append(title) + } + appendLine() + append(item.source.getSummary(context)) + }, + ) + binding.textViewTitle.text = title binding.textViewTitle.drawableStart = if (item.source.isPinned) iconPinned else null binding.imageViewIcon.setImageAsync(item.source) } diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/history/ui/util/ReadingProgressView.kt b/app/src/main/kotlin/org/koitharu/kotatsu/history/ui/util/ReadingProgressView.kt index 1f9c0fe63..9d2ffb752 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/history/ui/util/ReadingProgressView.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/history/ui/util/ReadingProgressView.kt @@ -43,8 +43,8 @@ class ReadingProgressView @JvmOverloads constructor( null, NONE -> "" - PERCENT_READ -> percentPattern.format((value.percent * 100f).toInt().toString()) - PERCENT_LEFT -> "-" + percentPattern.format((value.percentLeft * 100f).toInt().toString()) + PERCENT_READ -> percentPattern.format(ReadingProgress.percentToString(value.percent)) + PERCENT_LEFT -> "-" + percentPattern.format(ReadingProgress.percentToString(value.percentLeft)) CHAPTERS_READ -> value.chapters.toString() CHAPTERS_LEFT -> "-" + value.chaptersLeft.toString() diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/list/domain/ReadingProgress.kt b/app/src/main/kotlin/org/koitharu/kotatsu/list/domain/ReadingProgress.kt index e836e0966..17096c945 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/list/domain/ReadingProgress.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/list/domain/ReadingProgress.kt @@ -44,5 +44,11 @@ data class ReadingProgress( fun isValid(percent: Float) = percent in 0f..1f fun isCompleted(percent: Float) = percent >= PROGRESS_COMPLETED_THRESHOLD + + fun percentToString(percent: Float): String = if (isValid(percent)) { + if (isCompleted(percent)) "100" else (percent * 100f).toInt().toString() + } else { + "0" + } } } diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/list/ui/adapter/MangaGridItemAD.kt b/app/src/main/kotlin/org/koitharu/kotatsu/list/ui/adapter/MangaGridItemAD.kt index a4e4abfaa..9a9944c98 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/list/ui/adapter/MangaGridItemAD.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/list/ui/adapter/MangaGridItemAD.kt @@ -1,5 +1,6 @@ package org.koitharu.kotatsu.list.ui.adapter +import androidx.appcompat.widget.TooltipCompat import androidx.core.view.isVisible import com.hannesdorfmann.adapterdelegates4.dsl.adapterDelegateViewBinding import org.koitharu.kotatsu.R @@ -23,6 +24,7 @@ fun mangaGridItemAD( sizeResolver.attachToView(itemView, binding.textViewTitle, binding.progressView) bind { payloads -> + TooltipCompat.setTooltipText(itemView, item.getSummary(context)) binding.textViewTitle.text = item.title binding.progressView.setProgress(item.progress, PAYLOAD_PROGRESS_CHANGED in payloads) with(binding.iconsView) { diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/list/ui/adapter/MangaListItemAD.kt b/app/src/main/kotlin/org/koitharu/kotatsu/list/ui/adapter/MangaListItemAD.kt index a58a1cf12..5c7649dbe 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/list/ui/adapter/MangaListItemAD.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/list/ui/adapter/MangaListItemAD.kt @@ -1,5 +1,6 @@ package org.koitharu.kotatsu.list.ui.adapter +import androidx.appcompat.widget.TooltipCompat import androidx.core.view.isVisible import com.hannesdorfmann.adapterdelegates4.dsl.adapterDelegateViewBinding import org.koitharu.kotatsu.core.ui.list.AdapterDelegateClickListenerAdapter @@ -19,6 +20,7 @@ fun mangaListItemAD( AdapterDelegateClickListenerAdapter(this, clickListener, MangaCompactListModel::manga).attach(itemView) bind { + TooltipCompat.setTooltipText(itemView, item.getSummary(context)) binding.textViewTitle.text = item.title binding.textViewSubtitle.textAndVisible = item.subtitle binding.imageViewCover.setImageAsync(item.coverUrl, item.manga) diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/list/ui/model/MangaListModel.kt b/app/src/main/kotlin/org/koitharu/kotatsu/list/ui/model/MangaListModel.kt index 1be7efdd6..e5a40aec6 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/list/ui/model/MangaListModel.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/list/ui/model/MangaListModel.kt @@ -1,5 +1,9 @@ package org.koitharu.kotatsu.list.ui.model +import android.content.Context +import androidx.core.text.bold +import androidx.core.text.buildSpannedString +import org.koitharu.kotatsu.core.model.getTitle import org.koitharu.kotatsu.list.ui.ListModelDiffCallback.Companion.PAYLOAD_ANYTHING_CHANGED import org.koitharu.kotatsu.parsers.model.Manga import org.koitharu.kotatsu.parsers.model.MangaSource @@ -15,6 +19,18 @@ sealed class MangaListModel : ListModel { val source: MangaSource get() = manga.source + open fun getSummary(context: Context): CharSequence = buildSpannedString { + bold { + append(manga.title) + } + appendLine() + if (manga.tags.isNotEmpty()) { + manga.tags.joinTo(this) { it.title } + appendLine() + } + append(manga.source.getTitle(context)) + } + override fun areItemsTheSame(other: ListModel): Boolean { return other is MangaListModel && other.javaClass == javaClass && id == other.id } diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/ReaderActionsView.kt b/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/ReaderActionsView.kt index 53062c990..77da043ca 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/ReaderActionsView.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/ReaderActionsView.kt @@ -13,6 +13,7 @@ import android.widget.FrameLayout import android.widget.LinearLayout import androidx.annotation.AttrRes import androidx.annotation.StringRes +import androidx.appcompat.widget.TooltipCompat import androidx.core.view.ViewCompat import androidx.core.view.isVisible import androidx.core.view.updateLayoutParams @@ -253,13 +254,13 @@ class ReaderActionsView @JvmOverloads constructor( private fun Button.initAction() { setOnClickListener(this@ReaderActionsView) setOnLongClickListener(this@ReaderActionsView) - ViewCompat.setTooltipText(this, contentDescription) + TooltipCompat.setTooltipText(this, contentDescription) } private fun Button.setTitle(@StringRes titleResId: Int) { val text = resources.getString(titleResId) contentDescription = text - ViewCompat.setTooltipText(this, text) + TooltipCompat.setTooltipText(this, text) } private fun isAutoRotationEnabled(): Boolean = Settings.System.getInt( diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/search/ui/suggestion/adapter/SearchSuggestionsMangaListAD.kt b/app/src/main/kotlin/org/koitharu/kotatsu/search/ui/suggestion/adapter/SearchSuggestionsMangaListAD.kt index 76056d893..6bbd0489a 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/search/ui/suggestion/adapter/SearchSuggestionsMangaListAD.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/search/ui/suggestion/adapter/SearchSuggestionsMangaListAD.kt @@ -1,5 +1,6 @@ package org.koitharu.kotatsu.search.ui.suggestion.adapter +import androidx.appcompat.widget.TooltipCompat import androidx.core.view.updatePadding import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.RecyclerView @@ -46,6 +47,7 @@ private fun searchSuggestionMangaGridAD( } bind { + TooltipCompat.setTooltipText(itemView, item.title) binding.imageViewCover.setImageAsync(item.coverUrl, item.source) binding.textViewTitle.text = item.title } diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/settings/storage/directories/DirectoryConfigAD.kt b/app/src/main/kotlin/org/koitharu/kotatsu/settings/storage/directories/DirectoryConfigAD.kt index d1d823a14..4b6f16c9e 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/settings/storage/directories/DirectoryConfigAD.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/settings/storage/directories/DirectoryConfigAD.kt @@ -1,5 +1,6 @@ package org.koitharu.kotatsu.settings.storage.directories +import androidx.appcompat.widget.TooltipCompat import androidx.core.content.ContextCompat import androidx.core.view.isVisible import com.hannesdorfmann.adapterdelegates4.dsl.adapterDelegateViewBinding @@ -16,13 +17,14 @@ fun directoryConfigAD( { layoutInflater, parent -> ItemStorageConfigBinding.inflate(layoutInflater, parent, false) }, ) { - binding.imageViewRemove.setOnClickListener { v -> clickListener.onItemClick(item, v) } + binding.buttonRemove.setOnClickListener { v -> clickListener.onItemClick(item, v) } + TooltipCompat.setTooltipText(binding.buttonRemove, binding.buttonRemove.contentDescription) bind { binding.textViewTitle.text = item.title ?: getString(item.titleRes) binding.textViewSubtitle.textAndVisible = item.file?.absolutePath - binding.imageViewRemove.isVisible = item.isRemovable - binding.imageViewRemove.isEnabled = !item.isChecked + binding.buttonRemove.isVisible = item.isRemovable + binding.buttonRemove.isEnabled = !item.isChecked binding.textViewTitle.drawableStart = if (!item.isAvailable) { ContextCompat.getDrawable(context, R.drawable.ic_alert_outline)?.apply { setTint(ContextCompat.getColor(context, R.color.warning)) diff --git a/app/src/main/res/layout/item_categories_all.xml b/app/src/main/res/layout/item_categories_all.xml index e3926d7dd..0a3c47a04 100644 --- a/app/src/main/res/layout/item_categories_all.xml +++ b/app/src/main/res/layout/item_categories_all.xml @@ -54,7 +54,7 @@ app:layout_constraintVertical_chainStyle="packed" tools:text="@tools:sample/lorem[1]" /> - - @@ -97,7 +98,9 @@ android:background="?selectableItemBackgroundBorderless" android:contentDescription="@string/reorder" android:padding="@dimen/margin_normal" + android:pointerIcon="grab" android:src="@drawable/ic_reorder_handle" + android:tooltipText="@string/reorder" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="parent" /> diff --git a/app/src/main/res/layout/item_storage_config.xml b/app/src/main/res/layout/item_storage_config.xml index 7ca26ee5a..e03eaeb7a 100644 --- a/app/src/main/res/layout/item_storage_config.xml +++ b/app/src/main/res/layout/item_storage_config.xml @@ -40,8 +40,8 @@ - @style/ThemeOverlay.Kotatsu.BottomSheetDialog @style/ThemeOverlay.Kotatsu.SideSheetDialog ?textInputOutlinedStyle - ?materialCardViewFilledStyle @style/Widget.Kotatsu.RecyclerView @style/Widget.Kotatsu.Spinner.DropDown