home: Restore row focus when returning from the player

BACK from a video dropped the user on a random spot (often the search
screen, #2): the restore token was only bumped when it was already >= 1,
so the very first back never re-focused anything, and HomeRowsViewModel
refresh() cleared the continue-watching rows synchronously, disposing
the rows before their focus-restore effect could run. Bump the token on
every playing -> not-playing transition and keep the rows alive during
a refresh instead.

Refs #2
This commit is contained in:
Jeena 2026-10-12 09:42:09 +00:00
parent 40a9d1e2c6
commit 3635a4ed74
2 changed files with 10 additions and 3 deletions

View file

@ -78,9 +78,10 @@ class HomeRowsViewModel(private val repository: PeerTubeRepository) : ViewModel(
fetchContinue() fetchContinue()
} }
/** Re-fetch after playback changed server-side positions (UX report BUG-7). */ /** Re-fetch after playback changed server-side positions (UX report BUG-7).
* Keeps the current rows in place while re-fetching (clearing them disposed
* the rows and killed the focus-restore effect before it could run, #2). */
fun refresh() { fun refresh() {
continueItems = emptyList()
loaded = true loaded = true
fetchContinue() fetchContinue()
fetchSubs() fetchSubs()

View file

@ -87,8 +87,14 @@ fun HomeScreen(viewModel: AppViewModel = androidx.lifecycle.viewmodel.compose.vi
// After BACK from the player: bump the restore token so lists re-focus the opened // After BACK from the player: bump the restore token so lists re-focus the opened
// card and re-fetch positions (UX report BUG-3 + BUG-7). // card and re-fetch positions (UX report BUG-3 + BUG-7).
var hadPlaying by rememberSaveable { mutableStateOf(false) }
LaunchedEffect(playingVideo) { LaunchedEffect(playingVideo) {
if (playingVideo == null && restoreToken >= 1) restoreToken++ if (playingVideo != null) {
hadPlaying = true
} else if (hadPlaying) {
restoreToken++
hadPlaying = false
}
} }
// BACK order (TV standard): player (own handler) → drawer close → channel // BACK order (TV standard): player (own handler) → drawer close → channel