From 694467b038886b30048f1556ec252b849733ffd7 Mon Sep 17 00:00:00 2001 From: Jeena Date: Sat, 10 Oct 2026 22:29:00 +0000 Subject: [PATCH] ui: Visible drawer focus + subscriptions row on Home Menu items now flip to white/dark on focus (before, focus moved invisibly so navigation looked broken) with explicit UP/DOWN key handling. Home gains a 'New from your subscriptions' row (first page, refreshed with the rest after playback). --- .../net/jeena/jtubetv/ui/screens/HomeRows.kt | 28 +++++++++++++++ .../jeena/jtubetv/ui/screens/HomeScreen.kt | 34 +++++++++++++++++-- 2 files changed, 60 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/net/jeena/jtubetv/ui/screens/HomeRows.kt b/app/src/main/java/net/jeena/jtubetv/ui/screens/HomeRows.kt index baca2a6..935b14e 100644 --- a/app/src/main/java/net/jeena/jtubetv/ui/screens/HomeRows.kt +++ b/app/src/main/java/net/jeena/jtubetv/ui/screens/HomeRows.kt @@ -55,10 +55,18 @@ class HomeRowsViewModel(private val repository: PeerTubeRepository) : ViewModel( private set var continueLoading by mutableStateOf(true) private set + var subItems by mutableStateOf>(emptyList()) + private set private var loaded = false val recent = RecentVideosViewModel(repository) + private fun fetchSubs() { + viewModelScope.launch { + subItems = repository.subscriptionVideos(0, 12).getOrNull()?.data ?: emptyList() + } + } + /** History's newest entries + resume positions from the video detail endpoint. */ fun load() { if (loaded) return @@ -71,10 +79,12 @@ class HomeRowsViewModel(private val repository: PeerTubeRepository) : ViewModel( continueItems = emptyList() loaded = true fetchContinue() + fetchSubs() recent.refresh() } private fun fetchContinue() { + fetchSubs() viewModelScope.launch { continueLoading = true val history = repository.history(0, 12).getOrNull()?.takeIf { it.isNotEmpty() } @@ -199,6 +209,24 @@ fun HomeRowsScreen( } } } + if (viewModel.subItems.isNotEmpty()) { + item { + Text( + text = "New from your subscriptions", + style = MaterialTheme.typography.titleMedium, + color = Color.White, + modifier = Modifier.padding(start = 16.dp, top = 16.dp, bottom = 4.dp), + ) + } + item { + FocusScrollRow( + videos = viewModel.subItems, + progressOf = { null }, + onOpenVideo = onOpenVideo, + onLeftAtStart = { }, + ) + } + } } } /** diff --git a/app/src/main/java/net/jeena/jtubetv/ui/screens/HomeScreen.kt b/app/src/main/java/net/jeena/jtubetv/ui/screens/HomeScreen.kt index 18af7ea..b52885d 100644 --- a/app/src/main/java/net/jeena/jtubetv/ui/screens/HomeScreen.kt +++ b/app/src/main/java/net/jeena/jtubetv/ui/screens/HomeScreen.kt @@ -36,6 +36,12 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.focus.FocusRequester import androidx.compose.ui.focus.focusRequester +import androidx.compose.ui.focus.onFocusChanged +import androidx.compose.ui.input.key.Key +import androidx.compose.ui.input.key.key +import androidx.compose.ui.input.key.KeyEventType +import androidx.compose.ui.input.key.onPreviewKeyEvent +import androidx.compose.ui.input.key.type import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.input.pointer.pointerInput @@ -327,12 +333,36 @@ private fun MenuDrawerItem( onClick: () -> Unit, modifier: Modifier = Modifier, ) { - val labelColor = if (selected) Color(0xFFE0E0E0) else Color(0xFFB0B0B0) + val focusManager = androidx.compose.ui.platform.LocalFocusManager.current + var focused by remember { mutableStateOf(false) } + val labelColor = when { + focused -> Color(0xFF101010) + selected -> Color(0xFFE0E0E0) + else -> Color(0xFFB0B0B0) + } Row( modifier = modifier .fillMaxWidth() - .then(if (selected) Modifier.background(Color(0x33CE2B2B)) else Modifier) + .onFocusChanged { focused = it.isFocused } + .background( + when { + focused -> Color.White + selected -> Color(0x33CE2B2B) + else -> Color.Transparent + } + ) .focusable() + .onPreviewKeyEvent { ke -> + when (ke.key) { + androidx.compose.ui.input.key.Key.DirectionDown -> { + focusManager?.moveFocus(androidx.compose.ui.focus.FocusDirection.Down); true + } + androidx.compose.ui.input.key.Key.DirectionUp -> { + focusManager?.moveFocus(androidx.compose.ui.focus.FocusDirection.Up); true + } + else -> false + } + } .clickable(onClick = onClick) .padding(horizontal = 24.dp, vertical = 14.dp), verticalAlignment = Alignment.CenterVertically,