nav: swap the full slide-back for the predictive-back peek
Back was a full-width horizontal slide-off — too heavy. Replace it with floret-kit's Modifier.predictiveBack on each pop-able destination (task list, detail, edit) so the leaving screen scales/rounds with the gesture and the held screen is revealed unmoved; NavHost now does no pop animation. Settings applies it at the hub only (enabled = section == null) so its inner section back still returns to the hub. Forward stays a calm fade-in. Bumps the floret-kit submodule. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,11 +1,9 @@
|
|||||||
package de.jeanlucmakiola.agendula.ui.navigation
|
package de.jeanlucmakiola.agendula.ui.navigation
|
||||||
|
|
||||||
import de.jeanlucmakiola.floret.identity.rememberNavSlideSpec
|
import de.jeanlucmakiola.floret.identity.predictiveBack
|
||||||
import androidx.compose.animation.EnterTransition
|
import androidx.compose.animation.EnterTransition
|
||||||
import androidx.compose.animation.ExitTransition
|
import androidx.compose.animation.ExitTransition
|
||||||
import androidx.compose.animation.fadeIn
|
import androidx.compose.animation.fadeIn
|
||||||
import androidx.compose.animation.fadeOut
|
|
||||||
import androidx.compose.animation.slideOutHorizontally
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
@@ -35,7 +33,6 @@ import de.jeanlucmakiola.agendula.ui.tasklist.TaskListViewModel
|
|||||||
@Composable
|
@Composable
|
||||||
fun AgendulaNavHost(modifier: Modifier = Modifier) {
|
fun AgendulaNavHost(modifier: Modifier = Modifier) {
|
||||||
val nav = rememberNavController()
|
val nav = rememberNavController()
|
||||||
val slide = rememberNavSlideSpec()
|
|
||||||
|
|
||||||
NavHost(
|
NavHost(
|
||||||
navController = nav,
|
navController = nav,
|
||||||
@@ -43,12 +40,14 @@ fun AgendulaNavHost(modifier: Modifier = Modifier) {
|
|||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
// Only the screen on top moves; the background is always held static.
|
// 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.
|
// Forward is a plain fade-in over the held screen — calm, not a slide.
|
||||||
// Back (and the predictive-back drag, which drives popExit) is the snappy
|
// Back is the system predictive-back peek: each destination applies
|
||||||
// slide-out to the right, revealing the held screen unmoved.
|
// 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).
|
||||||
enterTransition = { fadeIn() },
|
enterTransition = { fadeIn() },
|
||||||
exitTransition = { ExitTransition.None },
|
exitTransition = { ExitTransition.None },
|
||||||
popEnterTransition = { EnterTransition.None },
|
popEnterTransition = { EnterTransition.None },
|
||||||
popExitTransition = { slideOutHorizontally(slide) { it } + fadeOut() },
|
popExitTransition = { ExitTransition.None },
|
||||||
) {
|
) {
|
||||||
composable(Dest.LISTS) {
|
composable(Dest.LISTS) {
|
||||||
ListsScreen(
|
ListsScreen(
|
||||||
@@ -72,6 +71,7 @@ fun AgendulaNavHost(modifier: Modifier = Modifier) {
|
|||||||
LaunchedEffect(filter) { vm.bind(filter) }
|
LaunchedEffect(filter) { vm.bind(filter) }
|
||||||
|
|
||||||
TaskListScreen(
|
TaskListScreen(
|
||||||
|
modifier = Modifier.predictiveBack(onBack = { nav.popBackStack() }),
|
||||||
filter = filter,
|
filter = filter,
|
||||||
viewModel = vm,
|
viewModel = vm,
|
||||||
onOpenTask = { taskId -> nav.navigate(Dest.TaskDetail.build(taskId)) },
|
onOpenTask = { taskId -> nav.navigate(Dest.TaskDetail.build(taskId)) },
|
||||||
@@ -89,6 +89,7 @@ fun AgendulaNavHost(modifier: Modifier = Modifier) {
|
|||||||
LaunchedEffect(taskId) { vm.bind(taskId) }
|
LaunchedEffect(taskId) { vm.bind(taskId) }
|
||||||
|
|
||||||
TaskDetailScreen(
|
TaskDetailScreen(
|
||||||
|
modifier = Modifier.predictiveBack(onBack = { nav.popBackStack() }),
|
||||||
viewModel = vm,
|
viewModel = vm,
|
||||||
onEdit = { nav.navigate(Dest.TaskEdit.buildEdit(taskId)) },
|
onEdit = { nav.navigate(Dest.TaskEdit.buildEdit(taskId)) },
|
||||||
onDeleted = { nav.popBackStack() },
|
onDeleted = { nav.popBackStack() },
|
||||||
@@ -117,6 +118,7 @@ fun AgendulaNavHost(modifier: Modifier = Modifier) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TaskEditScreen(
|
TaskEditScreen(
|
||||||
|
modifier = Modifier.predictiveBack(onBack = { nav.popBackStack() }),
|
||||||
viewModel = vm,
|
viewModel = vm,
|
||||||
onSaved = { nav.popBackStack() },
|
onSaved = { nav.popBackStack() },
|
||||||
onBack = { nav.popBackStack() },
|
onBack = { nav.popBackStack() },
|
||||||
|
|||||||
@@ -93,6 +93,7 @@ import de.jeanlucmakiola.floret.components.Position
|
|||||||
import de.jeanlucmakiola.agendula.ui.common.ReminderLeadPicker
|
import de.jeanlucmakiola.agendula.ui.common.ReminderLeadPicker
|
||||||
import de.jeanlucmakiola.floret.components.pastelize
|
import de.jeanlucmakiola.floret.components.pastelize
|
||||||
import de.jeanlucmakiola.floret.components.positionOf
|
import de.jeanlucmakiola.floret.components.positionOf
|
||||||
|
import de.jeanlucmakiola.floret.identity.predictiveBack
|
||||||
import de.jeanlucmakiola.floret.locale.AppLanguage
|
import de.jeanlucmakiola.floret.locale.AppLanguage
|
||||||
import de.jeanlucmakiola.floret.reminders.ReminderOverride
|
import de.jeanlucmakiola.floret.reminders.ReminderOverride
|
||||||
import de.jeanlucmakiola.agendula.ui.common.reminderLeadTimeLabel
|
import de.jeanlucmakiola.agendula.ui.common.reminderLeadTimeLabel
|
||||||
@@ -128,6 +129,9 @@ fun SettingsScreen(
|
|||||||
|
|
||||||
Box(
|
Box(
|
||||||
modifier = modifier
|
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()
|
.fillMaxSize()
|
||||||
.background(MaterialTheme.colorScheme.surface),
|
.background(MaterialTheme.colorScheme.surface),
|
||||||
) {
|
) {
|
||||||
|
|||||||
Submodule floret-kit updated: 10e0ca0b06...2085b82a5e
Reference in New Issue
Block a user