feat: Implement a simple bottom navigation bar based UI

for facilitating multiple screens in further releases
This commit is contained in:
Nishant Mishra
2025-07-03 13:59:00 +05:30
parent a5da20e32c
commit 7b7d10a233
6 changed files with 164 additions and 88 deletions

View File

@@ -1,7 +1,16 @@
package org.nsh07.pomodoro.ui
import androidx.compose.foundation.layout.calculateEndPadding
import androidx.compose.foundation.layout.calculateStartPadding
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
import androidx.compose.material3.Icon
import androidx.compose.material3.Scaffold
import androidx.compose.material3.ShortNavigationBar
import androidx.compose.material3.ShortNavigationBarItem
import androidx.compose.material3.ShortNavigationBarItemDefaults
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
@@ -10,10 +19,13 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberUpdatedState
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.res.painterResource
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.withContext
import org.nsh07.pomodoro.R
import org.nsh07.pomodoro.ui.timerScreen.TimerScreen
import org.nsh07.pomodoro.ui.viewModel.UiViewModel
@@ -36,13 +48,33 @@ fun AppScreen(
}
}
TimerScreen(
uiState = uiState,
showBrandTitle = showBrandTitle,
progress = { progress },
resetTimer = viewModel::resetTimer,
skipTimer = viewModel::skipTimer,
toggleTimer = viewModel::toggleTimer,
modifier = modifier
)
val layoutDirection = LocalLayoutDirection.current
Scaffold(
bottomBar = {
ShortNavigationBar {
ShortNavigationBarItem(
selected = true,
onClick = { },
icon = { Icon(painterResource(R.drawable.hourglass_filled), null) },
label = { Text("Timer") },
colors = ShortNavigationBarItemDefaults.colors()
)
}
}
) { contentPadding ->
TimerScreen(
uiState = uiState,
showBrandTitle = showBrandTitle,
progress = { progress },
resetTimer = viewModel::resetTimer,
skipTimer = viewModel::skipTimer,
toggleTimer = viewModel::toggleTimer,
modifier = modifier.padding(
start = contentPadding.calculateStartPadding(layoutDirection),
end = contentPadding.calculateEndPadding(layoutDirection),
bottom = contentPadding.calculateBottomPadding()
)
)
}
}

View File

@@ -31,7 +31,6 @@ import androidx.compose.material3.IconButtonDefaults
import androidx.compose.material3.MaterialTheme.colorScheme
import androidx.compose.material3.MaterialTheme.motionScheme
import androidx.compose.material3.MaterialTheme.typography
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.runtime.Composable
@@ -94,89 +93,84 @@ fun TimerScreen(
haptic.performHapticFeedback(HapticFeedbackType.LongPress)
}
Scaffold(
topBar = {
TopAppBar(
title = {
AnimatedContent(
if (!showBrandTitle) uiState.timerMode else TimerMode.BRAND,
transitionSpec = {
slideInVertically(
Column(modifier = modifier) {
TopAppBar(
title = {
AnimatedContent(
if (!showBrandTitle) uiState.timerMode else TimerMode.BRAND,
transitionSpec = {
slideInVertically(
animationSpec = motionScheme.slowSpatialSpec(),
initialOffsetY = { (-it * 1.25).toInt() }
).togetherWith(
slideOutVertically(
animationSpec = motionScheme.slowSpatialSpec(),
initialOffsetY = { (-it * 1.25).toInt() }
).togetherWith(
slideOutVertically(
animationSpec = motionScheme.slowSpatialSpec(),
targetOffsetY = { (it * 1.25).toInt() }
)
targetOffsetY = { (it * 1.25).toInt() }
)
}
) {
when (it) {
TimerMode.BRAND ->
Text(
"Tomato",
style = TextStyle(
fontFamily = robotoFlexTitle,
fontSize = 32.sp,
lineHeight = 32.sp,
color = colorScheme.onErrorContainer
),
textAlign = TextAlign.Center,
modifier = Modifier.width(210.dp)
)
TimerMode.FOCUS ->
Text(
"Focus",
style = TextStyle(
fontFamily = robotoFlexTitle,
fontSize = 32.sp,
lineHeight = 32.sp,
color = colorScheme.onPrimaryContainer
),
textAlign = TextAlign.Center,
modifier = Modifier.width(210.dp)
)
TimerMode.SHORT_BREAK -> Text(
"Short Break",
style = TextStyle(
fontFamily = robotoFlexTitle,
fontSize = 32.sp,
lineHeight = 32.sp,
color = colorScheme.onTertiaryContainer
),
textAlign = TextAlign.Center,
modifier = Modifier.width(210.dp)
)
TimerMode.LONG_BREAK -> Text(
"Long Break",
style = TextStyle(
fontFamily = robotoFlexTitle,
fontSize = 32.sp,
lineHeight = 32.sp,
color = colorScheme.onTertiaryContainer
),
textAlign = TextAlign.Center,
modifier = Modifier.width(210.dp)
)
}
)
}
},
subtitle = {},
titleHorizontalAlignment = Alignment.CenterHorizontally
)
},
modifier = modifier.fillMaxSize()
) { insets ->
) {
when (it) {
TimerMode.BRAND ->
Text(
"Tomato",
style = TextStyle(
fontFamily = robotoFlexTitle,
fontSize = 32.sp,
lineHeight = 32.sp,
color = colorScheme.onErrorContainer
),
textAlign = TextAlign.Center,
modifier = Modifier.width(210.dp)
)
TimerMode.FOCUS ->
Text(
"Focus",
style = TextStyle(
fontFamily = robotoFlexTitle,
fontSize = 32.sp,
lineHeight = 32.sp,
color = colorScheme.onPrimaryContainer
),
textAlign = TextAlign.Center,
modifier = Modifier.width(210.dp)
)
TimerMode.SHORT_BREAK -> Text(
"Short Break",
style = TextStyle(
fontFamily = robotoFlexTitle,
fontSize = 32.sp,
lineHeight = 32.sp,
color = colorScheme.onTertiaryContainer
),
textAlign = TextAlign.Center,
modifier = Modifier.width(210.dp)
)
TimerMode.LONG_BREAK -> Text(
"Long Break",
style = TextStyle(
fontFamily = robotoFlexTitle,
fontSize = 32.sp,
lineHeight = 32.sp,
color = colorScheme.onTertiaryContainer
),
textAlign = TextAlign.Center,
modifier = Modifier.width(210.dp)
)
}
}
},
subtitle = {},
titleHorizontalAlignment = Alignment.CenterHorizontally
)
Column(
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier
.fillMaxSize()
.padding(insets)
modifier = Modifier.fillMaxSize()
) {
Column(horizontalAlignment = Alignment.CenterHorizontally) {
Box(contentAlignment = Alignment.Center) {
@@ -423,6 +417,13 @@ fun TimerScreenPreview() {
timeStr = "03:34", nextTimeStr = "5:00", timerMode = TimerMode.FOCUS, timerRunning = true
)
TomatoTheme {
TimerScreen(uiState, false, { 0.3f }, {}, {}, {})
TimerScreen(
uiState,
false,
{ 0.3f },
{},
{},
{}
)
}
}