diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AppNavigation.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AppNavigation.kt index 664d76efab..ca9b0a039a 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AppNavigation.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AppNavigation.kt @@ -461,12 +461,12 @@ fun BuildNavigation( composableFromEnd { ShortsScreen(accountViewModel, nav) } composableFromEnd { PublicChatsScreen(accountViewModel, nav) } composableFromEnd { RelayGroupDiscoveryScreen(accountViewModel, nav) } - composableFromEnd { BuzzDmListScreen(accountViewModel, nav) } - composableFromEnd { BuzzNewDmScreen(accountViewModel, nav) } + composableFromEndArgs { BuzzDmListScreen(it.relayUrl, accountViewModel, nav) } + composableFromEndArgs { BuzzNewDmScreen(it.relayUrl, accountViewModel, nav) } composableFromEnd { FollowPacksScreen(accountViewModel, nav) } composableFromEnd { LiveStreamsScreen(accountViewModel, nav) } composableFromEnd { NestsScreen(accountViewModel, nav) } - composableFromEnd { AgentConsoleScreen(accountViewModel, nav) } + composableFromEndArgs { AgentConsoleScreen(it.relayUrl, accountViewModel, nav) } composableFromEnd { AgentAttestationScreen(accountViewModel, nav) } composableFromEndArgs { AgentPersonaEditScreen(it.slug, accountViewModel, nav) } composableFromEndArgs { NestLobbyScreen(it.addressValue, accountViewModel, nav) } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/bottombars/NavBarItem.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/bottombars/NavBarItem.kt index fc8cdcbb91..165b506fdd 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/bottombars/NavBarItem.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/bottombars/NavBarItem.kt @@ -69,8 +69,6 @@ enum class NavBarItem { PODCASTS, PUBLIC_CHATS, RELAY_GROUPS, - AGENT_CONSOLE, - BUZZ_DMS, CONCORD, GEOHASH_CHATS, FOLLOW_PACKS, @@ -346,20 +344,6 @@ val NavBarCatalog: Map = icon = MaterialSymbols.Forum, resolveRoute = { Route.RelayGroups }, ), - NavBarItem.AGENT_CONSOLE to - NavBarItemDef( - id = NavBarItem.AGENT_CONSOLE, - labelRes = R.string.buzz_console_card_title, - icon = MaterialSymbols.AutoAwesome, - resolveRoute = { Route.AgentConsole }, - ), - NavBarItem.BUZZ_DMS to - NavBarItemDef( - id = NavBarItem.BUZZ_DMS, - labelRes = R.string.buzz_dm_nav_label, - icon = MaterialSymbols.AutoMirrored.Send, - resolveRoute = { Route.BuzzDmList }, - ), NavBarItem.CONCORD to NavBarItemDef( id = NavBarItem.CONCORD, @@ -512,8 +496,6 @@ val BottomBarCategories: List = listOf( NavBarItem.PUBLIC_CHATS, NavBarItem.RELAY_GROUPS, - NavBarItem.AGENT_CONSOLE, - NavBarItem.BUZZ_DMS, NavBarItem.CONCORD, NavBarItem.GEOHASH_CHATS, ), @@ -597,8 +579,6 @@ val DrawerFeedsItems: List = NavBarItem.COMMUNITIES, NavBarItem.PUBLIC_CHATS, NavBarItem.RELAY_GROUPS, - NavBarItem.AGENT_CONSOLE, - NavBarItem.BUZZ_DMS, NavBarItem.CONCORD, NavBarItem.GEOHASH_CHATS, NavBarItem.CALENDARS, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/routes/Routes.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/routes/Routes.kt index d0ec6b04e6..a8ebf2d4af 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/routes/Routes.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/routes/Routes.kt @@ -469,7 +469,10 @@ sealed class Route { @Serializable object EditNestsServers : Route() - @Serializable object AgentConsole : Route() + @Serializable + data class AgentConsole( + val relayUrl: String, + ) : Route() @Serializable object AgentAttestation : Route() @@ -719,9 +722,15 @@ sealed class Route { @Serializable object RelayGroups : Route() - @Serializable object BuzzDmList : Route() + @Serializable + data class BuzzDmList( + val relayUrl: String, + ) : Route() - @Serializable object BuzzNewDm : Route() + @Serializable + data class BuzzNewDm( + val relayUrl: String, + ) : Route() @Serializable object RelayGroupBrowse : Route() diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/BottomBarFeedPreloaders.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/BottomBarFeedPreloaders.kt index 756fe6692e..856adf38c8 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/BottomBarFeedPreloaders.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/BottomBarFeedPreloaders.kt @@ -137,10 +137,6 @@ private fun PreloadFor( // this tab needs no extra preload. NavBarItem.RELAY_GROUPS -> Unit - // The Agent Console + Buzz DM inbox fetch on-screen; nothing extra to preload here. - NavBarItem.AGENT_CONSOLE -> Unit - NavBarItem.BUZZ_DMS -> Unit - NavBarItem.CONCORD -> ConcordChannelSubscription(accountViewModel.dataSources().concordChannels, accountViewModel) NavBarItem.FOLLOW_PACKS -> FollowPacksFilterAssemblerSubscription(accountViewModel) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/buzz/AgentConsoleScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/buzz/AgentConsoleScreen.kt index c77334afbe..f0ceecf79b 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/buzz/AgentConsoleScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/buzz/AgentConsoleScreen.kt @@ -81,13 +81,14 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel */ @Composable fun AgentConsoleScreen( + relayUrl: String, accountViewModel: AccountViewModel, nav: INav, ) { val pubkey = accountViewModel.account.userProfile().pubkeyHex - val viewModel: AgentConsoleViewModel = viewModel(key = "AgentConsole-$pubkey") + val viewModel: AgentConsoleViewModel = viewModel(key = "AgentConsole-$relayUrl-$pubkey") - viewModel.bindAccountIfMissing(accountViewModel.account) + viewModel.bind(accountViewModel.account, relayUrl) val metrics by viewModel.metrics.collectAsStateWithLifecycle() val personas by viewModel.personas.collectAsStateWithLifecycle() diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/buzz/AgentConsoleViewModel.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/buzz/AgentConsoleViewModel.kt index 6c45c3d884..0671e196e4 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/buzz/AgentConsoleViewModel.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/buzz/AgentConsoleViewModel.kt @@ -26,6 +26,8 @@ import androidx.lifecycle.viewModelScope import com.vitorpamplona.amethyst.commons.model.buzz.AgentFleetAggregator import com.vitorpamplona.amethyst.commons.model.buzz.AgentFleetMetrics import com.vitorpamplona.amethyst.commons.model.buzz.BuzzRelayDialect +import com.vitorpamplona.amethyst.commons.model.buzz.BuzzWorkspaces +import com.vitorpamplona.amethyst.commons.relayauth.RelayAuthDecision import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.filter @@ -38,6 +40,8 @@ import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.relay.client.accessories.fetchAllPagesFromPool import com.vitorpamplona.quartz.nip01Core.relay.client.reqs.subscribeAsFlow import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter +import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl +import com.vitorpamplona.quartz.nip01Core.relay.normalizer.RelayUrlNormalizer import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job import kotlinx.coroutines.flow.MutableStateFlow @@ -68,6 +72,9 @@ import java.util.Collections class AgentConsoleViewModel : ViewModel() { @Volatile private var account: Account? = null + /** The community (relay) this console is scoped to — agents/telemetry live on community relays. */ + private var scopeRelay: NormalizedRelayUrl? = null + /** event id -> decrypted payload (null = decryption failed; don't retry). */ private val decryptCache = HashMap() private val refreshMutex = Mutex() @@ -89,9 +96,19 @@ class AgentConsoleViewModel : ViewModel() { /** Dedups ephemeral frames across relays and re-emissions (accessed off multiple readers). */ private val observerSeen = Collections.synchronizedSet(HashSet()) - fun bindAccountIfMissing(account: Account) { + /** Binds to [account] scoped to the community [relayUrl] — the console shows that community's fleet. */ + fun bind( + account: Account, + relayUrl: String, + ) { if (this.account != null) return + val relay = RelayUrlNormalizer.normalizeOrNull(relayUrl) + this.scopeRelay = relay this.account = account + relay?.let { + BuzzWorkspaces.join(it) + viewModelScope.launch { account.relayAuthLedger.setDecision(it.url, RelayAuthDecision.ALLOW) } + } refresh() } @@ -118,7 +135,7 @@ class AgentConsoleViewModel : ViewModel() { */ private suspend fun fetchFromRelays(account: Account) { val myPubkey = account.userProfile().pubkeyHex - val relays = BuzzRelayDialect.flow.value + account.outboxRelays.flow.value + val relays = scopeRelay?.let { setOf(it) } ?: (BuzzRelayDialect.flow.value + account.outboxRelays.flow.value) if (relays.isEmpty()) return val filters = @@ -183,7 +200,7 @@ class AgentConsoleViewModel : ViewModel() { val account = account ?: return if (observerJob != null) return - val relays = BuzzRelayDialect.flow.value + val relays = scopeRelay?.let { setOf(it) } ?: BuzzRelayDialect.flow.value if (relays.isEmpty()) return val signer = account.signer diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/buzz/BuzzDmListScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/buzz/BuzzDmListScreen.kt index e6ae9f8d28..e555e14224 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/buzz/BuzzDmListScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/buzz/BuzzDmListScreen.kt @@ -90,12 +90,13 @@ import kotlinx.coroutines.launch */ @Composable fun BuzzDmListScreen( + relayUrl: String, accountViewModel: AccountViewModel, nav: INav, ) { val pubkey = accountViewModel.account.userProfile().pubkeyHex - val viewModel: BuzzDmListViewModel = viewModel(key = "BuzzDmList-$pubkey") - viewModel.bindAccountIfMissing(accountViewModel.account) + val viewModel: BuzzDmListViewModel = viewModel(key = "BuzzDmList-$relayUrl-$pubkey") + viewModel.bind(accountViewModel.account, relayUrl) val rows by viewModel.rows.collectAsStateWithLifecycle() @@ -105,7 +106,7 @@ fun BuzzDmListScreen( ExtendedFloatingActionButton( text = { Text(stringRes(R.string.buzz_dm_new)) }, icon = { Icon(symbol = MaterialSymbols.Add, contentDescription = null) }, - onClick = { nav.nav(Route.BuzzNewDm) }, + onClick = { nav.nav(Route.BuzzNewDm(relayUrl)) }, ) }, ) { padding -> diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/buzz/BuzzDmListViewModel.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/buzz/BuzzDmListViewModel.kt index 6a23a972c5..2bafa4e9c8 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/buzz/BuzzDmListViewModel.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/buzz/BuzzDmListViewModel.kt @@ -26,6 +26,7 @@ import androidx.lifecycle.viewModelScope import com.vitorpamplona.amethyst.commons.model.buzz.BuzzDmRegistry import com.vitorpamplona.amethyst.commons.model.buzz.BuzzRelayDialect import com.vitorpamplona.amethyst.commons.model.buzz.BuzzWorkspaces +import com.vitorpamplona.amethyst.commons.relayauth.RelayAuthDecision import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.filter @@ -40,6 +41,7 @@ import com.vitorpamplona.quartz.nip01Core.relay.client.accessories.fetchAllPages import com.vitorpamplona.quartz.nip01Core.relay.client.reqs.subscribeAsFlow import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl +import com.vitorpamplona.quartz.nip01Core.relay.normalizer.RelayUrlNormalizer import com.vitorpamplona.quartz.nip29RelayGroups.GroupId import com.vitorpamplona.quartz.nipC7Chats.ChatEvent import kotlinx.coroutines.Dispatchers @@ -73,6 +75,9 @@ import java.util.concurrent.ConcurrentHashMap */ class BuzzDmListViewModel : ViewModel() { @Volatile private var account: Account? = null + + /** The community (relay) this inbox is scoped to — DMs are per-community. */ + private var scopeRelay: NormalizedRelayUrl? = null private val refreshMutex = Mutex() private var liveJob: Job? = null @@ -98,11 +103,24 @@ class BuzzDmListViewModel : ViewModel() { val lastActivity: Long, ) - private fun relays(): Set = BuzzWorkspaces.flow.value + BuzzRelayDialect.flow.value + private fun relays(): Set = scopeRelay?.let { setOf(it) } ?: (BuzzWorkspaces.flow.value + BuzzRelayDialect.flow.value) - fun bindAccountIfMissing(account: Account) { + /** + * Binds to [account] scoped to the community [relayUrl]. Marks that relay a joined workspace and + * pre-approves NIP-42 so the read-only `#p=me` DM discovery authenticates against it. + */ + fun bind( + account: Account, + relayUrl: String, + ) { if (this.account != null) return + val relay = RelayUrlNormalizer.normalizeOrNull(relayUrl) + this.scopeRelay = relay this.account = account + relay?.let { + BuzzWorkspaces.join(it) + viewModelScope.launch { account.relayAuthLedger.setDecision(it.url, RelayAuthDecision.ALLOW) } + } refresh() startLive() } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/buzz/BuzzNewDmScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/buzz/BuzzNewDmScreen.kt index cd613cae5f..8de53e7d86 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/buzz/BuzzNewDmScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/buzz/BuzzNewDmScreen.kt @@ -75,11 +75,12 @@ import com.vitorpamplona.quartz.nip01Core.relay.normalizer.displayUrl @OptIn(ExperimentalLayoutApi::class) @Composable fun BuzzNewDmScreen( + relayUrl: String, accountViewModel: AccountViewModel, nav: INav, ) { - val viewModel: BuzzNewDmViewModel = viewModel() - viewModel.bindAccountIfMissing(accountViewModel.account) + val viewModel: BuzzNewDmViewModel = viewModel(key = "BuzzNewDm-$relayUrl") + viewModel.bind(accountViewModel.account, relayUrl) val relays by viewModel.relays.collectAsStateWithLifecycle() val selectedRelay by viewModel.relay.collectAsStateWithLifecycle() @@ -162,7 +163,7 @@ fun BuzzNewDmScreen( if (groupId != null) { nav.newStack(Route.RelayGroup(groupId.id, groupId.relayUrl.url)) } else { - nav.newStack(Route.BuzzDmList) + nav.newStack(Route.BuzzDmList(relayUrl)) } } }, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/buzz/BuzzNewDmViewModel.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/buzz/BuzzNewDmViewModel.kt index 77c2a53b26..b0de33e500 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/buzz/BuzzNewDmViewModel.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/buzz/BuzzNewDmViewModel.kt @@ -22,13 +22,12 @@ package com.vitorpamplona.amethyst.ui.screen.loggedIn.buzz import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope -import com.vitorpamplona.amethyst.commons.model.buzz.BuzzRelayDialect -import com.vitorpamplona.amethyst.commons.model.buzz.BuzzWorkspaces import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.quartz.buzz.dm.DmOpenEvent import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.isValid import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl +import com.vitorpamplona.quartz.nip01Core.relay.normalizer.RelayUrlNormalizer import com.vitorpamplona.quartz.nip19Bech32.decodePublicKeyAsHexOrNull import com.vitorpamplona.quartz.nip29RelayGroups.GroupId import kotlinx.coroutines.Dispatchers @@ -70,15 +69,16 @@ class BuzzNewDmViewModel : ViewModel() { ) : Status } - fun bindAccountIfMissing(account: Account) { + /** Binds scoped to a single community [relayUrl] — a new DM is created on that community. */ + fun bind( + account: Account, + relayUrl: String, + ) { if (this.account != null) return this.account = account - val buzz = - (BuzzWorkspaces.flow.value + BuzzRelayDialect.flow.value) - .toList() - .sortedBy { it.url } - _relays.value = buzz - _relay.value = buzz.firstOrNull() + val relay = RelayUrlNormalizer.normalizeOrNull(relayUrl) + _relays.value = listOfNotNull(relay) + _relay.value = relay } fun selectRelay(relay: NormalizedRelayUrl) { diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/relayGroup/RelayGroupChannelListScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/relayGroup/RelayGroupChannelListScreen.kt index 3331f67c3d..824cc9df7c 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/relayGroup/RelayGroupChannelListScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/relayGroup/RelayGroupChannelListScreen.kt @@ -62,6 +62,7 @@ import androidx.lifecycle.viewmodel.compose.viewModel import com.vitorpamplona.amethyst.Amethyst import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.commons.icons.symbols.Icon +import com.vitorpamplona.amethyst.commons.icons.symbols.MaterialSymbol import com.vitorpamplona.amethyst.commons.icons.symbols.MaterialSymbols import com.vitorpamplona.amethyst.commons.model.buzz.BuzzRelayDialect import com.vitorpamplona.amethyst.commons.model.nip29RelayGroups.RelayGroupChannel @@ -218,7 +219,9 @@ fun RelayGroupChannelListScreen( ) { padding -> val myPubkey = accountViewModel.userProfile().pubkeyHex val showBuzz = isBuzz && buzzChannels.isNotEmpty() - if (channels.isEmpty() && !showBuzz) { + // A Buzz relay is a community, so always render its list (with the per-community DM + Console + // entries) even before channels load, rather than the generic "empty" text. + if (channels.isEmpty() && !showBuzz && !isBuzz) { // An empty directory on a relay whose NIP-11 says it doesn't run NIP-29 is almost // certainly the wrong relay, not a young one — say so instead of the generic empty text. // For a Buzz relay still discovering, say so; if it settled empty, guide the user. @@ -249,6 +252,13 @@ fun RelayGroupChannelListScreen( } } else { LazyColumn(modifier = Modifier.padding(padding)) { + // A Buzz relay is a community: its Direct Messages and (owner) Agent Console are + // scoped to it, reached from here rather than as global drawer entries. + if (isBuzz) { + item(key = "buzz-community-actions") { + BuzzCommunityActions(relayUrl = relay.url, nav = nav) + } + } // Buzz membership section: the channels you already belong to on this workspace, // each addable to your kind-10009 list. if (showBuzz) { @@ -325,6 +335,46 @@ private fun TorClearnetBanner( } } +/** + * Per-community entry points on a Buzz relay's screen: its Direct Messages inbox and (owner) Agent + * Console, both scoped to this one relay — replacing the old global drawer entries. + */ +@Composable +private fun BuzzCommunityActions( + relayUrl: String, + nav: INav, +) { + Column(Modifier.fillMaxWidth().padding(horizontal = 12.dp, vertical = 8.dp)) { + BuzzActionCard( + icon = MaterialSymbols.AutoMirrored.Send, + label = stringRes(R.string.buzz_dm_title), + onClick = { nav.nav(Route.BuzzDmList(relayUrl)) }, + ) + Spacer(Modifier.size(8.dp)) + BuzzActionCard( + icon = MaterialSymbols.AutoAwesome, + label = stringRes(R.string.buzz_console_card_title), + onClick = { nav.nav(Route.AgentConsole(relayUrl)) }, + ) + } +} + +@Composable +private fun BuzzActionCard( + icon: MaterialSymbol, + label: String, + onClick: () -> Unit, +) { + Card(onClick = onClick, modifier = Modifier.fillMaxWidth()) { + Row(Modifier.padding(14.dp), verticalAlignment = Alignment.CenterVertically) { + Icon(symbol = icon, contentDescription = null, tint = MaterialTheme.colorScheme.primary, modifier = Modifier.size(22.dp)) + Spacer(Modifier.size(12.dp)) + Text(label, style = MaterialTheme.typography.titleSmall, fontWeight = FontWeight.Bold, modifier = Modifier.weight(1f)) + Icon(symbol = MaterialSymbols.ChevronRight, contentDescription = null, tint = MaterialTheme.colorScheme.onSurfaceVariant, modifier = Modifier.size(20.dp)) + } + } +} + @Composable private fun RelayGroupChannelRow( channel: RelayGroupChannel, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/SettingsCatalogBuilder.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/SettingsCatalogBuilder.kt index d8ea10d119..b63e323eef 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/SettingsCatalogBuilder.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/SettingsCatalogBuilder.kt @@ -104,7 +104,6 @@ fun buildSettingsCatalog( symEntry(R.string.ots_explorer_settings, MaterialSymbols.Search, R.string.ots_explorer_search_keywords, Route.OtsSettings), symEntry(R.string.namecoin_settings, MaterialSymbols.Security, R.string.namecoin_search_keywords, Route.NamecoinSettings), symEntry(R.string.resource_usage_title, MaterialSymbols.Bolt, R.string.resource_usage_search_keywords, Route.ResourceUsage), - symEntry(R.string.agent_console_title, MaterialSymbols.AutoAwesome, R.string.agent_console_search_keywords, Route.AgentConsole), ), )