diff --git a/app/src/main/java/com/bnyro/clock/ui/components/NumberKeypad.kt b/app/src/main/java/com/bnyro/clock/ui/components/NumberKeypad.kt
index 0d472850..62fc25f6 100644
--- a/app/src/main/java/com/bnyro/clock/ui/components/NumberKeypad.kt
+++ b/app/src/main/java/com/bnyro/clock/ui/components/NumberKeypad.kt
@@ -38,28 +38,32 @@ fun NumberKeypad(
verticalArrangement = Arrangement.spacedBy(buttonSpacing)
) {
Row(
- horizontalArrangement = Arrangement.spacedBy(buttonSpacing)
+ horizontalArrangement = Arrangement.spacedBy(buttonSpacing),
+ modifier = Modifier.weight(1f)
) {
NumPadButton(number = "1", buttonSize, onOperation)
NumPadButton(number = "2", buttonSize, onOperation)
NumPadButton(number = "3", buttonSize, onOperation)
}
Row(
- horizontalArrangement = Arrangement.spacedBy(buttonSpacing)
+ horizontalArrangement = Arrangement.spacedBy(buttonSpacing),
+ modifier = Modifier.weight(1f)
) {
NumPadButton(number = "4", buttonSize, onOperation)
NumPadButton(number = "5", buttonSize, onOperation)
NumPadButton(number = "6", buttonSize, onOperation)
}
Row(
- horizontalArrangement = Arrangement.spacedBy(buttonSpacing)
+ horizontalArrangement = Arrangement.spacedBy(buttonSpacing),
+ modifier = Modifier.weight(1f)
) {
NumPadButton(number = "7", buttonSize, onOperation)
NumPadButton(number = "8", buttonSize, onOperation)
NumPadButton(number = "9", buttonSize, onOperation)
}
Row(
- horizontalArrangement = Arrangement.spacedBy(buttonSpacing)
+ horizontalArrangement = Arrangement.spacedBy(buttonSpacing),
+ modifier = Modifier.weight(1f)
) {
NumPadButton(number = "00", buttonSize, onOperation)
NumPadButton(number = "0", buttonSize, onOperation)
diff --git a/app/src/main/java/com/bnyro/clock/ui/screens/TimerScreen.kt b/app/src/main/java/com/bnyro/clock/ui/screens/TimerScreen.kt
index 311c0aaf..2262b9a0 100644
--- a/app/src/main/java/com/bnyro/clock/ui/screens/TimerScreen.kt
+++ b/app/src/main/java/com/bnyro/clock/ui/screens/TimerScreen.kt
@@ -1,5 +1,6 @@
package com.bnyro.clock.ui.screens
+import android.content.Context
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.background
import androidx.compose.foundation.combinedClickable
@@ -28,11 +29,15 @@ import androidx.compose.material.icons.filled.PlayArrow
import androidx.compose.material.icons.filled.Save
import androidx.compose.material.icons.rounded.Add
import androidx.compose.material.icons.rounded.AddAlarm
+import androidx.compose.material3.Button
+import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.FloatingActionButton
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.ModalBottomSheet
import androidx.compose.material3.SmallFloatingActionButton
import androidx.compose.material3.Text
+import androidx.compose.material3.rememberModalBottomSheetState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
@@ -58,7 +63,7 @@ import com.bnyro.clock.ui.model.TimerModel
import com.bnyro.clock.ui.nav.TopBarScaffold
import com.bnyro.clock.util.Preferences
-@OptIn(ExperimentalFoundationApi::class)
+@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun TimerScreen(onClickSettings: () -> Unit, timerModel: TimerModel) {
val context = LocalContext.current
@@ -72,129 +77,37 @@ fun TimerScreen(onClickSettings: () -> Unit, timerModel: TimerModel) {
mutableStateOf(false)
}
- TopBarScaffold(title = stringResource(R.string.timer), onClickSettings, fab = {
- if (timerModel.scheduledObjects.isEmpty() || createNew) {
- Column(
- horizontalAlignment = Alignment.CenterHorizontally
+ TopBarScaffold(title = stringResource(R.string.timer), onClickSettings, actions = {
+ if (timerModel.scheduledObjects.isEmpty()) {
+ ClickableIcon(
+ imageVector = Icons.Rounded.AddAlarm,
+ contentDescription = stringResource(R.string.add_preset_timer)
) {
- if (timerModel.scheduledObjects.isNotEmpty()) {
- SmallFloatingActionButton(
- containerColor = MaterialTheme.colorScheme.tertiaryContainer,
- onClick = { createNew = false }
- ) {
- Icon(imageVector = Icons.Default.ArrowBack, contentDescription = null)
- }
- Spacer(Modifier.height(8.dp))
- }
- FloatingActionButton(
- onClick = {
- createNew = false
- timerModel.startTimer(context)
- }
- ) {
- Icon(imageVector = Icons.Default.PlayArrow, contentDescription = null)
- }
+ timerModel.addPersistentTimer(timerModel.timePickerSeconds)
}
} else {
- FloatingActionButton(
- modifier = Modifier,
- onClick = { createNew = true }
- ) {
- Icon(imageVector = Icons.Default.Create, contentDescription = null)
- }
- }
- }, actions = {
- if (timerModel.scheduledObjects.isEmpty() || createNew) {
ClickableIcon(
- imageVector = Icons.Rounded.AddAlarm,
+ imageVector = Icons.Rounded.Add,
contentDescription = stringResource(R.string.add_preset_timer)
) {
- timerModel.addPersistentTimer(timerModel.timePickerSeconds)
+ createNew = true
}
}
}) { paddingValues ->
- if (timerModel.scheduledObjects.isEmpty() || createNew) {
+ if (timerModel.scheduledObjects.isEmpty()) {
Column(
- modifier = Modifier
- .fillMaxSize()
- .padding(paddingValues),
- horizontalAlignment = Alignment.CenterHorizontally
+ Modifier
+ .padding(paddingValues)
) {
- if (!useScrollPicker) {
- Row(
- Modifier
- .fillMaxWidth()
- .weight(2f),
- horizontalArrangement = Arrangement.Center,
- verticalAlignment = Alignment.CenterVertically
- ) {
- TimePickerDial(timerModel)
- }
- } else {
- Column(
- modifier = Modifier.weight(3f),
- horizontalAlignment = Alignment.CenterHorizontally,
- verticalArrangement = Arrangement.Center
- ) {
- FormattedTimerTime(
- seconds = timerModel.timePickerFakeUnits,
- modifier = Modifier.padding(bottom = 32.dp)
- )
- NumberKeypad(
- onOperation = { operation ->
- when (operation) {
- is NumberKeypadOperation.AddNumber -> timerModel.addNumber(
- operation.number
- )
-
- is NumberKeypadOperation.Delete -> timerModel.deleteLastNumber()
- is NumberKeypadOperation.Clear -> timerModel.clear()
- }
- }
- )
- }
- }
- if (showExampleTimers) {
- val haptic = LocalHapticFeedback.current
- LazyVerticalGrid(
- modifier = Modifier
- .fillMaxWidth(),
- columns = GridCells.Adaptive(100.dp),
- contentPadding = PaddingValues(16.dp),
- verticalArrangement = Arrangement.spacedBy(8.dp),
- horizontalArrangement = Arrangement.spacedBy(8.dp)
- ) {
- itemsIndexed(items = timerModel.persistentTimers) { index, timer ->
- Box(
- modifier = Modifier
- .clip(RoundedCornerShape(16.dp))
- .combinedClickable(
- onClick = {
- timerModel.timePickerSeconds = timer.seconds
- createNew = false
- timerModel.startTimer(context)
- },
- onLongClick = {
- haptic.performHapticFeedback(
- HapticFeedbackType.LongPress
- )
- timerModel.removePersistentTimer(index)
- }
- )
- .width(100.dp)
- .background(MaterialTheme.colorScheme.secondaryContainer)
- .padding(8.dp),
- contentAlignment = Alignment.Center
- ) {
- Text(
- timer.formattedTime,
- style = MaterialTheme.typography.titleLarge,
- color = MaterialTheme.colorScheme.onSecondaryContainer
- )
- }
- }
+ TimerPicker(
+ useScrollPicker,
+ timerModel,
+ showExampleTimers,
+ context,
+ onCreateNew = {
+ createNew = false
}
- }
+ )
}
} else {
LazyColumn(
@@ -209,4 +122,120 @@ fun TimerScreen(onClickSettings: () -> Unit, timerModel: TimerModel) {
}
}
}
+
+ if (createNew) {
+ val sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)
+ ModalBottomSheet(
+ onDismissRequest = { createNew = false },
+ sheetState = sheetState
+ ) {
+ TimerPicker(
+ useScrollPicker,
+ timerModel,
+ showExampleTimers,
+ context,
+ onCreateNew = {
+ createNew = false
+ }
+ )
+ }
+ }
+}
+
+@Composable
+@OptIn(ExperimentalFoundationApi::class)
+private fun TimerPicker(
+ useScrollPicker: Boolean,
+ timerModel: TimerModel,
+ showExampleTimers: Boolean,
+ context: Context,
+ onCreateNew: () -> Unit
+) {
+ Column(
+ modifier = Modifier
+ .fillMaxSize(),
+ horizontalAlignment = Alignment.CenterHorizontally
+ ) {
+ if (!useScrollPicker) {
+ Row(
+ Modifier
+ .fillMaxWidth()
+ .weight(2f),
+ horizontalArrangement = Arrangement.Center,
+ verticalAlignment = Alignment.CenterVertically
+ ) {
+ TimePickerDial(timerModel)
+ }
+ } else {
+ Column(
+ modifier = Modifier.weight(3f),
+ horizontalAlignment = Alignment.CenterHorizontally,
+ verticalArrangement = Arrangement.Center
+ ) {
+ FormattedTimerTime(
+ seconds = timerModel.timePickerFakeUnits,
+ modifier = Modifier.padding(bottom = 32.dp)
+ )
+ NumberKeypad(
+ onOperation = { operation ->
+ when (operation) {
+ is NumberKeypadOperation.AddNumber -> timerModel.addNumber(
+ operation.number
+ )
+
+ is NumberKeypadOperation.Delete -> timerModel.deleteLastNumber()
+ is NumberKeypadOperation.Clear -> timerModel.clear()
+ }
+ }
+ )
+ }
+ }
+ if (showExampleTimers) {
+ val haptic = LocalHapticFeedback.current
+ LazyVerticalGrid(
+ modifier = Modifier
+ .fillMaxWidth(),
+ columns = GridCells.Adaptive(100.dp),
+ contentPadding = PaddingValues(16.dp),
+ verticalArrangement = Arrangement.spacedBy(8.dp),
+ horizontalArrangement = Arrangement.spacedBy(8.dp)
+ ) {
+ itemsIndexed(items = timerModel.persistentTimers) { index, timer ->
+ Box(
+ modifier = Modifier
+ .clip(RoundedCornerShape(16.dp))
+ .combinedClickable(
+ onClick = {
+ timerModel.timePickerSeconds = timer.seconds
+ onCreateNew.invoke()
+ timerModel.startTimer(context)
+ },
+ onLongClick = {
+ haptic.performHapticFeedback(
+ HapticFeedbackType.LongPress
+ )
+ timerModel.removePersistentTimer(index)
+ }
+ )
+ .width(100.dp)
+ .background(MaterialTheme.colorScheme.secondaryContainer)
+ .padding(8.dp),
+ contentAlignment = Alignment.Center
+ ) {
+ Text(
+ timer.formattedTime,
+ style = MaterialTheme.typography.titleLarge,
+ color = MaterialTheme.colorScheme.onSecondaryContainer
+ )
+ }
+ }
+ }
+ }
+ Button(modifier = Modifier.padding(vertical = 16.dp), onClick = {
+ onCreateNew.invoke()
+ timerModel.startTimer(context)
+ }) {
+ Text(text = stringResource(R.string.start), style = MaterialTheme.typography.titleLarge)
+ }
+ }
}
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 419c4c46..0186c981 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -109,4 +109,5 @@
Lap Time
Overall Time
Add preset timer
+ Start
\ No newline at end of file