mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2026-10-05 19:28:25 +00:00
feat: route follow hashtag-labels through each follow's outbox relays
The kind-1985 label subscription for the hashtag feed now follows the NIP-65 outbox model: instead of querying the flat hashtag relay set for all labels and filtering to follows locally, it queries each follow's outbox relays for that follow's own label events (authors restricted per relay via account.followsPerRelay), tagged with the hashtag. This ensures a follow's labels are picked up even when they never reach the hashtag's own relays. https://claude.ai/code/session_019gc3FipVBcndF9fmqCCfVX
This commit is contained in:
+13
-6
@@ -31,14 +31,16 @@ import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.hashtags.hashtagAlts
|
||||
import com.vitorpamplona.quartz.nip32Labeling.LabelEvent
|
||||
import com.vitorpamplona.quartz.utils.mapOfSet
|
||||
import kotlin.math.min
|
||||
|
||||
/**
|
||||
* Builds the relay filters that power the NIP-32 side of the hashtag feed:
|
||||
*
|
||||
* 1. A subscription for kind 1985 label events that tag posts with this hashtag
|
||||
* (the `l` tag under the `#t` namespace). We don't restrict authors at the relay
|
||||
* — the feed restricts display to the user's follows locally — but we do bound it
|
||||
* with a limit.
|
||||
* 1. A subscription for kind 1985 label events that tag posts with this hashtag (the `l`
|
||||
* tag under the `#t` namespace), routed through the NIP-65 outbox model: each follow's
|
||||
* labels are requested from THAT follow's outbox relays, with the relay's filter
|
||||
* restricted to the follows that actually write there. This is what guarantees we pick
|
||||
* up a follow's labels even if they never reach the hashtag's own relays.
|
||||
* 2. Requests for the underlying posts a *followed* user has labeled but that aren't in
|
||||
* cache yet, so they can actually render in the feed. This rotates as new label
|
||||
* events arrive (the sub-assembler re-runs after each EOSE).
|
||||
@@ -51,15 +53,20 @@ fun filterHashtagLabels(
|
||||
): List<RelayBasedFilter> {
|
||||
val labelValues = hashtagAlts(hashtag).sorted()
|
||||
|
||||
// Outbox routing: relay -> the follows who publish to it.
|
||||
val followsPerRelay = account.followsPerRelay.value
|
||||
val labelFilters =
|
||||
relays.map { relay ->
|
||||
followsPerRelay.mapNotNull { (relay, authors) ->
|
||||
if (authors.isEmpty()) return@mapNotNull null
|
||||
val authorList = authors.sorted()
|
||||
RelayBasedFilter(
|
||||
relay = relay,
|
||||
filter =
|
||||
Filter(
|
||||
kinds = listOf(LabelEvent.KIND),
|
||||
authors = authorList,
|
||||
tags = mapOf("l" to labelValues),
|
||||
limit = 200,
|
||||
limit = min(authorList.size * 5, 500),
|
||||
since = since?.get(relay)?.time,
|
||||
),
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user