fix: genre loading spinner + NowPlaying back button priority
GenreViewModel: GenreUiState(genres = it) left isLoading=true (default), so genres loaded but spinner never cleared. Added isLoading=false explicitly. AppNavigation: replace BackHandler + navController.enableOnBackPressed with a DisposableEffect that re-adds an OnBackPressedCallback each time NowPlaying opens. Since callbacks are LIFO, a freshly-added callback always beats the BackHandler NavHost registers internally, regardless of composition order. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
f01fc71f54
commit
42c12cbd3a
2 files changed
+15
-10
No files matched your search
@@ -1,6 +1,7 @@
|
||||
package com.novasonic.app.ui
|
||||
|
||||
import androidx.activity.compose.BackHandler
|
||||
import androidx.activity.OnBackPressedCallback
|
||||
import androidx.activity.compose.LocalOnBackPressedDispatcherOwner
|
||||
import androidx.compose.animation.*
|
||||
import androidx.compose.animation.core.FastOutSlowInEasing
|
||||
import androidx.compose.animation.core.tween
|
||||
@@ -69,10 +70,17 @@ fun AppNavigation() {
|
||||
val navController = rememberNavController()
|
||||
var showNowPlaying by remember { mutableStateOf(false) }
|
||||
|
||||
// Disable NavController's own back-stack handler while NowPlaying is open so
|
||||
// our BackHandler below takes priority instead of it popping tabs first.
|
||||
LaunchedEffect(showNowPlaying) {
|
||||
navController.enableOnBackPressed(!showNowPlaying)
|
||||
// Re-register a fresh callback each time NowPlaying opens so it is always
|
||||
// the LAST entry in the dispatcher queue (LIFO = highest priority), beating
|
||||
// the BackHandler that NavHost registers internally for its own back stack.
|
||||
val backDispatcher = LocalOnBackPressedDispatcherOwner.current?.onBackPressedDispatcher
|
||||
DisposableEffect(showNowPlaying, backDispatcher) {
|
||||
if (!showNowPlaying || backDispatcher == null) return@DisposableEffect onDispose {}
|
||||
val cb = object : OnBackPressedCallback(true) {
|
||||
override fun handleOnBackPressed() { showNowPlaying = false }
|
||||
}
|
||||
backDispatcher.addCallback(cb)
|
||||
onDispose { cb.remove() }
|
||||
}
|
||||
|
||||
var contextMenuSong by remember { mutableStateOf<Song?>(null) }
|
||||
@@ -298,9 +306,6 @@ fun AppNavigation() {
|
||||
}
|
||||
}
|
||||
|
||||
// Dismiss NowPlaying with hardware back button
|
||||
BackHandler(enabled = showNowPlaying) { showNowPlaying = false }
|
||||
|
||||
// NowPlaying overlay — outside Scaffold so WindowInsets are not double-consumed
|
||||
AnimatedVisibility(
|
||||
visible = showNowPlaying,
|
||||
|
||||
@@ -26,8 +26,8 @@ class GenreViewModel(app: Application) : AndroidViewModel(app) {
|
||||
viewModelScope.launch {
|
||||
_state.value = GenreUiState(isLoading = true)
|
||||
runCatching { repo.getGenres().filter { it.songCount > 0 }.sortedByDescending { it.songCount } }
|
||||
.onSuccess { _state.value = GenreUiState(genres = it) }
|
||||
.onFailure { _state.value = GenreUiState(error = it.message) }
|
||||
.onSuccess { _state.value = GenreUiState(genres = it, isLoading = false) }
|
||||
.onFailure { _state.value = GenreUiState(error = it.message, isLoading = false) }
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user