manager: Adding a separate status to the update module

fix duplicate installations of update modules due to status confusion. fix #287

Signed-off-by: ShirkNeko <109797057+ShirkNeko@users.noreply.github.com>
This commit is contained in:
ShirkNeko
2025-07-19 16:59:36 +08:00
parent 60f0a721ce
commit b8544b4f53
2 changed files with 96 additions and 15 deletions

View File

@@ -113,6 +113,9 @@ fun FlashScreen(navigator: DestinationsNavigator, flashIt: FlashIt) {
// 添加状态跟踪是否已经完成刷写 // 添加状态跟踪是否已经完成刷写
var hasFlashCompleted by rememberSaveable { mutableStateOf(false) } var hasFlashCompleted by rememberSaveable { mutableStateOf(false) }
var hasExecuted by rememberSaveable { mutableStateOf(false) } var hasExecuted by rememberSaveable { mutableStateOf(false) }
// 更新模块状态管理
var hasUpdateExecuted by rememberSaveable { mutableStateOf(false) }
var hasUpdateCompleted by rememberSaveable { mutableStateOf(false) }
val snackBarHost = LocalSnackbarHost.current val snackBarHost = LocalSnackbarHost.current
val scope = rememberCoroutineScope() val scope = rememberCoroutineScope()
@@ -130,21 +133,76 @@ fun FlashScreen(navigator: DestinationsNavigator, flashIt: FlashIt) {
// 重置状态 // 重置状态
LaunchedEffect(flashIt) { LaunchedEffect(flashIt) {
if (flashIt is FlashIt.FlashModules && flashIt.currentIndex == 0) { when (flashIt) {
moduleInstallStatus.value = ModuleInstallStatus( is FlashIt.FlashModules -> {
totalModules = flashIt.uris.size, if (flashIt.currentIndex == 0) {
currentModule = 1 moduleInstallStatus.value = ModuleInstallStatus(
) totalModules = flashIt.uris.size,
hasFlashCompleted = false currentModule = 1
hasExecuted = false )
} else if (flashIt !is FlashIt.FlashModules) { hasFlashCompleted = false
hasFlashCompleted = false hasExecuted = false
hasExecuted = false }
}
is FlashIt.FlashModuleUpdate -> {
hasUpdateCompleted = false
hasUpdateExecuted = false
}
else -> {
hasFlashCompleted = false
hasExecuted = false
}
} }
} }
// 只有在未完成刷写时才执行刷写操作 // 处理更新模块安装
LaunchedEffect(flashIt) { LaunchedEffect(flashIt) {
if (flashIt !is FlashIt.FlashModuleUpdate) return@LaunchedEffect
if (hasUpdateExecuted || hasUpdateCompleted || text.isNotEmpty()) {
return@LaunchedEffect
}
hasUpdateExecuted = true
withContext(Dispatchers.IO) {
setFlashingStatus(FlashingStatus.FLASHING)
try {
logContent.append(text).append("\n")
} catch (_: Exception) {
logContent.append(text).append("\n")
}
flashModuleUpdate(flashIt.uri, onFinish = { showReboot, code ->
if (code != 0) {
text += "$errorCodeString $code.\n$checkLogString\n"
setFlashingStatus(FlashingStatus.FAILED)
} else {
setFlashingStatus(FlashingStatus.SUCCESS)
viewModel.markNeedRefresh()
}
if (showReboot) {
text += "\n\n\n"
showFloatAction = true
}
hasUpdateCompleted = true
}, onStdout = {
tempText = "$it\n"
if (tempText.startsWith("")) { // clear command
text = tempText.substring(6)
} else {
text += tempText
}
logContent.append(it).append("\n")
}, onStderr = {
logContent.append(it).append("\n")
})
}
}
// 安装但排除更新模块
LaunchedEffect(flashIt) {
if (flashIt is FlashIt.FlashModuleUpdate) return@LaunchedEffect
if (hasExecuted || hasFlashCompleted || text.isNotEmpty()) { if (hasExecuted || hasFlashCompleted || text.isNotEmpty()) {
return@LaunchedEffect return@LaunchedEffect
} }
@@ -214,8 +272,13 @@ fun FlashScreen(navigator: DestinationsNavigator, flashIt: FlashIt) {
} }
val onBack: () -> Unit = { val onBack: () -> Unit = {
if (currentFlashingStatus.value != FlashingStatus.FLASHING) { val canGoBack = when (flashIt) {
if (flashIt is FlashIt.FlashModules) { is FlashIt.FlashModuleUpdate -> currentFlashingStatus.value != FlashingStatus.FLASHING
else -> currentFlashingStatus.value != FlashingStatus.FLASHING
}
if (canGoBack) {
if (flashIt is FlashIt.FlashModules || flashIt is FlashIt.FlashModuleUpdate) {
viewModel.markNeedRefresh() viewModel.markNeedRefresh()
viewModel.fetchModuleList() viewModel.fetchModuleList()
navigator.navigate(ModuleScreenDestination) navigator.navigate(ModuleScreenDestination)
@@ -364,7 +427,7 @@ fun ModuleInstallProgressBar(
horizontalArrangement = Arrangement.SpaceBetween horizontalArrangement = Arrangement.SpaceBetween
) { ) {
Text( Text(
text = if (currentModuleName.isNotEmpty()) currentModuleName else stringResource(R.string.module), text = currentModuleName.ifEmpty { stringResource(R.string.module) },
style = MaterialTheme.typography.titleMedium, style = MaterialTheme.typography.titleMedium,
fontWeight = FontWeight.Bold fontWeight = FontWeight.Bold
) )
@@ -536,10 +599,21 @@ sealed class FlashIt : Parcelable {
data class FlashBoot(val boot: Uri? = null, val lkm: LkmSelection, val ota: Boolean) : FlashIt() data class FlashBoot(val boot: Uri? = null, val lkm: LkmSelection, val ota: Boolean) : FlashIt()
data class FlashModule(val uri: Uri) : FlashIt() data class FlashModule(val uri: Uri) : FlashIt()
data class FlashModules(val uris: List<Uri>, val currentIndex: Int = 0) : FlashIt() data class FlashModules(val uris: List<Uri>, val currentIndex: Int = 0) : FlashIt()
data class FlashModuleUpdate(val uri: Uri) : FlashIt() // 模块更新
data object FlashRestore : FlashIt() data object FlashRestore : FlashIt()
data object FlashUninstall : FlashIt() data object FlashUninstall : FlashIt()
} }
// 模块更新刷写
fun flashModuleUpdate(
uri: Uri,
onFinish: (Boolean, Int) -> Unit,
onStdout: (String) -> Unit,
onStderr: (String) -> Unit
) {
flashModule(uri, onFinish, onStdout, onStderr)
}
fun flashIt( fun flashIt(
flashIt: FlashIt, flashIt: FlashIt,
onFinish: (Boolean, Int) -> Unit, onFinish: (Boolean, Int) -> Unit,
@@ -567,6 +641,9 @@ fun flashIt(
flashModule(currentUri, onFinish, onStdout, onStderr) flashModule(currentUri, onFinish, onStdout, onStderr)
} }
is FlashIt.FlashModuleUpdate -> {
onFinish(false, 0)
}
FlashIt.FlashRestore -> restoreBoot(onFinish, onStdout, onStderr) FlashIt.FlashRestore -> restoreBoot(onFinish, onStdout, onStderr)
FlashIt.FlashUninstall -> uninstallPermanently(onFinish, onStdout, onStderr) FlashIt.FlashUninstall -> uninstallPermanently(onFinish, onStdout, onStderr)
} }

View File

@@ -352,6 +352,9 @@ fun ModuleScreen(navigator: DestinationsNavigator) {
onInstallModule = { onInstallModule = {
navigator.navigate(FlashScreenDestination(FlashIt.FlashModule(it))) navigator.navigate(FlashScreenDestination(FlashIt.FlashModule(it)))
}, },
onUpdateModule = {
navigator.navigate(FlashScreenDestination(FlashIt.FlashModuleUpdate(it)))
},
onClickModule = { id, name, hasWebUi -> onClickModule = { id, name, hasWebUi ->
val currentTime = System.currentTimeMillis() val currentTime = System.currentTimeMillis()
if (currentTime - lastClickTime < 600) { if (currentTime - lastClickTime < 600) {
@@ -622,6 +625,7 @@ private fun ModuleList(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
boxModifier: Modifier = Modifier, boxModifier: Modifier = Modifier,
onInstallModule: (Uri) -> Unit, onInstallModule: (Uri) -> Unit,
onUpdateModule: (Uri) -> Unit,
onClickModule: (id: String, name: String, hasWebUi: Boolean) -> Unit, onClickModule: (id: String, name: String, hasWebUi: Boolean) -> Unit,
context: Context, context: Context,
snackBarHost: SnackbarHostState snackBarHost: SnackbarHostState
@@ -709,7 +713,7 @@ private fun ModuleList(
downloadUrl, downloadUrl,
fileName, fileName,
downloading, downloading,
onDownloaded = onInstallModule, onDownloaded = onUpdateModule,
onDownloading = { onDownloading = {
launch(Dispatchers.Main) { launch(Dispatchers.Main) {
Toast.makeText(context, downloading, Toast.LENGTH_SHORT).show() Toast.makeText(context, downloading, Toast.LENGTH_SHORT).show()