feat(cache): seed Reads and Bookmarks screens from cache on compose
Both screens now show cached data instantly on navigation instead of showing loading states while re-fetching from relays. - BookmarksScreen: reads cached BookmarkListEvent from addressableNotes, seeds public bookmark events from notes cache - ReadsScreen: seeds long-form notes (kind 30023) from notes cache Relay subscriptions still run to fetch fresh data in parallel. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
+21
@@ -121,6 +121,27 @@ fun BookmarksScreen(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Seed from cache — bookmark list event may already be in addressableNotes
|
||||||
|
LaunchedEffect(account.pubKeyHex) {
|
||||||
|
val address = BookmarkListEvent.createBookmarkAddress(account.pubKeyHex)
|
||||||
|
val cachedNote = localCache.getOrCreateAddressableNote(address)
|
||||||
|
val cachedEvent = cachedNote.event as? BookmarkListEvent
|
||||||
|
if (cachedEvent != null) {
|
||||||
|
bookmarkList = cachedEvent
|
||||||
|
publicBookmarkIds =
|
||||||
|
cachedEvent
|
||||||
|
.publicBookmarks()
|
||||||
|
.filterIsInstance<EventBookmark>()
|
||||||
|
.map { it.eventId }
|
||||||
|
// Seed public events from cache
|
||||||
|
publicBookmarkIds.forEach { id ->
|
||||||
|
val note = localCache.getNoteIfExists(id)
|
||||||
|
val event = note?.event
|
||||||
|
if (event != null) publicEventState.addItem(event)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Subscribe to user's bookmark list (kind 30001)
|
// Subscribe to user's bookmark list (kind 30001)
|
||||||
rememberSubscription(connectedRelays, account.pubKeyHex, relayManager = relayManager) {
|
rememberSubscription(connectedRelays, account.pubKeyHex, relayManager = relayManager) {
|
||||||
if (connectedRelays.isNotEmpty()) {
|
if (connectedRelays.isNotEmpty()) {
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ import androidx.compose.material3.IconButton
|
|||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.collectAsState
|
import androidx.compose.runtime.collectAsState
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
@@ -207,6 +208,18 @@ fun ReadsScreen(
|
|||||||
var eoseReceivedCount by remember { mutableStateOf(0) }
|
var eoseReceivedCount by remember { mutableStateOf(0) }
|
||||||
val initialLoadComplete = eoseReceivedCount > 0
|
val initialLoadComplete = eoseReceivedCount > 0
|
||||||
|
|
||||||
|
// Seed from cache — long-form notes already consumed are in cache
|
||||||
|
LaunchedEffect(Unit) {
|
||||||
|
val cached =
|
||||||
|
localCache.notes.filterIntoSet { _, note ->
|
||||||
|
note.event is LongTextNoteEvent
|
||||||
|
}
|
||||||
|
cached.forEach { note ->
|
||||||
|
(note.event as? LongTextNoteEvent)?.let { eventState.addItem(it) }
|
||||||
|
}
|
||||||
|
if (cached.isNotEmpty()) eoseReceivedCount++
|
||||||
|
}
|
||||||
|
|
||||||
// Load followed users for Following feed mode
|
// Load followed users for Following feed mode
|
||||||
rememberSubscription(connectedRelays, account, feedMode, relayManager = relayManager) {
|
rememberSubscription(connectedRelays, account, feedMode, relayManager = relayManager) {
|
||||||
val connectedRelays = connectedRelays
|
val connectedRelays = connectedRelays
|
||||||
|
|||||||
Reference in New Issue
Block a user