manager: Support monet colors

Co-authored-by: YuKongA <70465933+YuKongA@users.noreply.github.com>
This commit is contained in:
ShirkNeko
2025-11-20 12:02:49 +08:00
parent d2a6fa4513
commit 8e7f1f1cc7
23 changed files with 229 additions and 397 deletions

View File

@@ -1,5 +1,7 @@
package com.sukisu.ultra.ui package com.sukisu.ultra.ui
import android.content.SharedPreferences
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
@@ -19,11 +21,14 @@ import androidx.compose.foundation.pager.PagerState
import androidx.compose.foundation.pager.rememberPagerState import androidx.compose.foundation.pager.rememberPagerState
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.compositionLocalOf import androidx.compose.runtime.compositionLocalOf
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.produceState import androidx.compose.runtime.produceState
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import com.sukisu.ultra.ui.util.getKpmVersion import com.sukisu.ultra.ui.util.getKpmVersion
@@ -69,7 +74,24 @@ class MainActivity : ComponentActivity() {
if (isManager && !Natives.requireNewKernel()) install() if (isManager && !Natives.requireNewKernel()) install()
setContent { setContent {
KernelSUTheme { val context = LocalActivity.current ?: this
val prefs = context.getSharedPreferences("settings", MODE_PRIVATE)
var colorMode by remember { mutableIntStateOf(prefs.getInt("color_mode", 0)) }
var keyColorInt by remember { mutableIntStateOf(prefs.getInt("key_color", 0)) }
val keyColor = remember(keyColorInt) { if (keyColorInt == 0) null else Color(keyColorInt) }
DisposableEffect(prefs) {
val listener = SharedPreferences.OnSharedPreferenceChangeListener { _, key ->
when (key) {
"color_mode" -> colorMode = prefs.getInt("color_mode", 0)
"key_color" -> keyColorInt = prefs.getInt("key_color", 0)
}
}
prefs.registerOnSharedPreferenceChangeListener(listener)
onDispose { prefs.unregisterOnSharedPreferenceChangeListener(listener) }
}
KernelSUTheme(colorMode = colorMode, keyColor = keyColor) {
val navController = rememberNavController() val navController = rememberNavController()
Scaffold { Scaffold {

View File

@@ -11,6 +11,8 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import top.yukonga.miuix.kmp.basic.Text import top.yukonga.miuix.kmp.basic.Text
import top.yukonga.miuix.kmp.extra.DropdownColors
import top.yukonga.miuix.kmp.extra.DropdownDefaults
import top.yukonga.miuix.kmp.theme.MiuixTheme import top.yukonga.miuix.kmp.theme.MiuixTheme
@Composable @Composable

View File

@@ -1,299 +0,0 @@
package com.sukisu.ultra.ui.component
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.RowScope
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.widthIn
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Immutable
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.key
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberUpdatedState
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.BlendMode
import androidx.compose.ui.graphics.BlendModeColorFilter
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.hapticfeedback.HapticFeedback
import androidx.compose.ui.hapticfeedback.HapticFeedbackType
import androidx.compose.ui.platform.LocalHapticFeedback
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import top.yukonga.miuix.kmp.basic.BasicComponent
import top.yukonga.miuix.kmp.basic.BasicComponentColors
import top.yukonga.miuix.kmp.basic.BasicComponentDefaults
import top.yukonga.miuix.kmp.basic.ListPopup
import top.yukonga.miuix.kmp.basic.ListPopupColumn
import top.yukonga.miuix.kmp.basic.PopupPositionProvider
import top.yukonga.miuix.kmp.basic.Text
import top.yukonga.miuix.kmp.icon.MiuixIcons
import top.yukonga.miuix.kmp.icon.icons.basic.ArrowUpDownIntegrated
import top.yukonga.miuix.kmp.icon.icons.basic.Check
import top.yukonga.miuix.kmp.theme.MiuixTheme
/**
* A dropdown with a title and a summary.
*
* @param items The options of the [SuperDropdown].
* @param selectedIndex The index of the selected option.
* @param title The title of the [SuperDropdown].
* @param titleColor The color of the title.
* @param summary The summary of the [SuperDropdown].
* @param summaryColor The color of the summary.
* @param dropdownColors The [DropdownColors] of the [SuperDropdown].
* @param insideMargin The margin inside the [SuperDropdown].
* @param maxHeight The maximum height of the [ListPopup].
* @param enabled Whether the [SuperDropdown] is enabled.
* @param showValue Whether to show the selected value of the [SuperDropdown].
* @param onClick The callback when the [SuperDropdown] is clicked.
* @param onSelectedIndexChange The callback when the selected index of the [SuperDropdown] is changed.
*/
@Composable
fun SuperDropdown(
items: List<String>,
selectedIndex: Int,
title: String,
titleColor: BasicComponentColors = BasicComponentDefaults.titleColor(),
summary: String? = null,
summaryColor: BasicComponentColors = BasicComponentDefaults.summaryColor(),
dropdownColors: DropdownColors = DropdownDefaults.dropdownColors(),
leftAction: (@Composable (() -> Unit))? = null,
insideMargin: PaddingValues = BasicComponentDefaults.InsideMargin,
maxHeight: Dp? = null,
enabled: Boolean = true,
showValue: Boolean = true,
onClick: (() -> Unit)? = null,
onSelectedIndexChange: ((Int) -> Unit)?,
) {
val interactionSource = remember { MutableInteractionSource() }
val isDropdownExpanded = remember { mutableStateOf(false) }
val hapticFeedback = LocalHapticFeedback.current
val itemsNotEmpty = items.isNotEmpty()
val actualEnabled = enabled && itemsNotEmpty
val actionColor = if (actualEnabled) {
MiuixTheme.colorScheme.onSurfaceVariantActions
} else {
MiuixTheme.colorScheme.disabledOnSecondaryVariant
}
val handleClick: () -> Unit = {
if (actualEnabled) {
onClick?.invoke()
isDropdownExpanded.value = !isDropdownExpanded.value
if (isDropdownExpanded.value) {
hapticFeedback.performHapticFeedback(HapticFeedbackType.ContextClick)
}
}
}
BasicComponent(
interactionSource = interactionSource,
insideMargin = insideMargin,
title = title,
titleColor = titleColor,
summary = summary,
summaryColor = summaryColor,
leftAction = if (itemsNotEmpty) {
{
SuperDropdownPopup(
items = items,
selectedIndex = selectedIndex,
isDropdownExpanded = isDropdownExpanded,
maxHeight = maxHeight,
dropdownColors = dropdownColors,
hapticFeedback = hapticFeedback,
onSelectedIndexChange = onSelectedIndexChange
)
leftAction?.invoke()
}
} else null,
rightActions = {
SuperDropdownRightActions(
showValue = showValue,
itemsNotEmpty = itemsNotEmpty,
items = items,
selectedIndex = selectedIndex,
actionColor = actionColor
)
},
onClick = handleClick,
holdDownState = isDropdownExpanded.value,
enabled = actualEnabled
)
}
@Composable
private fun SuperDropdownPopup(
items: List<String>,
selectedIndex: Int,
isDropdownExpanded: MutableState<Boolean>,
maxHeight: Dp?,
dropdownColors: DropdownColors,
hapticFeedback: HapticFeedback,
onSelectedIndexChange: ((Int) -> Unit)?
) {
val onSelectState = rememberUpdatedState(onSelectedIndexChange)
ListPopup(
show = isDropdownExpanded,
alignment = PopupPositionProvider.Align.Right,
onDismissRequest = {
isDropdownExpanded.value = false
},
maxHeight = maxHeight
) {
ListPopupColumn {
items.forEachIndexed { index, string ->
key(index) {
DropdownImpl(
text = string,
optionSize = items.size,
isSelected = selectedIndex == index,
dropdownColors = dropdownColors,
onSelectedIndexChange = { selectedIdx ->
hapticFeedback.performHapticFeedback(HapticFeedbackType.Confirm)
onSelectState.value?.invoke(selectedIdx)
isDropdownExpanded.value = false
},
index = index
)
}
}
}
}
}
@Composable
private fun RowScope.SuperDropdownRightActions(
showValue: Boolean,
itemsNotEmpty: Boolean,
items: List<String>,
selectedIndex: Int,
actionColor: Color
) {
if (showValue && itemsNotEmpty) {
Text(
modifier = Modifier.widthIn(max = 130.dp),
text = items[selectedIndex],
fontSize = MiuixTheme.textStyles.body2.fontSize,
color = actionColor,
textAlign = TextAlign.End,
overflow = TextOverflow.Ellipsis,
maxLines = 2
)
}
Image(
modifier = Modifier
.padding(start = 8.dp)
.size(10.dp, 16.dp)
.align(Alignment.CenterVertically),
imageVector = MiuixIcons.Basic.ArrowUpDownIntegrated,
colorFilter = ColorFilter.tint(actionColor),
contentDescription = null
)
}
/**
* The implementation of the dropdown.
*
* @param text The text of the current option.
* @param optionSize The size of the options.
* @param isSelected Whether the option is selected.
* @param index The index of the current option in the options.
* @param onSelectedIndexChange The callback when the index is selected.
*/
@Composable
fun DropdownImpl(
text: String,
optionSize: Int,
isSelected: Boolean,
index: Int,
dropdownColors: DropdownColors = DropdownDefaults.dropdownColors(),
onSelectedIndexChange: (Int) -> Unit
) {
val additionalTopPadding = if (index == 0) 20.dp else 12.dp
val additionalBottomPadding = if (index == optionSize - 1) 20.dp else 12.dp
val (textColor, backgroundColor) = if (isSelected) {
dropdownColors.selectedContentColor to dropdownColors.selectedContainerColor
} else {
dropdownColors.contentColor to dropdownColors.containerColor
}
val checkColor = if (isSelected) {
dropdownColors.selectedContentColor
} else {
Color.Transparent
}
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceBetween,
modifier = Modifier
.clickable { onSelectedIndexChange(index) }
.background(backgroundColor)
.padding(horizontal = 20.dp)
.padding(
top = additionalTopPadding,
bottom = additionalBottomPadding
)
) {
Text(
modifier = Modifier.widthIn(max = 200.dp),
text = text,
fontSize = MiuixTheme.textStyles.body1.fontSize,
fontWeight = FontWeight.Medium,
color = textColor,
)
Image(
modifier = Modifier
.padding(start = 12.dp)
.size(20.dp),
imageVector = MiuixIcons.Basic.Check,
colorFilter = BlendModeColorFilter(checkColor, BlendMode.SrcIn),
contentDescription = null,
)
}
}
@Immutable
class DropdownColors(
val contentColor: Color,
val containerColor: Color,
val selectedContentColor: Color,
val selectedContainerColor: Color
)
object DropdownDefaults {
@Composable
fun dropdownColors(
contentColor: Color = MiuixTheme.colorScheme.onSurface,
containerColor: Color = MiuixTheme.colorScheme.surface,
selectedContentColor: Color = MiuixTheme.colorScheme.onTertiaryContainer,
selectedContainerColor: Color = MiuixTheme.colorScheme.surface
): DropdownColors {
return DropdownColors(
contentColor = contentColor,
containerColor = containerColor,
selectedContentColor = selectedContentColor,
selectedContainerColor = selectedContainerColor
)
}
}

View File

@@ -30,13 +30,12 @@ import top.yukonga.miuix.kmp.extra.SuperDialog
@Composable @Composable
fun SuperEditArrow( fun SuperEditArrow(
modifier: Modifier = Modifier,
title: String, title: String,
titleColor: BasicComponentColors = BasicComponentDefaults.titleColor(), titleColor: BasicComponentColors = BasicComponentDefaults.titleColor(),
defaultValue: Int = -1, defaultValue: Int = -1,
summaryColor: BasicComponentColors = BasicComponentDefaults.summaryColor(), summaryColor: BasicComponentColors = BasicComponentDefaults.summaryColor(),
leftAction: @Composable (() -> Unit)? = null, leftAction: @Composable (() -> Unit)? = null,
rightActionColor: RightActionColors = SuperArrowDefaults.rightActionColors(),
modifier: Modifier = Modifier,
insideMargin: PaddingValues = BasicComponentDefaults.InsideMargin, insideMargin: PaddingValues = BasicComponentDefaults.InsideMargin,
enabled: Boolean = true, enabled: Boolean = true,
onValueChange: ((Int) -> Unit)? = null onValueChange: ((Int) -> Unit)? = null
@@ -50,7 +49,6 @@ fun SuperEditArrow(
summary = dialogTextFieldValue.intValue.toString(), summary = dialogTextFieldValue.intValue.toString(),
summaryColor = summaryColor, summaryColor = summaryColor,
leftAction = leftAction, leftAction = leftAction,
rightActionColor = rightActionColor,
modifier = modifier, modifier = modifier,
insideMargin = insideMargin, insideMargin = insideMargin,
onClick = { onClick = {

View File

@@ -1,5 +1,6 @@
package com.sukisu.ultra.ui.component package com.sukisu.ultra.ui.component
import androidx.activity.compose.BackHandler
import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.core.FastOutSlowInEasing import androidx.compose.animation.core.FastOutSlowInEasing
import androidx.compose.animation.core.LinearOutSlowInEasing import androidx.compose.animation.core.LinearOutSlowInEasing
@@ -73,7 +74,6 @@ import top.yukonga.miuix.kmp.icon.MiuixIcons
import top.yukonga.miuix.kmp.icon.icons.basic.Search import top.yukonga.miuix.kmp.icon.icons.basic.Search
import top.yukonga.miuix.kmp.icon.icons.basic.SearchCleanup import top.yukonga.miuix.kmp.icon.icons.basic.SearchCleanup
import top.yukonga.miuix.kmp.theme.MiuixTheme.colorScheme import top.yukonga.miuix.kmp.theme.MiuixTheme.colorScheme
import top.yukonga.miuix.kmp.utils.BackHandler
import top.yukonga.miuix.kmp.utils.overScrollVertical import top.yukonga.miuix.kmp.utils.overScrollVertical
// Search Status Class // Search Status Class

View File

@@ -15,12 +15,12 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import com.sukisu.ultra.Natives import com.sukisu.ultra.Natives
import com.sukisu.ultra.R import com.sukisu.ultra.R
import com.sukisu.ultra.ui.component.SuperDropdown
import com.sukisu.ultra.ui.util.listAppProfileTemplates import com.sukisu.ultra.ui.util.listAppProfileTemplates
import com.sukisu.ultra.ui.util.setSepolicy import com.sukisu.ultra.ui.util.setSepolicy
import com.sukisu.ultra.ui.viewmodel.getTemplateInfoById import com.sukisu.ultra.ui.viewmodel.getTemplateInfoById
import top.yukonga.miuix.kmp.basic.Icon import top.yukonga.miuix.kmp.basic.Icon
import top.yukonga.miuix.kmp.extra.SuperArrow import top.yukonga.miuix.kmp.extra.SuperArrow
import top.yukonga.miuix.kmp.extra.SuperDropdown
import top.yukonga.miuix.kmp.theme.MiuixTheme import top.yukonga.miuix.kmp.theme.MiuixTheme
/** /**

View File

@@ -67,8 +67,8 @@ fun AboutScreen(navigator: DestinationsNavigator) {
val scrollBehavior = MiuixScrollBehavior() val scrollBehavior = MiuixScrollBehavior()
val hazeState = remember { HazeState() } val hazeState = remember { HazeState() }
val hazeStyle = HazeStyle( val hazeStyle = HazeStyle(
backgroundColor = colorScheme.background, backgroundColor = colorScheme.surface,
tint = HazeTint(colorScheme.background.copy(0.8f)) tint = HazeTint(colorScheme.surface.copy(0.8f))
) )
val htmlString = stringResource( val htmlString = stringResource(

View File

@@ -62,7 +62,6 @@ import com.sukisu.ultra.Natives
import com.sukisu.ultra.R import com.sukisu.ultra.R
import com.sukisu.ultra.ui.component.AppIconImage import com.sukisu.ultra.ui.component.AppIconImage
import com.sukisu.ultra.ui.component.DropdownItem import com.sukisu.ultra.ui.component.DropdownItem
import com.sukisu.ultra.ui.component.SuperDropdown
import com.sukisu.ultra.ui.component.profile.AppProfileConfig import com.sukisu.ultra.ui.component.profile.AppProfileConfig
import com.sukisu.ultra.ui.component.profile.RootProfileConfig import com.sukisu.ultra.ui.component.profile.RootProfileConfig
import com.sukisu.ultra.ui.component.profile.TemplateConfig import com.sukisu.ultra.ui.component.profile.TemplateConfig
@@ -90,6 +89,7 @@ import top.yukonga.miuix.kmp.basic.ScrollBehavior
import top.yukonga.miuix.kmp.basic.SmallTitle import top.yukonga.miuix.kmp.basic.SmallTitle
import top.yukonga.miuix.kmp.basic.Text import top.yukonga.miuix.kmp.basic.Text
import top.yukonga.miuix.kmp.basic.TopAppBar import top.yukonga.miuix.kmp.basic.TopAppBar
import top.yukonga.miuix.kmp.extra.SuperDropdown
import top.yukonga.miuix.kmp.extra.SuperSwitch import top.yukonga.miuix.kmp.extra.SuperSwitch
import top.yukonga.miuix.kmp.icon.MiuixIcons import top.yukonga.miuix.kmp.icon.MiuixIcons
import top.yukonga.miuix.kmp.icon.icons.useful.Back import top.yukonga.miuix.kmp.icon.icons.useful.Back
@@ -113,8 +113,8 @@ fun AppProfileScreen(
val scrollBehavior = MiuixScrollBehavior() val scrollBehavior = MiuixScrollBehavior()
val hazeState = remember { HazeState() } val hazeState = remember { HazeState() }
val hazeStyle = HazeStyle( val hazeStyle = HazeStyle(
backgroundColor = colorScheme.background, backgroundColor = colorScheme.surface,
tint = HazeTint(colorScheme.background.copy(0.8f)) tint = HazeTint(colorScheme.surface.copy(0.8f))
) )
val scope = rememberCoroutineScope() val scope = rememberCoroutineScope()
val failToUpdateAppProfile = stringResource(R.string.failed_to_update_app_profile).format(appInfo.label).format(appInfo.uid) val failToUpdateAppProfile = stringResource(R.string.failed_to_update_app_profile).format(appInfo.label).format(appInfo.uid)

View File

@@ -78,8 +78,8 @@ fun ExecuteModuleActionScreen(navigator: DestinationsNavigator, moduleId: String
var actionResult: Boolean var actionResult: Boolean
val hazeState = remember { HazeState() } val hazeState = remember { HazeState() }
val hazeStyle = HazeStyle( val hazeStyle = HazeStyle(
backgroundColor = colorScheme.background, backgroundColor = colorScheme.surface,
tint = HazeTint(colorScheme.background.copy(0.8f)) tint = HazeTint(colorScheme.surface.copy(0.8f))
) )
LaunchedEffect(Unit) { LaunchedEffect(Unit) {

View File

@@ -89,6 +89,7 @@ import top.yukonga.miuix.kmp.icon.MiuixIcons
import top.yukonga.miuix.kmp.icon.icons.useful.Save import top.yukonga.miuix.kmp.icon.icons.useful.Save
import top.yukonga.miuix.kmp.theme.MiuixTheme import top.yukonga.miuix.kmp.theme.MiuixTheme
import top.yukonga.miuix.kmp.theme.MiuixTheme.colorScheme import top.yukonga.miuix.kmp.theme.MiuixTheme.colorScheme
import top.yukonga.miuix.kmp.theme.MiuixTheme.isDynamicColor
import top.yukonga.miuix.kmp.utils.PressFeedbackType import top.yukonga.miuix.kmp.utils.PressFeedbackType
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
@@ -104,8 +105,8 @@ fun HomePager(
val scrollBehavior = MiuixScrollBehavior() val scrollBehavior = MiuixScrollBehavior()
val hazeState = remember { HazeState() } val hazeState = remember { HazeState() }
val hazeStyle = HazeStyle( val hazeStyle = HazeStyle(
backgroundColor = colorScheme.background, backgroundColor = colorScheme.surface,
tint = HazeTint(colorScheme.background.copy(0.8f)) tint = HazeTint(colorScheme.surface.copy(0.8f))
) )
val context = LocalContext.current val context = LocalContext.current
@@ -334,7 +335,11 @@ private fun StatusCard(
.weight(1f) .weight(1f)
.fillMaxHeight(), .fillMaxHeight(),
colors = CardDefaults.defaultColors( colors = CardDefaults.defaultColors(
color = if (isSystemInDarkTheme()) Color(0xFF1A3825) else Color(0xFFDFFAE4) color = when {
isDynamicColor -> colorScheme.secondaryContainer
isSystemInDarkTheme() -> Color(0xFF1A3825)
else -> Color(0xFFDFFAE4)
}
), ),
onClick = { onClick = {
if (kernelVersion.isGKI()) onClickInstall() if (kernelVersion.isGKI()) onClickInstall()
@@ -354,7 +359,11 @@ private fun StatusCard(
Icon( Icon(
modifier = Modifier.size(170.dp), modifier = Modifier.size(170.dp),
imageVector = Icons.Rounded.CheckCircleOutline, imageVector = Icons.Rounded.CheckCircleOutline,
tint = Color(0xFF36D167), tint = if (isDynamicColor) {
colorScheme.primary.copy(alpha = 0.8f)
} else {
Color(0xFF36D167)
},
contentDescription = null contentDescription = null
) )
} }
@@ -367,16 +376,14 @@ private fun StatusCard(
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
text = workingText, text = workingText,
fontSize = 20.sp, fontSize = 20.sp,
fontWeight = FontWeight.SemiBold, fontWeight = FontWeight.SemiBold
color = if (isSystemInDarkTheme()) Color(0xFFB8E6C5) else Color(0xFF1A5A2E)
) )
Spacer(Modifier.height(2.dp)) Spacer(Modifier.height(2.dp))
Text( Text(
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
text = stringResource(R.string.home_working_version, ksuVersion), text = stringResource(R.string.home_working_version, ksuVersion),
fontSize = 14.sp, fontSize = 14.sp,
fontWeight = FontWeight.Medium, fontWeight = FontWeight.Medium
color = if (isSystemInDarkTheme()) Color(0xFF9DD4AC) else Color(0xFF2D7A4A)
) )
} }
} }
@@ -503,15 +510,19 @@ private fun StatusCard(
@Composable @Composable
fun WarningCard( fun WarningCard(
message: String, message: String,
color: Color = if (isSystemInDarkTheme()) Color(0XFF310808) else Color(0xFFF8E2E2), color: Color? = null,
onClick: (() -> Unit)? = null onClick: (() -> Unit)? = null,
) { ) {
Card( Card(
onClick = { onClick = {
onClick?.invoke() onClick?.invoke()
}, },
colors = CardDefaults.defaultColors( colors = CardDefaults.defaultColors(
color = color color = color ?: when {
isDynamicColor -> colorScheme.errorContainer
isSystemInDarkTheme() -> Color(0XFF310808)
else -> Color(0xFFF8E2E2)
}
), ),
showIndication = onClick != null, showIndication = onClick != null,
pressFeedbackType = PressFeedbackType.Tilt pressFeedbackType = PressFeedbackType.Tilt
@@ -523,7 +534,7 @@ fun WarningCard(
) { ) {
Text( Text(
text = message, text = message,
color = Color(0xFFF72727), color = if (isDynamicColor) colorScheme.onErrorContainer else Color(0xFFF72727),
fontSize = 14.sp fontSize = 14.sp
) )
} }

View File

@@ -68,7 +68,6 @@ import dev.chrisbanes.haze.hazeSource
import com.sukisu.ultra.R import com.sukisu.ultra.R
import com.sukisu.ultra.getKernelVersion import com.sukisu.ultra.getKernelVersion
import com.sukisu.ultra.ui.component.ChooseKmiDialog import com.sukisu.ultra.ui.component.ChooseKmiDialog
import com.sukisu.ultra.ui.component.SuperDropdown
import com.sukisu.ultra.ui.component.rememberConfirmDialog import com.sukisu.ultra.ui.component.rememberConfirmDialog
import com.sukisu.ultra.ui.kernelFlash.component.SlotSelectionDialog import com.sukisu.ultra.ui.kernelFlash.component.SlotSelectionDialog
import com.sukisu.ultra.ui.util.LkmSelection import com.sukisu.ultra.ui.util.LkmSelection
@@ -90,6 +89,7 @@ import top.yukonga.miuix.kmp.basic.Text
import top.yukonga.miuix.kmp.basic.TopAppBar import top.yukonga.miuix.kmp.basic.TopAppBar
import top.yukonga.miuix.kmp.extra.SuperArrow import top.yukonga.miuix.kmp.extra.SuperArrow
import top.yukonga.miuix.kmp.extra.SuperCheckbox import top.yukonga.miuix.kmp.extra.SuperCheckbox
import top.yukonga.miuix.kmp.extra.SuperDropdown
import top.yukonga.miuix.kmp.icon.MiuixIcons import top.yukonga.miuix.kmp.icon.MiuixIcons
import top.yukonga.miuix.kmp.icon.icons.useful.Back 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.Edit
@@ -282,8 +282,8 @@ fun InstallScreen(
val scrollBehavior = MiuixScrollBehavior() val scrollBehavior = MiuixScrollBehavior()
val hazeState = remember { HazeState() } val hazeState = remember { HazeState() }
val hazeStyle = HazeStyle( val hazeStyle = HazeStyle(
backgroundColor = colorScheme.background, backgroundColor = colorScheme.surface,
tint = HazeTint(colorScheme.background.copy(0.8f)) tint = HazeTint(colorScheme.surface.copy(0.8f))
) )
Scaffold( Scaffold(

View File

@@ -107,8 +107,8 @@ fun KpmScreen(
} }
val hazeState = remember { HazeState() } val hazeState = remember { HazeState() }
val hazeStyle = HazeStyle( val hazeStyle = HazeStyle(
backgroundColor = colorScheme.background, backgroundColor = colorScheme.surface,
tint = HazeTint(colorScheme.background.copy(0.8f)) tint = HazeTint(colorScheme.surface.copy(0.8f))
) )
LaunchedEffect(searchStatus.searchText) { LaunchedEffect(searchStatus.searchText) {

View File

@@ -390,7 +390,7 @@ private fun LogControlPanel(
SuperArrow( SuperArrow(
title = stringResource(R.string.log_viewer_settings), title = stringResource(R.string.log_viewer_settings),
onClick = { isExpanded = !isExpanded }, onClick = { isExpanded = !isExpanded },
rightText = if (isExpanded) summary = if (isExpanded)
stringResource(R.string.log_viewer_collapse) stringResource(R.string.log_viewer_collapse)
else else
stringResource(R.string.log_viewer_expand) stringResource(R.string.log_viewer_expand)

View File

@@ -106,7 +106,6 @@ import com.sukisu.ultra.Natives
import com.sukisu.ultra.R import com.sukisu.ultra.R
import com.sukisu.ultra.ksuApp import com.sukisu.ultra.ksuApp
import com.sukisu.ultra.ui.component.ConfirmResult import com.sukisu.ultra.ui.component.ConfirmResult
import com.sukisu.ultra.ui.component.DropdownImpl
import com.sukisu.ultra.ui.component.RebootListPopup import com.sukisu.ultra.ui.component.RebootListPopup
import com.sukisu.ultra.ui.component.SearchBox import com.sukisu.ultra.ui.component.SearchBox
import com.sukisu.ultra.ui.component.SearchPager import com.sukisu.ultra.ui.component.SearchPager
@@ -137,6 +136,7 @@ import top.yukonga.miuix.kmp.basic.Switch
import top.yukonga.miuix.kmp.basic.Text import top.yukonga.miuix.kmp.basic.Text
import top.yukonga.miuix.kmp.basic.TopAppBar import top.yukonga.miuix.kmp.basic.TopAppBar
import top.yukonga.miuix.kmp.basic.rememberPullToRefreshState 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.MiuixIcons
import top.yukonga.miuix.kmp.icon.icons.useful.ImmersionMore import top.yukonga.miuix.kmp.icon.icons.useful.ImmersionMore
import top.yukonga.miuix.kmp.theme.MiuixTheme.colorScheme import top.yukonga.miuix.kmp.theme.MiuixTheme.colorScheme
@@ -387,8 +387,8 @@ fun ModulePager(
val hazeState = remember { HazeState() } val hazeState = remember { HazeState() }
val hazeStyle = HazeStyle( val hazeStyle = HazeStyle(
backgroundColor = colorScheme.background, backgroundColor = colorScheme.surface,
tint = HazeTint(colorScheme.background.copy(0.8f)) tint = HazeTint(colorScheme.surface.copy(0.8f))
) )
Scaffold( Scaffold(
@@ -916,11 +916,11 @@ fun ModuleItem(
val textDecoration by remember(module.remove) { val textDecoration by remember(module.remove) {
mutableStateOf(if (module.remove) TextDecoration.LineThrough else null) mutableStateOf(if (module.remove) TextDecoration.LineThrough else null)
} }
val onSurface = colorScheme.onSurface val colorScheme = colorScheme
val secondaryContainer = colorScheme.secondaryContainer.copy(alpha = 0.8f) val secondaryContainer = colorScheme.secondaryContainer.copy(alpha = 0.8f)
val actionIconTint = remember(isDark) { 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(isDark) { Color(if (isDark) 0xFF25354E else 0xFFEAF2FF) } val updateBg = remember(colorScheme) { colorScheme.tertiaryContainer.copy(alpha = 0.6f) }
val updateTint = remember { Color(0xFF0D84FF) } val updateTint = remember(colorScheme) { colorScheme.onTertiaryContainer.copy(alpha = 0.8f) }
Card( Card(
modifier = Modifier modifier = Modifier

View File

@@ -2,6 +2,7 @@ package com.sukisu.ultra.ui.screen
import android.app.Activity import android.app.Activity
import android.content.Context import android.content.Context
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.WindowInsetsSides import androidx.compose.foundation.layout.WindowInsetsSides
import androidx.compose.foundation.layout.add import androidx.compose.foundation.layout.add
@@ -22,6 +23,7 @@ import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.input.nestedscroll.nestedScroll import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
@@ -36,7 +38,6 @@ import dev.chrisbanes.haze.HazeTint
import dev.chrisbanes.haze.hazeEffect import dev.chrisbanes.haze.hazeEffect
import dev.chrisbanes.haze.hazeSource import dev.chrisbanes.haze.hazeSource
import com.sukisu.ultra.R import com.sukisu.ultra.R
import com.sukisu.ultra.ui.component.SuperDropdown
import top.yukonga.miuix.kmp.basic.Card import top.yukonga.miuix.kmp.basic.Card
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
@@ -46,6 +47,7 @@ import top.yukonga.miuix.kmp.basic.TopAppBar
import top.yukonga.miuix.kmp.icon.MiuixIcons import top.yukonga.miuix.kmp.icon.MiuixIcons
import top.yukonga.miuix.kmp.icon.icons.useful.Back import top.yukonga.miuix.kmp.icon.icons.useful.Back
import top.yukonga.miuix.kmp.theme.MiuixTheme.colorScheme import top.yukonga.miuix.kmp.theme.MiuixTheme.colorScheme
import top.yukonga.miuix.kmp.extra.SuperDropdown
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
import top.yukonga.miuix.kmp.utils.scrollEndHaptic import top.yukonga.miuix.kmp.utils.scrollEndHaptic
@@ -58,8 +60,8 @@ fun Personalization(
val scrollBehavior = MiuixScrollBehavior() val scrollBehavior = MiuixScrollBehavior()
val hazeState = remember { HazeState() } val hazeState = remember { HazeState() }
val hazeStyle = HazeStyle( val hazeStyle = HazeStyle(
backgroundColor = colorScheme.background, backgroundColor = colorScheme.surface,
tint = HazeTint(colorScheme.background.copy(0.8f)) tint = HazeTint(colorScheme.surface.copy(0.8f))
) )
Scaffold( Scaffold(
@@ -91,7 +93,6 @@ fun Personalization(
contentWindowInsets = WindowInsets.systemBars.add(WindowInsets.displayCutout).only(WindowInsetsSides.Horizontal) contentWindowInsets = WindowInsets.systemBars.add(WindowInsets.displayCutout).only(WindowInsetsSides.Horizontal)
) { innerPadding -> ) { innerPadding ->
val context = LocalContext.current val context = LocalContext.current
val activity = context as? Activity
val prefs = context.getSharedPreferences("settings", Context.MODE_PRIVATE) val prefs = context.getSharedPreferences("settings", Context.MODE_PRIVATE)
LazyColumn( LazyColumn(
@@ -112,36 +113,84 @@ fun Personalization(
.fillMaxWidth(), .fillMaxWidth(),
) { ) {
val themeItems = listOf( val themeItems = listOf(
stringResource(id = R.string.theme_follow_system), stringResource(id = R.string.settings_theme_mode_system),
stringResource(id = R.string.theme_light), stringResource(id = R.string.settings_theme_mode_light),
stringResource(id = R.string.theme_dark), stringResource(id = R.string.settings_theme_mode_dark),
stringResource(id = R.string.settings_theme_mode_monet_system),
stringResource(id = R.string.settings_theme_mode_monet_light),
stringResource(id = R.string.settings_theme_mode_monet_dark),
) )
var themeMode by rememberSaveable { var themeMode by rememberSaveable {
mutableIntStateOf(prefs.getInt("theme_mode", 0)) mutableIntStateOf(prefs.getInt("color_mode", 0))
} }
SuperDropdown( SuperDropdown(
title = stringResource(id = R.string.theme_mode), title = stringResource(id = R.string.settings_theme),
summary = stringResource(id = R.string.theme_mode_summary), summary = stringResource(id = R.string.settings_theme_summary),
items = themeItems, items = themeItems,
leftAction = { leftAction = {
Icon( Icon(
Icons.Rounded.Palette, Icons.Rounded.Palette,
modifier = Modifier.padding(end = 16.dp), modifier = Modifier.padding(end = 16.dp),
contentDescription = stringResource(id = R.string.theme_mode), contentDescription = stringResource(id = R.string.settings_theme),
tint = colorScheme.onBackground tint = colorScheme.onBackground
) )
}, },
selectedIndex = themeMode, selectedIndex = themeMode,
onSelectedIndexChange = { index -> onSelectedIndexChange = { index ->
prefs.edit { prefs.edit { putInt("color_mode", index) }
putInt("theme_mode", index)
}
themeMode = index themeMode = index
activity?.recreate()
} }
) )
AnimatedVisibility(
visible = themeMode in 3..5
) {
val colorItems = listOf(
stringResource(id = R.string.settings_key_color_default),
stringResource(id = R.string.color_blue),
stringResource(id = R.string.color_red),
stringResource(id = R.string.color_green),
stringResource(id = R.string.color_purple),
stringResource(id = R.string.color_orange),
stringResource(id = R.string.color_teal),
stringResource(id = R.string.color_pink),
stringResource(id = R.string.color_brown),
)
val colorValues = listOf(
0,
Color(0xFF1A73E8).toArgb(),
Color(0xFFEA4335).toArgb(),
Color(0xFF34A853).toArgb(),
Color(0xFF9333EA).toArgb(),
Color(0xFFFB8C00).toArgb(),
Color(0xFF009688).toArgb(),
Color(0xFFE91E63).toArgb(),
Color(0xFF795548).toArgb(),
)
var keyColorIndex by rememberSaveable {
mutableIntStateOf(
colorValues.indexOf(prefs.getInt("key_color", 0)).coerceAtLeast(0)
)
}
SuperDropdown(
title = stringResource(id = R.string.settings_key_color),
summary = stringResource(id = R.string.settings_key_color_summary),
items = colorItems,
leftAction = {
Icon(
Icons.Rounded.Palette,
modifier = Modifier.padding(end = 16.dp),
contentDescription = stringResource(id = R.string.settings_key_color),
tint = colorScheme.onBackground
)
},
selectedIndex = keyColorIndex,
onSelectedIndexChange = { index ->
prefs.edit { putInt("key_color", colorValues[index]) }
keyColorIndex = index
}
)
}
} }
} }
} }

View File

@@ -8,6 +8,7 @@ import androidx.compose.animation.expandVertically
import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut import androidx.compose.animation.fadeOut
import androidx.compose.animation.shrinkVertically import androidx.compose.animation.shrinkVertically
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.WindowInsetsSides import androidx.compose.foundation.layout.WindowInsetsSides
@@ -19,6 +20,8 @@ import androidx.compose.foundation.layout.only
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.systemBars import androidx.compose.foundation.layout.systemBars
import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material.icons.rounded.Palette
import androidx.compose.ui.graphics.toArgb
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.CleaningServices import androidx.compose.material.icons.filled.CleaningServices
import androidx.compose.material.icons.filled.Groups import androidx.compose.material.icons.filled.Groups
@@ -75,7 +78,6 @@ import com.sukisu.ultra.ui.component.ConfirmResult
import com.sukisu.ultra.ui.component.DynamicManagerCard import com.sukisu.ultra.ui.component.DynamicManagerCard
import com.sukisu.ultra.ui.component.KsuIsValid import com.sukisu.ultra.ui.component.KsuIsValid
import com.sukisu.ultra.ui.component.SendLogDialog import com.sukisu.ultra.ui.component.SendLogDialog
import com.sukisu.ultra.ui.component.SuperDropdown
import com.sukisu.ultra.ui.component.UninstallDialog import com.sukisu.ultra.ui.component.UninstallDialog
import com.sukisu.ultra.ui.component.rememberConfirmDialog import com.sukisu.ultra.ui.component.rememberConfirmDialog
import com.sukisu.ultra.ui.component.rememberLoadingDialog import com.sukisu.ultra.ui.component.rememberLoadingDialog
@@ -95,6 +97,7 @@ import top.yukonga.miuix.kmp.basic.MiuixScrollBehavior
import top.yukonga.miuix.kmp.basic.Scaffold import top.yukonga.miuix.kmp.basic.Scaffold
import top.yukonga.miuix.kmp.basic.TopAppBar import top.yukonga.miuix.kmp.basic.TopAppBar
import top.yukonga.miuix.kmp.extra.SuperArrow import top.yukonga.miuix.kmp.extra.SuperArrow
import top.yukonga.miuix.kmp.extra.SuperDropdown
import top.yukonga.miuix.kmp.extra.SuperSwitch import top.yukonga.miuix.kmp.extra.SuperSwitch
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
@@ -114,8 +117,8 @@ fun SettingPager(
val scrollBehavior = MiuixScrollBehavior() val scrollBehavior = MiuixScrollBehavior()
val hazeState = remember { HazeState() } val hazeState = remember { HazeState() }
val hazeStyle = HazeStyle( val hazeStyle = HazeStyle(
backgroundColor = colorScheme.background, backgroundColor = colorScheme.surface,
tint = HazeTint(colorScheme.background.copy(0.8f)) tint = HazeTint(colorScheme.surface.copy(0.8f))
) )
Scaffold( Scaffold(

View File

@@ -133,8 +133,8 @@ fun SuperUserPager(
} }
val hazeState = remember { HazeState() } val hazeState = remember { HazeState() }
val hazeStyle = HazeStyle( val hazeStyle = HazeStyle(
backgroundColor = colorScheme.background, backgroundColor = colorScheme.surface,
tint = HazeTint(colorScheme.background.copy(0.8f)) tint = HazeTint(colorScheme.surface.copy(0.8f))
) )
Scaffold( Scaffold(
@@ -469,19 +469,23 @@ private fun GroupItem(
) { ) {
val isDark = isSystemInDarkTheme() val isDark = isSystemInDarkTheme()
val colorScheme = colorScheme val colorScheme = colorScheme
val bg = remember { colorScheme.secondaryContainer.copy(alpha = 0.8f) } val bg = remember(colorScheme) { colorScheme.secondaryContainer.copy(alpha = 0.8f) }
val rootBg = remember { colorScheme.tertiaryContainer.copy(alpha = 0.6f) } val rootBg = remember(colorScheme) { colorScheme.tertiaryContainer.copy(alpha = 0.6f) }
val unmountBg = remember(isDark) { if (isDark) Color.White.copy(alpha = 0.4f) else Color.Black.copy(alpha = 0.3f) } val unmountBg = remember(isDark, colorScheme) {
val fg = remember { colorScheme.onSecondaryContainer } if (isDark) Color.White.copy(alpha = 0.4f) else Color.Black.copy(alpha = 0.3f)
val rootFg = remember { colorScheme.onTertiaryContainer.copy(alpha = 0.8f) } }
val unmountFg = remember(isDark) { if (isDark) Color.Black.copy(alpha = 0.4f) else Color.White.copy(alpha = 0.8f) } val fg = remember(colorScheme) { colorScheme.onSecondaryContainer }
val rootFg = remember(colorScheme) { colorScheme.onTertiaryContainer.copy(alpha = 0.8f) }
val unmountFg = remember(isDark, colorScheme) {
if (isDark) Color.Black.copy(alpha = 0.4f) else Color.White.copy(alpha = 0.8f)
}
val userId = group.uid / 100000 val userId = group.uid / 100000
val packageInfo = group.primary.packageInfo val packageInfo = group.primary.packageInfo
val applicationInfo = packageInfo.applicationInfo val applicationInfo = packageInfo.applicationInfo
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) { val tags = remember(group.uid, group.anyAllowSu, group.anyCustom, colorScheme) {
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

@@ -164,8 +164,8 @@ fun AppProfileTemplateScreen(
) )
val hazeState = remember { HazeState() } val hazeState = remember { HazeState() }
val hazeStyle = HazeStyle( val hazeStyle = HazeStyle(
backgroundColor = colorScheme.background, backgroundColor = colorScheme.surface,
tint = HazeTint(colorScheme.background.copy(0.8f)) tint = HazeTint(colorScheme.surface.copy(0.8f))
) )
Scaffold( Scaffold(

View File

@@ -87,8 +87,8 @@ fun TemplateEditorScreen(
val scrollBehavior = MiuixScrollBehavior() val scrollBehavior = MiuixScrollBehavior()
val hazeState = remember { HazeState() } val hazeState = remember { HazeState() }
val hazeStyle = HazeStyle( val hazeStyle = HazeStyle(
backgroundColor = colorScheme.background, backgroundColor = colorScheme.surface,
tint = HazeTint(colorScheme.background.copy(0.8f)) tint = HazeTint(colorScheme.surface.copy(0.8f))
) )
BackHandler { BackHandler {

View File

@@ -1,34 +1,42 @@
package com.sukisu.ultra.ui.theme package com.sukisu.ultra.ui.theme
import android.content.Context
import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.graphics.Color
import top.yukonga.miuix.kmp.theme.ColorSchemeMode
import top.yukonga.miuix.kmp.theme.MiuixTheme import top.yukonga.miuix.kmp.theme.MiuixTheme
import top.yukonga.miuix.kmp.theme.darkColorScheme import top.yukonga.miuix.kmp.theme.ThemeController
import top.yukonga.miuix.kmp.theme.lightColorScheme
@Composable @Composable
fun KernelSUTheme( fun KernelSUTheme(
darkTheme: Boolean = isSystemInDarkTheme(), colorMode: Int = 0,
keyColor: Color? = null,
content: @Composable () -> Unit content: @Composable () -> Unit
) { ) {
val context = LocalContext.current val isDark = isSystemInDarkTheme()
val prefs = context.getSharedPreferences("settings", Context.MODE_PRIVATE) val controller = when (colorMode) {
val themeMode = prefs.getInt("theme_mode", 0) 1 -> ThemeController(ColorSchemeMode.Light)
2 -> ThemeController(ColorSchemeMode.Dark)
3 -> ThemeController(
ColorSchemeMode.MonetSystem,
keyColor = keyColor,
isDark = isDark
)
val useDarkTheme = when (themeMode) { 4 -> ThemeController(
1 -> false // 浅色 ColorSchemeMode.MonetLight,
2 -> true // 深色 keyColor = keyColor,
else -> darkTheme // 跟随系统 )
}
val colorScheme = when { 5 -> ThemeController(
useDarkTheme -> darkColorScheme() ColorSchemeMode.MonetDark,
else -> lightColorScheme() keyColor = keyColor,
)
else -> ThemeController(ColorSchemeMode.System)
} }
MiuixTheme( return MiuixTheme(
colors = colorScheme, controller = controller,
content = content content = content
) )
} }

View File

@@ -158,6 +158,26 @@
<string name="module_undo_uninstall_success">成功撤销卸载 %s</string> <string name="module_undo_uninstall_success">成功撤销卸载 %s</string>
<string name="module_undo_uninstall_failed">撤销卸载 %s 失败</string> <string name="module_undo_uninstall_failed">撤销卸载 %s 失败</string>
<string name="group_contains_apps">包含 %1$d 个应用</string> <string name="group_contains_apps">包含 %1$d 个应用</string>
<string name="settings_theme">主题</string>
<string name="settings_theme_summary">选择应用的主题模式。</string>
<string name="settings_theme_mode_system">跟随系统</string>
<string name="settings_theme_mode_light">浅色</string>
<string name="settings_theme_mode_dark">深色</string>
<string name="settings_theme_mode_monet_system">Monet跟随系统</string>
<string name="settings_theme_mode_monet_light">Monet浅色</string>
<string name="settings_theme_mode_monet_dark">Monet深色</string>
<string name="settings_key_color">强调色</string>
<string name="settings_key_color_summary">在使用 Monet 时自定义种子色。</string>
<string name="settings_key_color_default">默认</string>
<string name="color_blue">蓝色</string>
<string name="color_red">红色</string>
<string name="color_green">绿色</string>
<string name="color_purple">紫色</string>
<string name="color_orange">橙色</string>
<string name="color_teal">青色</string>
<string name="color_pink">粉色</string>
<string name="color_brown">棕色</string>
<!-- Customize -->
<string name="home_susfs_version">SuSFS 版本</string> <string name="home_susfs_version">SuSFS 版本</string>
<string name="manual_hook">Manual Hook</string> <string name="manual_hook">Manual Hook</string>
<string name="inline_hook">Inline Hook</string> <string name="inline_hook">Inline Hook</string>
@@ -243,9 +263,6 @@
<string name="theme_settings">主题设置</string> <string name="theme_settings">主题设置</string>
<string name="theme_mode">主题模式</string> <string name="theme_mode">主题模式</string>
<string name="theme_mode_summary">选择应用的显示主题</string> <string name="theme_mode_summary">选择应用的显示主题</string>
<string name="theme_light">浅色</string>
<string name="theme_dark">深色</string>
<string name="theme_follow_system">跟随系统</string>
<!-- Kernel Flash Progress Related --> <!-- Kernel Flash Progress Related -->
<string name="horizon_flash_complete">刷入完成</string> <string name="horizon_flash_complete">刷入完成</string>
<string name="horizon_preparing">准备中…</string> <string name="horizon_preparing">准备中…</string>

View File

@@ -160,6 +160,26 @@
<string name="module_undo_uninstall_success">Successfully canceled uninstall of %s</string> <string name="module_undo_uninstall_success">Successfully canceled uninstall of %s</string>
<string name="module_undo_uninstall_failed">Failed to undo uninstall: %s</string> <string name="module_undo_uninstall_failed">Failed to undo uninstall: %s</string>
<string name="group_contains_apps">Contains %d apps</string> <string name="group_contains_apps">Contains %d apps</string>
<string name="settings_theme">Theme</string>
<string name="settings_theme_summary">Choose the app theme mode.</string>
<string name="settings_theme_mode_system">Follow system</string>
<string name="settings_theme_mode_light">Light</string>
<string name="settings_theme_mode_dark">Dark</string>
<string name="settings_theme_mode_monet_system">Monet (Follow system)</string>
<string name="settings_theme_mode_monet_light">Monet (Light)</string>
<string name="settings_theme_mode_monet_dark">Monet (Dark)</string>
<string name="settings_key_color">Key color</string>
<string name="settings_key_color_summary">Customize accent when using Monet.</string>
<string name="settings_key_color_default">Default</string>
<string name="color_blue">Blue</string>
<string name="color_red">Red</string>
<string name="color_green">Green</string>
<string name="color_purple">Purple</string>
<string name="color_orange">Orange</string>
<string name="color_teal">Teal</string>
<string name="color_pink">Pink</string>
<string name="color_brown">Brown</string>
<!-- Customize -->
<string name="home_susfs_version">SuSFS Version</string> <string name="home_susfs_version">SuSFS Version</string>
<string name="manual_hook">Manual Hook</string> <string name="manual_hook">Manual Hook</string>
<string name="inline_hook">Inline Hook</string> <string name="inline_hook">Inline Hook</string>
@@ -247,9 +267,6 @@
<string name="theme_settings">Theme Settings</string> <string name="theme_settings">Theme Settings</string>
<string name="theme_mode">Theme Mode</string> <string name="theme_mode">Theme Mode</string>
<string name="theme_mode_summary">Select the app\'s display theme</string> <string name="theme_mode_summary">Select the app\'s display theme</string>
<string name="theme_light">Light</string>
<string name="theme_dark">Dark</string>
<string name="theme_follow_system">Follow System</string>
<!-- Kernel Flash Progress Related --> <!-- Kernel Flash Progress Related -->
<string name="horizon_flash_complete">Flash Complete</string> <string name="horizon_flash_complete">Flash Complete</string>
<string name="horizon_preparing">Preparing…</string> <string name="horizon_preparing">Preparing…</string>

View File

@@ -3,8 +3,8 @@ agp = "8.13.1"
gson = "2.13.2" gson = "2.13.2"
kotlin = "2.2.21" kotlin = "2.2.21"
ksp = "2.3.2" ksp = "2.3.2"
compose-bom = "2025.11.00" compose-bom = "2025.11.01"
lifecycle = "2.9.4" lifecycle = "2.10.0"
navigation = "2.9.6" navigation = "2.9.6"
activity-compose = "1.11.0" activity-compose = "1.11.0"
kotlinx-coroutines = "1.10.2" kotlinx-coroutines = "1.10.2"
@@ -17,7 +17,7 @@ ndk = "29.0.13599879-beta2"
libsu = "6.0.0" libsu = "6.0.0"
apksign = "1.4" apksign = "1.4"
cmaker = "1.2" cmaker = "1.2"
miuix = "0.6.1" miuix = "0.7.1"
haze = "1.7.0" haze = "1.7.0"
capsule = "2.1.1" capsule = "2.1.1"
documentfile = "1.1.0" documentfile = "1.1.0"