From 912d0f33df3be66028883d6f491165870e0fbd76 Mon Sep 17 00:00:00 2001 From: Uwe Trottmann Date: Thu, 10 Oct 2024 11:40:38 +0200 Subject: [PATCH 1/3] Consistently show tooltips for actions --- CHANGELOG.md | 1 + .../seriesguide/movies/MovieViewHolder.kt | 8 +++-- .../shows/WatchProviderFilterView.kt | 26 +++++++++++----- .../shows/calendar/CalendarItemViewHolder.kt | 11 ++++--- .../shows/episodes/EpisodesAdapter.kt | 7 +++-- .../shows/episodes/EpisodesFragment.kt | 31 ++++++++++--------- .../shows/overview/SeasonsAdapter.kt | 8 +++-- .../shows/overview/SeasonsFragment.kt | 31 ++++++++++--------- .../shows/search/discover/AddFragment.kt | 4 +++ .../search/discover/ShowsDiscoverAdapter.kt | 3 ++ app/src/main/res/layout/fragment_episodes.xml | 4 +-- app/src/main/res/layout/fragment_seasons.xml | 2 ++ 12 files changed, 89 insertions(+), 47 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 99311825a1..86fd99e623 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,7 @@ Releases marked with ๐Ÿงช (or previously with the "beta" suffix) were released o * ๐Ÿ”จ Show overview: do not display no spoiler warning if there is no image. * ๐Ÿ”จ Consistently style more options menus. * ๐Ÿ”จ Episodes: can use watched button also after dismissing the popup menu. +* ๐Ÿ”จ Consistently show tooltips for actions. ### 2024.4.3 - 2024-09-13 ๐Ÿงช diff --git a/app/src/main/java/com/battlelancer/seriesguide/movies/MovieViewHolder.kt b/app/src/main/java/com/battlelancer/seriesguide/movies/MovieViewHolder.kt index c7b7aec04b..6947fdf92e 100644 --- a/app/src/main/java/com/battlelancer/seriesguide/movies/MovieViewHolder.kt +++ b/app/src/main/java/com/battlelancer/seriesguide/movies/MovieViewHolder.kt @@ -7,6 +7,7 @@ import android.annotation.SuppressLint import android.content.Context import android.view.LayoutInflater import android.view.ViewGroup +import androidx.appcompat.widget.TooltipCompat import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.RecyclerView import com.battlelancer.seriesguide.R @@ -37,8 +38,11 @@ class MovieViewHolder( itemView.setContextAndLongClickListener { onMoreOptionsClick() } - moreOptions.setOnClickListener { - onMoreOptionsClick() + moreOptions.also { + TooltipCompat.setTooltipText(it, it.contentDescription) + it.setOnClickListener { + onMoreOptionsClick() + } } } diff --git a/app/src/main/java/com/battlelancer/seriesguide/shows/WatchProviderFilterView.kt b/app/src/main/java/com/battlelancer/seriesguide/shows/WatchProviderFilterView.kt index 156c488b7d..3889bf0a54 100644 --- a/app/src/main/java/com/battlelancer/seriesguide/shows/WatchProviderFilterView.kt +++ b/app/src/main/java/com/battlelancer/seriesguide/shows/WatchProviderFilterView.kt @@ -22,8 +22,12 @@ import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.PlainTooltip import androidx.compose.material3.Surface import androidx.compose.material3.Text +import androidx.compose.material3.TooltipBox +import androidx.compose.material3.TooltipDefaults +import androidx.compose.material3.rememberTooltipState import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue @@ -91,14 +95,22 @@ fun WatchProviderList( ) { Text(stringResource(id = R.string.action_reset)) } - IconButton( - modifier = Modifier.padding(top = 2.dp, start = 4.dp, end = 4.dp), - onClick = onSelectRegion + val descriptionStreamSettingsButton = + stringResource(id = R.string.action_stream_info) + TooltipBox( + positionProvider = TooltipDefaults.rememberPlainTooltipPositionProvider(), + tooltip = { PlainTooltip { Text(descriptionStreamSettingsButton) } }, + state = rememberTooltipState() ) { - Icon( - imageVector = Icons.Outlined.Settings, - contentDescription = stringResource(id = R.string.action_stream_info) - ) + IconButton( + modifier = Modifier.padding(top = 2.dp, start = 4.dp, end = 4.dp), + onClick = onSelectRegion + ) { + Icon( + imageVector = Icons.Outlined.Settings, + contentDescription = descriptionStreamSettingsButton + ) + } } } } diff --git a/app/src/main/java/com/battlelancer/seriesguide/shows/calendar/CalendarItemViewHolder.kt b/app/src/main/java/com/battlelancer/seriesguide/shows/calendar/CalendarItemViewHolder.kt index b6efe5f012..30a8ef83a3 100644 --- a/app/src/main/java/com/battlelancer/seriesguide/shows/calendar/CalendarItemViewHolder.kt +++ b/app/src/main/java/com/battlelancer/seriesguide/shows/calendar/CalendarItemViewHolder.kt @@ -41,7 +41,7 @@ class CalendarItemViewHolder( private val episodeTextView: TextView = itemView.findViewById(R.id.textViewActivityEpisode) private val collected: View = itemView.findViewById(R.id.imageViewActivityCollected) private val watchedBox: WatchedBox = itemView.findViewById(R.id.watchedBoxActivity) - private val contextMenu: ImageView = itemView.findViewById(R.id.imageViewActivityMoreOptions) + private val moreOptionsButton: ImageView = itemView.findViewById(R.id.imageViewActivityMoreOptions) private val info: TextView = itemView.findViewById(R.id.textViewActivityInfo) private val timestamp: TextView = itemView.findViewById(R.id.textViewActivityTimestamp) private val poster: ImageView = itemView.findViewById(R.id.imageViewActivityPoster) @@ -57,8 +57,11 @@ class CalendarItemViewHolder( itemContainer.setContextAndLongClickListener { onMoreOptionsClick() } - contextMenu.setOnClickListener { - onMoreOptionsClick() + moreOptionsButton.also { + TooltipCompat.setTooltipText(it, it.contentDescription) + it.setOnClickListener { + onMoreOptionsClick() + } } watchedBox.setOnClickListener { item?.episode?.let { @@ -74,7 +77,7 @@ class CalendarItemViewHolder( private fun onMoreOptionsClick() { item?.episode?.let { - itemClickListener.onMoreOptionsClick(contextMenu, it) + itemClickListener.onMoreOptionsClick(moreOptionsButton, it) } } diff --git a/app/src/main/java/com/battlelancer/seriesguide/shows/episodes/EpisodesAdapter.kt b/app/src/main/java/com/battlelancer/seriesguide/shows/episodes/EpisodesAdapter.kt index 9dda565cc7..04f96f5f13 100644 --- a/app/src/main/java/com/battlelancer/seriesguide/shows/episodes/EpisodesAdapter.kt +++ b/app/src/main/java/com/battlelancer/seriesguide/shows/episodes/EpisodesAdapter.kt @@ -108,8 +108,11 @@ class EpisodeViewHolder( binding.root.setContextAndLongClickListener { onMoreOptionsClick() } - binding.imageViewItemEpisodeMoreOptions.setOnClickListener { - onMoreOptionsClick() + binding.imageViewItemEpisodeMoreOptions.also { + TooltipCompat.setTooltipText(it, it.contentDescription) + it.setOnClickListener { + onMoreOptionsClick() + } } } diff --git a/app/src/main/java/com/battlelancer/seriesguide/shows/episodes/EpisodesFragment.kt b/app/src/main/java/com/battlelancer/seriesguide/shows/episodes/EpisodesFragment.kt index f4b46998c6..01ec71a92b 100644 --- a/app/src/main/java/com/battlelancer/seriesguide/shows/episodes/EpisodesFragment.kt +++ b/app/src/main/java/com/battlelancer/seriesguide/shows/episodes/EpisodesFragment.kt @@ -12,6 +12,7 @@ import android.view.MenuItem import android.view.View import android.view.ViewGroup import androidx.appcompat.widget.PopupMenu +import androidx.appcompat.widget.TooltipCompat import androidx.core.view.MenuProvider import androidx.fragment.app.Fragment import androidx.fragment.app.viewModels @@ -341,17 +342,18 @@ class EpisodesFragment : Fragment() { private fun setWatchedToggleState(unwatchedEpisodes: Int) { watchedAllEpisodes = unwatchedEpisodes == 0 - binding?.imageViewEpisodesWatched?.apply { + binding?.imageViewEpisodesWatched?.also { // using vectors is safe because it will be an AppCompatImageView - contentDescription = if (watchedAllEpisodes) { - setImageResource(R.drawable.ic_watched_all_24dp) - getString(R.string.unmark_all) + if (watchedAllEpisodes) { + it.setImageResource(R.drawable.ic_watched_all_24dp) + it.contentDescription = getString(R.string.unmark_all) } else { - setImageResource(R.drawable.ic_watch_all_black_24dp) - getString(R.string.mark_all) + it.setImageResource(R.drawable.ic_watch_all_black_24dp) + it.contentDescription = getString(R.string.mark_all) } + TooltipCompat.setTooltipText(it, it.contentDescription) // set onClick listener not before here to avoid unexpected actions - setOnClickListener(watchedAllClickListener) + it.setOnClickListener(watchedAllClickListener) } } @@ -389,17 +391,18 @@ class EpisodesFragment : Fragment() { private fun setCollectedToggleState(uncollectedEpisodes: Int) { collectedAllEpisodes = uncollectedEpisodes == 0 - binding?.imageViewEpisodesCollected?.apply { + binding?.imageViewEpisodesCollected?.also { // using vectors is safe because it will be an AppCompatImageView - contentDescription = if (collectedAllEpisodes) { - setImageResource(R.drawable.ic_collected_all_24dp) - getString(R.string.uncollect_all) + if (collectedAllEpisodes) { + it.setImageResource(R.drawable.ic_collected_all_24dp) + it.contentDescription = getString(R.string.uncollect_all) } else { - setImageResource(R.drawable.ic_collect_all_black_24dp) - getString(R.string.collect_all) + it.setImageResource(R.drawable.ic_collect_all_black_24dp) + it.contentDescription = getString(R.string.collect_all) } + TooltipCompat.setTooltipText(it, it.contentDescription) // set onClick listener not before here to avoid unexpected actions - setOnClickListener(collectedAllClickListener) + it.setOnClickListener(collectedAllClickListener) } } diff --git a/app/src/main/java/com/battlelancer/seriesguide/shows/overview/SeasonsAdapter.kt b/app/src/main/java/com/battlelancer/seriesguide/shows/overview/SeasonsAdapter.kt index 073bbf99d8..d3a9d987f4 100644 --- a/app/src/main/java/com/battlelancer/seriesguide/shows/overview/SeasonsAdapter.kt +++ b/app/src/main/java/com/battlelancer/seriesguide/shows/overview/SeasonsAdapter.kt @@ -7,6 +7,7 @@ import android.content.Context import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import androidx.appcompat.widget.TooltipCompat import androidx.core.view.isVisible import androidx.core.widget.TextViewCompat import androidx.recyclerview.widget.DiffUtil @@ -50,8 +51,11 @@ class SeasonsAdapter( itemView.setContextAndLongClickListener { onMoreOptionsClick() } - binding.imageViewSeasonMoreOptions.setOnClickListener { - onMoreOptionsClick() + binding.imageViewSeasonMoreOptions.also { + TooltipCompat.setTooltipText(it, it.contentDescription) + it.setOnClickListener { + onMoreOptionsClick() + } } } diff --git a/app/src/main/java/com/battlelancer/seriesguide/shows/overview/SeasonsFragment.kt b/app/src/main/java/com/battlelancer/seriesguide/shows/overview/SeasonsFragment.kt index 3a78665a4d..055bf76ea2 100644 --- a/app/src/main/java/com/battlelancer/seriesguide/shows/overview/SeasonsFragment.kt +++ b/app/src/main/java/com/battlelancer/seriesguide/shows/overview/SeasonsFragment.kt @@ -12,6 +12,7 @@ import android.view.MenuItem import android.view.View import android.view.ViewGroup import androidx.appcompat.widget.PopupMenu +import androidx.appcompat.widget.TooltipCompat import androidx.core.app.ActivityCompat import androidx.core.app.ActivityOptionsCompat import androidx.core.os.bundleOf @@ -296,17 +297,18 @@ class SeasonsFragment() : Fragment() { private fun setWatchedToggleState(watchedAllEpisodes: Boolean) { this.watchedAllEpisodes = watchedAllEpisodes - binding?.imageViewSeasonsWatchedToggle?.apply { + binding?.imageViewSeasonsWatchedToggle?.also { // using vectors is safe because it will be an AppCompatImageView - contentDescription = if (watchedAllEpisodes) { - setImageResource(R.drawable.ic_watched_all_24dp) - getString(R.string.unmark_all) + if (watchedAllEpisodes) { + it.setImageResource(R.drawable.ic_watched_all_24dp) + it.contentDescription = getString(R.string.unmark_all) } else { - setImageResource(R.drawable.ic_watch_all_black_24dp) - getString(R.string.mark_all) + it.setImageResource(R.drawable.ic_watch_all_black_24dp) + it.contentDescription = getString(R.string.mark_all) } + TooltipCompat.setTooltipText(it, it.contentDescription) // set onClick listener not before here to avoid unexpected actions - setOnClickListener(watchedAllClickListener) + it.setOnClickListener(watchedAllClickListener) } } @@ -336,17 +338,18 @@ class SeasonsFragment() : Fragment() { private fun setCollectedToggleState(collectedAllEpisodes: Boolean) { this.collectedAllEpisodes = collectedAllEpisodes - binding?.imageViewSeasonsCollectedToggle?.apply { + binding?.imageViewSeasonsCollectedToggle?.also { // using vectors is safe because it will be an AppCompatImageView - contentDescription = if (collectedAllEpisodes) { - setImageResource(R.drawable.ic_collected_all_24dp) - getString(R.string.uncollect_all) + if (collectedAllEpisodes) { + it.setImageResource(R.drawable.ic_collected_all_24dp) + it.contentDescription = getString(R.string.uncollect_all) } else { - setImageResource(R.drawable.ic_collect_all_black_24dp) - getString(R.string.collect_all) + it.setImageResource(R.drawable.ic_collect_all_black_24dp) + it.contentDescription = getString(R.string.collect_all) } + TooltipCompat.setTooltipText(it, it.contentDescription) // set onClick listener not before here to avoid unexpected actions - setOnClickListener(collectedAllClickListener) + it.setOnClickListener(collectedAllClickListener) } } diff --git a/app/src/main/java/com/battlelancer/seriesguide/shows/search/discover/AddFragment.kt b/app/src/main/java/com/battlelancer/seriesguide/shows/search/discover/AddFragment.kt index 78d8b511ab..ff21881eb7 100644 --- a/app/src/main/java/com/battlelancer/seriesguide/shows/search/discover/AddFragment.kt +++ b/app/src/main/java/com/battlelancer/seriesguide/shows/search/discover/AddFragment.kt @@ -12,6 +12,7 @@ import android.view.ViewGroup import android.view.animation.AnimationUtils import android.widget.ArrayAdapter import android.widget.GridView +import androidx.appcompat.widget.TooltipCompat import androidx.core.view.ViewCompat import androidx.fragment.app.Fragment import com.battlelancer.seriesguide.R @@ -224,6 +225,9 @@ abstract class AddFragment : Fragment() { binding.addIndicatorAddShow.setOnAddClickListener { item?.let { itemClickListener.onAddClick(it) } } + binding.buttonItemAddMoreOptions.also { + TooltipCompat.setTooltipText(it, it.contentDescription) + } } private fun onMoreOptionsClick() { diff --git a/app/src/main/java/com/battlelancer/seriesguide/shows/search/discover/ShowsDiscoverAdapter.kt b/app/src/main/java/com/battlelancer/seriesguide/shows/search/discover/ShowsDiscoverAdapter.kt index b64019dd5f..d4fcc58afe 100644 --- a/app/src/main/java/com/battlelancer/seriesguide/shows/search/discover/ShowsDiscoverAdapter.kt +++ b/app/src/main/java/com/battlelancer/seriesguide/shows/search/discover/ShowsDiscoverAdapter.kt @@ -260,6 +260,9 @@ class ShowsDiscoverAdapter( binding.addIndicatorAddShow.setOnAddClickListener { item?.let { itemClickListener.onAddClick(it) } } + binding.buttonItemAddMoreOptions.also { + TooltipCompat.setTooltipText(it, it.contentDescription) + } } private fun onMoreOptionsClick() { diff --git a/app/src/main/res/layout/fragment_episodes.xml b/app/src/main/res/layout/fragment_episodes.xml index 49d3abb341..d85ea578bc 100644 --- a/app/src/main/res/layout/fragment_episodes.xml +++ b/app/src/main/res/layout/fragment_episodes.xml @@ -26,7 +26,7 @@ android:layout_height="wrap_content" android:orientation="horizontal"> - + - + + + Date: Thu, 10 Oct 2024 11:50:54 +0200 Subject: [PATCH 2/3] WatchedBox: let it itself update content description and tooltip --- .../shows/calendar/CalendarItemViewHolder.kt | 10 ++++------ .../seriesguide/shows/episodes/EpisodesAdapter.kt | 12 ------------ .../seriesguide/shows/episodes/WatchedBox.kt | 12 ++++++++++++ 3 files changed, 16 insertions(+), 18 deletions(-) diff --git a/app/src/main/java/com/battlelancer/seriesguide/shows/calendar/CalendarItemViewHolder.kt b/app/src/main/java/com/battlelancer/seriesguide/shows/calendar/CalendarItemViewHolder.kt index 30a8ef83a3..34c699f2f7 100644 --- a/app/src/main/java/com/battlelancer/seriesguide/shows/calendar/CalendarItemViewHolder.kt +++ b/app/src/main/java/com/battlelancer/seriesguide/shows/calendar/CalendarItemViewHolder.kt @@ -155,12 +155,10 @@ class CalendarItemViewHolder( info.text = TextTools.dotSeparate(episode.network, time) // watched box - watchedBox.isEnabled = true - val episodeFlag = episode.watched - watchedBox.episodeFlag = episodeFlag - val watched = EpisodeTools.isWatched(episodeFlag) - watchedBox.contentDescription = - context.getString(if (watched) R.string.action_unwatched else R.string.action_watched) + watchedBox.apply { + isEnabled = true + episodeFlag = episode.watched + } // collected indicator collected.isGone = !episode.episode_collected diff --git a/app/src/main/java/com/battlelancer/seriesguide/shows/episodes/EpisodesAdapter.kt b/app/src/main/java/com/battlelancer/seriesguide/shows/episodes/EpisodesAdapter.kt index 04f96f5f13..564e213233 100644 --- a/app/src/main/java/com/battlelancer/seriesguide/shows/episodes/EpisodesAdapter.kt +++ b/app/src/main/java/com/battlelancer/seriesguide/shows/episodes/EpisodesAdapter.kt @@ -162,18 +162,6 @@ class EpisodeViewHolder( // watched box binding.watchedBoxEpisode.episodeFlag = watchedFlag binding.watchedBoxEpisode.isEnabled = true - val watched = - EpisodeTools.isWatched( - watchedFlag - ) - binding.watchedBoxEpisode.contentDescription = - context.getString(if (watched) R.string.action_unwatched else R.string.action_watched) - TooltipCompat.setTooltipText( - binding.watchedBoxEpisode, - binding.watchedBoxEpisode.context.getString( - if (watched) R.string.action_unwatched else R.string.action_watched - ) - ) // collected tag val isCollected = episode.collected diff --git a/app/src/main/java/com/battlelancer/seriesguide/shows/episodes/WatchedBox.kt b/app/src/main/java/com/battlelancer/seriesguide/shows/episodes/WatchedBox.kt index 6f25f07397..8b1098c88c 100644 --- a/app/src/main/java/com/battlelancer/seriesguide/shows/episodes/WatchedBox.kt +++ b/app/src/main/java/com/battlelancer/seriesguide/shows/episodes/WatchedBox.kt @@ -6,10 +6,13 @@ package com.battlelancer.seriesguide.shows.episodes import android.content.Context import android.util.AttributeSet import androidx.appcompat.widget.AppCompatImageView +import androidx.appcompat.widget.TooltipCompat import com.battlelancer.seriesguide.R /** * Image view that displays a watched, skipped or watch icon depending on the given episode flag. + * + * Provides a content description and tooltip out of the box. */ class WatchedBox(context: Context, attrs: AttributeSet?) : AppCompatImageView(context, attrs) { @@ -21,6 +24,7 @@ class WatchedBox(context: Context, attrs: AttributeSet?) : AppCompatImageView(co EpisodeTools.validateFlags(value) field = value updateStateImage() + updateContentDescription() } init { @@ -48,4 +52,12 @@ class WatchedBox(context: Context, attrs: AttributeSet?) : AppCompatImageView(co } } } + + private fun updateContentDescription() { + val watched = EpisodeTools.isWatched(episodeFlag) + contentDescription = + context.getString(if (watched) R.string.action_unwatched else R.string.action_watched) + // Re-set tooltip text after updating + TooltipCompat.setTooltipText(this, contentDescription) + } } From fac7c3aebc56543a581e58d36183b5315a5853ac Mon Sep 17 00:00:00 2001 From: Uwe Trottmann Date: Thu, 10 Oct 2024 15:05:36 +0200 Subject: [PATCH 3/3] AddIndicator: add content description and tooltip for all states --- .../shows/search/discover/AddFragment.kt | 17 +++++----- .../shows/search/discover/AddIndicator.kt | 32 +++++++++++++++---- .../search/discover/SearchResultViewHolder.kt | 9 ++---- .../search/discover/ShowsDiscoverAdapter.kt | 4 +-- .../main/res/layout/layout_add_indicator.xml | 3 +- 5 files changed, 40 insertions(+), 25 deletions(-) diff --git a/app/src/main/java/com/battlelancer/seriesguide/shows/search/discover/AddFragment.kt b/app/src/main/java/com/battlelancer/seriesguide/shows/search/discover/AddFragment.kt index ff21881eb7..8cf293c5ea 100644 --- a/app/src/main/java/com/battlelancer/seriesguide/shows/search/discover/AddFragment.kt +++ b/app/src/main/java/com/battlelancer/seriesguide/shows/search/discover/AddFragment.kt @@ -14,8 +14,9 @@ import android.widget.ArrayAdapter import android.widget.GridView import androidx.appcompat.widget.TooltipCompat import androidx.core.view.ViewCompat +import androidx.core.view.isGone +import androidx.core.view.isVisible import androidx.fragment.app.Fragment -import com.battlelancer.seriesguide.R import com.battlelancer.seriesguide.databinding.ItemAddshowBinding import com.battlelancer.seriesguide.enums.NetworkResult import com.battlelancer.seriesguide.shows.tools.AddShowTask.OnShowAddedEvent @@ -258,18 +259,18 @@ abstract class AddFragment : Fragment() { if (enableMoreOptions) View.VISIBLE else View.GONE if (item == null) { - binding.addIndicatorAddShow.setState(SearchResult.STATE_ADD) - binding.addIndicatorAddShow.setContentDescriptionAdded(null) + binding.addIndicatorAddShow.isGone = true binding.textViewAddTitle.text = null binding.textViewAddDescription.text = null binding.imageViewAddPoster.setImageDrawable(null) } else { - // display added indicator instead of add button if already added that show - binding.addIndicatorAddShow.setState(item.state) + // add indicator val showTitle = item.title - binding.addIndicatorAddShow.setContentDescriptionAdded( - context.getString(R.string.add_already_exists, showTitle) - ) + binding.addIndicatorAddShow.apply { + setState(item.state) + setNameOfAssociatedItem(showTitle) + isVisible = true + } // set text properties immediately binding.textViewAddTitle.text = showTitle diff --git a/app/src/main/java/com/battlelancer/seriesguide/shows/search/discover/AddIndicator.kt b/app/src/main/java/com/battlelancer/seriesguide/shows/search/discover/AddIndicator.kt index ffcd1ef188..9e4bdd0911 100644 --- a/app/src/main/java/com/battlelancer/seriesguide/shows/search/discover/AddIndicator.kt +++ b/app/src/main/java/com/battlelancer/seriesguide/shows/search/discover/AddIndicator.kt @@ -7,27 +7,43 @@ import android.content.Context import android.util.AttributeSet import android.view.LayoutInflater import android.widget.FrameLayout +import androidx.appcompat.widget.TooltipCompat +import com.battlelancer.seriesguide.R import com.battlelancer.seriesguide.databinding.LayoutAddIndicatorBinding /** * A three state visual indicator with states add, adding and added from [SearchResult]. + * + * Make sure to call [setNameOfAssociatedItem] to provide content description and tooltips for all + * states. */ class AddIndicator(context: Context, attrs: AttributeSet?) : FrameLayout(context, attrs) { - private val binding: LayoutAddIndicatorBinding - - init { - binding = LayoutAddIndicatorBinding.inflate(LayoutInflater.from(context), this) - } + private val binding = LayoutAddIndicatorBinding.inflate(LayoutInflater.from(context), this) override fun onFinishInflate() { super.onFinishInflate() + binding.imageViewAddIndicator.also { + TooltipCompat.setTooltipText(it, it.contentDescription) + } binding.imageViewAddIndicatorAdded.visibility = GONE binding.progressBarAddIndicator.visibility = GONE } - fun setContentDescriptionAdded(contentDescription: CharSequence?) { - binding.imageViewAddIndicatorAdded.contentDescription = contentDescription + /** + * Sets content descriptions and tooltips of added and adding states. + */ + fun setNameOfAssociatedItem(name: String) { + binding.apply { + imageViewAddIndicatorAdded.also { + it.contentDescription = context.getString(R.string.add_already_exists, name) + TooltipCompat.setTooltipText(it, it.contentDescription) + } + progressBarAddIndicator.also { + it.contentDescription = context.getString(R.string.add_started, name) + TooltipCompat.setTooltipText(it, it.contentDescription) + } + } } fun setOnAddClickListener(onClickListener: OnClickListener?) { @@ -41,11 +57,13 @@ class AddIndicator(context: Context, attrs: AttributeSet?) : FrameLayout(context binding.progressBarAddIndicator.visibility = GONE binding.imageViewAddIndicatorAdded.visibility = GONE } + SearchResult.STATE_ADDING -> { binding.imageViewAddIndicator.visibility = GONE binding.progressBarAddIndicator.visibility = VISIBLE binding.imageViewAddIndicatorAdded.visibility = GONE } + SearchResult.STATE_ADDED -> { binding.imageViewAddIndicator.visibility = GONE binding.progressBarAddIndicator.visibility = GONE diff --git a/app/src/main/java/com/battlelancer/seriesguide/shows/search/discover/SearchResultViewHolder.kt b/app/src/main/java/com/battlelancer/seriesguide/shows/search/discover/SearchResultViewHolder.kt index 5777a5771b..5b5790520b 100644 --- a/app/src/main/java/com/battlelancer/seriesguide/shows/search/discover/SearchResultViewHolder.kt +++ b/app/src/main/java/com/battlelancer/seriesguide/shows/search/discover/SearchResultViewHolder.kt @@ -43,19 +43,16 @@ class SearchResultViewHolder( // hide more options button moreOptionsButton.visibility = View.GONE - // display added indicator instead of add button if already added that show - val showTitle = searchResult?.title + // add indicator if (searchResult != null) { addIndicator.setState(searchResult.state) - addIndicator.setContentDescriptionAdded( - itemView.context.getString(R.string.add_already_exists, showTitle) - ) + addIndicator.setNameOfAssociatedItem(searchResult.title) addIndicator.visibility = View.VISIBLE } else { addIndicator.visibility = View.GONE } - title.text = showTitle + title.text = searchResult?.title description.text = searchResult?.overview // only local shows will have a poster path set diff --git a/app/src/main/java/com/battlelancer/seriesguide/shows/search/discover/ShowsDiscoverAdapter.kt b/app/src/main/java/com/battlelancer/seriesguide/shows/search/discover/ShowsDiscoverAdapter.kt index d4fcc58afe..aacdf19e23 100644 --- a/app/src/main/java/com/battlelancer/seriesguide/shows/search/discover/ShowsDiscoverAdapter.kt +++ b/app/src/main/java/com/battlelancer/seriesguide/shows/search/discover/ShowsDiscoverAdapter.kt @@ -299,9 +299,7 @@ class ShowsDiscoverAdapter( // display added indicator instead of add button if already added that show binding.addIndicatorAddShow.setState(item.state) val showTitle = item.title - binding.addIndicatorAddShow.setContentDescriptionAdded( - context.getString(R.string.add_already_exists, showTitle) - ) + binding.addIndicatorAddShow.setNameOfAssociatedItem(showTitle) // set text properties immediately binding.textViewAddTitle.text = showTitle diff --git a/app/src/main/res/layout/layout_add_indicator.xml b/app/src/main/res/layout/layout_add_indicator.xml index a85cc35e18..8de43364e6 100644 --- a/app/src/main/res/layout/layout_add_indicator.xml +++ b/app/src/main/res/layout/layout_add_indicator.xml @@ -12,7 +12,7 @@ android:scaleType="centerInside" app:srcCompat="@drawable/ic_add_white_24dp" /> - + +