diff --git a/app/src/main/java/net/jeena/jtubetv/ui/screens/ChannelsScreen.kt b/app/src/main/java/net/jeena/jtubetv/ui/screens/ChannelsScreen.kt index 57d4fa3..4207968 100644 --- a/app/src/main/java/net/jeena/jtubetv/ui/screens/ChannelsScreen.kt +++ b/app/src/main/java/net/jeena/jtubetv/ui/screens/ChannelsScreen.kt @@ -358,6 +358,14 @@ fun ChannelsScreen( // as stats stream in the rows re-sort, and re-focusing their first card // would steal focus mid-navigation (user: "up jumps to the first row"). val focusHandedOut = remember { mutableStateOf(false) } + // The channel we came back from only wins the focus while it is still + // in the rows. When it isn't (renamed, unsubscribed, or the rows simply + // never carried it) every row used to ask for no focus at all — "when I + // click on Channels, none is selected" (#32 review). Fall back to the + // first row in that case, like the video cards do. + val focusRowExists = focusHandle != null && viewModel.userRows.any { + group -> group.channels.any { it.name + "@" + it.host == focusHandle } + } LazyColumn(Modifier.fillMaxSize()) { viewModel.userRows.forEach { group -> item(key = "hdr-" + group.ownerName) { @@ -379,7 +387,7 @@ fun ChannelsScreen( onOpenDrawer, drawerPulse = drawerPulse, focused = !focusHandedOut.value && ( - if (focusHandle != null) isTargetRow + if (focusRowExists) isTargetRow else group == viewModel.userRows.firstOrNull() ), focusIndex = if (isTargetRow) target else 0, @@ -479,6 +487,11 @@ private fun ChannelRow( return@LaunchedEffect } } + // The wanted card never became focusable (its row scrolled past it, + // or the handle went stale): take the first card instead, so the + // screen is never left with nothing selected (#32 review). + val first = focusRequesters[0] + if (first != null && runCatching { first.requestFocus() }.isSuccess) onFocused() } } }