MindMachine: add immersive fullscreen and tap-to-reveal bars
This commit is contained in:
@@ -48,6 +48,7 @@ import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.DisposableEffect
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableIntStateOf
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.produceState
|
||||
import androidx.compose.runtime.remember
|
||||
@@ -61,6 +62,9 @@ import androidx.compose.ui.platform.LocalLifecycleOwner
|
||||
import androidx.compose.ui.semantics.contentDescription
|
||||
import androidx.compose.ui.semantics.semantics
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.core.view.WindowCompat
|
||||
import androidx.core.view.WindowInsetsCompat
|
||||
import androidx.core.view.WindowInsetsControllerCompat
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.LifecycleEventObserver
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
@@ -80,7 +84,10 @@ 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.shouldShowActiveControlsByDefault
|
||||
import com.mindmachine.mvp.session.shouldUseImmersiveFullscreen
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
private val MindMachineColors = darkColorScheme(
|
||||
@@ -320,6 +327,13 @@ fun ActiveSessionScreen(vm: MainViewModel, onFinish: () -> Unit, onBackToSetup:
|
||||
}
|
||||
}
|
||||
|
||||
val immersiveFullscreen = shouldUseImmersiveFullscreen(isVisualMode, ui.runtimeState)
|
||||
var revealSystemBarsSignal by remember { mutableIntStateOf(0) }
|
||||
ApplyImmersiveMode(
|
||||
enabled = immersiveFullscreen,
|
||||
revealSignal = revealSystemBarsSignal,
|
||||
)
|
||||
|
||||
var showOverlay by remember(ui.runtimeState) { mutableStateOf(shouldShowActiveControlsByDefault(ui.runtimeState)) }
|
||||
LaunchedEffect(ui.runtimeState) {
|
||||
showOverlay = shouldShowActiveControlsByDefault(ui.runtimeState)
|
||||
@@ -334,7 +348,12 @@ fun ActiveSessionScreen(vm: MainViewModel, onFinish: () -> Unit, onBackToSetup:
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.background(Color.Black)
|
||||
.clickable { showOverlay = !showOverlay }
|
||||
.clickable {
|
||||
showOverlay = !showOverlay
|
||||
if (shouldRevealSystemBarsOnTap(isVisualMode, ui.runtimeState)) {
|
||||
revealSystemBarsSignal += 1
|
||||
}
|
||||
}
|
||||
) {
|
||||
if (isVisualMode) {
|
||||
Row(Modifier.fillMaxSize()) {
|
||||
@@ -389,6 +408,41 @@ fun ActiveSessionScreen(vm: MainViewModel, onFinish: () -> Unit, onBackToSetup:
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ApplyImmersiveMode(enabled: Boolean, revealSignal: Int) {
|
||||
val context = LocalContext.current
|
||||
val activity = context as? Activity ?: return
|
||||
val window = activity.window
|
||||
val controller = remember(window) { WindowInsetsControllerCompat(window, window.decorView) }
|
||||
|
||||
DisposableEffect(window) {
|
||||
onDispose {
|
||||
controller.show(WindowInsetsCompat.Type.systemBars())
|
||||
WindowCompat.setDecorFitsSystemWindows(window, true)
|
||||
}
|
||||
}
|
||||
|
||||
LaunchedEffect(enabled) {
|
||||
if (enabled) {
|
||||
WindowCompat.setDecorFitsSystemWindows(window, false)
|
||||
controller.systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
|
||||
controller.hide(WindowInsetsCompat.Type.systemBars())
|
||||
} else {
|
||||
controller.show(WindowInsetsCompat.Type.systemBars())
|
||||
WindowCompat.setDecorFitsSystemWindows(window, true)
|
||||
}
|
||||
}
|
||||
|
||||
LaunchedEffect(revealSignal, enabled) {
|
||||
if (!enabled || revealSignal == 0) return@LaunchedEffect
|
||||
controller.show(WindowInsetsCompat.Type.systemBars())
|
||||
delay(2500)
|
||||
if (enabled) {
|
||||
controller.hide(WindowInsetsCompat.Type.systemBars())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun FlashColor.toComposeColor(): Color = when (this) {
|
||||
FlashColor.RED -> Color.Red
|
||||
FlashColor.GREEN -> Color.Green
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.mindmachine.mvp.session
|
||||
|
||||
import com.mindmachine.mvp.domain.RuntimeState
|
||||
|
||||
fun shouldUseImmersiveFullscreen(isVisualMode: Boolean, runtimeState: RuntimeState): Boolean {
|
||||
return isVisualMode && (runtimeState == RuntimeState.COUNTDOWN || runtimeState == RuntimeState.RUNNING)
|
||||
}
|
||||
|
||||
fun shouldRevealSystemBarsOnTap(isVisualMode: Boolean, runtimeState: RuntimeState): Boolean {
|
||||
return shouldUseImmersiveFullscreen(isVisualMode, runtimeState)
|
||||
}
|
||||
Reference in New Issue
Block a user