From 9f2b3799da09be113c47c4f4428df89c332630d5 Mon Sep 17 00:00:00 2001 From: imashnake0 Date: Mon, 5 Feb 2024 01:35:07 -0500 Subject: [PATCH 1/6] Created `BannerLayout` --- .../animite/features/home/HomeScreen.kt | 132 +++++++-------- .../animite/features/media/MediaPage.kt | 152 ++++++++---------- app/src/main/res/values/dimens.xml | 1 - ...ableText.kt => NestedScrollableContent.kt} | 2 +- .../animite/core/ui/layouts/BannerLayout.kt | 46 ++++++ .../ui/layouts/TranslucentStatusBarLayout.kt | 34 ++-- core/src/main/res/values/dimens.xml | 2 + 7 files changed, 200 insertions(+), 169 deletions(-) rename core/src/main/kotlin/com/imashnake/animite/core/ui/{ScrollableText.kt => NestedScrollableContent.kt} (97%) create mode 100644 core/src/main/kotlin/com/imashnake/animite/core/ui/layouts/BannerLayout.kt diff --git a/app/src/main/java/com/imashnake/animite/features/home/HomeScreen.kt b/app/src/main/java/com/imashnake/animite/features/home/HomeScreen.kt index cde0f838..522e171d 100644 --- a/app/src/main/java/com/imashnake/animite/features/home/HomeScreen.kt +++ b/app/src/main/java/com/imashnake/animite/features/home/HomeScreen.kt @@ -7,7 +7,6 @@ import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height @@ -61,6 +60,7 @@ import com.ramcosta.composedestinations.annotation.Destination import com.ramcosta.composedestinations.navigation.DestinationsNavigator import com.imashnake.animite.R import com.imashnake.animite.core.ui.LocalPaddings +import com.imashnake.animite.core.ui.layouts.BannerLayout @Destination @Composable @@ -87,88 +87,76 @@ fun HomeScreen( when { rows.all { it.first is Resource.Success } -> { val scrollState = rememberScrollState() - TranslucentStatusBarLayout( - scrollState = scrollState, - distanceUntilAnimated = dimensionResource(R.dimen.banner_height) - ) { + TranslucentStatusBarLayout(scrollState) { Box( modifier = Modifier .verticalScroll(scrollState) .navigationBarsPadding() ) { - Box { - Image( - painter = painterResource(R.drawable.background), - contentDescription = null, - modifier = Modifier - .fillMaxWidth() - .height(dimensionResource(R.dimen.banner_height)) - .bannerParallax(scrollState), - contentScale = ContentScale.Crop, - alignment = Alignment.TopCenter - ) + BannerLayout( + banner = { bannerModifier -> + Box { + Image( + painter = painterResource(R.drawable.background), + contentDescription = null, + modifier = bannerModifier.bannerParallax(scrollState), + contentScale = ContentScale.Crop, + alignment = Alignment.TopCenter + ) - Box( - modifier = Modifier - .background( - Brush.verticalGradient( - listOf( - Color.Transparent, - MaterialTheme.colorScheme.secondaryContainer.copy( - alpha = 0.5f + Box( + modifier = bannerModifier + .background( + Brush.verticalGradient( + listOf( + Color.Transparent, + MaterialTheme.colorScheme.secondaryContainer.copy( + alpha = 0.5f + ) + ) ) ) - ) - ) - .fillMaxWidth() - .height(dimensionResource(R.dimen.banner_height)) - ) { } + ) { } - Row( - modifier = Modifier - .fillMaxWidth() - .align(Alignment.BottomCenter), - horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically - ) { - Text( - text = stringResource(R.string.okaeri), - color = MaterialTheme.colorScheme.onSecondaryContainer, - style = MaterialTheme.typography.displayMedium, - modifier = Modifier - .padding( - start = LocalPaddings.current.large, - bottom = LocalPaddings.current.medium + Row( + modifier = Modifier + .fillMaxWidth() + .align(Alignment.BottomCenter), + horizontalArrangement = Arrangement.SpaceBetween, + verticalAlignment = Alignment.CenterVertically + ) { + Text( + text = stringResource(R.string.okaeri), + color = MaterialTheme.colorScheme.onSecondaryContainer, + style = MaterialTheme.typography.displayMedium, + modifier = Modifier + .padding( + start = LocalPaddings.current.large, + bottom = LocalPaddings.current.medium + ) + .landscapeCutoutPadding() + .weight(1f, fill = false), + maxLines = 1 ) - .landscapeCutoutPadding() - .weight(1f, fill = false), - maxLines = 1 - ) - MediaTypeSelector( - modifier = Modifier - .padding( - end = LocalPaddings.current.large, - bottom = LocalPaddings.current.medium + MediaTypeSelector( + modifier = Modifier + .padding( + end = LocalPaddings.current.large, + bottom = LocalPaddings.current.medium + ) + .landscapeCutoutPadding(), + selectedOption = homeMediaType, + viewModel = viewModel ) - .landscapeCutoutPadding(), - selectedOption = homeMediaType, - viewModel = viewModel - ) - } - } - - Column { - Spacer(Modifier.size(dimensionResource(R.dimen.banner_height))) - - Column( - modifier = Modifier - .background(MaterialTheme.colorScheme.background) - .padding(vertical = LocalPaddings.current.large) - // TODO: Move this one out of Home when we can pass modifiers in. - .padding(bottom = dimensionResource(R.dimen.navigation_bar_height)), - verticalArrangement = Arrangement.spacedBy(LocalPaddings.current.large) - ) { + } + } + }, + contentModifier = Modifier.padding( + top = LocalPaddings.current.large, + bottom = dimensionResource(R.dimen.navigation_bar_height) + ), + content = { _ -> rows.fastForEach { row -> HomeRow( list = row.first.data.orEmpty(), @@ -188,7 +176,7 @@ fun HomeScreen( ) } } - } + ) } } } diff --git a/app/src/main/java/com/imashnake/animite/features/media/MediaPage.kt b/app/src/main/java/com/imashnake/animite/features/media/MediaPage.kt index 967ff453..ad583e9d 100644 --- a/app/src/main/java/com/imashnake/animite/features/media/MediaPage.kt +++ b/app/src/main/java/com/imashnake/animite/features/media/MediaPage.kt @@ -73,6 +73,7 @@ import com.imashnake.animite.core.extensions.bannerParallax import com.imashnake.animite.core.extensions.landscapeCutoutPadding import com.imashnake.animite.core.ui.LocalPaddings import com.imashnake.animite.core.ui.NestedScrollableContent +import com.imashnake.animite.core.ui.layouts.BannerLayout import com.imashnake.animite.core.ui.layouts.TranslucentStatusBarLayout import com.imashnake.animite.dev.internal.Constants import com.imashnake.animite.features.ui.MediaSmall @@ -90,14 +91,12 @@ fun MediaPage( viewModel: MediaPageViewModel = hiltViewModel() ) { val scrollState = rememberScrollState() - val bannerHeight = dimensionResource(R.dimen.banner_height) val media = viewModel.uiState MaterialTheme(colorScheme = rememberColorSchemeFor(color = media.color)) { TranslucentStatusBarLayout( scrollState = scrollState, - distanceUntilAnimated = bannerHeight, modifier = Modifier.background(MaterialTheme.colorScheme.background) ) { Box( @@ -105,92 +104,83 @@ fun MediaPage( .fillMaxSize() .verticalScroll(scrollState) ) { - MediaBanner( - imageUrl = media.bannerImage, - tintColor = Color(media.color ?: 0).copy(alpha = 0.25f), - modifier = Modifier - .height(bannerHeight) - .fillMaxWidth() - .bannerParallax(scrollState) - ) - - Column( - modifier = Modifier - .fillMaxHeight() - .padding(top = bannerHeight) - .background(MaterialTheme.colorScheme.background) - .padding(bottom = LocalPaddings.current.large) - .navigationBarsPadding(), - verticalArrangement = Arrangement.spacedBy(LocalPaddings.current.large) - ) { - MediaDetails( - title = media.title.orEmpty(), - description = media.description.orEmpty(), - // TODO: Can we do something about this Modifier chain? - // Fix this in a follow up PR with `BannerLayout`. - modifier = Modifier - .padding( - start = LocalPaddings.current.large - + dimensionResource(R.dimen.media_card_width) - + LocalPaddings.current.large, - top = LocalPaddings.current.medium, - end = LocalPaddings.current.large - ) - .landscapeCutoutPadding() - .height( - WindowInsets.statusBars - .asPaddingValues() - .calculateTopPadding() - + dimensionResource(R.dimen.media_card_top_padding) - + dimensionResource(R.dimen.media_card_height) - - dimensionResource(R.dimen.banner_height) - - LocalPaddings.current.medium - ) - .fillMaxSize() - ) - - if (!media.ranks.isNullOrEmpty()) { - MediaRankings( - rankings = media.ranks, + BannerLayout( + banner = { bannerModifier -> + MediaBanner( + imageUrl = media.bannerImage, + tintColor = Color(media.color ?: 0).copy(alpha = 0.25f), + modifier = bannerModifier.bannerParallax(scrollState) + ) + }, + content = { bannerHeight -> + MediaDetails( + title = media.title.orEmpty(), + description = media.description.orEmpty(), + // TODO: Can we do something about this Modifier chain? + // Fix this in a follow up PR with `BannerLayout`. modifier = Modifier - .fillMaxWidth() - .padding(horizontal = LocalPaddings.current.large) + .padding( + start = LocalPaddings.current.large + + dimensionResource(R.dimen.media_card_width) + + LocalPaddings.current.large, + end = LocalPaddings.current.large + ) .landscapeCutoutPadding() + .height( + WindowInsets.statusBars + .asPaddingValues() + .calculateTopPadding() + + dimensionResource(R.dimen.media_card_top_padding) + + dimensionResource(R.dimen.media_card_height) + - bannerHeight + - LocalPaddings.current.medium + ) + .fillMaxSize() ) - } - if (!media.genres.isNullOrEmpty()) { - MediaGenres( - genres = media.genres, - contentPadding = PaddingValues( - start = LocalPaddings.current.large + if ( - LocalConfiguration.current.orientation == Configuration.ORIENTATION_LANDSCAPE - ) { - WindowInsets.displayCutout.asPaddingValues() - .calculateLeftPadding(LayoutDirection.Ltr) - } else 0.dp, - end = LocalPaddings.current.large - ), - color = Color(media.color ?: 0xFF152232.toInt()), - ) - } + if (!media.ranks.isNullOrEmpty()) { + MediaRankings( + rankings = media.ranks, + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = LocalPaddings.current.large) + .landscapeCutoutPadding() + ) + } - if (!media.characters.isNullOrEmpty()) { - MediaCharacters( - characters = media.characters, - contentPadding = PaddingValues(horizontal = LocalPaddings.current.large) - ) - } + if (!media.genres.isNullOrEmpty()) { + MediaGenres( + genres = media.genres, + contentPadding = PaddingValues( + start = LocalPaddings.current.large + if ( + LocalConfiguration.current.orientation == Configuration.ORIENTATION_LANDSCAPE + ) { + WindowInsets.displayCutout.asPaddingValues() + .calculateLeftPadding(LayoutDirection.Ltr) + } else 0.dp, + end = LocalPaddings.current.large + ), + color = Color(media.color ?: 0xFF152232.toInt()), + ) + } - if (media.trailer != null) { - MediaTrailer( - trailer = media.trailer, - modifier = Modifier - .padding(horizontal = LocalPaddings.current.large) - .landscapeCutoutPadding() - ) + if (!media.characters.isNullOrEmpty()) { + MediaCharacters( + characters = media.characters, + contentPadding = PaddingValues(horizontal = LocalPaddings.current.large) + ) + } + + if (media.trailer != null) { + MediaTrailer( + trailer = media.trailer, + modifier = Modifier + .padding(horizontal = LocalPaddings.current.large) + .landscapeCutoutPadding() + ) + } } - } + ) Box( modifier = Modifier diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index e07e6db8..e4377adf 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -6,7 +6,6 @@ 65dp - 168dp 140dp 200dp 96dp diff --git a/core/src/main/kotlin/com/imashnake/animite/core/ui/ScrollableText.kt b/core/src/main/kotlin/com/imashnake/animite/core/ui/NestedScrollableContent.kt similarity index 97% rename from core/src/main/kotlin/com/imashnake/animite/core/ui/ScrollableText.kt rename to core/src/main/kotlin/com/imashnake/animite/core/ui/NestedScrollableContent.kt index 577821de..9d43572c 100644 --- a/core/src/main/kotlin/com/imashnake/animite/core/ui/ScrollableText.kt +++ b/core/src/main/kotlin/com/imashnake/animite/core/ui/NestedScrollableContent.kt @@ -23,7 +23,7 @@ fun NestedScrollableContent( modifier: Modifier = Modifier, gradientSize: Dp = dimensionResource(R.dimen.edge_gradient_size), gradientColor: Color = MaterialTheme.colorScheme.background, - content: @Composable (modifier: Modifier) -> Unit, + content: @Composable (Modifier) -> Unit, ) { Box(modifier) { content(Modifier.verticalScroll(rememberScrollState()).padding(vertical = gradientSize)) diff --git a/core/src/main/kotlin/com/imashnake/animite/core/ui/layouts/BannerLayout.kt b/core/src/main/kotlin/com/imashnake/animite/core/ui/layouts/BannerLayout.kt new file mode 100644 index 00000000..530aa96b --- /dev/null +++ b/core/src/main/kotlin/com/imashnake/animite/core/ui/layouts/BannerLayout.kt @@ -0,0 +1,46 @@ +package com.imashnake.animite.core.ui.layouts + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.navigationBarsPadding +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.MaterialTheme +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.dimensionResource +import androidx.compose.ui.unit.Dp +import com.imashnake.animite.core.R +import com.imashnake.animite.core.ui.LocalPaddings + +@Composable +fun BannerLayout( + banner: @Composable (Modifier) -> Unit, + content: @Composable (bannerHeight: Dp) -> Unit, + modifier: Modifier = Modifier, + contentModifier: Modifier = Modifier, + bannerHeight: Dp = dimensionResource(R.dimen.banner_height) +) { + Box(modifier) { + banner( + Modifier + .height(bannerHeight) + .fillMaxWidth() + ) + + Column( + modifier = Modifier + .fillMaxSize() + .padding(top = bannerHeight) + .background(MaterialTheme.colorScheme.background) + .padding(bottom = LocalPaddings.current.large) + .navigationBarsPadding() + .then(contentModifier), + verticalArrangement = Arrangement.spacedBy(LocalPaddings.current.large) + ) { content(bannerHeight) } + } +} diff --git a/core/src/main/kotlin/com/imashnake/animite/core/ui/layouts/TranslucentStatusBarLayout.kt b/core/src/main/kotlin/com/imashnake/animite/core/ui/layouts/TranslucentStatusBarLayout.kt index cd265d9c..861a81d1 100644 --- a/core/src/main/kotlin/com/imashnake/animite/core/ui/layouts/TranslucentStatusBarLayout.kt +++ b/core/src/main/kotlin/com/imashnake/animite/core/ui/layouts/TranslucentStatusBarLayout.kt @@ -12,14 +12,16 @@ import androidx.compose.ui.draw.drawWithContent import androidx.compose.ui.geometry.Size import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalDensity +import androidx.compose.ui.res.dimensionResource import androidx.compose.ui.unit.Dp +import com.imashnake.animite.core.R @Composable @Suppress("LongParameterList") fun TranslucentStatusBarLayout( scrollState: ScrollState, - distanceUntilAnimated: Dp, modifier: Modifier = Modifier, + distanceUntilAnimated: Dp = dimensionResource(R.dimen.banner_height), targetAlpha: Float = ContentAlpha.medium, targetColor: Color = MaterialTheme.colorScheme.background, content: @Composable () -> Unit @@ -28,20 +30,24 @@ fun TranslucentStatusBarLayout( val distanceUntilAnimatedPx = with(LocalDensity.current) { distanceUntilAnimated.toPx() } val statusBarInsets = WindowInsets.statusBars Box( - Modifier.drawWithContent { - drawContent() - drawRect( - color = targetColor.copy( - alpha = targetAlpha * if (scrollState.value < distanceUntilAnimatedPx) { - scrollState.value.toFloat() / distanceUntilAnimatedPx - } else 1f - ), - size = Size( - width = size.width, - height = statusBarInsets.getTop(this).toFloat() + Modifier + .drawWithContent { + drawContent() + drawRect( + color = targetColor.copy( + alpha = targetAlpha * if (scrollState.value < distanceUntilAnimatedPx) { + scrollState.value.toFloat() / distanceUntilAnimatedPx + } else 1f + ), + size = Size( + width = size.width, + height = statusBarInsets + .getTop(this) + .toFloat() + ) ) - ) - }.then(modifier) + } + .then(modifier) ) { content() } diff --git a/core/src/main/res/values/dimens.xml b/core/src/main/res/values/dimens.xml index 3a928496..7b4b72bd 100644 --- a/core/src/main/res/values/dimens.xml +++ b/core/src/main/res/values/dimens.xml @@ -14,4 +14,6 @@ 16dp 56dp + + 168dp From 09d513b9ea3f9803371e37eb04b085a51a84dfb7 Mon Sep 17 00:00:00 2001 From: imashnake0 Date: Mon, 5 Feb 2024 02:03:58 -0500 Subject: [PATCH 2/6] Add top padding --- .../main/java/com/imashnake/animite/features/media/MediaPage.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/java/com/imashnake/animite/features/media/MediaPage.kt b/app/src/main/java/com/imashnake/animite/features/media/MediaPage.kt index ad583e9d..b0a2246a 100644 --- a/app/src/main/java/com/imashnake/animite/features/media/MediaPage.kt +++ b/app/src/main/java/com/imashnake/animite/features/media/MediaPage.kt @@ -112,6 +112,7 @@ fun MediaPage( modifier = bannerModifier.bannerParallax(scrollState) ) }, + contentModifier = Modifier.padding(top = LocalPaddings.current.medium), content = { bannerHeight -> MediaDetails( title = media.title.orEmpty(), From 902ab9a7d8ec52c14c577390e2c31a46146231b0 Mon Sep 17 00:00:00 2001 From: imashnake0 Date: Mon, 5 Feb 2024 02:41:35 -0500 Subject: [PATCH 3/6] `MediaDetails` dictates baseline --- .../animite/features/media/MediaPage.kt | 39 +++++++------------ app/src/main/res/values/dimens.xml | 2 +- 2 files changed, 15 insertions(+), 26 deletions(-) diff --git a/app/src/main/java/com/imashnake/animite/features/media/MediaPage.kt b/app/src/main/java/com/imashnake/animite/features/media/MediaPage.kt index b0a2246a..b9d2ef7a 100644 --- a/app/src/main/java/com/imashnake/animite/features/media/MediaPage.kt +++ b/app/src/main/java/com/imashnake/animite/features/media/MediaPage.kt @@ -19,11 +19,9 @@ import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.asPaddingValues import androidx.compose.foundation.layout.aspectRatio import androidx.compose.foundation.layout.displayCutout -import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.statusBars import androidx.compose.foundation.layout.statusBarsPadding @@ -113,12 +111,10 @@ fun MediaPage( ) }, contentModifier = Modifier.padding(top = LocalPaddings.current.medium), - content = { bannerHeight -> + content = { MediaDetails( title = media.title.orEmpty(), description = media.description.orEmpty(), - // TODO: Can we do something about this Modifier chain? - // Fix this in a follow up PR with `BannerLayout`. modifier = Modifier .padding( start = LocalPaddings.current.large @@ -127,16 +123,7 @@ fun MediaPage( end = LocalPaddings.current.large ) .landscapeCutoutPadding() - .height( - WindowInsets.statusBars - .asPaddingValues() - .calculateTopPadding() - + dimensionResource(R.dimen.media_card_top_padding) - + dimensionResource(R.dimen.media_card_height) - - bannerHeight - - LocalPaddings.current.medium - ) - .fillMaxSize() + .height(dimensionResource(R.dimen.media_details_height)) ) if (!media.ranks.isNullOrEmpty()) { @@ -183,22 +170,24 @@ fun MediaPage( } ) - Box( + MediaSmall( + image = media.coverImage, + label = null, + onClick = {}, modifier = Modifier .statusBarsPadding() + // TODO: Try using `AlignmentLine`s. .padding( - top = dimensionResource(R.dimen.media_card_top_padding), + top = dimensionResource(R.dimen.media_details_height) + + LocalPaddings.current.medium + + dimensionResource(coreR.dimen.banner_height) + - WindowInsets.statusBars.asPaddingValues().calculateTopPadding() + - dimensionResource(R.dimen.media_card_height), start = LocalPaddings.current.large ) .landscapeCutoutPadding() - ) { - MediaSmall( - image = media.coverImage, - label = null, - onClick = {}, - modifier = Modifier.width(dimensionResource(R.dimen.media_card_width)) - ) - } + .width(dimensionResource(R.dimen.media_card_width)) + ) } } } diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index e4377adf..5f7d8bda 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -8,7 +8,7 @@ 140dp 200dp - 96dp + 172dp 96dp 30dp From d34f6fb0ad234296a80a27ead24d5a2d2eaa7e5b Mon Sep 17 00:00:00 2001 From: imashnake0 Date: Mon, 5 Feb 2024 03:32:43 -0500 Subject: [PATCH 4/6] Not squishy animation (bounds) --- .../animite/features/media/MediaPage.kt | 21 +++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/imashnake/animite/features/media/MediaPage.kt b/app/src/main/java/com/imashnake/animite/features/media/MediaPage.kt index b9d2ef7a..f248eb02 100644 --- a/app/src/main/java/com/imashnake/animite/features/media/MediaPage.kt +++ b/app/src/main/java/com/imashnake/animite/features/media/MediaPage.kt @@ -6,6 +6,8 @@ import android.net.Uri import android.text.method.LinkMovementMethod import android.util.Log import android.widget.TextView +import androidx.compose.animation.core.animateDpAsState +import androidx.compose.animation.core.tween import androidx.compose.foundation.BorderStroke import androidx.compose.foundation.Image import androidx.compose.foundation.background @@ -170,6 +172,17 @@ fun MediaPage( } ) + // TODO: https://developer.android.com/jetpack/compose/animation/quick-guide#concurrent-animations + val offset by animateDpAsState( + targetValue = if (scrollState.value == 0) { + 0.dp + } else { + dimensionResource(R.dimen.media_card_height) - dimensionResource(R.dimen.media_details_height) + }, + animationSpec = tween(durationMillis = 750), + label = "media_card_height" + ) + MediaSmall( image = media.coverImage, label = null, @@ -181,11 +194,15 @@ fun MediaPage( top = dimensionResource(R.dimen.media_details_height) + LocalPaddings.current.medium + dimensionResource(coreR.dimen.banner_height) - - WindowInsets.statusBars.asPaddingValues().calculateTopPadding() - - dimensionResource(R.dimen.media_card_height), + - WindowInsets.statusBars + .asPaddingValues() + .calculateTopPadding() + - dimensionResource(R.dimen.media_card_height) + + offset, start = LocalPaddings.current.large ) .landscapeCutoutPadding() + .height(dimensionResource(R.dimen.media_card_height) - offset) .width(dimensionResource(R.dimen.media_card_width)) ) } From 2ab2ab06d5cec353e2c1ce3f3e00f2cc9d62a9a9 Mon Sep 17 00:00:00 2001 From: imashnake0 Date: Mon, 5 Feb 2024 04:39:26 -0500 Subject: [PATCH 5/6] Documentation and reorder params --- .../animite/features/home/HomeScreen.kt | 10 ++++---- .../animite/features/media/MediaPage.kt | 4 ++-- .../animite/core/ui/layouts/BannerLayout.kt | 23 ++++++++++++++----- 3 files changed, 24 insertions(+), 13 deletions(-) diff --git a/app/src/main/java/com/imashnake/animite/features/home/HomeScreen.kt b/app/src/main/java/com/imashnake/animite/features/home/HomeScreen.kt index 522e171d..fe14d53d 100644 --- a/app/src/main/java/com/imashnake/animite/features/home/HomeScreen.kt +++ b/app/src/main/java/com/imashnake/animite/features/home/HomeScreen.kt @@ -152,10 +152,6 @@ fun HomeScreen( } } }, - contentModifier = Modifier.padding( - top = LocalPaddings.current.large, - bottom = dimensionResource(R.dimen.navigation_bar_height) - ), content = { _ -> rows.fastForEach { row -> HomeRow( @@ -175,7 +171,11 @@ fun HomeScreen( } ) } - } + }, + contentModifier = Modifier.padding( + top = LocalPaddings.current.large, + bottom = dimensionResource(R.dimen.navigation_bar_height) + ) ) } } diff --git a/app/src/main/java/com/imashnake/animite/features/media/MediaPage.kt b/app/src/main/java/com/imashnake/animite/features/media/MediaPage.kt index f248eb02..9bcc79f8 100644 --- a/app/src/main/java/com/imashnake/animite/features/media/MediaPage.kt +++ b/app/src/main/java/com/imashnake/animite/features/media/MediaPage.kt @@ -112,7 +112,6 @@ fun MediaPage( modifier = bannerModifier.bannerParallax(scrollState) ) }, - contentModifier = Modifier.padding(top = LocalPaddings.current.medium), content = { MediaDetails( title = media.title.orEmpty(), @@ -169,7 +168,8 @@ fun MediaPage( .landscapeCutoutPadding() ) } - } + }, + contentModifier = Modifier.padding(top = LocalPaddings.current.medium) ) // TODO: https://developer.android.com/jetpack/compose/animation/quick-guide#concurrent-animations diff --git a/core/src/main/kotlin/com/imashnake/animite/core/ui/layouts/BannerLayout.kt b/core/src/main/kotlin/com/imashnake/animite/core/ui/layouts/BannerLayout.kt index 530aa96b..b50ce2ae 100644 --- a/core/src/main/kotlin/com/imashnake/animite/core/ui/layouts/BannerLayout.kt +++ b/core/src/main/kotlin/com/imashnake/animite/core/ui/layouts/BannerLayout.kt @@ -17,20 +17,31 @@ import androidx.compose.ui.unit.Dp import com.imashnake.animite.core.R import com.imashnake.animite.core.ui.LocalPaddings +/** + * Most screens and pages follow a banner-style layout in Animite. + * + * @param banner A banner [Composable] that is usually an image with + * [com.imashnake.animite.core.extensions.bannerParallax] and other components. + * @param content The content that appears in a [Column] below the banner. + * @param modifier Modifier for [BannerLayout]. + * @param bannerHeight The height of the banner in [Dp]s. + * @param bannerModifier Modifier for [banner]. Use this if a [Composable] in [banner] should have + * the dimensions of the banner. + * @param contentModifier Modifier for [content]. + */ @Composable fun BannerLayout( banner: @Composable (Modifier) -> Unit, content: @Composable (bannerHeight: Dp) -> Unit, modifier: Modifier = Modifier, + bannerHeight: Dp = dimensionResource(R.dimen.banner_height), + bannerModifier: Modifier = Modifier + .height(bannerHeight) + .fillMaxWidth(), contentModifier: Modifier = Modifier, - bannerHeight: Dp = dimensionResource(R.dimen.banner_height) ) { Box(modifier) { - banner( - Modifier - .height(bannerHeight) - .fillMaxWidth() - ) + banner(bannerModifier) Column( modifier = Modifier From 8ce814d37f0687f6a548de7b9a8653ec43bbfaad Mon Sep 17 00:00:00 2001 From: imashnake0 Date: Mon, 5 Feb 2024 04:50:56 -0500 Subject: [PATCH 6/6] `bannerHeight` is never used --- .../java/com/imashnake/animite/features/home/HomeScreen.kt | 2 +- .../com/imashnake/animite/core/ui/layouts/BannerLayout.kt | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/imashnake/animite/features/home/HomeScreen.kt b/app/src/main/java/com/imashnake/animite/features/home/HomeScreen.kt index fe14d53d..66b7857e 100644 --- a/app/src/main/java/com/imashnake/animite/features/home/HomeScreen.kt +++ b/app/src/main/java/com/imashnake/animite/features/home/HomeScreen.kt @@ -152,7 +152,7 @@ fun HomeScreen( } } }, - content = { _ -> + content = { rows.fastForEach { row -> HomeRow( list = row.first.data.orEmpty(), diff --git a/core/src/main/kotlin/com/imashnake/animite/core/ui/layouts/BannerLayout.kt b/core/src/main/kotlin/com/imashnake/animite/core/ui/layouts/BannerLayout.kt index b50ce2ae..23d6a972 100644 --- a/core/src/main/kotlin/com/imashnake/animite/core/ui/layouts/BannerLayout.kt +++ b/core/src/main/kotlin/com/imashnake/animite/core/ui/layouts/BannerLayout.kt @@ -32,7 +32,7 @@ import com.imashnake.animite.core.ui.LocalPaddings @Composable fun BannerLayout( banner: @Composable (Modifier) -> Unit, - content: @Composable (bannerHeight: Dp) -> Unit, + content: @Composable () -> Unit, modifier: Modifier = Modifier, bannerHeight: Dp = dimensionResource(R.dimen.banner_height), bannerModifier: Modifier = Modifier @@ -52,6 +52,6 @@ fun BannerLayout( .navigationBarsPadding() .then(contentModifier), verticalArrangement = Arrangement.spacedBy(LocalPaddings.current.large) - ) { content(bannerHeight) } + ) { content() } } }