mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2026-10-06 19:53:08 +00:00
fix(home-banner): float DVM status banner over the feed instead of in the top bar
Putting HomeDvmStatusBanner inside the top-bar Column meant the SecondaryTabRow shifted up/down every time the banner appeared or disappeared (filter selection, refresh, response arrival). Annoying. Move the banner into a Box that wraps the HorizontalPager and align it to TopCenter so it floats over the feed: - topBar Column is back to just HomeTopBar + SecondaryTabRow; tabs no longer reflow when the banner toggles. - BannerCard takes a Modifier and gets tonalElevation + shadowElevation + a slightly stronger surface tint so it reads as a floating overlay rather than part of the scaffold chrome.
This commit is contained in:
+21
-8
@@ -58,13 +58,14 @@ import com.vitorpamplona.quartz.nip89AppHandlers.definition.AppDefinitionEvent
|
||||
fun HomeDvmStatusBanner(
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: INav,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
val topFilter by accountViewModel.account.settings.defaultHomeFollowList
|
||||
.collectAsStateWithLifecycle()
|
||||
|
||||
when (val filter = topFilter) {
|
||||
is TopFilter.FavoriteDvm -> SingleDvmBanner(filter, accountViewModel, nav)
|
||||
is TopFilter.AllFavoriteDvms -> AllFavoriteDvmsBanner(accountViewModel)
|
||||
is TopFilter.FavoriteDvm -> SingleDvmBanner(filter, accountViewModel, nav, modifier)
|
||||
is TopFilter.AllFavoriteDvms -> AllFavoriteDvmsBanner(accountViewModel, modifier)
|
||||
else -> Unit
|
||||
}
|
||||
}
|
||||
@@ -74,6 +75,7 @@ private fun SingleDvmBanner(
|
||||
favDvm: TopFilter.FavoriteDvm,
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: INav,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
val snapshot by accountViewModel.account.favoriteDvmOrchestrator
|
||||
.observe(favDvm.address)
|
||||
@@ -95,7 +97,7 @@ private fun SingleDvmBanner(
|
||||
?: ""
|
||||
}
|
||||
|
||||
BannerCard {
|
||||
BannerCard(modifier) {
|
||||
val status = snapshot.latestStatus?.status()
|
||||
|
||||
when {
|
||||
@@ -167,7 +169,10 @@ private fun SingleDvmBanner(
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun AllFavoriteDvmsBanner(accountViewModel: AccountViewModel) {
|
||||
private fun AllFavoriteDvmsBanner(
|
||||
accountViewModel: AccountViewModel,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
val addresses by accountViewModel.account.favoriteDvmList.flow
|
||||
.collectAsStateWithLifecycle()
|
||||
|
||||
@@ -189,7 +194,7 @@ private fun AllFavoriteDvmsBanner(accountViewModel: AccountViewModel) {
|
||||
|
||||
val allErrored = snapshots.all { it.errorMessage != null || it.latestStatus?.status()?.code == "error" }
|
||||
|
||||
BannerCard {
|
||||
BannerCard(modifier) {
|
||||
if (allErrored) {
|
||||
BannerMessageRow(
|
||||
message = stringRes(R.string.dvm_home_status_error),
|
||||
@@ -209,14 +214,22 @@ private fun AllFavoriteDvmsBanner(accountViewModel: AccountViewModel) {
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun BannerCard(content: @Composable () -> Unit) {
|
||||
private fun BannerCard(
|
||||
modifier: Modifier = Modifier,
|
||||
content: @Composable () -> Unit,
|
||||
) {
|
||||
// Sits above the feed instead of in the topBar Column, so adding/removing
|
||||
// the banner doesn't shift the tabs/filter up and down. tonalElevation
|
||||
// gives it a faint surface tint so it reads as a floating overlay.
|
||||
Surface(
|
||||
modifier =
|
||||
Modifier
|
||||
modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 12.dp, vertical = 6.dp),
|
||||
shape = RoundedCornerShape(12.dp),
|
||||
color = MaterialTheme.colorScheme.surfaceContainerLow,
|
||||
color = MaterialTheme.colorScheme.surfaceContainerHigh,
|
||||
tonalElevation = 4.dp,
|
||||
shadowElevation = 4.dp,
|
||||
) {
|
||||
Column(modifier = Modifier.padding(12.dp)) { content() }
|
||||
}
|
||||
|
||||
+33
-17
@@ -23,11 +23,14 @@ package com.vitorpamplona.amethyst.ui.screen.loggedIn.home
|
||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Arrangement.Absolute.spacedBy
|
||||
import androidx.compose.foundation.layout.Box
|
||||
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.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.LazyListState
|
||||
import androidx.compose.foundation.lazy.LazyRow
|
||||
@@ -52,6 +55,7 @@ import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.vitorpamplona.amethyst.Amethyst
|
||||
import com.vitorpamplona.amethyst.R
|
||||
@@ -179,7 +183,6 @@ private fun HomePages(
|
||||
topBar = {
|
||||
Column {
|
||||
HomeTopBar(accountViewModel, nav)
|
||||
HomeDvmStatusBanner(accountViewModel, nav)
|
||||
SecondaryTabRow(
|
||||
containerColor = Color.Transparent,
|
||||
contentColor = MaterialTheme.colorScheme.onBackground,
|
||||
@@ -210,24 +213,37 @@ private fun HomePages(
|
||||
HomeScreenFloatingButton(accountViewModel, nav)
|
||||
},
|
||||
accountViewModel = accountViewModel,
|
||||
) {
|
||||
HorizontalPager(
|
||||
contentPadding = it,
|
||||
state = pagerState,
|
||||
userScrollEnabled = true,
|
||||
modifier =
|
||||
Modifier.zonedDrawerSwipe(
|
||||
pagerState = pagerState,
|
||||
openDrawer = nav::openDrawer,
|
||||
),
|
||||
) { page ->
|
||||
HomeFeeds(
|
||||
feedState = tabs[page].feedState,
|
||||
routeForLastRead = tabs[page].routeForLastRead,
|
||||
scrollStateKey = tabs[page].scrollStateKey,
|
||||
liveSection = tabs[page].liveSection,
|
||||
) { paddingValues ->
|
||||
// Wrap pager + banner in a Box so the banner can float over the feed
|
||||
// (anchored top-center) instead of living in the topBar Column where
|
||||
// it would push the tabs down every time it appears or disappears.
|
||||
Box(
|
||||
modifier = Modifier.fillMaxSize().padding(paddingValues),
|
||||
) {
|
||||
HorizontalPager(
|
||||
contentPadding = PaddingValues(0.dp),
|
||||
state = pagerState,
|
||||
userScrollEnabled = true,
|
||||
modifier =
|
||||
Modifier.zonedDrawerSwipe(
|
||||
pagerState = pagerState,
|
||||
openDrawer = nav::openDrawer,
|
||||
),
|
||||
) { page ->
|
||||
HomeFeeds(
|
||||
feedState = tabs[page].feedState,
|
||||
routeForLastRead = tabs[page].routeForLastRead,
|
||||
scrollStateKey = tabs[page].scrollStateKey,
|
||||
liveSection = tabs[page].liveSection,
|
||||
accountViewModel = accountViewModel,
|
||||
nav = nav,
|
||||
)
|
||||
}
|
||||
|
||||
HomeDvmStatusBanner(
|
||||
accountViewModel = accountViewModel,
|
||||
nav = nav,
|
||||
modifier = Modifier.align(Alignment.TopCenter),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user