Add ability to skip to the next mode
This commit is contained in:
@@ -41,6 +41,7 @@ fun AppScreen(
|
||||
showBrandTitle = showBrandTitle,
|
||||
progress = { progress },
|
||||
resetTimer = viewModel::resetTimer,
|
||||
skipTimer = viewModel::skipTimer,
|
||||
toggleTimer = viewModel::toggleTimer,
|
||||
modifier = modifier
|
||||
)
|
||||
|
||||
@@ -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 }, {}, {}, {})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 ->
|
||||
|
||||
13
app/src/main/res/drawable/skip_next.xml
Normal file
13
app/src/main/res/drawable/skip_next.xml
Normal 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>
|
||||
13
app/src/main/res/drawable/skip_next_large.xml
Normal file
13
app/src/main/res/drawable/skip_next_large.xml
Normal 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>
|
||||
Reference in New Issue
Block a user