mirror of
https://github.com/d4rken-org/capod.git
synced 2026-09-16 11:16:12 -04:00
fix(navigation): Defer onNewIntent navCtrl call until Compose attaches
Move consumeUpgradeExtra() out of MainActivity.onNewIntent and into a Compose-level LaunchedEffect that collects a new MainActivity.warmIntents SingleEventFlow.
onNewIntent could fire before the setContent{} lambda registered the back stack with NavigationController, leaving navCtrl.goTo(Nav.Main.Upgrade) to throw IllegalStateException("NavigationController not initialized"). Same race shipped a fix for in octi (d4rken-org/octi#284).
This commit is contained in:
committed by
Matthias Urhahn
parent
8a81d354e6
commit
ebfb034fdd
@@ -24,6 +24,7 @@ import androidx.lifecycle.lifecycleScope
|
|||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import eu.darken.capod.common.debug.logging.log
|
import eu.darken.capod.common.debug.logging.log
|
||||||
import eu.darken.capod.common.debug.logging.logTag
|
import eu.darken.capod.common.debug.logging.logTag
|
||||||
|
import eu.darken.capod.common.flow.SingleEventFlow
|
||||||
import eu.darken.capod.common.navigation.LocalNavigationController
|
import eu.darken.capod.common.navigation.LocalNavigationController
|
||||||
import eu.darken.capod.common.navigation.Nav
|
import eu.darken.capod.common.navigation.Nav
|
||||||
import eu.darken.capod.common.navigation.NavigationController
|
import eu.darken.capod.common.navigation.NavigationController
|
||||||
@@ -50,6 +51,11 @@ class MainActivity : Activity2() {
|
|||||||
@Inject lateinit var popUpWindow: PopUpWindow
|
@Inject lateinit var popUpWindow: PopUpWindow
|
||||||
@Inject lateinit var upgradeRepo: UpgradeRepo
|
@Inject lateinit var upgradeRepo: UpgradeRepo
|
||||||
|
|
||||||
|
// Buffers warm-start intents (onNewIntent) so they are consumed from inside the Compose tree,
|
||||||
|
// after navCtrl.setup(backStack) has run. Calling navCtrl directly from onNewIntent races with
|
||||||
|
// the asynchronous Compose lambda and crashes if the back stack is not yet registered.
|
||||||
|
private val warmIntents = SingleEventFlow<Intent>()
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
installSplashScreen()
|
installSplashScreen()
|
||||||
@@ -80,7 +86,11 @@ class MainActivity : Activity2() {
|
|||||||
navCtrl.setup(backStack)
|
navCtrl.setup(backStack)
|
||||||
|
|
||||||
LaunchedEffect(Unit) {
|
LaunchedEffect(Unit) {
|
||||||
|
// Cold-start intent (the activity's launching intent).
|
||||||
consumeUpgradeExtra(intent)
|
consumeUpgradeExtra(intent)
|
||||||
|
// Warm-start intents delivered via onNewIntent. Consuming them here (instead of
|
||||||
|
// directly from onNewIntent) guarantees navCtrl.setup() has run.
|
||||||
|
warmIntents.collect { newIntent -> consumeUpgradeExtra(newIntent) }
|
||||||
}
|
}
|
||||||
|
|
||||||
CapodTheme(state = themeState) {
|
CapodTheme(state = themeState) {
|
||||||
@@ -132,7 +142,9 @@ class MainActivity : Activity2() {
|
|||||||
|
|
||||||
override fun onNewIntent(intent: Intent) {
|
override fun onNewIntent(intent: Intent) {
|
||||||
super.onNewIntent(intent)
|
super.onNewIntent(intent)
|
||||||
consumeUpgradeExtra(intent)
|
setIntent(intent)
|
||||||
|
// Defer to the Compose-side collector — navCtrl may not yet be set up here.
|
||||||
|
warmIntents.tryEmit(intent)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun consumeUpgradeExtra(intent: Intent?) {
|
private fun consumeUpgradeExtra(intent: Intent?) {
|
||||||
|
|||||||
Reference in New Issue
Block a user