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.Build
import android.os.Bundle import android.os.Bundle
import androidx.activity.ComponentActivity import androidx.activity.ComponentActivity
import androidx.activity.SystemBarStyle
import androidx.activity.compose.BackHandler import androidx.activity.compose.BackHandler
import androidx.activity.compose.LocalActivity import androidx.activity.compose.LocalActivity
import androidx.activity.compose.setContent 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.core.tween
import androidx.compose.animation.slideInHorizontally import androidx.compose.animation.slideInHorizontally
import androidx.compose.animation.slideOutHorizontally import androidx.compose.animation.slideOutHorizontally
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.pager.HorizontalPager import androidx.compose.foundation.pager.HorizontalPager
import androidx.compose.foundation.pager.PagerState import androidx.compose.foundation.pager.PagerState
import androidx.compose.foundation.pager.rememberPagerState import androidx.compose.foundation.pager.rememberPagerState
@@ -59,14 +61,12 @@ class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
// Enable edge to edge super.onCreate(savedInstanceState)
enableEdgeToEdge()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
window.isNavigationBarContrastEnforced = false window.isNavigationBarContrastEnforced = false
} }
super.onCreate(savedInstanceState)
val isManager = Natives.isManager val isManager = Natives.isManager
if (isManager && !Natives.requireNewKernel()) install() if (isManager && !Natives.requireNewKernel()) install()
@@ -77,7 +77,23 @@ class MainActivity : ComponentActivity() {
var keyColorInt by remember { mutableIntStateOf(prefs.getInt("key_color", 0)) } var keyColorInt by remember { mutableIntStateOf(prefs.getInt("key_color", 0)) }
val keyColor = remember(keyColorInt) { if (keyColorInt == 0) null else Color(keyColorInt) } 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 -> val listener = SharedPreferences.OnSharedPreferenceChangeListener { _, key ->
when (key) { when (key) {
"color_mode" -> colorMode = prefs.getInt("color_mode", 0) "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.background
import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.*
import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.CheckCircle import androidx.compose.material.icons.filled.CheckCircle
@@ -18,6 +19,7 @@ import androidx.compose.runtime.*
import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier 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.input.key.key import androidx.compose.ui.input.key.key
import androidx.compose.ui.platform.LocalContext 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.FloatingActionButton
import top.yukonga.miuix.kmp.basic.Icon import top.yukonga.miuix.kmp.basic.Icon
import top.yukonga.miuix.kmp.basic.IconButton 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.Scaffold
import top.yukonga.miuix.kmp.basic.SmallTopAppBar import top.yukonga.miuix.kmp.basic.SmallTopAppBar
import top.yukonga.miuix.kmp.basic.Text import top.yukonga.miuix.kmp.basic.Text
@@ -67,9 +68,6 @@ private object KernelFlashStateHolder {
var isFlashing = false var isFlashing = false
} }
/**
* Kernel刷写界面
*/
@Destination<RootGraph> @Destination<RootGraph>
@Composable @Composable
fun KernelFlashScreen( fun KernelFlashScreen(
@@ -116,7 +114,6 @@ fun KernelFlashScreen(
showFloatAction = true showFloatAction = true
KernelFlashStateHolder.isFlashing = false KernelFlashStateHolder.isFlashing = false
// 如果需要自动退出延迟1.5秒后退出
if (shouldAutoExit) { if (shouldAutoExit) {
scope.launch { scope.launch {
delay(1500) delay(1500)
@@ -172,7 +169,6 @@ fun KernelFlashScreen(
val onBack: () -> Unit = { val onBack: () -> Unit = {
if (!flashState.isFlashing || flashState.isCompleted || flashState.error.isNotEmpty()) { if (!flashState.isFlashing || flashState.isCompleted || flashState.error.isNotEmpty()) {
// 清理全局状态
if (flashState.isCompleted || flashState.error.isNotEmpty()) { if (flashState.isCompleted || flashState.error.isNotEmpty()) {
KernelFlashStateHolder.currentState = null KernelFlashStateHolder.currentState = null
KernelFlashStateHolder.currentUri = null KernelFlashStateHolder.currentUri = null
@@ -279,7 +275,7 @@ private fun FlashProgressIndicator(
kpmUndoPatch: Boolean = false kpmUndoPatch: Boolean = false
) { ) {
val progressColor = when { val progressColor = when {
flashState.error.isNotEmpty() -> colorScheme.primary flashState.error.isNotEmpty() -> colorScheme.error
flashState.isCompleted -> colorScheme.secondary flashState.isCompleted -> colorScheme.secondary
else -> colorScheme.primary else -> colorScheme.primary
} }
@@ -319,7 +315,7 @@ private fun FlashProgressIndicator(
Icon( Icon(
imageVector = Icons.Default.Error, imageVector = Icons.Default.Error,
contentDescription = null, contentDescription = null,
tint = colorScheme.primary tint = colorScheme.error
) )
} }
flashState.isCompleted -> { flashState.isCompleted -> {
@@ -353,12 +349,22 @@ private fun FlashProgressIndicator(
Spacer(modifier = Modifier.height(8.dp)) Spacer(modifier = Modifier.height(8.dp))
} }
LinearProgressIndicator( val progressFraction = progress.value.coerceIn(0f, 1f)
progress = progress.value, Box(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.height(8.dp) .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()) { if (flashState.error.isNotEmpty()) {
Spacer(modifier = Modifier.height(8.dp)) Spacer(modifier = Modifier.height(8.dp))
@@ -369,7 +375,7 @@ private fun FlashProgressIndicator(
Icon( Icon(
imageVector = Icons.Default.Error, imageVector = Icons.Default.Error,
contentDescription = null, contentDescription = null,
tint = colorScheme.primary, tint = colorScheme.error,
modifier = Modifier.size(16.dp) modifier = Modifier.size(16.dp)
) )
} }
@@ -378,11 +384,11 @@ private fun FlashProgressIndicator(
Text( Text(
text = flashState.error, text = flashState.error,
color = colorScheme.primary, color = colorScheme.onErrorContainer,
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.background( .background(
colorScheme.primaryContainer.copy(alpha = 0.3f) colorScheme.errorContainer.copy(alpha = 0.8f)
) )
.padding(8.dp) .padding(8.dp)
) )

View File

@@ -112,6 +112,7 @@ fun HomePager(
val context = LocalContext.current val context = LocalContext.current
val prefs = context.getSharedPreferences("settings", Context.MODE_PRIVATE) val prefs = context.getSharedPreferences("settings", Context.MODE_PRIVATE)
val checkUpdate = prefs.getBoolean("check_update", true) val checkUpdate = prefs.getBoolean("check_update", true)
val themeMode = prefs.getInt("color_mode", 0)
Scaffold( Scaffold(
topBar = { topBar = {
@@ -158,14 +159,15 @@ fun HomePager(
) { ) {
if (isManager && Natives.requireNewKernel()) { if (isManager && Natives.requireNewKernel()) {
WarningCard( WarningCard(
stringResource(id = R.string.require_kernel_version).format( stringResource(id = R.string.require_kernel_version)
ksuVersion, Natives.MINIMAL_SUPPORTED_KERNEL .format(ksuVersion, Natives.MINIMAL_SUPPORTED_KERNEL),
) themeMode
) )
} }
if (ksuVersion != null && !rootAvailable()) { if (ksuVersion != null && !rootAvailable()) {
WarningCard( WarningCard(
stringResource(id = R.string.grant_root_failed) stringResource(id = R.string.grant_root_failed),
themeMode
) )
} }
StatusCard( StatusCard(
@@ -184,11 +186,12 @@ fun HomePager(
coroutineScope.launch { coroutineScope.launch {
pagerState.animateScrollToPage(getModulePageIndex(isKpmAvailable)) pagerState.animateScrollToPage(getModulePageIndex(isKpmAvailable))
} }
} },
themeMode = themeMode
) )
if (checkUpdate) { if (checkUpdate) {
UpdateCard() UpdateCard(themeMode)
} }
InfoCard() InfoCard()
DonateCard() DonateCard()
@@ -201,7 +204,9 @@ fun HomePager(
} }
@Composable @Composable
fun UpdateCard() { fun UpdateCard(
themeMode: Int,
) {
val context = LocalContext.current val context = LocalContext.current
val latestVersionInfo = LatestVersionInfo() val latestVersionInfo = LatestVersionInfo()
val newVersion by produceState(initialValue = latestVersionInfo) { val newVersion by produceState(initialValue = latestVersionInfo) {
@@ -227,7 +232,8 @@ fun UpdateCard() {
val updateDialog = rememberConfirmDialog(onConfirm = { uriHandler.openUri(newVersionUrl) }) val updateDialog = rememberConfirmDialog(onConfirm = { uriHandler.openUri(newVersionUrl) })
WarningCard( WarningCard(
message = stringResource(id = R.string.new_version_available).format(newVersionCode), message = stringResource(id = R.string.new_version_available).format(newVersionCode),
colorScheme.outline themeMode = themeMode,
color = colorScheme.outline
) { ) {
if (changelog.isEmpty()) { if (changelog.isEmpty()) {
uriHandler.openUri(newVersionUrl) uriHandler.openUri(newVersionUrl)
@@ -306,6 +312,7 @@ private fun StatusCard(
onClickInstall: () -> Unit = {}, onClickInstall: () -> Unit = {},
onClickSuperuser: () -> Unit = {}, onClickSuperuser: () -> Unit = {},
onclickModule: () -> Unit = {}, onclickModule: () -> Unit = {},
themeMode: Int,
) { ) {
Column( Column(
modifier = Modifier modifier = Modifier
@@ -339,7 +346,7 @@ private fun StatusCard(
colors = CardDefaults.defaultColors( colors = CardDefaults.defaultColors(
color = when { color = when {
isDynamicColor -> colorScheme.secondaryContainer isDynamicColor -> colorScheme.secondaryContainer
isSystemInDarkTheme() -> Color(0xFF1A3825) isSystemInDarkTheme() || themeMode == 2 -> Color(0xFF1A3825)
else -> Color(0xFFDFFAE4) else -> Color(0xFFDFFAE4)
} }
), ),
@@ -512,6 +519,7 @@ private fun StatusCard(
@Composable @Composable
fun WarningCard( fun WarningCard(
message: String, message: String,
themeMode: Int,
color: Color? = null, color: Color? = null,
onClick: (() -> Unit)? = null, onClick: (() -> Unit)? = null,
) { ) {
@@ -522,7 +530,7 @@ fun WarningCard(
colors = CardDefaults.defaultColors( colors = CardDefaults.defaultColors(
color = color ?: when { color = color ?: when {
isDynamicColor -> colorScheme.errorContainer isDynamicColor -> colorScheme.errorContainer
isSystemInDarkTheme() -> Color(0XFF310808) isSystemInDarkTheme() || themeMode == 2 -> Color(0XFF310808)
else -> Color(0xFFF8E2E2) 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.extra.DropdownImpl
import top.yukonga.miuix.kmp.icon.MiuixIcons import top.yukonga.miuix.kmp.icon.MiuixIcons
import top.yukonga.miuix.kmp.icon.icons.useful.ImmersionMore 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.theme.MiuixTheme.colorScheme
import top.yukonga.miuix.kmp.utils.getWindowSize import top.yukonga.miuix.kmp.utils.getWindowSize
import top.yukonga.miuix.kmp.utils.overScrollVertical import top.yukonga.miuix.kmp.utils.overScrollVertical
@@ -911,16 +912,18 @@ fun ModuleItem(
onExecuteAction: () -> Unit, onExecuteAction: () -> Unit,
onOpenWebUi: () -> Unit onOpenWebUi: () -> Unit
) { ) {
val isDark = isSystemInDarkTheme() val context = LocalContext.current
val hasUpdate by remember(updateUrl) { derivedStateOf { updateUrl.isNotEmpty() } } val prefs = context.getSharedPreferences("settings", Context.MODE_PRIVATE)
val textDecoration by remember(module.remove) { val isDark = isSystemInDarkTheme() || prefs.getInt("color_mode", 0) == 2 || prefs.getInt("color_mode", 0) == 5
mutableStateOf(if (module.remove) TextDecoration.LineThrough else null)
}
val colorScheme = colorScheme val colorScheme = colorScheme
val secondaryContainer = colorScheme.secondaryContainer.copy(alpha = 0.8f) val secondaryContainer = colorScheme.secondaryContainer.copy(alpha = 0.8f)
val actionIconTint = remember(isDark) { colorScheme.onSurface.copy(alpha = if (isDark) 0.7f else 0.9f) } 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 updateBg = remember(colorScheme) { colorScheme.tertiaryContainer.copy(alpha = 0.6f) }
val updateTint = remember(colorScheme) { colorScheme.onTertiaryContainer.copy(alpha = 0.8f) } 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( Card(
modifier = Modifier modifier = Modifier
@@ -1126,7 +1129,7 @@ fun ModuleItem(
Icon( Icon(
modifier = Modifier.size(20.dp), modifier = Modifier.size(20.dp),
imageVector = if (module.remove) { imageVector = if (module.remove) {
Icons.AutoMirrored.Outlined.Undo MiuixIcons.Useful.Undo
} else { } else {
Icons.Outlined.Delete Icons.Outlined.Delete
}, },

View File

@@ -467,7 +467,9 @@ private fun GroupItem(
onToggleExpand: () -> Unit, onToggleExpand: () -> Unit,
onClickPrimary: () -> 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 colorScheme = colorScheme
val bg = remember(colorScheme) { colorScheme.secondaryContainer.copy(alpha = 0.8f) } val bg = remember(colorScheme) { colorScheme.secondaryContainer.copy(alpha = 0.8f) }
val rootBg = remember(colorScheme) { colorScheme.tertiaryContainer.copy(alpha = 0.6f) } val rootBg = remember(colorScheme) { colorScheme.tertiaryContainer.copy(alpha = 0.6f) }
@@ -485,7 +487,7 @@ private fun GroupItem(
val hasSharedUserId = !packageInfo.sharedUserId.isNullOrEmpty() val hasSharedUserId = !packageInfo.sharedUserId.isNullOrEmpty()
val isSystemApp = applicationInfo?.flags?.and(ApplicationInfo.FLAG_SYSTEM) != 0 val isSystemApp = applicationInfo?.flags?.and(ApplicationInfo.FLAG_SYSTEM) != 0
|| applicationInfo.flags.and(ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 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 { buildList {
if (group.anyAllowSu) add(StatusMeta("ROOT", rootBg, rootFg)) if (group.anyAllowSu) add(StatusMeta("ROOT", rootBg, rootFg))
if (Natives.uidShouldUmount(group.uid)) add(StatusMeta("UMOUNT", unmountBg, unmountFg)) if (Natives.uidShouldUmount(group.uid)) add(StatusMeta("UMOUNT", unmountBg, unmountFg))

View File

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

View File

@@ -365,6 +365,6 @@
<string name="allowlist_backup_failed">备份失败</string> <string name="allowlist_backup_failed">备份失败</string>
<string name="allowlist_restore_title">还原允许列表</string> <string name="allowlist_restore_title">还原允许列表</string>
<string name="allowlist_restore_summary_picker">选择备份文件进行导入</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> <string name="allowlist_restore_failed">还原失败</string>
</resources> </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_summary_picker">Choose a location to export the allowlist</string>
<string name="allowlist_backup_success">Backup succeeded</string> <string name="allowlist_backup_success">Backup succeeded</string>
<string name="allowlist_backup_failed">Backup failed</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_summary_picker">Choose a backup file to import</string>
<string name="allowlist_restore_success">Restore succeeded</string> <string name="allowlist_restore_success">Restore succeeded</string>
<string name="allowlist_restore_failed">Restore failed</string> <string name="allowlist_restore_failed">Restore failed</string>