From e73715f64a0d2c02437bd1c3fce2b4596981d64b Mon Sep 17 00:00:00 2001 From: davotoula Date: Thu, 14 May 2026 21:21:55 +0200 Subject: [PATCH] =?UTF-8?q?Layout=20changes:=20pin=20"Add=20more=E2=80=A6"?= =?UTF-8?q?=20button=20to=20bottom=20of=20populated=20favourites=20screen?= =?UTF-8?q?=20group=20empty-state=20icon/headline/steps=20and=20add=20top?= =?UTF-8?q?=20breathing=20room=20spread=20empty-state=20evenly=20and=20add?= =?UTF-8?q?=20numbered=20step=20prefixes=20replace=20empty-state=20subtitl?= =?UTF-8?q?e=20with=202-step=20instruction=20including=20inline=20star=20i?= =?UTF-8?q?con=20hide=20explainer=20when=20favorite=20feeds=20exist=20and?= =?UTF-8?q?=20add=20"Add=20more=E2=80=A6"=20button?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../favorites/FavoriteAlgoFeedsListScreen.kt | 137 +++++++++++++++--- amethyst/src/main/res/values/strings.xml | 3 + 2 files changed, 116 insertions(+), 24 deletions(-) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/dvms/favorites/FavoriteAlgoFeedsListScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/dvms/favorites/FavoriteAlgoFeedsListScreen.kt index 3fdefd677d..6b5837cd88 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/dvms/favorites/FavoriteAlgoFeedsListScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/dvms/favorites/FavoriteAlgoFeedsListScreen.kt @@ -25,6 +25,7 @@ import androidx.compose.foundation.combinedClickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.ColumnScope import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.consumeWindowInsets @@ -37,6 +38,8 @@ import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyListState import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.rememberLazyListState +import androidx.compose.foundation.text.InlineTextContent +import androidx.compose.foundation.text.appendInlineContent import androidx.compose.material3.Button import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme @@ -48,10 +51,14 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment.Companion.BottomStart import androidx.compose.ui.Modifier import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.text.Placeholder +import androidx.compose.ui.text.PlaceholderVerticalAlign +import androidx.compose.ui.text.buildAnnotatedString import androidx.compose.ui.text.font.FontWeight 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.sp import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.commons.icons.symbols.Icon @@ -82,6 +89,8 @@ fun FavoriteAlgoFeedsListScreen( ) { val listState = rememberLazyListState() val coroutineScope = rememberCoroutineScope() + val favorites by accountViewModel.account.favoriteAlgoFeedsList.flowNotes + .collectAsStateWithLifecycle() DisappearingScaffold( isInvertedLayout = false, @@ -113,33 +122,34 @@ fun FavoriteAlgoFeedsListScreen( bottom = padding.calculateBottomPadding(), ).consumeWindowInsets(padding), ) { - Text( - text = stringRes(R.string.favorite_dvms_explainer), - textAlign = TextAlign.Center, - modifier = Modifier.fillMaxWidth().padding(vertical = 12.dp), - style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.grayText, - ) + if (favorites.isEmpty()) { + Text( + text = stringRes(R.string.favorite_dvms_explainer), + textAlign = TextAlign.Center, + modifier = Modifier.fillMaxWidth().padding(top = 24.dp, bottom = 12.dp), + style = MaterialTheme.typography.bodyMedium, + color = MaterialTheme.colorScheme.grayText, + ) + } - FavoriteAlgoFeedList(listState, accountViewModel, nav) + FavoriteAlgoFeedList(favorites, listState, accountViewModel, nav) } } } @Composable -private fun FavoriteAlgoFeedList( +private fun ColumnScope.FavoriteAlgoFeedList( + favorites: List, listState: LazyListState, accountViewModel: AccountViewModel, nav: INav, ) { - val favorites by accountViewModel.account.favoriteAlgoFeedsList.flowNotes - .collectAsStateWithLifecycle() - if (favorites.isEmpty()) { - Box( - modifier = Modifier.fillMaxSize().padding(24.dp), - contentAlignment = Alignment.Center, + Column( + modifier = Modifier.fillMaxSize().padding(horizontal = 24.dp, vertical = 32.dp), + horizontalAlignment = Alignment.CenterHorizontally, ) { + Spacer(modifier = Modifier.weight(1f)) Column( horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.spacedBy(16.dp), @@ -156,22 +166,21 @@ private fun FavoriteAlgoFeedList( style = MaterialTheme.typography.titleMedium, fontWeight = FontWeight.SemiBold, ) - Text( - text = stringRes(R.string.favorite_dvms_empty_subtitle), - textAlign = TextAlign.Center, - style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.grayText, - modifier = Modifier.widthIn(max = 280.dp), + FavoriteAlgoFeedsEmptySteps( + ctaLabel = stringRes(R.string.favorite_dvms_empty_cta), + modifier = Modifier.widthIn(max = 320.dp), ) - Button(onClick = { nav.nav(Route.Discover(initialTab = DiscoverTab.ALGOS)) }) { - Text(text = stringRes(R.string.favorite_dvms_empty_cta)) - } + } + Spacer(modifier = Modifier.weight(1f)) + Button(onClick = { nav.nav(Route.Discover(initialTab = DiscoverTab.ALGOS)) }) { + Text(text = stringRes(R.string.favorite_dvms_empty_cta)) } } return } LazyColumn( + modifier = Modifier.weight(1f), state = listState, verticalArrangement = Arrangement.spacedBy(4.dp), contentPadding = FeedPadding, @@ -188,6 +197,14 @@ private fun FavoriteAlgoFeedList( ) } } + Box( + modifier = Modifier.fillMaxWidth().padding(vertical = 32.dp), + contentAlignment = Alignment.Center, + ) { + Button(onClick = { nav.nav(Route.Discover(initialTab = DiscoverTab.ALGOS)) }) { + Text(text = stringRes(R.string.favorite_dvms_add_more)) + } + } } @OptIn(ExperimentalFoundationApi::class) @@ -267,3 +284,75 @@ private fun FavoriteAlgoFeedRow( } } } + +@Composable +private fun FavoriteAlgoFeedsEmptySteps( + ctaLabel: String, + modifier: Modifier = Modifier, +) { + val starInlineId = "star" + val step2Template = stringRes(R.string.favorite_dvms_empty_step2) + val step2Parts = step2Template.split("%1\$s", limit = 2) + + val step2Text = + buildAnnotatedString { + append(step2Parts.first()) + appendInlineContent(starInlineId, "[star]") + if (step2Parts.size > 1) append(step2Parts[1]) + } + + val starInlineContent = + mapOf( + starInlineId to + InlineTextContent( + Placeholder( + width = 18.sp, + height = 18.sp, + placeholderVerticalAlign = PlaceholderVerticalAlign.Center, + ), + ) { + Icon( + symbol = MaterialSymbols.StarBorder, + contentDescription = null, + tint = MaterialTheme.colorScheme.primary, + ) + }, + ) + + Column( + modifier = modifier, + verticalArrangement = Arrangement.spacedBy(12.dp), + ) { + NumberedStep(number = "1.") { + Text( + text = stringRes(R.string.favorite_dvms_empty_step1, ctaLabel), + style = MaterialTheme.typography.bodyMedium, + color = MaterialTheme.colorScheme.grayText, + ) + } + NumberedStep(number = "2.") { + Text( + text = step2Text, + inlineContent = starInlineContent, + style = MaterialTheme.typography.bodyMedium, + color = MaterialTheme.colorScheme.grayText, + ) + } + } +} + +@Composable +private fun NumberedStep( + number: String, + content: @Composable () -> Unit, +) { + Row(verticalAlignment = Alignment.Top) { + Text( + text = number, + style = MaterialTheme.typography.bodyMedium, + fontWeight = FontWeight.SemiBold, + modifier = Modifier.padding(end = 8.dp), + ) + content() + } +} diff --git a/amethyst/src/main/res/values/strings.xml b/amethyst/src/main/res/values/strings.xml index 5e87fff51f..dc4cdb6c0d 100644 --- a/amethyst/src/main/res/values/strings.xml +++ b/amethyst/src/main/res/values/strings.xml @@ -2181,7 +2181,10 @@ Feed algorithms you star appear here and as filter chips on the Home feed. Pin your favorite algorithms Tap the button below to browse algorithms and star the ones you want to keep here. + Tap \"%1$s\" below to browse algorithms. + Tap the %1$s next to a feed to keep it here. Add some feeds + Add more… Asking %1$s for a feed… Asking your favorite feed algorithms for feeds… Processing your feed…