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:
6 files changed
+57
No files matched your search
@@ -31,6 +31,7 @@ kotlin {
|
||||
api(libs.compose.foundation)
|
||||
api(libs.compose.ui.tooling.preview)
|
||||
api(libs.compose.material3)
|
||||
api(libs.compose.backhandler)
|
||||
implementation(libs.kotlinx.datetime)
|
||||
implementation(libs.kotlinx.serialization.json)
|
||||
implementation(libs.kotlinx.coroutines.core)
|
||||
|
||||
@@ -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())
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user