Add dimming effect to highlight which episode is currenty selected (#232)

On the series overview page, when moving off of the episode row, such as
to do the play/more buttons, the other episodes will now become dimmer
to indicate which episode you're interacting with.

Also, when moving back to the page from the nav drawer, focus is
restored to where it left from. This is useful when scrolling fast left
on the season tabs and you overshoot onto the nav drawer, moving right
once will always move back to the season tabs.

In this example screenshot, Episode 3 is selected, so the others are
darker.
<img width="1280" height="771" alt="dim Large"
src="https://github.com/user-attachments/assets/fa21ade4-3345-4e97-873f-d654123a1ae5"
/>

This is a follow up from #158
This commit is contained in:
damontecres 2025-11-16 21:23:55 -05:00 committed by GitHub
parent e3d94ad819
commit b42aa297f6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -1,5 +1,7 @@
package com.github.damontecres.wholphin.ui.detail.series
import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.foundation.background
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.interaction.collectIsFocusedAsState
import androidx.compose.foundation.layout.Arrangement
@ -15,11 +17,13 @@ import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.relocation.BringIntoViewRequester
import androidx.compose.foundation.relocation.bringIntoViewRequester
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.key
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
@ -30,6 +34,7 @@ import androidx.compose.ui.draw.drawWithContent
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.focus.focusRestorer
import androidx.compose.ui.focus.onFocusChanged
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
@ -86,6 +91,9 @@ fun SeriesOverviewContent(
val focusedEpisode =
(episodes as? EpisodeList.Success)?.episodes?.getOrNull(position.episodeRowIndex)
var pageHasFocus by remember { mutableStateOf(false) }
var cardRowHasFocus by remember { mutableStateOf(false) }
val dimming by animateFloatAsState(if (pageHasFocus && !cardRowHasFocus) .4f else 1f)
Box(
modifier =
@ -127,7 +135,10 @@ fun SeriesOverviewContent(
LazyColumn(
verticalArrangement = Arrangement.spacedBy(8.dp),
contentPadding = PaddingValues(16.dp),
modifier = Modifier,
modifier =
Modifier
.focusRestorer(episodeRowFocusRequester)
.onFocusChanged { pageHasFocus = it.hasFocus },
) {
item {
val paddingValues =
@ -150,6 +161,7 @@ fun SeriesOverviewContent(
modifier =
Modifier
.focusRequester(tabRowFocusRequester)
.focusRestorer()
.padding(paddingValues)
.fillMaxWidth(),
)
@ -193,7 +205,10 @@ fun SeriesOverviewContent(
modifier =
Modifier
.focusRestorer(firstItemFocusRequester)
.focusRequester(episodeRowFocusRequester),
.focusRequester(episodeRowFocusRequester)
.onFocusChanged {
cardRowHasFocus = it.hasFocus
},
) {
itemsIndexed(eps.episodes) { episodeIndex, episode ->
val interactionSource = remember { MutableInteractionSource() }
@ -232,10 +247,18 @@ fun SeriesOverviewContent(
}
},
modifier =
Modifier.ifElse(
episodeIndex == position.episodeRowIndex,
Modifier.focusRequester(firstItemFocusRequester),
),
Modifier
.ifElse(
episodeIndex == position.episodeRowIndex,
Modifier.focusRequester(firstItemFocusRequester),
).ifElse(
episodeIndex != position.episodeRowIndex,
Modifier
.background(
Color.Black,
shape = RoundedCornerShape(8.dp),
).alpha(dimming),
),
interactionSource = interactionSource,
cardHeight = 120.dp,
)