Skip to content

Commit

Permalink
manager: hides navbar on action screen, disable back gesture and save…
Browse files Browse the repository at this point in the history
… logs until action is completed

Fix irresponsive behaviour of runModuleAction() in ui.util.KsuCli to avoid app crash or hang during transition (tiann#2321)
  • Loading branch information
rifsxd authored and armv7a committed Jan 2, 2025
1 parent 7f3c229 commit f5f77ff
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 15 deletions.
23 changes: 22 additions & 1 deletion manager/app/src/main/java/me/weishu/kernelsu/ui/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,14 @@ import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.animation.AnimatedContentTransitionScope
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.EnterTransition
import androidx.compose.animation.ExitTransition
import androidx.compose.animation.core.tween
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.animation.slideInVertically
import androidx.compose.animation.slideOutVertically
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.WindowInsetsSides
import androidx.compose.foundation.layout.displayCutout
Expand All @@ -34,8 +37,10 @@ import androidx.compose.ui.unit.dp
import androidx.navigation.NavBackStackEntry
import androidx.navigation.NavHostController
import androidx.navigation.compose.rememberNavController
import androidx.navigation.compose.currentBackStackEntryAsState
import com.ramcosta.composedestinations.DestinationsNavHost
import com.ramcosta.composedestinations.animations.NavHostAnimatedDestinationStyle
import com.ramcosta.composedestinations.generated.destinations.ExecuteModuleActionScreenDestination
import com.ramcosta.composedestinations.generated.NavGraphs
import com.ramcosta.composedestinations.utils.isRouteOnBackStackAsState
import com.ramcosta.composedestinations.utils.rememberDestinationsNavigator
Expand All @@ -46,6 +51,7 @@ import me.weishu.kernelsu.ui.theme.KernelSUTheme
import me.weishu.kernelsu.ui.util.LocalSnackbarHost
import me.weishu.kernelsu.ui.util.rootAvailable
import me.weishu.kernelsu.ui.util.install
import me.weishu.kernelsu.ui.util.*

class MainActivity : ComponentActivity() {

Expand All @@ -66,8 +72,23 @@ 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
}

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(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,23 @@
package me.weishu.kernelsu.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
Expand Down Expand Up @@ -49,12 +57,17 @@ import java.util.Locale
@Destination<RootGraph>
fun ExecuteModuleActionScreen(navigator: DestinationsNavigator, moduleId: String) {
var text by rememberSaveable { mutableStateOf("") }
var tempText : String
var tempText: String
val logContent = rememberSaveable { StringBuilder() }
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()) {
Expand All @@ -79,29 +92,44 @@ fun ExecuteModuleActionScreen(navigator: DestinationsNavigator, moduleId: String
actionResult = it
}
}
if (actionResult) navigator.popBackStack()
isActionRunning = false
}

Scaffold(
topBar = {
TopBar(
isActionRunning = isActionRunning,
onBack = {
navigator.popBackStack()
},
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 {
Expand Down Expand Up @@ -129,16 +157,20 @@ fun ExecuteModuleActionScreen(navigator: DestinationsNavigator, moduleId: String

@OptIn(ExperimentalMaterial3Api::class)
@Composable
private fun TopBar(onBack: () -> Unit = {}, onSave: () -> Unit = {}) {
private fun TopBar(isActionRunning: Boolean, onBack: () -> Unit = {}, onSave: () -> Unit = {}) {
TopAppBar(
title = { Text(stringResource(R.string.action)) },
navigationIcon = {
IconButton(
onClick = onBack
onClick = onBack,
enabled = !isActionRunning
) { 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),
Expand Down
1 change: 1 addition & 0 deletions manager/app/src/main/res/values-zh-rCN/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@
<string name="grant_root_failed">获取 root 失败!</string>
<string name="action">执行</string>
<string name="open">打开</string>
<string name="close">关闭</string>
<string name="enable_web_debugging">启用 WebView 调试</string>
<string name="enable_web_debugging_summary">可用于调试 WebUI ,请仅在需要时启用。</string>
<string name="direct_install">直接安装(推荐)</string>
Expand Down
1 change: 1 addition & 0 deletions manager/app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@
<string name="grant_root_failed">Failed to grant root!</string>
<string name="action">Action</string>
<string name="open">Open</string>
<string name="close">Close</string>
<string name="enable_web_debugging">Enable WebView debugging</string>
<string name="enable_web_debugging_summary">Can be used to debug WebUI, please enable only when needed.</string>
<string name="direct_install">Direct install (Recommended)</string>
Expand Down

0 comments on commit f5f77ff

Please sign in to comment.