Auto commit Tue Mar 24 05:01:02 PM CDT 2026
This commit is contained in:
@@ -11,6 +11,7 @@ import androidx.compose.foundation.background
|
|||||||
import com.mindmachine.mvp.session.DurationSliderCard
|
import com.mindmachine.mvp.session.DurationSliderCard
|
||||||
import com.mindmachine.mvp.session.SetupTimelineEditor
|
import com.mindmachine.mvp.session.SetupTimelineEditor
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.clickable
|
||||||
|
import androidx.compose.foundation.gestures.detectTapGestures
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
@@ -59,6 +60,7 @@ import androidx.compose.runtime.withFrameNanos
|
|||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.input.pointer.pointerInput
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.platform.LocalLifecycleOwner
|
import androidx.compose.ui.platform.LocalLifecycleOwner
|
||||||
import androidx.compose.ui.semantics.contentDescription
|
import androidx.compose.ui.semantics.contentDescription
|
||||||
@@ -405,6 +407,20 @@ fun ActiveSessionScreen(vm: MainViewModel, onFinish: () -> Unit, onBackToSetup:
|
|||||||
LaunchedEffect(ui.runtimeState) {
|
LaunchedEffect(ui.runtimeState) {
|
||||||
showOverlay = shouldShowActiveControlsByDefault(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(
|
val flashFrame by rememberSplitFlashFrame(
|
||||||
isRunning = ui.runtimeState == RuntimeState.RUNNING,
|
isRunning = ui.runtimeState == RuntimeState.RUNNING,
|
||||||
flashOnMs = ui.runtimeParams.flashOnMs,
|
flashOnMs = ui.runtimeParams.flashOnMs,
|
||||||
@@ -420,11 +436,15 @@ fun ActiveSessionScreen(vm: MainViewModel, onFinish: () -> Unit, onBackToSetup:
|
|||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
.background(Color.Black)
|
.background(Color.Black)
|
||||||
.clickable {
|
.pointerInput(immersiveFullscreen) {
|
||||||
|
detectTapGestures {
|
||||||
|
brightnessOverlayVisible = true
|
||||||
|
brightnessOverlayToken++
|
||||||
if (!immersiveFullscreen) {
|
if (!immersiveFullscreen) {
|
||||||
showOverlay = !showOverlay
|
showOverlay = !showOverlay
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
) {
|
) {
|
||||||
if (isVisualMode) {
|
if (isVisualMode) {
|
||||||
Row(Modifier.fillMaxSize()) {
|
Row(Modifier.fillMaxSize()) {
|
||||||
@@ -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) {
|
if (showOverlay) {
|
||||||
Column(
|
Column(
|
||||||
Modifier
|
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
|
@Composable
|
||||||
private fun ApplyImmersiveMode(enabled: Boolean, revealSignal: Int) {
|
private fun ApplyImmersiveMode(enabled: Boolean, revealSignal: Int) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ class SettingsRepository(private val context: Context) {
|
|||||||
val countdownSeconds = intPreferencesKey("countdown_seconds")
|
val countdownSeconds = intPreferencesKey("countdown_seconds")
|
||||||
val forceAudioWithoutHeadphones = booleanPreferencesKey("force_audio_without_headphones")
|
val forceAudioWithoutHeadphones = booleanPreferencesKey("force_audio_without_headphones")
|
||||||
val showImmersiveProgressBar = booleanPreferencesKey("show_immersive_progress_bar")
|
val showImmersiveProgressBar = booleanPreferencesKey("show_immersive_progress_bar")
|
||||||
|
val immersiveBrightnessPercent = intPreferencesKey("immersive_brightness_percent")
|
||||||
val lastPresetId = stringPreferencesKey("last_preset")
|
val lastPresetId = stringPreferencesKey("last_preset")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -32,6 +33,7 @@ class SettingsRepository(private val context: Context) {
|
|||||||
?: 5,
|
?: 5,
|
||||||
forceAudioWithoutHeadphones = p[Keys.forceAudioWithoutHeadphones] ?: false,
|
forceAudioWithoutHeadphones = p[Keys.forceAudioWithoutHeadphones] ?: false,
|
||||||
showImmersiveProgressBar = p[Keys.showImmersiveProgressBar] ?: true,
|
showImmersiveProgressBar = p[Keys.showImmersiveProgressBar] ?: true,
|
||||||
|
immersiveBrightnessPercent = (p[Keys.immersiveBrightnessPercent] ?: 100).coerceIn(5, 100),
|
||||||
lastPresetId = p[Keys.lastPresetId],
|
lastPresetId = p[Keys.lastPresetId],
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -55,6 +57,10 @@ class SettingsRepository(private val context: Context) {
|
|||||||
it[Keys.showImmersiveProgressBar] = value
|
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 }
|
suspend fun updateLastPreset(id: String) = context.dataStore.edit { it[Keys.lastPresetId] = id }
|
||||||
|
|
||||||
private fun legacyCountdownStringToSeconds(raw: String?): Int? = when (raw) {
|
private fun legacyCountdownStringToSeconds(raw: String?): Int? = when (raw) {
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ data class AppSettings(
|
|||||||
val countdownSeconds: Int = 5,
|
val countdownSeconds: Int = 5,
|
||||||
val forceAudioWithoutHeadphones: Boolean = false,
|
val forceAudioWithoutHeadphones: Boolean = false,
|
||||||
val showImmersiveProgressBar: Boolean = true,
|
val showImmersiveProgressBar: Boolean = true,
|
||||||
|
val immersiveBrightnessPercent: Int = 100,
|
||||||
val lastPresetId: String? = null,
|
val lastPresetId: String? = null,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -295,6 +295,9 @@ class MainViewModel(
|
|||||||
settingsRepository.updateForceAudioWithoutHeadphones(value)
|
settingsRepository.updateForceAudioWithoutHeadphones(value)
|
||||||
}
|
}
|
||||||
fun updateShowImmersiveProgressBar(value: Boolean) = viewModelScope.launch { settingsRepository.updateShowImmersiveProgressBar(value) }
|
fun updateShowImmersiveProgressBar(value: Boolean) = viewModelScope.launch { settingsRepository.updateShowImmersiveProgressBar(value) }
|
||||||
|
fun updateImmersiveBrightnessPercent(value: Int) = viewModelScope.launch {
|
||||||
|
settingsRepository.updateImmersiveBrightnessPercent(value)
|
||||||
|
}
|
||||||
|
|
||||||
fun startSession(): Boolean {
|
fun startSession(): Boolean {
|
||||||
val state = _ui.value
|
val state = _ui.value
|
||||||
|
|||||||
Reference in New Issue
Block a user