Skip to content

Commit 095ed7e

Browse files
committed
Give each PaneScaffoldState its own backPreviewState
1 parent e707e78 commit 095ed7e

File tree

4 files changed

+52
-41
lines changed

4 files changed

+52
-41
lines changed

scaffold/src/commonMain/kotlin/com/tunjid/heron/scaffold/scaffold/App.kt

Lines changed: 0 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -22,21 +22,15 @@ import androidx.compose.foundation.layout.fillMaxSize
2222
import androidx.compose.material3.Surface
2323
import androidx.compose.runtime.Composable
2424
import androidx.compose.runtime.CompositionLocalProvider
25-
import androidx.compose.runtime.LaunchedEffect
2625
import androidx.compose.runtime.getValue
2726
import androidx.compose.runtime.mutableStateOf
2827
import androidx.compose.runtime.remember
2928
import androidx.compose.runtime.rememberUpdatedState
3029
import androidx.compose.runtime.setValue
3130
import androidx.compose.ui.Modifier
32-
import androidx.compose.ui.geometry.Offset
3331
import androidx.compose.ui.layout.layout
3432
import androidx.compose.ui.platform.LocalDensity
3533
import androidx.compose.ui.platform.LocalWindowInfo
36-
import androidx.compose.ui.unit.round
37-
import androidx.navigationevent.NavigationEvent
38-
import androidx.navigationevent.NavigationEventTransitionState
39-
import androidx.navigationevent.compose.LocalNavigationEventDispatcherOwner
4034
import com.tunjid.composables.splitlayout.SplitLayout
4135
import com.tunjid.heron.images.LocalImageLoader
4236
import com.tunjid.heron.media.video.LocalVideoPlayerController
@@ -142,33 +136,6 @@ fun App(
142136
},
143137
)
144138
}
145-
146-
val navigationEventDispatcher =
147-
LocalNavigationEventDispatcherOwner.current!!
148-
.navigationEventDispatcher
149-
150-
LaunchedEffect(navigationEventDispatcher) {
151-
navigationEventDispatcher.transitionState
152-
.collect { eventState ->
153-
when (eventState) {
154-
is NavigationEventTransitionState.Idle -> {
155-
appState.backPreviewState.progress = 0f
156-
}
157-
158-
is NavigationEventTransitionState.InProgress -> {
159-
appState.backPreviewState.progress =
160-
eventState.latestEvent.progress
161-
appState.backPreviewState.atStart =
162-
eventState.latestEvent.swipeEdge == NavigationEvent.EDGE_LEFT
163-
appState.backPreviewState.pointerOffset =
164-
Offset(
165-
eventState.latestEvent.touchX,
166-
eventState.latestEvent.touchY,
167-
).round()
168-
}
169-
}
170-
}
171-
}
172139
}
173140
}
174141
}

scaffold/src/commonMain/kotlin/com/tunjid/heron/scaffold/scaffold/AppState.kt

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ import androidx.navigation3.runtime.rememberSaveableStateHolderNavEntryDecorator
4040
import androidx.navigationevent.NavigationEvent
4141
import androidx.navigationevent.NavigationEventTransitionState
4242
import androidx.navigationevent.compose.LocalNavigationEventDispatcherOwner
43-
import com.tunjid.composables.backpreview.BackPreviewState
4443
import com.tunjid.composables.splitlayout.SplitLayoutState
4544
import com.tunjid.heron.data.core.models.Preferences
4645
import com.tunjid.heron.data.core.types.GenericUri
@@ -110,9 +109,6 @@ class AppState(
110109
}
111110

112111
internal val navigation by multiStackNavState
113-
internal val backPreviewState = BackPreviewState(
114-
minScale = 0.75f,
115-
)
116112

117113
internal var dismissBehavior by mutableStateOf<DismissBehavior>(DismissBehavior.None)
118114
private set

scaffold/src/commonMain/kotlin/com/tunjid/heron/scaffold/scaffold/PaneScaffold.kt

Lines changed: 51 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
package com.tunjid.heron.scaffold.scaffold
1818

