diff --git a/manager/app/src/main/java/com/sukisu/ultra/ui/component/SearchBar.kt b/manager/app/src/main/java/com/sukisu/ultra/ui/component/SearchBar.kt index 31743ec0..91d08b17 100644 --- a/manager/app/src/main/java/com/sukisu/ultra/ui/component/SearchBar.kt +++ b/manager/app/src/main/java/com/sukisu/ultra/ui/component/SearchBar.kt @@ -63,7 +63,12 @@ fun SearchAppBar( var onSearch by remember { mutableStateOf(false) } // 获取卡片颜色和透明度 - val cardColor = MaterialTheme.colorScheme.surfaceContainerLow + val colorScheme = MaterialTheme.colorScheme + val cardColor = if (CardConfig.isCustomBackgroundEnabled) { + colorScheme.surfaceContainerLow + } else { + colorScheme.background + } val cardAlpha = CardConfig.cardAlpha if (onSearch) { diff --git a/manager/app/src/main/java/com/sukisu/ultra/ui/component/SettingsItem.kt b/manager/app/src/main/java/com/sukisu/ultra/ui/component/SettingsItem.kt deleted file mode 100644 index 23f2e2af..00000000 --- a/manager/app/src/main/java/com/sukisu/ultra/ui/component/SettingsItem.kt +++ /dev/null @@ -1,87 +0,0 @@ -package com.sukisu.ultra.ui.component - -import androidx.compose.foundation.LocalIndication -import androidx.compose.foundation.interaction.MutableInteractionSource -import androidx.compose.foundation.selection.toggleable -import androidx.compose.material3.Icon -import androidx.compose.material3.ListItem -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Switch -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.remember -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.alpha -import androidx.compose.ui.graphics.vector.ImageVector -import androidx.compose.ui.semantics.Role -import com.dergoogler.mmrl.ui.component.LabelItem -import com.dergoogler.mmrl.ui.component.text.TextRow - -@Composable -fun SwitchItem( - icon: ImageVector? = null, - title: String, - summary: String? = null, - checked: Boolean, - enabled: Boolean = true, - beta: Boolean = false, - onCheckedChange: (Boolean) -> Unit, -) { - val interactionSource = remember { MutableInteractionSource() } - val stateAlpha = remember(checked, enabled) { Modifier.alpha(if (enabled) 1f else 0.5f) } - - ListItem( - modifier = Modifier - .toggleable( - value = checked, - interactionSource = interactionSource, - role = Role.Switch, - enabled = enabled, - indication = LocalIndication.current, - onValueChange = onCheckedChange - ), - headlineContent = { - TextRow( - leadingContent = if (beta) { - { - LabelItem( - modifier = Modifier.then(stateAlpha), - text = "Beta" - ) - } - } else null - ) { - Text( - modifier = Modifier.then(stateAlpha), - text = title, - ) - } - }, - leadingContent = icon?.let { - { - Icon( - modifier = Modifier.then(stateAlpha), - imageVector = icon, - contentDescription = title, - tint = MaterialTheme.colorScheme.primary - ) - } - }, - trailingContent = { - Switch( - checked = checked, - enabled = enabled, - onCheckedChange = onCheckedChange, - interactionSource = interactionSource - ) - }, - supportingContent = { - if (summary != null) { - Text( - modifier = Modifier.then(stateAlpha), - text = summary - ) - } - } - ) -} \ No newline at end of file diff --git a/manager/app/src/main/java/com/sukisu/ultra/ui/component/SwitchItem.kt b/manager/app/src/main/java/com/sukisu/ultra/ui/component/SwitchItem.kt index 4d994a42..ad9eb0cf 100644 --- a/manager/app/src/main/java/com/sukisu/ultra/ui/component/SwitchItem.kt +++ b/manager/app/src/main/java/com/sukisu/ultra/ui/component/SwitchItem.kt @@ -21,7 +21,7 @@ import androidx.compose.ui.unit.dp @Composable fun SwitchItem( - icon: ImageVector, + icon: ImageVector? = null, title: String, summary: String? = null, checked: Boolean, @@ -55,47 +55,55 @@ fun SwitchItem( disabledUncheckedIconColor = MaterialTheme.colorScheme.surfaceVariant ) - ListItem( - headlineContent = { - Text( - text = title, - style = MaterialTheme.typography.titleMedium, - maxLines = Int.MAX_VALUE, - overflow = TextOverflow.Ellipsis - ) - }, - supportingContent = summary?.let { - { + MaterialTheme( + colorScheme = MaterialTheme.colorScheme.copy( + surface = MaterialTheme.colorScheme.surfaceContainerHigh + ) + ) { + ListItem( + headlineContent = { Text( - text = it, - style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant, + text = title, + style = MaterialTheme.typography.titleMedium, maxLines = Int.MAX_VALUE, overflow = TextOverflow.Ellipsis ) - } - }, - leadingContent = { - Icon( - imageVector = icon, - contentDescription = null, - modifier = Modifier.size(24.dp), - tint = iconTint - ) - }, - trailingContent = { - Switch( - checked = checked, - onCheckedChange = null, - enabled = enabled, - colors = switchColors - ) - }, - modifier = Modifier - .fillMaxWidth() - .clickable(enabled = enabled) { - onCheckedChange(!checked) - } - .padding(vertical = 4.dp) - ) + }, + supportingContent = summary?.let { + { + Text( + text = it, + style = MaterialTheme.typography.bodyMedium, + color = MaterialTheme.colorScheme.onSurfaceVariant, + maxLines = Int.MAX_VALUE, + overflow = TextOverflow.Ellipsis + ) + } + }, + leadingContent = icon?.let { + { + Icon( + imageVector = it, + contentDescription = null, + modifier = Modifier.size(24.dp), + tint = iconTint + ) + } + }, + trailingContent = { + Switch( + checked = checked, + onCheckedChange = null, + enabled = enabled, + colors = switchColors + ) + }, + modifier = Modifier + .fillMaxWidth() + .clickable(enabled = enabled) { + onCheckedChange(!checked) + } + .padding(vertical = 4.dp) + ) + } } \ No newline at end of file diff --git a/manager/app/src/main/java/com/sukisu/ultra/ui/component/profile/AppProfileConfig.kt b/manager/app/src/main/java/com/sukisu/ultra/ui/component/profile/AppProfileConfig.kt index 563497c7..ba0ce2a1 100644 --- a/manager/app/src/main/java/com/sukisu/ultra/ui/component/profile/AppProfileConfig.kt +++ b/manager/app/src/main/java/com/sukisu/ultra/ui/component/profile/AppProfileConfig.kt @@ -31,7 +31,6 @@ fun AppProfileConfig( onValueChange = { onProfileChange(profile.copy(name = it)) } ) } - SwitchItem( title = stringResource(R.string.profile_umount_modules), summary = stringResource(R.string.profile_umount_modules_summary), diff --git a/manager/app/src/main/java/com/sukisu/ultra/ui/screen/AppProfile.kt b/manager/app/src/main/java/com/sukisu/ultra/ui/screen/AppProfile.kt index 59527bde..a3cad340 100644 --- a/manager/app/src/main/java/com/sukisu/ultra/ui/screen/AppProfile.kt +++ b/manager/app/src/main/java/com/sukisu/ultra/ui/screen/AppProfile.kt @@ -37,7 +37,6 @@ import androidx.compose.material3.FilterChip import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.Icon import androidx.compose.material3.IconButton -import androidx.compose.material3.IconButtonDefaults import androidx.compose.material3.ListItem import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Scaffold @@ -84,6 +83,8 @@ import com.sukisu.ultra.ui.component.profile.AppProfileConfig import com.sukisu.ultra.ui.component.profile.RootProfileConfig import com.sukisu.ultra.ui.component.profile.TemplateConfig import com.sukisu.ultra.ui.theme.CardConfig +import com.sukisu.ultra.ui.theme.getCardColors +import com.sukisu.ultra.ui.theme.getCardElevation import com.sukisu.ultra.ui.util.LocalSnackbarHost import com.sukisu.ultra.ui.util.forceStopApp import com.sukisu.ultra.ui.util.getSepolicy @@ -122,7 +123,12 @@ fun AppProfileScreen( mutableStateOf(initialProfile) } - val cardColor = MaterialTheme.colorScheme.surfaceContainerLow + val colorScheme = MaterialTheme.colorScheme + val cardColor = if (CardConfig.isCustomBackgroundEnabled) { + colorScheme.surfaceContainerLow + } else { + colorScheme.background + } val cardAlpha = CardConfig.cardAlpha Scaffold( @@ -203,149 +209,172 @@ private fun AppProfileInner( onProfileChange: (Natives.Profile) -> Unit, ) { val isRootGranted = profile.allowSu + val cardColors = getCardColors(MaterialTheme.colorScheme.surfaceContainerHigh) - Column(modifier = modifier) { - ElevatedCard( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 16.dp, vertical = 8.dp), - shape = MaterialTheme.shapes.medium - ) { - AppMenuBox(packageName) { - ListItem( - headlineContent = { - Text( - text = appLabel, - style = MaterialTheme.typography.titleMedium - ) - }, - supportingContent = { - Text( - text = packageName, - style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - }, - leadingContent = appIcon, + MaterialTheme( + colorScheme = MaterialTheme.colorScheme.copy( + surface = MaterialTheme.colorScheme.surfaceContainerHigh + ) + ) { + Column(modifier = modifier) { + ElevatedCard( + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 16.dp, vertical = 8.dp), + shape = MaterialTheme.shapes.medium, + colors = cardColors, + elevation = getCardElevation(), + ) { + AppMenuBox(packageName) { + ListItem( + headlineContent = { + Text( + text = appLabel, + style = MaterialTheme.typography.titleMedium + ) + }, + supportingContent = { + Text( + text = packageName, + style = MaterialTheme.typography.bodyMedium, + color = MaterialTheme.colorScheme.onSurfaceVariant + ) + }, + leadingContent = appIcon, + ) + } + } + + ElevatedCard( + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 16.dp, vertical = 8.dp), + shape = MaterialTheme.shapes.medium, + colors = cardColors, + elevation = getCardElevation(), + ) { + SwitchItem( + icon = Icons.Filled.Security, + title = stringResource(id = R.string.superuser), + checked = isRootGranted, + onCheckedChange = { onProfileChange(profile.copy(allowSu = it)) }, ) } - } - ElevatedCard( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 16.dp, vertical = 8.dp), - shape = MaterialTheme.shapes.medium - ) { - SwitchItem( - icon = Icons.Filled.Security, - title = stringResource(id = R.string.superuser), - checked = isRootGranted, - onCheckedChange = { onProfileChange(profile.copy(allowSu = it)) }, - ) - } - - Crossfade( - targetState = isRootGranted, - label = "RootAccess" - ) { current -> - Column( - modifier = Modifier.padding(bottom = 6.dp + 48.dp + 6.dp /* SnackBar height */) - ) { - if (current) { - val initialMode = if (profile.rootUseDefault) { - Mode.Default - } else if (profile.rootTemplate != null) { - Mode.Template - } else { - Mode.Custom - } - var mode by rememberSaveable { - mutableStateOf(initialMode) - } - - ElevatedCard( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 16.dp, vertical = 8.dp), - shape = MaterialTheme.shapes.medium - ) { - ProfileBox(mode, true) { - // template mode shouldn't change profile here! - if (it == Mode.Default || it == Mode.Custom) { - onProfileChange(profile.copy(rootUseDefault = it == Mode.Default)) - } - mode = it + Crossfade( + targetState = isRootGranted, + label = "RootAccess" + ) { current -> + Column( + modifier = Modifier.padding(bottom = 6.dp + 48.dp + 6.dp /* SnackBar height */) + ) { + if (current) { + val initialMode = if (profile.rootUseDefault) { + Mode.Default + } else if (profile.rootTemplate != null) { + Mode.Template + } else { + Mode.Custom + } + var mode by rememberSaveable { + mutableStateOf(initialMode) } - } - AnimatedVisibility( - visible = mode != Mode.Default, - enter = fadeIn() + expandVertically(), - exit = fadeOut() + shrinkVertically() - ) { ElevatedCard( modifier = Modifier .fillMaxWidth() .padding(horizontal = 16.dp, vertical = 8.dp), - shape = MaterialTheme.shapes.medium + shape = MaterialTheme.shapes.medium, + colors = cardColors, ) { - Column(modifier = Modifier.padding(vertical = 8.dp)) { - Crossfade(targetState = mode, label = "ProfileMode") { currentMode -> - when (currentMode) { - Mode.Template -> { - TemplateConfig( - profile = profile, - onViewTemplate = onViewTemplate, - onManageTemplate = onManageTemplate, - onProfileChange = onProfileChange - ) + ProfileBox(mode, true) { + // template mode shouldn't change profile here! + if (it == Mode.Default || it == Mode.Custom) { + onProfileChange(profile.copy(rootUseDefault = it == Mode.Default)) + } + mode = it + } + } + + AnimatedVisibility( + visible = mode != Mode.Default, + enter = fadeIn() + expandVertically(), + exit = fadeOut() + shrinkVertically() + ) { + ElevatedCard( + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 16.dp, vertical = 8.dp), + shape = MaterialTheme.shapes.medium, + colors = cardColors, + elevation = getCardElevation(), + ) { + Column(modifier = Modifier.padding(vertical = 8.dp)) { + Crossfade( + targetState = mode, + label = "ProfileMode" + ) { currentMode -> + when (currentMode) { + Mode.Template -> { + TemplateConfig( + profile = profile, + onViewTemplate = onViewTemplate, + onManageTemplate = onManageTemplate, + onProfileChange = onProfileChange + ) + } + + Mode.Custom -> { + RootProfileConfig( + fixedName = true, + profile = profile, + onProfileChange = onProfileChange + ) + } + + else -> {} } - Mode.Custom -> { - RootProfileConfig( - fixedName = true, - profile = profile, - onProfileChange = onProfileChange - ) - } - else -> {} } } } } - } - } else { - val mode = if (profile.nonRootUseDefault) Mode.Default else Mode.Custom + } else { + val mode = if (profile.nonRootUseDefault) Mode.Default else Mode.Custom - ElevatedCard( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 16.dp, vertical = 8.dp), - shape = MaterialTheme.shapes.medium - ) { - ProfileBox(mode, false) { - onProfileChange(profile.copy(nonRootUseDefault = (it == Mode.Default))) - } - } - - AnimatedVisibility( - visible = mode == Mode.Custom, - enter = fadeIn() + expandVertically(), - exit = fadeOut() + shrinkVertically() - ) { ElevatedCard( modifier = Modifier .fillMaxWidth() .padding(horizontal = 16.dp, vertical = 8.dp), - shape = MaterialTheme.shapes.medium + shape = MaterialTheme.shapes.medium, + colors = cardColors, + elevation = getCardElevation(), ) { - Column(modifier = Modifier.padding(vertical = 8.dp)) { - AppProfileConfig( - fixedName = true, - profile = profile, - enabled = mode == Mode.Custom, - onProfileChange = onProfileChange - ) + ProfileBox(mode, false) { + onProfileChange(profile.copy(nonRootUseDefault = (it == Mode.Default))) + } + } + + AnimatedVisibility( + visible = mode == Mode.Custom, + enter = fadeIn() + expandVertically(), + exit = fadeOut() + shrinkVertically() + ) { + ElevatedCard( + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 16.dp, vertical = 8.dp), + shape = MaterialTheme.shapes.medium, + colors = cardColors, + elevation = getCardElevation(), + ) { + Column(modifier = Modifier.padding(vertical = 8.dp)) { + AppProfileConfig( + fixedName = true, + profile = profile, + enabled = mode == Mode.Custom, + onProfileChange = onProfileChange + ) + } } } } @@ -377,12 +406,10 @@ private fun TopBar( Text( text = title, style = MaterialTheme.typography.titleMedium, - color = MaterialTheme.colorScheme.onSurface ) Text( text = packageName, style = MaterialTheme.typography.bodySmall, - color = MaterialTheme.colorScheme.onSurfaceVariant, modifier = Modifier.alpha(0.8f) ) } @@ -391,9 +418,6 @@ private fun TopBar( navigationIcon = { IconButton( onClick = onBack, - colors = IconButtonDefaults.iconButtonColors( - contentColor = MaterialTheme.colorScheme.onSurface - ) ) { Icon( imageVector = Icons.AutoMirrored.Filled.ArrowBack, @@ -408,7 +432,6 @@ private fun TopBar( modifier = Modifier.shadow( elevation = if ((scrollBehavior?.state?.overlappedFraction ?: 0f) > 0.01f) 4.dp else 0.dp, - spotColor = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.1f) ) ) } @@ -431,7 +454,6 @@ private fun ProfileBox( Text( text = mode.text, style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant ) }, leadingContent = { @@ -444,7 +466,6 @@ private fun ProfileBox( HorizontalDivider( thickness = Dp.Hairline, - color = MaterialTheme.colorScheme.outlineVariant ) ListItem( @@ -574,20 +595,26 @@ private fun AppMenuOption(text: String, onClick: () -> Unit) { @Composable private fun AppProfilePreview() { var profile by remember { mutableStateOf(Natives.Profile("")) } - Surface { - AppProfileInner( - packageName = "icu.nullptr.test", - appLabel = "Test", - appIcon = { - Icon( - imageVector = Icons.Filled.Android, - contentDescription = null, - ) - }, - profile = profile, - onProfileChange = { - profile = it - }, + MaterialTheme( + colorScheme = MaterialTheme.colorScheme.copy( + surface = MaterialTheme.colorScheme.surfaceContainerHigh ) + ) { + Surface { + AppProfileInner( + packageName = "icu.nullptr.test", + appLabel = "Test", + appIcon = { + Icon( + imageVector = Icons.Filled.Android, + contentDescription = null, + ) + }, + profile = profile, + onProfileChange = { + profile = it + }, + ) + } } } \ No newline at end of file diff --git a/manager/app/src/main/java/com/sukisu/ultra/ui/screen/Flash.kt b/manager/app/src/main/java/com/sukisu/ultra/ui/screen/Flash.kt index 09d8ed90..04dadfeb 100644 --- a/manager/app/src/main/java/com/sukisu/ultra/ui/screen/Flash.kt +++ b/manager/app/src/main/java/com/sukisu/ultra/ui/screen/Flash.kt @@ -439,7 +439,12 @@ private fun TopBar( onSave: () -> Unit = {}, scrollBehavior: TopAppBarScrollBehavior? = null ) { - val cardColor = MaterialTheme.colorScheme.surfaceContainerLow + val colorScheme = MaterialTheme.colorScheme + val cardColor = if (CardConfig.isCustomBackgroundEnabled) { + colorScheme.surfaceContainerLow + } else { + colorScheme.background + } val cardAlpha = CardConfig.cardAlpha val statusColor = when(status) { diff --git a/manager/app/src/main/java/com/sukisu/ultra/ui/screen/Home.kt b/manager/app/src/main/java/com/sukisu/ultra/ui/screen/Home.kt index 03034d95..75b3f296 100644 --- a/manager/app/src/main/java/com/sukisu/ultra/ui/screen/Home.kt +++ b/manager/app/src/main/java/com/sukisu/ultra/ui/screen/Home.kt @@ -90,9 +90,11 @@ import com.sukisu.ultra.Natives import com.sukisu.ultra.R import com.sukisu.ultra.ui.component.KsuIsValid import com.sukisu.ultra.ui.component.rememberConfirmDialog +import com.sukisu.ultra.ui.theme.CardConfig import com.sukisu.ultra.ui.theme.CardConfig.cardAlpha import com.sukisu.ultra.ui.theme.CardConfig.cardElevation import com.sukisu.ultra.ui.theme.getCardColors +import com.sukisu.ultra.ui.theme.getCardElevation import com.sukisu.ultra.ui.util.checkNewVersion import com.sukisu.ultra.ui.util.getKpmModuleCount import com.sukisu.ultra.ui.util.getKpmVersion @@ -281,7 +283,12 @@ private fun TopBar( onInstallClick: () -> Unit, scrollBehavior: TopAppBarScrollBehavior? = null ) { - val cardColor = MaterialTheme.colorScheme.surfaceContainerLow + val colorScheme = MaterialTheme.colorScheme + val cardColor = if (CardConfig.isCustomBackgroundEnabled) { + colorScheme.surfaceContainerLow + } else { + colorScheme.background + } TopAppBar( title = { @@ -336,7 +343,7 @@ private fun StatusCard( ElevatedCard( colors = getCardColors( if (systemStatus.ksuVersion != null)MaterialTheme.colorScheme.secondaryContainer else MaterialTheme.colorScheme.errorContainer), - elevation = CardDefaults.cardElevation(defaultElevation = cardElevation), + elevation = getCardElevation(), ) { Row( modifier = Modifier @@ -510,7 +517,7 @@ fun WarningCard( ) { ElevatedCard( colors = getCardColors(color), - elevation = CardDefaults.cardElevation(defaultElevation = cardElevation), + elevation = getCardElevation(), ) { Row( modifier = Modifier @@ -534,7 +541,7 @@ fun ContributionCard() { ElevatedCard( colors = getCardColors(MaterialTheme.colorScheme.surfaceContainer), - elevation = CardDefaults.cardElevation(defaultElevation = cardElevation), + elevation = getCardElevation(), ) { Row( modifier = Modifier @@ -602,7 +609,7 @@ fun DonateCard() { ElevatedCard( colors = getCardColors(MaterialTheme.colorScheme.surfaceContainer), - elevation = CardDefaults.cardElevation(defaultElevation = cardElevation), + elevation = getCardElevation(), ) { Row( modifier = Modifier @@ -641,7 +648,7 @@ private fun InfoCard( ) { ElevatedCard( colors = getCardColors(MaterialTheme.colorScheme.surfaceContainer), - elevation = CardDefaults.cardElevation(defaultElevation = cardElevation), + elevation = getCardElevation(), ) { Column( modifier = Modifier diff --git a/manager/app/src/main/java/com/sukisu/ultra/ui/screen/Install.kt b/manager/app/src/main/java/com/sukisu/ultra/ui/screen/Install.kt index 3590a4a8..1cfa57e7 100644 --- a/manager/app/src/main/java/com/sukisu/ultra/ui/screen/Install.kt +++ b/manager/app/src/main/java/com/sukisu/ultra/ui/screen/Install.kt @@ -33,7 +33,6 @@ import androidx.compose.material.icons.filled.FileUpload import androidx.compose.material3.AlertDialog import androidx.compose.material3.Button import androidx.compose.material3.ButtonDefaults -import androidx.compose.material3.CardDefaults import androidx.compose.material3.ElevatedCard import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon @@ -92,6 +91,8 @@ import com.sukisu.ultra.ui.util.isAbDevice import com.sukisu.ultra.ui.util.isInitBoot import com.sukisu.ultra.ui.util.rootAvailable import com.sukisu.ultra.getKernelVersion +import com.sukisu.ultra.ui.theme.CardConfig +import com.sukisu.ultra.ui.theme.getCardElevation /** * @author ShirkNeko @@ -253,7 +254,7 @@ fun InstallScreen(navigator: DestinationsNavigator) { (lkmSelection as? LkmSelection.LkmUri)?.let { ElevatedCard( colors = getCardColors(MaterialTheme.colorScheme.surfaceVariant), - elevation = CardDefaults.cardElevation(defaultElevation = cardElevation), + elevation = getCardElevation(), modifier = Modifier .fillMaxWidth() .padding(bottom = 12.dp) @@ -279,7 +280,7 @@ fun InstallScreen(navigator: DestinationsNavigator) { if (method.slot != null) { ElevatedCard( colors = getCardColors(MaterialTheme.colorScheme.surfaceVariant), - elevation = CardDefaults.cardElevation(defaultElevation = cardElevation), + elevation = getCardElevation(), modifier = Modifier .fillMaxWidth() .padding(bottom = 12.dp) @@ -478,7 +479,7 @@ private fun SelectInstallMethod( if (isGKI) { ElevatedCard( colors = getCardColors(MaterialTheme.colorScheme.surfaceVariant), - elevation = CardDefaults.cardElevation(defaultElevation = cardElevation), + elevation = getCardElevation(), modifier = Modifier .fillMaxWidth() .padding(bottom = 12.dp) @@ -489,24 +490,30 @@ private fun SelectInstallMethod( spotColor = MaterialTheme.colorScheme.primary.copy(alpha = 0.1f) ) ) { - ListItem( - leadingContent = { - Icon( - Icons.Filled.AutoFixHigh, - contentDescription = null, - tint = MaterialTheme.colorScheme.primary - ) - }, - headlineContent = { - Text( - stringResource(R.string.Lkm_install_methods), - style = MaterialTheme.typography.titleMedium - ) - }, - modifier = Modifier.clickable { - LKMExpanded = !LKMExpanded - } - ) + MaterialTheme( + colorScheme = MaterialTheme.colorScheme.copy( + surface = MaterialTheme.colorScheme.surfaceVariant + ) + ) { + ListItem( + leadingContent = { + Icon( + Icons.Filled.AutoFixHigh, + contentDescription = null, + tint = MaterialTheme.colorScheme.primary + ) + }, + headlineContent = { + Text( + stringResource(R.string.Lkm_install_methods), + style = MaterialTheme.typography.titleMedium + ) + }, + modifier = Modifier.clickable { + LKMExpanded = !LKMExpanded + } + ) + } AnimatedVisibility( visible = LKMExpanded, @@ -584,7 +591,7 @@ private fun SelectInstallMethod( if (rootAvailable) { ElevatedCard( colors = getCardColors(MaterialTheme.colorScheme.surfaceVariant), - elevation = CardDefaults.cardElevation(defaultElevation = cardElevation), + elevation = getCardElevation(), modifier = Modifier .fillMaxWidth() .padding(bottom = 12.dp) @@ -595,24 +602,30 @@ private fun SelectInstallMethod( spotColor = MaterialTheme.colorScheme.primary.copy(alpha = 0.1f) ) ) { - ListItem( - leadingContent = { - Icon( - Icons.Filled.FileUpload, - contentDescription = null, - tint = MaterialTheme.colorScheme.primary - ) - }, - headlineContent = { - Text( - stringResource(R.string.GKI_install_methods), - style = MaterialTheme.typography.titleMedium - ) - }, - modifier = Modifier.clickable { - GKIExpanded = !GKIExpanded - } - ) + MaterialTheme( + colorScheme = MaterialTheme.colorScheme.copy( + surface = MaterialTheme.colorScheme.surfaceVariant + ) + ) { + ListItem( + leadingContent = { + Icon( + Icons.Filled.FileUpload, + contentDescription = null, + tint = MaterialTheme.colorScheme.primary + ) + }, + headlineContent = { + Text( + stringResource(R.string.GKI_install_methods), + style = MaterialTheme.typography.titleMedium + ) + }, + modifier = Modifier.clickable { + GKIExpanded = !GKIExpanded + } + ) + } AnimatedVisibility( visible = GKIExpanded, @@ -732,7 +745,12 @@ private fun TopBar( onLkmUpload: () -> Unit = {}, scrollBehavior: TopAppBarScrollBehavior? = null ) { - val cardColor = MaterialTheme.colorScheme.surfaceContainerLow + val colorScheme = MaterialTheme.colorScheme + val cardColor = if (CardConfig.isCustomBackgroundEnabled) { + colorScheme.surfaceContainerLow + } else { + colorScheme.background + } val cardAlpha = cardAlpha TopAppBar( diff --git a/manager/app/src/main/java/com/sukisu/ultra/ui/screen/KernelFlash.kt b/manager/app/src/main/java/com/sukisu/ultra/ui/screen/KernelFlash.kt index 5d6701cb..512289a6 100644 --- a/manager/app/src/main/java/com/sukisu/ultra/ui/screen/KernelFlash.kt +++ b/manager/app/src/main/java/com/sukisu/ultra/ui/screen/KernelFlash.kt @@ -366,7 +366,12 @@ private fun TopBar( else -> MaterialTheme.colorScheme.primary } - val cardColor = MaterialTheme.colorScheme.surfaceContainerLow + val colorScheme = MaterialTheme.colorScheme + val cardColor = if (CardConfig.isCustomBackgroundEnabled) { + colorScheme.surfaceContainerLow + } else { + colorScheme.background + } val cardAlpha = CardConfig.cardAlpha TopAppBar( diff --git a/manager/app/src/main/java/com/sukisu/ultra/ui/screen/Kpm.kt b/manager/app/src/main/java/com/sukisu/ultra/ui/screen/Kpm.kt index a4cd1d13..6d51d8ed 100644 --- a/manager/app/src/main/java/com/sukisu/ultra/ui/screen/Kpm.kt +++ b/manager/app/src/main/java/com/sukisu/ultra/ui/screen/Kpm.kt @@ -617,7 +617,7 @@ private fun KpmModuleItem( Card( colors = getCardColors(MaterialTheme.colorScheme.surfaceContainerHigh), - elevation = CardDefaults.cardElevation(defaultElevation = cardElevation) + elevation = getCardElevation() ) { Column( modifier = Modifier.padding(20.dp) diff --git a/manager/app/src/main/java/com/sukisu/ultra/ui/screen/Module.kt b/manager/app/src/main/java/com/sukisu/ultra/ui/screen/Module.kt index 3be18169..4341d563 100644 --- a/manager/app/src/main/java/com/sukisu/ultra/ui/screen/Module.kt +++ b/manager/app/src/main/java/com/sukisu/ultra/ui/screen/Module.kt @@ -72,6 +72,7 @@ import com.dergoogler.mmrl.platform.Platform import androidx.core.net.toUri import com.dergoogler.mmrl.platform.model.ModuleConfig import com.dergoogler.mmrl.platform.model.ModuleConfig.Companion.asModuleConfig +import com.sukisu.ultra.ui.theme.getCardElevation /** * @author ShirkNeko @@ -711,7 +712,7 @@ fun ModuleItem( ) { ElevatedCard( colors = getCardColors(MaterialTheme.colorScheme.surfaceContainerHigh), - elevation = CardDefaults.cardElevation(defaultElevation = cardElevation), + elevation = getCardElevation(), ) { val textDecoration = if (!module.remove) null else TextDecoration.LineThrough val interactionSource = remember { MutableInteractionSource() } diff --git a/manager/app/src/main/java/com/sukisu/ultra/ui/screen/MoreSettings.kt b/manager/app/src/main/java/com/sukisu/ultra/ui/screen/MoreSettings.kt index 62c3de16..68e70ece 100644 --- a/manager/app/src/main/java/com/sukisu/ultra/ui/screen/MoreSettings.kt +++ b/manager/app/src/main/java/com/sukisu/ultra/ui/screen/MoreSettings.kt @@ -11,31 +11,42 @@ import android.widget.Toast import androidx.activity.compose.rememberLauncherForActivityResult import androidx.activity.result.contract.ActivityResultContracts import androidx.compose.animation.AnimatedVisibility +import androidx.compose.animation.core.animateFloatAsState import androidx.compose.animation.expandVertically import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeOut import androidx.compose.animation.shrinkVertically +import androidx.compose.animation.slideInVertically +import androidx.compose.animation.slideOutVertically import androidx.compose.foundation.background +import androidx.compose.foundation.border import androidx.compose.foundation.clickable import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.WindowInsets +import androidx.compose.foundation.layout.WindowInsetsSides +import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.only import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.safeDrawing import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.shape.CircleShape +import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.verticalScroll import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.filled.ArrowBack import androidx.compose.material.icons.automirrored.filled.NavigateNext import androidx.compose.material.icons.filled.* import androidx.compose.material3.AlertDialog +import androidx.compose.material3.Card import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.* +import androidx.compose.material3.HorizontalDivider import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue @@ -49,14 +60,16 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.input.nestedscroll.nestedScroll import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import androidx.core.content.edit import com.ramcosta.composedestinations.annotation.Destination import com.ramcosta.composedestinations.annotation.RootGraph -import com.ramcosta.composedestinations.navigation.DestinationsNavigator import com.sukisu.ultra.Natives import com.sukisu.ultra.R import com.sukisu.ultra.ui.MainActivity @@ -68,6 +81,7 @@ import com.sukisu.ultra.ui.theme.CardConfig.cardElevation import com.sukisu.ultra.ui.theme.ThemeColors import com.sukisu.ultra.ui.theme.ThemeConfig import com.sukisu.ultra.ui.theme.getCardColors +import com.sukisu.ultra.ui.theme.getCardElevation import com.sukisu.ultra.ui.theme.saveAndApplyCustomBackground import com.sukisu.ultra.ui.theme.saveCustomBackground import com.sukisu.ultra.ui.theme.saveDynamicColorState @@ -96,7 +110,7 @@ fun saveCardConfig(context: Context) { @OptIn(ExperimentalMaterial3Api::class) @Destination @Composable -fun MoreSettingsScreen(navigator: DestinationsNavigator) { +fun MoreSettingsScreen() { val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(rememberTopAppBarState()) val context = LocalContext.current val coroutineScope = rememberCoroutineScope() @@ -393,7 +407,7 @@ fun MoreSettingsScreen(navigator: DestinationsNavigator) { // 如果启用了系统跟随且系统是深色模式,应用深色模式默认值 if (themeMode == 0 && systemIsDark) { - CardConfig.setDarkModeDefaults() + CardConfig.setThemeDefaults(true) } currentDpi = prefs.getInt("app_dpi", systemDpi) @@ -476,557 +490,518 @@ fun MoreSettingsScreen(navigator: DestinationsNavigator) { } ) } - - val cardColor = MaterialTheme.colorScheme.surfaceContainerHigh val isDarkTheme = isSystemInDarkTheme() Scaffold( modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection), topBar = { - TopAppBar( - title = { Text(stringResource(R.string.more_settings)) }, - colors = TopAppBarDefaults.topAppBarColors( - containerColor = cardColor.copy(alpha = cardAlpha), - scrolledContainerColor = cardColor.copy(alpha = cardAlpha)), - navigationIcon = { - IconButton(onClick = { navigator.popBackStack() }) { - Icon(Icons.AutoMirrored.Filled.ArrowBack, - contentDescription = stringResource(R.string.back)) - } - }, - scrollBehavior = scrollBehavior, - ) - } + TopBar(scrollBehavior = scrollBehavior) + }, + contentWindowInsets = WindowInsets.safeDrawing.only(WindowInsetsSides.Top + WindowInsetsSides.Horizontal) ) { paddingValues -> Column( modifier = Modifier + .fillMaxSize() .padding(paddingValues) .verticalScroll(rememberScrollState()) - .padding(horizontal = 16.dp, vertical = 8.dp) + .padding(horizontal = 16.dp) + .padding(top = 8.dp) ) { // 外观设置部分 - Card( - modifier = Modifier - .fillMaxWidth() - .padding(bottom = 16.dp), - colors = getCardColors(MaterialTheme.colorScheme.surfaceContainerHigh), - elevation = CardDefaults.cardElevation(defaultElevation = cardElevation) + SettingsCard( + title = stringResource(R.string.appearance_settings), + icon = Icons.Default.Palette + ) { + // 语言设置 + SettingItem( + icon = Icons.Default.Language, + title = stringResource(R.string.language_setting), + subtitle = supportedLanguages.find { it.first == currentLanguage }?.second + ?: stringResource(R.string.language_follow_system), + onClick = { showLanguageDialog = true } + ) + + // 主题模式 + SettingItem( + icon = Icons.Default.DarkMode, + title = stringResource(R.string.theme_mode), + subtitle = themeOptions[themeMode], + onClick = { showThemeModeDialog = true } + ) + + // 动态颜色开关 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { + SwitchItem( + icon = Icons.Filled.ColorLens, + title = stringResource(R.string.dynamic_color_title), + summary = stringResource(R.string.dynamic_color_summary), + checked = useDynamicColor + ) { enabled -> + useDynamicColor = enabled + context.saveDynamicColorState(enabled) + } + } + + // 只在未启用动态颜色时显示主题色选择 + AnimatedVisibility( + visible = Build.VERSION.SDK_INT < Build.VERSION_CODES.S || !useDynamicColor, + enter = fadeIn() + expandVertically(), + exit = fadeOut() + shrinkVertically() ) { - Column(modifier = Modifier.padding(vertical = 8.dp)) { - Text( - text = stringResource(R.string.appearance_settings), - style = MaterialTheme.typography.titleMedium, - modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp) - ) - // 语言设置 - ListItem( - headlineContent = { Text(stringResource(R.string.language_setting)) }, - supportingContent = { - Text(supportedLanguages.find { it.first == currentLanguage }?.second - ?: stringResource(R.string.language_follow_system)) - }, - leadingContent = { - Icon( - Icons.Default.Language, - contentDescription = null, - tint = MaterialTheme.colorScheme.primary - ) - }, - trailingContent = { - Icon( - Icons.AutoMirrored.Filled.NavigateNext, - contentDescription = null, - tint = MaterialTheme.colorScheme.onSurfaceVariant - ) - }, - modifier = Modifier.clickable { showLanguageDialog = true } - ) - - // 主题模式 - ListItem( - headlineContent = { Text(stringResource(R.string.theme_mode)) }, - supportingContent = { Text(themeOptions[themeMode]) }, - leadingContent = { - Icon( - Icons.Default.DarkMode, - contentDescription = null, - tint = MaterialTheme.colorScheme.primary - ) - }, - trailingContent = { - Icon( - Icons.AutoMirrored.Filled.NavigateNext, - contentDescription = null, - tint = MaterialTheme.colorScheme.onSurfaceVariant - ) - }, - modifier = Modifier.clickable { showThemeModeDialog = true } - ) - - // 动态颜色开关 - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { - SwitchItem( - icon = Icons.Filled.ColorLens, - title = stringResource(R.string.dynamic_color_title), - summary = stringResource(R.string.dynamic_color_summary), - checked = useDynamicColor - ) { enabled -> - useDynamicColor = enabled - context.saveDynamicColorState(enabled) - } - } - - // 只在未启用动态颜色时显示主题色选择 - AnimatedVisibility( - visible = Build.VERSION.SDK_INT < Build.VERSION_CODES.S || !useDynamicColor, - enter = fadeIn() + expandVertically(), - exit = fadeOut() + shrinkVertically() - ) { - Column { - ListItem( - headlineContent = { Text(stringResource(R.string.theme_color)) }, - supportingContent = { - val currentThemeName = when (ThemeConfig.currentTheme) { - is ThemeColors.Green -> stringResource(R.string.color_green) - is ThemeColors.Purple -> stringResource(R.string.color_purple) - is ThemeColors.Orange -> stringResource(R.string.color_orange) - is ThemeColors.Pink -> stringResource(R.string.color_pink) - is ThemeColors.Gray -> stringResource(R.string.color_gray) - is ThemeColors.Yellow -> stringResource(R.string.color_yellow) - else -> stringResource(R.string.color_default) - } - Text(currentThemeName) - }, - leadingContent = { - Icon( - Icons.Default.Palette, - contentDescription = null, - tint = MaterialTheme.colorScheme.primary - ) - }, - trailingContent = { - Icon( - Icons.AutoMirrored.Filled.NavigateNext, - contentDescription = null, - tint = MaterialTheme.colorScheme.onSurfaceVariant - ) - }, - modifier = Modifier.clickable { showThemeColorDialog = true } - ) - } - } - - // DPI 设置 - ListItem( - headlineContent = { Text(stringResource(R.string.app_dpi_title)) }, - supportingContent = { Text(stringResource(R.string.app_dpi_summary)) }, - leadingContent = { - Icon( - Icons.Default.AcUnit, - contentDescription = null, - tint = MaterialTheme.colorScheme.primary - ) - }, - trailingContent = { - Text( - text = getDpiFriendlyName(tempDpi), - style = MaterialTheme.typography.bodyMedium, - ) - } - ) - - // DPI 滑动条 - Column(modifier = Modifier.padding(horizontal = 32.dp, vertical = 8.dp)) { - Slider( - value = tempDpi.toFloat(), - onValueChange = { - tempDpi = it.toInt() - isDpiCustom = !dpiPresets.containsValue(tempDpi) - }, - valueRange = 160f..600f, - steps = 11, - colors = SliderDefaults.colors( - thumbColor = MaterialTheme.colorScheme.primary, - activeTrackColor = MaterialTheme.colorScheme.primary, - inactiveTrackColor = MaterialTheme.colorScheme.surfaceVariant - ) - ) - - Row( - modifier = Modifier - .fillMaxWidth() - .padding(top = 8.dp), - ) { - dpiPresets.forEach { (name, dpi) -> - TextButton( - onClick = { - tempDpi = dpi - isDpiCustom = false - }, - modifier = Modifier.weight(1f) - ) { - Text( - text = name, - color = if (tempDpi == dpi) - MaterialTheme.colorScheme.primary - else - MaterialTheme.colorScheme.onSurfaceVariant - ) - } + SettingItem( + icon = Icons.Default.Palette, + title = stringResource(R.string.theme_color), + subtitle = when (ThemeConfig.currentTheme) { + is ThemeColors.Green -> stringResource(R.string.color_green) + is ThemeColors.Purple -> stringResource(R.string.color_purple) + is ThemeColors.Orange -> stringResource(R.string.color_orange) + is ThemeColors.Pink -> stringResource(R.string.color_pink) + is ThemeColors.Gray -> stringResource(R.string.color_gray) + is ThemeColors.Yellow -> stringResource(R.string.color_yellow) + else -> stringResource(R.string.color_default) + }, + onClick = { showThemeColorDialog = true }, + trailingContent = { + Row { + themeColorOptions.take(4).forEach { (_, theme) -> + ColorCircle( + color = if (isDarkTheme) theme.primaryDark else theme.primaryLight, + isSelected = ThemeConfig.currentTheme::class == theme::class, + modifier = Modifier.padding(horizontal = 2.dp) + ) } } + } + ) + } - TextButton( - onClick = { - if (tempDpi != currentDpi) { - showDpiConfirmDialog = true - } - }, + HorizontalDivider( + modifier = Modifier.padding(vertical = 8.dp) + ) + + // DPI 设置 + SettingItem( + icon = Icons.Default.FormatSize, + title = stringResource(R.string.app_dpi_title), + subtitle = stringResource(R.string.app_dpi_summary), + onClick = {}, + trailingContent = { + Text( + text = getDpiFriendlyName(tempDpi), + style = MaterialTheme.typography.bodyMedium, + color = MaterialTheme.colorScheme.primary + ) + } + ) + + // DPI 滑动条 + Column(modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp)) { + val sliderValue by animateFloatAsState( + targetValue = tempDpi.toFloat(), + label = "DPI Slider Animation" + ) + + Slider( + value = sliderValue, + onValueChange = { + tempDpi = it.toInt() + isDpiCustom = !dpiPresets.containsValue(tempDpi) + }, + valueRange = 160f..600f, + steps = 11, + colors = SliderDefaults.colors( + thumbColor = MaterialTheme.colorScheme.primary, + activeTrackColor = MaterialTheme.colorScheme.primary, + inactiveTrackColor = MaterialTheme.colorScheme.surfaceVariant + ) + ) + + Row( + modifier = Modifier + .fillMaxWidth() + .padding(top = 8.dp), + ) { + dpiPresets.forEach { (name, dpi) -> + val isSelected = tempDpi == dpi + val buttonColor = if (isSelected) + MaterialTheme.colorScheme.primaryContainer + else + MaterialTheme.colorScheme.surfaceVariant + + Box( modifier = Modifier - .fillMaxWidth() - .padding(top = 8.dp) + .weight(1f) + .padding(horizontal = 2.dp) + .clip(RoundedCornerShape(8.dp)) + .background(buttonColor) + .clickable { + tempDpi = dpi + isDpiCustom = false + } + .padding(vertical = 8.dp, horizontal = 4.dp), + contentAlignment = Alignment.Center ) { - Text(stringResource(R.string.dpi_apply_settings)) + Text( + text = name, + style = MaterialTheme.typography.labelMedium, + color = if (isSelected) + MaterialTheme.colorScheme.onPrimaryContainer + else + MaterialTheme.colorScheme.onSurfaceVariant, + maxLines = 1, + overflow = TextOverflow.Ellipsis + ) + } + } + } + + Text( + text = if (isDpiCustom) + "${stringResource(R.string.dpi_size_custom)}: $tempDpi" + else + "${getDpiFriendlyName(tempDpi)}: $tempDpi", + style = MaterialTheme.typography.bodySmall, + modifier = Modifier.padding(top = 8.dp) + ) + + Button( + onClick = { + if (tempDpi != currentDpi) { + showDpiConfirmDialog = true + } + }, + modifier = Modifier + .fillMaxWidth() + .padding(top = 8.dp), + enabled = tempDpi != currentDpi + ) { + Icon( + Icons.Default.Check, + contentDescription = null, + modifier = Modifier.size(16.dp) + ) + Spacer(modifier = Modifier.width(8.dp)) + Text(stringResource(R.string.dpi_apply_settings)) + } + } + + HorizontalDivider( + modifier = Modifier.padding(vertical = 8.dp), + ) + + // 自定义背景开关 + SwitchItem( + icon = Icons.Filled.Wallpaper, + title = stringResource(id = R.string.settings_custom_background), + summary = stringResource(id = R.string.settings_custom_background_summary), + checked = isCustomBackgroundEnabled + ) { isChecked -> + if (isChecked) { + pickImageLauncher.launch("image/*") + } else { + context.saveCustomBackground(null) + isCustomBackgroundEnabled = false + CardConfig.cardAlpha = 1f + CardConfig.cardDim = 0f + CardConfig.isCustomAlphaSet = false + CardConfig.isCustomDimSet = false + CardConfig.isCustomBackgroundEnabled = false + saveCardConfig(context) + + // 重置其他相关设置 + ThemeConfig.needsResetOnThemeChange = true + ThemeConfig.preventBackgroundRefresh = false + + context.getSharedPreferences("theme_prefs", Context.MODE_PRIVATE) + .edit { + putBoolean( + "prevent_background_refresh", + false + ) } + Toast.makeText( + context, + context.getString(R.string.background_removed), + Toast.LENGTH_SHORT + ).show() + } + } + + // 透明度和亮度调节滑动条 + AnimatedVisibility( + visible = ThemeConfig.customBackgroundUri != null, + enter = fadeIn() + slideInVertically(), + exit = fadeOut() + slideOutVertically() + ) { + Column(modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp)) { + // 透明度滑动条 + Row( + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier.padding(bottom = 4.dp) + ) { + Icon( + Icons.Filled.Opacity, + contentDescription = null, + modifier = Modifier.size(20.dp), + tint = MaterialTheme.colorScheme.primary + ) + Spacer(modifier = Modifier.width(8.dp)) Text( - text = if (isDpiCustom) - "${stringResource(R.string.dpi_size_custom)}: $tempDpi" - else - "${getDpiFriendlyName(tempDpi)}: $tempDpi", - style = MaterialTheme.typography.bodySmall, - modifier = Modifier.padding(top = 4.dp) + text = stringResource(R.string.settings_card_alpha), + style = MaterialTheme.typography.titleSmall + ) + Spacer(modifier = Modifier.weight(1f)) + Text( + text = "${(cardAlpha * 100).roundToInt()}%", + style = MaterialTheme.typography.labelMedium, ) } - // 自定义背景开关 - SwitchItem( - icon = Icons.Filled.Wallpaper, - title = stringResource(id = R.string.settings_custom_background), - summary = stringResource(id = R.string.settings_custom_background_summary), - checked = isCustomBackgroundEnabled - ) { isChecked -> - if (isChecked) { - pickImageLauncher.launch("image/*") + val alphaSliderValue by animateFloatAsState( + targetValue = cardAlpha, + label = "Alpha Slider Animation" + ) + + Slider( + value = alphaSliderValue, + onValueChange = { newValue -> + cardAlpha = newValue + CardConfig.cardAlpha = newValue + CardConfig.isCustomAlphaSet = true + prefs.edit { + putBoolean("is_custom_alpha_set", true) + putFloat("card_alpha", newValue) + } + }, + onValueChangeFinished = { + coroutineScope.launch(Dispatchers.IO) { + saveCardConfig(context) + } + }, + valueRange = 0f..1f, + steps = 20, + colors = SliderDefaults.colors( + thumbColor = MaterialTheme.colorScheme.primary, + activeTrackColor = MaterialTheme.colorScheme.primary, + inactiveTrackColor = MaterialTheme.colorScheme.surfaceVariant + ) + ) + + // 亮度调节滑动条 + Row( + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier.padding(top = 16.dp, bottom = 4.dp) + ) { + Icon( + Icons.Filled.LightMode, + contentDescription = null, + modifier = Modifier.size(20.dp), + tint = MaterialTheme.colorScheme.primary + ) + Spacer(modifier = Modifier.width(8.dp)) + Text( + text = stringResource(R.string.settings_card_dim), + style = MaterialTheme.typography.titleSmall + ) + Spacer(modifier = Modifier.weight(1f)) + Text( + text = "${(cardDim * 100).roundToInt()}%", + style = MaterialTheme.typography.labelMedium, + ) + } + + val dimSliderValue by animateFloatAsState( + targetValue = cardDim, + label = "Dim Slider Animation" + ) + + Slider( + value = dimSliderValue, + onValueChange = { newValue -> + cardDim = newValue + CardConfig.cardDim = newValue + CardConfig.isCustomDimSet = true + prefs.edit { + putBoolean("is_custom_dim_set", true) + putFloat("card_dim", newValue) + } + }, + onValueChangeFinished = { + coroutineScope.launch(Dispatchers.IO) { + saveCardConfig(context) + } + }, + valueRange = 0f..1f, + steps = 20, + colors = SliderDefaults.colors( + thumbColor = MaterialTheme.colorScheme.primary, + activeTrackColor = MaterialTheme.colorScheme.primary, + inactiveTrackColor = MaterialTheme.colorScheme.surfaceVariant + ) + ) + } + } + } + + // 自定义设置部分 + SettingsCard( + title = stringResource(R.string.custom_settings), + icon = Icons.Default.Settings + ) { + // 添加简洁模式开关 + SwitchItem( + icon = Icons.Filled.Brush, + title = stringResource(R.string.simple_mode), + summary = stringResource(R.string.simple_mode_summary), + checked = isSimpleMode + ) { + onSimpleModeChange(it) + } + + // 隐藏内核部分版本号 + SwitchItem( + icon = Icons.Filled.VisibilityOff, + title = stringResource(R.string.hide_kernel_kernelsu_version), + summary = stringResource(R.string.hide_kernel_kernelsu_version_summary), + checked = isHideVersion + ) { + onHideVersionChange(it) + } + + // 模块数量等信息 + SwitchItem( + icon = Icons.Filled.VisibilityOff, + title = stringResource(R.string.hide_other_info), + summary = stringResource(R.string.hide_other_info_summary), + checked = isHideOtherInfo + ) { + onHideOtherInfoChange(it) + } + + // SuSFS 状态信息 + SwitchItem( + icon = Icons.Filled.VisibilityOff, + title = stringResource(R.string.hide_susfs_status), + summary = stringResource(R.string.hide_susfs_status_summary), + checked = isHideSusfsStatus + ) { + onHideSusfsStatusChange(it) + } + + if (Natives.version >= Natives.MINIMAL_SUPPORTED_KPM) { + // 显示KPM开关 + SwitchItem( + icon = Icons.Filled.Visibility, + title = stringResource(R.string.show_kpm_info), + summary = stringResource(R.string.show_kpm_info_summary), + checked = isShowKpmInfo + ) { + onShowKpmInfoChange(it) + } + } + + // 隐藏链接信息 + SwitchItem( + icon = Icons.Filled.VisibilityOff, + title = stringResource(R.string.hide_link_card), + summary = stringResource(R.string.hide_link_card_summary), + checked = isHideLinkCard + ) { + onHideLinkCardChange(it) + } + } + + // 高级设置部分 + SettingsCard( + title = stringResource(R.string.advanced_settings), + icon = Icons.Default.AdminPanelSettings + ) { + // SELinux 开关 + KsuIsValid { + SwitchItem( + icon = Icons.Filled.Security, + title = stringResource(R.string.selinux), + summary = if (selinuxEnabled) + stringResource(R.string.selinux_enabled) else + stringResource(R.string.selinux_disabled), + checked = selinuxEnabled + ) { enabled -> + val command = if (enabled) "setenforce 1" else "setenforce 0" + Shell.getShell().newJob().add(command).exec().let { result -> + if (result.isSuccess) { + selinuxEnabled = enabled + // 显示成功提示 + val message = if (enabled) + context.getString(R.string.selinux_enabled_toast) + else + context.getString(R.string.selinux_disabled_toast) + + Toast.makeText(context, message, Toast.LENGTH_SHORT).show() } else { - context.saveCustomBackground(null) - isCustomBackgroundEnabled = false - cardElevation - CardConfig.cardAlpha = 1f - CardConfig.cardDim = 0f - CardConfig.isCustomAlphaSet = false - CardConfig.isCustomDimSet = false - CardConfig.isCustomBackgroundEnabled = false - saveCardConfig(context) - cardAlpha = 1f - cardDim = 0f - - // 重置其他相关设置 - ThemeConfig.needsResetOnThemeChange = true - ThemeConfig.preventBackgroundRefresh = false - - context.getSharedPreferences("theme_prefs", Context.MODE_PRIVATE) - .edit { - putBoolean( - "prevent_background_refresh", - false - ) - } - + // 显示失败提示 Toast.makeText( context, - context.getString(R.string.background_removed), + context.getString(R.string.selinux_change_failed), Toast.LENGTH_SHORT ).show() } } - - // 透明度和亮度调节滑动条 - AnimatedVisibility( - visible = ThemeConfig.customBackgroundUri != null, - enter = fadeIn() + expandVertically(), - exit = fadeOut() + shrinkVertically(), - modifier = Modifier.padding(horizontal = 32.dp) - ) { - Column(modifier = Modifier.padding(vertical = 8.dp)) { - // 透明度滑动条 - Row( - verticalAlignment = Alignment.CenterVertically, - modifier = Modifier.padding(bottom = 4.dp) - ) { - Icon( - Icons.Filled.Opacity, - contentDescription = null, - modifier = Modifier.size(20.dp), - tint = MaterialTheme.colorScheme.primary - ) - Spacer(modifier = Modifier.width(8.dp)) - Text( - text = stringResource(R.string.settings_card_alpha), - style = MaterialTheme.typography.titleSmall - ) - Spacer(modifier = Modifier.weight(1f)) - Text( - text = "${(cardAlpha * 100).roundToInt()}%", - style = MaterialTheme.typography.labelMedium, - ) - } - - Slider( - value = cardAlpha, - onValueChange = { newValue -> - cardAlpha = newValue - CardConfig.cardAlpha = newValue - CardConfig.isCustomAlphaSet = true - prefs.edit { - putBoolean("is_custom_alpha_set", true) - putFloat("card_alpha", newValue) - } - }, - onValueChangeFinished = { - coroutineScope.launch(Dispatchers.IO) { - saveCardConfig(context) - } - }, - valueRange = 0f..1f, - steps = 20, - colors = SliderDefaults.colors( - thumbColor = MaterialTheme.colorScheme.primary, - activeTrackColor = MaterialTheme.colorScheme.primary, - inactiveTrackColor = MaterialTheme.colorScheme.surfaceVariant - ) - ) - - // 亮度调节滑动条 - Row( - verticalAlignment = Alignment.CenterVertically, - modifier = Modifier.padding(top = 16.dp, bottom = 4.dp) - ) { - Icon( - Icons.Filled.LightMode, - contentDescription = null, - modifier = Modifier.size(20.dp), - tint = MaterialTheme.colorScheme.primary - ) - Spacer(modifier = Modifier.width(8.dp)) - Text( - text = stringResource(R.string.settings_card_dim), - style = MaterialTheme.typography.titleSmall - ) - Spacer(modifier = Modifier.weight(1f)) - Text( - text = "${(cardDim * 100).roundToInt()}%", - style = MaterialTheme.typography.labelMedium, - ) - } - - Slider( - value = cardDim, - onValueChange = { newValue -> - cardDim = newValue - CardConfig.cardDim = newValue - CardConfig.isCustomDimSet = true - prefs.edit { - putBoolean("is_custom_dim_set", true) - putFloat("card_dim", newValue) - } - }, - onValueChangeFinished = { - coroutineScope.launch(Dispatchers.IO) { - saveCardConfig(context) - } - }, - valueRange = 0f..1f, - steps = 20, - colors = SliderDefaults.colors( - thumbColor = MaterialTheme.colorScheme.primary, - activeTrackColor = MaterialTheme.colorScheme.primary, - inactiveTrackColor = MaterialTheme.colorScheme.surfaceVariant - ) - ) - } - } } } - // 自定义设置部分 - Card( - modifier = Modifier - .fillMaxWidth() - .padding(bottom = 16.dp), - colors = getCardColors(MaterialTheme.colorScheme.surfaceContainerHigh), - elevation = CardDefaults.cardElevation(defaultElevation = cardElevation) - ) { - Column(Modifier.padding(vertical = 8.dp)) { - Text( - text = stringResource(R.string.custom_settings), - style = MaterialTheme.typography.titleMedium, - modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp) - ) - // 添加简洁模式开关 - SwitchItem( - icon = Icons.Filled.Brush, - title = stringResource(R.string.simple_mode), - summary = stringResource(R.string.simple_mode_summary), - checked = isSimpleMode - ) { - onSimpleModeChange(it) - } - - // 隐藏内核部分版本号 - SwitchItem( - icon = Icons.Filled.VisibilityOff, - title = stringResource(R.string.hide_kernel_kernelsu_version), - summary = stringResource(R.string.hide_kernel_kernelsu_version_summary), - checked = isHideVersion - ) { - onHideVersionChange(it) - } - - // 模块数量等信息 - SwitchItem( - icon = Icons.Filled.VisibilityOff, - title = stringResource(R.string.hide_other_info), - summary = stringResource(R.string.hide_other_info_summary), - checked = isHideOtherInfo - ) { - onHideOtherInfoChange(it) - } - - // SuSFS 状态信息 - SwitchItem( - icon = Icons.Filled.VisibilityOff, - title = stringResource(R.string.hide_susfs_status), - summary = stringResource(R.string.hide_susfs_status_summary), - checked = isHideSusfsStatus - ) { - onHideSusfsStatusChange(it) - } - - if (Natives.version >= Natives.MINIMAL_SUPPORTED_KPM) { - // 显示KPM开关 - SwitchItem( - icon = Icons.Filled.Visibility, - title = stringResource(R.string.show_kpm_info), - summary = stringResource(R.string.show_kpm_info_summary), - checked = isShowKpmInfo - ) { - onShowKpmInfoChange(it) - } - } - - // 隐藏链接信息 - SwitchItem( - icon = Icons.Filled.VisibilityOff, - title = stringResource(R.string.hide_link_card), - summary = stringResource(R.string.hide_link_card_summary), - checked = isHideLinkCard - ) { - onHideLinkCardChange(it) - } + // SuSFS 配置(仅在支持时显示) + val suSFS = getSuSFS() + val isSUS_SU = getSuSFSFeatures() + if (suSFS == "Supported" && isSUS_SU == "CONFIG_KSU_SUSFS_SUS_SU") { + // 默认启用 + var isEnabled by rememberSaveable { + mutableStateOf(true) } - } - // 高级设置部分 - Card( - modifier = Modifier - .fillMaxWidth() - .padding(bottom = 16.dp), - colors = getCardColors(MaterialTheme.colorScheme.surfaceContainerHigh), - elevation = CardDefaults.cardElevation(defaultElevation = cardElevation) - ) { - Column( Modifier.padding(vertical = 8.dp)) { - Text( - text = stringResource(R.string.advanced_settings), - style = MaterialTheme.typography.titleMedium, - modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp) - ) - // SELinux 开关 - KsuIsValid { - SwitchItem( - icon = Icons.Filled.Security, - title = stringResource(R.string.selinux), - summary = if (selinuxEnabled) - stringResource(R.string.selinux_enabled) else - stringResource(R.string.selinux_disabled), - checked = selinuxEnabled - ) { enabled -> - val command = if (enabled) "setenforce 1" else "setenforce 0" - Shell.getShell().newJob().add(command).exec().let { result -> - if (result.isSuccess) { - selinuxEnabled = enabled - // 显示成功提示 - val message = if (enabled) - context.getString(R.string.selinux_enabled_toast) - else - context.getString(R.string.selinux_disabled_toast) - - Toast.makeText(context, message, Toast.LENGTH_SHORT).show() - } else { - // 显示失败提示 - Toast.makeText( - context, - context.getString(R.string.selinux_change_failed), - Toast.LENGTH_SHORT - ).show() - } - } - } + // 在启动时检查状态 + LaunchedEffect(Unit) { + // 如果当前模式不是2就强制启用 + val currentMode = susfsSUS_SU_Mode() + val wasManuallyDisabled = prefs.getBoolean("enable_sus_su", true) + if (currentMode != "2" && wasManuallyDisabled) { + susfsSUS_SU_2() // 强制切换到模式2 + prefs.edit { putBoolean("enable_sus_su", true) } } + isEnabled = currentMode == "2" + } - // SuSFS 配置(仅在支持时显示) - val suSFS = getSuSFS() - val isSUS_SU = getSuSFSFeatures() - if (suSFS == "Supported" && isSUS_SU == "CONFIG_KSU_SUSFS_SUS_SU") { - // 默认启用 - var isEnabled by rememberSaveable { - mutableStateOf(true) - } - - // 在启动时检查状态 - LaunchedEffect(Unit) { - // 如果当前模式不是2就强制启用 - val currentMode = susfsSUS_SU_Mode() - val wasManuallyDisabled = prefs.getBoolean("enable_sus_su", true) - if (currentMode != "2" && wasManuallyDisabled) { - susfsSUS_SU_2() // 强制切换到模式2 - prefs.edit { putBoolean("enable_sus_su", true) } - } - isEnabled = currentMode == "2" - } - - SwitchItem( - icon = Icons.Filled.Security, - title = stringResource(id = R.string.settings_susfs_toggle), - summary = stringResource(id = R.string.settings_susfs_toggle_summary), - checked = isEnabled - ) { - if (it) { - // 手动启用 - susfsSUS_SU_2() - prefs.edit { putBoolean("enable_sus_su", true) } - Toast.makeText( - context, - context.getString(R.string.susfs_enabled), - Toast.LENGTH_SHORT - ).show() - } else { - // 手动关闭 - susfsSUS_SU_0() - prefs.edit { putBoolean("enable_sus_su", false) } - Toast.makeText( - context, - context.getString(R.string.susfs_disabled), - Toast.LENGTH_SHORT - ).show() - } - isEnabled = it - } + SwitchItem( + icon = Icons.Filled.Security, + title = stringResource(id = R.string.settings_susfs_toggle), + summary = stringResource(id = R.string.settings_susfs_toggle_summary), + checked = isEnabled + ) { + if (it) { + // 手动启用 + susfsSUS_SU_2() + prefs.edit { putBoolean("enable_sus_su", true) } + Toast.makeText( + context, + context.getString(R.string.susfs_enabled), + Toast.LENGTH_SHORT + ).show() + } else { + // 手动关闭 + susfsSUS_SU_0() + prefs.edit { putBoolean("enable_sus_su", false) } + Toast.makeText( + context, + context.getString(R.string.susfs_disabled), + Toast.LENGTH_SHORT + ).show() } + isEnabled = it } } } } + } // 主题模式选择对话框 if (showThemeModeDialog) { @@ -1053,36 +1028,21 @@ fun MoreSettingsScreen(navigator: DestinationsNavigator) { ThemeConfig.forceDarkMode = true CardConfig.isUserDarkModeEnabled = true CardConfig.isUserLightModeEnabled = false - if (!CardConfig.isCustomAlphaSet) { - CardConfig.cardAlpha = 1f - } - if (!CardConfig.isCustomDimSet) { - CardConfig.cardDim = 0.5f - } + CardConfig.setThemeDefaults(true) CardConfig.save(context) } 1 -> { // 浅色 ThemeConfig.forceDarkMode = false CardConfig.isUserLightModeEnabled = true CardConfig.isUserDarkModeEnabled = false - if (!CardConfig.isCustomAlphaSet) { - CardConfig.cardAlpha = 1f - } - if (!CardConfig.isCustomDimSet) { - CardConfig.cardDim = 0f - } + CardConfig.setThemeDefaults(false) CardConfig.save(context) } 0 -> { // 跟随系统 ThemeConfig.forceDarkMode = null CardConfig.isUserLightModeEnabled = false CardConfig.isUserDarkModeEnabled = false - if (!CardConfig.isCustomAlphaSet) { - CardConfig.cardAlpha = 1f - } - if (!CardConfig.isCustomDimSet) { - CardConfig.cardDim = if (isDarkTheme) 0.5f else 0f - } + CardConfig.setThemeDefaults(isDarkTheme) CardConfig.save(context) } } @@ -1199,4 +1159,144 @@ fun MoreSettingsScreen(navigator: DestinationsNavigator) { } ) } +} + +@Composable +fun SettingsCard( + title: String, + icon: ImageVector, + content: @Composable () -> Unit +) { + Card( + modifier = Modifier + .fillMaxWidth() + .padding(bottom = 16.dp), + colors = getCardColors(MaterialTheme.colorScheme.surfaceContainerHigh), + elevation = getCardElevation(), + shape = MaterialTheme.shapes.medium + ) { + Column(modifier = Modifier.padding(vertical = 8.dp)) { + Row( + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier.padding(horizontal = 16.dp, vertical = 12.dp) + ) { + Icon( + imageVector = icon, + contentDescription = null, + tint = MaterialTheme.colorScheme.primary, + modifier = Modifier.size(24.dp) + ) + Spacer(modifier = Modifier.width(12.dp)) + Text( + text = title, + style = MaterialTheme.typography.titleLarge, + ) + } + content() + } + } +} + +@Composable +fun SettingItem( + icon: ImageVector, + title: String, + subtitle: String? = null, + onClick: () -> Unit, + iconTint: Color = MaterialTheme.colorScheme.primary, + trailingContent: @Composable (() -> Unit)? = { + Icon( + Icons.AutoMirrored.Filled.NavigateNext, + contentDescription = null, + tint = MaterialTheme.colorScheme.onSurfaceVariant + ) + } +) { + Row( + modifier = Modifier + .fillMaxWidth() + .clickable(onClick = onClick) + .padding(horizontal = 16.dp, vertical = 12.dp), + verticalAlignment = Alignment.CenterVertically + ) { + Icon( + imageVector = icon, + contentDescription = null, + tint = iconTint, + modifier = Modifier + .padding(end = 16.dp) + .size(24.dp) + ) + + Column( + modifier = Modifier.weight(1f) + ) { + Text( + text = title, + style = MaterialTheme.typography.titleMedium, + ) + if (subtitle != null) { + Text( + text = subtitle, + style = MaterialTheme.typography.bodyMedium, + color = MaterialTheme.colorScheme.onSurfaceVariant + ) + } + } + + trailingContent?.invoke() + } +} + + +@Composable +fun ColorCircle( + color: Color, + isSelected: Boolean, + modifier: Modifier = Modifier +) { + Box( + modifier = modifier + .size(20.dp) + .clip(CircleShape) + .background(color) + .then( + if (isSelected) { + Modifier.border( + width = 2.dp, + color = MaterialTheme.colorScheme.primary, + shape = CircleShape + ) + } else { + Modifier + } + ) + ) +} + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +private fun TopBar( + scrollBehavior: TopAppBarScrollBehavior? = null +) { + val colorScheme = MaterialTheme.colorScheme + val cardColor = if (CardConfig.isCustomBackgroundEnabled) { + colorScheme.surfaceContainerLow + } else { + colorScheme.background + } + TopAppBar( + title = { + Text( + text = stringResource(R.string.more_settings), + style = MaterialTheme.typography.titleLarge + ) + }, + colors = TopAppBarDefaults.topAppBarColors( + containerColor = cardColor.copy(alpha = CardConfig.cardAlpha), + scrolledContainerColor = cardColor.copy(alpha = CardConfig.cardAlpha) + ), + windowInsets = WindowInsets.safeDrawing.only(WindowInsetsSides.Top + WindowInsetsSides.Horizontal), + scrollBehavior = scrollBehavior + ) } \ No newline at end of file diff --git a/manager/app/src/main/java/com/sukisu/ultra/ui/screen/Settings.kt b/manager/app/src/main/java/com/sukisu/ultra/ui/screen/Settings.kt index e8901850..93df089c 100644 --- a/manager/app/src/main/java/com/sukisu/ultra/ui/screen/Settings.kt +++ b/manager/app/src/main/java/com/sukisu/ultra/ui/screen/Settings.kt @@ -63,7 +63,6 @@ import com.sukisu.ultra.ui.util.getBugreportFile import java.time.LocalDateTime import java.time.format.DateTimeFormatter import com.sukisu.ultra.ui.component.KsuIsValid -import com.sukisu.ultra.ui.theme.CardConfig.cardElevation /** * @author ShirkNeko @@ -127,7 +126,7 @@ fun SettingScreen(navigator: DestinationsNavigator) { .fillMaxWidth() .padding(horizontal = 16.dp, vertical = 8.dp), colors = getCardColors(MaterialTheme.colorScheme.surfaceContainerHigh), - elevation = CardDefaults.cardElevation(defaultElevation = cardElevation) + elevation = getCardElevation() ) { Column(modifier = Modifier.padding(vertical = 8.dp)) { Text( @@ -195,7 +194,7 @@ fun SettingScreen(navigator: DestinationsNavigator) { .fillMaxWidth() .padding(horizontal = 16.dp, vertical = 8.dp), colors = getCardColors(MaterialTheme.colorScheme.surfaceContainerHigh), - elevation = CardDefaults.cardElevation(defaultElevation = cardElevation) + elevation = getCardElevation() ) { Column(modifier = Modifier.padding(vertical = 8.dp)) { Text( @@ -340,7 +339,7 @@ fun SettingScreen(navigator: DestinationsNavigator) { .fillMaxWidth() .padding(horizontal = 16.dp, vertical = 8.dp), colors = getCardColors(MaterialTheme.colorScheme.surfaceContainerHigh), - elevation = CardDefaults.cardElevation(defaultElevation = cardElevation) + elevation = getCardElevation() ) { Column(modifier = Modifier.padding(vertical = 8.dp)) { Text( @@ -436,7 +435,7 @@ fun SettingScreen(navigator: DestinationsNavigator) { .fillMaxWidth() .padding(horizontal = 16.dp, vertical = 8.dp), colors = getCardColors(MaterialTheme.colorScheme.surfaceContainerHigh), - elevation = CardDefaults.cardElevation(defaultElevation = cardElevation) + elevation = getCardElevation() ) { Column(modifier = Modifier.padding(vertical = 8.dp)) { Text( @@ -740,14 +739,12 @@ fun rememberUninstallDialog(onSelected: (UninstallType) -> Unit): DialogHandle { private fun TopBar( scrollBehavior: TopAppBarScrollBehavior? = null ) { - val systemIsDark = isSystemInDarkTheme() - val cardColor = MaterialTheme.colorScheme.surfaceContainerLow - val cardAlpha = if (ThemeConfig.customBackgroundUri != null) { - cardAlpha + val colorScheme = MaterialTheme.colorScheme + val cardColor = if (CardConfig.isCustomBackgroundEnabled) { + colorScheme.surfaceContainerLow } else { - if (systemIsDark) 0.8f else 1f + colorScheme.background } - TopAppBar( title = { Text( diff --git a/manager/app/src/main/java/com/sukisu/ultra/ui/screen/Template.kt b/manager/app/src/main/java/com/sukisu/ultra/ui/screen/Template.kt index 54ee0541..535e7d33 100644 --- a/manager/app/src/main/java/com/sukisu/ultra/ui/screen/Template.kt +++ b/manager/app/src/main/java/com/sukisu/ultra/ui/screen/Template.kt @@ -231,7 +231,12 @@ private fun TopBar( colors: TopAppBarColors, scrollBehavior: TopAppBarScrollBehavior? = null ) { - val cardColor = MaterialTheme.colorScheme.surfaceContainerLow + val colorScheme = MaterialTheme.colorScheme + val cardColor = if (CardConfig.isCustomBackgroundEnabled) { + colorScheme.surfaceContainerLow + } else { + colorScheme.background + } val cardAlpha = CardConfig.cardAlpha TopAppBar( diff --git a/manager/app/src/main/java/com/sukisu/ultra/ui/theme/CardManage.kt b/manager/app/src/main/java/com/sukisu/ultra/ui/theme/CardManage.kt index 798c16b1..18d8761c 100644 --- a/manager/app/src/main/java/com/sukisu/ultra/ui/theme/CardManage.kt +++ b/manager/app/src/main/java/com/sukisu/ultra/ui/theme/CardManage.kt @@ -10,19 +10,15 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.luminance -import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp object CardConfig { - val settingElevation: Dp = 4.dp - val customBackgroundElevation: Dp = 0.dp - // 卡片透明度 var cardAlpha by mutableFloatStateOf(1f) // 卡片亮度 var cardDim by mutableFloatStateOf(0f) // 卡片阴影 - var cardElevation by mutableStateOf(settingElevation) + var cardElevation by mutableStateOf(4.dp) var isShadowEnabled by mutableStateOf(true) var isCustomAlphaSet by mutableStateOf(false) var isCustomDimSet by mutableStateOf(false) @@ -69,37 +65,24 @@ object CardConfig { */ fun updateShadowEnabled(enabled: Boolean) { isShadowEnabled = enabled - cardElevation = if (isCustomBackgroundEnabled && cardAlpha != 1f) { - customBackgroundElevation + cardElevation = if (isCustomBackgroundEnabled) { + 0.dp } else if (enabled) { - settingElevation + 4.dp } else { - customBackgroundElevation + 0.dp } } /** - * 设置深色模式默认值 + * 设置主题模式默认值 */ - fun setDarkModeDefaults() { + fun setThemeDefaults(isDarkMode: Boolean) { if (!isCustomAlphaSet) { cardAlpha = 1f } if (!isCustomDimSet) { - cardDim = 0.5f - } - updateShadowEnabled(isShadowEnabled) - } - - /** - * 设置浅色模式默认值 - */ - fun setLightModeDefaults() { - if (!isCustomAlphaSet) { - cardAlpha = 1f - } - if (!isCustomDimSet) { - cardDim = 0f + cardDim = if (isDarkMode) 0.5f else 0f } updateShadowEnabled(isShadowEnabled) } @@ -114,6 +97,19 @@ fun getCardColors(originalColor: Color) = CardDefaults.cardColors( contentColor = determineContentColor(originalColor) ) +/** + * 获取卡片阴影配置 + */ +@Composable +fun getCardElevation() = CardDefaults.cardElevation( + defaultElevation = CardConfig.cardElevation, + pressedElevation = if (CardConfig.isCustomBackgroundEnabled) 0.dp else 8.dp, + focusedElevation = if (CardConfig.isCustomBackgroundEnabled) 0.dp else 6.dp, + hoveredElevation = if (CardConfig.isCustomBackgroundEnabled) 0.dp else 4.dp, + draggedElevation = if (CardConfig.isCustomBackgroundEnabled) 0.dp else 8.dp, + disabledElevation = 0.dp +) + /** * 根据背景颜色、主题模式和用户设置确定内容颜色 */ diff --git a/manager/app/src/main/java/com/sukisu/ultra/ui/theme/Theme.kt b/manager/app/src/main/java/com/sukisu/ultra/ui/theme/Theme.kt index 7ecd3d6a..1989a150 100644 --- a/manager/app/src/main/java/com/sukisu/ultra/ui/theme/Theme.kt +++ b/manager/app/src/main/java/com/sukisu/ultra/ui/theme/Theme.kt @@ -47,6 +47,7 @@ import com.sukisu.ultra.ui.util.saveTransformedBackground import androidx.activity.SystemBarStyle import androidx.activity.ComponentActivity import androidx.activity.enableEdgeToEdge +import androidx.compose.material3.ColorScheme import androidx.compose.runtime.SideEffect import androidx.compose.ui.graphics.toArgb @@ -150,9 +151,9 @@ fun KernelSUTheme( // 根据暗色模式和自定义背景调整卡片配置 val isDarkModeWithCustomBackground = darkTheme && ThemeConfig.customBackgroundUri != null if (darkTheme && !dynamicColor) { - CardConfig.setDarkModeDefaults() + CardConfig.setThemeDefaults(true) } else if (!darkTheme && !dynamicColor) { - CardConfig.setLightModeDefaults() + CardConfig.setThemeDefaults(false) } CardConfig.updateShadowEnabled(!isDarkModeWithCustomBackground) @@ -216,7 +217,8 @@ fun KernelSUTheme( modifier = Modifier .fillMaxSize() .zIndex(-2f) - .background(if (darkTheme) MaterialTheme.colorScheme.surfaceContainerLow else MaterialTheme.colorScheme.surfaceContainerLow) + .background(if (darkTheme) if (CardConfig.isCustomBackgroundEnabled) { colorScheme.surfaceContainerLow } else { colorScheme.background } + else if (CardConfig.isCustomBackgroundEnabled) { colorScheme.surfaceContainerLow } else { colorScheme.background }) ) // 自定义背景层 @@ -287,22 +289,30 @@ fun KernelSUTheme( */ @RequiresApi(Build.VERSION_CODES.S) @Composable -private fun createDynamicDarkColorScheme(context: Context) = - dynamicDarkColorScheme(context).copy( - background = Color.Transparent, - surface = Color.Transparent +private fun createDynamicDarkColorScheme(context: Context): ColorScheme { + val scheme = dynamicDarkColorScheme(context) + return scheme.copy( + background = if (CardConfig.isCustomBackgroundEnabled) Color.Transparent else scheme.background, + surface = if (CardConfig.isCustomBackgroundEnabled) Color.Transparent else scheme.surface, + onBackground = Color.White, + onSurface = Color.White ) +} /** * 创建动态浅色颜色方案 */ @RequiresApi(Build.VERSION_CODES.S) @Composable -private fun createDynamicLightColorScheme(context: Context) = - dynamicLightColorScheme(context).copy( - background = Color.Transparent, - surface = Color.Transparent +private fun createDynamicLightColorScheme(context: Context): ColorScheme { + val scheme = dynamicLightColorScheme(context) + return scheme.copy( + background = if (CardConfig.isCustomBackgroundEnabled) Color.Transparent else scheme.background, + surface = if (CardConfig.isCustomBackgroundEnabled) Color.Transparent else scheme.surface ) +} + + /** * 创建深色颜色方案 @@ -325,9 +335,9 @@ private fun createDarkColorScheme() = darkColorScheme( onError = ThemeConfig.currentTheme.onErrorDark, errorContainer = ThemeConfig.currentTheme.errorContainerDark, onErrorContainer = ThemeConfig.currentTheme.onErrorContainerDark, - background = Color.Transparent, + background = if (CardConfig.isCustomBackgroundEnabled) Color.Transparent else ThemeConfig.currentTheme.backgroundDark, onBackground = ThemeConfig.currentTheme.onBackgroundDark, - surface = Color.Transparent, + surface = if (CardConfig.isCustomBackgroundEnabled) Color.Transparent else ThemeConfig.currentTheme.surfaceDark, onSurface = ThemeConfig.currentTheme.onSurfaceDark, surfaceVariant = ThemeConfig.currentTheme.surfaceVariantDark, onSurfaceVariant = ThemeConfig.currentTheme.onSurfaceVariantDark, @@ -367,9 +377,9 @@ private fun createLightColorScheme() = lightColorScheme( onError = ThemeConfig.currentTheme.onErrorLight, errorContainer = ThemeConfig.currentTheme.errorContainerLight, onErrorContainer = ThemeConfig.currentTheme.onErrorContainerLight, - background = Color.Transparent, + background = if (CardConfig.isCustomBackgroundEnabled) Color.Transparent else ThemeConfig.currentTheme.backgroundLight, onBackground = ThemeConfig.currentTheme.onBackgroundLight, - surface = Color.Transparent, + surface = if (CardConfig.isCustomBackgroundEnabled) Color.Transparent else ThemeConfig.currentTheme.surfaceLight, onSurface = ThemeConfig.currentTheme.onSurfaceLight, surfaceVariant = ThemeConfig.currentTheme.surfaceVariantLight, onSurfaceVariant = ThemeConfig.currentTheme.onSurfaceVariantLight, @@ -388,6 +398,7 @@ private fun createLightColorScheme() = lightColorScheme( surfaceContainerHighest = ThemeConfig.currentTheme.surfaceContainerHighestLight, ) + /** * 复制图片到应用内部存储并提升持久性 */