Auto commit Sat Mar 21 11:01:02 PM CDT 2026

This commit is contained in:
Tretzi
2026-03-21 23:01:02 -05:00
parent 5c48387dc2
commit 869c98a47c
11 changed files with 354 additions and 104 deletions

View File

@@ -32,12 +32,10 @@ import androidx.compose.material3.Button
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.Checkbox
import androidx.compose.material3.DropdownMenu
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.ExposedDropdownMenuBox
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.LinearProgressIndicator
import androidx.compose.material3.OutlinedButton
import androidx.compose.material3.SegmentedButton
import androidx.compose.material3.SingleChoiceSegmentedButtonRow
@@ -79,7 +77,6 @@ import com.mindmachine.mvp.audio.BinauralAudioEngine
import com.mindmachine.mvp.audio.HeadsetMonitor
import com.mindmachine.mvp.data.SettingsRepository
import com.mindmachine.mvp.data.UserProgramRepository
import com.mindmachine.mvp.domain.CountdownPreference
import com.mindmachine.mvp.domain.RuntimeState
import com.mindmachine.mvp.domain.SessionMode
import com.mindmachine.mvp.session.FlashColor
@@ -88,7 +85,7 @@ import com.mindmachine.mvp.session.SplitFlashFrame
import com.mindmachine.mvp.session.computeSplitFlashFrame
import com.mindmachine.mvp.session.flashIntervalMsToSeconds
import com.mindmachine.mvp.session.flashIntervalSecondsToMs
import com.mindmachine.mvp.session.shouldRevealSystemBarsOnTap
import com.mindmachine.mvp.session.sessionProgressFraction
import com.mindmachine.mvp.session.shouldShowActiveControlsByDefault
import com.mindmachine.mvp.session.shouldUseImmersiveFullscreen
import kotlinx.coroutines.delay
@@ -196,9 +193,7 @@ fun App(vm: MainViewModel = viewModel()) {
Text(p.description)
Text("${p.defaultDurationSec / 60} min • ${p.visualPatternType} • binaural ${p.binauralDifferenceHz}")
}
if (p.isUserProgram) {
TextButton(onClick = { vm.deleteProgram(p.id) }) { Text("Delete") }
}
TextButton(onClick = { vm.deleteProgram(p.id) }) { Text("Delete") }
}
}
}
@@ -380,14 +375,18 @@ fun ActiveSessionScreen(vm: MainViewModel, onFinish: () -> Unit, onBackToSetup:
flashOffMs = ui.runtimeParams.flashOffMs,
)
val progress = sessionProgressFraction(
durationSec = ui.timeline.durationSec,
remainingSec = ui.remainingSec,
)
Box(
modifier = Modifier
.fillMaxSize()
.background(Color.Black)
.clickable {
showOverlay = !showOverlay
if (shouldRevealSystemBarsOnTap(isVisualMode, ui.runtimeState)) {
revealSystemBarsSignal += 1
if (!immersiveFullscreen) {
showOverlay = !showOverlay
}
}
) {
@@ -416,6 +415,19 @@ fun ActiveSessionScreen(vm: MainViewModel, onFinish: () -> Unit, onBackToSetup:
color = Color.White
)
}
if (immersiveFullscreen && ui.settings.showImmersiveProgressBar) {
LinearProgressIndicator(
progress = { progress },
modifier = Modifier
.align(Alignment.BottomCenter)
.fillMaxWidth()
.height(5.dp),
trackColor = Color.White.copy(alpha = 0.2f),
color = Color.White,
)
}
if (showOverlay) {
Column(
Modifier
@@ -503,35 +515,40 @@ private fun rememberSplitFlashFrame(
}
}
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun SettingsScreen(vm: MainViewModel, onBack: () -> Unit) {
val ui by vm.ui.collectAsStateWithLifecycle()
var expanded by remember { mutableStateOf(false) }
Column(
Modifier.fillMaxSize().background(MaterialTheme.colorScheme.background).padding(16.dp),
verticalArrangement = Arrangement.spacedBy(12.dp)
) {
Text("Settings", style = MaterialTheme.typography.headlineSmall, color = MaterialTheme.colorScheme.onBackground)
Text("Countdown", color = MaterialTheme.colorScheme.onBackground)
ExposedDropdownMenuBox(expanded = expanded, onExpandedChange = { expanded = it }) {
TextButton(onClick = { expanded = true }) { Text(ui.settings.countdownPreference.name) }
DropdownMenu(expanded = expanded, onDismissRequest = { expanded = false }) {
CountdownPreference.values().forEach {
DropdownMenuItem(text = { Text(it.name) }, onClick = { vm.updateCountdown(it); expanded = false })
}
}
}
Text("Countdown: ${ui.settings.countdownSeconds}s", color = MaterialTheme.colorScheme.onBackground)
Slider(
value = ui.settings.countdownSeconds.toFloat(),
onValueChange = { vm.updateCountdownSeconds(it.roundToInt()) },
valueRange = 0f..10f,
steps = 9,
)
Text("Default mode", color = MaterialTheme.colorScheme.onBackground)
Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
SessionMode.values().forEach { mode ->
OutlinedButton(onClick = { vm.updateDefaultMode(mode) }) { Text(mode.name) }
}
}
Row(verticalAlignment = Alignment.CenterVertically) {
Checkbox(checked = ui.settings.showHolderGuidanceBeforeSession, onCheckedChange = vm::updateGuidance)
Text("Show holder guidance before session", color = MaterialTheme.colorScheme.onBackground)
}
Row(verticalAlignment = Alignment.CenterVertically) {
Checkbox(checked = ui.settings.showImmersiveProgressBar, onCheckedChange = vm::updateShowImmersiveProgressBar)
Text("Show immersive bottom progress bar", color = MaterialTheme.colorScheme.onBackground)
}
HorizontalDivider()
Text("About/Disclaimer: MindMachine is a prototype and not a medical device.", color = MaterialTheme.colorScheme.onBackground)
OutlinedButton(onClick = onBack) { Text("Back") }