19+
import androidx.compose.animation.EnterExitState
1920
import androidx.compose.animation.animateBounds
2021
import androidx.compose.animation.core.animateDpAsState
2122
import androidx.compose.foundation.gestures.Orientation
@@ -36,13 +37,21 @@ import androidx.compose.runtime.Composable
3637
import androidx.compose.runtime.LaunchedEffect
3738
import androidx.compose.runtime.getValue
3839
import androidx.compose.runtime.remember
40+
import androidx.compose.runtime.rememberCoroutineScope
3941
import androidx.compose.runtime.rememberUpdatedState
4042
import androidx.compose.runtime.snapshotFlow
4143
import androidx.compose.ui.Modifier
4244
import androidx.compose.ui.draw.clip
45+
import androidx.compose.ui.geometry.Offset
4346
import androidx.compose.ui.graphics.Color
4447
import androidx.compose.ui.unit.dp
48+
import androidx.compose.ui.unit.round
4549
import androidx.compose.ui.zIndex
50+
import androidx.lifecycle.compose.LifecycleStartEffect
51+
import androidx.navigationevent.NavigationEvent
52+
import androidx.navigationevent.NavigationEventTransitionState
53+
import androidx.navigationevent.compose.LocalNavigationEventDispatcherOwner
54+
import com.tunjid.composables.backpreview.BackPreviewState
4655
import com.tunjid.composables.constrainedsize.constrainedSizePlacement
4756
import com.tunjid.heron.ui.text.Memo
4857
import com.tunjid.heron.ui.text.message
@@ -51,7 +60,10 @@ import com.tunjid.treenav.compose.threepane.ThreePane
5160
import com.tunjid.treenav.compose.threepane.ThreePaneMovableElementSharedTransitionScope
5261
import com.tunjid.treenav.compose.threepane.rememberThreePaneMovableElementSharedTransitionScope
5362
import com.tunjid.treenav.strings.Route
63+
import kotlinx.coroutines.flow.collectLatest
5464
import kotlinx.coroutines.flow.filterNotNull
65+
import kotlinx.coroutines.flow.first
66+
import kotlinx.coroutines.launch
5567

5668
class PaneScaffoldState internal constructor(
5769
internal val appState: AppState,
@@ -108,8 +120,9 @@ class PaneScaffoldState internal constructor(
108120
internal val hasSiblings
109121
get() = splitPaneState.filteredPaneOrder.size > 1
110122

111-
internal val backPreviewProgress
112-
get() = appState.backPreviewState.progress
123+
internal val backPreviewState = BackPreviewState(
124+
minScale = 0.75f,
125+
)
113126

114127
internal val defaultContainerColor: Color
115128
@Composable get() {
@@ -135,7 +148,7 @@ fun PaneScope<ThreePane, Route>.rememberPaneScaffoldState(): PaneScaffoldState {
135148
val splitPaneState = LocalSplitPaneState.current
136149
val paneMovableElementSharedTransitionScope =
137150
rememberThreePaneMovableElementSharedTransitionScope()
138-
return remember(
151+
val paneScaffoldState = remember(
139152
appState,
140153
splitPaneState,
141154
paneMovableElementSharedTransitionScope,
@@ -146,6 +159,41 @@ fun PaneScope<ThreePane, Route>.rememberPaneScaffoldState(): PaneScaffoldState {
146159
paneMovableElementSharedTransitionScope = paneMovableElementSharedTransitionScope,
147160
)
148161
}
162+
163+
val scope = rememberCoroutineScope()
164+
165+
val navigationEventDispatcher =
166+
LocalNavigationEventDispatcherOwner.current!!
167+
.navigationEventDispatcher
168+
169+
LifecycleStartEffect(
170+
key1 = scope,
171+
key2 = navigationEventDispatcher,
172+
) {
173+
val job = scope.launch {
174+
navigationEventDispatcher.transitionState
175+
.collectLatest { eventState ->
176+
when (eventState) {
177+
is NavigationEventTransitionState.Idle -> {
178+
// Wait to be visible
179+
snapshotFlow { paneScaffoldState.transition.targetState }
180+
.first { it == EnterExitState.Visible }
181+
paneScaffoldState.backPreviewState.progress = 0f
182+
}
183+
is NavigationEventTransitionState.InProgress -> paneScaffoldState.backPreviewState.apply {
184+
progress = eventState.latestEvent.progress
185+
atStart = eventState.latestEvent.swipeEdge == NavigationEvent.EDGE_LEFT
186+
pointerOffset = Offset(
187+
x = eventState.latestEvent.touchX,
188+
y = eventState.latestEvent.touchY,
189+
).round()
190+
}
191+
}
192+
}
193+
}
194+
onStopOrDispose { job.cancel() }
195+
}
196+
return paneScaffoldState
149197
}
150198

151199
@Composable

scaffold/src/commonMain/kotlin/com/tunjid/heron/scaffold/scaffold/PredictiveBack.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ fun Modifier.predictiveBackPlacement(
4040
appState.dismissBehavior != AppState.DismissBehavior.Gesture.DragToPop
4141

4242
ifTrue(shouldDrawBackground) {
43-
backPreview(appState.backPreviewState)
43+
backPreview(backPreviewState)
4444
}
4545
.animatedRoundedCornerClip(
4646
cornerRadius = if (shouldDrawBackground) 16.dp else 0.dp,

0 commit comments

Comments
 (0)