Step 5-2: Simplify and separate the main logic for flashing anykernel3
This commit is contained in:
@@ -0,0 +1,252 @@
|
||||
package com.sukisu.ultra.ui.kernelFlash
|
||||
|
||||
import android.net.Uri
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Security
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.MutableState
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.DpSize
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.core.net.toUri
|
||||
import com.sukisu.ultra.R
|
||||
import com.sukisu.ultra.ui.screen.InstallMethod
|
||||
import top.yukonga.miuix.kmp.basic.Icon
|
||||
import top.yukonga.miuix.kmp.basic.Text
|
||||
import top.yukonga.miuix.kmp.basic.TextButton
|
||||
import top.yukonga.miuix.kmp.extra.SuperArrow
|
||||
import top.yukonga.miuix.kmp.extra.SuperDialog
|
||||
import top.yukonga.miuix.kmp.theme.MiuixTheme
|
||||
import top.yukonga.miuix.kmp.theme.MiuixTheme.colorScheme
|
||||
|
||||
enum class KpmPatchOption {
|
||||
FOLLOW_KERNEL,
|
||||
PATCH_KPM,
|
||||
UNDO_PATCH_KPM
|
||||
}
|
||||
|
||||
@Stable
|
||||
data class AnyKernel3State(
|
||||
val kpmPatchOption: KpmPatchOption,
|
||||
val showSlotSelectionDialog: Boolean,
|
||||
val showKpmPatchDialog: Boolean,
|
||||
val onHorizonKernelSelected: (InstallMethod.HorizonKernel) -> Unit,
|
||||
val onSlotSelected: (String) -> Unit,
|
||||
val onDismissSlotDialog: () -> Unit,
|
||||
val onOptionSelected: (KpmPatchOption) -> Unit,
|
||||
val onDismissPatchDialog: () -> Unit
|
||||
)
|
||||
|
||||
@Composable
|
||||
fun rememberAnyKernel3State(
|
||||
installMethodState: MutableState<InstallMethod?>,
|
||||
preselectedKernelUri: String?,
|
||||
horizonKernelSummary: String,
|
||||
isAbDevice: Boolean
|
||||
): AnyKernel3State {
|
||||
var kpmPatchOption by remember { mutableStateOf(KpmPatchOption.FOLLOW_KERNEL) }
|
||||
var showSlotSelectionDialog by remember { mutableStateOf(false) }
|
||||
var showKpmPatchDialog by remember { mutableStateOf(false) }
|
||||
var tempKernelUri by remember { mutableStateOf<Uri?>(null) }
|
||||
|
||||
val onHorizonKernelSelected: (InstallMethod.HorizonKernel) -> Unit = { method ->
|
||||
val uri = method.uri
|
||||
if (uri != null) {
|
||||
if (isAbDevice) {
|
||||
tempKernelUri = uri
|
||||
showSlotSelectionDialog = true
|
||||
} else {
|
||||
installMethodState.value = method
|
||||
showKpmPatchDialog = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val onSlotSelected: (String) -> Unit = { slot ->
|
||||
val uri = tempKernelUri
|
||||
if (uri != null) {
|
||||
installMethodState.value = InstallMethod.HorizonKernel(
|
||||
uri = uri,
|
||||
slot = slot,
|
||||
summary = horizonKernelSummary
|
||||
)
|
||||
tempKernelUri = null
|
||||
showSlotSelectionDialog = false
|
||||
showKpmPatchDialog = true
|
||||
}
|
||||
}
|
||||
|
||||
val onDismissSlotDialog = {
|
||||
showSlotSelectionDialog = false
|
||||
tempKernelUri = null
|
||||
}
|
||||
|
||||
val onOptionSelected: (KpmPatchOption) -> Unit = { option ->
|
||||
kpmPatchOption = option
|
||||
showKpmPatchDialog = false
|
||||
}
|
||||
|
||||
val onDismissPatchDialog = {
|
||||
showKpmPatchDialog = false
|
||||
}
|
||||
|
||||
LaunchedEffect(preselectedKernelUri, isAbDevice, horizonKernelSummary) {
|
||||
preselectedKernelUri?.let { uriString ->
|
||||
runCatching { uriString.toUri() }
|
||||
.getOrNull()
|
||||
?.let { preselectedUri ->
|
||||
val method = InstallMethod.HorizonKernel(
|
||||
uri = preselectedUri,
|
||||
summary = horizonKernelSummary
|
||||
)
|
||||
if (isAbDevice) {
|
||||
tempKernelUri = preselectedUri
|
||||
showSlotSelectionDialog = true
|
||||
} else {
|
||||
installMethodState.value = method
|
||||
showKpmPatchDialog = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return AnyKernel3State(
|
||||
kpmPatchOption = kpmPatchOption,
|
||||
showSlotSelectionDialog = showSlotSelectionDialog,
|
||||
showKpmPatchDialog = showKpmPatchDialog,
|
||||
onHorizonKernelSelected = onHorizonKernelSelected,
|
||||
onSlotSelected = onSlotSelected,
|
||||
onDismissSlotDialog = onDismissSlotDialog,
|
||||
onOptionSelected = onOptionSelected,
|
||||
onDismissPatchDialog = onDismissPatchDialog
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun KpmPatchSelectionDialog(
|
||||
show: Boolean,
|
||||
currentOption: KpmPatchOption,
|
||||
onDismiss: () -> Unit,
|
||||
onOptionSelected: (KpmPatchOption) -> Unit
|
||||
) {
|
||||
var selectedOption by remember { mutableStateOf(currentOption) }
|
||||
val showDialog = remember { mutableStateOf(show) }
|
||||
|
||||
LaunchedEffect(show) {
|
||||
showDialog.value = show
|
||||
if (show) {
|
||||
selectedOption = currentOption
|
||||
}
|
||||
}
|
||||
|
||||
SuperDialog(
|
||||
show = showDialog,
|
||||
insideMargin = DpSize(0.dp, 0.dp),
|
||||
onDismissRequest = {
|
||||
showDialog.value = false
|
||||
onDismiss()
|
||||
},
|
||||
content = {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(vertical = 24.dp)
|
||||
) {
|
||||
Text(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 24.dp, vertical = 12.dp),
|
||||
text = stringResource(id = R.string.kpm_patch_options),
|
||||
fontSize = MiuixTheme.textStyles.title4.fontSize,
|
||||
fontWeight = FontWeight.Medium,
|
||||
textAlign = TextAlign.Center,
|
||||
color = colorScheme.onSurface
|
||||
)
|
||||
|
||||
Text(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 24.dp, vertical = 8.dp),
|
||||
text = stringResource(id = R.string.kpm_patch_description),
|
||||
fontSize = MiuixTheme.textStyles.body2.fontSize,
|
||||
color = colorScheme.onSurfaceVariantSummary,
|
||||
textAlign = TextAlign.Center
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.height(12.dp))
|
||||
|
||||
val options = listOf(
|
||||
KpmPatchOption.FOLLOW_KERNEL to stringResource(R.string.kpm_follow_kernel_file),
|
||||
KpmPatchOption.PATCH_KPM to stringResource(R.string.enable_kpm_patch),
|
||||
KpmPatchOption.UNDO_PATCH_KPM to stringResource(R.string.enable_kpm_undo_patch)
|
||||
)
|
||||
|
||||
options.forEach { (option, title) ->
|
||||
SuperArrow(
|
||||
title = title,
|
||||
onClick = {
|
||||
selectedOption = option
|
||||
},
|
||||
leftAction = {
|
||||
Icon(
|
||||
imageVector = Icons.Filled.Security,
|
||||
contentDescription = null,
|
||||
tint = if (selectedOption == option) {
|
||||
colorScheme.primary
|
||||
} else {
|
||||
colorScheme.onSurfaceVariantSummary
|
||||
}
|
||||
)
|
||||
},
|
||||
insideMargin = PaddingValues(horizontal = 24.dp, vertical = 12.dp)
|
||||
)
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.height(12.dp))
|
||||
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 24.dp),
|
||||
horizontalArrangement = Arrangement.spacedBy(12.dp)
|
||||
) {
|
||||
TextButton(
|
||||
text = stringResource(android.R.string.cancel),
|
||||
onClick = {
|
||||
showDialog.value = false
|
||||
onDismiss()
|
||||
},
|
||||
modifier = Modifier.weight(1f)
|
||||
)
|
||||
TextButton(
|
||||
text = stringResource(android.R.string.ok),
|
||||
onClick = {
|
||||
onOptionSelected(selectedOption)
|
||||
showDialog.value = false
|
||||
onDismiss()
|
||||
},
|
||||
modifier = Modifier.weight(1f)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
@@ -14,7 +14,6 @@ import androidx.compose.animation.expandVertically
|
||||
import androidx.compose.animation.shrinkVertically
|
||||
import androidx.compose.foundation.LocalIndication
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
@@ -47,13 +46,10 @@ import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.semantics.Role
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.SdStorage
|
||||
import androidx.compose.material.icons.filled.Security
|
||||
import androidx.core.net.toUri
|
||||
import androidx.lifecycle.compose.dropUnlessResumed
|
||||
import com.ramcosta.composedestinations.annotation.Destination
|
||||
import com.ramcosta.composedestinations.annotation.RootGraph
|
||||
@@ -69,7 +65,10 @@ import com.sukisu.ultra.R
|
||||
import com.sukisu.ultra.getKernelVersion
|
||||
import com.sukisu.ultra.ui.component.ChooseKmiDialog
|
||||
import com.sukisu.ultra.ui.component.rememberConfirmDialog
|
||||
import com.sukisu.ultra.ui.kernelFlash.KpmPatchOption
|
||||
import com.sukisu.ultra.ui.kernelFlash.KpmPatchSelectionDialog
|
||||
import com.sukisu.ultra.ui.kernelFlash.component.SlotSelectionDialog
|
||||
import com.sukisu.ultra.ui.kernelFlash.rememberAnyKernel3State
|
||||
import com.sukisu.ultra.ui.util.LkmSelection
|
||||
import com.sukisu.ultra.ui.util.getAvailablePartitions
|
||||
import com.sukisu.ultra.ui.util.getCurrentKmi
|
||||
@@ -94,11 +93,6 @@ import top.yukonga.miuix.kmp.icon.MiuixIcons
|
||||
import top.yukonga.miuix.kmp.icon.icons.useful.Back
|
||||
import top.yukonga.miuix.kmp.icon.icons.useful.Edit
|
||||
import top.yukonga.miuix.kmp.icon.icons.useful.Move
|
||||
import top.yukonga.miuix.kmp.extra.SuperDialog
|
||||
import top.yukonga.miuix.kmp.basic.TextButton
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.ui.unit.DpSize
|
||||
import top.yukonga.miuix.kmp.theme.MiuixTheme
|
||||
import top.yukonga.miuix.kmp.theme.MiuixTheme.colorScheme
|
||||
import top.yukonga.miuix.kmp.utils.getWindowSize
|
||||
@@ -109,12 +103,6 @@ import top.yukonga.miuix.kmp.utils.scrollEndHaptic
|
||||
* @author weishu
|
||||
* @date 2024/3/12.
|
||||
*/
|
||||
enum class KpmPatchOption {
|
||||
FOLLOW_KERNEL,
|
||||
PATCH_KPM,
|
||||
UNDO_PATCH_KPM
|
||||
}
|
||||
|
||||
@Composable
|
||||
@Destination<RootGraph>
|
||||
fun InstallScreen(
|
||||
@@ -122,19 +110,15 @@ fun InstallScreen(
|
||||
preselectedKernelUri: String? = null
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
var installMethod by remember {
|
||||
val installMethodState = remember {
|
||||
mutableStateOf<InstallMethod?>(null)
|
||||
}
|
||||
var installMethod by installMethodState
|
||||
|
||||
var lkmSelection by remember {
|
||||
mutableStateOf<LkmSelection>(LkmSelection.KmiNone)
|
||||
}
|
||||
|
||||
var kpmPatchOption by remember { mutableStateOf(KpmPatchOption.FOLLOW_KERNEL) }
|
||||
var showSlotSelectionDialog by remember { mutableStateOf(false) }
|
||||
var showKpmPatchDialog by remember { mutableStateOf(false) }
|
||||
var tempKernelUri by remember { mutableStateOf<Uri?>(null) }
|
||||
|
||||
val kernelVersion = getKernelVersion()
|
||||
val isGKI = kernelVersion.isGKI()
|
||||
val isAbDevice = produceState(initialValue = false) {
|
||||
@@ -145,28 +129,14 @@ fun InstallScreen(
|
||||
var partitionsState by remember { mutableStateOf<List<String>>(emptyList()) }
|
||||
var hasCustomSelected by remember { mutableStateOf(false) }
|
||||
val horizonKernelSummary = stringResource(R.string.horizon_kernel_summary)
|
||||
|
||||
// 处理预选的内核文件
|
||||
LaunchedEffect(preselectedKernelUri) {
|
||||
preselectedKernelUri?.let { uriString ->
|
||||
try {
|
||||
val preselectedUri = uriString.toUri()
|
||||
val horizonMethod = InstallMethod.HorizonKernel(
|
||||
uri = preselectedUri,
|
||||
summary = horizonKernelSummary
|
||||
)
|
||||
installMethod = horizonMethod
|
||||
tempKernelUri = preselectedUri
|
||||
if (isAbDevice) {
|
||||
showSlotSelectionDialog = true
|
||||
} else {
|
||||
showKpmPatchDialog = true
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
}
|
||||
// AnyKernel3 刷写状态
|
||||
val anyKernel3State = rememberAnyKernel3State(
|
||||
installMethodState = installMethodState,
|
||||
preselectedKernelUri = preselectedKernelUri,
|
||||
horizonKernelSummary = horizonKernelSummary,
|
||||
isAbDevice = isAbDevice
|
||||
)
|
||||
val kpmPatchOption = anyKernel3State.kpmPatchOption
|
||||
|
||||
val onInstall = {
|
||||
installMethod?.let { method ->
|
||||
@@ -203,33 +173,24 @@ fun InstallScreen(
|
||||
}
|
||||
|
||||
// 槽位选择对话框
|
||||
if (showSlotSelectionDialog && isAbDevice) {
|
||||
if (anyKernel3State.showSlotSelectionDialog && isAbDevice) {
|
||||
SlotSelectionDialog(
|
||||
show = true,
|
||||
onDismiss = { showSlotSelectionDialog = false },
|
||||
onDismiss = { anyKernel3State.onDismissSlotDialog() },
|
||||
onSlotSelected = { slot ->
|
||||
showSlotSelectionDialog = false
|
||||
val horizonMethod = InstallMethod.HorizonKernel(
|
||||
uri = tempKernelUri,
|
||||
slot = slot,
|
||||
summary = horizonKernelSummary
|
||||
)
|
||||
installMethod = horizonMethod
|
||||
// 槽位选择后,显示 KPM 补丁选择对话框
|
||||
showKpmPatchDialog = true
|
||||
anyKernel3State.onSlotSelected(slot)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
// KPM补丁选择对话框
|
||||
if (showKpmPatchDialog) {
|
||||
if (anyKernel3State.showKpmPatchDialog) {
|
||||
KpmPatchSelectionDialog(
|
||||
show = true,
|
||||
currentOption = kpmPatchOption,
|
||||
onDismiss = { showKpmPatchDialog = false },
|
||||
currentOption = anyKernel3State.kpmPatchOption,
|
||||
onDismiss = { anyKernel3State.onDismissPatchDialog() },
|
||||
onOptionSelected = { option ->
|
||||
kpmPatchOption = option
|
||||
showKpmPatchDialog = false
|
||||
anyKernel3State.onOptionSelected(option)
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -318,13 +279,7 @@ fun InstallScreen(
|
||||
SelectInstallMethod(
|
||||
onSelected = { method ->
|
||||
if (method is InstallMethod.HorizonKernel && method.uri != null) {
|
||||
if (isAbDevice) {
|
||||
tempKernelUri = method.uri
|
||||
showSlotSelectionDialog = true
|
||||
} else {
|
||||
installMethod = method
|
||||
showKpmPatchDialog = true
|
||||
}
|
||||
anyKernel3State.onHorizonKernelSelected(method)
|
||||
} else {
|
||||
installMethod = method
|
||||
}
|
||||
@@ -377,7 +332,7 @@ fun InstallScreen(
|
||||
)
|
||||
}
|
||||
}
|
||||
// LKM 上传选项(仅 GKI)
|
||||
// LKM 上传(仅 GKI)
|
||||
if (isGKI) {
|
||||
Card(
|
||||
modifier = Modifier
|
||||
@@ -405,7 +360,7 @@ fun InstallScreen(
|
||||
}
|
||||
}
|
||||
|
||||
// AnyKernel3 相关信息显示
|
||||
// AnyKernel3 刷写
|
||||
(installMethod as? InstallMethod.HorizonKernel)?.let { method ->
|
||||
if (method.slot != null) {
|
||||
Card(
|
||||
@@ -449,7 +404,7 @@ fun InstallScreen(
|
||||
leftAction = {
|
||||
Icon(
|
||||
Icons.Filled.Security,
|
||||
tint = if (kpmPatchOption == KpmPatchOption.PATCH_KPM)
|
||||
tint = if (kpmPatchOption == KpmPatchOption.PATCH_KPM)
|
||||
colorScheme.primary
|
||||
else
|
||||
colorScheme.secondary,
|
||||
@@ -649,121 +604,6 @@ private fun TopBar(
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun KpmPatchSelectionDialog(
|
||||
show: Boolean,
|
||||
currentOption: KpmPatchOption,
|
||||
onDismiss: () -> Unit,
|
||||
onOptionSelected: (KpmPatchOption) -> Unit
|
||||
) {
|
||||
var selectedOption by remember { mutableStateOf(currentOption) }
|
||||
val showDialog = remember { mutableStateOf(show) }
|
||||
|
||||
LaunchedEffect(show) {
|
||||
showDialog.value = show
|
||||
if (show) {
|
||||
selectedOption = currentOption
|
||||
}
|
||||
}
|
||||
|
||||
SuperDialog(
|
||||
show = showDialog,
|
||||
insideMargin = DpSize(0.dp, 0.dp),
|
||||
onDismissRequest = {
|
||||
showDialog.value = false
|
||||
onDismiss()
|
||||
},
|
||||
content = {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(vertical = 24.dp)
|
||||
) {
|
||||
// 标题
|
||||
Text(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 24.dp, vertical = 12.dp),
|
||||
text = stringResource(id = R.string.kpm_patch_options),
|
||||
fontSize = MiuixTheme.textStyles.title4.fontSize,
|
||||
fontWeight = FontWeight.Medium,
|
||||
textAlign = TextAlign.Center,
|
||||
color = colorScheme.onSurface
|
||||
)
|
||||
|
||||
// 描述
|
||||
Text(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 24.dp, vertical = 8.dp),
|
||||
text = stringResource(id = R.string.kpm_patch_description),
|
||||
fontSize = MiuixTheme.textStyles.body2.fontSize,
|
||||
color = colorScheme.onSurfaceVariantSummary,
|
||||
textAlign = TextAlign.Center
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.height(12.dp))
|
||||
|
||||
// 选项列表
|
||||
val options = listOf(
|
||||
KpmPatchOption.FOLLOW_KERNEL to stringResource(R.string.kpm_follow_kernel_file),
|
||||
KpmPatchOption.PATCH_KPM to stringResource(R.string.enable_kpm_patch),
|
||||
KpmPatchOption.UNDO_PATCH_KPM to stringResource(R.string.enable_kpm_undo_patch)
|
||||
)
|
||||
|
||||
options.forEach { (option, title) ->
|
||||
SuperArrow(
|
||||
title = title,
|
||||
onClick = {
|
||||
selectedOption = option
|
||||
},
|
||||
leftAction = {
|
||||
Icon(
|
||||
imageVector = Icons.Filled.Security,
|
||||
contentDescription = null,
|
||||
tint = if (selectedOption == option) {
|
||||
colorScheme.primary
|
||||
} else {
|
||||
colorScheme.onSurfaceVariantSummary
|
||||
}
|
||||
)
|
||||
},
|
||||
insideMargin = PaddingValues(horizontal = 24.dp, vertical = 12.dp)
|
||||
)
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.height(12.dp))
|
||||
|
||||
// 按钮行
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 24.dp),
|
||||
horizontalArrangement = Arrangement.spacedBy(12.dp)
|
||||
) {
|
||||
TextButton(
|
||||
text = stringResource(android.R.string.cancel),
|
||||
onClick = {
|
||||
showDialog.value = false
|
||||
onDismiss()
|
||||
},
|
||||
modifier = Modifier.weight(1f)
|
||||
)
|
||||
TextButton(
|
||||
text = stringResource(android.R.string.ok),
|
||||
onClick = {
|
||||
onOptionSelected(selectedOption)
|
||||
showDialog.value = false
|
||||
onDismiss()
|
||||
},
|
||||
modifier = Modifier.weight(1f)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
private fun isKoFile(context: Context, uri: Uri): Boolean {
|
||||
val seg = uri.lastPathSegment ?: ""
|
||||
if (seg.endsWith(".ko", ignoreCase = true)) return true
|
||||
@@ -787,4 +627,4 @@ private fun isKoFile(context: Context, uri: Uri): Boolean {
|
||||
} catch (_: Throwable) {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user