leftover changes
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright (c) 2024 Vitor Pamplona
|
* Copyright (c) 2025 Vitor Pamplona
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
* this software and associated documentation files (the "Software"), to deal in
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
@@ -42,8 +42,6 @@ import androidx.compose.material.icons.filled.Refresh
|
|||||||
import androidx.compose.material.icons.filled.Search
|
import androidx.compose.material.icons.filled.Search
|
||||||
import androidx.compose.material.icons.filled.Settings
|
import androidx.compose.material.icons.filled.Settings
|
||||||
import androidx.compose.material3.Button
|
import androidx.compose.material3.Button
|
||||||
import androidx.compose.material3.Card
|
|
||||||
import androidx.compose.material3.CardDefaults
|
|
||||||
import androidx.compose.material3.HorizontalDivider
|
import androidx.compose.material3.HorizontalDivider
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.IconButton
|
import androidx.compose.material3.IconButton
|
||||||
@@ -86,56 +84,58 @@ import com.vitorpamplona.amethyst.desktop.network.DesktopRelayConnectionManager
|
|||||||
import com.vitorpamplona.amethyst.desktop.ui.FeedScreen
|
import com.vitorpamplona.amethyst.desktop.ui.FeedScreen
|
||||||
import com.vitorpamplona.amethyst.desktop.ui.LoginScreen
|
import com.vitorpamplona.amethyst.desktop.ui.LoginScreen
|
||||||
|
|
||||||
fun main() = application {
|
fun main() =
|
||||||
val windowState = rememberWindowState(
|
application {
|
||||||
width = 1200.dp,
|
val windowState =
|
||||||
height = 800.dp,
|
rememberWindowState(
|
||||||
position = WindowPosition.Aligned(Alignment.Center)
|
width = 1200.dp,
|
||||||
)
|
height = 800.dp,
|
||||||
|
position = WindowPosition.Aligned(Alignment.Center),
|
||||||
|
)
|
||||||
|
|
||||||
Window(
|
Window(
|
||||||
onCloseRequest = ::exitApplication,
|
onCloseRequest = ::exitApplication,
|
||||||
state = windowState,
|
state = windowState,
|
||||||
title = "Amethyst"
|
title = "Amethyst",
|
||||||
) {
|
) {
|
||||||
MenuBar {
|
MenuBar {
|
||||||
Menu("File") {
|
Menu("File") {
|
||||||
Item(
|
Item(
|
||||||
"New Note",
|
"New Note",
|
||||||
shortcut = KeyShortcut(Key.N, ctrl = true),
|
shortcut = KeyShortcut(Key.N, ctrl = true),
|
||||||
onClick = { /* TODO: Open new note dialog */ }
|
onClick = { /* TODO: Open new note dialog */ },
|
||||||
)
|
)
|
||||||
Separator()
|
Separator()
|
||||||
Item(
|
Item(
|
||||||
"Settings",
|
"Settings",
|
||||||
shortcut = KeyShortcut(Key.Comma, ctrl = true),
|
shortcut = KeyShortcut(Key.Comma, ctrl = true),
|
||||||
onClick = { /* TODO: Open settings */ }
|
onClick = { /* TODO: Open settings */ },
|
||||||
)
|
)
|
||||||
Separator()
|
Separator()
|
||||||
Item(
|
Item(
|
||||||
"Quit",
|
"Quit",
|
||||||
shortcut = KeyShortcut(Key.Q, ctrl = true),
|
shortcut = KeyShortcut(Key.Q, ctrl = true),
|
||||||
onClick = ::exitApplication
|
onClick = ::exitApplication,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
Menu("Edit") {
|
Menu("Edit") {
|
||||||
Item("Copy", shortcut = KeyShortcut(Key.C, ctrl = true), onClick = { })
|
Item("Copy", shortcut = KeyShortcut(Key.C, ctrl = true), onClick = { })
|
||||||
Item("Paste", shortcut = KeyShortcut(Key.V, ctrl = true), onClick = { })
|
Item("Paste", shortcut = KeyShortcut(Key.V, ctrl = true), onClick = { })
|
||||||
}
|
}
|
||||||
Menu("View") {
|
Menu("View") {
|
||||||
Item("Feed", onClick = { })
|
Item("Feed", onClick = { })
|
||||||
Item("Messages", onClick = { })
|
Item("Messages", onClick = { })
|
||||||
Item("Notifications", onClick = { })
|
Item("Notifications", onClick = { })
|
||||||
}
|
}
|
||||||
Menu("Help") {
|
Menu("Help") {
|
||||||
Item("About Amethyst", onClick = { })
|
Item("About Amethyst", onClick = { })
|
||||||
Item("Keyboard Shortcuts", onClick = { })
|
Item("Keyboard Shortcuts", onClick = { })
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
App()
|
||||||
}
|
}
|
||||||
|
|
||||||
App()
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun App() {
|
fun App() {
|
||||||
@@ -153,17 +153,17 @@ fun App() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
MaterialTheme(
|
MaterialTheme(
|
||||||
colorScheme = darkColorScheme()
|
colorScheme = darkColorScheme(),
|
||||||
) {
|
) {
|
||||||
Surface(
|
Surface(
|
||||||
modifier = Modifier.fillMaxSize(),
|
modifier = Modifier.fillMaxSize(),
|
||||||
color = MaterialTheme.colorScheme.background
|
color = MaterialTheme.colorScheme.background,
|
||||||
) {
|
) {
|
||||||
when (accountState) {
|
when (accountState) {
|
||||||
is AccountState.LoggedOut -> {
|
is AccountState.LoggedOut -> {
|
||||||
LoginScreen(
|
LoginScreen(
|
||||||
accountManager = accountManager,
|
accountManager = accountManager,
|
||||||
onLoginSuccess = { currentScreen = AppScreen.Feed }
|
onLoginSuccess = { currentScreen = AppScreen.Feed },
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
is AccountState.LoggedIn -> {
|
is AccountState.LoggedIn -> {
|
||||||
@@ -192,7 +192,7 @@ fun MainContent(
|
|||||||
// Sidebar Navigation
|
// Sidebar Navigation
|
||||||
NavigationRail(
|
NavigationRail(
|
||||||
modifier = Modifier.width(80.dp).fillMaxHeight(),
|
modifier = Modifier.width(80.dp).fillMaxHeight(),
|
||||||
containerColor = MaterialTheme.colorScheme.surfaceVariant
|
containerColor = MaterialTheme.colorScheme.surfaceVariant,
|
||||||
) {
|
) {
|
||||||
Spacer(Modifier.height(16.dp))
|
Spacer(Modifier.height(16.dp))
|
||||||
|
|
||||||
@@ -200,35 +200,35 @@ fun MainContent(
|
|||||||
icon = { Icon(Icons.Default.Home, contentDescription = "Feed") },
|
icon = { Icon(Icons.Default.Home, contentDescription = "Feed") },
|
||||||
label = { Text("Feed") },
|
label = { Text("Feed") },
|
||||||
selected = currentScreen == AppScreen.Feed,
|
selected = currentScreen == AppScreen.Feed,
|
||||||
onClick = { onScreenChange(AppScreen.Feed) }
|
onClick = { onScreenChange(AppScreen.Feed) },
|
||||||
)
|
)
|
||||||
|
|
||||||
NavigationRailItem(
|
NavigationRailItem(
|
||||||
icon = { Icon(Icons.Default.Search, contentDescription = "Search") },
|
icon = { Icon(Icons.Default.Search, contentDescription = "Search") },
|
||||||
label = { Text("Search") },
|
label = { Text("Search") },
|
||||||
selected = currentScreen == AppScreen.Search,
|
selected = currentScreen == AppScreen.Search,
|
||||||
onClick = { onScreenChange(AppScreen.Search) }
|
onClick = { onScreenChange(AppScreen.Search) },
|
||||||
)
|
)
|
||||||
|
|
||||||
NavigationRailItem(
|
NavigationRailItem(
|
||||||
icon = { Icon(Icons.Default.Email, contentDescription = "Messages") },
|
icon = { Icon(Icons.Default.Email, contentDescription = "Messages") },
|
||||||
label = { Text("DMs") },
|
label = { Text("DMs") },
|
||||||
selected = currentScreen == AppScreen.Messages,
|
selected = currentScreen == AppScreen.Messages,
|
||||||
onClick = { onScreenChange(AppScreen.Messages) }
|
onClick = { onScreenChange(AppScreen.Messages) },
|
||||||
)
|
)
|
||||||
|
|
||||||
NavigationRailItem(
|
NavigationRailItem(
|
||||||
icon = { Icon(Icons.Default.Notifications, contentDescription = "Notifications") },
|
icon = { Icon(Icons.Default.Notifications, contentDescription = "Notifications") },
|
||||||
label = { Text("Alerts") },
|
label = { Text("Alerts") },
|
||||||
selected = currentScreen == AppScreen.Notifications,
|
selected = currentScreen == AppScreen.Notifications,
|
||||||
onClick = { onScreenChange(AppScreen.Notifications) }
|
onClick = { onScreenChange(AppScreen.Notifications) },
|
||||||
)
|
)
|
||||||
|
|
||||||
NavigationRailItem(
|
NavigationRailItem(
|
||||||
icon = { Icon(Icons.Default.Person, contentDescription = "Profile") },
|
icon = { Icon(Icons.Default.Person, contentDescription = "Profile") },
|
||||||
label = { Text("Profile") },
|
label = { Text("Profile") },
|
||||||
selected = currentScreen == AppScreen.Profile,
|
selected = currentScreen == AppScreen.Profile,
|
||||||
onClick = { onScreenChange(AppScreen.Profile) }
|
onClick = { onScreenChange(AppScreen.Profile) },
|
||||||
)
|
)
|
||||||
|
|
||||||
Spacer(Modifier.weight(1f))
|
Spacer(Modifier.weight(1f))
|
||||||
@@ -239,7 +239,7 @@ fun MainContent(
|
|||||||
icon = { Icon(Icons.Default.Settings, contentDescription = "Settings") },
|
icon = { Icon(Icons.Default.Settings, contentDescription = "Settings") },
|
||||||
label = { Text("Settings") },
|
label = { Text("Settings") },
|
||||||
selected = currentScreen == AppScreen.Settings,
|
selected = currentScreen == AppScreen.Settings,
|
||||||
onClick = { onScreenChange(AppScreen.Settings) }
|
onClick = { onScreenChange(AppScreen.Settings) },
|
||||||
)
|
)
|
||||||
|
|
||||||
Spacer(Modifier.height(16.dp))
|
Spacer(Modifier.height(16.dp))
|
||||||
@@ -249,7 +249,7 @@ fun MainContent(
|
|||||||
|
|
||||||
// Main Content
|
// Main Content
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier.weight(1f).fillMaxHeight().padding(24.dp)
|
modifier = Modifier.weight(1f).fillMaxHeight().padding(24.dp),
|
||||||
) {
|
) {
|
||||||
when (currentScreen) {
|
when (currentScreen) {
|
||||||
AppScreen.Feed -> FeedScreen(relayManager)
|
AppScreen.Feed -> FeedScreen(relayManager)
|
||||||
@@ -263,14 +263,16 @@ fun MainContent(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ProfileScreen(account: AccountState.LoggedIn, accountManager: AccountManager) {
|
fun ProfileScreen(
|
||||||
|
account: AccountState.LoggedIn,
|
||||||
|
accountManager: AccountManager,
|
||||||
|
) {
|
||||||
Column {
|
Column {
|
||||||
Text(
|
Text(
|
||||||
"Profile",
|
"Profile",
|
||||||
style = MaterialTheme.typography.headlineMedium,
|
style = MaterialTheme.typography.headlineMedium,
|
||||||
color = MaterialTheme.colorScheme.onBackground
|
color = MaterialTheme.colorScheme.onBackground,
|
||||||
)
|
)
|
||||||
Spacer(Modifier.height(16.dp))
|
Spacer(Modifier.height(16.dp))
|
||||||
|
|
||||||
@@ -284,9 +286,10 @@ fun ProfileScreen(account: AccountState.LoggedIn, accountManager: AccountManager
|
|||||||
|
|
||||||
OutlinedButton(
|
OutlinedButton(
|
||||||
onClick = { accountManager.logout() },
|
onClick = { accountManager.logout() },
|
||||||
colors = androidx.compose.material3.ButtonDefaults.outlinedButtonColors(
|
colors =
|
||||||
contentColor = Color.Red
|
androidx.compose.material3.ButtonDefaults.outlinedButtonColors(
|
||||||
)
|
contentColor = Color.Red,
|
||||||
|
),
|
||||||
) {
|
) {
|
||||||
Text("Logout")
|
Text("Logout")
|
||||||
}
|
}
|
||||||
@@ -303,24 +306,24 @@ fun RelaySettingsScreen(relayManager: DesktopRelayConnectionManager) {
|
|||||||
Text(
|
Text(
|
||||||
"Relay Settings",
|
"Relay Settings",
|
||||||
style = MaterialTheme.typography.headlineMedium,
|
style = MaterialTheme.typography.headlineMedium,
|
||||||
color = MaterialTheme.colorScheme.onBackground
|
color = MaterialTheme.colorScheme.onBackground,
|
||||||
)
|
)
|
||||||
Spacer(Modifier.height(8.dp))
|
Spacer(Modifier.height(8.dp))
|
||||||
|
|
||||||
Row(
|
Row(
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
horizontalArrangement = Arrangement.spacedBy(8.dp)
|
horizontalArrangement = Arrangement.spacedBy(8.dp),
|
||||||
) {
|
) {
|
||||||
Text(
|
Text(
|
||||||
"${connectedRelays.size} of ${relayStatuses.size} relays connected",
|
"${connectedRelays.size} of ${relayStatuses.size} relays connected",
|
||||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||||
style = MaterialTheme.typography.bodyMedium
|
style = MaterialTheme.typography.bodyMedium,
|
||||||
)
|
)
|
||||||
IconButton(onClick = { relayManager.connect() }) {
|
IconButton(onClick = { relayManager.connect() }) {
|
||||||
Icon(
|
Icon(
|
||||||
Icons.Default.Refresh,
|
Icons.Default.Refresh,
|
||||||
contentDescription = "Reconnect",
|
contentDescription = "Reconnect",
|
||||||
tint = MaterialTheme.colorScheme.primary
|
tint = MaterialTheme.colorScheme.primary,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -330,7 +333,7 @@ fun RelaySettingsScreen(relayManager: DesktopRelayConnectionManager) {
|
|||||||
Row(
|
Row(
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier.fillMaxWidth(),
|
||||||
horizontalArrangement = Arrangement.spacedBy(8.dp),
|
horizontalArrangement = Arrangement.spacedBy(8.dp),
|
||||||
verticalAlignment = Alignment.CenterVertically
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
) {
|
) {
|
||||||
OutlinedTextField(
|
OutlinedTextField(
|
||||||
value = newRelayUrl,
|
value = newRelayUrl,
|
||||||
@@ -338,7 +341,7 @@ fun RelaySettingsScreen(relayManager: DesktopRelayConnectionManager) {
|
|||||||
label = { Text("Add relay") },
|
label = { Text("Add relay") },
|
||||||
placeholder = { Text("wss://relay.example.com") },
|
placeholder = { Text("wss://relay.example.com") },
|
||||||
modifier = Modifier.weight(1f),
|
modifier = Modifier.weight(1f),
|
||||||
singleLine = true
|
singleLine = true,
|
||||||
)
|
)
|
||||||
Button(
|
Button(
|
||||||
onClick = {
|
onClick = {
|
||||||
@@ -347,7 +350,7 @@ fun RelaySettingsScreen(relayManager: DesktopRelayConnectionManager) {
|
|||||||
newRelayUrl = ""
|
newRelayUrl = ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
enabled = newRelayUrl.isNotBlank()
|
enabled = newRelayUrl.isNotBlank(),
|
||||||
) {
|
) {
|
||||||
Text("Add")
|
Text("Add")
|
||||||
}
|
}
|
||||||
@@ -357,12 +360,12 @@ fun RelaySettingsScreen(relayManager: DesktopRelayConnectionManager) {
|
|||||||
|
|
||||||
LazyColumn(
|
LazyColumn(
|
||||||
verticalArrangement = Arrangement.spacedBy(8.dp),
|
verticalArrangement = Arrangement.spacedBy(8.dp),
|
||||||
modifier = Modifier.weight(1f)
|
modifier = Modifier.weight(1f),
|
||||||
) {
|
) {
|
||||||
items(relayStatuses.values.toList()) { status ->
|
items(relayStatuses.values.toList()) { status ->
|
||||||
RelayStatusCard(
|
RelayStatusCard(
|
||||||
status = status,
|
status = status,
|
||||||
onRemove = { relayManager.removeRelay(status.url) }
|
onRemove = { relayManager.removeRelay(status.url) },
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-2
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright (c) 2024 Vitor Pamplona
|
* Copyright (c) 2025 Vitor Pamplona
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
* this software and associated documentation files (the "Software"), to deal in
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
@@ -26,7 +26,8 @@ import java.util.concurrent.TimeUnit
|
|||||||
|
|
||||||
object DesktopHttpClient {
|
object DesktopHttpClient {
|
||||||
private val client: OkHttpClient by lazy {
|
private val client: OkHttpClient by lazy {
|
||||||
OkHttpClient.Builder()
|
OkHttpClient
|
||||||
|
.Builder()
|
||||||
.connectTimeout(30, TimeUnit.SECONDS)
|
.connectTimeout(30, TimeUnit.SECONDS)
|
||||||
.readTimeout(30, TimeUnit.SECONDS)
|
.readTimeout(30, TimeUnit.SECONDS)
|
||||||
.writeTimeout(30, TimeUnit.SECONDS)
|
.writeTimeout(30, TimeUnit.SECONDS)
|
||||||
|
|||||||
+5
-4
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright (c) 2024 Vitor Pamplona
|
* Copyright (c) 2025 Vitor Pamplona
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
* this software and associated documentation files (the "Software"), to deal in
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
@@ -27,6 +27,7 @@ import com.vitorpamplona.quartz.nip01Core.relay.sockets.okhttp.BasicOkHttpWebSoc
|
|||||||
* Desktop-specific relay connection manager that configures OkHttp for websockets.
|
* Desktop-specific relay connection manager that configures OkHttp for websockets.
|
||||||
* Delegates to the shared RelayConnectionManager from commons.
|
* Delegates to the shared RelayConnectionManager from commons.
|
||||||
*/
|
*/
|
||||||
class DesktopRelayConnectionManager : RelayConnectionManager(
|
class DesktopRelayConnectionManager :
|
||||||
websocketBuilder = BasicOkHttpWebSocket.Builder(DesktopHttpClient::getHttpClient)
|
RelayConnectionManager(
|
||||||
)
|
websocketBuilder = BasicOkHttpWebSocket.Builder(DesktopHttpClient::getHttpClient),
|
||||||
|
)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright (c) 2024 Vitor Pamplona
|
* Copyright (c) 2025 Vitor Pamplona
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
* this software and associated documentation files (the "Software"), to deal in
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
@@ -60,41 +60,43 @@ fun FeedScreen(relayManager: DesktopRelayConnectionManager) {
|
|||||||
DisposableEffect(configuredRelays) {
|
DisposableEffect(configuredRelays) {
|
||||||
if (configuredRelays.isNotEmpty()) {
|
if (configuredRelays.isNotEmpty()) {
|
||||||
val subId = "global-feed-${System.currentTimeMillis()}"
|
val subId = "global-feed-${System.currentTimeMillis()}"
|
||||||
val filters = listOf(
|
val filters =
|
||||||
Filter(
|
listOf(
|
||||||
kinds = listOf(TextNoteEvent.KIND),
|
Filter(
|
||||||
limit = 50,
|
kinds = listOf(TextNoteEvent.KIND),
|
||||||
|
limit = 50,
|
||||||
|
),
|
||||||
)
|
)
|
||||||
)
|
|
||||||
|
|
||||||
relayManager.subscribe(
|
relayManager.subscribe(
|
||||||
subId = subId,
|
subId = subId,
|
||||||
filters = filters,
|
filters = filters,
|
||||||
relays = configuredRelays,
|
relays = configuredRelays,
|
||||||
listener = object : IRequestListener {
|
listener =
|
||||||
override fun onEvent(
|
object : IRequestListener {
|
||||||
event: Event,
|
override fun onEvent(
|
||||||
isLive: Boolean,
|
event: Event,
|
||||||
relay: NormalizedRelayUrl,
|
isLive: Boolean,
|
||||||
forFilters: List<Filter>?
|
relay: NormalizedRelayUrl,
|
||||||
) {
|
forFilters: List<Filter>?,
|
||||||
if (event.id !in seenIds) {
|
) {
|
||||||
seenIds.add(event.id)
|
if (event.id !in seenIds) {
|
||||||
events.add(0, event)
|
seenIds.add(event.id)
|
||||||
if (events.size > 200) {
|
events.add(0, event)
|
||||||
val removed = events.removeAt(events.size - 1)
|
if (events.size > 200) {
|
||||||
seenIds.remove(removed.id)
|
val removed = events.removeAt(events.size - 1)
|
||||||
|
seenIds.remove(removed.id)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
override fun onEose(
|
override fun onEose(
|
||||||
relay: NormalizedRelayUrl,
|
relay: NormalizedRelayUrl,
|
||||||
forFilters: List<Filter>?
|
forFilters: List<Filter>?,
|
||||||
) {
|
) {
|
||||||
// End of stored events
|
// End of stored events
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
onDispose {
|
onDispose {
|
||||||
@@ -109,7 +111,7 @@ fun FeedScreen(relayManager: DesktopRelayConnectionManager) {
|
|||||||
FeedHeader(
|
FeedHeader(
|
||||||
title = "Global Feed",
|
title = "Global Feed",
|
||||||
connectedRelayCount = connectedRelays.size,
|
connectedRelayCount = connectedRelays.size,
|
||||||
onRefresh = { relayManager.connect() }
|
onRefresh = { relayManager.connect() },
|
||||||
)
|
)
|
||||||
|
|
||||||
Spacer(Modifier.height(16.dp))
|
Spacer(Modifier.height(16.dp))
|
||||||
@@ -120,12 +122,12 @@ fun FeedScreen(relayManager: DesktopRelayConnectionManager) {
|
|||||||
LoadingState("Loading notes...")
|
LoadingState("Loading notes...")
|
||||||
} else {
|
} else {
|
||||||
LazyColumn(
|
LazyColumn(
|
||||||
verticalArrangement = Arrangement.spacedBy(8.dp)
|
verticalArrangement = Arrangement.spacedBy(8.dp),
|
||||||
) {
|
) {
|
||||||
items(events, key = { it.id }) { event ->
|
items(events, key = { it.id }) { event ->
|
||||||
// Use NoteCard from commons
|
// Use NoteCard from commons
|
||||||
NoteCard(
|
NoteCard(
|
||||||
note = event.toNoteDisplayData()
|
note = event.toNoteDisplayData(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright (c) 2024 Vitor Pamplona
|
* Copyright (c) 2025 Vitor Pamplona
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
* this software and associated documentation files (the "Software"), to deal in
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
|||||||
Reference in New Issue
Block a user