fix: sync Android navigation state with in-app destination changes

MainActivity kept its own currentDestination alongside FluxaAppHost's
internal appState.uiState.destination, with only a one-way sync
(external -> internal). Any purely-internal navigation (bottom nav
taps, "switch profiles" from Settings) moved appState's destination
without MainActivity's copy ever finding out. If a later external
navigation call (e.g. profile selection completing) happened to name
a destination MainActivity's stale copy already equaled, it was
treated as a no-op and silently dropped -- reproducible by going
Settings -> Switch profiles -> tapping a profile, which then did
nothing.

Add a callback that mirrors appState's destination back out to
MainActivity whenever it changes internally, and guard the existing
external->internal effect so it only re-applies on a genuine change
(avoiding a reset loop that would otherwise wipe editingProfile/
selectedDetail/etc. on every round trip).

Also account for showProfilePickerSettings in the screen transition
key, which was missing and left the profile picker settings screen
keyed identically to whatever destination was active underneath it.
This commit is contained in:
KhooLy 2026-07-28 02:23:47 +03:00
parent 8318822ce6
commit cfc03cba00
4 changed files with 14 additions and 2 deletions

View file

@ -531,6 +531,7 @@ class MainActivity : FragmentActivity() {
settingsPopRequestId = settingsPopRequestId,
onSettingsCanPopChanged = { canPopSettings = it },
onNavigateToDestination = { destination -> navigateToDestination(destination, false) },
onDestinationChanged = { destination -> currentDestination = destination },
onPlayerRequestChanged = { playerRequest = it },
profileManager = profileManager,
homeViewModel = homeViewModel,

View file

@ -61,7 +61,8 @@ internal fun AppRoutesHost(
onUpdateInfoChanged: (UpdateManager.UpdateInfo?) -> Unit,
navigateBackSafely: () -> Unit,
settingsPopRequestId: Int,
onSettingsCanPopChanged: (Boolean) -> Unit
onSettingsCanPopChanged: (Boolean) -> Unit,
onDestinationChanged: (FluxaDestination) -> Unit = {}
) {
if (playerRequest != null) {
PlayerRoute(
@ -226,6 +227,7 @@ internal fun AppRoutesHost(
onSettingsBackRequested = navigateBackSafely,
settingsPopRequestId = settingsPopRequestId,
onSettingsCanPopChanged = onSettingsCanPopChanged,
onDestinationChanged = onDestinationChanged,
onManageAddonsRequested = { onNavigateToDestination(FluxaDestination.AddonStore) },
onManagePluginsRequested = { onNavigateToDestination(FluxaDestination.Plugins) },
onConnectStremioRequested = {

View file

@ -247,6 +247,7 @@ fun FluxaApp(
val screenKey = when {
playerState?.content != null -> "player:${playerState.content?.id.orEmpty()}"
state.editingProfile != null -> "profileEdit"
state.showProfilePickerSettings -> "profilePickerSettings"
state.showSourceSelection -> "sources"
state.selectedDetail != null -> "detail:${state.selectedDetail.id}"
libraryState?.folderDetail?.folder != null -> "folder:${libraryState.folderDetail.folder.id}"

View file

@ -101,6 +101,7 @@ fun FluxaAppHost(
onSettingsBackRequested: () -> Unit = {},
settingsPopRequestId: Int = 0,
onSettingsCanPopChanged: (Boolean) -> Unit = {},
onDestinationChanged: (FluxaDestination) -> Unit = {},
modifier: Modifier = Modifier
) {
FluxaAppHost(
@ -150,6 +151,7 @@ fun FluxaAppHost(
onSettingsBackRequested = onSettingsBackRequested,
settingsPopRequestId = settingsPopRequestId,
onSettingsCanPopChanged = onSettingsCanPopChanged,
onDestinationChanged = onDestinationChanged,
modifier = modifier
)
}
@ -202,6 +204,7 @@ fun FluxaAppHost(
onSettingsBackRequested: () -> Unit = {},
settingsPopRequestId: Int = 0,
onSettingsCanPopChanged: (Boolean) -> Unit = {},
onDestinationChanged: (FluxaDestination) -> Unit = {},
modifier: Modifier = Modifier
) {
val scope = rememberCoroutineScope()
@ -255,6 +258,9 @@ fun FluxaAppHost(
catalogHome = catalogHome
)
)
LaunchedEffect(appState.uiState.destination) {
onDestinationChanged(appState.uiState.destination)
}
var profileAvatarUrl by remember(appState.uiState.editingProfile) {
val target = appState.uiState.editingProfile
val initial = (target as? ProfileEditTarget.Existing)?.let { existing ->
@ -288,7 +294,9 @@ fun FluxaAppHost(
appState.updateLanguage(language)
}
LaunchedEffect(destination) {
destination?.let(appState::selectDestination)
if (destination != null && destination != appState.uiState.destination) {
appState.selectDestination(destination)
}
}
LaunchedEffect(detailRequest) {
detailRequest?.let(appState::selectDetail)