[manager]: Add KPM function display options and related settings

- Eruda injection web UI X will not be displayed when the modification is not enabled.

Signed-off-by: ShirkNeko <109797057+ShirkNeko@users.noreply.github.com>
This commit is contained in:
ShirkNeko
2025-05-13 21:44:42 +08:00
parent 9e7ea19567
commit 01199470f2
7 changed files with 92 additions and 32 deletions

View File

@@ -1,5 +1,6 @@
package com.sukisu.ultra.ui package com.sukisu.ultra.ui
import android.content.Context
import android.database.ContentObserver import android.database.ContentObserver
import android.os.Build import android.os.Build
import android.os.Bundle import android.os.Bundle
@@ -13,6 +14,7 @@ import androidx.compose.foundation.layout.*
import androidx.compose.material3.* import androidx.compose.material3.*
import androidx.compose.runtime.* import androidx.compose.runtime.*
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.navigation.NavBackStackEntry import androidx.navigation.NavBackStackEntry
import androidx.navigation.NavHostController import androidx.navigation.NavHostController
@@ -167,6 +169,10 @@ private fun BottomBar(navController: NavHostController) {
val containerColor = MaterialTheme.colorScheme.surfaceVariant val containerColor = MaterialTheme.colorScheme.surfaceVariant
val cardColor = MaterialTheme.colorScheme.surfaceVariant val cardColor = MaterialTheme.colorScheme.surfaceVariant
// 检查是否显示KPM
val showKpmInfo = LocalContext.current.getSharedPreferences("settings", Context.MODE_PRIVATE)
.getBoolean("show_kpm_info", true)
NavigationBar( NavigationBar(
modifier = Modifier.windowInsetsPadding( modifier = Modifier.windowInsetsPadding(
WindowInsets.navigationBars.only(WindowInsetsSides.Horizontal) WindowInsets.navigationBars.only(WindowInsetsSides.Horizontal)
@@ -179,7 +185,7 @@ private fun BottomBar(navController: NavHostController) {
) { ) {
BottomBarDestination.entries.forEach { destination -> BottomBarDestination.entries.forEach { destination ->
if (destination == BottomBarDestination.Kpm) { if (destination == BottomBarDestination.Kpm) {
if (kpmVersion.isNotEmpty() && !kpmVersion.startsWith("Error")) { if (kpmVersion.isNotEmpty() && !kpmVersion.startsWith("Error") && showKpmInfo) {
if (!fullFeatured && destination.rootRequired) return@forEach if (!fullFeatured && destination.rootRequired) return@forEach
val isCurrentDestOnBackStack by navController.isRouteOnBackStackAsState(destination.direction) val isCurrentDestOnBackStack by navController.isRouteOnBackStackAsState(destination.direction)
NavigationBarItem( NavigationBarItem(

View File

@@ -133,6 +133,7 @@ fun HomeScreen(navigator: DestinationsNavigator) {
var isHideOtherInfo by rememberSaveable { mutableStateOf(false) } var isHideOtherInfo by rememberSaveable { mutableStateOf(false) }
var isHideSusfsStatus by rememberSaveable { mutableStateOf(false) } var isHideSusfsStatus by rememberSaveable { mutableStateOf(false) }
var isHideLinkCard by rememberSaveable { mutableStateOf(false) } var isHideLinkCard by rememberSaveable { mutableStateOf(false) }
var showKpmInfo by rememberSaveable { mutableStateOf(true) }
// 从 SharedPreferences 加载简洁模式状态 // 从 SharedPreferences 加载简洁模式状态
LaunchedEffect(Unit) { LaunchedEffect(Unit) {
@@ -150,6 +151,9 @@ fun HomeScreen(navigator: DestinationsNavigator) {
isHideLinkCard = context.getSharedPreferences("settings", Context.MODE_PRIVATE) isHideLinkCard = context.getSharedPreferences("settings", Context.MODE_PRIVATE)
.getBoolean("is_hide_link_card", false) .getBoolean("is_hide_link_card", false)
showKpmInfo = context.getSharedPreferences("settings", Context.MODE_PRIVATE)
.getBoolean("show_kpm_info", true)
} }
val kernelVersion = getKernelVersion() val kernelVersion = getKernelVersion()
@@ -487,6 +491,9 @@ private fun StatusCard(
val isHideSusfsStatus = LocalContext.current.getSharedPreferences("settings", Context.MODE_PRIVATE) val isHideSusfsStatus = LocalContext.current.getSharedPreferences("settings", Context.MODE_PRIVATE)
.getBoolean("is_hide_susfs_status", false) .getBoolean("is_hide_susfs_status", false)
val showKpmInfo = LocalContext.current.getSharedPreferences("settings", Context.MODE_PRIVATE)
.getBoolean("show_kpm_info", true)
Icon( Icon(
Icons.Outlined.CheckCircle, Icons.Outlined.CheckCircle,
contentDescription = stringResource(R.string.home_working), contentDescription = stringResource(R.string.home_working),
@@ -526,7 +533,7 @@ private fun StatusCard(
) )
val kpmVersion = getKpmVersion() val kpmVersion = getKpmVersion()
if (kpmVersion.isNotEmpty() && !kpmVersion.startsWith("Error")) { if (kpmVersion.isNotEmpty() && !kpmVersion.startsWith("Error") && showKpmInfo) {
Spacer(Modifier.height(4.dp)) Spacer(Modifier.height(4.dp))
Text( Text(
text = stringResource(R.string.home_kpm_module, getKpmModuleCount()), text = stringResource(R.string.home_kpm_module, getKpmModuleCount()),
@@ -790,6 +797,8 @@ private fun InfoCard() {
val context = LocalContext.current val context = LocalContext.current
val isSimpleMode = LocalContext.current.getSharedPreferences("settings", Context.MODE_PRIVATE) val isSimpleMode = LocalContext.current.getSharedPreferences("settings", Context.MODE_PRIVATE)
.getBoolean("is_simple_mode", false) .getBoolean("is_simple_mode", false)
val showKpmInfo = LocalContext.current.getSharedPreferences("settings", Context.MODE_PRIVATE)
.getBoolean("show_kpm_info", true)
ElevatedCard( ElevatedCard(
colors = getCardColors(MaterialTheme.colorScheme.surfaceContainerHighest), colors = getCardColors(MaterialTheme.colorScheme.surfaceContainerHighest),
@@ -891,6 +900,8 @@ private fun InfoCard() {
val kpmVersion = getKpmVersion() val kpmVersion = getKpmVersion()
val isKpmConfigured = checkKpmConfigured() val isKpmConfigured = checkKpmConfigured()
// 根据showKpmInfo决定是否显示KPM信息
if (showKpmInfo) {
val displayVersion = if (kpmVersion.isEmpty() || kpmVersion.startsWith("Error")) { val displayVersion = if (kpmVersion.isEmpty() || kpmVersion.startsWith("Error")) {
val statusText = if (isKpmConfigured) { val statusText = if (isKpmConfigured) {
stringResource(R.string.kernel_patched) stringResource(R.string.kernel_patched)
@@ -909,6 +920,7 @@ private fun InfoCard() {
) )
} }
} }
}
val isHideSusfsStatus = LocalContext.current.getSharedPreferences("settings", Context.MODE_PRIVATE) val isHideSusfsStatus = LocalContext.current.getSharedPreferences("settings", Context.MODE_PRIVATE)
.getBoolean("is_hide_susfs_status", false) .getBoolean("is_hide_susfs_status", false)

View File

@@ -176,6 +176,17 @@ fun MoreSettingsScreen(navigator: DestinationsNavigator) {
isHideOtherInfo = newValue isHideOtherInfo = newValue
} }
// 显示KPM开关状态
var isShowKpmInfo by remember {
mutableStateOf(prefs.getBoolean("show_kpm_info", true))
}
// 更新显示KPM开关状态
val onShowKpmInfoChange = { newValue: Boolean ->
prefs.edit { putBoolean("show_kpm_info", newValue) }
isShowKpmInfo = newValue
}
// 隐藏SuSFS状态开关状态 // 隐藏SuSFS状态开关状态
var isHideSusfsStatus by remember { var isHideSusfsStatus by remember {
mutableStateOf(prefs.getBoolean("is_hide_susfs_status", false)) mutableStateOf(prefs.getBoolean("is_hide_susfs_status", false))
@@ -642,6 +653,21 @@ fun MoreSettingsScreen(navigator: DestinationsNavigator) {
color = MaterialTheme.colorScheme.outlineVariant color = MaterialTheme.colorScheme.outlineVariant
) )
// 显示KPM开关
SwitchItem(
icon = Icons.Filled.VisibilityOff,
title = stringResource(R.string.show_kpm_info),
summary = stringResource(R.string.show_kpm_info_summary),
checked = isShowKpmInfo
) {
onShowKpmInfoChange(it)
}
HorizontalDivider(
modifier = Modifier.padding(horizontal = 16.dp),
color = MaterialTheme.colorScheme.outlineVariant
)
// 隐藏链接信息 // 隐藏链接信息
SwitchItem( SwitchItem(
icon = Icons.Filled.VisibilityOff, icon = Icons.Filled.VisibilityOff,

View File

@@ -6,6 +6,11 @@ import android.net.Uri
import android.widget.Toast import android.widget.Toast
import androidx.activity.compose.rememberLauncherForActivityResult import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.expandVertically
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.animation.shrinkVertically
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.foundation.isSystemInDarkTheme
@@ -81,7 +86,6 @@ fun SettingScreen(navigator: DestinationsNavigator) {
AboutDialog(it) AboutDialog(it)
} }
val loadingDialog = rememberLoadingDialog() val loadingDialog = rememberLoadingDialog()
// endregion
Column( Column(
modifier = Modifier modifier = Modifier
@@ -89,12 +93,8 @@ fun SettingScreen(navigator: DestinationsNavigator) {
.nestedScroll(scrollBehavior.nestedScrollConnection) .nestedScroll(scrollBehavior.nestedScrollConnection)
.verticalScroll(rememberScrollState()) .verticalScroll(rememberScrollState())
) { ) {
// region 上下文与协程
val context = LocalContext.current val context = LocalContext.current
val scope = rememberCoroutineScope() val scope = rememberCoroutineScope()
// endregion
// region 日志导出功能
val exportBugreportLauncher = rememberLauncherForActivityResult( val exportBugreportLauncher = rememberLauncherForActivityResult(
ActivityResultContracts.CreateDocument("application/gzip") ActivityResultContracts.CreateDocument("application/gzip")
) { uri: Uri? -> ) { uri: Uri? ->
@@ -184,7 +184,7 @@ fun SettingScreen(navigator: DestinationsNavigator) {
} }
} }
// 设置分组卡片 - 应用设置 // 应用设置
Card( Card(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
@@ -240,6 +240,7 @@ fun SettingScreen(navigator: DestinationsNavigator) {
) )
} }
// Web X 开关
var useWebUIX by rememberSaveable { var useWebUIX by rememberSaveable {
mutableStateOf( mutableStateOf(
prefs.getBoolean("use_webuix", false) prefs.getBoolean("use_webuix", false)
@@ -258,12 +259,19 @@ fun SettingScreen(navigator: DestinationsNavigator) {
useWebUIX = it useWebUIX = it
} }
} }
// Web X Eruda 开关
var useWebUIXEruda by rememberSaveable { var useWebUIXEruda by rememberSaveable {
mutableStateOf( mutableStateOf(
prefs.getBoolean("use_webuix_eruda", false) prefs.getBoolean("use_webuix_eruda", false)
) )
} }
KsuIsValid { KsuIsValid {
AnimatedVisibility(
visible = useWebUIX && enableWebDebugging,
enter = fadeIn() + expandVertically(),
exit = fadeOut() + shrinkVertically()
) {
SwitchItem( SwitchItem(
beta = true, beta = true,
enabled = Platform.isAlive && useWebUIX && enableWebDebugging, enabled = Platform.isAlive && useWebUIX && enableWebDebugging,
@@ -276,6 +284,7 @@ fun SettingScreen(navigator: DestinationsNavigator) {
useWebUIXEruda = it useWebUIXEruda = it
} }
} }
}
// 更多设置 // 更多设置
SettingItem( SettingItem(
@@ -289,7 +298,7 @@ fun SettingScreen(navigator: DestinationsNavigator) {
} }
} }
// 设置分组卡片 - 工具 // 工具
Card( Card(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()

View File

@@ -8,7 +8,6 @@ import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge import androidx.activity.enableEdgeToEdge
import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf

View File

@@ -320,6 +320,10 @@
<string name="background_set_success">背景设置成功</string> <string name="background_set_success">背景设置成功</string>
<string name="background_removed">已移除自定义背景</string> <string name="background_removed">已移除自定义背景</string>
<string name="root_require_for_install">需要 root 权限</string> <string name="root_require_for_install">需要 root 权限</string>
<!-- KPM 显示设置相关 -->
<string name="show_kpm_info">显示 KPM 功能</string>
<string name="show_kpm_info_summary">在主页和底栏显示 KPM 相关功能和信息 (需要重新打开应用</string>
<!-- Webui X 设置相关 -->
<string name="use_webuix">使用 WebUI X</string> <string name="use_webuix">使用 WebUI X</string>
<string name="use_webuix_summary">使用支持更多 API 的 WebUI X 而不是 WebUI</string> <string name="use_webuix_summary">使用支持更多 API 的 WebUI X 而不是 WebUI</string>
<string name="use_webuix_eruda">将 Eruda 注入 WebUI X</string> <string name="use_webuix_eruda">将 Eruda 注入 WebUI X</string>

View File

@@ -324,6 +324,10 @@
<string name="background_set_success">Background set successfully</string> <string name="background_set_success">Background set successfully</string>
<string name="background_removed">Removed custom backgrounds</string> <string name="background_removed">Removed custom backgrounds</string>
<string name="root_require_for_install">Requires root privileges</string> <string name="root_require_for_install">Requires root privileges</string>
<!-- KPM display settings -->
<string name="show_kpm_info">Display KPM Function</string>
<string name="show_kpm_info_summary">Display KPM information and Function in home and bottom bar (Need to reopen the app)</string>
<!-- Webui X settings -->
<string name="use_webuix">Use WebUI X</string> <string name="use_webuix">Use WebUI X</string>
<string name="use_webuix_summary">Use WebUI X instead of WebUI which supports more API\'s</string> <string name="use_webuix_summary">Use WebUI X instead of WebUI which supports more API\'s</string>
<string name="use_webuix_eruda">Inject Eruda into WebUI X</string> <string name="use_webuix_eruda">Inject Eruda into WebUI X</string>