From a142a40c2b369efdf07abe62c647914481fd4fb5 Mon Sep 17 00:00:00 2001 From: "Jack Boswell (boswelja)" Date: Sat, 22 Feb 2025 17:20:17 +1100 Subject: [PATCH 01/27] Gutted existing implementation --- .../animite/features/home/HomeScreen.kt | 5 +---- .../features/searchbar/SearchFrontDrop.kt | 15 +++------------ .../animite/core/extensions/ModifierExt.kt | 12 ------------ .../com/imashnake/animite/core/ui/MediaSmall.kt | 16 +--------------- .../com/imashnake/animite/media/MediaPage.kt | 16 +--------------- .../animite/navigation/NavigationBar.kt | 9 +-------- .../imashnake/animite/profile/ProfileScreen.kt | 6 ------ .../com/imashnake/animite/profile/tabs/About.kt | 3 --- 8 files changed, 7 insertions(+), 75 deletions(-) diff --git a/app/src/main/kotlin/com/imashnake/animite/features/home/HomeScreen.kt b/app/src/main/kotlin/com/imashnake/animite/features/home/HomeScreen.kt index 0bd8b632..9c7801c4 100644 --- a/app/src/main/kotlin/com/imashnake/animite/features/home/HomeScreen.kt +++ b/app/src/main/kotlin/com/imashnake/animite/features/home/HomeScreen.kt @@ -67,7 +67,6 @@ import com.imashnake.animite.api.anilist.sanitize.media.MediaList import com.imashnake.animite.api.anilist.type.MediaType import com.imashnake.animite.core.data.Resource import com.imashnake.animite.core.extensions.bannerParallax -import com.imashnake.animite.core.extensions.landscapeCutoutPadding import com.imashnake.animite.core.extensions.thenIf import com.imashnake.animite.core.ui.LocalPaddings import com.imashnake.animite.core.ui.MediaSmall @@ -182,7 +181,6 @@ fun HomeScreen( start = LocalPaddings.current.large, bottom = LocalPaddings.current.medium ) - .landscapeCutoutPadding() .weight(1f, fill = false), maxLines = 1 ) @@ -192,8 +190,7 @@ fun HomeScreen( .padding( end = LocalPaddings.current.large, bottom = LocalPaddings.current.medium - ) - .landscapeCutoutPadding(), + ), selectedOption = homeMediaType, viewModel = viewModel ) diff --git a/app/src/main/kotlin/com/imashnake/animite/features/searchbar/SearchFrontDrop.kt b/app/src/main/kotlin/com/imashnake/animite/features/searchbar/SearchFrontDrop.kt index 52236604..3c582ded 100644 --- a/app/src/main/kotlin/com/imashnake/animite/features/searchbar/SearchFrontDrop.kt +++ b/app/src/main/kotlin/com/imashnake/animite/features/searchbar/SearchFrontDrop.kt @@ -10,18 +10,14 @@ import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.WindowInsets -import androidx.compose.foundation.layout.asPaddingValues import androidx.compose.foundation.layout.consumeWindowInsets import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.imePadding -import androidx.compose.foundation.layout.navigationBars import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size -import androidx.compose.foundation.layout.statusBars import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.MaterialTheme @@ -45,7 +41,6 @@ import com.imashnake.animite.R import com.imashnake.animite.api.anilist.sanitize.search.Search import com.imashnake.animite.api.anilist.type.MediaType import com.imashnake.animite.core.Constants -import com.imashnake.animite.core.extensions.landscapeCutoutPadding import com.imashnake.animite.core.ui.LocalPaddings import com.imashnake.animite.core.ui.MediaSmall import com.imashnake.animite.core.R as coreR @@ -96,10 +91,9 @@ fun SearchFrontDrop( searchList.data?.let { SearchList( searchList = it, - modifier = Modifier + modifier = Modifier, // TODO: Add this back; https://issuetracker.google.com/issues/323708850. - //.imeNestedScroll() - .landscapeCutoutPadding(), + //.imeNestedScroll(), onItemClick = { id -> isExpanded = false viewModel.setQuery(null) @@ -113,7 +107,6 @@ fun SearchFrontDrop( setExpanded = { isExpanded = it }, onSearched = viewModel::setQuery, modifier = modifier - .landscapeCutoutPadding() .padding(bottom = searchBarBottomPadding) .navigationBarsPadding() .consumeWindowInsets(PaddingValues(bottom = searchBarBottomPadding)) @@ -133,13 +126,11 @@ fun SearchList( contentPadding = PaddingValues( start = LocalPaddings.current.large, end = LocalPaddings.current.large, - top = LocalPaddings.current.large - + WindowInsets.statusBars.asPaddingValues().calculateTopPadding(), + top = LocalPaddings.current.large, bottom = dimensionResource(R.dimen.search_bar_height) + LocalPaddings.current.large + LocalPaddings.current.large + dimensionResource(navigationR.dimen.navigation_bar_height) - + WindowInsets.navigationBars.asPaddingValues().calculateBottomPadding() ), verticalArrangement = Arrangement.spacedBy(LocalPaddings.current.small) ) { diff --git a/core/src/main/kotlin/com/imashnake/animite/core/extensions/ModifierExt.kt b/core/src/main/kotlin/com/imashnake/animite/core/extensions/ModifierExt.kt index 815437b4..2697a6d7 100644 --- a/core/src/main/kotlin/com/imashnake/animite/core/extensions/ModifierExt.kt +++ b/core/src/main/kotlin/com/imashnake/animite/core/extensions/ModifierExt.kt @@ -1,24 +1,12 @@ package com.imashnake.animite.core.extensions -import android.content.res.Configuration import androidx.compose.foundation.ScrollState -import androidx.compose.foundation.layout.displayCutoutPadding import androidx.compose.foundation.layout.heightIn import androidx.compose.ui.Modifier -import androidx.compose.ui.composed import androidx.compose.ui.graphics.graphicsLayer -import androidx.compose.ui.platform.LocalConfiguration import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp -fun Modifier.landscapeCutoutPadding() = composed { - if (LocalConfiguration.current.orientation == Configuration.ORIENTATION_LANDSCAPE) { - displayCutoutPadding() - } else { - this - } -} - fun Modifier.bannerParallax(scrollState: ScrollState) = graphicsLayer { translationY = 0.7f * scrollState.value } diff --git a/core/src/main/kotlin/com/imashnake/animite/core/ui/MediaSmall.kt b/core/src/main/kotlin/com/imashnake/animite/core/ui/MediaSmall.kt index c4869b55..f049c896 100644 --- a/core/src/main/kotlin/com/imashnake/animite/core/ui/MediaSmall.kt +++ b/core/src/main/kotlin/com/imashnake/animite/core/ui/MediaSmall.kt @@ -1,13 +1,9 @@ package com.imashnake.animite.core.ui -import android.content.res.Configuration import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues -import androidx.compose.foundation.layout.WindowInsets -import androidx.compose.foundation.layout.asPaddingValues -import androidx.compose.foundation.layout.displayCutout import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding @@ -23,17 +19,13 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.layout.ContentScale -import androidx.compose.ui.platform.LocalConfiguration import androidx.compose.ui.res.dimensionResource import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.Dp -import androidx.compose.ui.unit.LayoutDirection -import androidx.compose.ui.unit.dp import coil3.compose.AsyncImage import com.imashnake.animite.core.R import com.imashnake.animite.core.extensions.crossfadeModel -import com.imashnake.animite.core.extensions.landscapeCutoutPadding /** * A [LazyRow] of [MediaSmall]s. @@ -59,18 +51,12 @@ fun MediaSmallRow( style = MaterialTheme.typography.titleMedium, modifier = Modifier .padding(start = LocalPaddings.current.large) - .landscapeCutoutPadding() ) } LazyRow( horizontalArrangement = Arrangement.spacedBy(LocalPaddings.current.small), contentPadding = PaddingValues( - start = LocalPaddings.current.large + if ( - LocalConfiguration.current.orientation == Configuration.ORIENTATION_LANDSCAPE - ) { - WindowInsets.displayCutout.asPaddingValues() - .calculateLeftPadding(LayoutDirection.Ltr) - } else 0.dp, + start = LocalPaddings.current.large, end = LocalPaddings.current.large ) ) { diff --git a/media/src/main/kotlin/com/imashnake/animite/media/MediaPage.kt b/media/src/main/kotlin/com/imashnake/animite/media/MediaPage.kt index e19181e0..d6e2e86a 100644 --- a/media/src/main/kotlin/com/imashnake/animite/media/MediaPage.kt +++ b/media/src/main/kotlin/com/imashnake/animite/media/MediaPage.kt @@ -16,7 +16,6 @@ import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues 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 @@ -72,7 +71,6 @@ import com.imashnake.animite.api.anilist.sanitize.media.Media import com.imashnake.animite.core.Constants import com.imashnake.animite.core.extensions.bannerParallax import com.imashnake.animite.core.extensions.crossfadeModel -import com.imashnake.animite.core.extensions.landscapeCutoutPadding import com.imashnake.animite.core.ui.LocalPaddings import com.imashnake.animite.core.ui.MediaSmall import com.imashnake.animite.core.ui.MediaSmallRow @@ -159,7 +157,6 @@ fun MediaPage( + LocalPaddings.current.large, end = LocalPaddings.current.large / 2 ) - .landscapeCutoutPadding() .height( dimensionResource(R.dimen.media_details_height) + LocalPaddings.current.medium / 2 ), @@ -182,7 +179,6 @@ fun MediaPage( modifier = Modifier .fillMaxWidth() .padding(horizontal = LocalPaddings.current.large) - .landscapeCutoutPadding() ) { Text( text = it.type.name, @@ -206,12 +202,7 @@ fun MediaPage( 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, + start = LocalPaddings.current.large, end = LocalPaddings.current.large ), color = Color(media.color ?: 0xFF152232.toInt()), @@ -229,7 +220,6 @@ fun MediaPage( trailer = media.trailer, modifier = Modifier .padding(horizontal = LocalPaddings.current.large) - .landscapeCutoutPadding() ) } }, @@ -254,14 +244,10 @@ fun MediaPage( top = dimensionResource(R.dimen.media_details_height) + LocalPaddings.current.medium + dimensionResource(coreR.dimen.banner_height) - - WindowInsets.statusBars - .asPaddingValues() - .calculateTopPadding() - dimensionResource(coreR.dimen.media_image_height) + offset, start = LocalPaddings.current.large ) - .landscapeCutoutPadding() .height(dimensionResource(coreR.dimen.media_image_height) - offset) ) { MediaSmall( diff --git a/navigation/src/main/kotlin/com/imashnake/animite/navigation/NavigationBar.kt b/navigation/src/main/kotlin/com/imashnake/animite/navigation/NavigationBar.kt index b33c2d83..fc7bead8 100644 --- a/navigation/src/main/kotlin/com/imashnake/animite/navigation/NavigationBar.kt +++ b/navigation/src/main/kotlin/com/imashnake/animite/navigation/NavigationBar.kt @@ -3,10 +3,8 @@ package com.imashnake.animite.navigation import android.content.res.Configuration import androidx.annotation.StringRes import androidx.compose.foundation.layout.WindowInsets -import androidx.compose.foundation.layout.asPaddingValues import androidx.compose.foundation.layout.displayCutout import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.navigationBars import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.material3.Icon import androidx.compose.material3.NavigationBar @@ -36,12 +34,7 @@ fun NavigationBar( // TODO: Can we use `navigationBarsPadding()` instead? NavigationBar( - Modifier.height( - dimensionResource(R.dimen.navigation_bar_height) + WindowInsets - .navigationBars - .asPaddingValues() - .calculateBottomPadding() - ), + Modifier.height(dimensionResource(R.dimen.navigation_bar_height)), // TODO: Use a `NavigationRail` instead. windowInsets = if (LocalConfiguration.current.orientation == Configuration.ORIENTATION_LANDSCAPE diff --git a/profile/src/main/kotlin/com/imashnake/animite/profile/ProfileScreen.kt b/profile/src/main/kotlin/com/imashnake/animite/profile/ProfileScreen.kt index eeb3656f..0d711b1d 100644 --- a/profile/src/main/kotlin/com/imashnake/animite/profile/ProfileScreen.kt +++ b/profile/src/main/kotlin/com/imashnake/animite/profile/ProfileScreen.kt @@ -40,10 +40,8 @@ import com.imashnake.animite.core.data.Resource import com.imashnake.animite.core.extensions.animiteBlockQuoteStyle import com.imashnake.animite.core.extensions.animiteCodeBlockStyle import com.imashnake.animite.core.extensions.crossfadeModel -import com.imashnake.animite.core.extensions.landscapeCutoutPadding import com.imashnake.animite.core.extensions.maxHeight import com.imashnake.animite.core.ui.FallbackMessage -import com.imashnake.animite.core.ui.FallbackScreen import com.imashnake.animite.core.ui.LocalPaddings import com.imashnake.animite.core.ui.NestedScrollableContent import com.imashnake.animite.core.ui.ProgressIndicatorScreen @@ -95,7 +93,6 @@ fun ProfileScreen( contentDescription = "avatar", modifier = Modifier .align(Alignment.BottomStart) - .landscapeCutoutPadding() .padding(start = LocalPaddings.current.medium) .size(100.dp) ) @@ -110,14 +107,12 @@ fun ProfileScreen( overflow = TextOverflow.Ellipsis, modifier = Modifier .padding(horizontal = LocalPaddings.current.large) - .landscapeCutoutPadding() ) UserDescription( description = description, modifier = Modifier .maxHeight(dimensionResource(R.dimen.user_about_height)) .padding(horizontal = LocalPaddings.current.large) - .landscapeCutoutPadding() ) Spacer(Modifier.size(LocalPaddings.current.medium)) UserTabs( @@ -184,7 +179,6 @@ private fun UserTabs( Column(modifier) { PrimaryTabRow( selectedTabIndex = pagerState.currentPage, - modifier = Modifier.landscapeCutoutPadding(), containerColor = MaterialTheme.colorScheme.background, divider = {} ) { diff --git a/profile/src/main/kotlin/com/imashnake/animite/profile/tabs/About.kt b/profile/src/main/kotlin/com/imashnake/animite/profile/tabs/About.kt index e4f87184..a59b5995 100644 --- a/profile/src/main/kotlin/com/imashnake/animite/profile/tabs/About.kt +++ b/profile/src/main/kotlin/com/imashnake/animite/profile/tabs/About.kt @@ -30,7 +30,6 @@ import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import com.boswelja.markdown.material3.m3TextStyles import com.imashnake.animite.api.anilist.sanitize.profile.User -import com.imashnake.animite.core.extensions.landscapeCutoutPadding import com.imashnake.animite.core.ui.LocalPaddings import com.imashnake.animite.core.ui.StatsRow import com.imashnake.animite.profile.R @@ -58,7 +57,6 @@ fun AboutTab( Column( modifier .verticalScroll(scrollState) - .landscapeCutoutPadding() .padding(bottom = LocalPaddings.current.large) ) { Column( @@ -69,7 +67,6 @@ fun AboutTab( stats = statsLabelToValue, modifier = Modifier .fillMaxWidth() - .landscapeCutoutPadding() ) { Text( text = it.first, From a29d33c9a4b836e5d73772cae4628c6ede46da75 Mon Sep 17 00:00:00 2001 From: "Jack Boswell (boswelja)" Date: Sat, 22 Feb 2025 17:48:26 +1100 Subject: [PATCH 02/27] Re-implement for HomeScreen.kt --- .../animite/features/home/HomeScreen.kt | 128 ++++++++++-------- .../imashnake/animite/core/ui/MediaSmall.kt | 21 ++- 2 files changed, 87 insertions(+), 62 deletions(-) diff --git a/app/src/main/kotlin/com/imashnake/animite/features/home/HomeScreen.kt b/app/src/main/kotlin/com/imashnake/animite/features/home/HomeScreen.kt index 9c7801c4..539bd2bb 100644 --- a/app/src/main/kotlin/com/imashnake/animite/features/home/HomeScreen.kt +++ b/app/src/main/kotlin/com/imashnake/animite/features/home/HomeScreen.kt @@ -16,13 +16,18 @@ import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.WindowInsets +import androidx.compose.foundation.layout.asPaddingValues +import androidx.compose.foundation.layout.calculateEndPadding +import androidx.compose.foundation.layout.calculateStartPadding import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.layout.offset import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.requiredWidth +import androidx.compose.foundation.layout.safeDrawing import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.foundation.rememberScrollState @@ -53,6 +58,7 @@ import androidx.compose.ui.graphics.ShaderBrush import androidx.compose.ui.graphics.toArgb import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.platform.LocalLayoutDirection import androidx.compose.ui.res.dimensionResource import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource @@ -93,7 +99,10 @@ fun HomeScreen( sharedTransitionScope: SharedTransitionScope, animatedVisibilityScope: AnimatedVisibilityScope, viewModel: HomeViewModel = hiltViewModel(), + contentInsets: WindowInsets = WindowInsets.safeDrawing ) { + val insetPaddingValues = contentInsets.asPaddingValues() + val homeMediaType = rememberSaveable { mutableStateOf(MediaType.ANIME) } viewModel.setMediaType(homeMediaType.value) @@ -143,29 +152,38 @@ fun HomeScreen( ) Row( - modifier = bannerModifier.thenIf(shader != null) { - drawWithCache @SuppressLint("NewApi") { - shader!!.run { - setFloatUniform( - "resolution", - size.width, - size.height - ) - setFloatUniform("time", time.floatValue) - setColorUniform( - "orb", - Color(0xFF6C408D).toArgb() - ) - setColorUniform( - "bg", - android.graphics.Color.TRANSPARENT - ) - onDrawBehind { - drawRect(ShaderBrush(this@run)) + modifier = bannerModifier + .thenIf(shader != null) { + drawWithCache @SuppressLint("NewApi") { + shader!!.run { + setFloatUniform( + "resolution", + size.width, + size.height + ) + setFloatUniform("time", time.floatValue) + setColorUniform( + "orb", + Color(0xFF6C408D).toArgb() + ) + setColorUniform( + "bg", + android.graphics.Color.TRANSPARENT + ) + onDrawBehind { + drawRect(ShaderBrush(this@run)) + } } } } - }, + .padding( + start = LocalPaddings.current.large + + insetPaddingValues.calculateStartPadding(LocalLayoutDirection.current), + top = LocalPaddings.current.medium + insetPaddingValues.calculateTopPadding(), + end = LocalPaddings.current.large + + insetPaddingValues.calculateStartPadding(LocalLayoutDirection.current), + bottom = LocalPaddings.current.medium + ), horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.Bottom, ) { @@ -177,20 +195,11 @@ fun HomeScreen( } ?: MaterialTheme.colorScheme.secondaryContainer, style = MaterialTheme.typography.displayMedium, modifier = Modifier - .padding( - start = LocalPaddings.current.large, - bottom = LocalPaddings.current.medium - ) .weight(1f, fill = false), maxLines = 1 ) MediaTypeSelector( - modifier = Modifier - .padding( - end = LocalPaddings.current.large, - bottom = LocalPaddings.current.medium - ), selectedOption = homeMediaType, viewModel = viewModel ) @@ -208,58 +217,63 @@ fun HomeScreen( }, label = "animate_home_row" ) { mediaList -> - if (mediaList.list.isNotEmpty()) - HomeRow( - list = mediaList.list, - type = mediaList.type, - onItemClicked = { media -> - onNavigateToMediaItem( - MediaPage( - id = media.id, - // TODO: We can use the list's index instead. - source = mediaList.type.name, - mediaType = homeMediaType.value.rawValue, - ) + HomeRow( + items = mediaList.list, + type = mediaList.type, + onItemClicked = { media -> + onNavigateToMediaItem( + MediaPage( + id = media.id, + source = mediaList.type.name, + mediaType = homeMediaType.value.rawValue, ) - }, - sharedTransitionScope = sharedTransitionScope, - animatedVisibilityScope = animatedVisibilityScope, - modifier = Modifier.padding( - vertical = LocalPaddings.current.large / 2 ) + }, + sharedTransitionScope = sharedTransitionScope, + animatedVisibilityScope = animatedVisibilityScope, + contentPadding = PaddingValues( + start = LocalPaddings.current.large + + insetPaddingValues.calculateStartPadding(LocalLayoutDirection.current), + top = LocalPaddings.current.medium, + end = LocalPaddings.current.large + + insetPaddingValues.calculateEndPadding(LocalLayoutDirection.current), + bottom = LocalPaddings.current.medium ) - else - /* With this, AnimatedContent shrinks/expands the - `HomeRow` vertically. */ - Box(Modifier.fillMaxWidth()) + ) } } } }, contentModifier = Modifier.padding( - top = LocalPaddings.current.large / 2, - bottom = LocalPaddings.current.large / 2 + - dimensionResource(navigationR.dimen.navigation_bar_height) + top = LocalPaddings.current.medium, + bottom = LocalPaddings.current.medium + + dimensionResource(navigationR.dimen.navigation_bar_height) ), verticalArrangement = Arrangement.spacedBy(0.dp) ) } } } - else -> ProgressIndicatorScreen() + else -> ProgressIndicatorScreen(Modifier.padding(insetPaddingValues)) } } @Composable fun HomeRow( - list: List, + items: List, type: MediaList.Type, onItemClicked: (Media.Small) -> Unit, sharedTransitionScope: SharedTransitionScope, animatedVisibilityScope: AnimatedVisibilityScope, modifier: Modifier = Modifier, + contentPadding: PaddingValues = PaddingValues() ) { - MediaSmallRow(type.title, list, modifier) { media -> + MediaSmallRow( + title = type.title, + mediaList = items, + modifier = modifier, + contentPadding = contentPadding, + ) { media -> with(sharedTransitionScope) { MediaSmall( image = media.coverImage, diff --git a/core/src/main/kotlin/com/imashnake/animite/core/ui/MediaSmall.kt b/core/src/main/kotlin/com/imashnake/animite/core/ui/MediaSmall.kt index f049c896..3709fbf4 100644 --- a/core/src/main/kotlin/com/imashnake/animite/core/ui/MediaSmall.kt +++ b/core/src/main/kotlin/com/imashnake/animite/core/ui/MediaSmall.kt @@ -4,6 +4,8 @@ import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.calculateEndPadding +import androidx.compose.foundation.layout.calculateStartPadding import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding @@ -19,6 +21,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.platform.LocalLayoutDirection import androidx.compose.ui.res.dimensionResource import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextOverflow @@ -37,27 +40,35 @@ fun MediaSmallRow( title: String?, mediaList: List, modifier: Modifier = Modifier, + contentPadding: PaddingValues = PaddingValues(), content: @Composable (T) -> Unit ) { Column( - modifier = modifier, + modifier = modifier.padding( + top = contentPadding.calculateTopPadding(), + bottom = contentPadding.calculateBottomPadding() + ), verticalArrangement = Arrangement.spacedBy(LocalPaddings.current.medium) ) { - // TODO: Does this behave as expected if `title` is null? + val startPadding = contentPadding.calculateStartPadding(LocalLayoutDirection.current) + val endPadding = contentPadding.calculateEndPadding(LocalLayoutDirection.current) if (title != null) { Text( text = title, color = MaterialTheme.colorScheme.onBackground, style = MaterialTheme.typography.titleMedium, modifier = Modifier - .padding(start = LocalPaddings.current.large) + .padding( + start = startPadding, + end = endPadding + ) ) } LazyRow( horizontalArrangement = Arrangement.spacedBy(LocalPaddings.current.small), contentPadding = PaddingValues( - start = LocalPaddings.current.large, - end = LocalPaddings.current.large + start = startPadding, + end = endPadding ) ) { items(mediaList) { media -> From c96f3a62bb70ee471f75ab2b0c00d56a44c9759f Mon Sep 17 00:00:00 2001 From: "Jack Boswell (boswelja)" Date: Sat, 22 Feb 2025 18:22:15 +1100 Subject: [PATCH 03/27] SearchFrontDrop --- .../animite/features/home/HomeScreen.kt | 49 ++++++++++--------- .../features/searchbar/SearchFrontDrop.kt | 40 ++++++++++----- .../animite/navigation/NavigationBar.kt | 7 --- 3 files changed, 54 insertions(+), 42 deletions(-) diff --git a/app/src/main/kotlin/com/imashnake/animite/features/home/HomeScreen.kt b/app/src/main/kotlin/com/imashnake/animite/features/home/HomeScreen.kt index 539bd2bb..9af563bd 100644 --- a/app/src/main/kotlin/com/imashnake/animite/features/home/HomeScreen.kt +++ b/app/src/main/kotlin/com/imashnake/animite/features/home/HomeScreen.kt @@ -22,6 +22,7 @@ import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.asPaddingValues import androidx.compose.foundation.layout.calculateEndPadding import androidx.compose.foundation.layout.calculateStartPadding +import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.layout.offset @@ -99,9 +100,9 @@ fun HomeScreen( sharedTransitionScope: SharedTransitionScope, animatedVisibilityScope: AnimatedVisibilityScope, viewModel: HomeViewModel = hiltViewModel(), - contentInsets: WindowInsets = WindowInsets.safeDrawing + contentWindowInsets: WindowInsets = WindowInsets.safeDrawing ) { - val insetPaddingValues = contentInsets.asPaddingValues() + val insetPaddingValues = contentWindowInsets.asPaddingValues() val homeMediaType = rememberSaveable { mutableStateOf(MediaType.ANIME) } viewModel.setMediaType(homeMediaType.value) @@ -217,29 +218,33 @@ fun HomeScreen( }, label = "animate_home_row" ) { mediaList -> - HomeRow( - items = mediaList.list, - type = mediaList.type, - onItemClicked = { media -> - onNavigateToMediaItem( - MediaPage( - id = media.id, - source = mediaList.type.name, - mediaType = homeMediaType.value.rawValue, + if (mediaList.list.isNotEmpty()) { + HomeRow( + items = mediaList.list, + type = mediaList.type, + onItemClicked = { media -> + onNavigateToMediaItem( + MediaPage( + id = media.id, + source = mediaList.type.name, + mediaType = homeMediaType.value.rawValue, + ) ) + }, + sharedTransitionScope = sharedTransitionScope, + animatedVisibilityScope = animatedVisibilityScope, + contentPadding = PaddingValues( + start = LocalPaddings.current.large + + insetPaddingValues.calculateStartPadding(LocalLayoutDirection.current), + top = LocalPaddings.current.medium, + end = LocalPaddings.current.large + + insetPaddingValues.calculateEndPadding(LocalLayoutDirection.current), + bottom = LocalPaddings.current.medium ) - }, - sharedTransitionScope = sharedTransitionScope, - animatedVisibilityScope = animatedVisibilityScope, - contentPadding = PaddingValues( - start = LocalPaddings.current.large + - insetPaddingValues.calculateStartPadding(LocalLayoutDirection.current), - top = LocalPaddings.current.medium, - end = LocalPaddings.current.large + - insetPaddingValues.calculateEndPadding(LocalLayoutDirection.current), - bottom = LocalPaddings.current.medium ) - ) + } else { + Box(Modifier.fillMaxWidth()) + } } } } diff --git a/app/src/main/kotlin/com/imashnake/animite/features/searchbar/SearchFrontDrop.kt b/app/src/main/kotlin/com/imashnake/animite/features/searchbar/SearchFrontDrop.kt index 3c582ded..74803d5b 100644 --- a/app/src/main/kotlin/com/imashnake/animite/features/searchbar/SearchFrontDrop.kt +++ b/app/src/main/kotlin/com/imashnake/animite/features/searchbar/SearchFrontDrop.kt @@ -10,13 +10,16 @@ import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.consumeWindowInsets +import androidx.compose.foundation.layout.WindowInsets +import androidx.compose.foundation.layout.asPaddingValues +import androidx.compose.foundation.layout.calculateEndPadding +import androidx.compose.foundation.layout.calculateStartPadding import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.imePadding -import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.safeDrawing import androidx.compose.foundation.layout.size import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.shape.RoundedCornerShape @@ -31,11 +34,11 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.drawBehind +import androidx.compose.ui.platform.LocalLayoutDirection import androidx.compose.ui.res.dimensionResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.Dp -import androidx.compose.ui.unit.dp import androidx.lifecycle.viewmodel.compose.viewModel import com.imashnake.animite.R import com.imashnake.animite.api.anilist.sanitize.search.Search @@ -61,8 +64,11 @@ fun SearchFrontDrop( hasExtraPadding: Boolean, onItemClick: (Int, MediaType) -> Unit, modifier: Modifier = Modifier, + contentWindowInsets: WindowInsets = WindowInsets.safeDrawing, viewModel: SearchViewModel = viewModel() ) { + val insetPaddingValues = contentWindowInsets.asPaddingValues() + val searchMediaType = MediaType.ANIME viewModel.setMediaType(searchMediaType) val searchList by viewModel.searchList.collectAsState() @@ -71,7 +77,7 @@ fun SearchFrontDrop( val searchBarBottomPadding: Dp by animateDpAsState( targetValue = if (hasExtraPadding) { dimensionResource(navigationR.dimen.navigation_bar_height) - } else 0.dp, + } else insetPaddingValues.calculateBottomPadding(), label = "translate_search_bar" ) val frontDropColor by animateColorAsState( @@ -94,6 +100,7 @@ fun SearchFrontDrop( modifier = Modifier, // TODO: Add this back; https://issuetracker.google.com/issues/323708850. //.imeNestedScroll(), + contentPadding = insetPaddingValues, onItemClick = { id -> isExpanded = false viewModel.setQuery(null) @@ -108,8 +115,11 @@ fun SearchFrontDrop( onSearched = viewModel::setQuery, modifier = modifier .padding(bottom = searchBarBottomPadding) - .navigationBarsPadding() - .consumeWindowInsets(PaddingValues(bottom = searchBarBottomPadding)) + .padding( + start = insetPaddingValues.calculateStartPadding(LocalLayoutDirection.current), + top = insetPaddingValues.calculateTopPadding(), + end = insetPaddingValues.calculateEndPadding(LocalLayoutDirection.current) + ) .imePadding() .height(dimensionResource(R.dimen.search_bar_height)) ) @@ -119,18 +129,22 @@ fun SearchFrontDrop( fun SearchList( searchList: List, modifier: Modifier = Modifier, + contentPadding: PaddingValues = PaddingValues(), onItemClick: (Int) -> Unit ) { LazyColumn( modifier = modifier, contentPadding = PaddingValues( - start = LocalPaddings.current.large, - end = LocalPaddings.current.large, - top = LocalPaddings.current.large, - bottom = dimensionResource(R.dimen.search_bar_height) - + LocalPaddings.current.large - + LocalPaddings.current.large - + dimensionResource(navigationR.dimen.navigation_bar_height) + start = LocalPaddings.current.large + + contentPadding.calculateStartPadding(LocalLayoutDirection.current), + end = LocalPaddings.current.large + + contentPadding.calculateEndPadding(LocalLayoutDirection.current), + top = LocalPaddings.current.large + + contentPadding.calculateTopPadding(), + bottom = dimensionResource(R.dimen.search_bar_height) + + LocalPaddings.current.large + + dimensionResource(navigationR.dimen.navigation_bar_height) + + contentPadding.calculateBottomPadding() ), verticalArrangement = Arrangement.spacedBy(LocalPaddings.current.small) ) { diff --git a/navigation/src/main/kotlin/com/imashnake/animite/navigation/NavigationBar.kt b/navigation/src/main/kotlin/com/imashnake/animite/navigation/NavigationBar.kt index fc7bead8..c373b4f3 100644 --- a/navigation/src/main/kotlin/com/imashnake/animite/navigation/NavigationBar.kt +++ b/navigation/src/main/kotlin/com/imashnake/animite/navigation/NavigationBar.kt @@ -14,11 +14,9 @@ import androidx.compose.runtime.getValue import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.vector.ImageVector -import androidx.compose.ui.platform.LocalConfiguration import androidx.compose.ui.res.dimensionResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.vectorResource -import androidx.compose.ui.unit.dp import androidx.navigation.NavBackStackEntry import androidx.navigation.NavController import androidx.navigation.NavDestination.Companion.hasRoute @@ -32,13 +30,8 @@ fun NavigationBar( ) { val currentBackStackEntry by navController.currentBackStackEntryAsState() - // TODO: Can we use `navigationBarsPadding()` instead? NavigationBar( Modifier.height(dimensionResource(R.dimen.navigation_bar_height)), - // TODO: Use a `NavigationRail` instead. - windowInsets = if (LocalConfiguration.current.orientation - == Configuration.ORIENTATION_LANDSCAPE - ) { WindowInsets.displayCutout } else { WindowInsets(0.dp) } ) { NavigationBarPaths.entries.forEach { destination -> val selected = remember(destination, currentBackStackEntry) { From 2070f4dbf985ca15bfe1de044f866eeb3b8009d3 Mon Sep 17 00:00:00 2001 From: "Jack Boswell (boswelja)" Date: Sat, 22 Feb 2025 18:54:34 +1100 Subject: [PATCH 04/27] MediaPage --- .../com/imashnake/animite/media/MediaPage.kt | 45 ++++++++++++++++--- 1 file changed, 38 insertions(+), 7 deletions(-) diff --git a/media/src/main/kotlin/com/imashnake/animite/media/MediaPage.kt b/media/src/main/kotlin/com/imashnake/animite/media/MediaPage.kt index d6e2e86a..db112ee1 100644 --- a/media/src/main/kotlin/com/imashnake/animite/media/MediaPage.kt +++ b/media/src/main/kotlin/com/imashnake/animite/media/MediaPage.kt @@ -16,13 +16,19 @@ import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.WindowInsets +import androidx.compose.foundation.layout.WindowInsetsSides +import androidx.compose.foundation.layout.asPaddingValues import androidx.compose.foundation.layout.aspectRatio +import androidx.compose.foundation.layout.calculateEndPadding +import androidx.compose.foundation.layout.calculateStartPadding 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.only import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.safeDrawing import androidx.compose.foundation.layout.statusBars import androidx.compose.foundation.layout.statusBarsPadding import androidx.compose.foundation.layout.wrapContentSize @@ -55,6 +61,7 @@ import androidx.compose.ui.graphics.painter.ColorPainter import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.platform.LocalConfiguration import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.platform.LocalLayoutDirection import androidx.compose.ui.res.dimensionResource import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource @@ -99,8 +106,14 @@ private const val DEVICE_CORNER_RADIUS = 30 fun MediaPage( sharedTransitionScope: SharedTransitionScope, animatedVisibilityScope: AnimatedVisibilityScope, + contentWindowInsets: WindowInsets = WindowInsets.safeDrawing, viewModel: MediaPageViewModel = hiltViewModel(), ) { + val insetPaddingValues = contentWindowInsets.asPaddingValues() + val horizontalInsets = PaddingValues( + start = insetPaddingValues.calculateStartPadding(LocalLayoutDirection.current), + end = insetPaddingValues.calculateEndPadding(LocalLayoutDirection.current) + ) val scrollState = rememberScrollState() val media = viewModel.uiState @@ -152,13 +165,14 @@ fun MediaPage( modifier = Modifier .skipToLookaheadSize() .padding( - start = LocalPaddings.current.large / 2 + start = LocalPaddings.current.medium + dimensionResource(coreR.dimen.media_card_width) + LocalPaddings.current.large, - end = LocalPaddings.current.large / 2 + end = LocalPaddings.current.medium ) + .padding(horizontalInsets) .height( - dimensionResource(R.dimen.media_details_height) + LocalPaddings.current.medium / 2 + dimensionResource(R.dimen.media_details_height) + LocalPaddings.current.small ), onClick = { showSheet = true }, textModifier = Modifier.sharedBounds( @@ -179,6 +193,7 @@ fun MediaPage( modifier = Modifier .fillMaxWidth() .padding(horizontal = LocalPaddings.current.large) + .padding(horizontalInsets) ) { Text( text = it.type.name, @@ -202,8 +217,10 @@ fun MediaPage( MediaGenres( genres = media.genres, contentPadding = PaddingValues( - start = LocalPaddings.current.large, - end = LocalPaddings.current.large + start = LocalPaddings.current.large + + horizontalInsets.calculateStartPadding(LocalLayoutDirection.current), + end = LocalPaddings.current.large + + horizontalInsets.calculateEndPadding(LocalLayoutDirection.current) ), color = Color(media.color ?: 0xFF152232.toInt()), ) @@ -212,6 +229,12 @@ fun MediaPage( if (!media.characters.isNullOrEmpty()) { MediaCharacters( characters = media.characters, + contentPadding = PaddingValues( + start = LocalPaddings.current.large + + horizontalInsets.calculateStartPadding(LocalLayoutDirection.current), + end = LocalPaddings.current.large + + horizontalInsets.calculateEndPadding(LocalLayoutDirection.current) + ), ) } @@ -220,10 +243,14 @@ fun MediaPage( trailer = media.trailer, modifier = Modifier .padding(horizontal = LocalPaddings.current.large) + .padding(horizontalInsets) ) } }, - contentModifier = Modifier.padding(top = LocalPaddings.current.medium / 2) + contentModifier = Modifier.padding( + top = LocalPaddings.current.small, + bottom = insetPaddingValues.calculateBottomPadding() + ) ) // TODO: https://developer.android.com/jetpack/compose/animation/quick-guide#concurrent-animations @@ -245,9 +272,11 @@ fun MediaPage( + LocalPaddings.current.medium + dimensionResource(coreR.dimen.banner_height) - dimensionResource(coreR.dimen.media_image_height) + - WindowInsets.safeDrawing.asPaddingValues().calculateTopPadding() + offset, start = LocalPaddings.current.large ) + .padding(horizontalInsets) .height(dimensionResource(coreR.dimen.media_image_height) - offset) ) { MediaSmall( @@ -403,11 +432,13 @@ fun MediaGenres( fun MediaCharacters( characters: List, modifier: Modifier = Modifier, + contentPadding: PaddingValues = PaddingValues() ) { MediaSmallRow( title = stringResource(R.string.characters), mediaList = characters, - modifier = modifier + modifier = modifier, + contentPadding = contentPadding, ) { character -> MediaSmall( image = character.image, From 8c6000d2a169a03b18bc8f812478ccf7530ea924 Mon Sep 17 00:00:00 2001 From: imashnake0 Date: Mon, 24 Feb 2025 00:45:49 -0500 Subject: [PATCH 05/27] fix compilation --- core/src/main/kotlin/com/imashnake/animite/core/ui/MediaSmall.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/core/src/main/kotlin/com/imashnake/animite/core/ui/MediaSmall.kt b/core/src/main/kotlin/com/imashnake/animite/core/ui/MediaSmall.kt index 7146c06f..ed0fcdd2 100644 --- a/core/src/main/kotlin/com/imashnake/animite/core/ui/MediaSmall.kt +++ b/core/src/main/kotlin/com/imashnake/animite/core/ui/MediaSmall.kt @@ -26,6 +26,7 @@ import androidx.compose.ui.res.dimensionResource import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp import coil3.compose.AsyncImage import com.imashnake.animite.core.R import com.imashnake.animite.core.extensions.crossfadeModel From d8c4caaef56970ae9a5d48e87705408074609729 Mon Sep 17 00:00:00 2001 From: "Jack Boswell (boswelja)" Date: Mon, 24 Feb 2025 17:52:46 +1100 Subject: [PATCH 06/27] No funny cutout override --- .../kotlin/com/imashnake/animite/features/MainActivity.kt | 5 ----- 1 file changed, 5 deletions(-) diff --git a/app/src/main/kotlin/com/imashnake/animite/features/MainActivity.kt b/app/src/main/kotlin/com/imashnake/animite/features/MainActivity.kt index af8bb3f6..550c82fa 100644 --- a/app/src/main/kotlin/com/imashnake/animite/features/MainActivity.kt +++ b/app/src/main/kotlin/com/imashnake/animite/features/MainActivity.kt @@ -50,11 +50,6 @@ class MainActivity : ComponentActivity() { enableEdgeToEdge() - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { - window.attributes.layoutInDisplayCutoutMode = - WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES - } - setContent { AnimiteTheme { MainScreen( From 027eaae91cbf36652dcec525920af2db36a39101 Mon Sep 17 00:00:00 2001 From: "Jack Boswell (boswelja)" Date: Mon, 24 Feb 2025 18:10:56 +1100 Subject: [PATCH 07/27] Fix navigation bar padding --- .../animite/navigation/NavigationBar.kt | 66 ++++++++++++++----- 1 file changed, 48 insertions(+), 18 deletions(-) diff --git a/navigation/src/main/kotlin/com/imashnake/animite/navigation/NavigationBar.kt b/navigation/src/main/kotlin/com/imashnake/animite/navigation/NavigationBar.kt index c373b4f3..9fa5b1de 100644 --- a/navigation/src/main/kotlin/com/imashnake/animite/navigation/NavigationBar.kt +++ b/navigation/src/main/kotlin/com/imashnake/animite/navigation/NavigationBar.kt @@ -1,22 +1,32 @@ package com.imashnake.animite.navigation -import android.content.res.Configuration import androidx.annotation.StringRes +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.WindowInsets -import androidx.compose.foundation.layout.displayCutout +import androidx.compose.foundation.layout.defaultMinSize +import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.navigationBarsPadding +import androidx.compose.foundation.layout.windowInsetsPadding +import androidx.compose.foundation.selection.selectableGroup import androidx.compose.material3.Icon -import androidx.compose.material3.NavigationBar +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.NavigationBarDefaults import androidx.compose.material3.NavigationBarItem +import androidx.compose.material3.Surface +import androidx.compose.material3.contentColorFor import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.remember +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.res.dimensionResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.vectorResource +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp import androidx.navigation.NavBackStackEntry import androidx.navigation.NavController import androidx.navigation.NavDestination.Companion.hasRoute @@ -26,25 +36,45 @@ import androidx.navigation.compose.currentBackStackEntryAsState @Composable fun NavigationBar( - navController: NavController + navController: NavController, + modifier: Modifier = Modifier, + containerColor: Color = NavigationBarDefaults.containerColor, + contentColor: Color = MaterialTheme.colorScheme.contentColorFor(containerColor), + tonalElevation: Dp = NavigationBarDefaults.Elevation, + windowInsets: WindowInsets = NavigationBarDefaults.windowInsets, ) { val currentBackStackEntry by navController.currentBackStackEntryAsState() - NavigationBar( - Modifier.height(dimensionResource(R.dimen.navigation_bar_height)), + // This is a clone of Material3 NavigationBar, except we've shrunk the height from 80dp to 65dp + Surface( + color = containerColor, + contentColor = contentColor, + tonalElevation = tonalElevation, + modifier = modifier ) { - NavigationBarPaths.entries.forEach { destination -> - val selected = remember(destination, currentBackStackEntry) { - currentBackStackEntry?.let { destination.matchesDestination(it) } ?: false + Row( + modifier = + Modifier.fillMaxWidth() + .windowInsetsPadding(windowInsets) + .defaultMinSize(minHeight = dimensionResource(R.dimen.navigation_bar_height)) + .selectableGroup(), + horizontalArrangement = Arrangement.spacedBy(8.dp), + verticalAlignment = Alignment.CenterVertically, + ) { + NavigationBarPaths.entries.forEach { destination -> + val selected = remember(destination, currentBackStackEntry) { + currentBackStackEntry?.let { destination.matchesDestination(it) } ?: false + } + NavigationBarItem( + modifier = Modifier + .height(dimensionResource(R.dimen.navigation_bar_height)), + selected = selected, + onClick = { + if (!selected) destination.navigateTo(navController) + }, + icon = destination.icon + ) } - NavigationBarItem( - modifier = Modifier.navigationBarsPadding(), - selected = selected, - onClick = { - if (!selected) destination.navigateTo(navController) - }, - icon = destination.icon - ) } } } From 15840bad28f4e3ce1f608d4bd13cc5e47cfd9cb2 Mon Sep 17 00:00:00 2001 From: "Jack Boswell (boswelja)" Date: Mon, 24 Feb 2025 18:15:41 +1100 Subject: [PATCH 08/27] Fix drawing behind navbar --- .../imashnake/animite/features/searchbar/SearchFrontDrop.kt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/src/main/kotlin/com/imashnake/animite/features/searchbar/SearchFrontDrop.kt b/app/src/main/kotlin/com/imashnake/animite/features/searchbar/SearchFrontDrop.kt index 666c09cb..d33046fd 100644 --- a/app/src/main/kotlin/com/imashnake/animite/features/searchbar/SearchFrontDrop.kt +++ b/app/src/main/kotlin/com/imashnake/animite/features/searchbar/SearchFrontDrop.kt @@ -75,7 +75,7 @@ fun SearchFrontDrop( var isExpanded by rememberSaveable { mutableStateOf(false) } val searchBarBottomPadding: Dp by animateDpAsState( targetValue = if (hasExtraPadding) { - dimensionResource(navigationR.dimen.navigation_bar_height) + dimensionResource(navigationR.dimen.navigation_bar_height) + insetPaddingValues.calculateBottomPadding() } else insetPaddingValues.calculateBottomPadding(), label = "translate_search_bar" ) @@ -119,7 +119,6 @@ fun SearchFrontDrop( top = insetPaddingValues.calculateTopPadding(), end = insetPaddingValues.calculateEndPadding(LocalLayoutDirection.current) ) - .imePadding() .height(dimensionResource(R.dimen.search_bar_height)) ) } From 818b04d990fb44f9c12c03d45c73cd1a62c8aba2 Mon Sep 17 00:00:00 2001 From: "Jack Boswell (boswelja)" Date: Mon, 24 Feb 2025 18:23:37 +1100 Subject: [PATCH 09/27] Fix double-up on padding --- .../com/imashnake/animite/core/ui/layouts/BannerLayout.kt | 2 -- 1 file changed, 2 deletions(-) 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 40af740a..d8fd0e4c 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 @@ -8,7 +8,6 @@ import androidx.compose.foundation.layout.ColumnScope 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 @@ -50,7 +49,6 @@ fun BannerLayout( .fillMaxSize() .padding(top = bannerHeight) .background(MaterialTheme.colorScheme.background) - .navigationBarsPadding() .then(contentModifier), verticalArrangement = verticalArrangement ) { content() } From b7d66b3bea6ccab898047401451c5e8bdddaae55 Mon Sep 17 00:00:00 2001 From: imashnake0 Date: Wed, 26 Feb 2025 00:12:12 -0500 Subject: [PATCH 10/27] refactor padding --- .../imashnake/animite/features/home/HomeScreen.kt | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/app/src/main/kotlin/com/imashnake/animite/features/home/HomeScreen.kt b/app/src/main/kotlin/com/imashnake/animite/features/home/HomeScreen.kt index ac272ab8..0df7c620 100644 --- a/app/src/main/kotlin/com/imashnake/animite/features/home/HomeScreen.kt +++ b/app/src/main/kotlin/com/imashnake/animite/features/home/HomeScreen.kt @@ -177,12 +177,14 @@ fun HomeScreen( } } .padding( - start = LocalPaddings.current.large + - insetPaddingValues.calculateStartPadding(LocalLayoutDirection.current), - top = LocalPaddings.current.medium + insetPaddingValues.calculateTopPadding(), - end = LocalPaddings.current.large + - insetPaddingValues.calculateStartPadding(LocalLayoutDirection.current), - bottom = LocalPaddings.current.medium + horizontal = LocalPaddings.current.large, + vertical = LocalPaddings.current.medium + ) + // Inset padding + .padding( + start = insetPaddingValues.calculateStartPadding(LocalLayoutDirection.current), + top = insetPaddingValues.calculateTopPadding(), + end = insetPaddingValues.calculateEndPadding(LocalLayoutDirection.current), ), horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.Bottom, From 3c0c0fd8436c354cfa932e698e11e9563d9d1af2 Mon Sep 17 00:00:00 2001 From: imashnake0 Date: Wed, 26 Feb 2025 01:09:03 -0500 Subject: [PATCH 11/27] create `PaddingValuesExt` --- .../animite/features/home/HomeScreen.kt | 14 ++-- .../core/extensions/PaddingValuesExt.kt | 79 +++++++++++++++++++ 2 files changed, 86 insertions(+), 7 deletions(-) create mode 100644 core/src/main/kotlin/com/imashnake/animite/core/extensions/PaddingValuesExt.kt diff --git a/app/src/main/kotlin/com/imashnake/animite/features/home/HomeScreen.kt b/app/src/main/kotlin/com/imashnake/animite/features/home/HomeScreen.kt index 0df7c620..ca8ada00 100644 --- a/app/src/main/kotlin/com/imashnake/animite/features/home/HomeScreen.kt +++ b/app/src/main/kotlin/com/imashnake/animite/features/home/HomeScreen.kt @@ -73,6 +73,7 @@ import com.imashnake.animite.api.anilist.sanitize.media.Media import com.imashnake.animite.api.anilist.sanitize.media.MediaList import com.imashnake.animite.api.anilist.type.MediaType import com.imashnake.animite.core.data.Resource +import com.imashnake.animite.core.extensions.Paddings import com.imashnake.animite.core.extensions.bannerParallax import com.imashnake.animite.core.extensions.thenIf import com.imashnake.animite.core.ui.LocalPaddings @@ -234,13 +235,12 @@ fun HomeScreen( }, sharedTransitionScope = sharedTransitionScope, animatedVisibilityScope = animatedVisibilityScope, - contentPadding = PaddingValues( - start = LocalPaddings.current.large + - insetPaddingValues.calculateStartPadding(LocalLayoutDirection.current), - top = LocalPaddings.current.medium, - end = LocalPaddings.current.large + - insetPaddingValues.calculateEndPadding(LocalLayoutDirection.current), - bottom = LocalPaddings.current.medium + contentPadding = Paddings( + horizontal = LocalPaddings.current.large, + vertical = LocalPaddings.current.medium, + ) + Paddings( + start = insetPaddingValues.calculateStartPadding(LocalLayoutDirection.current), + end = insetPaddingValues.calculateEndPadding(LocalLayoutDirection.current), ) ) } else { diff --git a/core/src/main/kotlin/com/imashnake/animite/core/extensions/PaddingValuesExt.kt b/core/src/main/kotlin/com/imashnake/animite/core/extensions/PaddingValuesExt.kt new file mode 100644 index 00000000..f8eee1ed --- /dev/null +++ b/core/src/main/kotlin/com/imashnake/animite/core/extensions/PaddingValuesExt.kt @@ -0,0 +1,79 @@ +@file:Suppress("FunctionName", "unused") + +package com.imashnake.animite.core.extensions + +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.runtime.Stable +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.LayoutDirection +import androidx.compose.ui.unit.dp + +@Stable +fun Paddings(all: Dp) = PaddingValuesExt(all, all, all, all) + +@Stable +fun Paddings( + horizontal: Dp = 0.dp, + vertical: Dp = 0.dp +) = PaddingValuesExt(horizontal, vertical, horizontal, vertical) + +@Stable +fun Paddings( + start: Dp = 0.dp, + top: Dp = 0.dp, + end: Dp = 0.dp, + bottom: Dp = 0.dp +) = PaddingValuesExt(start, top, end, bottom) + +class PaddingValuesExt( + @Stable + val start: Dp = 0.dp, + @Stable + val top: Dp = 0.dp, + @Stable + val end: Dp = 0.dp, + @Stable + val bottom: Dp = 0.dp, +) : PaddingValues { + init { + require(start.value >= 0) { "Start padding must be non-negative" } + require(top.value >= 0) { "Top padding must be non-negative" } + require(end.value >= 0) { "End padding must be non-negative" } + require(bottom.value >= 0) { "Bottom padding must be non-negative" } + } + + override fun calculateLeftPadding(layoutDirection: LayoutDirection) = + if (layoutDirection == LayoutDirection.Ltr) start else end + + override fun calculateTopPadding() = top + + override fun calculateRightPadding(layoutDirection: LayoutDirection) = + if (layoutDirection == LayoutDirection.Ltr) end else start + + override fun calculateBottomPadding() = bottom + + override fun equals(other: Any?): Boolean { + if (other !is PaddingValuesExt) return false + return start == other.start && + top == other.top && + end == other.end && + bottom == other.bottom + } + + override fun hashCode() = + ((start.hashCode() * 31 + top.hashCode()) * 31 + end.hashCode()) * 31 + bottom.hashCode() + + override fun toString() = "PaddingValues(start=$start, top=$top, end=$end, bottom=$bottom)" + + /** + * Add paddings without regard to the current [LayoutDirection]. + */ + operator fun plus(other: PaddingValuesExt): PaddingValues { + return Paddings( + start = start + other.start, + top = top + other.top, + end = end + other.end, + bottom = bottom + other.bottom, + ) + } +} From 3e05164137e41177788eaedad20926cb61c7377a Mon Sep 17 00:00:00 2001 From: imashnake0 Date: Wed, 26 Feb 2025 01:16:17 -0500 Subject: [PATCH 12/27] reset padding --- .../kotlin/com/imashnake/animite/features/home/HomeScreen.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/kotlin/com/imashnake/animite/features/home/HomeScreen.kt b/app/src/main/kotlin/com/imashnake/animite/features/home/HomeScreen.kt index ca8ada00..19f9e75a 100644 --- a/app/src/main/kotlin/com/imashnake/animite/features/home/HomeScreen.kt +++ b/app/src/main/kotlin/com/imashnake/animite/features/home/HomeScreen.kt @@ -251,8 +251,8 @@ fun HomeScreen( } }, contentModifier = Modifier.padding( - top = LocalPaddings.current.medium, - bottom = LocalPaddings.current.medium + + top = LocalPaddings.current.large / 2, + bottom = LocalPaddings.current.large / 2 + dimensionResource(navigationR.dimen.navigation_bar_height) ), verticalArrangement = Arrangement.spacedBy(0.dp) From 30c255fc10d30e4c58f04d58bb3af410e7613e48 Mon Sep 17 00:00:00 2001 From: imashnake0 Date: Wed, 26 Feb 2025 01:17:02 -0500 Subject: [PATCH 13/27] what --- .../kotlin/com/imashnake/animite/features/home/HomeScreen.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/kotlin/com/imashnake/animite/features/home/HomeScreen.kt b/app/src/main/kotlin/com/imashnake/animite/features/home/HomeScreen.kt index 19f9e75a..89a3fcd6 100644 --- a/app/src/main/kotlin/com/imashnake/animite/features/home/HomeScreen.kt +++ b/app/src/main/kotlin/com/imashnake/animite/features/home/HomeScreen.kt @@ -253,7 +253,7 @@ fun HomeScreen( contentModifier = Modifier.padding( top = LocalPaddings.current.large / 2, bottom = LocalPaddings.current.large / 2 + - dimensionResource(navigationR.dimen.navigation_bar_height) + dimensionResource(navigationR.dimen.navigation_bar_height) ), verticalArrangement = Arrangement.spacedBy(0.dp) ) From 895699a210a4aba284ae49b5b9a233d5cbb61ee5 Mon Sep 17 00:00:00 2001 From: imashnake0 Date: Wed, 26 Feb 2025 01:26:28 -0500 Subject: [PATCH 14/27] cleanup --- .../com/imashnake/animite/core/ui/MediaSmall.kt | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/core/src/main/kotlin/com/imashnake/animite/core/ui/MediaSmall.kt b/core/src/main/kotlin/com/imashnake/animite/core/ui/MediaSmall.kt index ed0fcdd2..b8f39fcf 100644 --- a/core/src/main/kotlin/com/imashnake/animite/core/ui/MediaSmall.kt +++ b/core/src/main/kotlin/com/imashnake/animite/core/ui/MediaSmall.kt @@ -51,25 +51,25 @@ fun MediaSmallRow( ), verticalArrangement = Arrangement.spacedBy(LocalPaddings.current.medium) ) { - val startPadding = contentPadding.calculateStartPadding(LocalLayoutDirection.current) - val endPadding = contentPadding.calculateEndPadding(LocalLayoutDirection.current) + val layoutDirection = LocalLayoutDirection.current + val startPadding = contentPadding.calculateStartPadding(layoutDirection) + val endPadding = contentPadding.calculateEndPadding(layoutDirection) if (title != null) { Text( text = title, color = MaterialTheme.colorScheme.onBackground, style = MaterialTheme.typography.titleMedium, - modifier = Modifier - .padding( - start = startPadding, - end = endPadding - ) + modifier = Modifier.padding( + start = startPadding, + end = endPadding, + ) ) } LazyRow( horizontalArrangement = Arrangement.spacedBy(LocalPaddings.current.small), contentPadding = PaddingValues( start = startPadding, - end = endPadding + end = endPadding, ) ) { items(mediaList) { media -> From 97ee2494d74bf8358f6f8ae35bafb2723ea09245 Mon Sep 17 00:00:00 2001 From: imashnake0 Date: Wed, 26 Feb 2025 01:52:15 -0500 Subject: [PATCH 15/27] cleanup `MediaPage` --- .../animite/features/home/HomeScreen.kt | 1 - .../com/imashnake/animite/media/MediaPage.kt | 56 ++++++++----------- 2 files changed, 24 insertions(+), 33 deletions(-) diff --git a/app/src/main/kotlin/com/imashnake/animite/features/home/HomeScreen.kt b/app/src/main/kotlin/com/imashnake/animite/features/home/HomeScreen.kt index 89a3fcd6..c7e081ac 100644 --- a/app/src/main/kotlin/com/imashnake/animite/features/home/HomeScreen.kt +++ b/app/src/main/kotlin/com/imashnake/animite/features/home/HomeScreen.kt @@ -181,7 +181,6 @@ fun HomeScreen( horizontal = LocalPaddings.current.large, vertical = LocalPaddings.current.medium ) - // Inset padding .padding( start = insetPaddingValues.calculateStartPadding(LocalLayoutDirection.current), top = insetPaddingValues.calculateTopPadding(), diff --git a/media/src/main/kotlin/com/imashnake/animite/media/MediaPage.kt b/media/src/main/kotlin/com/imashnake/animite/media/MediaPage.kt index 70e5d2e8..633ddd61 100644 --- a/media/src/main/kotlin/com/imashnake/animite/media/MediaPage.kt +++ b/media/src/main/kotlin/com/imashnake/animite/media/MediaPage.kt @@ -1,7 +1,6 @@ package com.imashnake.animite.media import android.content.Intent -import android.content.res.Configuration import android.util.Log import androidx.compose.animation.AnimatedVisibilityScope import androidx.compose.animation.SharedTransitionScope @@ -16,20 +15,16 @@ import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.WindowInsets -import androidx.compose.foundation.layout.WindowInsetsSides import androidx.compose.foundation.layout.asPaddingValues import androidx.compose.foundation.layout.aspectRatio import androidx.compose.foundation.layout.calculateEndPadding import androidx.compose.foundation.layout.calculateStartPadding -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.only import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.safeDrawing -import androidx.compose.foundation.layout.statusBars import androidx.compose.foundation.layout.statusBarsPadding import androidx.compose.foundation.layout.wrapContentSize import androidx.compose.foundation.lazy.LazyRow @@ -59,7 +54,6 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.ColorFilter import androidx.compose.ui.graphics.painter.ColorPainter import androidx.compose.ui.layout.ContentScale -import androidx.compose.ui.platform.LocalConfiguration import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalLayoutDirection import androidx.compose.ui.res.dimensionResource @@ -68,7 +62,6 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.AnnotatedString import androidx.compose.ui.text.fromHtml import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.unit.LayoutDirection import androidx.compose.ui.unit.dp import androidx.core.net.toUri import androidx.hilt.navigation.compose.hiltViewModel @@ -77,6 +70,7 @@ import coil3.request.ImageRequest import coil3.request.crossfade import com.imashnake.animite.api.anilist.sanitize.media.Media import com.imashnake.animite.core.Constants +import com.imashnake.animite.core.extensions.Paddings import com.imashnake.animite.core.extensions.bannerParallax import com.imashnake.animite.core.extensions.crossfadeModel import com.imashnake.animite.core.ui.CharacterCard @@ -107,14 +101,16 @@ private const val DEVICE_CORNER_RADIUS = 30 fun MediaPage( sharedTransitionScope: SharedTransitionScope, animatedVisibilityScope: AnimatedVisibilityScope, - contentWindowInsets: WindowInsets = WindowInsets.safeDrawing, viewModel: MediaPageViewModel = hiltViewModel(), + contentWindowInsets: WindowInsets = WindowInsets.safeDrawing, ) { val insetPaddingValues = contentWindowInsets.asPaddingValues() - val horizontalInsets = PaddingValues( - start = insetPaddingValues.calculateStartPadding(LocalLayoutDirection.current), - end = insetPaddingValues.calculateEndPadding(LocalLayoutDirection.current) + val layoutDirection = LocalLayoutDirection.current + val horizontalInsets = Paddings( + start = insetPaddingValues.calculateStartPadding(layoutDirection), + end = insetPaddingValues.calculateEndPadding(layoutDirection), ) + val scrollState = rememberScrollState() val media = viewModel.uiState @@ -165,15 +161,11 @@ fun MediaPage( description = media.description.orEmpty(), modifier = Modifier .skipToLookaheadSize() - .padding( - start = LocalPaddings.current.medium - + dimensionResource(coreR.dimen.media_card_width) - + LocalPaddings.current.large, - end = LocalPaddings.current.medium - ) + .padding(horizontal = LocalPaddings.current.large / 2) + .padding(start = dimensionResource(coreR.dimen.media_card_width) + LocalPaddings.current.large) .padding(horizontalInsets) .height( - dimensionResource(R.dimen.media_details_height) + LocalPaddings.current.small + dimensionResource(R.dimen.media_details_height) + LocalPaddings.current.medium / 2 ), onClick = { showSheet = true }, textModifier = Modifier.sharedBounds( @@ -217,11 +209,11 @@ fun MediaPage( if (!media.genres.isNullOrEmpty()) { MediaGenres( genres = media.genres, - contentPadding = PaddingValues( - start = LocalPaddings.current.large + - horizontalInsets.calculateStartPadding(LocalLayoutDirection.current), - end = LocalPaddings.current.large + - horizontalInsets.calculateEndPadding(LocalLayoutDirection.current) + contentPadding = Paddings( + horizontal = LocalPaddings.current.large + ) + Paddings( + start = horizontalInsets.calculateStartPadding(LocalLayoutDirection.current), + end = horizontalInsets.calculateEndPadding(LocalLayoutDirection.current), ), color = Color(media.color ?: 0xFF152232.toInt()), ) @@ -230,11 +222,11 @@ fun MediaPage( if (!media.characters.isNullOrEmpty()) { MediaCharacters( characters = media.characters, - contentPadding = PaddingValues( - start = LocalPaddings.current.large + - horizontalInsets.calculateStartPadding(LocalLayoutDirection.current), - end = LocalPaddings.current.large + - horizontalInsets.calculateEndPadding(LocalLayoutDirection.current) + contentPadding = Paddings( + horizontal = LocalPaddings.current.large + ) + Paddings( + start = horizontalInsets.calculateStartPadding(LocalLayoutDirection.current), + end = horizontalInsets.calculateEndPadding(LocalLayoutDirection.current), ), ) } @@ -249,8 +241,8 @@ fun MediaPage( } }, contentModifier = Modifier.padding( - top = LocalPaddings.current.small, - bottom = insetPaddingValues.calculateBottomPadding() + top = LocalPaddings.current.medium / 2, + bottom = insetPaddingValues.calculateBottomPadding(), ) ) @@ -273,9 +265,9 @@ fun MediaPage( + LocalPaddings.current.medium + dimensionResource(coreR.dimen.banner_height) - dimensionResource(coreR.dimen.media_image_height) - - WindowInsets.safeDrawing.asPaddingValues().calculateTopPadding() + - contentWindowInsets.asPaddingValues().calculateTopPadding() + offset, - start = LocalPaddings.current.large + start = LocalPaddings.current.large, ) .padding(horizontalInsets) .height(dimensionResource(coreR.dimen.media_image_height) - offset) From a5298e18a148d066bc6bbbd0151ab795f1df982e Mon Sep 17 00:00:00 2001 From: imashnake0 Date: Wed, 26 Feb 2025 02:15:05 -0500 Subject: [PATCH 16/27] cleanup `NavigationBar` --- .../imashnake/animite/navigation/NavigationBar.kt | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/navigation/src/main/kotlin/com/imashnake/animite/navigation/NavigationBar.kt b/navigation/src/main/kotlin/com/imashnake/animite/navigation/NavigationBar.kt index 9fa5b1de..f273560f 100644 --- a/navigation/src/main/kotlin/com/imashnake/animite/navigation/NavigationBar.kt +++ b/navigation/src/main/kotlin/com/imashnake/animite/navigation/NavigationBar.kt @@ -53,21 +53,20 @@ fun NavigationBar( modifier = modifier ) { Row( - modifier = - Modifier.fillMaxWidth() - .windowInsetsPadding(windowInsets) - .defaultMinSize(minHeight = dimensionResource(R.dimen.navigation_bar_height)) - .selectableGroup(), + modifier = Modifier + .fillMaxWidth() + .windowInsetsPadding(windowInsets) + .defaultMinSize(minHeight = dimensionResource(R.dimen.navigation_bar_height)) + .selectableGroup(), horizontalArrangement = Arrangement.spacedBy(8.dp), verticalAlignment = Alignment.CenterVertically, ) { NavigationBarPaths.entries.forEach { destination -> val selected = remember(destination, currentBackStackEntry) { - currentBackStackEntry?.let { destination.matchesDestination(it) } ?: false + currentBackStackEntry?.let { destination.matchesDestination(it) } == true } NavigationBarItem( - modifier = Modifier - .height(dimensionResource(R.dimen.navigation_bar_height)), + modifier = Modifier.height(dimensionResource(R.dimen.navigation_bar_height)), selected = selected, onClick = { if (!selected) destination.navigateTo(navController) From 002cdf8de15f281c65f9c4dad658a6051f9b097b Mon Sep 17 00:00:00 2001 From: imashnake0 Date: Wed, 26 Feb 2025 02:15:46 -0500 Subject: [PATCH 17/27] re: cleanup `NavigationBar` --- .../com/imashnake/animite/navigation/NavigationBar.kt | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/navigation/src/main/kotlin/com/imashnake/animite/navigation/NavigationBar.kt b/navigation/src/main/kotlin/com/imashnake/animite/navigation/NavigationBar.kt index f273560f..74c8e19f 100644 --- a/navigation/src/main/kotlin/com/imashnake/animite/navigation/NavigationBar.kt +++ b/navigation/src/main/kotlin/com/imashnake/animite/navigation/NavigationBar.kt @@ -68,9 +68,7 @@ fun NavigationBar( NavigationBarItem( modifier = Modifier.height(dimensionResource(R.dimen.navigation_bar_height)), selected = selected, - onClick = { - if (!selected) destination.navigateTo(navController) - }, + onClick = { if (!selected) destination.navigateTo(navController) }, icon = destination.icon ) } @@ -137,4 +135,4 @@ enum class NavigationBarPaths( }, labelRes = R.string.profile ), -} \ No newline at end of file +} From 3320afec5fc031680a924595f92ffcb23ab5b8cd Mon Sep 17 00:00:00 2001 From: imashnake0 Date: Sat, 1 Mar 2025 01:06:13 -0500 Subject: [PATCH 18/27] add insets for some of profile --- .../animite/features/home/HomeScreen.kt | 2 +- .../animite/profile/ProfileScreen.kt | 44 ++++++++++++------- 2 files changed, 28 insertions(+), 18 deletions(-) diff --git a/app/src/main/kotlin/com/imashnake/animite/features/home/HomeScreen.kt b/app/src/main/kotlin/com/imashnake/animite/features/home/HomeScreen.kt index c7e081ac..4ee1bf71 100644 --- a/app/src/main/kotlin/com/imashnake/animite/features/home/HomeScreen.kt +++ b/app/src/main/kotlin/com/imashnake/animite/features/home/HomeScreen.kt @@ -100,7 +100,7 @@ fun HomeScreen( sharedTransitionScope: SharedTransitionScope, animatedVisibilityScope: AnimatedVisibilityScope, viewModel: HomeViewModel = hiltViewModel(), - contentWindowInsets: WindowInsets = WindowInsets.safeDrawing + contentWindowInsets: WindowInsets = WindowInsets.safeDrawing, ) { val insetPaddingValues = contentWindowInsets.asPaddingValues() diff --git a/profile/src/main/kotlin/com/imashnake/animite/profile/ProfileScreen.kt b/profile/src/main/kotlin/com/imashnake/animite/profile/ProfileScreen.kt index 0d711b1d..e5fd07a1 100644 --- a/profile/src/main/kotlin/com/imashnake/animite/profile/ProfileScreen.kt +++ b/profile/src/main/kotlin/com/imashnake/animite/profile/ProfileScreen.kt @@ -3,11 +3,15 @@ package com.imashnake.animite.profile import androidx.compose.animation.AnimatedVisibilityScope import androidx.compose.animation.SharedTransitionScope 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.Spacer +import androidx.compose.foundation.layout.WindowInsets +import androidx.compose.foundation.layout.asPaddingValues +import androidx.compose.foundation.layout.calculateStartPadding import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.safeDrawing import androidx.compose.foundation.layout.size import androidx.compose.foundation.pager.HorizontalPager import androidx.compose.foundation.pager.rememberPagerState @@ -27,6 +31,7 @@ import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.Color import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.platform.LocalLayoutDirection import androidx.compose.ui.res.dimensionResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextOverflow @@ -62,7 +67,10 @@ fun ProfileScreen( sharedTransitionScope: SharedTransitionScope, animatedVisibilityScope: AnimatedVisibilityScope, viewModel: ProfileViewModel = hiltViewModel(), + contentWindowInsets: WindowInsets = WindowInsets.safeDrawing, ) { + val insetPaddingValues = contentWindowInsets.asPaddingValues() + val isLoggedIn by viewModel.isLoggedIn.collectAsState(initial = false) val viewer by viewModel.viewer.collectAsState() val viewerAnimeLists by viewModel.viewerAnimeLists.collectAsState() @@ -94,27 +102,28 @@ fun ProfileScreen( modifier = Modifier .align(Alignment.BottomStart) .padding(start = LocalPaddings.current.medium) + .padding(start = insetPaddingValues.calculateStartPadding(LocalLayoutDirection.current)) .size(100.dp) ) } }, content = { - Column { - Text( - text = name, - color = MaterialTheme.colorScheme.onBackground, - style = MaterialTheme.typography.titleLarge, - overflow = TextOverflow.Ellipsis, - modifier = Modifier - .padding(horizontal = LocalPaddings.current.large) - ) - UserDescription( - description = description, - modifier = Modifier - .maxHeight(dimensionResource(R.dimen.user_about_height)) - .padding(horizontal = LocalPaddings.current.large) - ) - Spacer(Modifier.size(LocalPaddings.current.medium)) + Column(verticalArrangement = Arrangement.spacedBy(LocalPaddings.current.medium)) { + Column(Modifier.padding(start = insetPaddingValues.calculateStartPadding(LocalLayoutDirection.current))) { + Text( + text = name, + color = MaterialTheme.colorScheme.onBackground, + style = MaterialTheme.typography.titleLarge, + overflow = TextOverflow.Ellipsis, + modifier = Modifier.padding(horizontal = LocalPaddings.current.large) + ) + UserDescription( + description = description, + modifier = Modifier + .maxHeight(dimensionResource(R.dimen.user_about_height)) + .padding(horizontal = LocalPaddings.current.large) + ) + } UserTabs( user = this@run, animeCollection = viewerAnimeLists.data, @@ -170,6 +179,7 @@ private fun UserTabs( sharedTransitionScope: SharedTransitionScope, animatedVisibilityScope: AnimatedVisibilityScope, modifier: Modifier = Modifier, + ) { val coroutineScope = rememberCoroutineScope() val pagerState = rememberPagerState(pageCount = { ProfileTab.entries.size }) From 4ef40c7632e61f0a41e3609992becf51144bc361 Mon Sep 17 00:00:00 2001 From: imashnake0 Date: Sat, 1 Mar 2025 01:27:54 -0500 Subject: [PATCH 19/27] add inset padding for `UserTabs` --- .../com/imashnake/animite/profile/ProfileScreen.kt | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/profile/src/main/kotlin/com/imashnake/animite/profile/ProfileScreen.kt b/profile/src/main/kotlin/com/imashnake/animite/profile/ProfileScreen.kt index e5fd07a1..73facf20 100644 --- a/profile/src/main/kotlin/com/imashnake/animite/profile/ProfileScreen.kt +++ b/profile/src/main/kotlin/com/imashnake/animite/profile/ProfileScreen.kt @@ -6,6 +6,7 @@ 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.PaddingValues import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.asPaddingValues import androidx.compose.foundation.layout.calculateStartPadding @@ -131,6 +132,9 @@ fun ProfileScreen( onNavigateToMediaItem = onNavigateToMediaItem, sharedTransitionScope = sharedTransitionScope, animatedVisibilityScope = animatedVisibilityScope, + contentInsetPadding = PaddingValues( + start = insetPaddingValues.calculateStartPadding(LocalLayoutDirection.current) + ) ) } }, @@ -179,7 +183,7 @@ private fun UserTabs( sharedTransitionScope: SharedTransitionScope, animatedVisibilityScope: AnimatedVisibilityScope, modifier: Modifier = Modifier, - + contentInsetPadding: PaddingValues = PaddingValues(), ) { val coroutineScope = rememberCoroutineScope() val pagerState = rememberPagerState(pageCount = { ProfileTab.entries.size }) @@ -190,7 +194,8 @@ private fun UserTabs( PrimaryTabRow( selectedTabIndex = pagerState.currentPage, containerColor = MaterialTheme.colorScheme.background, - divider = {} + divider = {}, + modifier = Modifier.padding(contentInsetPadding) ) { titles.forEachIndexed { index, tab -> Tab( @@ -230,6 +235,7 @@ private fun UserTabs( ) ) ) + .padding(contentInsetPadding) ) { page -> Box(Modifier.fillMaxSize()) { when (ProfileTab.entries[page]) { From 28115326b0fd841c624676a811dc4eb22816c9d9 Mon Sep 17 00:00:00 2001 From: imashnake0 Date: Sat, 1 Mar 2025 03:27:29 -0500 Subject: [PATCH 20/27] shenanigans --- .../animite/features/home/HomeScreen.kt | 21 ++++------ .../animite/profile/ProfileScreen.kt | 42 ++++++++++++++----- .../imashnake/animite/profile/tabs/About.kt | 5 ++- .../imashnake/animite/profile/tabs/Media.kt | 22 ++++++---- 4 files changed, 58 insertions(+), 32 deletions(-) diff --git a/app/src/main/kotlin/com/imashnake/animite/features/home/HomeScreen.kt b/app/src/main/kotlin/com/imashnake/animite/features/home/HomeScreen.kt index 4ee1bf71..f0e636ee 100644 --- a/app/src/main/kotlin/com/imashnake/animite/features/home/HomeScreen.kt +++ b/app/src/main/kotlin/com/imashnake/animite/features/home/HomeScreen.kt @@ -24,7 +24,6 @@ import androidx.compose.foundation.layout.calculateEndPadding import androidx.compose.foundation.layout.calculateStartPadding import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.layout.offset import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.requiredWidth @@ -136,11 +135,7 @@ fun HomeScreen( rows.all { it is Resource.Success } -> { val scrollState = rememberScrollState() TranslucentStatusBarLayout(scrollState) { - Box( - modifier = Modifier - .verticalScroll(scrollState) - .navigationBarsPadding() - ) { + Box(Modifier.verticalScroll(scrollState)) { BannerLayout( banner = { bannerModifier -> Box { @@ -236,7 +231,7 @@ fun HomeScreen( animatedVisibilityScope = animatedVisibilityScope, contentPadding = Paddings( horizontal = LocalPaddings.current.large, - vertical = LocalPaddings.current.medium, + vertical = LocalPaddings.current.large / 2, ) + Paddings( start = insetPaddingValues.calculateStartPadding(LocalLayoutDirection.current), end = insetPaddingValues.calculateEndPadding(LocalLayoutDirection.current), @@ -249,11 +244,13 @@ fun HomeScreen( } } }, - contentModifier = Modifier.padding( - top = LocalPaddings.current.large / 2, - bottom = LocalPaddings.current.large / 2 + - dimensionResource(navigationR.dimen.navigation_bar_height) - ), + contentModifier = Modifier + .padding( + top = LocalPaddings.current.large / 2, + bottom = LocalPaddings.current.large / 2 + + dimensionResource(navigationR.dimen.navigation_bar_height) + ) + .padding(bottom = insetPaddingValues.calculateBottomPadding()), verticalArrangement = Arrangement.spacedBy(0.dp) ) } diff --git a/profile/src/main/kotlin/com/imashnake/animite/profile/ProfileScreen.kt b/profile/src/main/kotlin/com/imashnake/animite/profile/ProfileScreen.kt index 73facf20..eba0c2e1 100644 --- a/profile/src/main/kotlin/com/imashnake/animite/profile/ProfileScreen.kt +++ b/profile/src/main/kotlin/com/imashnake/animite/profile/ProfileScreen.kt @@ -6,9 +6,9 @@ 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.PaddingValues import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.asPaddingValues +import androidx.compose.foundation.layout.calculateEndPadding import androidx.compose.foundation.layout.calculateStartPadding import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding @@ -43,6 +43,8 @@ import com.boswelja.markdown.material3.MarkdownDocument import com.boswelja.markdown.material3.m3TextStyles import com.imashnake.animite.api.anilist.sanitize.profile.User import com.imashnake.animite.core.data.Resource +import com.imashnake.animite.core.extensions.PaddingValuesExt +import com.imashnake.animite.core.extensions.Paddings import com.imashnake.animite.core.extensions.animiteBlockQuoteStyle import com.imashnake.animite.core.extensions.animiteCodeBlockStyle import com.imashnake.animite.core.extensions.crossfadeModel @@ -103,14 +105,22 @@ fun ProfileScreen( modifier = Modifier .align(Alignment.BottomStart) .padding(start = LocalPaddings.current.medium) - .padding(start = insetPaddingValues.calculateStartPadding(LocalLayoutDirection.current)) + .padding( + start = insetPaddingValues.calculateStartPadding(LocalLayoutDirection.current), + end = insetPaddingValues.calculateEndPadding(LocalLayoutDirection.current), + ) .size(100.dp) ) } }, content = { Column(verticalArrangement = Arrangement.spacedBy(LocalPaddings.current.medium)) { - Column(Modifier.padding(start = insetPaddingValues.calculateStartPadding(LocalLayoutDirection.current))) { + Column( + Modifier.padding( + start = insetPaddingValues.calculateStartPadding(LocalLayoutDirection.current), + end = insetPaddingValues.calculateEndPadding(LocalLayoutDirection.current), + ) + ) { Text( text = name, color = MaterialTheme.colorScheme.onBackground, @@ -132,15 +142,17 @@ fun ProfileScreen( onNavigateToMediaItem = onNavigateToMediaItem, sharedTransitionScope = sharedTransitionScope, animatedVisibilityScope = animatedVisibilityScope, - contentInsetPadding = PaddingValues( - start = insetPaddingValues.calculateStartPadding(LocalLayoutDirection.current) + contentInsetPadding = Paddings( + start = insetPaddingValues.calculateStartPadding(LocalLayoutDirection.current), + end = insetPaddingValues.calculateEndPadding(LocalLayoutDirection.current), ) ) } }, contentModifier = Modifier.padding( - top = LocalPaddings.current.large, - bottom = dimensionResource(navigationR.dimen.navigation_bar_height) + top = LocalPaddings.current.large / 2, + bottom = LocalPaddings.current.large / 2 + + dimensionResource(navigationR.dimen.navigation_bar_height) ) ) } @@ -183,7 +195,7 @@ private fun UserTabs( sharedTransitionScope: SharedTransitionScope, animatedVisibilityScope: AnimatedVisibilityScope, modifier: Modifier = Modifier, - contentInsetPadding: PaddingValues = PaddingValues(), + contentInsetPadding: PaddingValuesExt = Paddings(), ) { val coroutineScope = rememberCoroutineScope() val pagerState = rememberPagerState(pageCount = { ProfileTab.entries.size }) @@ -235,22 +247,32 @@ private fun UserTabs( ) ) ) - .padding(contentInsetPadding) ) { page -> Box(Modifier.fillMaxSize()) { when (ProfileTab.entries[page]) { - ProfileTab.ABOUT -> AboutTab(user) + ProfileTab.ABOUT -> AboutTab( + user = user, + contentPadding = contentInsetPadding, + ) ProfileTab.ANIME -> MediaTab( mediaCollection = animeCollection, onNavigateToMediaItem = onNavigateToMediaItem, sharedTransitionScope = sharedTransitionScope, animatedVisibilityScope = animatedVisibilityScope, + contentPadding = Paddings( + horizontal = LocalPaddings.current.large, + vertical = LocalPaddings.current.large / 2, + ) + contentInsetPadding, ) ProfileTab.MANGA -> MediaTab( mediaCollection = mangaCollection, onNavigateToMediaItem = onNavigateToMediaItem, sharedTransitionScope = sharedTransitionScope, animatedVisibilityScope = animatedVisibilityScope, + contentPadding = Paddings( + horizontal = LocalPaddings.current.large, + vertical = LocalPaddings.current.large / 2, + ) + contentInsetPadding, ) ProfileTab.FAVOURITES -> FavouritesTab(user.favourites) else -> FallbackMessage( diff --git a/profile/src/main/kotlin/com/imashnake/animite/profile/tabs/About.kt b/profile/src/main/kotlin/com/imashnake/animite/profile/tabs/About.kt index a59b5995..a3bc1c43 100644 --- a/profile/src/main/kotlin/com/imashnake/animite/profile/tabs/About.kt +++ b/profile/src/main/kotlin/com/imashnake/animite/profile/tabs/About.kt @@ -6,6 +6,7 @@ import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.IntrinsicSize +import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxWidth @@ -43,7 +44,8 @@ import kotlinx.coroutines.launch @Composable fun AboutTab( user: User, - modifier: Modifier = Modifier + modifier: Modifier = Modifier, + contentPadding: PaddingValues = PaddingValues(), ) { val scrollState = rememberScrollState() @@ -58,6 +60,7 @@ fun AboutTab( modifier .verticalScroll(scrollState) .padding(bottom = LocalPaddings.current.large) + .padding(contentPadding) ) { Column( modifier = Modifier.padding(LocalPaddings.current.large), diff --git a/profile/src/main/kotlin/com/imashnake/animite/profile/tabs/Media.kt b/profile/src/main/kotlin/com/imashnake/animite/profile/tabs/Media.kt index 38dc7bb2..e05ebe97 100644 --- a/profile/src/main/kotlin/com/imashnake/animite/profile/tabs/Media.kt +++ b/profile/src/main/kotlin/com/imashnake/animite/profile/tabs/Media.kt @@ -2,8 +2,8 @@ package com.imashnake.animite.profile.tabs import androidx.compose.animation.AnimatedVisibilityScope import androidx.compose.animation.SharedTransitionScope -import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.padding import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll @@ -38,6 +38,7 @@ fun MediaTab( sharedTransitionScope: SharedTransitionScope, animatedVisibilityScope: AnimatedVisibilityScope, modifier: Modifier = Modifier, + contentPadding: PaddingValues = PaddingValues(), ) { val scrollState = rememberScrollState() @@ -56,16 +57,17 @@ fun MediaTab( else -> Column( modifier .verticalScroll(scrollState) - .padding(vertical = LocalPaddings.current.large) + .padding(vertical = LocalPaddings.current.large / 2) + .padding(bottom = contentPadding.calculateBottomPadding()) ) { - // TODO: Why is this not smart-casting? if (!mediaCollection?.namedLists.isNullOrEmpty()) { UserMediaLists( - lists = mediaCollection!!.namedLists, + lists = mediaCollection.namedLists, onNavigateToMediaItem = onNavigateToMediaItem, sharedTransitionScope = sharedTransitionScope, animatedVisibilityScope = animatedVisibilityScope, modifier = modifier, + contentPadding = contentPadding, ) } } @@ -79,13 +81,15 @@ private fun UserMediaLists( sharedTransitionScope: SharedTransitionScope, animatedVisibilityScope: AnimatedVisibilityScope, modifier: Modifier = Modifier, + contentPadding: PaddingValues = PaddingValues(), ) { - Column( - verticalArrangement = Arrangement.spacedBy(LocalPaddings.current.large), - modifier = modifier, - ) { + Column(modifier = modifier) { lists.fastForEach { namedList -> - MediaSmallRow(namedList.name, namedList.list) { item -> + MediaSmallRow( + title = namedList.name, + mediaList = namedList.list, + contentPadding = contentPadding, + ) { item -> with(sharedTransitionScope) { val media = item as Media.Small MediaCard( From 7317c49387f3985d1cd6e9f69f812e473df5ff77 Mon Sep 17 00:00:00 2001 From: imashnake0 Date: Sat, 1 Mar 2025 03:40:00 -0500 Subject: [PATCH 21/27] add inset padding to fave tab --- .../animite/profile/ProfileScreen.kt | 8 +++++- .../animite/profile/tabs/Favourites.kt | 27 ++++++++++++------- 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/profile/src/main/kotlin/com/imashnake/animite/profile/ProfileScreen.kt b/profile/src/main/kotlin/com/imashnake/animite/profile/ProfileScreen.kt index eba0c2e1..747c44d4 100644 --- a/profile/src/main/kotlin/com/imashnake/animite/profile/ProfileScreen.kt +++ b/profile/src/main/kotlin/com/imashnake/animite/profile/ProfileScreen.kt @@ -274,7 +274,13 @@ private fun UserTabs( vertical = LocalPaddings.current.large / 2, ) + contentInsetPadding, ) - ProfileTab.FAVOURITES -> FavouritesTab(user.favourites) + ProfileTab.FAVOURITES -> FavouritesTab( + favouriteLists = user.favourites, + contentPadding = Paddings( + horizontal = LocalPaddings.current.large, + vertical = LocalPaddings.current.large / 2, + ) + contentInsetPadding, + ) else -> FallbackMessage( message = stringResource(coreR.string.coming_soon), modifier = Modifier.align(Alignment.Center), diff --git a/profile/src/main/kotlin/com/imashnake/animite/profile/tabs/Favourites.kt b/profile/src/main/kotlin/com/imashnake/animite/profile/tabs/Favourites.kt index 865d2cda..b3891bde 100644 --- a/profile/src/main/kotlin/com/imashnake/animite/profile/tabs/Favourites.kt +++ b/profile/src/main/kotlin/com/imashnake/animite/profile/tabs/Favourites.kt @@ -1,8 +1,8 @@ package com.imashnake.animite.profile.tabs import android.util.Log -import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.padding import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll @@ -28,6 +28,7 @@ import com.imashnake.animite.profile.R fun FavouritesTab( favouriteLists: List, modifier: Modifier = Modifier, + contentPadding: PaddingValues = PaddingValues(), ) { val scrollState = rememberScrollState() @@ -36,22 +37,30 @@ fun FavouritesTab( else -> Column( modifier .verticalScroll(scrollState) - .padding(vertical = LocalPaddings.current.large) - ) { UserFavouriteLists(favouriteLists) } + .padding(vertical = LocalPaddings.current.large / 2) + .padding(bottom = contentPadding.calculateBottomPadding()) + ) { + UserFavouriteLists( + lists = favouriteLists, + contentPadding = contentPadding, + ) + } } } @Composable private fun UserFavouriteLists( lists: List, - modifier: Modifier = Modifier + modifier: Modifier = Modifier, + contentPadding: PaddingValues = PaddingValues(), ) { - Column( - verticalArrangement = Arrangement.spacedBy(LocalPaddings.current.large), - modifier = modifier - ) { + Column(modifier = modifier) { lists.fastForEach { namedList -> - MediaSmallRow(namedList.name, namedList.list) { item -> + MediaSmallRow( + title = namedList.name, + mediaList = namedList.list, + contentPadding = contentPadding, + ) { item -> when(item) { is Media.Small -> { MediaCard( From 542c5e1bcfb6fee1086a67798740bc6c99452b13 Mon Sep 17 00:00:00 2001 From: imashnake0 Date: Sat, 1 Mar 2025 03:48:34 -0500 Subject: [PATCH 22/27] pad text screens --- .../kotlin/com/imashnake/animite/profile/ProfileScreen.kt | 4 +++- .../main/kotlin/com/imashnake/animite/profile/tabs/Media.kt | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/profile/src/main/kotlin/com/imashnake/animite/profile/ProfileScreen.kt b/profile/src/main/kotlin/com/imashnake/animite/profile/ProfileScreen.kt index 747c44d4..119ca512 100644 --- a/profile/src/main/kotlin/com/imashnake/animite/profile/ProfileScreen.kt +++ b/profile/src/main/kotlin/com/imashnake/animite/profile/ProfileScreen.kt @@ -283,7 +283,9 @@ private fun UserTabs( ) else -> FallbackMessage( message = stringResource(coreR.string.coming_soon), - modifier = Modifier.align(Alignment.Center), + modifier = Modifier + .align(Alignment.Center) + .padding(contentInsetPadding), ) } } diff --git a/profile/src/main/kotlin/com/imashnake/animite/profile/tabs/Media.kt b/profile/src/main/kotlin/com/imashnake/animite/profile/tabs/Media.kt index e05ebe97..c96475c0 100644 --- a/profile/src/main/kotlin/com/imashnake/animite/profile/tabs/Media.kt +++ b/profile/src/main/kotlin/com/imashnake/animite/profile/tabs/Media.kt @@ -51,7 +51,8 @@ fun MediaTab( Media.Small.Type.MANGA -> R.string.no_manga Media.Small.Type.UNKNOWN -> R.string.no_media } - ) + ), + modifier = Modifier.padding(contentPadding) ) } else -> Column( From b630ca476fa33420d654e55752226913ca55d132 Mon Sep 17 00:00:00 2001 From: imashnake0 Date: Sat, 1 Mar 2025 04:48:53 -0500 Subject: [PATCH 23/27] fix inset padding in `SearchFrontDrop` --- .../animite/features/searchbar/SearchFab.kt | 1 - .../features/searchbar/SearchFrontDrop.kt | 45 ++++++++++++------- .../core/extensions/PaddingValuesExt.kt | 2 +- 3 files changed, 29 insertions(+), 19 deletions(-) diff --git a/app/src/main/kotlin/com/imashnake/animite/features/searchbar/SearchFab.kt b/app/src/main/kotlin/com/imashnake/animite/features/searchbar/SearchFab.kt index 408fc78d..dccde7d9 100644 --- a/app/src/main/kotlin/com/imashnake/animite/features/searchbar/SearchFab.kt +++ b/app/src/main/kotlin/com/imashnake/animite/features/searchbar/SearchFab.kt @@ -36,7 +36,6 @@ import androidx.compose.ui.res.dimensionResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.vectorResource import androidx.compose.ui.text.input.ImeAction -import androidx.compose.ui.unit.dp import com.imashnake.animite.R /** diff --git a/app/src/main/kotlin/com/imashnake/animite/features/searchbar/SearchFrontDrop.kt b/app/src/main/kotlin/com/imashnake/animite/features/searchbar/SearchFrontDrop.kt index d33046fd..c5450ee6 100644 --- a/app/src/main/kotlin/com/imashnake/animite/features/searchbar/SearchFrontDrop.kt +++ b/app/src/main/kotlin/com/imashnake/animite/features/searchbar/SearchFrontDrop.kt @@ -14,10 +14,12 @@ import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.asPaddingValues import androidx.compose.foundation.layout.calculateEndPadding import androidx.compose.foundation.layout.calculateStartPadding +import androidx.compose.foundation.layout.consumeWindowInsets import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.imePadding +import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.safeDrawing import androidx.compose.foundation.layout.size @@ -39,11 +41,13 @@ import androidx.compose.ui.res.dimensionResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp import androidx.lifecycle.viewmodel.compose.viewModel import com.imashnake.animite.R import com.imashnake.animite.api.anilist.sanitize.search.Search import com.imashnake.animite.api.anilist.type.MediaType import com.imashnake.animite.core.Constants +import com.imashnake.animite.core.extensions.Paddings import com.imashnake.animite.core.ui.LocalPaddings import com.imashnake.animite.core.ui.MediaCard import com.imashnake.animite.core.R as coreR @@ -73,10 +77,10 @@ fun SearchFrontDrop( val searchList by viewModel.searchList.collectAsState() var isExpanded by rememberSaveable { mutableStateOf(false) } - val searchBarBottomPadding: Dp by animateDpAsState( + val searchBarBottomPadding by animateDpAsState( targetValue = if (hasExtraPadding) { - dimensionResource(navigationR.dimen.navigation_bar_height) + insetPaddingValues.calculateBottomPadding() - } else insetPaddingValues.calculateBottomPadding(), + dimensionResource(navigationR.dimen.navigation_bar_height) + } else 0.dp, label = "translate_search_bar" ) val frontDropColor by animateColorAsState( @@ -100,6 +104,7 @@ fun SearchFrontDrop( // TODO: Add this back; https://issuetracker.google.com/issues/323708850. //.imeNestedScroll(), contentPadding = insetPaddingValues, + searchBarBottomPadding = searchBarBottomPadding, onItemClick = { id -> isExpanded = false viewModel.setQuery(null) @@ -113,12 +118,15 @@ fun SearchFrontDrop( setExpanded = { isExpanded = it }, onSearched = viewModel::setQuery, modifier = modifier - .padding(bottom = searchBarBottomPadding) .padding( start = insetPaddingValues.calculateStartPadding(LocalLayoutDirection.current), top = insetPaddingValues.calculateTopPadding(), end = insetPaddingValues.calculateEndPadding(LocalLayoutDirection.current) ) + .padding(bottom = searchBarBottomPadding) + .navigationBarsPadding() + .consumeWindowInsets(PaddingValues(bottom = searchBarBottomPadding)) + .imePadding() .height(dimensionResource(R.dimen.search_bar_height)) ) } @@ -126,23 +134,26 @@ fun SearchFrontDrop( @Composable fun SearchList( searchList: List, + searchBarBottomPadding: Dp, + onItemClick: (Int) -> Unit, modifier: Modifier = Modifier, contentPadding: PaddingValues = PaddingValues(), - onItemClick: (Int) -> Unit ) { LazyColumn( - modifier = modifier, - contentPadding = PaddingValues( - start = LocalPaddings.current.large + - contentPadding.calculateStartPadding(LocalLayoutDirection.current), - end = LocalPaddings.current.large + - contentPadding.calculateEndPadding(LocalLayoutDirection.current), - top = LocalPaddings.current.large + - contentPadding.calculateTopPadding(), - bottom = dimensionResource(R.dimen.search_bar_height) + - LocalPaddings.current.large + - dimensionResource(navigationR.dimen.navigation_bar_height) + - contentPadding.calculateBottomPadding() + modifier = modifier + .padding(bottom = searchBarBottomPadding) + .navigationBarsPadding() + .consumeWindowInsets(PaddingValues(bottom = searchBarBottomPadding)) + .imePadding(), + contentPadding = Paddings( + all = LocalPaddings.current.large + ) + Paddings( + bottom = LocalPaddings.current.large + + dimensionResource(R.dimen.search_bar_height) + ) + Paddings( + start = contentPadding.calculateStartPadding(LocalLayoutDirection.current), + top = contentPadding.calculateTopPadding(), + end = contentPadding.calculateEndPadding(LocalLayoutDirection.current), ), verticalArrangement = Arrangement.spacedBy(LocalPaddings.current.small) ) { diff --git a/core/src/main/kotlin/com/imashnake/animite/core/extensions/PaddingValuesExt.kt b/core/src/main/kotlin/com/imashnake/animite/core/extensions/PaddingValuesExt.kt index f8eee1ed..6b9d10a7 100644 --- a/core/src/main/kotlin/com/imashnake/animite/core/extensions/PaddingValuesExt.kt +++ b/core/src/main/kotlin/com/imashnake/animite/core/extensions/PaddingValuesExt.kt @@ -68,7 +68,7 @@ class PaddingValuesExt( /** * Add paddings without regard to the current [LayoutDirection]. */ - operator fun plus(other: PaddingValuesExt): PaddingValues { + operator fun plus(other: PaddingValuesExt): PaddingValuesExt { return Paddings( start = start + other.start, top = top + other.top, From e63143faa9f6495ede8357688a7c29a11c09cb67 Mon Sep 17 00:00:00 2001 From: imashnake0 Date: Sat, 1 Mar 2025 04:54:59 -0500 Subject: [PATCH 24/27] cleanup --- .../core/extensions/PaddingValuesExt.kt | 2 +- .../animite/profile/ProfileScreen.kt | 25 +++++++++++++++---- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/core/src/main/kotlin/com/imashnake/animite/core/extensions/PaddingValuesExt.kt b/core/src/main/kotlin/com/imashnake/animite/core/extensions/PaddingValuesExt.kt index 6b9d10a7..0859e021 100644 --- a/core/src/main/kotlin/com/imashnake/animite/core/extensions/PaddingValuesExt.kt +++ b/core/src/main/kotlin/com/imashnake/animite/core/extensions/PaddingValuesExt.kt @@ -25,7 +25,7 @@ fun Paddings( bottom: Dp = 0.dp ) = PaddingValuesExt(start, top, end, bottom) -class PaddingValuesExt( +class PaddingValuesExt internal constructor( @Stable val start: Dp = 0.dp, @Stable diff --git a/profile/src/main/kotlin/com/imashnake/animite/profile/ProfileScreen.kt b/profile/src/main/kotlin/com/imashnake/animite/profile/ProfileScreen.kt index 119ca512..7205701d 100644 --- a/profile/src/main/kotlin/com/imashnake/animite/profile/ProfileScreen.kt +++ b/profile/src/main/kotlin/com/imashnake/animite/profile/ProfileScreen.kt @@ -6,6 +6,7 @@ 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.PaddingValues import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.asPaddingValues import androidx.compose.foundation.layout.calculateEndPadding @@ -43,7 +44,6 @@ import com.boswelja.markdown.material3.MarkdownDocument import com.boswelja.markdown.material3.m3TextStyles import com.imashnake.animite.api.anilist.sanitize.profile.User import com.imashnake.animite.core.data.Resource -import com.imashnake.animite.core.extensions.PaddingValuesExt import com.imashnake.animite.core.extensions.Paddings import com.imashnake.animite.core.extensions.animiteBlockQuoteStyle import com.imashnake.animite.core.extensions.animiteCodeBlockStyle @@ -195,7 +195,7 @@ private fun UserTabs( sharedTransitionScope: SharedTransitionScope, animatedVisibilityScope: AnimatedVisibilityScope, modifier: Modifier = Modifier, - contentInsetPadding: PaddingValuesExt = Paddings(), + contentInsetPadding: PaddingValues = PaddingValues(), ) { val coroutineScope = rememberCoroutineScope() val pagerState = rememberPagerState(pageCount = { ProfileTab.entries.size }) @@ -262,7 +262,12 @@ private fun UserTabs( contentPadding = Paddings( horizontal = LocalPaddings.current.large, vertical = LocalPaddings.current.large / 2, - ) + contentInsetPadding, + ) + Paddings( + start = contentInsetPadding.calculateStartPadding(LocalLayoutDirection.current), + top = contentInsetPadding.calculateTopPadding(), + end = contentInsetPadding.calculateEndPadding(LocalLayoutDirection.current), + bottom = contentInsetPadding.calculateBottomPadding() + ), ) ProfileTab.MANGA -> MediaTab( mediaCollection = mangaCollection, @@ -272,14 +277,24 @@ private fun UserTabs( contentPadding = Paddings( horizontal = LocalPaddings.current.large, vertical = LocalPaddings.current.large / 2, - ) + contentInsetPadding, + ) + Paddings( + start = contentInsetPadding.calculateStartPadding(LocalLayoutDirection.current), + top = contentInsetPadding.calculateTopPadding(), + end = contentInsetPadding.calculateEndPadding(LocalLayoutDirection.current), + bottom = contentInsetPadding.calculateBottomPadding() + ), ) ProfileTab.FAVOURITES -> FavouritesTab( favouriteLists = user.favourites, contentPadding = Paddings( horizontal = LocalPaddings.current.large, vertical = LocalPaddings.current.large / 2, - ) + contentInsetPadding, + ) + Paddings( + start = contentInsetPadding.calculateStartPadding(LocalLayoutDirection.current), + top = contentInsetPadding.calculateTopPadding(), + end = contentInsetPadding.calculateEndPadding(LocalLayoutDirection.current), + bottom = contentInsetPadding.calculateBottomPadding() + ), ) else -> FallbackMessage( message = stringResource(coreR.string.coming_soon), From e81aa176a94e914bab63b95396dd66bc483a7977 Mon Sep 17 00:00:00 2001 From: imashnake0 Date: Sat, 1 Mar 2025 05:42:24 -0500 Subject: [PATCH 25/27] added imeNestedScroll back now that it works --- .../animite/features/searchbar/SearchFrontDrop.kt | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/app/src/main/kotlin/com/imashnake/animite/features/searchbar/SearchFrontDrop.kt b/app/src/main/kotlin/com/imashnake/animite/features/searchbar/SearchFrontDrop.kt index c5450ee6..49ebca9d 100644 --- a/app/src/main/kotlin/com/imashnake/animite/features/searchbar/SearchFrontDrop.kt +++ b/app/src/main/kotlin/com/imashnake/animite/features/searchbar/SearchFrontDrop.kt @@ -7,6 +7,7 @@ import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.ExperimentalLayoutApi import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer @@ -18,6 +19,7 @@ import androidx.compose.foundation.layout.consumeWindowInsets import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.imeNestedScroll import androidx.compose.foundation.layout.imePadding import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.layout.padding @@ -62,6 +64,7 @@ import com.imashnake.animite.navigation.R as navigationR * @param modifier the [Modifier] to be applied to this Front Drop. * @param viewModel [SearchViewModel] instance. */ +@OptIn(ExperimentalLayoutApi::class) @Composable fun SearchFrontDrop( hasExtraPadding: Boolean, @@ -100,9 +103,7 @@ fun SearchFrontDrop( searchList.data?.let { SearchList( searchList = it, - modifier = Modifier, - // TODO: Add this back; https://issuetracker.google.com/issues/323708850. - //.imeNestedScroll(), + modifier = Modifier.imeNestedScroll(), contentPadding = insetPaddingValues, searchBarBottomPadding = searchBarBottomPadding, onItemClick = { id -> From 421863b7816fab1297bd55eb615eb85d7aa54c4f Mon Sep 17 00:00:00 2001 From: imashnake0 Date: Sat, 1 Mar 2025 14:28:58 -0500 Subject: [PATCH 26/27] cleanup --- .../imashnake/animite/features/home/HomeScreen.kt | 3 ++- .../com/imashnake/animite/media/MediaPage.kt | 15 ++++++--------- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/app/src/main/kotlin/com/imashnake/animite/features/home/HomeScreen.kt b/app/src/main/kotlin/com/imashnake/animite/features/home/HomeScreen.kt index f0e636ee..a93220e4 100644 --- a/app/src/main/kotlin/com/imashnake/animite/features/home/HomeScreen.kt +++ b/app/src/main/kotlin/com/imashnake/animite/features/home/HomeScreen.kt @@ -24,6 +24,7 @@ import androidx.compose.foundation.layout.calculateEndPadding import androidx.compose.foundation.layout.calculateStartPadding import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.layout.offset import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.requiredWidth @@ -250,7 +251,7 @@ fun HomeScreen( bottom = LocalPaddings.current.large / 2 + dimensionResource(navigationR.dimen.navigation_bar_height) ) - .padding(bottom = insetPaddingValues.calculateBottomPadding()), + .navigationBarsPadding(), verticalArrangement = Arrangement.spacedBy(0.dp) ) } diff --git a/media/src/main/kotlin/com/imashnake/animite/media/MediaPage.kt b/media/src/main/kotlin/com/imashnake/animite/media/MediaPage.kt index 633ddd61..690ef1bd 100644 --- a/media/src/main/kotlin/com/imashnake/animite/media/MediaPage.kt +++ b/media/src/main/kotlin/com/imashnake/animite/media/MediaPage.kt @@ -23,6 +23,7 @@ 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.safeDrawing import androidx.compose.foundation.layout.statusBarsPadding @@ -224,10 +225,7 @@ fun MediaPage( characters = media.characters, contentPadding = Paddings( horizontal = LocalPaddings.current.large - ) + Paddings( - start = horizontalInsets.calculateStartPadding(LocalLayoutDirection.current), - end = horizontalInsets.calculateEndPadding(LocalLayoutDirection.current), - ), + ) + horizontalInsets, ) } @@ -240,10 +238,9 @@ fun MediaPage( ) } }, - contentModifier = Modifier.padding( - top = LocalPaddings.current.medium / 2, - bottom = insetPaddingValues.calculateBottomPadding(), - ) + contentModifier = Modifier + .padding(top = LocalPaddings.current.medium / 2) + .navigationBarsPadding() ) // TODO: https://developer.android.com/jetpack/compose/animation/quick-guide#concurrent-animations @@ -265,7 +262,7 @@ fun MediaPage( + LocalPaddings.current.medium + dimensionResource(coreR.dimen.banner_height) - dimensionResource(coreR.dimen.media_image_height) - - contentWindowInsets.asPaddingValues().calculateTopPadding() + - insetPaddingValues.calculateTopPadding() + offset, start = LocalPaddings.current.large, ) From ca401c788c9138a45bdcba823cc01b6e5337d85e Mon Sep 17 00:00:00 2001 From: imashnake0 Date: Sun, 2 Mar 2025 01:25:46 -0500 Subject: [PATCH 27/27] cleanup --- .../animite/profile/ProfileScreen.kt | 22 +++++++------------ 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/profile/src/main/kotlin/com/imashnake/animite/profile/ProfileScreen.kt b/profile/src/main/kotlin/com/imashnake/animite/profile/ProfileScreen.kt index 7205701d..e2bfdfd2 100644 --- a/profile/src/main/kotlin/com/imashnake/animite/profile/ProfileScreen.kt +++ b/profile/src/main/kotlin/com/imashnake/animite/profile/ProfileScreen.kt @@ -73,6 +73,11 @@ fun ProfileScreen( contentWindowInsets: WindowInsets = WindowInsets.safeDrawing, ) { val insetPaddingValues = contentWindowInsets.asPaddingValues() + val layoutDirection = LocalLayoutDirection.current + val horizontalInsets = Paddings( + start = insetPaddingValues.calculateStartPadding(layoutDirection), + end = insetPaddingValues.calculateEndPadding(layoutDirection), + ) val isLoggedIn by viewModel.isLoggedIn.collectAsState(initial = false) val viewer by viewModel.viewer.collectAsState() @@ -105,22 +110,14 @@ fun ProfileScreen( modifier = Modifier .align(Alignment.BottomStart) .padding(start = LocalPaddings.current.medium) - .padding( - start = insetPaddingValues.calculateStartPadding(LocalLayoutDirection.current), - end = insetPaddingValues.calculateEndPadding(LocalLayoutDirection.current), - ) + .padding(horizontalInsets) .size(100.dp) ) } }, content = { Column(verticalArrangement = Arrangement.spacedBy(LocalPaddings.current.medium)) { - Column( - Modifier.padding( - start = insetPaddingValues.calculateStartPadding(LocalLayoutDirection.current), - end = insetPaddingValues.calculateEndPadding(LocalLayoutDirection.current), - ) - ) { + Column(Modifier.padding(horizontalInsets)) { Text( text = name, color = MaterialTheme.colorScheme.onBackground, @@ -142,10 +139,7 @@ fun ProfileScreen( onNavigateToMediaItem = onNavigateToMediaItem, sharedTransitionScope = sharedTransitionScope, animatedVisibilityScope = animatedVisibilityScope, - contentInsetPadding = Paddings( - start = insetPaddingValues.calculateStartPadding(LocalLayoutDirection.current), - end = insetPaddingValues.calculateEndPadding(LocalLayoutDirection.current), - ) + contentInsetPadding = horizontalInsets ) } },