From 460ccc2d02d6ac711350bb9f5abe69c55e9f0783 Mon Sep 17 00:00:00 2001 From: davotoula Date: Fri, 20 Mar 2026 12:05:49 +0100 Subject: [PATCH 1/4] modernize SpinnerSelectionDialog with Material 3 styling --- .../amethyst/ui/components/TextSpinner.kt | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/TextSpinner.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/TextSpinner.kt index f8522fe3fc..2325e0752a 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/TextSpinner.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/TextSpinner.kt @@ -20,7 +20,6 @@ */ package com.vitorpamplona.amethyst.ui.components -import androidx.compose.foundation.BorderStroke import androidx.compose.foundation.clickable import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.Arrangement @@ -34,7 +33,6 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Surface @@ -61,7 +59,6 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.window.Dialog import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.ui.stringRes -import com.vitorpamplona.amethyst.ui.theme.DividerThickness import com.vitorpamplona.amethyst.ui.theme.Font14SP import kotlinx.collections.immutable.ImmutableList @@ -211,14 +208,14 @@ fun SpinnerSelectionDialog( ) { Dialog(onDismissRequest = onDismiss) { Surface( - border = BorderStroke(0.25.dp, Color.LightGray), - shape = RoundedCornerShape(5.dp), + shape = RoundedCornerShape(28.dp), + color = MaterialTheme.colorScheme.surfaceContainerHigh, ) { LazyColumn { title?.let { item { Row( - modifier = Modifier.fillMaxWidth().padding(16.dp, 16.dp), + modifier = Modifier.fillMaxWidth().padding(20.dp), horizontalArrangement = Arrangement.Center, ) { Text( @@ -227,7 +224,6 @@ fun SpinnerSelectionDialog( fontWeight = FontWeight.Bold, ) } - HorizontalDivider(color = Color.LightGray, thickness = DividerThickness) } } itemsIndexed(options) { index, item -> @@ -237,7 +233,7 @@ fun SpinnerSelectionDialog( Modifier .fillMaxWidth() .clickable { onSelect(index) } - .padding(16.dp, 16.dp) + .padding(horizontal = 16.dp, vertical = 12.dp) .semantics { role = Role.Button contentDescription = optionsOfLabel @@ -245,9 +241,6 @@ fun SpinnerSelectionDialog( ) { Column { onRenderItem(item) } } - if (index < options.lastIndex) { - HorizontalDivider(color = Color.LightGray, thickness = DividerThickness) - } } } } From 3a195c4648efb6c03f41b1c9a8b5d27fed8c7db4 Mon Sep 17 00:00:00 2001 From: davotoula Date: Fri, 20 Mar 2026 12:09:07 +0100 Subject: [PATCH 2/4] add grouped feed filter dialog with Material 3 styling add icons, reduce text size, center group headers in filter dialog --- .../navigation/topbars/FeedFilterSpinner.kt | 309 ++++++++++++++---- amethyst/src/main/res/values/strings.xml | 2 +- 2 files changed, 252 insertions(+), 59 deletions(-) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/topbars/FeedFilterSpinner.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/topbars/FeedFilterSpinner.kt index 62f7217670..c39afbece0 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/topbars/FeedFilterSpinner.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/topbars/FeedFilterSpinner.kt @@ -21,20 +21,37 @@ package com.vitorpamplona.amethyst.ui.navigation.topbars import android.Manifest +import androidx.compose.foundation.BorderStroke import androidx.compose.foundation.clickable import androidx.compose.foundation.interaction.MutableInteractionSource 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.FlowRow import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.ExpandMore +import androidx.compose.material.icons.outlined.Groups +import androidx.compose.material.icons.outlined.LocationOn +import androidx.compose.material.icons.outlined.Person +import androidx.compose.material.icons.outlined.Public +import androidx.compose.material.icons.outlined.SensorDoor +import androidx.compose.material.icons.outlined.ViewList +import androidx.compose.material.icons.outlined.VolumeOff import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.Immutable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue @@ -43,14 +60,17 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.semantics.Role import androidx.compose.ui.semantics.onClick import androidx.compose.ui.semantics.role import androidx.compose.ui.semantics.semantics import androidx.compose.ui.semantics.stateDescription +import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp +import androidx.compose.ui.window.Dialog import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.google.accompanist.permissions.ExperimentalPermissionsApi import com.google.accompanist.permissions.isGranted @@ -62,7 +82,6 @@ import com.vitorpamplona.amethyst.model.TopFilter import com.vitorpamplona.amethyst.service.location.LocationState import com.vitorpamplona.amethyst.service.relayClient.reqCommand.event.observeNote import com.vitorpamplona.amethyst.ui.components.LoadingAnimation -import com.vitorpamplona.amethyst.ui.components.SpinnerSelectionDialog import com.vitorpamplona.amethyst.ui.note.creators.location.LoadCityName import com.vitorpamplona.amethyst.ui.screen.CommunityName import com.vitorpamplona.amethyst.ui.screen.FeedDefinition @@ -217,7 +236,7 @@ fun FeedFilterSpinner( if (optionsShowing) { options.isNotEmpty().also { - SpinnerSelectionDialog( + GroupedFeedFilterDialog( title = explainer, options = options, onDismiss = { optionsShowing = false }, @@ -241,84 +260,258 @@ fun RenderOption( when (option) { is GeoHashName -> { LoadCityName(option.geoHashTag) { - Row( - horizontalArrangement = Arrangement.Center, - modifier = Modifier.fillMaxWidth(), - ) { - Text(text = "/g/$it", color = MaterialTheme.colorScheme.onSurface) - } + Text(text = "/g/$it", fontSize = 14.sp, color = MaterialTheme.colorScheme.onSurface) } } is HashtagName -> { - Row( - horizontalArrangement = Arrangement.Center, - modifier = Modifier.fillMaxWidth(), - ) { - Text(text = option.name(), color = MaterialTheme.colorScheme.onSurface) - } + Text(text = option.name(), fontSize = 14.sp, color = MaterialTheme.colorScheme.onSurface) } is ResourceName -> { - Row( - horizontalArrangement = Arrangement.Center, - modifier = Modifier.fillMaxWidth(), - ) { - Text( - text = stringRes(id = option.resourceId), - color = MaterialTheme.colorScheme.onSurface, - ) - } + Text( + text = stringRes(id = option.resourceId), + fontSize = 14.sp, + color = MaterialTheme.colorScheme.onSurface, + ) } is PeopleListName -> { - Row( - horizontalArrangement = Arrangement.Center, - modifier = Modifier.fillMaxWidth(), - ) { - val noteState by observeNote(option.note, accountViewModel) + val noteState by observeNote(option.note, accountViewModel) - val noteEvent = noteState.note.event - val name = - when (noteEvent) { - is PeopleListEvent -> { - noteEvent.titleOrName() ?: option.note.dTag() - } - - is FollowListEvent -> { - noteEvent.title() ?: option.note.dTag() - } - - else -> { - option.note.dTag() - } + val noteEvent = noteState.note.event + val name = + when (noteEvent) { + is PeopleListEvent -> { + noteEvent.titleOrName() ?: option.note.dTag() } - Text(text = name, color = MaterialTheme.colorScheme.onSurface) - } + is FollowListEvent -> { + noteEvent.title() ?: option.note.dTag() + } + + else -> { + option.note.dTag() + } + } + + Text(text = name, fontSize = 14.sp, color = MaterialTheme.colorScheme.onSurface) } is CommunityName -> { - Row( - horizontalArrangement = Arrangement.Center, - modifier = Modifier.fillMaxWidth(), - ) { - val it by observeNote(option.note, accountViewModel) + val it by observeNote(option.note, accountViewModel) - Text(text = "/n/${((it.note as? AddressableNote)?.dTag() ?: "")}", color = MaterialTheme.colorScheme.onSurface) - } + Text(text = "/n/${((it.note as? AddressableNote)?.dTag() ?: "")}", fontSize = 14.sp, color = MaterialTheme.colorScheme.onSurface) } is RelayName -> { - Row( - horizontalArrangement = Arrangement.Center, - modifier = Modifier.fillMaxWidth(), + Text( + text = option.name(), + fontSize = 14.sp, + color = MaterialTheme.colorScheme.onSurface, + ) + } + } +} + +@Immutable +private data class IndexedFeedDefinition( + val originalIndex: Int, + val item: FeedDefinition, +) + +private enum class FeedGroup( + val label: String, +) { + FEEDS("Feeds"), + HASHTAGS("Hashtags"), + COMMUNITIES("Communities"), + LISTS("Lists"), +} + +private fun groupFeedDefinitions(options: ImmutableList): Map> { + val indexed = options.mapIndexed { index, item -> IndexedFeedDefinition(index, item) } + return indexed.groupBy { entry -> + when (entry.item.name) { + is HashtagName -> FeedGroup.HASHTAGS + is CommunityName -> FeedGroup.COMMUNITIES + is PeopleListName -> FeedGroup.LISTS + else -> FeedGroup.FEEDS + } + } +} + +@OptIn(ExperimentalLayoutApi::class) +@Composable +private fun GroupedFeedFilterDialog( + title: String, + options: ImmutableList, + onSelect: (Int) -> Unit, + onDismiss: () -> Unit, + onRenderItem: @Composable (FeedDefinition) -> Unit, +) { + val grouped = remember(options) { groupFeedDefinitions(options) } + + Dialog(onDismissRequest = onDismiss) { + Surface( + shape = RoundedCornerShape(28.dp), + color = MaterialTheme.colorScheme.surfaceContainerHigh, + ) { + LazyColumn( + modifier = Modifier.padding(vertical = 20.dp), ) { - Text( - text = option.name(), - color = MaterialTheme.colorScheme.onSurface, - ) + item { + Text( + text = title, + style = MaterialTheme.typography.titleSmall, + color = MaterialTheme.colorScheme.onSurfaceVariant, + textAlign = TextAlign.Center, + modifier = Modifier.fillMaxWidth().padding(horizontal = 20.dp, vertical = 8.dp), + ) + } + + FeedGroup.entries.forEach { group -> + val items = grouped[group] + if (!items.isNullOrEmpty()) { + item { + GroupSection( + label = group.label, + items = items, + isChipLayout = group == FeedGroup.HASHTAGS, + onSelect = onSelect, + onRenderItem = onRenderItem, + ) + } + } + } } } } } + +@OptIn(ExperimentalLayoutApi::class) +@Composable +private fun GroupSection( + label: String, + items: List, + isChipLayout: Boolean, + onSelect: (Int) -> Unit, + onRenderItem: @Composable (FeedDefinition) -> Unit, +) { + Surface( + modifier = Modifier.padding(horizontal = 12.dp, vertical = 4.dp), + shape = RoundedCornerShape(16.dp), + color = MaterialTheme.colorScheme.surfaceContainerLow, + ) { + Column { + Text( + text = label.uppercase(), + fontSize = 12.sp, + letterSpacing = 0.8.sp, + color = MaterialTheme.colorScheme.onSurfaceVariant, + textAlign = TextAlign.Center, + modifier = Modifier.fillMaxWidth().padding(top = 10.dp, bottom = 6.dp), + ) + + if (isChipLayout) { + FlowRow( + modifier = Modifier.padding(horizontal = 12.dp, vertical = 4.dp), + horizontalArrangement = Arrangement.spacedBy(6.dp), + verticalArrangement = Arrangement.spacedBy(6.dp), + ) { + items.forEach { entry -> + Surface( + modifier = Modifier.clickable { onSelect(entry.originalIndex) }, + shape = RoundedCornerShape(18.dp), + border = BorderStroke(1.dp, MaterialTheme.colorScheme.outline), + color = Color.Transparent, + ) { + Text( + text = entry.item.name.name(), + fontSize = 13.sp, + color = MaterialTheme.colorScheme.onSurface, + modifier = Modifier.padding(horizontal = 14.dp, vertical = 7.dp), + ) + } + } + } + Spacer(modifier = Modifier.height(4.dp)) + } else { + items.forEach { entry -> + Row( + verticalAlignment = Alignment.CenterVertically, + modifier = + Modifier + .fillMaxWidth() + .clickable { onSelect(entry.originalIndex) } + .padding(horizontal = 16.dp, vertical = 6.dp), + ) { + FeedIcon( + item = entry.item, + modifier = Modifier.size(20.dp), + ) + Spacer(modifier = Modifier.padding(start = 12.dp)) + Column(modifier = Modifier.weight(1f)) { onRenderItem(entry.item) } + } + } + } + } + } +} + +@Composable +private fun FeedIcon( + item: FeedDefinition, + modifier: Modifier = Modifier, +) { + val icon = + when (item.code) { + is TopFilter.Global -> { + Icons.Outlined.Public + } + + is TopFilter.AroundMe -> { + Icons.Outlined.LocationOn + } + + is TopFilter.AllFollows -> { + Icons.Outlined.Groups + } + + is TopFilter.AllUserFollows -> { + Icons.Outlined.Person + } + + is TopFilter.DefaultFollows -> { + Icons.Outlined.Groups + } + + is TopFilter.MuteList -> { + Icons.Outlined.VolumeOff + } + + is TopFilter.Chess -> { + Icons.Outlined.Groups + } + + is TopFilter.PeopleList -> { + Icons.Outlined.ViewList + } + + else -> { + when (item.name) { + is GeoHashName -> Icons.Outlined.LocationOn + is RelayName -> Icons.Outlined.SensorDoor + is CommunityName -> Icons.Outlined.Groups + is PeopleListName -> Icons.Outlined.ViewList + else -> Icons.Outlined.Person + } + } + } + Icon( + imageVector = icon, + contentDescription = null, + modifier = modifier, + tint = MaterialTheme.colorScheme.onSurfaceVariant, + ) +} diff --git a/amethyst/src/main/res/values/strings.xml b/amethyst/src/main/res/values/strings.xml index a935341290..2e07051681 100644 --- a/amethyst/src/main/res/values/strings.xml +++ b/amethyst/src/main/res/values/strings.xml @@ -1545,7 +1545,7 @@ My Lists/Sets My Lists Users - Select a list to filter the feed + Select an option to filter the feed Log off on device lock Private Message From f15b7620df748cf6d436aeedafff8e79166409a5 Mon Sep 17 00:00:00 2001 From: davotoula Date: Fri, 20 Mar 2026 13:46:49 +0100 Subject: [PATCH 3/4] update gitignore --- .gitignore | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitignore b/.gitignore index b5af05773e..de1c06cf0b 100644 --- a/.gitignore +++ b/.gitignore @@ -33,6 +33,10 @@ /captures .cxx +# superpowers skill +.superpowers +docs/brainstorms +docs/superpowers # Built application files *.apk From 620f8dbf10e8556a3da8ab44ad8c341fd1d28a98 Mon Sep 17 00:00:00 2001 From: davotoula Date: Fri, 20 Mar 2026 14:30:07 +0100 Subject: [PATCH 4/4] =?UTF-8?q?code=20review=20fixes:=20=20=201.=20options?= =?UTF-8?q?.isNotEmpty().also=20=E2=86=92=20if=20guard=20=20=202.=20Hardco?= =?UTF-8?q?ded=20English=20strings=20in=20FeedGroup=20enum=20=20=203.=20Ha?= =?UTF-8?q?rdcoded=20accessibility=20label=20=20=204.=20Raw=2014.sp=20lite?= =?UTF-8?q?rals=20(=C3=976)=20=E2=86=92=20replaced=20with=20Font14SP=20the?= =?UTF-8?q?me=20constant=20=20=205.=20Raw=2012.sp=20literal=20=E2=86=92=20?= =?UTF-8?q?replaced=20with=20Font12SP=20theme=20constant=20=20=206.=20Modi?= =?UTF-8?q?fier.size(20.dp)=20=E2=86=92=20replaced=20with=20existing=20Siz?= =?UTF-8?q?e20Modifier=20theme=20constant?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../amethyst/ui/components/TextSpinner.kt | 12 ++- .../navigation/topbars/FeedFilterSpinner.kt | 81 ++++++++++--------- amethyst/src/main/res/values/strings.xml | 4 + 3 files changed, 50 insertions(+), 47 deletions(-) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/TextSpinner.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/TextSpinner.kt index 2325e0752a..8d704df193 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/TextSpinner.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/TextSpinner.kt @@ -156,13 +156,11 @@ private fun BaseTextSpinner( ) } - if (optionsShowing) { - options.isNotEmpty().also { - SpinnerSelectionDialog(options = options, onDismiss = { optionsShowing = false }) { - currentText = options[it].title - optionsShowing = false - onSelect(it) - } + if (optionsShowing && options.isNotEmpty()) { + SpinnerSelectionDialog(options = options, onDismiss = { optionsShowing = false }) { + currentText = options[it].title + optionsShowing = false + onSelect(it) } } } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/topbars/FeedFilterSpinner.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/topbars/FeedFilterSpinner.kt index c39afbece0..be00e48457 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/topbars/FeedFilterSpinner.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/topbars/FeedFilterSpinner.kt @@ -34,18 +34,17 @@ import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.automirrored.outlined.ViewList +import androidx.compose.material.icons.automirrored.outlined.VolumeOff import androidx.compose.material.icons.filled.ExpandMore import androidx.compose.material.icons.outlined.Groups import androidx.compose.material.icons.outlined.LocationOn import androidx.compose.material.icons.outlined.Person import androidx.compose.material.icons.outlined.Public import androidx.compose.material.icons.outlined.SensorDoor -import androidx.compose.material.icons.outlined.ViewList -import androidx.compose.material.icons.outlined.VolumeOff import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Surface @@ -93,6 +92,8 @@ import com.vitorpamplona.amethyst.ui.screen.RelayName import com.vitorpamplona.amethyst.ui.screen.ResourceName import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.stringRes +import com.vitorpamplona.amethyst.ui.theme.Font12SP +import com.vitorpamplona.amethyst.ui.theme.Font14SP import com.vitorpamplona.amethyst.ui.theme.Size20Modifier import com.vitorpamplona.amethyst.ui.theme.StdHorzSpacer import com.vitorpamplona.amethyst.ui.theme.placeholderText @@ -139,6 +140,8 @@ fun FeedFilterSpinner( stringRes(R.string.feed_filter_select_an_option, selectAnOption) } + val openDropdownLabel = stringRes(R.string.open_dropdown_menu) + Box( modifier = modifier, contentAlignment = Alignment.Center, @@ -156,7 +159,7 @@ fun FeedFilterSpinner( Text( text = stringRes(R.string.lack_location_permissions), - fontSize = 12.sp, + fontSize = Font12SP, lineHeight = 12.sp, ) } else { @@ -171,7 +174,7 @@ fun FeedFilterSpinner( Row { Text( text = "(${myLocation.geoHash})", - fontSize = 12.sp, + fontSize = Font12SP, lineHeight = 12.sp, ) Spacer(modifier = StdHorzSpacer) @@ -181,7 +184,7 @@ fun FeedFilterSpinner( ) { cityName -> Text( text = "($cityName)", - fontSize = 12.sp, + fontSize = Font12SP, lineHeight = 12.sp, ) } @@ -190,7 +193,7 @@ fun FeedFilterSpinner( LocationState.LocationResult.LackPermission -> { Text( text = stringRes(R.string.lack_location_permissions), - fontSize = 12.sp, + fontSize = Font12SP, lineHeight = 12.sp, ) } @@ -198,7 +201,7 @@ fun FeedFilterSpinner( LocationState.LocationResult.Loading -> { Text( text = stringRes(R.string.loading_location), - fontSize = 12.sp, + fontSize = Font12SP, lineHeight = 12.sp, ) } @@ -226,7 +229,7 @@ fun FeedFilterSpinner( }.semantics { role = Role.DropdownList stateDescription = accessibilityDescription - onClick(label = "Open feed filter menu") { + onClick(label = openDropdownLabel) { optionsShowing = true return@onClick true } @@ -234,20 +237,18 @@ fun FeedFilterSpinner( ) } - if (optionsShowing) { - options.isNotEmpty().also { - GroupedFeedFilterDialog( - title = explainer, - options = options, - onDismiss = { optionsShowing = false }, - onSelect = { - selected = options[it] - optionsShowing = false - onSelect(it) - }, - ) { - RenderOption(it.name, accountViewModel) - } + if (optionsShowing && options.isNotEmpty()) { + GroupedFeedFilterDialog( + title = explainer, + options = options, + onDismiss = { optionsShowing = false }, + onSelect = { + selected = options[it] + optionsShowing = false + onSelect(it) + }, + ) { + RenderOption(it.name, accountViewModel) } } } @@ -260,18 +261,18 @@ fun RenderOption( when (option) { is GeoHashName -> { LoadCityName(option.geoHashTag) { - Text(text = "/g/$it", fontSize = 14.sp, color = MaterialTheme.colorScheme.onSurface) + Text(text = "/g/$it", fontSize = Font14SP, color = MaterialTheme.colorScheme.onSurface) } } is HashtagName -> { - Text(text = option.name(), fontSize = 14.sp, color = MaterialTheme.colorScheme.onSurface) + Text(text = option.name(), fontSize = Font14SP, color = MaterialTheme.colorScheme.onSurface) } is ResourceName -> { Text( text = stringRes(id = option.resourceId), - fontSize = 14.sp, + fontSize = Font14SP, color = MaterialTheme.colorScheme.onSurface, ) } @@ -295,19 +296,19 @@ fun RenderOption( } } - Text(text = name, fontSize = 14.sp, color = MaterialTheme.colorScheme.onSurface) + Text(text = name, fontSize = Font14SP, color = MaterialTheme.colorScheme.onSurface) } is CommunityName -> { val it by observeNote(option.note, accountViewModel) - Text(text = "/n/${((it.note as? AddressableNote)?.dTag() ?: "")}", fontSize = 14.sp, color = MaterialTheme.colorScheme.onSurface) + Text(text = "/n/${((it.note as? AddressableNote)?.dTag() ?: "")}", fontSize = Font14SP, color = MaterialTheme.colorScheme.onSurface) } is RelayName -> { Text( text = option.name(), - fontSize = 14.sp, + fontSize = Font14SP, color = MaterialTheme.colorScheme.onSurface, ) } @@ -321,12 +322,12 @@ private data class IndexedFeedDefinition( ) private enum class FeedGroup( - val label: String, + @param:androidx.annotation.StringRes val labelRes: Int, ) { - FEEDS("Feeds"), - HASHTAGS("Hashtags"), - COMMUNITIES("Communities"), - LISTS("Lists"), + FEEDS(R.string.feed_group_feeds), + HASHTAGS(R.string.feed_group_hashtags), + COMMUNITIES(R.string.feed_group_communities), + LISTS(R.string.feed_group_lists), } private fun groupFeedDefinitions(options: ImmutableList): Map> { @@ -375,7 +376,7 @@ private fun GroupedFeedFilterDialog( if (!items.isNullOrEmpty()) { item { GroupSection( - label = group.label, + label = stringRes(group.labelRes), items = items, isChipLayout = group == FeedGroup.HASHTAGS, onSelect = onSelect, @@ -406,7 +407,7 @@ private fun GroupSection( Column { Text( text = label.uppercase(), - fontSize = 12.sp, + fontSize = Font12SP, letterSpacing = 0.8.sp, color = MaterialTheme.colorScheme.onSurfaceVariant, textAlign = TextAlign.Center, @@ -448,7 +449,7 @@ private fun GroupSection( ) { FeedIcon( item = entry.item, - modifier = Modifier.size(20.dp), + modifier = Size20Modifier, ) Spacer(modifier = Modifier.padding(start = 12.dp)) Column(modifier = Modifier.weight(1f)) { onRenderItem(entry.item) } @@ -487,7 +488,7 @@ private fun FeedIcon( } is TopFilter.MuteList -> { - Icons.Outlined.VolumeOff + Icons.AutoMirrored.Outlined.VolumeOff } is TopFilter.Chess -> { @@ -495,7 +496,7 @@ private fun FeedIcon( } is TopFilter.PeopleList -> { - Icons.Outlined.ViewList + Icons.AutoMirrored.Outlined.ViewList } else -> { @@ -503,7 +504,7 @@ private fun FeedIcon( is GeoHashName -> Icons.Outlined.LocationOn is RelayName -> Icons.Outlined.SensorDoor is CommunityName -> Icons.Outlined.Groups - is PeopleListName -> Icons.Outlined.ViewList + is PeopleListName -> Icons.AutoMirrored.Outlined.ViewList else -> Icons.Outlined.Person } } diff --git a/amethyst/src/main/res/values/strings.xml b/amethyst/src/main/res/values/strings.xml index 2e07051681..a506604f92 100644 --- a/amethyst/src/main/res/values/strings.xml +++ b/amethyst/src/main/res/values/strings.xml @@ -1546,6 +1546,10 @@ My Lists Users Select an option to filter the feed + Feeds + Hashtags + Communities + Lists Log off on device lock Private Message