From 9d60c36437b25ef36280683183f9fbe5f7b3faf1 Mon Sep 17 00:00:00 2001 From: Damontecres Date: Sat, 11 Oct 2025 15:19:58 -0400 Subject: [PATCH] Restore focus for series details --- .../damontecres/dolphin/ui/Extensions.kt | 13 ++++++++++++ .../dolphin/ui/detail/SeriesDetails.kt | 20 +++++++++++++++---- .../damontecres/dolphin/ui/main/SearchPage.kt | 8 ++------ 3 files changed, 31 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/com/github/damontecres/dolphin/ui/Extensions.kt b/app/src/main/java/com/github/damontecres/dolphin/ui/Extensions.kt index 86a16159..08ad61dd 100644 --- a/app/src/main/java/com/github/damontecres/dolphin/ui/Extensions.kt +++ b/app/src/main/java/com/github/damontecres/dolphin/ui/Extensions.kt @@ -26,6 +26,8 @@ import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import androidx.media3.common.Player import coil3.request.ErrorResult +import com.github.damontecres.dolphin.ui.data.RowColumn +import com.github.damontecres.dolphin.ui.data.RowColumnSaver import kotlinx.coroutines.CoroutineScope import org.jellyfin.sdk.model.api.BaseItemDto import org.jellyfin.sdk.model.extensions.ticks @@ -296,3 +298,14 @@ fun logCoilError( Timber.e(errorResult.throwable, "Error loading image: %s", url) } } + +/** + * Convenient way to [rememberSaveable] a [RowColumn] + */ +@Composable +fun rememberPosition(initialPosition: RowColumn = RowColumn(-1, -1)) = + rememberSaveable(stateSaver = RowColumnSaver) { + mutableStateOf( + initialPosition, + ) + } diff --git a/app/src/main/java/com/github/damontecres/dolphin/ui/detail/SeriesDetails.kt b/app/src/main/java/com/github/damontecres/dolphin/ui/detail/SeriesDetails.kt index 83079193..fe7e7fd2 100644 --- a/app/src/main/java/com/github/damontecres/dolphin/ui/detail/SeriesDetails.kt +++ b/app/src/main/java/com/github/damontecres/dolphin/ui/detail/SeriesDetails.kt @@ -63,11 +63,14 @@ import com.github.damontecres.dolphin.ui.components.StarRating import com.github.damontecres.dolphin.ui.components.StarRatingPrecision import com.github.damontecres.dolphin.ui.data.ItemDetailsDialog import com.github.damontecres.dolphin.ui.data.ItemDetailsDialogInfo +import com.github.damontecres.dolphin.ui.data.RowColumn +import com.github.damontecres.dolphin.ui.ifElse import com.github.damontecres.dolphin.ui.isNotNullOrBlank import com.github.damontecres.dolphin.ui.letNotEmpty import com.github.damontecres.dolphin.ui.nav.Destination import com.github.damontecres.dolphin.ui.playOnClickSound import com.github.damontecres.dolphin.ui.playSoundOnFocus +import com.github.damontecres.dolphin.ui.rememberPosition import com.github.damontecres.dolphin.ui.roundMinutes import com.github.damontecres.dolphin.ui.tryRequestFocus import com.github.damontecres.dolphin.util.LoadingState @@ -159,6 +162,7 @@ fun SeriesDetailsContent( ) { val bringIntoViewRequester = remember { BringIntoViewRequester() } + var position by rememberPosition() val focusRequester = remember { FocusRequester() } LaunchedEffect(Unit) { focusRequester.tryRequestFocus() } @@ -217,8 +221,8 @@ fun SeriesDetailsContent( Modifier .fillMaxWidth(.6f) .bringIntoViewRequester(bringIntoViewRequester) - .focusRequester(focusRequester) - .padding(bottom = 80.dp), + .padding(bottom = 80.dp) + .ifElse(position.row < 0, Modifier.focusRequester(focusRequester)), ) } item { @@ -240,11 +244,19 @@ fun SeriesDetailsContent( cardContent = @Composable { index, item, mod, onClick, onLongClick -> SeasonCard( item = item, - onClick = onClick, + onClick = { + position = RowColumn(0, index) + onClick.invoke() + }, onLongClick = onLongClick, - modifier = mod, imageHeight = Cards.height2x3, imageWidth = Dp.Unspecified, + modifier = + mod + .ifElse( + position.row == 0 && position.column == index, + Modifier.focusRequester(focusRequester), + ), ) }, ) diff --git a/app/src/main/java/com/github/damontecres/dolphin/ui/main/SearchPage.kt b/app/src/main/java/com/github/damontecres/dolphin/ui/main/SearchPage.kt index 19b41721..c4d7f3f8 100644 --- a/app/src/main/java/com/github/damontecres/dolphin/ui/main/SearchPage.kt +++ b/app/src/main/java/com/github/damontecres/dolphin/ui/main/SearchPage.kt @@ -32,10 +32,10 @@ import com.github.damontecres.dolphin.ui.cards.ItemRow import com.github.damontecres.dolphin.ui.cards.SeasonCard import com.github.damontecres.dolphin.ui.components.SearchEditTextBox import com.github.damontecres.dolphin.ui.data.RowColumn -import com.github.damontecres.dolphin.ui.data.RowColumnSaver import com.github.damontecres.dolphin.ui.ifElse import com.github.damontecres.dolphin.ui.isNotNullOrBlank import com.github.damontecres.dolphin.ui.nav.NavigationManager +import com.github.damontecres.dolphin.ui.rememberPosition import com.github.damontecres.dolphin.ui.tryRequestFocus import com.github.damontecres.dolphin.util.ApiRequestPager import com.github.damontecres.dolphin.util.ExceptionHandler @@ -143,11 +143,7 @@ fun SearchPage( var query by rememberSaveable { mutableStateOf("") } val focusRequester = remember { FocusRequester() } - var position by rememberSaveable(stateSaver = RowColumnSaver) { - mutableStateOf( - RowColumn(-1, -1), - ) - } + var position by rememberPosition() LaunchedEffect(query) { delay(750L)