# Conflicts:
#	quartz/README.md
This commit is contained in:
Vitor Pamplona
2026-04-30 17:26:28 -04:00
3 changed files with 23 additions and 32 deletions
@@ -197,30 +197,17 @@ private fun NestLobbyContent(
.consumeWindowInsets(padding) .consumeWindowInsets(padding)
.imePadding(), .imePadding(),
) { ) {
// Same chat list shape as NestFullScreen: a reverse-layout RoomHeader(event, accountViewModel, nav)
// LazyColumn keyed by note id. The lobby uses cached CachedListenerCount(roomATag)
// LocalCache notes instead of an active NestViewModel.chat,
// and stacks the room metadata (header, listener count, // Reverse-layout LazyColumn keyed by note id, same shape as
// "Recent chat" label) above the oldest message so the // NestFullScreen's chat list. The lobby reads cached
// user can scroll up through history into the room info. // LocalCache notes instead of an active NestViewModel.chat.
LazyColumn( LazyColumn(
modifier = Modifier.weight(1f).fillMaxSize(), modifier = Modifier.weight(1f).fillMaxWidth(),
state = listState, state = listState,
reverseLayout = true, reverseLayout = true,
) { ) {
items(
items = messages,
key = { it.idHex },
) { note ->
ChatroomMessageCompose(
baseNote = note,
routeForLastRead = routeForLastRead,
accountViewModel = accountViewModel,
nav = nav,
onWantsToReply = nestScreenModel::reply,
onWantsToEditDraft = nestScreenModel::editFromDraft,
)
}
if (messages.isEmpty()) { if (messages.isEmpty()) {
item("chat-empty") { item("chat-empty") {
Text( Text(
@@ -233,19 +220,19 @@ private fun NestLobbyContent(
) )
} }
} }
item("chat-header") { items(
Text( items = messages,
text = stringRes(R.string.nest_lobby_recent_chat), key = { it.idHex },
style = MaterialTheme.typography.titleSmall, ) { note ->
modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp), ChatroomMessageCompose(
baseNote = note,
routeForLastRead = routeForLastRead,
accountViewModel = accountViewModel,
nav = nav,
onWantsToReply = nestScreenModel::reply,
onWantsToEditDraft = nestScreenModel::editFromDraft,
) )
} }
item("listeners") {
CachedListenerCount(roomATag)
}
item("header") {
RoomHeader(event, accountViewModel, nav)
}
} }
// The composer sits above the 3-button nav when the keyboard // The composer sits above the 3-button nav when the keyboard
+2
View File
@@ -357,6 +357,8 @@ results.forEach { (relay, success) ->
6. On disconnection, exponential backoff retries the connection 6. On disconnection, exponential backoff retries the connection
7. On reconnection, filters are re-sent and events re-delivered 7. On reconnection, filters are re-sent and events re-delivered
`NostrClient` starts active by default and connects on demand — there's no need to call `client.connect()` at startup. That method only matters for resuming after a prior `disconnect()` (e.g., a user-toggled offline mode). Conversely, `client.disconnect()` is what you want when the app is going to background or being shut down: it tears down every socket and stops the auto-reconnect loop.
### Subscription Flow ### Subscription Flow
``` ```
+3 -1
View File
@@ -83,6 +83,8 @@ Notice that the `notes` flow is ready for the UI and automatically subscribes
and unsubscribes to any group of relays and filters the user wants. Similarly, and unsubscribes to any group of relays and filters the user wants. Similarly,
the `send` function updates both the local db and the relay. the `send` function updates both the local db and the relay.
`NostrClient` connects on-demand: the first `subscribe(...)` or `publish(...)` to a relay triggers the socket. There's no need to call `client.connect()` at startup — it's only useful for resuming after a prior `disconnect()`.
## Building a reactive feed UI ## Building a reactive feed UI
A feed screen reads from the view model's feed flow, which only updates when A feed screen reads from the view model's feed flow, which only updates when
@@ -202,4 +204,4 @@ private fun NoteRow(handle: MutableStateFlow<TextNoteEvent>) {
``` ```
Notice how each how also subscribe for changes. This is important to receive Notice how each how also subscribe for changes. This is important to receive
updates from replaceable and addressable events. updates from replaceable and addressable events.