diff --git a/manager/app/src/main/java/com/sukisu/ultra/flash/KernelFlash.kt b/manager/app/src/main/java/com/sukisu/ultra/flash/KernelFlash.kt index 85bff66f..343c265f 100644 --- a/manager/app/src/main/java/com/sukisu/ultra/flash/KernelFlash.kt +++ b/manager/app/src/main/java/com/sukisu/ultra/flash/KernelFlash.kt @@ -354,7 +354,7 @@ fun HorizonKernelFlashProgress(state: FlashState) { Surface( modifier = Modifier .fillMaxWidth() - .heightIn(max = 150.dp) + .heightIn(max = 230.dp) .padding(vertical = 4.dp), color = MaterialTheme.colorScheme.surface, tonalElevation = 1.dp, diff --git a/manager/app/src/main/java/com/sukisu/ultra/ui/screen/Install.kt b/manager/app/src/main/java/com/sukisu/ultra/ui/screen/Install.kt index faad2c2b..1758922f 100644 --- a/manager/app/src/main/java/com/sukisu/ultra/ui/screen/Install.kt +++ b/manager/app/src/main/java/com/sukisu/ultra/ui/screen/Install.kt @@ -21,6 +21,7 @@ import androidx.compose.foundation.selection.toggleable import androidx.compose.foundation.verticalScroll import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.ArrowBack +import androidx.compose.material.icons.filled.AutoFixHigh import androidx.compose.material.icons.filled.FileUpload import androidx.compose.material3.* import androidx.compose.runtime.* @@ -335,8 +336,16 @@ private fun SelectInstallMethod(onSelected: (InstallMethod) -> Unit = {}) { if (it.resultCode == Activity.RESULT_OK) { it.data?.data?.let { uri -> val option = when (currentSelectingMethod) { - is InstallMethod.SelectFile -> InstallMethod.SelectFile(uri, summary = selectFileTip) - is InstallMethod.HorizonKernel -> InstallMethod.HorizonKernel(uri, summary = horizonKernelSummary) + is InstallMethod.SelectFile -> InstallMethod.SelectFile( + uri, + summary = selectFileTip + ) + + is InstallMethod.HorizonKernel -> InstallMethod.HorizonKernel( + uri, + summary = horizonKernelSummary + ) + else -> null } option?.let { @@ -364,57 +373,136 @@ private fun SelectInstallMethod(onSelected: (InstallMethod) -> Unit = {}) { is InstallMethod.SelectFile, is InstallMethod.HorizonKernel -> { selectImageLauncher.launch(Intent(Intent.ACTION_GET_CONTENT).apply { type = "application/*" - putExtra(Intent.EXTRA_MIME_TYPES, arrayOf("application/octet-stream", "application/zip")) + putExtra( + Intent.EXTRA_MIME_TYPES, + arrayOf("application/octet-stream", "application/zip") + ) }) } + is InstallMethod.DirectInstall -> { selectedOption = option onSelected(option) } + is InstallMethod.DirectInstallToInactiveSlot -> { confirmDialog.showConfirm(dialogTitle, dialogContent) } } } + var LKMExpanded by remember { mutableStateOf(false) } + var GKIExpanded by remember { mutableStateOf(false) } + Column { - radioOptions.forEach { option -> - val interactionSource = remember { MutableInteractionSource() } - Row( - verticalAlignment = Alignment.CenterVertically, - modifier = Modifier - .fillMaxWidth() - .toggleable( - value = option.javaClass == selectedOption?.javaClass, - onValueChange = { onClick(option) }, - role = Role.RadioButton, - indication = LocalIndication.current, - interactionSource = interactionSource - ) + ListItem( + leadingContent = { Icon(Icons.Filled.AutoFixHigh, null) }, + headlineContent = { Text(stringResource(R.string.Lkm_install_methods)) }, + modifier = Modifier.clickable { + LKMExpanded = !LKMExpanded + } + ) + radioOptions.take(3).forEach { option -> + AnimatedVisibility( + visible = LKMExpanded, + modifier = Modifier.fillMaxWidth().padding(horizontal = 24.dp) ) { - RadioButton( - selected = option.javaClass == selectedOption?.javaClass, - onClick = { onClick(option) }, - interactionSource = interactionSource - ) - Column( - modifier = Modifier.padding(vertical = 12.dp) - ) { - Text( - text = stringResource(id = option.label), - fontSize = MaterialTheme.typography.titleMedium.fontSize, - fontFamily = MaterialTheme.typography.titleMedium.fontFamily, - fontStyle = MaterialTheme.typography.titleMedium.fontStyle - ) - option.summary?.let { - Text( - text = it, - fontSize = MaterialTheme.typography.bodySmall.fontSize, - fontFamily = MaterialTheme.typography.bodySmall.fontFamily, - fontStyle = MaterialTheme.typography.bodySmall.fontStyle + Column { + val interactionSource = remember { MutableInteractionSource() } + Row( + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier + .fillMaxWidth() + .toggleable( + value = option.javaClass == selectedOption?.javaClass, + onValueChange = { onClick(option) }, + role = Role.RadioButton, + indication = LocalIndication.current, + interactionSource = interactionSource + ) + ) { + RadioButton( + selected = option.javaClass == selectedOption?.javaClass, + onClick = { onClick(option) }, + interactionSource = interactionSource ) + Column( + modifier = Modifier.padding(vertical = 12.dp) + ) { + Text( + text = stringResource(id = option.label), + fontSize = MaterialTheme.typography.titleMedium.fontSize, + fontFamily = MaterialTheme.typography.titleMedium.fontFamily, + fontStyle = MaterialTheme.typography.titleMedium.fontStyle + ) + option.summary?.let { + Text( + text = it, + fontSize = MaterialTheme.typography.bodySmall.fontSize, + fontFamily = MaterialTheme.typography.bodySmall.fontFamily, + fontStyle = MaterialTheme.typography.bodySmall.fontStyle + ) + } + } } } + Spacer(modifier = Modifier.height(8.dp)) + } + } + } + Column { + ListItem( + leadingContent = { Icon(Icons.Filled.FileUpload, null) }, + headlineContent = { Text(stringResource(R.string.GKI_install_methods)) }, + modifier = Modifier.clickable { + GKIExpanded = !GKIExpanded + } + ) + AnimatedVisibility( + visible = GKIExpanded, + modifier = Modifier.fillMaxWidth().padding(horizontal = 24.dp) + ) { + Column { + radioOptions.drop(3).forEach { option -> + val interactionSource = remember { MutableInteractionSource() } + Row( + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier + .fillMaxWidth() + .toggleable( + value = option.javaClass == selectedOption?.javaClass, + onValueChange = { onClick(option) }, + role = Role.RadioButton, + indication = LocalIndication.current, + interactionSource = interactionSource + ) + ) { + RadioButton( + selected = option.javaClass == selectedOption?.javaClass, + onClick = { onClick(option) }, + interactionSource = interactionSource + ) + Column( + modifier = Modifier.padding(vertical = 12.dp) + ) { + Text( + text = stringResource(id = option.label), + fontSize = MaterialTheme.typography.titleMedium.fontSize, + fontFamily = MaterialTheme.typography.titleMedium.fontFamily, + fontStyle = MaterialTheme.typography.titleMedium.fontStyle + ) + option.summary?.let { + Text( + text = it, + fontSize = MaterialTheme.typography.bodySmall.fontSize, + fontFamily = MaterialTheme.typography.bodySmall.fontFamily, + fontStyle = MaterialTheme.typography.bodySmall.fontStyle + ) + } + } + } + Spacer(modifier = Modifier.height(8.dp)) + } } } } @@ -522,11 +610,6 @@ private fun TopBar( Icon(Icons.AutoMirrored.Filled.ArrowBack, contentDescription = null) } }, - actions = { - IconButton(onClick = onLkmUpload) { - Icon(Icons.Filled.FileUpload, contentDescription = null) - } - }, windowInsets = WindowInsets.safeDrawing.only( WindowInsetsSides.Top + WindowInsetsSides.Horizontal ), diff --git a/manager/app/src/main/res/values-zh-rCN/strings.xml b/manager/app/src/main/res/values-zh-rCN/strings.xml index 40de3327..6f9e2c8b 100644 --- a/manager/app/src/main/res/values-zh-rCN/strings.xml +++ b/manager/app/src/main/res/values-zh-rCN/strings.xml @@ -117,7 +117,7 @@ 启用 WebView 调试 可用于调试 WebUI 。请仅在需要时启用。 直接安装(推荐) - 选择一个文件 + 选择一个需要修补的镜像 安装到未使用的槽位(OTA 后) 将在重启后强制切换到另一个槽位!\n注意只能在 OTA 更新完成后的重启之前使用。\n确认? 下一步 @@ -284,12 +284,15 @@ A槽位 B槽位 已选择槽位: %1$s - - 复制失败 - 未知错误 获取原有槽位 设置指定槽位 恢复默认槽位 当前槽位:%1$s + + 复制失败 + 未知错误 刷写失败 + + LKM修补/安装 + GKI安装 diff --git a/manager/app/src/main/res/values/strings.xml b/manager/app/src/main/res/values/strings.xml index 2e7f51dd..382f6b9a 100644 --- a/manager/app/src/main/res/values/strings.xml +++ b/manager/app/src/main/res/values/strings.xml @@ -118,7 +118,7 @@ Enable WebView debugging Can be used to debug WebUI. Please enable only when needed. Direct install (Recommended) - Select a file + Select a mirror that needs to be patched Install to inactive slot (After OTA) Your device will be **FORCED** to boot to the current inactive slot after a reboot!\nOnly use this option after OTA is done.\nContinue? Next @@ -288,12 +288,15 @@ Slot A Slot B Selected slot: %1$s - - Copy failed - Unknown error Getting the original slot Setting the specified slot Restore Default Slot Current Slot:%1$s + + Copy failed + Unknown error Flash failed + + LKM repair/installation + GKI installation