manager: added animation for nav bar hiding and improved flash screen and action screen

This commit is contained in:
Rifat Azad
2025-01-02 17:27:02 +06:00
parent 6695dfbb26
commit 89a33b3484
3 changed files with 50 additions and 46 deletions

View File

@@ -5,6 +5,9 @@ import android.os.Bundle
import androidx.activity.ComponentActivity 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.animation.AnimatedVisibility
import androidx.compose.animation.slideInVertically
import androidx.compose.animation.slideOutVertically
import androidx.compose.animation.AnimatedContentTransitionScope import androidx.compose.animation.AnimatedContentTransitionScope
import androidx.compose.animation.EnterTransition import androidx.compose.animation.EnterTransition
import androidx.compose.animation.ExitTransition import androidx.compose.animation.ExitTransition
@@ -91,7 +94,11 @@ class MainActivity : ComponentActivity() {
Scaffold( Scaffold(
bottomBar = { bottomBar = {
if (showBottomBar) { AnimatedVisibility(
visible = showBottomBar,
enter = slideInVertically(initialOffsetY = { it }) + fadeIn(),
exit = slideOutVertically(targetOffsetY = { it }) + fadeOut()
) {
BottomBar(navController) BottomBar(navController)
} }
}, },

View File

@@ -14,6 +14,7 @@ import androidx.compose.foundation.layout.defaultMinSize
import androidx.compose.foundation.layout.safeDrawing import androidx.compose.foundation.layout.safeDrawing
import androidx.compose.foundation.layout.only import androidx.compose.foundation.layout.only
import androidx.compose.material.icons.Icons 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.Close
import androidx.compose.material.icons.filled.Save import androidx.compose.material.icons.filled.Save
import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.ExperimentalMaterial3Api
@@ -99,6 +100,9 @@ fun ExecuteModuleActionScreen(navigator: DestinationsNavigator, moduleId: String
topBar = { topBar = {
TopBar( TopBar(
isActionRunning = isActionRunning, isActionRunning = isActionRunning,
onBack = {
navigator.popBackStack()
},
onSave = { onSave = {
if (!isActionRunning) { if (!isActionRunning) {
scope.launch { scope.launch {
@@ -122,13 +126,11 @@ fun ExecuteModuleActionScreen(navigator: DestinationsNavigator, moduleId: String
icon = { Icon(Icons.Filled.Close, contentDescription = null) }, icon = { Icon(Icons.Filled.Close, contentDescription = null) },
onClick = { onClick = {
navigator.popBackStack() navigator.popBackStack()
}, }
modifier = Modifier
.navigationBarsPadding()
) )
} }
}, },
contentWindowInsets = WindowInsets.safeDrawing.only(WindowInsetsSides.Top + WindowInsetsSides.Horizontal), contentWindowInsets = WindowInsets.safeDrawing,
snackbarHost = { SnackbarHost(snackBarHost) } snackbarHost = { SnackbarHost(snackBarHost) }
) { innerPadding -> ) { innerPadding ->
KeyEventBlocker { KeyEventBlocker {
@@ -156,9 +158,15 @@ fun ExecuteModuleActionScreen(navigator: DestinationsNavigator, moduleId: String
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
private fun TopBar(isActionRunning: Boolean, onSave: () -> Unit = {}) { private fun TopBar(isActionRunning: Boolean, onBack: () -> Unit = {}, onSave: () -> Unit = {}) {
TopAppBar( TopAppBar(
title = { Text(stringResource(R.string.action)) }, title = { Text(stringResource(R.string.action)) },
navigationIcon = {
IconButton(
onClick = onBack,
enabled = !isActionRunning
) { Icon(Icons.AutoMirrored.Filled.ArrowBack, contentDescription = null) }
},
actions = { actions = {
IconButton( IconButton(
onClick = onSave, onClick = onSave,

View File

@@ -16,6 +16,7 @@ import androidx.compose.foundation.layout.safeDrawing
import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material.icons.filled.Refresh import androidx.compose.material.icons.filled.Refresh
import androidx.compose.material.icons.filled.Close import androidx.compose.material.icons.filled.Close
import androidx.compose.material.icons.filled.Save import androidx.compose.material.icons.filled.Save
@@ -133,6 +134,9 @@ fun FlashScreen(navigator: DestinationsNavigator, flashIt: FlashIt) {
topBar = { topBar = {
TopBar( TopBar(
flashing, flashing,
onBack = {
navigator.popBackStack()
},
onSave = { onSave = {
scope.launch { scope.launch {
val format = SimpleDateFormat("yyyy-MM-dd-HH-mm-ss", Locale.getDefault()) val format = SimpleDateFormat("yyyy-MM-dd-HH-mm-ss", Locale.getDefault())
@@ -148,8 +152,24 @@ fun FlashScreen(navigator: DestinationsNavigator, flashIt: FlashIt) {
scrollBehavior = scrollBehavior scrollBehavior = scrollBehavior
) )
}, },
snackbarHost = { SnackbarHost(hostState = snackBarHost) }, floatingActionButton = {
contentWindowInsets = WindowInsets.safeDrawing.only(WindowInsetsSides.Top + WindowInsetsSides.Horizontal) if (showFloatAction) {
// Reboot button (bottom left)
ExtendedFloatingActionButton(
onClick = {
scope.launch {
withContext(Dispatchers.IO) {
reboot()
}
}
},
icon = { Icon(Icons.Filled.Refresh, contentDescription = stringResource(R.string.reboot)) },
text = { Text(text = stringResource(R.string.reboot)) }
)
}
},
contentWindowInsets = WindowInsets.safeDrawing,
snackbarHost = { SnackbarHost(hostState = snackBarHost) }
) { innerPadding -> ) { innerPadding ->
KeyEventBlocker { KeyEventBlocker {
it.key == Key.VolumeDown || it.key == Key.VolumeUp it.key == Key.VolumeDown || it.key == Key.VolumeUp
@@ -172,44 +192,6 @@ fun FlashScreen(navigator: DestinationsNavigator, flashIt: FlashIt) {
lineHeight = MaterialTheme.typography.bodySmall.lineHeight, lineHeight = MaterialTheme.typography.bodySmall.lineHeight,
) )
} }
// Floating Action Buttons
Box(modifier = Modifier.fillMaxSize()) {
// Reboot button (bottom left)
if (showFloatAction) {
val reboot = stringResource(id = R.string.reboot)
ExtendedFloatingActionButton(
onClick = {
scope.launch {
withContext(Dispatchers.IO) {
reboot()
}
}
},
icon = { Icon(Icons.Filled.Refresh, reboot) },
text = { Text(text = reboot) },
modifier = Modifier
.align(Alignment.BottomStart)
.padding(16.dp)
.navigationBarsPadding()
)
}
if (showFloatAction) {
// Back button (bottom right)
ExtendedFloatingActionButton(
onClick = {
navigator.popBackStack()
},
text = { Text(text = stringResource(R.string.close)) },
icon = { Icon(Icons.Filled.Close, contentDescription = null) },
modifier = Modifier
.align(Alignment.BottomEnd)
.padding(16.dp)
.navigationBarsPadding()
)
}
}
} }
} }
@@ -252,6 +234,7 @@ fun flashIt(
@Composable @Composable
private fun TopBar( private fun TopBar(
status: FlashingStatus, status: FlashingStatus,
onBack: () -> Unit = {},
onSave: () -> Unit = {}, onSave: () -> Unit = {},
scrollBehavior: TopAppBarScrollBehavior? = null scrollBehavior: TopAppBarScrollBehavior? = null
) { ) {
@@ -267,6 +250,12 @@ private fun TopBar(
) )
) )
}, },
navigationIcon = {
IconButton(
onClick = { if (status != FlashingStatus.FLASHING) onBack() },
enabled = status != FlashingStatus.FLASHING
) { Icon(Icons.AutoMirrored.Filled.ArrowBack, contentDescription = null) }
},
actions = { actions = {
IconButton( IconButton(
onClick = { if (status != FlashingStatus.FLASHING) onSave() }, onClick = { if (status != FlashingStatus.FLASHING) onSave() },