-
Notifications
You must be signed in to change notification settings - Fork 1
/
NostrFeedSubscriber.kt
121 lines (102 loc) · 4.25 KB
/
NostrFeedSubscriber.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
package com.dluvian.voyage.data.nostr
import com.dluvian.nostr_kt.RelayUrl
import com.dluvian.voyage.core.PubkeyHex
import com.dluvian.voyage.core.Topic
import com.dluvian.voyage.core.syncedPutOrAdd
import com.dluvian.voyage.core.textNoteAndRepostKinds
import com.dluvian.voyage.data.provider.FriendProvider
import com.dluvian.voyage.data.provider.RelayProvider
import com.dluvian.voyage.data.provider.TopicProvider
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
import rust.nostr.protocol.Filter
import rust.nostr.protocol.PublicKey
import rust.nostr.protocol.Timestamp
class NostrFeedSubscriber(
private val scope: CoroutineScope,
private val relayProvider: RelayProvider,
private val topicProvider: TopicProvider,
private val friendProvider: FriendProvider,
) {
suspend fun getHomeFeedSubscriptions(
until: ULong,
since: ULong,
limit: ULong
): Map<RelayUrl, List<Filter>> {
if (limit <= 0u || since >= until) return emptyMap()
val result = mutableMapOf<RelayUrl, MutableList<Filter>>()
val sinceTimestamp = Timestamp.fromSecs(since)
val untilTimestamp = Timestamp.fromSecs(until)
val friendJob = scope.launch {
relayProvider
.getObserveRelays(pubkeys = friendProvider.getFriendPubkeys())
.forEach { (relayUrl, pubkeys) ->
val publicKeys = pubkeys.map { PublicKey.fromHex(it) }
val friendsNoteFilter = Filter()
.kinds(kinds = textNoteAndRepostKinds)
.authors(authors = publicKeys)
.since(timestamp = sinceTimestamp)
.until(timestamp = untilTimestamp)
.limit(limit = limit)
val friendsNoteFilters = mutableListOf(friendsNoteFilter)
result.syncedPutOrAdd(relayUrl, friendsNoteFilters)
}
}
val topics = topicProvider.getMyTopics()
if (topics.isNotEmpty()) {
val topicedNoteFilter = Filter()
.kinds(kinds = textNoteAndRepostKinds)
.hashtags(hashtags = topics)
.since(timestamp = sinceTimestamp)
.until(timestamp = untilTimestamp)
.limit(limit = limit)
val topicedNoteFilters = mutableListOf(topicedNoteFilter)
relayProvider.getReadRelays().forEach { relay ->
result.syncedPutOrAdd(relay, topicedNoteFilters)
}
}
friendJob.join()
return result
}
fun getTopicFeedSubscription(
topic: Topic,
until: ULong,
since: ULong,
limit: ULong
): Map<RelayUrl, List<Filter>> {
if (limit <= 0u || topic.isBlank() || since >= until) return emptyMap()
val result = mutableMapOf<RelayUrl, MutableList<Filter>>()
val topicedNoteFilter = Filter()
.kinds(kinds = textNoteAndRepostKinds)
.hashtag(hashtag = topic)
.since(timestamp = Timestamp.fromSecs(since))
.until(timestamp = Timestamp.fromSecs(until))
.limit(limit = limit)
val topicedNoteFilters = mutableListOf(topicedNoteFilter)
relayProvider.getReadRelays().forEach { relay ->
result.syncedPutOrAdd(relay, topicedNoteFilters)
}
return result
}
suspend fun getProfileFeedSubscription(
pubkey: PubkeyHex,
until: ULong,
since: ULong,
limit: ULong
): Map<RelayUrl, List<Filter>> {
if (limit <= 0u || pubkey.isBlank() || since >= until) return emptyMap()
val result = mutableMapOf<RelayUrl, MutableList<Filter>>()
val pubkeyNoteFilter = Filter()
.kinds(kinds = textNoteAndRepostKinds)
.author(PublicKey.fromHex(hex = pubkey))
.since(timestamp = Timestamp.fromSecs(since))
.until(timestamp = Timestamp.fromSecs(until))
.limit(limit = limit)
val pubkeyNoteFilters = mutableListOf(pubkeyNoteFilter)
relayProvider.getObserveRelays(pubkey = pubkey).forEach { relay ->
val present = result.putIfAbsent(relay, pubkeyNoteFilters)
present?.addAll(pubkeyNoteFilters)
}
return result
}
}