diff --git a/manager/app/src/main/java/com/sukisu/ultra/ui/MainActivity.kt b/manager/app/src/main/java/com/sukisu/ultra/ui/MainActivity.kt
index f6e1feb5..91ed399c 100644
--- a/manager/app/src/main/java/com/sukisu/ultra/ui/MainActivity.kt
+++ b/manager/app/src/main/java/com/sukisu/ultra/ui/MainActivity.kt
@@ -24,6 +24,7 @@ import androidx.navigation.compose.rememberNavController
import com.ramcosta.composedestinations.DestinationsNavHost
import com.ramcosta.composedestinations.animations.NavHostAnimatedDestinationStyle
import com.ramcosta.composedestinations.generated.NavGraphs
+import com.ramcosta.composedestinations.generated.destinations.ExecuteModuleActionScreenDestination
import com.ramcosta.composedestinations.spec.NavHostGraphSpec
import com.ramcosta.composedestinations.spec.RouteOrDirection
import com.ramcosta.composedestinations.utils.isRouteOnBackStackAsState
@@ -39,6 +40,10 @@ import androidx.core.content.edit
import com.sukisu.ultra.ui.theme.CardConfig.cardElevation
import com.sukisu.ultra.ui.webui.initPlatform
import java.util.Locale
+import androidx.compose.animation.AnimatedVisibility
+import androidx.compose.animation.slideInVertically
+import androidx.compose.animation.slideOutVertically
+import androidx.navigation.compose.currentBackStackEntryAsState
class MainActivity : ComponentActivity() {
private inner class ThemeChangeContentObserver(
@@ -94,6 +99,7 @@ class MainActivity : ComponentActivity() {
// 确保应用正确的语言设置
applyLanguageSetting()
+ // 应用自定义 DPI
applyCustomDpi()
// Enable edge to edge
@@ -152,6 +158,12 @@ class MainActivity : ComponentActivity() {
KernelSUTheme {
val navController = rememberNavController()
val snackBarHostState = remember { SnackbarHostState() }
+ val currentDestination = navController.currentBackStackEntryAsState().value?.destination
+
+ val showBottomBar = when (currentDestination?.route) {
+ ExecuteModuleActionScreenDestination.route -> false // Hide for ExecuteModuleActionScreen
+ else -> true
+ }
// pre-init platform to faster start WebUI X activities
LaunchedEffect(Unit) {
@@ -159,7 +171,15 @@ class MainActivity : ComponentActivity() {
}
Scaffold(
- bottomBar = { BottomBar(navController) },
+ bottomBar = {
+ AnimatedVisibility(
+ visible = showBottomBar,
+ enter = slideInVertically(initialOffsetY = { it }) + fadeIn(),
+ exit = slideOutVertically(targetOffsetY = { it }) + fadeOut()
+ ) {
+ BottomBar(navController)
+ }
+ },
contentWindowInsets = WindowInsets(0, 0, 0, 0)
) { innerPadding ->
CompositionLocalProvider(
diff --git a/manager/app/src/main/java/com/sukisu/ultra/ui/screen/ExecuteModuleAction.kt b/manager/app/src/main/java/com/sukisu/ultra/ui/screen/ExecuteModuleAction.kt
index c43c4f8a..32576dfb 100644
--- a/manager/app/src/main/java/com/sukisu/ultra/ui/screen/ExecuteModuleAction.kt
+++ b/manager/app/src/main/java/com/sukisu/ultra/ui/screen/ExecuteModuleAction.kt
@@ -1,15 +1,22 @@
package com.sukisu.ultra.ui.screen
import android.os.Environment
+import androidx.activity.compose.BackHandler
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
+import androidx.compose.foundation.layout.WindowInsets
+import androidx.compose.foundation.layout.WindowInsetsSides
+import androidx.compose.foundation.layout.defaultMinSize
+import androidx.compose.foundation.layout.safeDrawing
+import androidx.compose.foundation.layout.only
import androidx.compose.material.icons.Icons
-import androidx.compose.material.icons.automirrored.filled.ArrowBack
+import androidx.compose.material.icons.filled.Close
import androidx.compose.material.icons.filled.Save
import androidx.compose.material3.ExperimentalMaterial3Api
+import androidx.compose.material3.ExtendedFloatingActionButton
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
@@ -30,7 +37,6 @@ import androidx.compose.ui.input.key.key
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.unit.dp
-import androidx.lifecycle.compose.dropUnlessResumed
import com.ramcosta.composedestinations.annotation.Destination
import com.ramcosta.composedestinations.annotation.RootGraph
import com.ramcosta.composedestinations.navigation.DestinationsNavigator
@@ -55,7 +61,11 @@ fun ExecuteModuleActionScreen(navigator: DestinationsNavigator, moduleId: String
val snackBarHost = LocalSnackbarHost.current
val scope = rememberCoroutineScope()
val scrollState = rememberScrollState()
- var actionResult: Boolean
+ var isActionRunning by rememberSaveable { mutableStateOf(true) }
+
+ BackHandler(enabled = isActionRunning) {
+ // Disable back button if action is running
+ }
LaunchedEffect(Unit) {
if (text.isNotEmpty()) {
@@ -76,33 +86,43 @@ fun ExecuteModuleActionScreen(navigator: DestinationsNavigator, moduleId: String
onStderr = {
logContent.append(it).append("\n")
}
- ).let {
- actionResult = it
- }
+ )
}
- if (actionResult) navigator.popBackStack()
+ isActionRunning = false
}
Scaffold(
topBar = {
TopBar(
- onBack = dropUnlessResumed {
- navigator.popBackStack()
- },
+ isActionRunning = isActionRunning,
onSave = {
- scope.launch {
- val format = SimpleDateFormat("yyyy-MM-dd-HH-mm-ss", Locale.getDefault())
- val date = format.format(Date())
- val file = File(
- Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS),
- "KernelSU_module_action_log_${date}.log"
- )
- file.writeText(logContent.toString())
- snackBarHost.showSnackbar("Log saved to ${file.absolutePath}")
+ if (!isActionRunning) {
+ scope.launch {
+ val format = SimpleDateFormat("yyyy-MM-dd-HH-mm-ss", Locale.getDefault())
+ val date = format.format(Date())
+ val file = File(
+ Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS),
+ "KernelSU_module_action_log_${date}.log"
+ )
+ file.writeText(logContent.toString())
+ snackBarHost.showSnackbar("Log saved to ${file.absolutePath}")
+ }
}
}
)
},
+ floatingActionButton = {
+ if (!isActionRunning) {
+ ExtendedFloatingActionButton(
+ text = { Text(text = stringResource(R.string.close)) },
+ icon = { Icon(Icons.Filled.Close, contentDescription = null) },
+ onClick = {
+ navigator.popBackStack()
+ }
+ )
+ }
+ },
+ contentWindowInsets = WindowInsets.safeDrawing,
snackbarHost = { SnackbarHost(snackBarHost) }
) { innerPadding ->
KeyEventBlocker {
@@ -130,16 +150,14 @@ fun ExecuteModuleActionScreen(navigator: DestinationsNavigator, moduleId: String
@OptIn(ExperimentalMaterial3Api::class)
@Composable
-private fun TopBar(onBack: () -> Unit = {}, onSave: () -> Unit = {}) {
+private fun TopBar(isActionRunning: Boolean, onSave: () -> Unit = {}) {
TopAppBar(
title = { Text(stringResource(R.string.action)) },
- navigationIcon = {
- IconButton(
- onClick = onBack
- ) { Icon(Icons.AutoMirrored.Filled.ArrowBack, contentDescription = null) }
- },
actions = {
- IconButton(onClick = onSave) {
+ IconButton(
+ onClick = onSave,
+ enabled = !isActionRunning
+ ) {
Icon(
imageVector = Icons.Filled.Save,
contentDescription = stringResource(id = R.string.save_log),
@@ -147,4 +165,4 @@ private fun TopBar(onBack: () -> Unit = {}, onSave: () -> Unit = {}) {
}
}
)
-}
\ No newline at end of file
+}
diff --git a/manager/app/src/main/res/values-in/strings.xml b/manager/app/src/main/res/values-in/strings.xml
index c93bffab..7f602496 100644
--- a/manager/app/src/main/res/values-in/strings.xml
+++ b/manager/app/src/main/res/values-in/strings.xml
@@ -112,6 +112,7 @@
Instal ke slot nonaktif (setelah OTA)
Gagal memberikan akses root!
Buka
+ Tutup
Cek terbaru
Cek terbaru setiap membuka aplikasi
Hapus permanen KernelSU (root dan modul).
diff --git a/manager/app/src/main/res/values-zh-rCN/strings.xml b/manager/app/src/main/res/values-zh-rCN/strings.xml
index b57245cc..413338f8 100644
--- a/manager/app/src/main/res/values-zh-rCN/strings.xml
+++ b/manager/app/src/main/res/values-zh-rCN/strings.xml
@@ -113,6 +113,7 @@
获取 root 失败!
执行
打开
+ 关闭
启用 WebView 调试
可用于调试 WebUI 。请仅在需要时启用。
直接安装(推荐)
diff --git a/manager/app/src/main/res/values/strings.xml b/manager/app/src/main/res/values/strings.xml
index f862a13c..a32f04d4 100644
--- a/manager/app/src/main/res/values/strings.xml
+++ b/manager/app/src/main/res/values/strings.xml
@@ -115,6 +115,7 @@
Failed to grant root!
Action
Open
+ Close
Enable WebView debugging
Can be used to debug WebUI. Please enable only when needed.
Direct install (Recommended)