From 2a548edc9a25919fb6d75887d47718b95c47f2b7 Mon Sep 17 00:00:00 2001 From: Tretzi Date: Tue, 24 Mar 2026 17:01:02 -0500 Subject: [PATCH] Auto commit Tue Mar 24 05:01:02 PM CDT 2026 --- .../java/com/mindmachine/mvp/MainActivity.kt | 76 ++++++++++++++++++- .../mvp/data/SettingsRepository.kt | 6 ++ .../java/com/mindmachine/mvp/domain/Models.kt | 1 + .../mindmachine/mvp/session/MainViewModel.kt | 3 + 4 files changed, 83 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/mindmachine/mvp/MainActivity.kt b/app/src/main/java/com/mindmachine/mvp/MainActivity.kt index caaa0ca..f49b0d6 100644 --- a/app/src/main/java/com/mindmachine/mvp/MainActivity.kt +++ b/app/src/main/java/com/mindmachine/mvp/MainActivity.kt @@ -11,6 +11,7 @@ import androidx.compose.foundation.background import com.mindmachine.mvp.session.DurationSliderCard import com.mindmachine.mvp.session.SetupTimelineEditor import androidx.compose.foundation.clickable +import androidx.compose.foundation.gestures.detectTapGestures import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column @@ -59,6 +60,7 @@ import androidx.compose.runtime.withFrameNanos import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color +import androidx.compose.ui.input.pointer.pointerInput import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalLifecycleOwner import androidx.compose.ui.semantics.contentDescription @@ -405,6 +407,20 @@ fun ActiveSessionScreen(vm: MainViewModel, onFinish: () -> Unit, onBackToSetup: LaunchedEffect(ui.runtimeState) { showOverlay = shouldShowActiveControlsByDefault(ui.runtimeState) } + var brightnessOverlayVisible by remember { mutableStateOf(false) } + var brightnessOverlayToken by remember { mutableIntStateOf(0) } + + LaunchedEffect(brightnessOverlayToken) { + if (!brightnessOverlayVisible) return@LaunchedEffect + delay(2500) + brightnessOverlayVisible = false + } + + ApplyScreenBrightnessOverride( + enabled = true, + brightnessPercent = ui.settings.immersiveBrightnessPercent, + ) + val flashFrame by rememberSplitFlashFrame( isRunning = ui.runtimeState == RuntimeState.RUNNING, flashOnMs = ui.runtimeParams.flashOnMs, @@ -420,9 +436,13 @@ fun ActiveSessionScreen(vm: MainViewModel, onFinish: () -> Unit, onBackToSetup: modifier = Modifier .fillMaxSize() .background(Color.Black) - .clickable { - if (!immersiveFullscreen) { - showOverlay = !showOverlay + .pointerInput(immersiveFullscreen) { + detectTapGestures { + brightnessOverlayVisible = true + brightnessOverlayToken++ + if (!immersiveFullscreen) { + showOverlay = !showOverlay + } } } ) { @@ -464,6 +484,32 @@ fun ActiveSessionScreen(vm: MainViewModel, onFinish: () -> Unit, onBackToSetup: ) } + if (brightnessOverlayVisible) { + Column( + Modifier + .align(Alignment.TopCenter) + .padding(top = 24.dp) + .fillMaxWidth(0.45f) + .background(Color.Black.copy(alpha = 0.72f)) + .padding(horizontal = 12.dp, vertical = 10.dp) + ) { + Text( + text = "Brightness ${ui.settings.immersiveBrightnessPercent}%", + color = Color.White, + style = MaterialTheme.typography.bodyMedium, + ) + Slider( + value = ui.settings.immersiveBrightnessPercent.toFloat(), + onValueChange = { + vm.updateImmersiveBrightnessPercent(it.roundToInt()) + brightnessOverlayVisible = true + brightnessOverlayToken++ + }, + valueRange = 5f..100f, + ) + } + } + if (showOverlay) { Column( Modifier @@ -492,6 +538,30 @@ fun ActiveSessionScreen(vm: MainViewModel, onFinish: () -> Unit, onBackToSetup: } } +@Composable +private fun ApplyScreenBrightnessOverride(enabled: Boolean, brightnessPercent: Int) { + val activity = LocalContext.current as? Activity ?: return + val window = activity.window + + DisposableEffect(window) { + onDispose { + val reset = window.attributes + reset.screenBrightness = -1f + window.attributes = reset + } + } + + LaunchedEffect(enabled, brightnessPercent) { + val params = window.attributes + params.screenBrightness = if (enabled) { + (brightnessPercent.coerceIn(5, 100) / 100f) + } else { + -1f + } + window.attributes = params + } +} + @Composable private fun ApplyImmersiveMode(enabled: Boolean, revealSignal: Int) { val context = LocalContext.current diff --git a/app/src/main/java/com/mindmachine/mvp/data/SettingsRepository.kt b/app/src/main/java/com/mindmachine/mvp/data/SettingsRepository.kt index c81bb3a..ef4dbce 100644 --- a/app/src/main/java/com/mindmachine/mvp/data/SettingsRepository.kt +++ b/app/src/main/java/com/mindmachine/mvp/data/SettingsRepository.kt @@ -20,6 +20,7 @@ class SettingsRepository(private val context: Context) { val countdownSeconds = intPreferencesKey("countdown_seconds") val forceAudioWithoutHeadphones = booleanPreferencesKey("force_audio_without_headphones") val showImmersiveProgressBar = booleanPreferencesKey("show_immersive_progress_bar") + val immersiveBrightnessPercent = intPreferencesKey("immersive_brightness_percent") val lastPresetId = stringPreferencesKey("last_preset") } @@ -32,6 +33,7 @@ class SettingsRepository(private val context: Context) { ?: 5, forceAudioWithoutHeadphones = p[Keys.forceAudioWithoutHeadphones] ?: false, showImmersiveProgressBar = p[Keys.showImmersiveProgressBar] ?: true, + immersiveBrightnessPercent = (p[Keys.immersiveBrightnessPercent] ?: 100).coerceIn(5, 100), lastPresetId = p[Keys.lastPresetId], ) } @@ -55,6 +57,10 @@ class SettingsRepository(private val context: Context) { it[Keys.showImmersiveProgressBar] = value } + suspend fun updateImmersiveBrightnessPercent(value: Int) = context.dataStore.edit { + it[Keys.immersiveBrightnessPercent] = value.coerceIn(5, 100) + } + suspend fun updateLastPreset(id: String) = context.dataStore.edit { it[Keys.lastPresetId] = id } private fun legacyCountdownStringToSeconds(raw: String?): Int? = when (raw) { diff --git a/app/src/main/java/com/mindmachine/mvp/domain/Models.kt b/app/src/main/java/com/mindmachine/mvp/domain/Models.kt index f505462..29d1d2b 100644 --- a/app/src/main/java/com/mindmachine/mvp/domain/Models.kt +++ b/app/src/main/java/com/mindmachine/mvp/domain/Models.kt @@ -36,6 +36,7 @@ data class AppSettings( val countdownSeconds: Int = 5, val forceAudioWithoutHeadphones: Boolean = false, val showImmersiveProgressBar: Boolean = true, + val immersiveBrightnessPercent: Int = 100, val lastPresetId: String? = null, ) diff --git a/app/src/main/java/com/mindmachine/mvp/session/MainViewModel.kt b/app/src/main/java/com/mindmachine/mvp/session/MainViewModel.kt index 15e45c5..a7a0256 100644 --- a/app/src/main/java/com/mindmachine/mvp/session/MainViewModel.kt +++ b/app/src/main/java/com/mindmachine/mvp/session/MainViewModel.kt @@ -295,6 +295,9 @@ class MainViewModel( settingsRepository.updateForceAudioWithoutHeadphones(value) } fun updateShowImmersiveProgressBar(value: Boolean) = viewModelScope.launch { settingsRepository.updateShowImmersiveProgressBar(value) } + fun updateImmersiveBrightnessPercent(value: Int) = viewModelScope.launch { + settingsRepository.updateImmersiveBrightnessPercent(value) + } fun startSession(): Boolean { val state = _ui.value