Add ability to skip to the next mode

This commit is contained in:
Nishant Mishra
2025-07-02 21:10:01 +05:30
parent 0e6e63057d
commit a5da20e32c
5 changed files with 118 additions and 14 deletions

View File

@@ -41,6 +41,7 @@ fun AppScreen(
showBrandTitle = showBrandTitle,
progress = { progress },
resetTimer = viewModel::resetTimer,
skipTimer = viewModel::skipTimer,
toggleTimer = viewModel::toggleTimer,
modifier = modifier
)

View File

@@ -67,6 +67,7 @@ fun TimerScreen(
showBrandTitle: Boolean,
progress: () -> Float,
resetTimer: () -> Unit,
skipTimer: () -> Unit,
toggleTimer: () -> Unit,
modifier: Modifier = Modifier
) {
@@ -228,7 +229,7 @@ fun TimerScreen(
maxLines = 1
)
}
val interactionSources = remember { List(2) { MutableInteractionSource() } }
val interactionSources = remember { List(3) { MutableInteractionSource() } }
ButtonGroup(
overflowIndicator = { state ->
FilledTonalIconButton(
@@ -243,11 +244,13 @@ fun TimerScreen(
containerColor = colorContainer
),
shapes = IconButtonDefaults.shapes(),
modifier = Modifier.size(64.dp, 96.dp)
modifier = Modifier
.size(64.dp, 96.dp)
) {
Icon(
painterResource(R.drawable.more_vert_large),
contentDescription = "More"
contentDescription = "More",
modifier = Modifier.size(32.dp)
)
}
},
@@ -263,10 +266,10 @@ fun TimerScreen(
checkedContentColor = onColor
),
shapes = IconButtonDefaults.toggleableShapes(),
interactionSource = interactionSources[1],
interactionSource = interactionSources[0],
modifier = Modifier
.size(width = 128.dp, height = 96.dp)
.animateWidth(interactionSources[1])
.animateWidth(interactionSources[0])
) {
if (uiState.timerRunning) {
Icon(
@@ -306,6 +309,7 @@ fun TimerScreen(
)
}
)
customItem(
{
FilledTonalIconButton(
@@ -314,10 +318,10 @@ fun TimerScreen(
containerColor = colorContainer
),
shapes = IconButtonDefaults.shapes(),
interactionSource = interactionSources[0],
interactionSource = interactionSources[1],
modifier = Modifier
.size(96.dp)
.animateWidth(interactionSources[0])
.animateWidth(interactionSources[1])
) {
Icon(
painterResource(R.drawable.restart_large),
@@ -342,6 +346,43 @@ fun TimerScreen(
)
}
)
customItem(
{
FilledTonalIconButton(
onClick = skipTimer,
colors = IconButtonDefaults.filledTonalIconButtonColors(
containerColor = colorContainer
),
shapes = IconButtonDefaults.shapes(),
interactionSource = interactionSources[2],
modifier = Modifier
.size(64.dp, 96.dp)
.animateWidth(interactionSources[2])
) {
Icon(
painterResource(R.drawable.skip_next_large),
contentDescription = "Skip to next",
modifier = Modifier.size(32.dp)
)
}
},
{ state ->
DropdownMenuItem(
leadingIcon = {
Icon(
painterResource(R.drawable.skip_next),
"Skip to next"
)
},
text = { Text("Skip to next") },
onClick = {
skipTimer()
state.dismiss()
}
)
}
)
}
}
@@ -374,8 +415,7 @@ fun TimerScreen(
@Preview(
showSystemUi = true,
device = Devices.PIXEL_9_PRO,
// widthDp = 200
device = Devices.PIXEL_9_PRO
)
@Composable
fun TimerScreenPreview() {
@@ -383,6 +423,6 @@ fun TimerScreenPreview() {
timeStr = "03:34", nextTimeStr = "5:00", timerMode = TimerMode.FOCUS, timerRunning = true
)
TomatoTheme {
TimerScreen(uiState, false, { 0.3f }, {}, {})
TimerScreen(uiState, false, { 0.3f }, {}, {}, {})
}
}

View File

@@ -54,6 +54,43 @@ class UiViewModel : ViewModel() {
}
}
fun skipTimer() {
startTime = 0L
pauseTime = 0L
pauseDuration = 0L
cycles = (cycles + 1) % 8
if (cycles % 2 == 0) {
_time.update { focusTime }
_uiState.update { currentState ->
currentState.copy(
timerMode = TimerMode.FOCUS,
timeStr = millisecondsToStr(time.value),
totalTime = time.value,
nextTimerMode = if (cycles == 6) TimerMode.LONG_BREAK else TimerMode.SHORT_BREAK,
nextTimeStr = if (cycles == 6) millisecondsToStr(
longBreakTime
) else millisecondsToStr(
shortBreakTime
)
)
}
} else {
val long = cycles == 7
_time.update { if (long) longBreakTime else shortBreakTime }
_uiState.update { currentState ->
currentState.copy(
timerMode = if (long) TimerMode.LONG_BREAK else TimerMode.SHORT_BREAK,
timeStr = millisecondsToStr(time.value),
totalTime = time.value,
nextTimerMode = TimerMode.FOCUS,
nextTimeStr = millisecondsToStr(focusTime)
)
}
}
}
fun toggleTimer() {
if (uiState.value.timerRunning) {
_uiState.update { currentState ->
@@ -85,7 +122,7 @@ class UiViewModel : ViewModel() {
startTime = 0L
pauseTime = 0L
pauseDuration = 0L
cycles++
cycles = (cycles + 1) % 8
if (cycles % 2 == 0) {
_time.update { focusTime }
@@ -94,8 +131,8 @@ class UiViewModel : ViewModel() {
timerMode = TimerMode.FOCUS,
timeStr = millisecondsToStr(time.value),
totalTime = time.value,
nextTimerMode = if (cycles % 6 == 0) TimerMode.LONG_BREAK else TimerMode.SHORT_BREAK,
nextTimeStr = if (cycles % 6 == 0) millisecondsToStr(
nextTimerMode = if (cycles == 6) TimerMode.LONG_BREAK else TimerMode.SHORT_BREAK,
nextTimeStr = if (cycles == 6) millisecondsToStr(
longBreakTime
) else millisecondsToStr(
shortBreakTime
@@ -103,7 +140,7 @@ class UiViewModel : ViewModel() {
)
}
} else {
val long = cycles % 7 == 0
val long = cycles == 7
_time.update { if (long) longBreakTime else shortBreakTime }
_uiState.update { currentState ->

View File

@@ -0,0 +1,13 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:autoMirrored="true"
android:tint="#000000"
android:viewportWidth="960"
android:viewportHeight="960">
<path
android:fillColor="@android:color/white"
android:pathData="M660,680v-400q0,-17 11.5,-28.5T700,240q17,0 28.5,11.5T740,280v400q0,17 -11.5,28.5T700,720q-17,0 -28.5,-11.5T660,680ZM220,645v-330q0,-18 12,-29t28,-11q5,0 11,1t11,5l248,166q9,6 13.5,14.5T548,480q0,10 -4.5,18.5T530,513L282,679q-5,4 -11,5t-11,1q-16,0 -28,-11t-12,-29Z" />
</vector>

View File

@@ -0,0 +1,13 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="40dp"
android:height="40dp"
android:autoMirrored="true"
android:tint="#000000"
android:viewportWidth="960"
android:viewportHeight="960">
<path
android:fillColor="@android:color/white"
android:pathData="M681.33,703v-446.67q0,-17.16 12.29,-29.41 12.28,-12.25 30.16,-12.25 17.22,0 29.39,12.25 12.16,12.25 12.16,29.41L765.33,703q0,17.83 -12.28,30.08t-29.5,12.25q-17.88,0 -30.05,-12.25 -12.17,-12.25 -12.17,-30.08ZM194.67,666.33v-372.66q0,-18 12.66,-30.17Q220,251.33 237,251.33q6,0 11.67,2.34 5.66,2.33 11.33,6l272.67,185q9.33,6.66 13.83,16.03 4.5,9.36 4.5,19.3 0,9.94 -4.5,19.3 -4.5,9.37 -13.83,15.37L260,700.33q-5.67,3.67 -11.33,5.67 -5.67,2 -11.67,2 -17,0 -29.67,-11.83 -12.66,-11.84 -12.66,-29.84Z" />
</vector>