feat(desktop): tabs-first header for Home / Reads, compact Notifications header
Refactored the three feed screen headers so they all match the Messages
pattern — single compact row padded horizontal = 12, vertical = 8, no
oversized titles, no multi-row metadata.
FeedScreen (Home):
- Replaced the `headlineMedium` "Global Feed" / "Following Feed" title
plus a redundant Global/Following chip row plus a separate relay-count
meta-line plus a large "New Post" button with:
[ Following | Global ] [relays] [refresh] [+ compose]
The selected tab IS the screen title. Relay count + followed-user
count surface through a hover tooltip on the relays icon (desktop
convention; info is preserved without taking a whole row).
- Relays icon click opens the picker when the account can edit, falls
through to navigate-to-relays otherwise.
ReadsScreen:
- Same treatment: dropped the "Reads" label, lifted Following/Global
chips to the left, single refresh icon on the right. "N relays
connected" moved to the refresh button's content description.
commons/FeedHeader (used by NotificationsScreen):
- Dropped the RelayStatusIndicator (icon + count text + refresh button,
took 3 slots). Now just titleMedium on the left + a single refresh
IconButton on the right with relay count in its content description,
matching the Messages "titleMedium + icon buttons" rhythm.
- Internal padding(horizontal = 12, vertical = 8) baked in so callers
don't need a trailing Spacer.
https://claude.ai/code/session_01NufduPfZvYQVYwLkbCjCUo
This commit is contained in:
+13
-47
@@ -23,6 +23,7 @@ package com.vitorpamplona.amethyst.commons.ui.feed
|
|||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.size
|
import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.IconButton
|
import androidx.compose.material3.IconButton
|
||||||
@@ -34,10 +35,12 @@ import androidx.compose.ui.Modifier
|
|||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import com.vitorpamplona.amethyst.commons.icons.symbols.Icon
|
import com.vitorpamplona.amethyst.commons.icons.symbols.Icon
|
||||||
import com.vitorpamplona.amethyst.commons.icons.symbols.MaterialSymbols
|
import com.vitorpamplona.amethyst.commons.icons.symbols.MaterialSymbols
|
||||||
import com.vitorpamplona.amethyst.commons.ui.theme.RelayStatusColors
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Header component for feed screens with title and relay connection status.
|
* Compact Messages-style header for feed screens: titleMedium on the left,
|
||||||
|
* a single refresh IconButton on the right. Relay count is rolled into the
|
||||||
|
* refresh button's content description so it still surfaces in hover tooltips
|
||||||
|
* / accessibility readers without stealing a whole row.
|
||||||
*
|
*
|
||||||
* @param title The feed title
|
* @param title The feed title
|
||||||
* @param connectedRelayCount Number of connected relays
|
* @param connectedRelayCount Number of connected relays
|
||||||
@@ -52,62 +55,25 @@ fun FeedHeader(
|
|||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
) {
|
) {
|
||||||
Row(
|
Row(
|
||||||
modifier = modifier.fillMaxWidth(),
|
modifier = modifier.fillMaxWidth().padding(horizontal = 12.dp, vertical = 8.dp),
|
||||||
horizontalArrangement = Arrangement.SpaceBetween,
|
horizontalArrangement = Arrangement.SpaceBetween,
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
) {
|
) {
|
||||||
Text(
|
Text(
|
||||||
title,
|
title,
|
||||||
style = MaterialTheme.typography.headlineMedium,
|
style = MaterialTheme.typography.titleMedium,
|
||||||
color = MaterialTheme.colorScheme.onBackground,
|
color = MaterialTheme.colorScheme.onBackground,
|
||||||
)
|
)
|
||||||
|
|
||||||
RelayStatusIndicator(
|
IconButton(
|
||||||
connectedCount = connectedRelayCount,
|
onClick = onRefresh,
|
||||||
onRefresh = onRefresh,
|
modifier = Modifier.size(32.dp),
|
||||||
)
|
) {
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Compact relay connection status indicator with refresh button.
|
|
||||||
*/
|
|
||||||
@Composable
|
|
||||||
fun RelayStatusIndicator(
|
|
||||||
connectedCount: Int,
|
|
||||||
onRefresh: () -> Unit,
|
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
) {
|
|
||||||
Row(
|
|
||||||
modifier = modifier,
|
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
|
||||||
horizontalArrangement = Arrangement.spacedBy(8.dp),
|
|
||||||
) {
|
|
||||||
val statusColor =
|
|
||||||
when {
|
|
||||||
connectedCount == 0 -> RelayStatusColors.Disconnected
|
|
||||||
connectedCount < 3 -> RelayStatusColors.Connecting
|
|
||||||
else -> RelayStatusColors.Connected
|
|
||||||
}
|
|
||||||
|
|
||||||
Icon(
|
|
||||||
symbol = if (connectedCount > 0) MaterialSymbols.Check else MaterialSymbols.Close,
|
|
||||||
contentDescription = null,
|
|
||||||
tint = statusColor,
|
|
||||||
modifier = Modifier.size(16.dp),
|
|
||||||
)
|
|
||||||
|
|
||||||
Text(
|
|
||||||
"$connectedCount relay${if (connectedCount != 1) "s" else ""}",
|
|
||||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
|
||||||
style = MaterialTheme.typography.bodySmall,
|
|
||||||
)
|
|
||||||
|
|
||||||
IconButton(onClick = onRefresh) {
|
|
||||||
Icon(
|
Icon(
|
||||||
MaterialSymbols.Refresh,
|
MaterialSymbols.Refresh,
|
||||||
contentDescription = "Reconnect",
|
contentDescription = "Refresh ($connectedRelayCount relays connected)",
|
||||||
tint = MaterialTheme.colorScheme.primary,
|
tint = MaterialTheme.colorScheme.primary,
|
||||||
|
modifier = Modifier.size(20.dp),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,12 +20,11 @@
|
|||||||
*/
|
*/
|
||||||
package com.vitorpamplona.amethyst.desktop.ui
|
package com.vitorpamplona.amethyst.desktop.ui
|
||||||
|
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||||
|
import androidx.compose.foundation.TooltipArea
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
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.Row
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
@@ -33,15 +32,14 @@ import androidx.compose.foundation.layout.fillMaxWidth
|
|||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.size
|
import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.foundation.layout.width
|
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
import androidx.compose.foundation.lazy.items
|
import androidx.compose.foundation.lazy.items
|
||||||
import androidx.compose.material3.AlertDialog
|
import androidx.compose.material3.AlertDialog
|
||||||
import androidx.compose.material3.Button
|
|
||||||
import androidx.compose.material3.FilterChip
|
import androidx.compose.material3.FilterChip
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.IconButton
|
import androidx.compose.material3.IconButton
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.material3.Surface
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.material3.TextButton
|
import androidx.compose.material3.TextButton
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
@@ -489,7 +487,6 @@ fun FeedScreen(
|
|||||||
onDispose { subId?.let { coordinator.releaseInteractions(it) } }
|
onDispose { subId?.let { coordinator.releaseInteractions(it) } }
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(ExperimentalLayoutApi::class)
|
|
||||||
Box(modifier = Modifier.fillMaxSize()) {
|
Box(modifier = Modifier.fillMaxSize()) {
|
||||||
Column(modifier = Modifier.fillMaxSize()) {
|
Column(modifier = Modifier.fillMaxSize()) {
|
||||||
// Header with compose button
|
// Header with compose button
|
||||||
@@ -629,9 +626,15 @@ fun FeedScreen(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Feed header with title, mode selector, relay count, and compose button.
|
* Feed header \u2014 Messages-style single row: Following/Global tabs on the left,
|
||||||
|
* compact icon buttons on the right (relays, refresh, compose). The selected
|
||||||
|
* tab IS the title; no redundant "Global Feed" / "Following Feed" label.
|
||||||
|
*
|
||||||
|
* Relay count and followed-users count are surfaced via a hover tooltip on
|
||||||
|
* the relays icon (desktop convention \u2014 the at-a-glance info is preserved
|
||||||
|
* without stealing header real estate).
|
||||||
*/
|
*/
|
||||||
@OptIn(ExperimentalLayoutApi::class)
|
@OptIn(ExperimentalFoundationApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
private fun FeedHeader(
|
private fun FeedHeader(
|
||||||
feedMode: FeedMode,
|
feedMode: FeedMode,
|
||||||
@@ -644,90 +647,96 @@ private fun FeedHeader(
|
|||||||
onNavigateToRelays: () -> Unit = {},
|
onNavigateToRelays: () -> Unit = {},
|
||||||
onOpenRelayPicker: () -> Unit = {},
|
onOpenRelayPicker: () -> Unit = {},
|
||||||
) {
|
) {
|
||||||
FlowRow(
|
Row(
|
||||||
modifier = Modifier.fillMaxWidth().padding(bottom = 16.dp),
|
modifier = Modifier.fillMaxWidth().padding(horizontal = 12.dp, vertical = 8.dp),
|
||||||
horizontalArrangement = Arrangement.SpaceBetween,
|
horizontalArrangement = Arrangement.SpaceBetween,
|
||||||
verticalArrangement = Arrangement.spacedBy(8.dp),
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
) {
|
) {
|
||||||
Column {
|
// Tabs \u2014 the selected one is the screen title.
|
||||||
FlowRow(
|
Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||||
verticalArrangement = Arrangement.Center,
|
if (account != null) {
|
||||||
horizontalArrangement = Arrangement.spacedBy(8.dp),
|
FilterChip(
|
||||||
) {
|
selected = feedMode == FeedMode.FOLLOWING,
|
||||||
Text(
|
onClick = { onFeedModeChange(FeedMode.FOLLOWING) },
|
||||||
if (feedMode == FeedMode.GLOBAL) "Global Feed" else "Following Feed",
|
label = { Text("Following") },
|
||||||
style = MaterialTheme.typography.headlineMedium,
|
|
||||||
color = MaterialTheme.colorScheme.onBackground,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if (account != null) {
|
|
||||||
Row(horizontalArrangement = Arrangement.spacedBy(4.dp)) {
|
|
||||||
FilterChip(
|
|
||||||
selected = feedMode == FeedMode.GLOBAL,
|
|
||||||
onClick = { onFeedModeChange(FeedMode.GLOBAL) },
|
|
||||||
label = { Text("Global") },
|
|
||||||
)
|
|
||||||
FilterChip(
|
|
||||||
selected = feedMode == FeedMode.FOLLOWING,
|
|
||||||
onClick = { onFeedModeChange(FeedMode.FOLLOWING) },
|
|
||||||
label = { Text("Following") },
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Spacer(Modifier.height(4.dp))
|
|
||||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
|
||||||
Text(
|
|
||||||
"${feedRelays.size} relays",
|
|
||||||
style = MaterialTheme.typography.bodyMedium,
|
|
||||||
color = MaterialTheme.colorScheme.primary,
|
|
||||||
modifier =
|
|
||||||
Modifier.clickable { onNavigateToRelays() },
|
|
||||||
)
|
|
||||||
if (feedMode == FeedMode.FOLLOWING) {
|
|
||||||
Text(
|
|
||||||
" \u2022 $followedUsersCount followed",
|
|
||||||
style = MaterialTheme.typography.bodyMedium,
|
|
||||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
Spacer(Modifier.width(8.dp))
|
|
||||||
if (account != null && !account.isReadOnly) {
|
|
||||||
IconButton(
|
|
||||||
onClick = onOpenRelayPicker,
|
|
||||||
modifier = Modifier.size(24.dp),
|
|
||||||
) {
|
|
||||||
Icon(
|
|
||||||
MaterialSymbols.Dns,
|
|
||||||
contentDescription = "Edit Feed Relays",
|
|
||||||
tint = MaterialTheme.colorScheme.primary,
|
|
||||||
modifier = Modifier.size(18.dp),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
Spacer(Modifier.width(4.dp))
|
|
||||||
}
|
|
||||||
IconButton(
|
|
||||||
onClick = onRefresh,
|
|
||||||
modifier = Modifier.size(24.dp),
|
|
||||||
) {
|
|
||||||
Icon(
|
|
||||||
MaterialSymbols.Refresh,
|
|
||||||
contentDescription = "Refresh",
|
|
||||||
tint = MaterialTheme.colorScheme.primary,
|
|
||||||
modifier = Modifier.size(18.dp),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
FilterChip(
|
||||||
|
selected = feedMode == FeedMode.GLOBAL,
|
||||||
|
onClick = { onFeedModeChange(FeedMode.GLOBAL) },
|
||||||
|
label = { Text("Global") },
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
Button(
|
// Actions \u2014 compact icon buttons at the same scale as the Messages header.
|
||||||
onClick = onCompose,
|
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||||
enabled = account != null && !account.isReadOnly,
|
val relaysTooltip =
|
||||||
) {
|
buildString {
|
||||||
Icon(MaterialSymbols.Add, "New Post", Modifier.size(18.dp))
|
append("${feedRelays.size} relays")
|
||||||
Spacer(Modifier.width(8.dp))
|
if (feedMode == FeedMode.FOLLOWING) {
|
||||||
Text("New Post")
|
append(" \u2022 $followedUsersCount followed")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TooltipArea(
|
||||||
|
tooltip = {
|
||||||
|
Surface(
|
||||||
|
shape = MaterialTheme.shapes.small,
|
||||||
|
color = MaterialTheme.colorScheme.surfaceContainerHigh,
|
||||||
|
tonalElevation = 2.dp,
|
||||||
|
shadowElevation = 4.dp,
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
relaysTooltip,
|
||||||
|
modifier = Modifier.padding(horizontal = 8.dp, vertical = 4.dp),
|
||||||
|
style = MaterialTheme.typography.bodySmall,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
) {
|
||||||
|
IconButton(
|
||||||
|
onClick = {
|
||||||
|
if (account != null && !account.isReadOnly) {
|
||||||
|
onOpenRelayPicker()
|
||||||
|
} else {
|
||||||
|
onNavigateToRelays()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
modifier = Modifier.size(32.dp),
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
MaterialSymbols.Dns,
|
||||||
|
contentDescription = relaysTooltip,
|
||||||
|
tint = MaterialTheme.colorScheme.primary,
|
||||||
|
modifier = Modifier.size(20.dp),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
IconButton(
|
||||||
|
onClick = onRefresh,
|
||||||
|
modifier = Modifier.size(32.dp),
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
MaterialSymbols.Refresh,
|
||||||
|
contentDescription = "Refresh",
|
||||||
|
tint = MaterialTheme.colorScheme.primary,
|
||||||
|
modifier = Modifier.size(20.dp),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (account != null && !account.isReadOnly) {
|
||||||
|
IconButton(
|
||||||
|
onClick = onCompose,
|
||||||
|
modifier = Modifier.size(32.dp),
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
MaterialSymbols.Add,
|
||||||
|
contentDescription = "New Post",
|
||||||
|
tint = MaterialTheme.colorScheme.primary,
|
||||||
|
modifier = Modifier.size(20.dp),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
-2
@@ -245,8 +245,6 @@ fun NotificationsScreen(
|
|||||||
onRefresh = { relayManager.connect() },
|
onRefresh = { relayManager.connect() },
|
||||||
)
|
)
|
||||||
|
|
||||||
Spacer(Modifier.height(16.dp))
|
|
||||||
|
|
||||||
if (connectedRelays.isEmpty()) {
|
if (connectedRelays.isEmpty()) {
|
||||||
LoadingState("Connecting to relays...")
|
LoadingState("Connecting to relays...")
|
||||||
} else if (notifications.isEmpty() && !initialLoadComplete) {
|
} else if (notifications.isEmpty() && !initialLoadComplete) {
|
||||||
|
|||||||
+26
-54
@@ -23,8 +23,6 @@ package com.vitorpamplona.amethyst.desktop.ui
|
|||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Column
|
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.Row
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
@@ -32,7 +30,6 @@ import androidx.compose.foundation.layout.fillMaxWidth
|
|||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.size
|
import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.foundation.layout.width
|
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
import androidx.compose.foundation.lazy.items
|
import androidx.compose.foundation.lazy.items
|
||||||
import androidx.compose.material3.Card
|
import androidx.compose.material3.Card
|
||||||
@@ -290,70 +287,45 @@ fun ReadsScreen(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(ExperimentalLayoutApi::class)
|
|
||||||
Column(modifier = Modifier.fillMaxSize()) {
|
Column(modifier = Modifier.fillMaxSize()) {
|
||||||
// Header — wraps on narrow columns
|
// Header — Messages-style: tabs left, refresh right. The selected tab
|
||||||
FlowRow(
|
// (Following / Global) acts as the screen title, so no separate label.
|
||||||
|
Row(
|
||||||
modifier =
|
modifier =
|
||||||
Modifier
|
Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.padding(horizontal = 12.dp, vertical = 8.dp),
|
.padding(horizontal = 12.dp, vertical = 8.dp),
|
||||||
horizontalArrangement = Arrangement.SpaceBetween,
|
horizontalArrangement = Arrangement.SpaceBetween,
|
||||||
verticalArrangement = Arrangement.spacedBy(8.dp),
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
) {
|
) {
|
||||||
Column {
|
Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||||
FlowRow(
|
if (account != null) {
|
||||||
verticalArrangement = Arrangement.Center,
|
FilterChip(
|
||||||
horizontalArrangement = Arrangement.spacedBy(8.dp),
|
selected = feedMode == FeedMode.FOLLOWING,
|
||||||
) {
|
onClick = { feedMode = FeedMode.FOLLOWING },
|
||||||
Text(
|
label = { Text("Following") },
|
||||||
"Reads",
|
|
||||||
style = MaterialTheme.typography.titleMedium,
|
|
||||||
color = MaterialTheme.colorScheme.onBackground,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Feed mode selector
|
|
||||||
if (account != null) {
|
|
||||||
Row(horizontalArrangement = Arrangement.spacedBy(4.dp)) {
|
|
||||||
FilterChip(
|
|
||||||
selected = feedMode == FeedMode.GLOBAL,
|
|
||||||
onClick = { feedMode = FeedMode.GLOBAL },
|
|
||||||
label = { Text("Global") },
|
|
||||||
)
|
|
||||||
FilterChip(
|
|
||||||
selected = feedMode == FeedMode.FOLLOWING,
|
|
||||||
onClick = { feedMode = FeedMode.FOLLOWING },
|
|
||||||
label = { Text("Following") },
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
FilterChip(
|
||||||
|
selected = feedMode == FeedMode.GLOBAL,
|
||||||
|
onClick = { feedMode = FeedMode.GLOBAL },
|
||||||
|
label = { Text("Global") },
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
Spacer(Modifier.height(4.dp))
|
IconButton(
|
||||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
onClick = { relayManager.connect() },
|
||||||
Text(
|
modifier = Modifier.size(32.dp),
|
||||||
"${connectedRelays.size} relays connected",
|
) {
|
||||||
style = MaterialTheme.typography.bodyMedium,
|
Icon(
|
||||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
MaterialSymbols.Refresh,
|
||||||
)
|
contentDescription = "Refresh (${connectedRelays.size} relays connected)",
|
||||||
Spacer(Modifier.width(8.dp))
|
tint = MaterialTheme.colorScheme.primary,
|
||||||
IconButton(
|
modifier = Modifier.size(20.dp),
|
||||||
onClick = { relayManager.connect() },
|
)
|
||||||
modifier = Modifier.size(24.dp),
|
|
||||||
) {
|
|
||||||
Icon(
|
|
||||||
MaterialSymbols.Refresh,
|
|
||||||
contentDescription = "Refresh",
|
|
||||||
tint = MaterialTheme.colorScheme.primary,
|
|
||||||
modifier = Modifier.size(18.dp),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Spacer(Modifier.height(8.dp))
|
|
||||||
|
|
||||||
when {
|
when {
|
||||||
connectedRelays.isEmpty() -> {
|
connectedRelays.isEmpty() -> {
|
||||||
LoadingState("Connecting to relays...")
|
LoadingState("Connecting to relays...")
|
||||||
|
|||||||
Reference in New Issue
Block a user