fix: intercepter le back système pour revenir à l'accueil

Le geste back Android part du bord même de l'écran : l'OS intercepte
le geste avant le SwipeBack custom (zone de départ > 24 dp) et, sans
callback back enregistré, l'activité est envoyée en arrière-plan vers
le launcher au lieu de revenir à l'écran précédent. Enregistre un
BackHandler par écran (Historique et Résultats retournent à l'accueil,
la partie ouvre le dialogue d'abandon) et active le predictive back
dans le manifest.
This commit is contained in:
herel committed 2026-08-31 09:10:48 +02:00
1 parent b3fde748d2
commit bd070ba3a4
6 files changed
+57

No files matched your search

@@ -7,6 +7,7 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.backhandler.BackHandler
import com.livrets.data.HistoryRepository
import com.livrets.game.GameConfig
import com.livrets.game.GameResult
@@ -32,6 +33,13 @@ sealed interface Screen {
data object History : Screen
}
fun Screen.backTarget(): Screen? = when (this) {
Screen.Home -> null
is Screen.Game -> null
is Screen.Results -> Screen.Home
Screen.History -> Screen.Home
}
@Composable
fun App(
filesDirPath: String,
@@ -48,6 +56,11 @@ fun App(
HomeScreen(onPlay = {}, onHistory = {}, onLeaderboard = {})
}
screen.backTarget()?.let { target ->
@OptIn(androidx.compose.ui.ExperimentalComposeUiApi::class)
BackHandler { screen = target }
}
when (val current = screen) {
Screen.Home -> HomeScreen(
onPlay = { config -> screen = Screen.Game(config) },
@@ -30,6 +30,7 @@ import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.backhandler.BackHandler
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
@@ -52,6 +53,8 @@ fun GameScreen(
LaunchedEffect(engine) { engine.start() }
var showQuitDialog by remember { mutableStateOf(false) }
@OptIn(androidx.compose.ui.ExperimentalComposeUiApi::class)
BackHandler { showQuitDialog = true }
if (showQuitDialog) {
AlertDialog(
onDismissRequest = { showQuitDialog = false },
@@ -0,0 +1,38 @@
package com.livrets
import com.livrets.game.GameConfig
import com.livrets.game.GameResult
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertNull
class BackNavigationTest {
private val config = GameConfig(questionCount = 10, secondsPerQuestion = 5, maxTable = 10)
private val result = GameResult(
date = kotlin.time.Instant.fromEpochMilliseconds(0L),
config = config,
records = emptyList(),
)
@Test
fun `back depuis l historique ramene a l accueil`() {
assertEquals(Screen.Home, Screen.History.backTarget())
}
@Test
fun `back depuis les resultats ramene a l accueil`() {
assertEquals(Screen.Home, Screen.Results(result).backTarget())
}
@Test
fun `pas de navigation back depuis l accueil`() {
assertNull(Screen.Home.backTarget())
}
@Test
fun `pas de navigation back depuis une partie`() {
assertNull(Screen.Game(config).backTarget())
}
}