From ea36f213b9be384ba11173f1f4121ce0082073e4 Mon Sep 17 00:00:00 2001 From: Lasta Apps Date: Wed, 15 Jan 2025 23:53:07 +0200 Subject: [PATCH] feat: More shared element and other animations --- .../today/ui/navigation/RateDishComponent.kt | 4 +- .../today/ui/screen/DishListScreen.kt | 3 + .../today/ui/widget/TodayDishCarousel.kt | 105 +++++++++++++++++- .../today/ui/widget/TodayDishDetail.kt | 40 ++++--- .../features/today/ui/widget/TodayDishGrid.kt | 51 +++++++-- .../today/ui/widget/TodayDishHorizontal.kt | 57 +++++++--- .../features/today/ui/widget/TodayDishList.kt | 5 +- .../menza/ui/util/AnimationScopes.kt | 5 + 8 files changed, 225 insertions(+), 45 deletions(-) diff --git a/app/src/main/kotlin/cz/lastaapps/menza/features/today/ui/navigation/RateDishComponent.kt b/app/src/main/kotlin/cz/lastaapps/menza/features/today/ui/navigation/RateDishComponent.kt index 4022f2e5..c2934b87 100644 --- a/app/src/main/kotlin/cz/lastaapps/menza/features/today/ui/navigation/RateDishComponent.kt +++ b/app/src/main/kotlin/cz/lastaapps/menza/features/today/ui/navigation/RateDishComponent.kt @@ -1,5 +1,5 @@ /* - * Copyright 2024, Petr Laštovička as Lasta apps, All rights reserved + * Copyright 2025, Petr Laštovička as Lasta apps, All rights reserved * * This file is part of Menza. * @@ -20,6 +20,7 @@ package cz.lastaapps.menza.features.today.ui.navigation import androidx.compose.runtime.Composable +import androidx.compose.ui.window.DialogProperties import com.arkivanov.decompose.ComponentContext import cz.lastaapps.api.core.domain.model.DishOriginDescriptor import cz.lastaapps.menza.features.today.ui.screen.RateDishScreen @@ -54,6 +55,7 @@ internal class DefaultRateDishComponent( internal fun RateDishContent(component: RateDishComponent) { BaseDialog( onDismissRequest = component::dismiss, + properties = DialogProperties(dismissOnClickOutside = false), ) { RateDishScreen( viewModel = component.viewModel, diff --git a/app/src/main/kotlin/cz/lastaapps/menza/features/today/ui/screen/DishListScreen.kt b/app/src/main/kotlin/cz/lastaapps/menza/features/today/ui/screen/DishListScreen.kt index c449f9a5..bb67e53b 100644 --- a/app/src/main/kotlin/cz/lastaapps/menza/features/today/ui/screen/DishListScreen.kt +++ b/app/src/main/kotlin/cz/lastaapps/menza/features/today/ui/screen/DishListScreen.kt @@ -254,6 +254,7 @@ private fun DishListComposing( }, modifier = modifier.fillMaxSize(), scrollGrid = scrollStates.grid, + scopes = scopes, ) HORIZONTAL -> @@ -275,6 +276,7 @@ private fun DishListComposing( }, modifier = modifier.fillMaxSize(), scroll = scrollStates.horizontal, + scopes = scopes, ) CAROUSEL -> @@ -296,6 +298,7 @@ private fun DishListComposing( }, modifier = modifier.fillMaxSize(), scroll = scrollStates.carousel, + scopes = scopes, ) null -> {} diff --git a/app/src/main/kotlin/cz/lastaapps/menza/features/today/ui/widget/TodayDishCarousel.kt b/app/src/main/kotlin/cz/lastaapps/menza/features/today/ui/widget/TodayDishCarousel.kt index a5431abd..1ef856a0 100644 --- a/app/src/main/kotlin/cz/lastaapps/menza/features/today/ui/widget/TodayDishCarousel.kt +++ b/app/src/main/kotlin/cz/lastaapps/menza/features/today/ui/widget/TodayDishCarousel.kt @@ -17,9 +17,15 @@ * along with Menza. If not, see . */ +@file:OptIn(ExperimentalSharedTransitionApi::class) + package cz.lastaapps.menza.features.today.ui.widget import android.content.res.Configuration +import androidx.compose.animation.ExperimentalSharedTransitionApi +import androidx.compose.animation.SharedTransitionScope.OverlayClip +import androidx.compose.animation.SharedTransitionScope.ResizeMode +import androidx.compose.animation.SharedTransitionScope.SharedContentState import androidx.compose.foundation.MarqueeSpacing import androidx.compose.foundation.background import androidx.compose.foundation.basicMarquee @@ -50,13 +56,18 @@ import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.geometry.Rect import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.GraphicsLayerScope +import androidx.compose.ui.graphics.Path import androidx.compose.ui.graphics.graphicsLayer +import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.layout.onPlaced import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.Density +import androidx.compose.ui.unit.LayoutDirection import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.min import androidx.compose.ui.zIndex @@ -64,10 +75,19 @@ import cz.lastaapps.api.core.domain.model.dish.Dish import cz.lastaapps.api.core.domain.model.dish.DishCategory import cz.lastaapps.core.util.extensions.mapIf import cz.lastaapps.menza.features.today.domain.model.TodayUserSettings +import cz.lastaapps.menza.features.today.ui.util.dishContainerKey +import cz.lastaapps.menza.features.today.ui.util.dishImageKey +import cz.lastaapps.menza.features.today.ui.util.dishTitleKey import cz.lastaapps.menza.ui.components.NoItems import cz.lastaapps.menza.ui.components.PullToRefreshWrapper import cz.lastaapps.menza.ui.theme.Padding +import cz.lastaapps.menza.ui.util.AnimationScopes +import cz.lastaapps.menza.ui.util.OverlayParentClip import cz.lastaapps.menza.ui.util.PreviewWrapper +import cz.lastaapps.menza.ui.util.sharedBounds +import cz.lastaapps.menza.ui.util.sharedContainer +import cz.lastaapps.menza.ui.util.sharedElement +import cz.lastaapps.menza.ui.util.skipToLookaheadSize import kotlinx.collections.immutable.ImmutableList @Composable @@ -83,6 +103,7 @@ internal fun TodayDishCarousel( header: @Composable (Modifier) -> Unit, footer: @Composable (Modifier) -> Unit, scroll: LazyListState, + scopes: AnimationScopes, modifier: Modifier = Modifier, ) { PullToRefreshWrapper( @@ -90,7 +111,17 @@ internal fun TodayDishCarousel( onRefresh = onRefresh, modifier = modifier.fillMaxWidth(), ) { - Surface(shape = MaterialTheme.shapes.large) { + Surface( + shape = MaterialTheme.shapes.large, + modifier = + Modifier + // required so the individual items are properly clipped + .sharedContainer( + scopes, + "today_dish_list", + clipInOverlayDuringTransitionShape = MaterialTheme.shapes.large, + ), + ) { DishContent( data = data, onDish = onDish, @@ -101,6 +132,7 @@ internal fun TodayDishCarousel( scroll = scroll, header = header, footer = footer, + scopes = scopes, modifier = Modifier .padding(top = Padding.Smaller) // so text is not cut off @@ -123,6 +155,7 @@ private fun DishContent( scroll: LazyListState, header: @Composable (Modifier) -> Unit, footer: @Composable (Modifier) -> Unit, + scopes: AnimationScopes, modifier: Modifier = Modifier, ) { var maxWidth by remember { mutableIntStateOf(0) } @@ -187,6 +220,8 @@ private fun DishContent( onRating = onRating, appSettings = appSettings, isOnMetered = isOnMetered, + scopes = scopes, + size = null, modifier = Modifier .height(preferredItemSize), @@ -201,8 +236,11 @@ private fun DishContent( HorizontalMultiBrowseCarousel( state = carouselState, preferredItemWidth = preferredItemSize, - minSmallItemWidth = 64.dp, - maxSmallItemWidth = 128.dp, + // TODO revert +// minSmallItemWidth = 64.dp, +// maxSmallItemWidth = 128.dp, + minSmallItemWidth = 20.dp, + maxSmallItemWidth = 40.dp, itemSpacing = Padding.MidSmall, modifier = Modifier @@ -236,11 +274,13 @@ private fun DishContent( onRating = onRating, appSettings = appSettings, isOnMetered = isOnMetered, + scopes = scopes, + size = { carouselItemDrawInfo.size }, + progress = { progress }, modifier = Modifier .height(preferredItemSize) .maskClip(MaterialTheme.shapes.extraLarge), - progress = { progress }, ) } } @@ -283,6 +323,8 @@ private fun DishItem( onRating: (Dish) -> Unit, appSettings: TodayUserSettings, isOnMetered: Boolean, + scopes: AnimationScopes, + size: (() -> Float)?, modifier: Modifier = Modifier, progress: () -> Float = { 1f }, ) { @@ -301,8 +343,53 @@ private fun DishItem( scaleY = prog / 2f + 0.5f } + val shape = MaterialTheme.shapes.extraLarge Box( - modifier = modifier.clickable { onDish(dish) }, + modifier = + modifier + .clickable { onDish(dish) } + .also { + // this is ignored for now + it + .sharedContainer( + scopes, + dishContainerKey(dish.id), + // resizeMode = ResizeMode.RemeasureToBounds, + resizeMode = + ResizeMode.ScaleToBounds( + contentScale = ContentScale.Crop, + alignment = Alignment.CenterStart, + ), + clipInOverlayDuringTransition = + object : OverlayClip { + override fun getClipPath( + sharedContentState: SharedContentState, + bounds: Rect, + layoutDirection: LayoutDirection, + density: Density, + ): Path? { + val newRect = + size?.let { + bounds.copy( + left = bounds.center.x - size() / 2f, + right = bounds.center.x + size() / 2f, + ) + bounds.copy( + right = bounds.left + size(), + ) + } ?: bounds + return OverlayParentClip(shape) + .getClipPath( + sharedContentState, + newRect, + layoutDirection, + density, + ) + } + }, + ) + .sharedElement(scopes, key = dishImageKey(dish.id)) + }, ) { DishImageOrSupplement( dish, @@ -311,6 +398,7 @@ private fun DishItem( modifier = Modifier .fillMaxSize(), + // .sharedElement(scopes, key = dishImageKey(dish.id)), // zoom in effect // the carousel does not render correctly // .graphicsLayer { @@ -363,7 +451,12 @@ private fun DishItem( iterations = Int.MAX_VALUE, velocity = 69.dp, // default: 30.dp spacing = MarqueeSpacing.fractionOfContainer(1f / 5f), - ), + ) + .also { + it + .sharedBounds(scopes, dishTitleKey(dish.id)) + .skipToLookaheadSize(scopes) + }, maxLines = 1, color = TodayDishCarouselTokens.gradientForeground.takeIf { useGradient } diff --git a/app/src/main/kotlin/cz/lastaapps/menza/features/today/ui/widget/TodayDishDetail.kt b/app/src/main/kotlin/cz/lastaapps/menza/features/today/ui/widget/TodayDishDetail.kt index 1231a188..e6f41ac9 100644 --- a/app/src/main/kotlin/cz/lastaapps/menza/features/today/ui/widget/TodayDishDetail.kt +++ b/app/src/main/kotlin/cz/lastaapps/menza/features/today/ui/widget/TodayDishDetail.kt @@ -22,6 +22,8 @@ package cz.lastaapps.menza.features.today.ui.widget import androidx.compose.animation.ExperimentalSharedTransitionApi +import androidx.compose.animation.fadeIn +import androidx.compose.animation.slideInVertically import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column @@ -100,7 +102,8 @@ fun TodayDishDetail( ) { DishImageInfo( dish = dish, - modifier = Modifier.sharedElement(scopes, dishImageKey(dish.id)), + modifier = + Modifier.sharedElement(scopes, dishImageKey(dish.id)), ) Header( @@ -110,20 +113,31 @@ fun TodayDishDetail( PriceView( dish = dish, ) - IssueLocationList( - list = dish.servingPlaces, - ) - - RatingOverview(rating = dish.rating, onRating = { onRating(dish) }) + AnimatedAppearance( + 200.milliseconds, + enter = fadeIn(), + ) { + IssueLocationList( + list = dish.servingPlaces, + ) + } - AllergenList( - allergens = dish.allergens, - ) - Ingredients( - ingredients = dish.ingredients, - ) + AnimatedAppearance( + 250.milliseconds, + enter = slideInVertically { it } + fadeIn(), + ) { + RatingOverview(rating = dish.rating, onRating = { onRating(dish) }) + } - AnimatedAppearance(400.milliseconds) { + AnimatedAppearance(350.milliseconds, enter = slideInVertically { it } + fadeIn()) { + AllergenList( + allergens = dish.allergens, + ) + } + AnimatedAppearance(350.milliseconds, enter = slideInVertically { it } + fadeIn()) { + Ingredients( + ingredients = dish.ingredients, + ) } } } diff --git a/app/src/main/kotlin/cz/lastaapps/menza/features/today/ui/widget/TodayDishGrid.kt b/app/src/main/kotlin/cz/lastaapps/menza/features/today/ui/widget/TodayDishGrid.kt index 9c2c0e7a..7bbee71b 100644 --- a/app/src/main/kotlin/cz/lastaapps/menza/features/today/ui/widget/TodayDishGrid.kt +++ b/app/src/main/kotlin/cz/lastaapps/menza/features/today/ui/widget/TodayDishGrid.kt @@ -17,8 +17,12 @@ * along with Menza. If not, see . */ +@file:OptIn(ExperimentalSharedTransitionApi::class) + package cz.lastaapps.menza.features.today.ui.widget +import androidx.compose.animation.ExperimentalSharedTransitionApi +import androidx.compose.animation.SharedTransitionScope.ResizeMode import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box @@ -45,11 +49,18 @@ import cz.lastaapps.api.core.domain.model.dish.Dish import cz.lastaapps.api.core.domain.model.dish.DishCategory import cz.lastaapps.menza.features.settings.domain.model.PriceType import cz.lastaapps.menza.features.today.domain.model.TodayUserSettings +import cz.lastaapps.menza.features.today.ui.util.dishContainerKey +import cz.lastaapps.menza.features.today.ui.util.dishImageKey +import cz.lastaapps.menza.features.today.ui.util.dishTitleKey import cz.lastaapps.menza.ui.components.NoItems import cz.lastaapps.menza.ui.components.PullToRefreshWrapper import cz.lastaapps.menza.ui.locals.LocalWindowWidth import cz.lastaapps.menza.ui.theme.Padding +import cz.lastaapps.menza.ui.util.AnimationScopes import cz.lastaapps.menza.ui.util.appCardColors +import cz.lastaapps.menza.ui.util.sharedBounds +import cz.lastaapps.menza.ui.util.sharedContainer +import cz.lastaapps.menza.ui.util.sharedElement import kotlinx.collections.immutable.ImmutableList @Composable @@ -64,6 +75,7 @@ internal fun TodayDishGrid( isOnMetered: Boolean, header: @Composable (Modifier) -> Unit, footer: @Composable (Modifier) -> Unit, + scopes: AnimationScopes, modifier: Modifier = Modifier, scrollGrid: LazyStaggeredGridState = rememberLazyStaggeredGridState(), widthSize: WindowWidthSizeClass = LocalWindowWidth.current, @@ -73,7 +85,17 @@ internal fun TodayDishGrid( onRefresh = onRefresh, modifier = modifier.fillMaxSize(), ) { - Surface(shape = MaterialTheme.shapes.large) { + Surface( + shape = MaterialTheme.shapes.large, + modifier = + Modifier + // required so the individual items are properly clipped + .sharedContainer( + scopes, + "today_dish_list", + clipInOverlayDuringTransitionShape = MaterialTheme.shapes.large, + ), + ) { DishContent( data = data, onDish = onDish, @@ -85,10 +107,8 @@ internal fun TodayDishGrid( header = header, footer = footer, widthSize = widthSize, - modifier = - Modifier - .padding(top = Padding.Smaller) // so text is not cut off - .fillMaxSize(), + scopes = scopes, + modifier = Modifier.fillMaxSize(), ) } } @@ -107,6 +127,7 @@ private fun DishContent( header: @Composable (Modifier) -> Unit, footer: @Composable (Modifier) -> Unit, widthSize: WindowWidthSizeClass, + scopes: AnimationScopes, modifier: Modifier = Modifier, ) { if (data.isEmpty()) { @@ -161,6 +182,7 @@ private fun DishContent( onRating = onRating, userSettings = userSettings, isOnMetered = isOnMetered, + scopes = scopes, modifier = Modifier.fillMaxWidth(), ) } @@ -184,12 +206,21 @@ private fun DishItem( onRating: (Dish) -> Unit, userSettings: TodayUserSettings, isOnMetered: Boolean, + scopes: AnimationScopes, modifier: Modifier = Modifier, ) { Card( colors = appCardColors(MaterialTheme.colorScheme.primaryContainer), shape = MaterialTheme.shapes.large, - modifier = modifier.clickable { onDish(dish) }, + modifier = + modifier + .clickable { onDish(dish) } + .sharedContainer( + scopes, + dishContainerKey(dish.id), + resizeMode = ResizeMode.RemeasureToBounds, + clipInOverlayDuringTransitionShape = MaterialTheme.shapes.large, + ), ) { Column( modifier = Modifier.padding(Padding.MidSmall), @@ -203,10 +234,16 @@ private fun DishItem( priceType = userSettings.priceType, downloadOnMetered = userSettings.downloadOnMetered, isOnMetered = isOnMetered, + modifier = Modifier.sharedElement(scopes, key = dishImageKey(dish.id)), ) } - DishNameRow(dish, Modifier.fillMaxWidth()) + DishNameRow( + dish = dish, + modifier = Modifier + .align(Alignment.Start) + .sharedBounds(scopes, dishTitleKey(dish.id)), + ) if (dish.photoLink == null) { DishBadgesRow(dish = dish, onRating = onRating, priceType = userSettings.priceType) } diff --git a/app/src/main/kotlin/cz/lastaapps/menza/features/today/ui/widget/TodayDishHorizontal.kt b/app/src/main/kotlin/cz/lastaapps/menza/features/today/ui/widget/TodayDishHorizontal.kt index c04adc3c..4400180a 100644 --- a/app/src/main/kotlin/cz/lastaapps/menza/features/today/ui/widget/TodayDishHorizontal.kt +++ b/app/src/main/kotlin/cz/lastaapps/menza/features/today/ui/widget/TodayDishHorizontal.kt @@ -17,9 +17,13 @@ * along with Menza. If not, see . */ +@file:OptIn(ExperimentalSharedTransitionApi::class) + package cz.lastaapps.menza.features.today.ui.widget import android.os.Build +import androidx.compose.animation.ExperimentalSharedTransitionApi +import androidx.compose.animation.SharedTransitionScope.ResizeMode import androidx.compose.animation.animateContentSize import androidx.compose.foundation.horizontalScroll import androidx.compose.foundation.layout.Arrangement @@ -53,10 +57,17 @@ import cz.lastaapps.api.core.domain.model.dish.DishCategory import cz.lastaapps.menza.R import cz.lastaapps.menza.features.settings.domain.model.PriceType import cz.lastaapps.menza.features.today.domain.model.TodayUserSettings +import cz.lastaapps.menza.features.today.ui.util.dishContainerKey +import cz.lastaapps.menza.features.today.ui.util.dishImageKey +import cz.lastaapps.menza.features.today.ui.util.dishTitleKey import cz.lastaapps.menza.ui.components.NoItems import cz.lastaapps.menza.ui.components.PullToRefreshWrapper import cz.lastaapps.menza.ui.theme.Padding +import cz.lastaapps.menza.ui.util.AnimationScopes import cz.lastaapps.menza.ui.util.appCardColors +import cz.lastaapps.menza.ui.util.sharedBounds +import cz.lastaapps.menza.ui.util.sharedContainer +import cz.lastaapps.menza.ui.util.sharedElement import kotlinx.collections.immutable.ImmutableList @Composable @@ -72,6 +83,7 @@ internal fun TodayDishHorizontal( header: @Composable (Modifier) -> Unit, footer: @Composable (Modifier) -> Unit, scroll: LazyListState, + scopes: AnimationScopes, modifier: Modifier = Modifier, ) { PullToRefreshWrapper( @@ -79,7 +91,17 @@ internal fun TodayDishHorizontal( onRefresh = onRefresh, modifier = modifier.fillMaxWidth(), ) { - Surface(shape = MaterialTheme.shapes.large) { + Surface( + shape = MaterialTheme.shapes.large, + modifier = + Modifier + // required so the individual items are properly clipped + .sharedContainer( + scopes, + "today_dish_list", + clipInOverlayDuringTransitionShape = MaterialTheme.shapes.large, + ), + ) { DishContent( data = data, onDish = onDish, @@ -90,10 +112,8 @@ internal fun TodayDishHorizontal( scroll = scroll, header = header, footer = footer, - modifier = - Modifier - .padding(top = Padding.Smaller) // so text is not cut off - .fillMaxSize(), + scopes = scopes, + modifier = Modifier.fillMaxSize(), ) } } @@ -111,6 +131,7 @@ private fun DishContent( scroll: LazyListState, header: @Composable (Modifier) -> Unit, footer: @Composable (Modifier) -> Unit, + scopes: AnimationScopes, modifier: Modifier = Modifier, ) { // no data handling @@ -151,6 +172,7 @@ private fun DishContent( onDish = onDish, userSettings = userSettings, isOnMetered = isOnMetered, + scopes = scopes, modifier = Modifier .fillMaxWidth(), @@ -167,6 +189,7 @@ private fun DishContent( onDish = onDish, userSettings = userSettings, isOnMetered = isOnMetered, + scopes = scopes, modifier = @Suppress("ktlint:compose:modifier-not-used-at-root") modifier.sizeIn(maxWidth = 256.dp), ) @@ -243,13 +266,21 @@ private fun DishItem( onDish: (Dish) -> Unit, userSettings: TodayUserSettings, isOnMetered: Boolean, + scopes: AnimationScopes, modifier: Modifier = Modifier, ) { Card( onClick = { onDish(dish) }, colors = appCardColors(MaterialTheme.colorScheme.primaryContainer), shape = MaterialTheme.shapes.large, - modifier = modifier, + modifier = + modifier + .sharedContainer( + scopes, + dishContainerKey(dish.id), + resizeMode = ResizeMode.RemeasureToBounds, + clipInOverlayDuringTransitionShape = MaterialTheme.shapes.large, + ), ) { Column( modifier = Modifier.padding(Padding.MidSmall), @@ -261,20 +292,16 @@ private fun DishItem( priceType = userSettings.priceType, downloadOnMetered = userSettings.downloadOnMetered, isOnMetered = isOnMetered, + modifier = Modifier.sharedElement(scopes, key = dishImageKey(dish.id)), ) Column( verticalArrangement = Arrangement.spacedBy(Padding.Small), ) { - Row( - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.spacedBy(Padding.Smaller), - ) { - DishNameRow( - dish = dish, - modifier = Modifier.weight(1f), - ) - } + DishNameRow( + dish = dish, + modifier = Modifier.sharedBounds(scopes, dishTitleKey(dish.id)), + ) DishInfoRow(dish) } diff --git a/app/src/main/kotlin/cz/lastaapps/menza/features/today/ui/widget/TodayDishList.kt b/app/src/main/kotlin/cz/lastaapps/menza/features/today/ui/widget/TodayDishList.kt index 3452484b..0feb6a2a 100644 --- a/app/src/main/kotlin/cz/lastaapps/menza/features/today/ui/widget/TodayDishList.kt +++ b/app/src/main/kotlin/cz/lastaapps/menza/features/today/ui/widget/TodayDishList.kt @@ -257,7 +257,7 @@ private fun DishItem( label = "image_scale", ).value, isOnMetered = isOnMetered, - scopes = scopes, + modifier = Modifier.sharedElement(scopes, key = dishImageKey(dish.id)), ) DishNameRow( @@ -289,11 +289,10 @@ private fun DishImageWithBadge( downloadOnMetered: Boolean, imageScale: Float, isOnMetered: Boolean, - scopes: AnimationScopes, modifier: Modifier = Modifier, ) { Box( - modifier = modifier.sharedElement(scopes, key = dishImageKey(dish.id)), + modifier = modifier, ) { DishImageWithPlaceholder( photoLink = dish.photoLink, diff --git a/app/src/main/kotlin/cz/lastaapps/menza/ui/util/AnimationScopes.kt b/app/src/main/kotlin/cz/lastaapps/menza/ui/util/AnimationScopes.kt index 542d90e2..1ba1fa4e 100644 --- a/app/src/main/kotlin/cz/lastaapps/menza/ui/util/AnimationScopes.kt +++ b/app/src/main/kotlin/cz/lastaapps/menza/ui/util/AnimationScopes.kt @@ -162,6 +162,11 @@ fun Modifier.renderInSharedTransitionScopeOverlay( ) } +fun Modifier.skipToLookaheadSize(scopes: AnimationScopes): Modifier = + with(scopes.sharedTransitionScope) { + this@skipToLookaheadSize.skipToLookaheadSize() + } + fun OverlayParentClip(roundedCorner: Dp = 0.dp): OverlayClip = OverlayParentClip(RoundedCornerShape(roundedCorner)) fun OverlayParentClip(shape: Shape): OverlayClip =