From 6405764df372ff4819185d324b683e93f56c9368 Mon Sep 17 00:00:00 2001 From: ShirkNeko <109797057+ShirkNeko@users.noreply.github.com> Date: Fri, 30 May 2025 20:00:33 +0800 Subject: [PATCH] Adjust settings and optimize theme styles --- .../sukisu/ultra/ui/component/SettingsItem.kt | 19 +- .../sukisu/ultra/ui/screen/MoreSettings.kt | 2 +- .../com/sukisu/ultra/ui/screen/Settings.kt | 22 +- .../com/sukisu/ultra/ui/webui/WebUITheme.kt | 273 ------------------ .../sukisu/ultra/ui/webui/WebUIXActivity.kt | 5 +- .../sukisu/ultra/ui/webui/WebViewInterface.kt | 42 +-- 6 files changed, 18 insertions(+), 345 deletions(-) delete mode 100644 manager/app/src/main/java/com/sukisu/ultra/ui/webui/WebUITheme.kt 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 index 59bcc68d..020c143e 100644 --- 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 @@ -1,18 +1,19 @@ package com.sukisu.ultra.ui.component import androidx.compose.foundation.LocalIndication +import androidx.compose.foundation.background 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.RadioButton 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.Color import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.semantics.Role import com.dergoogler.mmrl.ui.component.LabelItem @@ -85,20 +86,4 @@ fun SwitchItem( } } ) -} - -@Composable -fun RadioItem( - title: String, - selected: Boolean, - onClick: () -> Unit, -) { - ListItem( - headlineContent = { - Text(title) - }, - leadingContent = { - RadioButton(selected = selected, onClick = onClick) - } - ) } \ No newline at end of file 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 3a80ff9f..495cf690 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 @@ -479,7 +479,7 @@ fun MoreSettingsScreen(navigator: DestinationsNavigator) { ) } - val cardColor = MaterialTheme.colorScheme.surfaceContainerLow + val cardColor = MaterialTheme.colorScheme.surfaceContainerHigh val cardAlphaUse = CardConfig.cardAlpha val isDarkTheme = isSystemInDarkTheme() 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 5e127024..f7a95802 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 @@ -59,13 +59,14 @@ import com.sukisu.ultra.* import com.sukisu.ultra.ui.component.* import com.sukisu.ultra.ui.theme.* import com.sukisu.ultra.ui.theme.CardConfig.cardAlpha -import com.sukisu.ultra.ui.theme.CardConfig.cardElevation import com.sukisu.ultra.ui.util.LocalSnackbarHost 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.dergoogler.mmrl.platform.Platform +import com.dergoogler.mmrl.ui.component.LabelItem +import com.dergoogler.mmrl.ui.component.text.TextRow @OptIn(ExperimentalMaterial3Api::class) @@ -119,9 +120,9 @@ fun SettingScreen(navigator: DestinationsNavigator) { .fillMaxWidth() .padding(horizontal = 16.dp, vertical = 8.dp), colors = CardDefaults.cardColors( - containerColor = MaterialTheme.colorScheme.surfaceContainerLow.copy(alpha = cardAlpha) + containerColor = MaterialTheme.colorScheme.surfaceContainerHigh.copy(alpha = cardAlpha) ), - elevation = CardDefaults.cardElevation(defaultElevation = cardElevation) + elevation = CardDefaults.cardElevation(defaultElevation = 0.dp) ) { Column(modifier = Modifier.padding(vertical = 8.dp)) { Text( @@ -192,9 +193,9 @@ fun SettingScreen(navigator: DestinationsNavigator) { .fillMaxWidth() .padding(horizontal = 16.dp, vertical = 8.dp), colors = CardDefaults.cardColors( - containerColor = MaterialTheme.colorScheme.surfaceContainerLow.copy(alpha = cardAlpha) + containerColor = MaterialTheme.colorScheme.surfaceContainerHigh.copy(alpha = cardAlpha) ), - elevation = CardDefaults.cardElevation(defaultElevation = cardElevation) + elevation = CardDefaults.cardElevation(defaultElevation = 0.dp) ) { Column(modifier = Modifier.padding(vertical = 8.dp)) { Text( @@ -306,9 +307,9 @@ fun SettingScreen(navigator: DestinationsNavigator) { .fillMaxWidth() .padding(horizontal = 16.dp, vertical = 8.dp), colors = CardDefaults.cardColors( - containerColor = MaterialTheme.colorScheme.surfaceContainerLow.copy(alpha = cardAlpha) + containerColor = MaterialTheme.colorScheme.surfaceContainerHigh.copy(alpha = cardAlpha) ), - elevation = CardDefaults.cardElevation(defaultElevation = cardElevation) + elevation = CardDefaults.cardElevation(defaultElevation = 0.dp) ) { Column(modifier = Modifier.padding(vertical = 8.dp)) { Text( @@ -399,15 +400,15 @@ fun SettingScreen(navigator: DestinationsNavigator) { } } - // 设置分组卡片 - 关于 + // 关于 Card( modifier = Modifier .fillMaxWidth() .padding(horizontal = 16.dp, vertical = 8.dp), colors = CardDefaults.cardColors( - containerColor = MaterialTheme.colorScheme.surfaceContainerLow.copy(alpha = cardAlpha) + containerColor = MaterialTheme.colorScheme.surfaceContainerHigh.copy(alpha = cardAlpha) ), - elevation = CardDefaults.cardElevation(defaultElevation = cardElevation) + elevation = CardDefaults.cardElevation(defaultElevation = 0.dp) ) { Column(modifier = Modifier.padding(vertical = 8.dp)) { Text( @@ -504,7 +505,6 @@ fun SettingItem( ) } } - Icon( imageVector = Icons.Filled.ChevronRight, contentDescription = null, diff --git a/manager/app/src/main/java/com/sukisu/ultra/ui/webui/WebUITheme.kt b/manager/app/src/main/java/com/sukisu/ultra/ui/webui/WebUITheme.kt deleted file mode 100644 index 48718bc4..00000000 --- a/manager/app/src/main/java/com/sukisu/ultra/ui/webui/WebUITheme.kt +++ /dev/null @@ -1,273 +0,0 @@ -package com.sukisu.ultra.ui.webui - -import androidx.activity.ComponentActivity -import androidx.activity.SystemBarStyle -import androidx.activity.enableEdgeToEdge -import androidx.compose.foundation.background -import androidx.compose.foundation.isSystemInDarkTheme -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.darkColorScheme -import androidx.compose.material3.dynamicDarkColorScheme -import androidx.compose.material3.dynamicLightColorScheme -import androidx.compose.material3.lightColorScheme -import androidx.compose.runtime.Composable -import androidx.compose.runtime.CompositionLocalProvider -import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.SideEffect -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.runtime.staticCompositionLocalOf -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.alpha -import androidx.compose.ui.draw.paint -import androidx.compose.ui.graphics.Brush -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.toArgb -import androidx.compose.ui.layout.ContentScale -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.zIndex -import android.os.Build -import androidx.compose.animation.core.animateFloat -import androidx.compose.animation.core.spring -import androidx.compose.animation.core.updateTransition -import androidx.compose.ui.graphics.graphicsLayer -import coil.compose.AsyncImagePainter -import coil.compose.rememberAsyncImagePainter -import com.sukisu.ultra.ui.theme.ThemeConfig -import com.sukisu.ultra.ui.theme.Typography -import com.sukisu.ultra.ui.theme.loadCustomBackground - -// 提供界面类型的本地组合 -val LocalIsSecondaryScreen = staticCompositionLocalOf { false } - -/** - * WebUI专用主题配置 - */ -@Composable -fun WebUIXTheme( - darkTheme: Boolean = isSystemInDarkTheme(), - dynamicColor: Boolean = true, - isSecondaryScreen: Boolean = false, - content: @Composable () -> Unit -) { - val context = LocalContext.current - - LaunchedEffect(Unit) { - if (!ThemeConfig.backgroundImageLoaded && !ThemeConfig.preventBackgroundRefresh) { - context.loadCustomBackground() - ThemeConfig.backgroundImageLoaded = false - } - } - - // 更新二级界面状态 - LaunchedEffect(isSecondaryScreen) { - WebViewInterface.updateSecondaryScreenState(isSecondaryScreen) - } - - val colorScheme = when { - dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> { - if (darkTheme) { - dynamicDarkColorScheme(context).let { scheme -> - if (isSecondaryScreen) { - scheme.copy( - background = scheme.surfaceContainerHighest, - surface = scheme.surfaceContainerHighest - ) - } else { - scheme.copy( - background = Color.Transparent, - surface = Color.Transparent - ) - } - } - } else { - dynamicLightColorScheme(context).let { scheme -> - if (isSecondaryScreen) { - scheme.copy( - background = scheme.surfaceContainerHighest, - surface = scheme.surfaceContainerHighest - ) - } else { - scheme.copy( - background = Color.Transparent, - surface = Color.Transparent - ) - } - } - } - } - darkTheme -> { - if (isSecondaryScreen) { - darkColorScheme().copy( - background = MaterialTheme.colorScheme.surfaceContainerHighest, - surface = MaterialTheme.colorScheme.surfaceContainerHighest - ) - } else { - darkColorScheme().copy( - background = Color.Transparent, - surface = Color.Transparent - ) - } - } - else -> { - if (isSecondaryScreen) { - lightColorScheme().copy( - background = MaterialTheme.colorScheme.surfaceContainerHighest, - surface = MaterialTheme.colorScheme.surfaceContainerHighest - ) - } else { - lightColorScheme().copy( - background = Color.Transparent, - surface = Color.Transparent - ) - } - } - } - - ConfigureSystemBars(darkTheme) - - val backgroundUri = remember { mutableStateOf(ThemeConfig.customBackgroundUri) } - - LaunchedEffect(ThemeConfig.customBackgroundUri) { - backgroundUri.value = ThemeConfig.customBackgroundUri - } - val bgImagePainter = backgroundUri.value?.let { - rememberAsyncImagePainter( - model = it, - onError = { - ThemeConfig.backgroundImageLoaded = false - }, - onSuccess = { - ThemeConfig.backgroundImageLoaded = true - ThemeConfig.isThemeChanging = false - } - ) - } - - // 背景透明度动画 - val transition = updateTransition( - targetState = ThemeConfig.backgroundImageLoaded, - label = "bgTransition" - ) - - val bgAlpha by transition.animateFloat( - label = "bgAlpha", - transitionSpec = { - spring( - dampingRatio = 0.8f, - stiffness = 300f - ) - } - ) { loaded -> if (loaded) 1f else 0f } - CompositionLocalProvider(LocalIsSecondaryScreen provides isSecondaryScreen) { - MaterialTheme( - colorScheme = colorScheme, - typography = Typography, - ) { - if (isSecondaryScreen) { - Box( - modifier = Modifier - .fillMaxSize() - .background(MaterialTheme.colorScheme.surfaceContainerHighest) - ) { - content() - } - } else { - Box(modifier = Modifier.fillMaxSize()) { - Box( - modifier = Modifier - .fillMaxSize() - .zIndex(-2f) - .background(if (darkTheme) Color.Black else Color.White) - ) - - backgroundUri.value?.let { uri -> - Box( - modifier = Modifier - .fillMaxSize() - .zIndex(-1f) - .alpha(bgAlpha) - ) { - bgImagePainter?.let { painter -> - Box( - modifier = Modifier - .fillMaxSize() - .paint( - painter = painter, - contentScale = ContentScale.Crop - ) - .graphicsLayer { - alpha = (painter.state as? AsyncImagePainter.State.Success)?.let { 1f } ?: 0f - } - ) - } - Box( - modifier = Modifier - .fillMaxSize() - .background( - if (darkTheme) Color.Black.copy(alpha = 0.6f) - else Color.White.copy(alpha = 0.1f) - ) - ) - Box( - modifier = Modifier - .fillMaxSize() - .background( - Brush.radialGradient( - colors = listOf( - Color.Transparent, - if (darkTheme) Color.Black.copy(alpha = 0.5f) - else Color.Black.copy(alpha = 0.2f) - ), - radius = 1200f - ) - ) - ) - } - } - Box( - modifier = Modifier - .fillMaxSize() - .zIndex(1f) - ) { - content() - } - } - } - } - } -} - -/** - * 配置WebUI的系统栏样式 - */ -@Composable -private fun ConfigureSystemBars( - darkMode: Boolean, - statusBarScrim: Color = Color.Transparent, - navigationBarScrim: Color = Color.Transparent -) { - val context = LocalContext.current - val activity = context as ComponentActivity - - SideEffect { - activity.enableEdgeToEdge( - statusBarStyle = SystemBarStyle.auto( - statusBarScrim.toArgb(), - statusBarScrim.toArgb() - ) { darkMode }, - navigationBarStyle = when { - darkMode -> SystemBarStyle.dark( - navigationBarScrim.toArgb() - ) - else -> SystemBarStyle.light( - navigationBarScrim.toArgb(), - navigationBarScrim.toArgb() - ) - } - ) - } -} \ No newline at end of file diff --git a/manager/app/src/main/java/com/sukisu/ultra/ui/webui/WebUIXActivity.kt b/manager/app/src/main/java/com/sukisu/ultra/ui/webui/WebUIXActivity.kt index a65fd79d..0a71575e 100644 --- a/manager/app/src/main/java/com/sukisu/ultra/ui/webui/WebUIXActivity.kt +++ b/manager/app/src/main/java/com/sukisu/ultra/ui/webui/WebUIXActivity.kt @@ -20,6 +20,7 @@ import com.dergoogler.mmrl.ui.component.Loading import com.dergoogler.mmrl.webui.screen.WebUIScreen import com.dergoogler.mmrl.webui.util.rememberWebUIOptions import com.sukisu.ultra.BuildConfig +import com.sukisu.ultra.ui.theme.KernelSUTheme import kotlinx.coroutines.delay import kotlinx.coroutines.launch @@ -68,7 +69,7 @@ class WebUIXActivity : ComponentActivity() { val prefs = getSharedPreferences("settings", MODE_PRIVATE) setContent { - WebUIXTheme { + KernelSUTheme { var isLoading by remember { mutableStateOf(true) } LaunchedEffect(Platform.isAlive) { @@ -81,7 +82,7 @@ class WebUIXActivity : ComponentActivity() { if (isLoading) { Loading() - return@WebUIXTheme + return@KernelSUTheme } val webDebugging = prefs.getBoolean("enable_web_debugging", false) diff --git a/manager/app/src/main/java/com/sukisu/ultra/ui/webui/WebViewInterface.kt b/manager/app/src/main/java/com/sukisu/ultra/ui/webui/WebViewInterface.kt index fef87f33..c4f9d4d7 100644 --- a/manager/app/src/main/java/com/sukisu/ultra/ui/webui/WebViewInterface.kt +++ b/manager/app/src/main/java/com/sukisu/ultra/ui/webui/WebViewInterface.kt @@ -7,9 +7,6 @@ import android.text.TextUtils import android.view.Window import android.webkit.JavascriptInterface import android.widget.Toast -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.setValue import androidx.core.view.WindowInsetsCompat import androidx.core.view.WindowInsetsControllerCompat import com.dergoogler.mmrl.webui.interfaces.WXInterface @@ -23,8 +20,7 @@ import com.sukisu.ultra.ui.util.listModules import com.sukisu.ultra.ui.util.withNewRootShell import org.json.JSONArray import org.json.JSONObject -import com.sukisu.ultra.ui.util.controlKpmModule -import com.sukisu.ultra.ui.util.listKpmModules +import com.sukisu.ultra.ui.util.* import java.io.File import java.util.concurrent.CompletableFuture @@ -34,47 +30,11 @@ class WebViewInterface( override var name: String = "ksu" companion object { - private var isSecondaryScreenState by mutableStateOf(false) - private var windowInsetsController: WindowInsetsControllerCompat? = null - fun factory() = JavaScriptInterface(WebViewInterface::class.java) - - fun updateSecondaryScreenState(isSecondary: Boolean) { - isSecondaryScreenState = isSecondary - - windowInsetsController?.let { controller -> - if (isSecondary) { - controller.show(WindowInsetsCompat.Type.systemBars()) - controller.systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_DEFAULT - } else { - controller.systemBarsBehavior = - WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE - } - } - } - - fun setWindowInsetsController(controller: WindowInsetsControllerCompat) { - windowInsetsController = controller - } } - init { - if (context is Activity) { - setWindowInsetsController(WindowInsetsControllerCompat( - activity.window, - activity.window.decorView - )) - } - } - - private val modDir get() = "/data/adb/modules/${modId.id}" - @JavascriptInterface - fun isSecondaryPage(): Boolean { - return isSecondaryScreenState - } - @JavascriptInterface fun exec(cmd: String): String { return withNewRootShell(true) { ShellUtils.fastCmd(this, cmd) }