Restore focus for series details

This commit is contained in:
Damontecres 2025-10-11 15:19:58 -04:00
parent b30ddab0fc
commit 9d60c36437
No known key found for this signature in database
3 changed files with 31 additions and 10 deletions

View file

@ -26,6 +26,8 @@ import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.media3.common.Player import androidx.media3.common.Player
import coil3.request.ErrorResult 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 kotlinx.coroutines.CoroutineScope
import org.jellyfin.sdk.model.api.BaseItemDto import org.jellyfin.sdk.model.api.BaseItemDto
import org.jellyfin.sdk.model.extensions.ticks import org.jellyfin.sdk.model.extensions.ticks
@ -296,3 +298,14 @@ fun logCoilError(
Timber.e(errorResult.throwable, "Error loading image: %s", url) 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,
)
}

View file

@ -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.components.StarRatingPrecision
import com.github.damontecres.dolphin.ui.data.ItemDetailsDialog import com.github.damontecres.dolphin.ui.data.ItemDetailsDialog
import com.github.damontecres.dolphin.ui.data.ItemDetailsDialogInfo 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.isNotNullOrBlank
import com.github.damontecres.dolphin.ui.letNotEmpty import com.github.damontecres.dolphin.ui.letNotEmpty
import com.github.damontecres.dolphin.ui.nav.Destination import com.github.damontecres.dolphin.ui.nav.Destination
import com.github.damontecres.dolphin.ui.playOnClickSound import com.github.damontecres.dolphin.ui.playOnClickSound
import com.github.damontecres.dolphin.ui.playSoundOnFocus 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.roundMinutes
import com.github.damontecres.dolphin.ui.tryRequestFocus import com.github.damontecres.dolphin.ui.tryRequestFocus
import com.github.damontecres.dolphin.util.LoadingState import com.github.damontecres.dolphin.util.LoadingState
@ -159,6 +162,7 @@ fun SeriesDetailsContent(
) { ) {
val bringIntoViewRequester = remember { BringIntoViewRequester() } val bringIntoViewRequester = remember { BringIntoViewRequester() }
var position by rememberPosition()
val focusRequester = remember { FocusRequester() } val focusRequester = remember { FocusRequester() }
LaunchedEffect(Unit) { focusRequester.tryRequestFocus() } LaunchedEffect(Unit) { focusRequester.tryRequestFocus() }
@ -217,8 +221,8 @@ fun SeriesDetailsContent(
Modifier Modifier
.fillMaxWidth(.6f) .fillMaxWidth(.6f)
.bringIntoViewRequester(bringIntoViewRequester) .bringIntoViewRequester(bringIntoViewRequester)
.focusRequester(focusRequester) .padding(bottom = 80.dp)
.padding(bottom = 80.dp), .ifElse(position.row < 0, Modifier.focusRequester(focusRequester)),
) )
} }
item { item {
@ -240,11 +244,19 @@ fun SeriesDetailsContent(
cardContent = @Composable { index, item, mod, onClick, onLongClick -> cardContent = @Composable { index, item, mod, onClick, onLongClick ->
SeasonCard( SeasonCard(
item = item, item = item,
onClick = onClick, onClick = {
position = RowColumn(0, index)
onClick.invoke()
},
onLongClick = onLongClick, onLongClick = onLongClick,
modifier = mod,
imageHeight = Cards.height2x3, imageHeight = Cards.height2x3,
imageWidth = Dp.Unspecified, imageWidth = Dp.Unspecified,
modifier =
mod
.ifElse(
position.row == 0 && position.column == index,
Modifier.focusRequester(focusRequester),
),
) )
}, },
) )

View file

@ -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.cards.SeasonCard
import com.github.damontecres.dolphin.ui.components.SearchEditTextBox import com.github.damontecres.dolphin.ui.components.SearchEditTextBox
import com.github.damontecres.dolphin.ui.data.RowColumn 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.ifElse
import com.github.damontecres.dolphin.ui.isNotNullOrBlank import com.github.damontecres.dolphin.ui.isNotNullOrBlank
import com.github.damontecres.dolphin.ui.nav.NavigationManager 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.ui.tryRequestFocus
import com.github.damontecres.dolphin.util.ApiRequestPager import com.github.damontecres.dolphin.util.ApiRequestPager
import com.github.damontecres.dolphin.util.ExceptionHandler import com.github.damontecres.dolphin.util.ExceptionHandler
@ -143,11 +143,7 @@ fun SearchPage(
var query by rememberSaveable { mutableStateOf("") } var query by rememberSaveable { mutableStateOf("") }
val focusRequester = remember { FocusRequester() } val focusRequester = remember { FocusRequester() }
var position by rememberSaveable(stateSaver = RowColumnSaver) { var position by rememberPosition()
mutableStateOf(
RowColumn(-1, -1),
)
}
LaunchedEffect(query) { LaunchedEffect(query) {
delay(750L) delay(750L)