Updated GKI installation selection style

This commit is contained in:
ShirkNeko
2025-04-29 18:07:29 +08:00
parent 39adba62d1
commit 1ea219bddc
3 changed files with 144 additions and 103 deletions

View File

@@ -1,9 +1,12 @@
package com.sukisu.ultra.ui.component package com.sukisu.ultra.ui.component
import android.content.Context import android.content.Context
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.horizontalScroll
import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.*
import androidx.compose.foundation.rememberScrollState
import androidx.compose.material3.* import androidx.compose.material3.*
import androidx.compose.material3.HorizontalDivider
import androidx.compose.runtime.* import androidx.compose.runtime.*
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
@@ -11,10 +14,12 @@ import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Dialog
import com.sukisu.ultra.R import com.sukisu.ultra.R
import com.sukisu.ultra.ui.theme.ThemeConfig import com.sukisu.ultra.ui.theme.ThemeConfig
import androidx.compose.foundation.shape.CornerSize import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.SdStorage
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.vector.ImageVector
/** /**
* 槽位选择对话框组件 * 槽位选择对话框组件
@@ -42,38 +47,26 @@ fun SlotSelectionDialog(
} }
if (show) { if (show) {
val backgroundColor = if (!ThemeConfig.useDynamicColor) { val cardColor = if (!ThemeConfig.useDynamicColor) {
ThemeConfig.currentTheme.ButtonContrast.copy(alpha = 1.0f) ThemeConfig.currentTheme.ButtonContrast
} else { } else {
MaterialTheme.colorScheme.secondaryContainer.copy(alpha = 1.0f) MaterialTheme.colorScheme.surfaceContainerHigh
} }
Dialog(onDismissRequest = onDismiss) { AlertDialog(
Card( onDismissRequest = onDismiss,
shape = MaterialTheme.shapes.medium.copy( title = {
topStart = CornerSize(16.dp), Text(
topEnd = CornerSize(16.dp), text = stringResource(id = R.string.select_slot_title),
bottomEnd = CornerSize(16.dp), style = MaterialTheme.typography.headlineSmall,
bottomStart = CornerSize(16.dp) color = MaterialTheme.colorScheme.onSurface
), )
colors = CardDefaults.cardColors( },
containerColor = backgroundColor text = {
),
elevation = CardDefaults.cardElevation(defaultElevation = 0.dp)
) {
Column( Column(
modifier = Modifier modifier = Modifier.padding(vertical = 8.dp),
.padding(24.dp) verticalArrangement = Arrangement.spacedBy(16.dp)
.fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally
) { ) {
Text(
text = stringResource(id = R.string.select_slot_title),
style = MaterialTheme.typography.headlineSmall,
textAlign = TextAlign.Center,
modifier = Modifier.padding(bottom = 16.dp)
)
if (errorMessage != null) { if (errorMessage != null) {
Text( Text(
text = "Error: $errorMessage", text = "Error: $errorMessage",
@@ -104,88 +97,134 @@ fun SlotSelectionDialog(
Spacer(modifier = Modifier.height(24.dp)) Spacer(modifier = Modifier.height(24.dp))
// Horizontal arrangement for slot options with highlighted current slot
Row( Row(
modifier = Modifier.fillMaxWidth(), modifier = Modifier
horizontalArrangement = Arrangement.spacedBy(6.dp) .fillMaxWidth()
) { .horizontalScroll(rememberScrollState()),
val isDefaultSlotA = currentSlot == "_a" || currentSlot == "a"
Button(
onClick = { onSlotSelected("a") },
modifier = Modifier.weight(1f),
colors = ButtonDefaults.buttonColors(
containerColor = if (isDefaultSlotA)
MaterialTheme.colorScheme.primary
else
MaterialTheme.colorScheme.primaryContainer,
contentColor = if (isDefaultSlotA)
MaterialTheme.colorScheme.onPrimary
else
MaterialTheme.colorScheme.onPrimaryContainer
)
) {
Text(
text = stringResource(id = R.string.slot_a),
style = MaterialTheme.typography.labelLarge
)
}
val isDefaultSlotB = currentSlot == "_b" || currentSlot == "b"
Button(
onClick = { onSlotSelected("b") },
modifier = Modifier.weight(1f),
colors = ButtonDefaults.buttonColors(
containerColor = if (isDefaultSlotB)
MaterialTheme.colorScheme.secondary
else
MaterialTheme.colorScheme.secondaryContainer,
contentColor = if (isDefaultSlotB)
MaterialTheme.colorScheme.onSecondary
else
MaterialTheme.colorScheme.onSecondaryContainer
)
) {
Text(
text = stringResource(id = R.string.slot_b),
style = MaterialTheme.typography.labelLarge
)
}
}
Spacer(modifier = Modifier.height(24.dp))
HorizontalDivider(
modifier = Modifier.fillMaxWidth(),
thickness = 1.dp,
color = MaterialTheme.colorScheme.outline
)
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween horizontalArrangement = Arrangement.SpaceBetween
) { ) {
TextButton( val slotOptions = listOf(
onClick = onDismiss, ListOption(
modifier = Modifier.weight(1f) titleText = stringResource(id = R.string.slot_a),
) { subtitleText = if (currentSlot == "a" || currentSlot == "_a") stringResource(id = R.string.currently_selected) else null,
Text(text = stringResource(id = android.R.string.cancel)) icon = Icons.Filled.SdStorage
} ),
TextButton( ListOption(
onClick = { titleText = stringResource(id = R.string.slot_b),
currentSlot?.let { onSlotSelected(it) } subtitleText = if (currentSlot == "b" || currentSlot == "_b") stringResource(id = R.string.currently_selected) else null,
onDismiss() icon = Icons.Filled.SdStorage
}, )
modifier = Modifier.weight(1f) )
) {
Text(text = stringResource(id = android.R.string.ok)) slotOptions.forEachIndexed { index, option ->
Column(
modifier = Modifier
.weight(1f)
.padding(horizontal = 8.dp)
) {
Row(
modifier = Modifier
.fillMaxWidth()
.clip(MaterialTheme.shapes.medium)
.background(
color = if (option.subtitleText != null) {
MaterialTheme.colorScheme.primary.copy(alpha = 0.9f)
} else {
MaterialTheme.colorScheme.primaryContainer.copy(alpha = 0.3f)
}
)
.clickable {
onSlotSelected(
when (index) {
0 -> "a"
else -> "b"
}
)
}
.padding(vertical = 12.dp, horizontal = 16.dp),
verticalAlignment = Alignment.CenterVertically
) {
Icon(
imageVector = option.icon,
contentDescription = null,
tint = if (option.subtitleText != null) {
MaterialTheme.colorScheme.onPrimary
} else {
MaterialTheme.colorScheme.primary
},
modifier = Modifier
.padding(end = 16.dp)
.size(24.dp)
)
Column(
modifier = Modifier.weight(1f)
) {
Text(
text = option.titleText,
style = MaterialTheme.typography.titleMedium,
color = if (option.subtitleText != null) {
MaterialTheme.colorScheme.onPrimary
} else {
MaterialTheme.colorScheme.primary
}
)
option.subtitleText?.let {
Text(
text = it,
style = MaterialTheme.typography.bodyMedium,
color = if (true) {
MaterialTheme.colorScheme.onPrimary.copy(alpha = 0.8f)
} else {
MaterialTheme.colorScheme.onSurfaceVariant
}
)
}
}
}
}
} }
} }
} }
} },
} confirmButton = {
TextButton(
onClick = {
currentSlot?.let { onSlotSelected(it) }
onDismiss()
}
) {
Text(
text = stringResource(android.R.string.ok),
color = MaterialTheme.colorScheme.primary
)
}
},
dismissButton = {
TextButton(
onClick = onDismiss
) {
Text(
text = stringResource(android.R.string.cancel),
color = MaterialTheme.colorScheme.primary
)
}
},
containerColor = cardColor,
shape = MaterialTheme.shapes.extraLarge,
tonalElevation = 4.dp
)
} }
} }
// 获取当前槽位信息 // Data class for list options
data class ListOption(
val titleText: String,
val subtitleText: String?,
val icon: ImageVector
)
// Utility function to get current slot
private fun getCurrentSlot(context: Context): String? { private fun getCurrentSlot(context: Context): String? {
return runCommandGetOutput(true, "getprop ro.boot.slot_suffix")?.let { return runCommandGetOutput(true, "getprop ro.boot.slot_suffix")?.let {
if (it.startsWith("_")) it.substring(1) else it if (it.startsWith("_")) it.substring(1) else it

View File

@@ -299,6 +299,7 @@
<string name="configuration">配置</string> <string name="configuration">配置</string>
<string name="app_settings">应用设置</string> <string name="app_settings">应用设置</string>
<string name="tools">工具</string> <string name="tools">工具</string>
<string name="currently_selected">当前</string>
<!-- SuperUser 里用到的字符串资源 --> <!-- SuperUser 里用到的字符串资源 -->
<string name="clear">清除</string> <string name="clear">清除</string>
<string name="apps_with_root">Root 权限应用</string> <string name="apps_with_root">Root 权限应用</string>

View File

@@ -303,6 +303,7 @@
<string name="configuration">Configure</string> <string name="configuration">Configure</string>
<string name="app_settings">Application Settings</string> <string name="app_settings">Application Settings</string>
<string name="tools">Tools</string> <string name="tools">Tools</string>
<string name="currently_selected">Currently</string>
<!-- String resources used in SuperUser --> <!-- String resources used in SuperUser -->
<string name="clear">Removals</string> <string name="clear">Removals</string>
<string name="apps_with_root">Root Application of permissions</string> <string name="apps_with_root">Root Application of permissions</string>