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)