为KPM模块添加控制功能,显示操作成功或失败的Snackbar提示,并优化模块信息获取逻辑

This commit is contained in:
ShirkNeko
2025-04-01 15:56:30 +08:00
parent 90b79f5c04
commit 08fdf2bdad
3 changed files with 38 additions and 8 deletions

View File

@@ -6,6 +6,8 @@ import android.content.Intent
import android.util.Log import android.util.Log
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.core.Spring
import androidx.compose.animation.core.SpringSpec
import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.items
@@ -13,6 +15,7 @@ import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.* import androidx.compose.material.icons.outlined.*
import androidx.compose.material3.* import androidx.compose.material3.*
import androidx.compose.material3.pulltorefresh.PullToRefreshBox import androidx.compose.material3.pulltorefresh.PullToRefreshBox
import androidx.compose.material3.pulltorefresh.rememberPullToRefreshState
import androidx.compose.runtime.* import androidx.compose.runtime.*
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
@@ -206,7 +209,7 @@ fun KpmScreen(
PullToRefreshBox( PullToRefreshBox(
onRefresh = { viewModel.fetchModuleList() }, onRefresh = { viewModel.fetchModuleList() },
isRefreshing = viewModel.isRefreshing, isRefreshing = viewModel.isRefreshing,
modifier = Modifier modifier = Modifier,
) { ) {
if (viewModel.moduleList.isEmpty()) { if (viewModel.moduleList.isEmpty()) {
Box( Box(
@@ -279,6 +282,13 @@ private fun KpmModuleItem(
onUninstall: () -> Unit, onUninstall: () -> Unit,
onControl: () -> Unit onControl: () -> Unit
) { ) {
val viewModel: KpmViewModel = viewModel()
val scope = rememberCoroutineScope()
val snackBarHost = remember { SnackbarHostState() }
val successMessage = stringResource(R.string.kpm_control_success)
val failureMessage = stringResource(R.string.kpm_control_failed)
ElevatedCard( ElevatedCard(
colors = getCardColors(MaterialTheme.colorScheme.secondaryContainer), colors = getCardColors(MaterialTheme.colorScheme.secondaryContainer),
elevation = CardDefaults.cardElevation(defaultElevation = getCardElevation()) elevation = CardDefaults.cardElevation(defaultElevation = getCardElevation())
@@ -325,7 +335,17 @@ private fun KpmModuleItem(
horizontalArrangement = Arrangement.spacedBy(8.dp) horizontalArrangement = Arrangement.spacedBy(8.dp)
) { ) {
FilledTonalButton( FilledTonalButton(
onClick = onControl, onClick = {
scope.launch {
val result = viewModel.controlModule(module.id, module.args)
val message = when (result) {
0 -> successMessage
else -> failureMessage
}
snackBarHost.showSnackbar(message)
onControl()
}
},
enabled = module.hasAction enabled = module.hasAction
) { ) {
Icon( Icon(

View File

@@ -24,7 +24,6 @@ class KpmViewModel : ViewModel() {
var currentModuleDetail by mutableStateOf("") var currentModuleDetail by mutableStateOf("")
private set private set
fun fetchModuleList() { fun fetchModuleList() {
viewModelScope.launch { viewModelScope.launch {
isRefreshing = true isRefreshing = true
@@ -70,7 +69,7 @@ class KpmViewModel : ViewModel() {
val info = getKpmModuleInfo(name) val info = getKpmModuleInfo(name)
if (info.isBlank()) return null if (info.isBlank()) return null
val properties = info.lineSequence() // 使用序列提升大文本性能 val properties = info.lineSequence()
.filter { line -> .filter { line ->
val trimmed = line.trim() val trimmed = line.trim()
trimmed.isNotEmpty() && !trimmed.startsWith("#") trimmed.isNotEmpty() && !trimmed.startsWith("#")
@@ -80,7 +79,7 @@ class KpmViewModel : ViewModel() {
when (parts.size) { when (parts.size) {
2 -> parts[0].trim() to parts[1].trim() 2 -> parts[0].trim() to parts[1].trim()
1 -> parts[0].trim() to "" 1 -> parts[0].trim() to ""
else -> null // 忽略无效行 else -> null
} }
} }
} }
@@ -89,8 +88,8 @@ class KpmViewModel : ViewModel() {
return ModuleInfo( return ModuleInfo(
id = name, id = name,
name = properties["name"] ?: name, name = properties["name"] ?: name,
version = properties["version"] ?: "unknown", version = properties["version"] ?: "",
author = properties["author"] ?: "unknown", author = properties["author"] ?: "",
description = properties["description"] ?: "", description = properties["description"] ?: "",
args = properties["args"] ?: "", args = properties["args"] ?: "",
enabled = true, enabled = true,
@@ -111,7 +110,16 @@ class KpmViewModel : ViewModel() {
} }
} }
} }
fun controlModule(moduleId: String, args: String? = null): Int {
return try {
val result = controlKpmModule(moduleId, args)
Log.d("KsuCli", "Control module $moduleId result: $result")
result
} catch (e: Exception) {
Log.e("KsuCli", "Failed to control module $moduleId", e)
-1
}
}
data class ModuleInfo( data class ModuleInfo(
val id: String, val id: String,

View File

@@ -242,5 +242,7 @@
<string name="close_notice">close</string> <string name="close_notice">close</string>
<string name="kernel_module_notice">The following kernel module functions were developed by KernelPatch and modified to include the kernel module functions of SukiSU Ultra</string> <string name="kernel_module_notice">The following kernel module functions were developed by KernelPatch and modified to include the kernel module functions of SukiSU Ultra</string>
<string name="home_ContributionCard_kernelsu">SukiSU Ultra Look forward to</string> <string name="home_ContributionCard_kernelsu">SukiSU Ultra Look forward to</string>
<string name="kpm_control_success">success</string>
<string name="kpm_control_failed">failed</string>
<string name="home_click_to_ContributionCard_kernelsu">SukiSU Ultra will be a relatively independent branch of KSU in the future, but thanks to the official KernelSU and MKSU etc. for their contributions!</string> <string name="home_click_to_ContributionCard_kernelsu">SukiSU Ultra will be a relatively independent branch of KSU in the future, but thanks to the official KernelSU and MKSU etc. for their contributions!</string>
</resources> </resources>