manager: Enhance Flash module handling

- Module screen for batch installation

Signed-off-by: ShirkNeko <109797057+ShirkNeko@users.noreply.github.com>
This commit is contained in:
ShirkNeko
2025-05-19 14:07:40 +08:00
parent b587216b5e
commit 4ff46a4911
2 changed files with 33 additions and 4 deletions

View File

@@ -24,6 +24,7 @@ import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.dropUnlessResumed import androidx.lifecycle.compose.dropUnlessResumed
import com.ramcosta.composedestinations.annotation.Destination import com.ramcosta.composedestinations.annotation.Destination
import com.ramcosta.composedestinations.annotation.RootGraph import com.ramcosta.composedestinations.annotation.RootGraph
import com.ramcosta.composedestinations.generated.destinations.FlashScreenDestination
import com.ramcosta.composedestinations.navigation.DestinationsNavigator import com.ramcosta.composedestinations.navigation.DestinationsNavigator
import com.ramcosta.composedestinations.navigation.EmptyDestinationsNavigator import com.ramcosta.composedestinations.navigation.EmptyDestinationsNavigator
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
@@ -33,6 +34,7 @@ import kotlinx.parcelize.Parcelize
import com.sukisu.ultra.ui.component.KeyEventBlocker import com.sukisu.ultra.ui.component.KeyEventBlocker
import com.sukisu.ultra.ui.util.* import com.sukisu.ultra.ui.util.*
import com.sukisu.ultra.R import com.sukisu.ultra.R
import com.sukisu.ultra.ui.theme.CardConfig
import java.io.File import java.io.File
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.* import java.util.*
@@ -80,6 +82,16 @@ fun FlashScreen(navigator: DestinationsNavigator, flashIt: FlashIt) {
text += "\n\n\n" text += "\n\n\n"
showFloatAction = true showFloatAction = true
} }
if (flashIt is FlashIt.FlashModules && flashIt.currentIndex < flashIt.uris.size - 1) {
val nextFlashIt = flashIt.copy(
currentIndex = flashIt.currentIndex + 1
)
scope.launch {
kotlinx.coroutines.delay(500)
navigator.navigate(FlashScreenDestination(nextFlashIt))
}
}
}, onStdout = { }, onStdout = {
tempText = "$it\n" tempText = "$it\n"
if (tempText.startsWith("[H[J")) { // clear command if (tempText.startsWith("[H[J")) { // clear command
@@ -166,6 +178,7 @@ fun FlashScreen(navigator: DestinationsNavigator, flashIt: FlashIt) {
sealed class FlashIt : Parcelable { 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 object FlashRestore : FlashIt() data object FlashRestore : FlashIt()
data object FlashUninstall : FlashIt() data object FlashUninstall : FlashIt()
} }
@@ -186,6 +199,17 @@ fun flashIt(
onStderr onStderr
) )
is FlashIt.FlashModule -> flashModule(flashIt.uri, onFinish, onStdout, onStderr) is FlashIt.FlashModule -> flashModule(flashIt.uri, onFinish, onStdout, onStderr)
is FlashIt.FlashModules -> {
if (flashIt.uris.isEmpty() || flashIt.currentIndex >= flashIt.uris.size) {
onFinish(false, 0)
return
}
val currentUri = flashIt.uris[flashIt.currentIndex]
onStdout("Installing module ${flashIt.currentIndex + 1} of ${flashIt.uris.size}")
flashModule(currentUri, onFinish, onStdout, onStderr)
}
FlashIt.FlashRestore -> restoreBoot(onFinish, onStdout, onStderr) FlashIt.FlashRestore -> restoreBoot(onFinish, onStdout, onStderr)
FlashIt.FlashUninstall -> uninstallPermanently(onFinish, onStdout, onStderr) FlashIt.FlashUninstall -> uninstallPermanently(onFinish, onStdout, onStderr)
} }
@@ -199,6 +223,9 @@ private fun TopBar(
onSave: () -> Unit = {}, onSave: () -> Unit = {},
scrollBehavior: TopAppBarScrollBehavior? = null scrollBehavior: TopAppBarScrollBehavior? = null
) { ) {
val cardColor = MaterialTheme.colorScheme.surfaceVariant
val cardAlpha = CardConfig.cardAlpha
TopAppBar( TopAppBar(
title = { title = {
Text( Text(
@@ -216,6 +243,10 @@ private fun TopBar(
onClick = onBack onClick = onBack
) { Icon(Icons.AutoMirrored.Filled.ArrowBack, contentDescription = null) } ) { Icon(Icons.AutoMirrored.Filled.ArrowBack, contentDescription = null) }
}, },
colors = TopAppBarDefaults.topAppBarColors(
containerColor = cardColor.copy(alpha = cardAlpha),
scrolledContainerColor = cardColor.copy(alpha = cardAlpha)
),
actions = { actions = {
IconButton(onClick = onSave) { IconButton(onClick = onSave) {
Icon( Icon(

View File

@@ -97,7 +97,7 @@ fun ModuleScreen(navigator: DestinationsNavigator) {
val clipData = data.clipData val clipData = data.clipData
if (clipData != null) { if (clipData != null) {
// 处理多选结果 // 处理多选结果
val selectedModules = mutableSetOf<Uri>() val selectedModules = mutableListOf<Uri>()
val selectedModuleNames = mutableMapOf<Uri, String>() val selectedModuleNames = mutableMapOf<Uri, String>()
suspend fun processUri(uri: Uri) { suspend fun processUri(uri: Uri) {
@@ -146,9 +146,7 @@ fun ModuleScreen(navigator: DestinationsNavigator) {
if (confirmResult == ConfirmResult.Confirmed) { if (confirmResult == ConfirmResult.Confirmed) {
// 批量安装模块 // 批量安装模块
selectedModules.forEach { uri -> navigator.navigate(FlashScreenDestination(FlashIt.FlashModules(selectedModules)))
navigator.navigate(FlashScreenDestination(FlashIt.FlashModule(uri)))
}
viewModel.markNeedRefresh() viewModel.markNeedRefresh()
} }
} else { } else {