Fix Events crash: bind FocusRequester before TopNav down to hub rail.
This commit is contained in:
parent
1f072b7d09
commit
244a8c97ed
2 changed files with 32 additions and 8 deletions
|
|
@ -20,8 +20,8 @@ android {
|
|||
applicationId = "nl.vonas.mediacluster.tv"
|
||||
minSdk = 24
|
||||
targetSdk = 36
|
||||
versionCode = 144
|
||||
versionName = "0.14.81"
|
||||
versionCode = 145
|
||||
versionName = "0.14.82"
|
||||
buildConfigField("String", "DEFAULT_API_BASE", "\"https://master.vonas.nl\"")
|
||||
ndk {
|
||||
abiFilters += listOf("arm64-v8a", "armeabi-v7a")
|
||||
|
|
|
|||
|
|
@ -133,6 +133,7 @@ fun EventsScreen(
|
|||
var providerFilter by remember { mutableStateOf<String?>(null) }
|
||||
var nowMs by remember { mutableLongStateOf(System.currentTimeMillis()) }
|
||||
var filterBarFocusReady by remember { mutableStateOf(false) }
|
||||
var hubRailFocusReady by remember { mutableStateOf(false) }
|
||||
/** Owner-id van first-rail FocusRequester — voorkomt dispose-race live↔upcoming. */
|
||||
var railFocusOwner by remember { mutableStateOf<String?>(null) }
|
||||
val railFocusReady = railFocusOwner != null
|
||||
|
|
@ -141,6 +142,7 @@ fun EventsScreen(
|
|||
val listState = rememberLazyListState()
|
||||
val firstRailFocus = remember { FocusRequester() }
|
||||
val restoreCardFocus = remember { FocusRequester() }
|
||||
val hubRailFocus = remember { FocusRequester() }
|
||||
|
||||
suspend fun refresh() {
|
||||
runCatching { api.listScheduleEvents() }
|
||||
|
|
@ -253,7 +255,7 @@ fun EventsScreen(
|
|||
val filterBarFocus = remember { FocusRequester() }
|
||||
val firstRailUpTarget = when {
|
||||
showFilterBar && filterBarFocusReady -> filterBarFocus
|
||||
hasHubRail -> contentFocusRequester
|
||||
hasHubRail && hubRailFocusReady -> hubRailFocus
|
||||
else -> navFocusRequester
|
||||
}
|
||||
val filterFocusDown: FocusRequester? = when {
|
||||
|
|
@ -342,19 +344,24 @@ fun EventsScreen(
|
|||
}
|
||||
|
||||
val entryReady = when {
|
||||
hasHubRail -> true
|
||||
hasHubRail -> hubRailFocusReady
|
||||
showFilterBar -> filterBarFocusReady
|
||||
else -> railFocusReady
|
||||
}
|
||||
val needContentSink = when {
|
||||
loading && events.isEmpty() -> true
|
||||
error != null && events.isEmpty() -> true
|
||||
hasHubRail -> false
|
||||
// contentFocusRequester mag nooit "los" staan (TopNav.down → crash)
|
||||
hasHubRail -> !hubRailFocusReady
|
||||
showFilterBar -> !filterBarFocusReady
|
||||
!hasRails -> true
|
||||
else -> !railFocusReady
|
||||
}
|
||||
|
||||
LaunchedEffect(hasHubRail) {
|
||||
if (!hasHubRail) hubRailFocusReady = false
|
||||
}
|
||||
|
||||
// Detail → back: card restore; fallback = chips of eerste rail.
|
||||
LaunchedEffect(
|
||||
pendingFocusRestore,
|
||||
|
|
@ -374,7 +381,7 @@ fun EventsScreen(
|
|||
if (restoredSuccessfully) return
|
||||
val entryOk = awaitReady({
|
||||
when {
|
||||
hasHubRail -> true
|
||||
hasHubRail -> hubRailFocusReady
|
||||
showFilterBar -> filterBarFocusReady
|
||||
else -> railFocusReady
|
||||
}
|
||||
|
|
@ -499,12 +506,17 @@ fun EventsScreen(
|
|||
) {
|
||||
if (hasHubRail) {
|
||||
item(key = "hub_rail") {
|
||||
// Zolang TopNav-sink contentFocusRequester vasthoudt → hubRailFocus op tile.
|
||||
// Zodra ready → contentFocusRequester op eerste tile.
|
||||
val hubEntryFocus =
|
||||
if (hubRailFocusReady) contentFocusRequester else hubRailFocus
|
||||
EventsHubRail(
|
||||
hubs = hubs,
|
||||
focusRequester = contentFocusRequester,
|
||||
focusRequester = hubEntryFocus,
|
||||
focusUp = navFocusRequester,
|
||||
onOpenF1 = onOpenF1Hub,
|
||||
onOpenViaplay = onOpenViaplayHub,
|
||||
onFocusReady = { hubRailFocusReady = it },
|
||||
onFocus = onContentFocused,
|
||||
)
|
||||
}
|
||||
|
|
@ -523,7 +535,11 @@ fun EventsScreen(
|
|||
liveCount = live.size,
|
||||
totalCount = filtered.size,
|
||||
firstFocusRequester = if (hasHubRail) filterBarFocus else contentFocusRequester,
|
||||
focusUp = if (hasHubRail) contentFocusRequester else navFocusRequester,
|
||||
focusUp = when {
|
||||
hasHubRail && hubRailFocusReady -> contentFocusRequester
|
||||
hasHubRail -> null
|
||||
else -> navFocusRequester
|
||||
},
|
||||
focusDown = filterFocusDown,
|
||||
onFocusReady = { filterBarFocusReady = it },
|
||||
onFocus = onContentFocused,
|
||||
|
|
@ -1108,6 +1124,7 @@ private fun EventsHubRail(
|
|||
focusUp: FocusRequester?,
|
||||
onOpenF1: (() -> Unit)?,
|
||||
onOpenViaplay: (() -> Unit)?,
|
||||
onFocusReady: ((Boolean) -> Unit)? = null,
|
||||
onFocus: () -> Unit,
|
||||
) {
|
||||
LazyRow(
|
||||
|
|
@ -1140,6 +1157,7 @@ private fun EventsHubRail(
|
|||
accent = accent,
|
||||
focusRequester = if (index == 0) focusRequester else null,
|
||||
focusUp = focusUp,
|
||||
onFocusReady = if (index == 0) onFocusReady else null,
|
||||
onOpen = onOpen,
|
||||
onFocus = onFocus,
|
||||
)
|
||||
|
|
@ -1156,9 +1174,15 @@ private fun HubRailTile(
|
|||
accent: Color,
|
||||
focusRequester: FocusRequester?,
|
||||
focusUp: FocusRequester?,
|
||||
onFocusReady: ((Boolean) -> Unit)? = null,
|
||||
onOpen: () -> Unit,
|
||||
onFocus: () -> Unit,
|
||||
) {
|
||||
// Ready = eerste tile is in composition (niet gekoppeld aan welk FocusRequester-object)
|
||||
DisposableEffect(Unit) {
|
||||
onFocusReady?.invoke(true)
|
||||
onDispose { onFocusReady?.invoke(false) }
|
||||
}
|
||||
var focused by remember { mutableStateOf(false) }
|
||||
Surface(
|
||||
onClick = onOpen,
|
||||
|
|
|
|||
Loading…
Reference in a new issue