From 771867be8bb4a8dcd409433a41bb2f8f1d82e55e Mon Sep 17 00:00:00 2001 From: Adetunji Dahunsi Date: Sat, 5 Jul 2025 16:03:46 -0700 Subject: [PATCH 1/5] Improvments for predictive back. Pane animaimations do not affect pane decorators. Predictive back background is now per screen --- .../treenav/compose/MultiPaneDisplay.kt | 31 +---------- .../treenav/compose/MultiPaneDisplayState.kt | 35 ++++++++---- .../panedecorators/PaneModifierDecorator.kt | 40 -------------- .../com/tunjid/demo/common/ui/DemoApp.kt | 15 +----- .../com/tunjid/demo/common/ui/PaneScaffold.kt | 17 +++++- .../tunjid/demo/common/ui/PredictiveBack.kt | 54 ++++++++----------- .../tunjid/demo/common/ui/avatar/PaneEntry.kt | 2 + .../tunjid/demo/common/ui/chat/PaneEntry.kt | 4 +- .../demo/common/ui/chatrooms/PaneEntry.kt | 2 + .../com/tunjid/demo/common/ui/me/PaneEntry.kt | 2 + .../demo/common/ui/profile/PaneEntry.kt | 4 +- 11 files changed, 77 insertions(+), 129 deletions(-) delete mode 100644 library/compose/src/commonMain/kotlin/com/tunjid/treenav/compose/panedecorators/PaneModifierDecorator.kt diff --git a/library/compose/src/commonMain/kotlin/com/tunjid/treenav/compose/MultiPaneDisplay.kt b/library/compose/src/commonMain/kotlin/com/tunjid/treenav/compose/MultiPaneDisplay.kt index a2686cd..4dc718a 100644 --- a/library/compose/src/commonMain/kotlin/com/tunjid/treenav/compose/MultiPaneDisplay.kt +++ b/library/compose/src/commonMain/kotlin/com/tunjid/treenav/compose/MultiPaneDisplay.kt @@ -18,9 +18,6 @@ package com.tunjid.treenav.compose import androidx.compose.animation.AnimatedContentTransitionScope import androidx.compose.animation.ContentTransform -import androidx.compose.animation.EnterTransition -import androidx.compose.animation.ExitTransition -import androidx.compose.foundation.layout.Box import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.Stable @@ -37,7 +34,6 @@ import com.tunjid.treenav.Node import com.tunjid.treenav.compose.MultiPaneDisplayState.Companion.children import com.tunjid.treenav.compose.MultiPaneDisplayState.Companion.destination import com.tunjid.treenav.compose.MultiPaneDisplayState.Companion.id -import com.tunjid.treenav.compose.MultiPaneDisplayState.Companion.paneContentTransform import com.tunjid.treenav.compose.navigation3.decorators.rememberViewModelStoreNavEntryDecorator import com.tunjid.treenav.compose.navigation3.runtime.NavEntry import com.tunjid.treenav.compose.navigation3.runtime.rememberSavedStateNavEntryDecorator @@ -363,32 +359,7 @@ private class MultiPaneDisplayScene( CompositionLocalProvider( LocalPaneScope provides scope ) { - with(scope) { - val paneModifier = remember( - isActive, - inPredictiveBack, - panedNavigationState.identityHash(), - animatedContentScope.transition.targetState, - ) { - val contentTransform = entry.paneContentTransform(this) - val shouldAnimate = - contentTransform.targetContentEnter != EnterTransition.None - || contentTransform.initialContentExit != ExitTransition.None - - if (shouldAnimate) Modifier.animateEnterExit( - enter = contentTransform.targetContentEnter, - exit = contentTransform.initialContentExit, - ) - else Modifier - } - - Box( - modifier = paneModifier, - content = { - entry.Content() - } - ) - } + entry.Content() } } diff --git a/library/compose/src/commonMain/kotlin/com/tunjid/treenav/compose/MultiPaneDisplayState.kt b/library/compose/src/commonMain/kotlin/com/tunjid/treenav/compose/MultiPaneDisplayState.kt index 62d8368..010e3a8 100644 --- a/library/compose/src/commonMain/kotlin/com/tunjid/treenav/compose/MultiPaneDisplayState.kt +++ b/library/compose/src/commonMain/kotlin/com/tunjid/treenav/compose/MultiPaneDisplayState.kt @@ -19,13 +19,16 @@ package com.tunjid.treenav.compose import androidx.compose.animation.ContentTransform import androidx.compose.animation.EnterTransition import androidx.compose.animation.ExitTransition +import androidx.compose.foundation.layout.Box import androidx.compose.runtime.Composable import androidx.compose.runtime.Stable import androidx.compose.runtime.State +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier import com.tunjid.treenav.Node import com.tunjid.treenav.compose.navigation3.runtime.NavEntry -import com.tunjid.treenav.compose.panedecorators.PaneMappingDecorator import com.tunjid.treenav.compose.panedecorators.PaneDecorator +import com.tunjid.treenav.compose.panedecorators.PaneMappingDecorator import com.tunjid.treenav.compose.panedecorators.PaneRenderDecorator /** @@ -67,7 +70,6 @@ class MultiPaneDisplayState in ID_KEY to destination.id, DESTINATION_KEY to destination, CHILDREN_KEY to destination.children, - PANE_CONTENT_TRANSFORM_KEY to paneEntry.contentTransform, ), content = { innerDestination -> destinationContent(localPaneScope(), paneEntry, innerDestination) @@ -84,8 +86,6 @@ class MultiPaneDisplayState in private const val ID_KEY = "com.tunjid.treenav.compose.id" private const val DESTINATION_KEY = "com.tunjid.treenav.compose.destination" private const val CHILDREN_KEY = "com.tunjid.treenav.compose.children" - private const val PANE_CONTENT_TRANSFORM_KEY = - "com.tunjid.treenav.compose.pane.enter.transition" internal val NavEntry<*>.id get() = metadata[ID_KEY] as String internal val NavEntry<*>.children get() = metadata[CHILDREN_KEY] @@ -93,10 +93,6 @@ class MultiPaneDisplayState in @Suppress("UNCHECKED_CAST") internal inline fun NavEntry<*>.destination() = metadata[DESTINATION_KEY] as T - - @Suppress("UNCHECKED_CAST") - internal inline val NavEntry<*>.paneContentTransform - get() = metadata[PANE_CONTENT_TRANSFORM_KEY] as PaneScope<*, *>.() -> ContentTransform } } @@ -146,7 +142,28 @@ fun MultiPaneDisplayState( entryProvider(destination).paneMapping(destination) }, destinationContent = transform@{ paneEntry, destination -> - paneEntry.content(this@transform, destination) + Box( + modifier = remember( + isActive, + inPredictiveBack, + paneState.pane, + transition.targetState, + ) { + val contentTransform = paneEntry.contentTransform(this) + val shouldAnimate = + contentTransform.targetContentEnter != EnterTransition.None + || contentTransform.initialContentExit != ExitTransition.None + + if (shouldAnimate) Modifier.animateEnterExit( + enter = contentTransform.targetContentEnter, + exit = contentTransform.initialContentExit, + ) + else Modifier + }, + content = { + paneEntry.content(this@transform, destination) + } + ) } ), operation = MultiPaneDisplayState::plus diff --git a/library/compose/src/commonMain/kotlin/com/tunjid/treenav/compose/panedecorators/PaneModifierDecorator.kt b/library/compose/src/commonMain/kotlin/com/tunjid/treenav/compose/panedecorators/PaneModifierDecorator.kt deleted file mode 100644 index 4240bc4..0000000 --- a/library/compose/src/commonMain/kotlin/com/tunjid/treenav/compose/panedecorators/PaneModifierDecorator.kt +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2021 Google LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.tunjid.treenav.compose.panedecorators - -import androidx.compose.foundation.layout.Box -import androidx.compose.ui.Modifier -import com.tunjid.treenav.Node -import com.tunjid.treenav.compose.MultiPaneDisplayState -import com.tunjid.treenav.compose.PaneScope - -/** - * A [MultiPaneDisplayState] that allows for centrally defining the [Modifier] for - * each [Pane] displayed within it. - * - * @param paneModifier a lambda for specifying the [Modifier] for each [Pane] in a [PaneScope]. - */ -fun paneModifierDecorator( - paneModifier: PaneScope.() -> Modifier = { Modifier }, -): PaneDecorator = - paneRenderDecorator { destination, destinationContent -> - Box( - modifier = paneModifier() - ) { - destinationContent(destination) - } - } \ No newline at end of file diff --git a/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/DemoApp.kt b/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/DemoApp.kt index 2f0402c..75c1782 100644 --- a/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/DemoApp.kt +++ b/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/DemoApp.kt @@ -66,7 +66,6 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.round import androidx.navigationevent.NavigationEvent import com.tunjid.composables.backpreview.BackPreviewState -import com.tunjid.composables.backpreview.backPreview import com.tunjid.composables.splitlayout.SplitLayout import com.tunjid.composables.splitlayout.SplitLayoutState import com.tunjid.demo.common.ui.AppState.Companion.rememberMultiPaneDisplayState @@ -84,11 +83,10 @@ import com.tunjid.treenav.compose.MultiPaneDisplayState import com.tunjid.treenav.compose.moveablesharedelement.MovableSharedElementHostState import com.tunjid.treenav.compose.multiPaneDisplayBackstack import com.tunjid.treenav.compose.navigation3.ui.NavigationEventHandler +import com.tunjid.treenav.compose.panedecorators.PaneDecorator import com.tunjid.treenav.compose.threepane.ThreePane import com.tunjid.treenav.compose.threepane.panedecorators.threePaneAdaptiveDecorator import com.tunjid.treenav.compose.threepane.panedecorators.threePaneMovableSharedElementDecorator -import com.tunjid.treenav.compose.panedecorators.PaneDecorator -import com.tunjid.treenav.compose.panedecorators.paneModifierDecorator import com.tunjid.treenav.pop import com.tunjid.treenav.popToRoot import com.tunjid.treenav.requireCurrent @@ -130,17 +128,6 @@ fun App( threePaneMovableSharedElementDecorator( movableSharedElementHostState = movableSharedElementHostState ), - paneModifierDecorator { - if (paneState.pane == ThreePane.Primary - && inPredictiveBack - && isActive - && !appState.dragToPopState.isDraggingToPop - ) Modifier - .fillMaxSize() - .backPreview(appState.backPreviewState) - else Modifier - .fillMaxSize() - }, ) }, ) diff --git a/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/PaneScaffold.kt b/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/PaneScaffold.kt index f56750b..e2cb791 100644 --- a/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/PaneScaffold.kt +++ b/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/PaneScaffold.kt @@ -19,6 +19,7 @@ package com.tunjid.demo.common.ui import androidx.compose.animation.BoundsTransform import androidx.compose.animation.ExperimentalSharedTransitionApi import androidx.compose.animation.animateBounds +import androidx.compose.animation.core.animateDpAsState import androidx.compose.animation.core.snap import androidx.compose.animation.core.spring import androidx.compose.foundation.layout.Box @@ -31,6 +32,7 @@ import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Scaffold import androidx.compose.material3.SnackbarHost import androidx.compose.material3.SnackbarHostState +import androidx.compose.material3.surfaceColorAtElevation import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.Stable @@ -75,6 +77,19 @@ class PaneScaffoldState internal constructor( internal var scaffoldTargetSize by mutableStateOf(IntSize.Zero) internal var scaffoldCurrentSize by mutableStateOf(IntSize.Zero) + + internal val defaultContainerColor: Color + @Composable get() { + val elevation by animateDpAsState( + if (paneState.pane == ThreePane.Primary + && isActive + && inPredictiveBack + ) 4.dp + else 0.dp + ) + + return MaterialTheme.colorScheme.surfaceColorAtElevation(elevation) + } } @Composable @@ -95,7 +110,7 @@ fun PaneScope.rememberPaneScaffoldState(): PaneSca @Composable fun PaneScaffoldState.PaneScaffold( modifier: Modifier = Modifier, - containerColor: Color = MaterialTheme.colorScheme.background, + containerColor: Color = defaultContainerColor, snackBarMessages: List = emptyList(), onSnackBarMessageConsumed: (String) -> Unit = {}, topBar: @Composable PaneScaffoldState.() -> Unit = {}, diff --git a/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/PredictiveBack.kt b/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/PredictiveBack.kt index 19741f0..ef87fc4 100644 --- a/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/PredictiveBack.kt +++ b/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/PredictiveBack.kt @@ -16,46 +16,34 @@ package com.tunjid.demo.common.ui -import androidx.compose.animation.core.Spring -import androidx.compose.animation.core.animate -import androidx.compose.animation.core.spring -import androidx.compose.foundation.background -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.surfaceColorAtElevation +import androidx.compose.animation.ContentTransform +import androidx.compose.animation.fadeIn +import androidx.compose.animation.fadeOut import androidx.compose.runtime.Composable -import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.unit.dp +import com.tunjid.composables.backpreview.backPreview +import com.tunjid.demo.common.ui.data.SampleDestination import com.tunjid.treenav.compose.PaneScope import com.tunjid.treenav.compose.threepane.ThreePane +import com.tunjid.treenav.compose.threepane.adaptTo @Composable fun Modifier.predictiveBackBackgroundModifier( paneScope: PaneScope, -): Modifier { - if (paneScope.paneState.pane != ThreePane.Primary - || !paneScope.isActive - || !paneScope.inPredictiveBack - ) return this +): Modifier = with(paneScope) { + val appState = LocalAppState.current + if (paneState.pane == ThreePane.Primary + && inPredictiveBack + && isActive + && !appState.dragToPopState.isDraggingToPop + ) backPreview(appState.backPreviewState) + else this@predictiveBackBackgroundModifier +} - var elevation by remember { mutableStateOf(0.dp) } - LaunchedEffect(Unit) { - animate( - initialValue = 0f, - targetValue = 4f, - animationSpec = spring(stiffness = Spring.StiffnessVeryLow) - ) { value, _ -> elevation = value.dp } +val predictiveBackContentTransform: PaneScope.() -> ContentTransform = + { + ContentTransform( + fadeIn(), + fadeOut(targetAlpha = if (inPredictiveBack) 0.9f else 0f), + ).adaptTo(paneScope = this) } - return background( - color = MaterialTheme.colorScheme.surfaceColorAtElevation(elevation), - shape = RoundedCornerShape(16.dp) - ) - .clip(RoundedCornerShape(16.dp)) - -} diff --git a/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/avatar/PaneEntry.kt b/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/avatar/PaneEntry.kt index e3feb24..f572787 100644 --- a/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/avatar/PaneEntry.kt +++ b/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/avatar/PaneEntry.kt @@ -24,6 +24,7 @@ import androidx.lifecycle.viewmodel.compose.viewModel import com.tunjid.demo.common.ui.PaneScaffold import com.tunjid.demo.common.ui.data.SampleDestination import com.tunjid.demo.common.ui.data.SampleDestination.NavTabs +import com.tunjid.demo.common.ui.predictiveBackBackgroundModifier import com.tunjid.demo.common.ui.rememberPaneScaffoldState import com.tunjid.demo.common.ui.viewModelCoroutineScope import com.tunjid.treenav.compose.threepane.ThreePane @@ -49,6 +50,7 @@ fun avatarPaneEntry() = threePaneEntry( } rememberPaneScaffoldState().PaneScaffold( modifier = Modifier + .predictiveBackBackgroundModifier(this) .fillMaxSize(), containerColor = Color.Transparent, content = { diff --git a/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/chat/PaneEntry.kt b/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/chat/PaneEntry.kt index 1b9bf10..e6ca3ba 100644 --- a/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/chat/PaneEntry.kt +++ b/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/chat/PaneEntry.kt @@ -26,12 +26,14 @@ import com.tunjid.demo.common.ui.PaneScaffold import com.tunjid.demo.common.ui.data.SampleDestination import com.tunjid.demo.common.ui.data.SampleDestination.NavTabs import com.tunjid.demo.common.ui.predictiveBackBackgroundModifier +import com.tunjid.demo.common.ui.predictiveBackContentTransform import com.tunjid.demo.common.ui.rememberPaneScaffoldState import com.tunjid.demo.common.ui.viewModelCoroutineScope import com.tunjid.treenav.compose.threepane.ThreePane import com.tunjid.treenav.compose.threepane.threePaneEntry -fun chatPaneEntry() = threePaneEntry( +fun chatPaneEntry() = threePaneEntry( + contentTransform = predictiveBackContentTransform, paneMapping = { destination -> mapOf( ThreePane.Primary to destination, diff --git a/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/chatrooms/PaneEntry.kt b/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/chatrooms/PaneEntry.kt index ce21e94..88f18d1 100644 --- a/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/chatrooms/PaneEntry.kt +++ b/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/chatrooms/PaneEntry.kt @@ -25,12 +25,14 @@ import com.tunjid.demo.common.ui.PaneNavigationRail import com.tunjid.demo.common.ui.PaneScaffold import com.tunjid.demo.common.ui.data.ChatsRepository import com.tunjid.demo.common.ui.predictiveBackBackgroundModifier +import com.tunjid.demo.common.ui.predictiveBackContentTransform import com.tunjid.demo.common.ui.rememberPaneScaffoldState import com.tunjid.demo.common.ui.viewModelCoroutineScope import com.tunjid.treenav.compose.threepane.threePaneEntry fun chatRoomPaneEntry( ) = threePaneEntry( + contentTransform = predictiveBackContentTransform, render = { val viewModel = viewModel { ChatRoomsViewModel( diff --git a/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/me/PaneEntry.kt b/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/me/PaneEntry.kt index 6e0cd8d..2debb21 100644 --- a/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/me/PaneEntry.kt +++ b/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/me/PaneEntry.kt @@ -24,6 +24,7 @@ import com.tunjid.demo.common.ui.PaneNavigationBar import com.tunjid.demo.common.ui.PaneNavigationRail import com.tunjid.demo.common.ui.PaneScaffold import com.tunjid.demo.common.ui.predictiveBackBackgroundModifier +import com.tunjid.demo.common.ui.predictiveBackContentTransform import com.tunjid.demo.common.ui.profile.ProfileScreen import com.tunjid.demo.common.ui.profile.ProfileViewModel import com.tunjid.demo.common.ui.rememberPaneScaffoldState @@ -32,6 +33,7 @@ import com.tunjid.treenav.compose.threepane.threePaneEntry fun mePaneEntry( ) = threePaneEntry( + contentTransform = predictiveBackContentTransform, render = { val viewModel = viewModel { ProfileViewModel( diff --git a/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/profile/PaneEntry.kt b/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/profile/PaneEntry.kt index 10c3031..56fc847 100644 --- a/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/profile/PaneEntry.kt +++ b/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/profile/PaneEntry.kt @@ -26,12 +26,14 @@ import com.tunjid.demo.common.ui.PaneScaffold import com.tunjid.demo.common.ui.data.SampleDestination import com.tunjid.demo.common.ui.data.SampleDestination.NavTabs import com.tunjid.demo.common.ui.predictiveBackBackgroundModifier +import com.tunjid.demo.common.ui.predictiveBackContentTransform import com.tunjid.demo.common.ui.rememberPaneScaffoldState import com.tunjid.demo.common.ui.viewModelCoroutineScope import com.tunjid.treenav.compose.threepane.ThreePane import com.tunjid.treenav.compose.threepane.threePaneEntry -fun profilePaneEntry() = threePaneEntry( +fun profilePaneEntry() = threePaneEntry( + contentTransform = predictiveBackContentTransform, paneMapping = { destination -> check(destination is SampleDestination.Profile) mapOf( From d63229458262db548f94ff8fea5a2a8266d3f9ac Mon Sep 17 00:00:00 2001 From: Adetunji Dahunsi Date: Sun, 6 Jul 2025 08:01:56 -0700 Subject: [PATCH 2/5] Fix predictivebackground modifier --- .../kotlin/com/tunjid/demo/common/ui/PredictiveBack.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/PredictiveBack.kt b/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/PredictiveBack.kt index ef87fc4..e1d2824 100644 --- a/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/PredictiveBack.kt +++ b/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/PredictiveBack.kt @@ -19,6 +19,7 @@ package com.tunjid.demo.common.ui import androidx.compose.animation.ContentTransform import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeOut +import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import com.tunjid.composables.backpreview.backPreview @@ -36,7 +37,8 @@ fun Modifier.predictiveBackBackgroundModifier( && inPredictiveBack && isActive && !appState.dragToPopState.isDraggingToPop - ) backPreview(appState.backPreviewState) + ) fillMaxSize() + .backPreview(appState.backPreviewState) else this@predictiveBackBackgroundModifier } From b3c332b57f031eb40267043fe3121756a3b1c57e Mon Sep 17 00:00:00 2001 From: Adetunji Dahunsi Date: Sun, 6 Jul 2025 08:20:42 -0700 Subject: [PATCH 3/5] Fix predictivebackground modifier --- .../kotlin/com/tunjid/demo/common/ui/PredictiveBack.kt | 4 +--- .../kotlin/com/tunjid/demo/common/ui/avatar/PaneEntry.kt | 4 ++-- .../kotlin/com/tunjid/demo/common/ui/chat/PaneEntry.kt | 4 ++-- .../kotlin/com/tunjid/demo/common/ui/chatrooms/PaneEntry.kt | 4 ++-- .../kotlin/com/tunjid/demo/common/ui/data/AppData.kt | 1 - .../kotlin/com/tunjid/demo/common/ui/me/PaneEntry.kt | 4 ++-- .../kotlin/com/tunjid/demo/common/ui/profile/PaneEntry.kt | 4 ++-- 7 files changed, 11 insertions(+), 14 deletions(-) diff --git a/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/PredictiveBack.kt b/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/PredictiveBack.kt index e1d2824..ef87fc4 100644 --- a/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/PredictiveBack.kt +++ b/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/PredictiveBack.kt @@ -19,7 +19,6 @@ package com.tunjid.demo.common.ui import androidx.compose.animation.ContentTransform import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeOut -import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import com.tunjid.composables.backpreview.backPreview @@ -37,8 +36,7 @@ fun Modifier.predictiveBackBackgroundModifier( && inPredictiveBack && isActive && !appState.dragToPopState.isDraggingToPop - ) fillMaxSize() - .backPreview(appState.backPreviewState) + ) backPreview(appState.backPreviewState) else this@predictiveBackBackgroundModifier } diff --git a/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/avatar/PaneEntry.kt b/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/avatar/PaneEntry.kt index f572787..d8d6a8e 100644 --- a/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/avatar/PaneEntry.kt +++ b/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/avatar/PaneEntry.kt @@ -50,8 +50,8 @@ fun avatarPaneEntry() = threePaneEntry( } rememberPaneScaffoldState().PaneScaffold( modifier = Modifier - .predictiveBackBackgroundModifier(this) - .fillMaxSize(), + .fillMaxSize() + .predictiveBackBackgroundModifier(this), containerColor = Color.Transparent, content = { AvatarScreen( diff --git a/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/chat/PaneEntry.kt b/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/chat/PaneEntry.kt index e6ca3ba..4cb45eb 100644 --- a/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/chat/PaneEntry.kt +++ b/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/chat/PaneEntry.kt @@ -50,8 +50,8 @@ fun chatPaneEntry() = threePaneEntry( } rememberPaneScaffoldState().PaneScaffold( modifier = Modifier - .predictiveBackBackgroundModifier(this) - .fillMaxSize(), + .fillMaxSize() + .predictiveBackBackgroundModifier(this), content = { ChatScreen( paneScaffoldState = this, diff --git a/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/chatrooms/PaneEntry.kt b/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/chatrooms/PaneEntry.kt index 88f18d1..9f3b5b5 100644 --- a/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/chatrooms/PaneEntry.kt +++ b/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/chatrooms/PaneEntry.kt @@ -42,8 +42,8 @@ fun chatRoomPaneEntry( } rememberPaneScaffoldState().PaneScaffold( modifier = Modifier - .predictiveBackBackgroundModifier(this) - .fillMaxSize(), + .fillMaxSize() + .predictiveBackBackgroundModifier(this), content = { ChatRoomsScreen( paneScaffoldState = this, diff --git a/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/data/AppData.kt b/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/data/AppData.kt index 5d9fb1e..7615db1 100644 --- a/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/data/AppData.kt +++ b/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/data/AppData.kt @@ -17,7 +17,6 @@ package com.tunjid.demo.common.ui.data import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.flowOf import kotlinx.datetime.Instant diff --git a/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/me/PaneEntry.kt b/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/me/PaneEntry.kt index 2debb21..22bc047 100644 --- a/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/me/PaneEntry.kt +++ b/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/me/PaneEntry.kt @@ -44,8 +44,8 @@ fun mePaneEntry( } rememberPaneScaffoldState().PaneScaffold( modifier = Modifier - .predictiveBackBackgroundModifier(this) - .fillMaxSize(), + .fillMaxSize() + .predictiveBackBackgroundModifier(this), content = { ProfileScreen( paneScaffoldState = this, diff --git a/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/profile/PaneEntry.kt b/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/profile/PaneEntry.kt index 56fc847..93e935d 100644 --- a/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/profile/PaneEntry.kt +++ b/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/profile/PaneEntry.kt @@ -53,8 +53,8 @@ fun profilePaneEntry() = threePaneEntry( } rememberPaneScaffoldState().PaneScaffold( modifier = Modifier - .predictiveBackBackgroundModifier(this) - .fillMaxSize(), + .fillMaxSize() + .predictiveBackBackgroundModifier(this), content = { ProfileScreen( paneScaffoldState = this, From 4aebaa4f9439d35b36d195d610c35bc6d1471f41 Mon Sep 17 00:00:00 2001 From: Adetunji Dahunsi Date: Sun, 6 Jul 2025 08:41:56 -0700 Subject: [PATCH 4/5] Clip predictive back modifier --- .../tunjid/demo/common/ui/PredictiveBack.kt | 22 ++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/PredictiveBack.kt b/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/PredictiveBack.kt index ef87fc4..f37aa77 100644 --- a/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/PredictiveBack.kt +++ b/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/PredictiveBack.kt @@ -17,10 +17,15 @@ package com.tunjid.demo.common.ui import androidx.compose.animation.ContentTransform +import androidx.compose.animation.core.animateDpAsState import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeOut +import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.unit.dp import com.tunjid.composables.backpreview.backPreview import com.tunjid.demo.common.ui.data.SampleDestination import com.tunjid.treenav.compose.PaneScope @@ -32,11 +37,18 @@ fun Modifier.predictiveBackBackgroundModifier( paneScope: PaneScope, ): Modifier = with(paneScope) { val appState = LocalAppState.current - if (paneState.pane == ThreePane.Primary - && inPredictiveBack - && isActive - && !appState.dragToPopState.isDraggingToPop - ) backPreview(appState.backPreviewState) + val shouldDrawBackground = paneState.pane == ThreePane.Primary + && inPredictiveBack + && isActive + && !appState.dragToPopState.isDraggingToPop + + val clipRadius by animateDpAsState( + if (shouldDrawBackground) 16.dp + else 0.dp + ) + + if (shouldDrawBackground) backPreview(appState.backPreviewState) + .clip(RoundedCornerShape(clipRadius)) else this@predictiveBackBackgroundModifier } From 055f56208890e7228540f801a0150297c53fd780 Mon Sep 17 00:00:00 2001 From: Adetunji Dahunsi Date: Sun, 6 Jul 2025 09:31:19 -0700 Subject: [PATCH 5/5] Version bump to 0.0.42 --- libraryVersion.properties | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libraryVersion.properties b/libraryVersion.properties index cf2df16..0a3a001 100644 --- a/libraryVersion.properties +++ b/libraryVersion.properties @@ -14,7 +14,7 @@ # limitations under the License. # groupId=com.tunjid.treenav -treenav_version=0.0.41 -strings_version=0.0.41 -compose_version=0.0.41 -compose-threepane_version=0.0.41 \ No newline at end of file +treenav_version=0.0.42 +strings_version=0.0.42 +compose_version=0.0.42 +compose-threepane_version=0.0.42 \ No newline at end of file