manager: fix dark mode color issue

Co-authored-by: YuKongA <70465933+YuKongA@users.noreply.github.com>
This commit is contained in:
ShirkNeko
2025-11-20 17:01:54 +08:00
parent 6465e7a874
commit 6826406494
8 changed files with 75 additions and 40 deletions

View File

@@ -5,6 +5,7 @@ import androidx.compose.ui.graphics.Color
import android.os.Build
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.SystemBarStyle
import androidx.activity.compose.BackHandler
import androidx.activity.compose.LocalActivity
import androidx.activity.compose.setContent
@@ -16,6 +17,7 @@ import androidx.compose.animation.core.FastOutSlowInEasing
import androidx.compose.animation.core.tween
import androidx.compose.animation.slideInHorizontally
import androidx.compose.animation.slideOutHorizontally
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.pager.HorizontalPager
import androidx.compose.foundation.pager.PagerState
import androidx.compose.foundation.pager.rememberPagerState
@@ -59,14 +61,12 @@ class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
// Enable edge to edge
enableEdgeToEdge()
super.onCreate(savedInstanceState)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
window.isNavigationBarContrastEnforced = false
}
super.onCreate(savedInstanceState)
val isManager = Natives.isManager
if (isManager && !Natives.requireNewKernel()) install()
@@ -77,7 +77,23 @@ class MainActivity : ComponentActivity() {
var keyColorInt by remember { mutableIntStateOf(prefs.getInt("key_color", 0)) }
val keyColor = remember(keyColorInt) { if (keyColorInt == 0) null else Color(keyColorInt) }
DisposableEffect(prefs) {
val darkMode = when (colorMode) {
2, 5 -> true
0, 3 -> isSystemInDarkTheme()
else -> false
}
DisposableEffect(prefs, darkMode) {
enableEdgeToEdge(
statusBarStyle = SystemBarStyle.auto(
android.graphics.Color.TRANSPARENT,
android.graphics.Color.TRANSPARENT
) { darkMode },
navigationBarStyle = SystemBarStyle.auto(
android.graphics.Color.TRANSPARENT,
android.graphics.Color.TRANSPARENT
) { darkMode },
)
val listener = SharedPreferences.OnSharedPreferenceChangeListener { _, key ->
when (key) {
"color_mode" -> colorMode = prefs.getInt("color_mode", 0)

View File

@@ -9,6 +9,7 @@ import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.CheckCircle
@@ -18,6 +19,7 @@ import androidx.compose.runtime.*
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.input.key.Key
import androidx.compose.ui.input.key.key
import androidx.compose.ui.platform.LocalContext
@@ -41,7 +43,6 @@ import top.yukonga.miuix.kmp.basic.Card
import top.yukonga.miuix.kmp.basic.FloatingActionButton
import top.yukonga.miuix.kmp.basic.Icon
import top.yukonga.miuix.kmp.basic.IconButton
import top.yukonga.miuix.kmp.basic.LinearProgressIndicator
import top.yukonga.miuix.kmp.basic.Scaffold
import top.yukonga.miuix.kmp.basic.SmallTopAppBar
import top.yukonga.miuix.kmp.basic.Text
@@ -67,9 +68,6 @@ private object KernelFlashStateHolder {
var isFlashing = false
}
/**
* Kernel刷写界面
*/
@Destination<RootGraph>
@Composable
fun KernelFlashScreen(
@@ -116,7 +114,6 @@ fun KernelFlashScreen(
showFloatAction = true
KernelFlashStateHolder.isFlashing = false
// 如果需要自动退出延迟1.5秒后退出
if (shouldAutoExit) {
scope.launch {
delay(1500)
@@ -172,7 +169,6 @@ fun KernelFlashScreen(
val onBack: () -> Unit = {
if (!flashState.isFlashing || flashState.isCompleted || flashState.error.isNotEmpty()) {
// 清理全局状态
if (flashState.isCompleted || flashState.error.isNotEmpty()) {
KernelFlashStateHolder.currentState = null
KernelFlashStateHolder.currentUri = null
@@ -279,7 +275,7 @@ private fun FlashProgressIndicator(
kpmUndoPatch: Boolean = false
) {
val progressColor = when {
flashState.error.isNotEmpty() -> colorScheme.primary
flashState.error.isNotEmpty() -> colorScheme.error
flashState.isCompleted -> colorScheme.secondary
else -> colorScheme.primary
}
@@ -319,7 +315,7 @@ private fun FlashProgressIndicator(
Icon(
imageVector = Icons.Default.Error,
contentDescription = null,
tint = colorScheme.primary
tint = colorScheme.error
)
}
flashState.isCompleted -> {
@@ -353,12 +349,22 @@ private fun FlashProgressIndicator(
Spacer(modifier = Modifier.height(8.dp))
}
LinearProgressIndicator(
progress = progress.value,
val progressFraction = progress.value.coerceIn(0f, 1f)
Box(
modifier = Modifier
.fillMaxWidth()
.height(8.dp)
)
.clip(RoundedCornerShape(999.dp))
.background(colorScheme.surfaceVariant)
) {
Box(
modifier = Modifier
.fillMaxHeight()
.fillMaxWidth(progressFraction)
.clip(RoundedCornerShape(999.dp))
.background(progressColor)
)
}
if (flashState.error.isNotEmpty()) {
Spacer(modifier = Modifier.height(8.dp))
@@ -369,7 +375,7 @@ private fun FlashProgressIndicator(
Icon(
imageVector = Icons.Default.Error,
contentDescription = null,
tint = colorScheme.primary,
tint = colorScheme.error,
modifier = Modifier.size(16.dp)
)
}
@@ -378,11 +384,11 @@ private fun FlashProgressIndicator(
Text(
text = flashState.error,
color = colorScheme.primary,
color = colorScheme.onErrorContainer,
modifier = Modifier
.fillMaxWidth()
.background(
colorScheme.primaryContainer.copy(alpha = 0.3f)
colorScheme.errorContainer.copy(alpha = 0.8f)
)
.padding(8.dp)
)

View File

@@ -112,6 +112,7 @@ fun HomePager(
val context = LocalContext.current
val prefs = context.getSharedPreferences("settings", Context.MODE_PRIVATE)
val checkUpdate = prefs.getBoolean("check_update", true)
val themeMode = prefs.getInt("color_mode", 0)
Scaffold(
topBar = {
@@ -158,14 +159,15 @@ fun HomePager(
) {
if (isManager && Natives.requireNewKernel()) {
WarningCard(
stringResource(id = R.string.require_kernel_version).format(
ksuVersion, Natives.MINIMAL_SUPPORTED_KERNEL
)
stringResource(id = R.string.require_kernel_version)
.format(ksuVersion, Natives.MINIMAL_SUPPORTED_KERNEL),
themeMode
)
}
if (ksuVersion != null && !rootAvailable()) {
WarningCard(
stringResource(id = R.string.grant_root_failed)
stringResource(id = R.string.grant_root_failed),
themeMode
)
}
StatusCard(
@@ -184,11 +186,12 @@ fun HomePager(
coroutineScope.launch {
pagerState.animateScrollToPage(getModulePageIndex(isKpmAvailable))
}
}
},
themeMode = themeMode
)
if (checkUpdate) {
UpdateCard()
UpdateCard(themeMode)
}
InfoCard()
DonateCard()
@@ -201,7 +204,9 @@ fun HomePager(
}
@Composable
fun UpdateCard() {
fun UpdateCard(
themeMode: Int,
) {
val context = LocalContext.current
val latestVersionInfo = LatestVersionInfo()
val newVersion by produceState(initialValue = latestVersionInfo) {
@@ -227,7 +232,8 @@ fun UpdateCard() {
val updateDialog = rememberConfirmDialog(onConfirm = { uriHandler.openUri(newVersionUrl) })
WarningCard(
message = stringResource(id = R.string.new_version_available).format(newVersionCode),
colorScheme.outline
themeMode = themeMode,
color = colorScheme.outline
) {
if (changelog.isEmpty()) {
uriHandler.openUri(newVersionUrl)
@@ -306,6 +312,7 @@ private fun StatusCard(
onClickInstall: () -> Unit = {},
onClickSuperuser: () -> Unit = {},
onclickModule: () -> Unit = {},
themeMode: Int,
) {
Column(
modifier = Modifier
@@ -339,7 +346,7 @@ private fun StatusCard(
colors = CardDefaults.defaultColors(
color = when {
isDynamicColor -> colorScheme.secondaryContainer
isSystemInDarkTheme() -> Color(0xFF1A3825)
isSystemInDarkTheme() || themeMode == 2 -> Color(0xFF1A3825)
else -> Color(0xFFDFFAE4)
}
),
@@ -512,6 +519,7 @@ private fun StatusCard(
@Composable
fun WarningCard(
message: String,
themeMode: Int,
color: Color? = null,
onClick: (() -> Unit)? = null,
) {
@@ -522,7 +530,7 @@ fun WarningCard(
colors = CardDefaults.defaultColors(
color = color ?: when {
isDynamicColor -> colorScheme.errorContainer
isSystemInDarkTheme() -> Color(0XFF310808)
isSystemInDarkTheme() || themeMode == 2 -> Color(0XFF310808)
else -> Color(0xFFF8E2E2)
}
),

View File

@@ -139,6 +139,7 @@ import top.yukonga.miuix.kmp.basic.rememberPullToRefreshState
import top.yukonga.miuix.kmp.extra.DropdownImpl
import top.yukonga.miuix.kmp.icon.MiuixIcons
import top.yukonga.miuix.kmp.icon.icons.useful.ImmersionMore
import top.yukonga.miuix.kmp.icon.icons.useful.Undo
import top.yukonga.miuix.kmp.theme.MiuixTheme.colorScheme
import top.yukonga.miuix.kmp.utils.getWindowSize
import top.yukonga.miuix.kmp.utils.overScrollVertical
@@ -911,16 +912,18 @@ fun ModuleItem(
onExecuteAction: () -> Unit,
onOpenWebUi: () -> Unit
) {
val isDark = isSystemInDarkTheme()
val hasUpdate by remember(updateUrl) { derivedStateOf { updateUrl.isNotEmpty() } }
val textDecoration by remember(module.remove) {
mutableStateOf(if (module.remove) TextDecoration.LineThrough else null)
}
val context = LocalContext.current
val prefs = context.getSharedPreferences("settings", Context.MODE_PRIVATE)
val isDark = isSystemInDarkTheme() || prefs.getInt("color_mode", 0) == 2 || prefs.getInt("color_mode", 0) == 5
val colorScheme = colorScheme
val secondaryContainer = colorScheme.secondaryContainer.copy(alpha = 0.8f)
val actionIconTint = remember(isDark) { colorScheme.onSurface.copy(alpha = if (isDark) 0.7f else 0.9f) }
val updateBg = remember(colorScheme) { colorScheme.tertiaryContainer.copy(alpha = 0.6f) }
val updateTint = remember(colorScheme) { colorScheme.onTertiaryContainer.copy(alpha = 0.8f) }
val hasUpdate by remember(updateUrl) { derivedStateOf { updateUrl.isNotEmpty() } }
val textDecoration by remember(module.remove) {
mutableStateOf(if (module.remove) TextDecoration.LineThrough else null)
}
Card(
modifier = Modifier
@@ -1126,7 +1129,7 @@ fun ModuleItem(
Icon(
modifier = Modifier.size(20.dp),
imageVector = if (module.remove) {
Icons.AutoMirrored.Outlined.Undo
MiuixIcons.Useful.Undo
} else {
Icons.Outlined.Delete
},

View File

@@ -467,7 +467,9 @@ private fun GroupItem(
onToggleExpand: () -> Unit,
onClickPrimary: () -> Unit,
) {
val isDark = isSystemInDarkTheme()
val context = LocalContext.current
val prefs = context.getSharedPreferences("settings", Context.MODE_PRIVATE)
val isDark = isSystemInDarkTheme() || prefs.getInt("color_mode", 0) == 2 || prefs.getInt("color_mode", 0) == 5
val colorScheme = colorScheme
val bg = remember(colorScheme) { colorScheme.secondaryContainer.copy(alpha = 0.8f) }
val rootBg = remember(colorScheme) { colorScheme.tertiaryContainer.copy(alpha = 0.6f) }
@@ -485,7 +487,7 @@ private fun GroupItem(
val hasSharedUserId = !packageInfo.sharedUserId.isNullOrEmpty()
val isSystemApp = applicationInfo?.flags?.and(ApplicationInfo.FLAG_SYSTEM) != 0
|| applicationInfo.flags.and(ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0
val tags = remember(group.uid, group.anyAllowSu, group.anyCustom, colorScheme) {
val tags = remember(group.uid, group.anyAllowSu, group.anyCustom, colorScheme, isDark) {
buildList {
if (group.anyAllowSu) add(StatusMeta("ROOT", rootBg, rootFg))
if (Natives.uidShouldUmount(group.uid)) add(StatusMeta("UMOUNT", unmountBg, unmountFg))

View File

@@ -168,7 +168,7 @@ fun Personalization(
)
var keyColorIndex by rememberSaveable {
mutableIntStateOf(
colorValues.indexOf(prefs.getInt("key_color", 0)).coerceAtLeast(0)
colorValues.indexOf(prefs.getInt("key_color", 0)).takeIf { it >= 0 } ?: 0
)
}
SuperDropdown(

View File

@@ -365,6 +365,6 @@
<string name="allowlist_backup_failed">备份失败</string>
<string name="allowlist_restore_title">还原允许列表</string>
<string name="allowlist_restore_summary_picker">选择备份文件进行导入</string>
<string name="allowlist_restore_success">还原成功</string>
<string name="allowlist_restore_success">还原成功,重启生效</string>
<string name="allowlist_restore_failed">还原失败</string>
</resources>

View File

@@ -367,7 +367,7 @@
<string name="allowlist_backup_summary_picker">Choose a location to export the allowlist</string>
<string name="allowlist_backup_success">Backup succeeded</string>
<string name="allowlist_backup_failed">Backup failed</string>
<string name="allowlist_restore_title">Restore allowlist</string>
<string name="allowlist_restore_title">Restoration successful. Changes will take effect after restart.</string>
<string name="allowlist_restore_summary_picker">Choose a backup file to import</string>
<string name="allowlist_restore_success">Restore succeeded</string>
<string name="allowlist_restore_failed">Restore failed</string>