Fix blank flash screen and crash when flashing module zips

FlashScreen's useTerminal was a plain getter on flashAction, which was
only set in LaunchedEffect (after first composition). Since it wasn't
a Compose State, no recomposition occurred, leaving the screen stuck on
an empty LazyColumn. The unreachable TerminalComposeView meant
onEmulatorReady was never called, hanging the coroutine and eventually
crashing the process.

Pass the action from the route key directly to FlashScreen so it can
pick the correct UI path on the very first composition.

Made-with: Cursor
This commit is contained in:
LoveSy
2026-03-05 16:45:02 +08:00
committed by topjohnwu
parent b087cb2876
commit 162b84661b
3 changed files with 5 additions and 5 deletions
@@ -183,7 +183,7 @@ class MainActivity : AppCompatActivity(), SplashScreenHost {
vm.startFlashing()
}
}
FlashScreen(vm, onBack = { navigator.pop() })
FlashScreen(vm, action = key.action, onBack = { navigator.pop() })
}
entry<Route.SuperuserDetail> { key ->
val vm: SuperuserViewModel = androidx.lifecycle.viewmodel.compose.viewModel(
@@ -19,6 +19,7 @@ import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.core.Const
import com.topjohnwu.magisk.ui.terminal.TerminalComposeView
import top.yukonga.miuix.kmp.basic.Icon
import top.yukonga.miuix.kmp.basic.IconButton
@@ -32,10 +33,11 @@ import top.yukonga.miuix.kmp.theme.MiuixTheme
import com.topjohnwu.magisk.core.R as CoreR
@Composable
fun FlashScreen(viewModel: FlashViewModel, onBack: () -> Unit) {
fun FlashScreen(viewModel: FlashViewModel, action: String, onBack: () -> Unit) {
val flashState by viewModel.flashState.collectAsState()
val showReboot by viewModel.showReboot.collectAsState()
val finished = flashState != FlashViewModel.State.FLASHING
val useTerminal = action == Const.Value.FLASH_ZIP
val statusText = when (flashState) {
FlashViewModel.State.FLASHING -> stringResource(CoreR.string.flashing)
@@ -91,7 +93,7 @@ fun FlashScreen(viewModel: FlashViewModel, onBack: () -> Unit) {
},
popupHost = { }
) { padding ->
if (viewModel.useTerminal) {
if (useTerminal) {
val session by viewModel.termSession.collectAsState()
TerminalComposeView(
session = session,
@@ -58,8 +58,6 @@ class FlashViewModel : BaseViewModel() {
private val emulatorReady = CompletableDeferred<Unit>()
val sessionCallback = TerminalSessionCallback()
val useTerminal get() = flashAction == Const.Value.FLASH_ZIP
fun setTerminalView(view: TerminalView) {
sessionCallback.terminalView = view
}