nav: fix blank back-gesture preview — let navigation drive predictive back
The per-screen Modifier.predictiveBack scaled the leaving screen with a graphicsLayer, but NavHost only composes one back-stack entry at a time, so nothing was drawn behind the shrinking screen — the gesture revealed the white window background instead of the previous screen. Drive predictive back through navigation-compose instead: it composes the destination being revealed and seeks popExit with the gesture. popExit is now a scaleOut + fade peek, so the leaving screen shrinks to reveal the real previous screen held static. Drops the predictiveBack modifier from the destinations and Settings (its inner section BackHandler is unchanged). The kit's predictiveBack stays for overlay-style screens. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,9 +1,10 @@
|
||||
package de.jeanlucmakiola.agendula.ui.navigation
|
||||
|
||||
import de.jeanlucmakiola.floret.identity.predictiveBack
|
||||
import androidx.compose.animation.EnterTransition
|
||||
import androidx.compose.animation.ExitTransition
|
||||
import androidx.compose.animation.fadeIn
|
||||
import androidx.compose.animation.fadeOut
|
||||
import androidx.compose.animation.scaleOut
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.ui.Modifier
|
||||
@@ -40,14 +41,13 @@ fun AgendulaNavHost(modifier: Modifier = Modifier) {
|
||||
modifier = modifier,
|
||||
// Only the screen on top moves; the background is always held static.
|
||||
// Forward is a plain fade-in over the held screen — calm, not a slide.
|
||||
// Back is the system predictive-back peek: each destination applies
|
||||
// Modifier.predictiveBack, so the leaving screen scales/rounds with the
|
||||
// gesture and the held screen is revealed unmoved. NavHost itself does no
|
||||
// pop animation (the screen owns the motion).
|
||||
// Back is the predictive-back peek: navigation-compose composes the
|
||||
// screen being revealed underneath and seeks popExit with the gesture, so
|
||||
// the leaving screen scales down to reveal the (unmoved) previous screen.
|
||||
enterTransition = { fadeIn() },
|
||||
exitTransition = { ExitTransition.None },
|
||||
popEnterTransition = { EnterTransition.None },
|
||||
popExitTransition = { ExitTransition.None },
|
||||
popExitTransition = { scaleOut(targetScale = 0.9f) + fadeOut() },
|
||||
) {
|
||||
composable(Dest.LISTS) {
|
||||
ListsScreen(
|
||||
@@ -71,7 +71,6 @@ fun AgendulaNavHost(modifier: Modifier = Modifier) {
|
||||
LaunchedEffect(filter) { vm.bind(filter) }
|
||||
|
||||
TaskListScreen(
|
||||
modifier = Modifier.predictiveBack(onBack = { nav.popBackStack() }),
|
||||
filter = filter,
|
||||
viewModel = vm,
|
||||
onOpenTask = { taskId -> nav.navigate(Dest.TaskDetail.build(taskId)) },
|
||||
@@ -89,7 +88,6 @@ fun AgendulaNavHost(modifier: Modifier = Modifier) {
|
||||
LaunchedEffect(taskId) { vm.bind(taskId) }
|
||||
|
||||
TaskDetailScreen(
|
||||
modifier = Modifier.predictiveBack(onBack = { nav.popBackStack() }),
|
||||
viewModel = vm,
|
||||
onEdit = { nav.navigate(Dest.TaskEdit.buildEdit(taskId)) },
|
||||
onDeleted = { nav.popBackStack() },
|
||||
@@ -118,7 +116,6 @@ fun AgendulaNavHost(modifier: Modifier = Modifier) {
|
||||
}
|
||||
|
||||
TaskEditScreen(
|
||||
modifier = Modifier.predictiveBack(onBack = { nav.popBackStack() }),
|
||||
viewModel = vm,
|
||||
onSaved = { nav.popBackStack() },
|
||||
onBack = { nav.popBackStack() },
|
||||
|
||||
@@ -93,7 +93,6 @@ import de.jeanlucmakiola.floret.components.pastelize
|
||||
import de.jeanlucmakiola.floret.components.positionOf
|
||||
import de.jeanlucmakiola.floret.identity.collapseExit
|
||||
import de.jeanlucmakiola.floret.identity.expandEnter
|
||||
import de.jeanlucmakiola.floret.identity.predictiveBack
|
||||
import de.jeanlucmakiola.floret.reminders.ReminderOverride
|
||||
import de.jeanlucmakiola.agendula.ui.common.reminderLeadTimeLabel
|
||||
|
||||
@@ -128,9 +127,6 @@ fun SettingsScreen(
|
||||
|
||||
Box(
|
||||
modifier = modifier
|
||||
// At the hub, the back gesture previews the pop to the lists overview;
|
||||
// in a section the BackHandler above takes it (section -> hub) instead.
|
||||
.predictiveBack(onBack = onBack, enabled = section == null)
|
||||
.fillMaxSize()
|
||||
.background(MaterialTheme.colorScheme.surface),
|
||||
) {
|
||||
|
||||
Reference in New Issue
Block a user