mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2026-08-12 01:07:46 +00:00
feat: pre-load reply threads from the feed
When a reply is visible in NoteCompose, eagerly subscribe to its thread root (filter on the root's e/a tag, like the thread screen) so opening the conversation finds it already loaded. The observer resolves the root and keys on its id, so sibling replies share one subscription and root notes are skipped.
This commit is contained in:
@@ -48,6 +48,7 @@ import com.vitorpamplona.amethyst.ui.note.ReplyNoteComposition
|
||||
import com.vitorpamplona.amethyst.ui.note.elements.DisplayUncitedHashtags
|
||||
import com.vitorpamplona.amethyst.ui.note.nip22Comments.DisplayExternalId
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.threadview.datasources.PreloadThreadForReply
|
||||
import com.vitorpamplona.amethyst.ui.theme.HalfVertSpacer
|
||||
import com.vitorpamplona.amethyst.ui.theme.StdVertSpacer
|
||||
import com.vitorpamplona.amethyst.ui.theme.placeholderText
|
||||
@@ -82,6 +83,10 @@ fun RenderTextEvent(
|
||||
val noteEvent = note.event ?: return
|
||||
|
||||
if (unPackReply != ReplyRenderType.NONE) {
|
||||
// Eagerly pull the rest of this reply's thread while it's on screen, so opening
|
||||
// the conversation finds it already loaded. No-op when the note is a root itself.
|
||||
PreloadThreadForReply(note, accountViewModel)
|
||||
|
||||
val canShowReply by
|
||||
remember(note) {
|
||||
derivedStateOf {
|
||||
|
||||
+29
@@ -22,8 +22,11 @@ package com.vitorpamplona.amethyst.ui.screen.loggedIn.threadview.datasources
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
import com.vitorpamplona.amethyst.commons.model.ThreadAssembler
|
||||
import com.vitorpamplona.amethyst.commons.relayClient.subscriptions.LifecycleAwareKeyDataSourceSubscription
|
||||
import com.vitorpamplona.amethyst.model.Account
|
||||
import com.vitorpamplona.amethyst.model.LocalCache
|
||||
import com.vitorpamplona.amethyst.model.Note
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
|
||||
@@ -52,3 +55,29 @@ fun ThreadFilterAssemblerSubscription(
|
||||
|
||||
LifecycleAwareKeyDataSourceSubscription(state, filterAssembler)
|
||||
}
|
||||
|
||||
/**
|
||||
* Eagerly pre-loads the whole thread of a reply that is visible in a feed.
|
||||
*
|
||||
* When a reply shows up in `NoteCompose`, this resolves the thread root and opens
|
||||
* the same root subscription the thread screen uses (a filter on the root's `e`/`a`
|
||||
* tag, covering NIP-10 and NIP-22 event/addressable roots), so tapping into the
|
||||
* conversation finds it already loaded. Keying on the resolved root id means every
|
||||
* visible reply that shares a root collapses onto a single subscription, and a note
|
||||
* that is itself a root (no parent) is skipped — nothing to pre-load.
|
||||
*/
|
||||
@Composable
|
||||
fun PreloadThreadForReply(
|
||||
note: Note,
|
||||
accountViewModel: AccountViewModel,
|
||||
) {
|
||||
val rootId =
|
||||
remember(note) {
|
||||
val root = ThreadAssembler(LocalCache).findRoot(note.idHex)
|
||||
if (root != null && root != note) root.idHex else null
|
||||
}
|
||||
|
||||
if (rootId != null) {
|
||||
ThreadFilterAssemblerSubscription(rootId, accountViewModel)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user