Auto commit Sat Apr 4 08:01:01 AM CDT 2026
This commit is contained in:
@@ -104,6 +104,7 @@ import com.mindmachine.mvp.session.flashIntervalMsToSeconds
|
|||||||
import com.mindmachine.mvp.session.flashIntervalSecondsToMs
|
import com.mindmachine.mvp.session.flashIntervalSecondsToMs
|
||||||
import com.mindmachine.mvp.session.formatDuration
|
import com.mindmachine.mvp.session.formatDuration
|
||||||
import com.mindmachine.mvp.session.sessionProgressFraction
|
import com.mindmachine.mvp.session.sessionProgressFraction
|
||||||
|
import com.mindmachine.mvp.session.shouldRequireStopConfirmation
|
||||||
import com.mindmachine.mvp.session.shouldShowActiveControlsByDefault
|
import com.mindmachine.mvp.session.shouldShowActiveControlsByDefault
|
||||||
import com.mindmachine.mvp.session.shouldUseImmersiveFullscreen
|
import com.mindmachine.mvp.session.shouldUseImmersiveFullscreen
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
@@ -113,6 +114,11 @@ import java.util.Locale
|
|||||||
private const val SESSION_ENTRY_HOME = "home"
|
private const val SESSION_ENTRY_HOME = "home"
|
||||||
private const val SESSION_ENTRY_SETUP = "setup"
|
private const val SESSION_ENTRY_SETUP = "setup"
|
||||||
|
|
||||||
|
private enum class StopConfirmationAction {
|
||||||
|
BACK,
|
||||||
|
STOP_BUTTON,
|
||||||
|
}
|
||||||
|
|
||||||
private val MindMachineColors = darkColorScheme(
|
private val MindMachineColors = darkColorScheme(
|
||||||
primary = Color(0xFF8AB4FF),
|
primary = Color(0xFF8AB4FF),
|
||||||
onPrimary = Color(0xFF001B3D),
|
onPrimary = Color(0xFF001B3D),
|
||||||
@@ -483,9 +489,15 @@ fun ActiveSessionScreen(vm: MainViewModel, onFinish: () -> Unit, onBackToEntry:
|
|||||||
val ui by vm.ui.collectAsStateWithLifecycle()
|
val ui by vm.ui.collectAsStateWithLifecycle()
|
||||||
if (ui.runtimeState == RuntimeState.COMPLETED) onFinish()
|
if (ui.runtimeState == RuntimeState.COMPLETED) onFinish()
|
||||||
|
|
||||||
|
var stopConfirmationAction by remember { mutableStateOf<StopConfirmationAction?>(null) }
|
||||||
|
|
||||||
BackHandler {
|
BackHandler {
|
||||||
|
if (shouldRequireStopConfirmation(ui.runtimeState)) {
|
||||||
|
stopConfirmationAction = StopConfirmationAction.BACK
|
||||||
|
} else {
|
||||||
onBackToEntry()
|
onBackToEntry()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val isVisualMode = true
|
val isVisualMode = true
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
@@ -633,7 +645,17 @@ fun ActiveSessionScreen(vm: MainViewModel, onFinish: () -> Unit, onBackToEntry:
|
|||||||
} else {
|
} else {
|
||||||
Button(onClick = { vm.resume() }, modifier = Modifier.fillMaxWidth()) { Text("Resume") }
|
Button(onClick = { vm.resume() }, modifier = Modifier.fillMaxWidth()) { Text("Resume") }
|
||||||
}
|
}
|
||||||
OutlinedButton(onClick = { vm.stop(); onFinish() }, modifier = Modifier.fillMaxWidth()) { Text("Stop") }
|
OutlinedButton(
|
||||||
|
onClick = {
|
||||||
|
if (shouldRequireStopConfirmation(ui.runtimeState)) {
|
||||||
|
stopConfirmationAction = StopConfirmationAction.STOP_BUTTON
|
||||||
|
} else {
|
||||||
|
vm.stop()
|
||||||
|
onFinish()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
modifier = Modifier.fillMaxWidth()
|
||||||
|
) { Text("Stop") }
|
||||||
if (ui.interruptionReason != null) {
|
if (ui.interruptionReason != null) {
|
||||||
Text(ui.interruptionReason!!, color = Color.White)
|
Text(ui.interruptionReason!!, color = Color.White)
|
||||||
if (ui.runtimeState == RuntimeState.INTERRUPTED) {
|
if (ui.runtimeState == RuntimeState.INTERRUPTED) {
|
||||||
@@ -645,6 +667,36 @@ fun ActiveSessionScreen(vm: MainViewModel, onFinish: () -> Unit, onBackToEntry:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (stopConfirmationAction != null) {
|
||||||
|
AlertDialog(
|
||||||
|
onDismissRequest = { stopConfirmationAction = null },
|
||||||
|
title = { Text("End session?") },
|
||||||
|
text = { Text("Your current session will stop and return to the previous screen.") },
|
||||||
|
confirmButton = {
|
||||||
|
TextButton(
|
||||||
|
onClick = {
|
||||||
|
when (stopConfirmationAction) {
|
||||||
|
StopConfirmationAction.BACK -> onBackToEntry()
|
||||||
|
StopConfirmationAction.STOP_BUTTON -> {
|
||||||
|
vm.stop()
|
||||||
|
onFinish()
|
||||||
|
}
|
||||||
|
null -> Unit
|
||||||
|
}
|
||||||
|
stopConfirmationAction = null
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
Text("End session", color = Color(0xFFFF5252))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
dismissButton = {
|
||||||
|
TextButton(onClick = { stopConfirmationAction = null }) {
|
||||||
|
Text("Keep running")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
|
|||||||
@@ -11,3 +11,10 @@ fun sessionProgressFraction(durationSec: Int, remainingSec: Int): Float {
|
|||||||
val elapsed = (total - remainingSec).coerceIn(0, total)
|
val elapsed = (total - remainingSec).coerceIn(0, total)
|
||||||
return elapsed.toFloat() / total.toFloat()
|
return elapsed.toFloat() / total.toFloat()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun shouldRequireStopConfirmation(runtimeState: RuntimeState): Boolean {
|
||||||
|
return runtimeState == RuntimeState.COUNTDOWN ||
|
||||||
|
runtimeState == RuntimeState.RUNNING ||
|
||||||
|
runtimeState == RuntimeState.PAUSED ||
|
||||||
|
runtimeState == RuntimeState.INTERRUPTED
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package com.mindmachine.mvp
|
|||||||
|
|
||||||
import com.mindmachine.mvp.domain.RuntimeState
|
import com.mindmachine.mvp.domain.RuntimeState
|
||||||
import com.mindmachine.mvp.session.sessionProgressFraction
|
import com.mindmachine.mvp.session.sessionProgressFraction
|
||||||
|
import com.mindmachine.mvp.session.shouldRequireStopConfirmation
|
||||||
import com.mindmachine.mvp.session.shouldRevealSystemBarsOnTap
|
import com.mindmachine.mvp.session.shouldRevealSystemBarsOnTap
|
||||||
import com.mindmachine.mvp.session.shouldShowActiveControlsByDefault
|
import com.mindmachine.mvp.session.shouldShowActiveControlsByDefault
|
||||||
import com.mindmachine.mvp.session.shouldUseImmersiveFullscreen
|
import com.mindmachine.mvp.session.shouldUseImmersiveFullscreen
|
||||||
@@ -53,4 +54,16 @@ class ActiveSessionUiTest {
|
|||||||
assertTrue(sessionProgressFraction(durationSec = 600, remainingSec = 800) == 0f)
|
assertTrue(sessionProgressFraction(durationSec = 600, remainingSec = 800) == 0f)
|
||||||
assertTrue(sessionProgressFraction(durationSec = 600, remainingSec = -10) == 1f)
|
assertTrue(sessionProgressFraction(durationSec = 600, remainingSec = -10) == 1f)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun stop_confirmation_is_required_only_while_session_is_active_or_paused() {
|
||||||
|
assertTrue(shouldRequireStopConfirmation(RuntimeState.COUNTDOWN))
|
||||||
|
assertTrue(shouldRequireStopConfirmation(RuntimeState.RUNNING))
|
||||||
|
assertTrue(shouldRequireStopConfirmation(RuntimeState.PAUSED))
|
||||||
|
assertTrue(shouldRequireStopConfirmation(RuntimeState.INTERRUPTED))
|
||||||
|
|
||||||
|
assertFalse(shouldRequireStopConfirmation(RuntimeState.IDLE))
|
||||||
|
assertFalse(shouldRequireStopConfirmation(RuntimeState.COMPLETED))
|
||||||
|
assertFalse(shouldRequireStopConfirmation(RuntimeState.STOPPED))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user