Correctly downloads Nest events
This commit is contained in:
+1
-2
@@ -22,7 +22,6 @@ package com.vitorpamplona.amethyst.ui.screen.loggedIn.discover.nip53LiveActiviti
|
|||||||
|
|
||||||
import com.vitorpamplona.amethyst.model.topNavFeeds.noteBased.allcommunities.AllCommunitiesTopNavPerRelayFilterSet
|
import com.vitorpamplona.amethyst.model.topNavFeeds.noteBased.allcommunities.AllCommunitiesTopNavPerRelayFilterSet
|
||||||
import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap
|
import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.discover.nip90DVMs.subassemblies.filterContentDVMsAllCommunities
|
|
||||||
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
|
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
|
||||||
import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter
|
import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter
|
||||||
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
|
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
|
||||||
@@ -78,7 +77,7 @@ fun filterLiveActivitiesByAllCommunities(
|
|||||||
|
|
||||||
return communitySet.set
|
return communitySet.set
|
||||||
.mapNotNull {
|
.mapNotNull {
|
||||||
filterContentDVMsAllCommunities(
|
filterLiveActivitiesAllCommunities(
|
||||||
relay = it.key,
|
relay = it.key,
|
||||||
communities = it.value.communities,
|
communities = it.value.communities,
|
||||||
since = since?.get(it.key)?.time ?: defaultSince,
|
since = since?.get(it.key)?.time ?: defaultSince,
|
||||||
|
|||||||
+4
-8
@@ -47,7 +47,6 @@ import com.vitorpamplona.quartz.nip53LiveActivities.presence.MeetingRoomPresence
|
|||||||
@Stable
|
@Stable
|
||||||
class NestRoomQueryState(
|
class NestRoomQueryState(
|
||||||
val roomATag: String,
|
val roomATag: String,
|
||||||
val localPubkey: String,
|
|
||||||
val account: Account,
|
val account: Account,
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -102,7 +101,7 @@ class NestRoomFilterSubAssembler(
|
|||||||
filter =
|
filter =
|
||||||
Filter(
|
Filter(
|
||||||
kinds = listOf(AdminCommandEvent.KIND),
|
kinds = listOf(AdminCommandEvent.KIND),
|
||||||
tags = mapOf("a" to listOf(key.roomATag), "p" to listOf(key.localPubkey)),
|
tags = mapOf("a" to listOf(key.roomATag), "p" to listOf(key.account.pubKey)),
|
||||||
since = since?.get(relay)?.time,
|
since = since?.get(relay)?.time,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -110,7 +109,7 @@ class NestRoomFilterSubAssembler(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun id(key: NestRoomQueryState): String = "${key.roomATag}|${key.localPubkey}"
|
override fun id(key: NestRoomQueryState): String = key.roomATag
|
||||||
}
|
}
|
||||||
|
|
||||||
@Stable
|
@Stable
|
||||||
@@ -137,11 +136,9 @@ class NestRoomFilterAssembler(
|
|||||||
@Composable
|
@Composable
|
||||||
fun NestRoomFilterAssemblerSubscription(
|
fun NestRoomFilterAssemblerSubscription(
|
||||||
roomATag: String,
|
roomATag: String,
|
||||||
localPubkey: String,
|
|
||||||
accountViewModel: AccountViewModel,
|
accountViewModel: AccountViewModel,
|
||||||
) = NestRoomFilterAssemblerSubscription(
|
) = NestRoomFilterAssemblerSubscription(
|
||||||
roomATag,
|
roomATag,
|
||||||
localPubkey,
|
|
||||||
accountViewModel.account,
|
accountViewModel.account,
|
||||||
accountViewModel.dataSources().nestRoom,
|
accountViewModel.dataSources().nestRoom,
|
||||||
)
|
)
|
||||||
@@ -149,13 +146,12 @@ fun NestRoomFilterAssemblerSubscription(
|
|||||||
@Composable
|
@Composable
|
||||||
fun NestRoomFilterAssemblerSubscription(
|
fun NestRoomFilterAssemblerSubscription(
|
||||||
roomATag: String,
|
roomATag: String,
|
||||||
localPubkey: String,
|
|
||||||
account: Account,
|
account: Account,
|
||||||
filterAssembler: NestRoomFilterAssembler,
|
filterAssembler: NestRoomFilterAssembler,
|
||||||
) {
|
) {
|
||||||
val state =
|
val state =
|
||||||
remember(roomATag, localPubkey) {
|
remember(roomATag, account.pubKey) {
|
||||||
NestRoomQueryState(roomATag, localPubkey, account)
|
NestRoomQueryState(roomATag, account)
|
||||||
}
|
}
|
||||||
KeyDataSourceSubscription(state, filterAssembler)
|
KeyDataSourceSubscription(state, filterAssembler)
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-2
@@ -24,7 +24,6 @@ import com.vitorpamplona.amethyst.model.TopFilter
|
|||||||
import com.vitorpamplona.amethyst.model.User
|
import com.vitorpamplona.amethyst.model.User
|
||||||
import com.vitorpamplona.amethyst.service.relayClient.eoseManagers.PerUserAndFollowListEoseManager
|
import com.vitorpamplona.amethyst.service.relayClient.eoseManagers.PerUserAndFollowListEoseManager
|
||||||
import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap
|
import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.discover.nip53LiveActivities.makeLiveActivitiesFilter
|
|
||||||
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient
|
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient
|
||||||
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
|
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
|
||||||
import com.vitorpamplona.quartz.nip01Core.relay.client.subscriptions.Subscription
|
import com.vitorpamplona.quartz.nip01Core.relay.client.subscriptions.Subscription
|
||||||
@@ -50,7 +49,7 @@ class NestsSubAssembler(
|
|||||||
since: SincePerRelayMap?,
|
since: SincePerRelayMap?,
|
||||||
): List<RelayBasedFilter> {
|
): List<RelayBasedFilter> {
|
||||||
val feedSettings = key.followsPerRelay()
|
val feedSettings = key.followsPerRelay()
|
||||||
return makeLiveActivitiesFilter(feedSettings, since, key.feedStates.nestsFeed.lastNoteCreatedAtIfFilled())
|
return makeNestsFilter(feedSettings, since, key.feedStates.nestsFeed.lastNoteCreatedAtIfFilled())
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun user(key: NestsQueryState) = key.account.userProfile()
|
override fun user(key: NestsQueryState) = key.account.userProfile()
|
||||||
|
|||||||
+57
@@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2025 Vitor Pamplona
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to use,
|
||||||
|
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||||
|
* Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||||
|
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
package com.vitorpamplona.amethyst.ui.screen.loggedIn.nests.datasource
|
||||||
|
|
||||||
|
import com.vitorpamplona.amethyst.model.topNavFeeds.IFeedTopNavPerRelayFilterSet
|
||||||
|
import com.vitorpamplona.amethyst.model.topNavFeeds.allFollows.AllFollowsTopNavPerRelayFilterSet
|
||||||
|
import com.vitorpamplona.amethyst.model.topNavFeeds.aroundMe.LocationTopNavPerRelayFilterSet
|
||||||
|
import com.vitorpamplona.amethyst.model.topNavFeeds.global.GlobalTopNavPerRelayFilterSet
|
||||||
|
import com.vitorpamplona.amethyst.model.topNavFeeds.hashtag.HashtagTopNavPerRelayFilterSet
|
||||||
|
import com.vitorpamplona.amethyst.model.topNavFeeds.noteBased.allcommunities.AllCommunitiesTopNavPerRelayFilterSet
|
||||||
|
import com.vitorpamplona.amethyst.model.topNavFeeds.noteBased.author.AuthorsTopNavPerRelayFilterSet
|
||||||
|
import com.vitorpamplona.amethyst.model.topNavFeeds.noteBased.community.SingleCommunityTopNavPerRelayFilterSet
|
||||||
|
import com.vitorpamplona.amethyst.model.topNavFeeds.noteBased.muted.MutedAuthorsTopNavPerRelayFilterSet
|
||||||
|
import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap
|
||||||
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.nests.datasource.subassemblies.filterNestsByAllCommunities
|
||||||
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.nests.datasource.subassemblies.filterNestsByAuthors
|
||||||
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.nests.datasource.subassemblies.filterNestsByCommunity
|
||||||
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.nests.datasource.subassemblies.filterNestsByFollows
|
||||||
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.nests.datasource.subassemblies.filterNestsByGeohash
|
||||||
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.nests.datasource.subassemblies.filterNestsByHashtag
|
||||||
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.nests.datasource.subassemblies.filterNestsGlobal
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
|
||||||
|
|
||||||
|
fun makeNestsFilter(
|
||||||
|
feedSettings: IFeedTopNavPerRelayFilterSet,
|
||||||
|
since: SincePerRelayMap?,
|
||||||
|
defaultSince: Long? = null,
|
||||||
|
): List<RelayBasedFilter> =
|
||||||
|
when (feedSettings) {
|
||||||
|
is AllCommunitiesTopNavPerRelayFilterSet -> filterNestsByAllCommunities(feedSettings, since, defaultSince)
|
||||||
|
is AllFollowsTopNavPerRelayFilterSet -> filterNestsByFollows(feedSettings, since, defaultSince)
|
||||||
|
is AuthorsTopNavPerRelayFilterSet -> filterNestsByAuthors(feedSettings, since, defaultSince)
|
||||||
|
is GlobalTopNavPerRelayFilterSet -> filterNestsGlobal(feedSettings, since, defaultSince)
|
||||||
|
is HashtagTopNavPerRelayFilterSet -> filterNestsByHashtag(feedSettings, since, defaultSince)
|
||||||
|
is LocationTopNavPerRelayFilterSet -> filterNestsByGeohash(feedSettings, since, defaultSince)
|
||||||
|
is MutedAuthorsTopNavPerRelayFilterSet -> filterNestsByAuthors(feedSettings, since, defaultSince)
|
||||||
|
is SingleCommunityTopNavPerRelayFilterSet -> filterNestsByCommunity(feedSettings, since, defaultSince)
|
||||||
|
else -> emptyList()
|
||||||
|
}
|
||||||
+85
@@ -0,0 +1,85 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2025 Vitor Pamplona
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to use,
|
||||||
|
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||||
|
* Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||||
|
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
package com.vitorpamplona.amethyst.ui.screen.loggedIn.nests.datasource.subassemblies
|
||||||
|
|
||||||
|
import com.vitorpamplona.amethyst.model.topNavFeeds.noteBased.allcommunities.AllCommunitiesTopNavPerRelayFilterSet
|
||||||
|
import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
|
||||||
|
import com.vitorpamplona.quartz.nip53LiveActivities.meetingSpaces.MeetingRoomEvent
|
||||||
|
import com.vitorpamplona.quartz.nip53LiveActivities.meetingSpaces.MeetingSpaceEvent
|
||||||
|
import com.vitorpamplona.quartz.nip53LiveActivities.streaming.LiveActivitiesEvent
|
||||||
|
import com.vitorpamplona.quartz.nip72ModCommunities.approval.CommunityPostApprovalEvent
|
||||||
|
|
||||||
|
fun filterNestsAllCommunities(
|
||||||
|
relay: NormalizedRelayUrl,
|
||||||
|
communities: Set<String>,
|
||||||
|
since: Long? = null,
|
||||||
|
): List<RelayBasedFilter> {
|
||||||
|
val communityList = communities.sorted()
|
||||||
|
|
||||||
|
return listOf(
|
||||||
|
// approved
|
||||||
|
RelayBasedFilter(
|
||||||
|
relay = relay,
|
||||||
|
filter =
|
||||||
|
Filter(
|
||||||
|
kinds = CommunityPostApprovalEvent.KIND_LIST,
|
||||||
|
tags =
|
||||||
|
mapOf(
|
||||||
|
"a" to communityList,
|
||||||
|
"k" to listOf(LiveActivitiesEvent.KIND.toString(), MeetingSpaceEvent.KIND.toString(), MeetingRoomEvent.KIND.toString()),
|
||||||
|
),
|
||||||
|
limit = 300,
|
||||||
|
since = since,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
// not approved
|
||||||
|
RelayBasedFilter(
|
||||||
|
relay = relay,
|
||||||
|
filter =
|
||||||
|
Filter(
|
||||||
|
tags = mapOf("k" to listOf("5300"), "a" to communityList),
|
||||||
|
kinds = listOf(MeetingSpaceEvent.KIND, MeetingRoomEvent.KIND),
|
||||||
|
limit = 300,
|
||||||
|
since = since,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun filterNestsByAllCommunities(
|
||||||
|
communitySet: AllCommunitiesTopNavPerRelayFilterSet,
|
||||||
|
since: SincePerRelayMap?,
|
||||||
|
defaultSince: Long? = null,
|
||||||
|
): List<RelayBasedFilter> {
|
||||||
|
if (communitySet.set.isEmpty()) return emptyList()
|
||||||
|
|
||||||
|
return communitySet.set
|
||||||
|
.mapNotNull {
|
||||||
|
filterNestsAllCommunities(
|
||||||
|
relay = it.key,
|
||||||
|
communities = it.value.communities,
|
||||||
|
since = since?.get(it.key)?.time ?: defaultSince,
|
||||||
|
)
|
||||||
|
}.flatten()
|
||||||
|
}
|
||||||
+104
@@ -0,0 +1,104 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2025 Vitor Pamplona
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to use,
|
||||||
|
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||||
|
* Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||||
|
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
package com.vitorpamplona.amethyst.ui.screen.loggedIn.nests.datasource.subassemblies
|
||||||
|
|
||||||
|
import com.vitorpamplona.amethyst.model.topNavFeeds.noteBased.author.AuthorsTopNavPerRelayFilterSet
|
||||||
|
import com.vitorpamplona.amethyst.model.topNavFeeds.noteBased.muted.MutedAuthorsTopNavPerRelayFilterSet
|
||||||
|
import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
|
||||||
|
import com.vitorpamplona.quartz.nip53LiveActivities.meetingSpaces.MeetingRoomEvent
|
||||||
|
import com.vitorpamplona.quartz.nip53LiveActivities.meetingSpaces.MeetingSpaceEvent
|
||||||
|
|
||||||
|
fun filterNestsAuthors(
|
||||||
|
relay: NormalizedRelayUrl,
|
||||||
|
authors: Set<HexKey>,
|
||||||
|
since: Long? = null,
|
||||||
|
): List<RelayBasedFilter> {
|
||||||
|
val authorList = authors.sorted()
|
||||||
|
return listOf(
|
||||||
|
RelayBasedFilter(
|
||||||
|
relay = relay,
|
||||||
|
filter =
|
||||||
|
Filter(
|
||||||
|
authors = authorList,
|
||||||
|
kinds = listOf(MeetingSpaceEvent.KIND, MeetingRoomEvent.KIND),
|
||||||
|
limit = 300,
|
||||||
|
since = since,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
// authors are participating in the live event.
|
||||||
|
RelayBasedFilter(
|
||||||
|
relay = relay,
|
||||||
|
filter =
|
||||||
|
Filter(
|
||||||
|
tags = mapOf("p" to authorList),
|
||||||
|
kinds = listOf(MeetingSpaceEvent.KIND, MeetingRoomEvent.KIND),
|
||||||
|
limit = 100,
|
||||||
|
since = since,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun filterNestsByAuthors(
|
||||||
|
authorSet: AuthorsTopNavPerRelayFilterSet,
|
||||||
|
since: SincePerRelayMap?,
|
||||||
|
defaultSince: Long? = null,
|
||||||
|
): List<RelayBasedFilter> {
|
||||||
|
if (authorSet.set.isEmpty()) return emptyList()
|
||||||
|
|
||||||
|
return authorSet.set
|
||||||
|
.mapNotNull {
|
||||||
|
if (it.value.authors.isEmpty()) {
|
||||||
|
null
|
||||||
|
} else {
|
||||||
|
filterNestsAuthors(
|
||||||
|
relay = it.key,
|
||||||
|
authors = it.value.authors,
|
||||||
|
since = since?.get(it.key)?.time ?: defaultSince,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}.flatten()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun filterNestsByAuthors(
|
||||||
|
authorSet: MutedAuthorsTopNavPerRelayFilterSet,
|
||||||
|
since: SincePerRelayMap?,
|
||||||
|
defaultSince: Long? = null,
|
||||||
|
): List<RelayBasedFilter> {
|
||||||
|
if (authorSet.set.isEmpty()) return emptyList()
|
||||||
|
|
||||||
|
return authorSet.set
|
||||||
|
.mapNotNull {
|
||||||
|
if (it.value.authors.isEmpty()) {
|
||||||
|
null
|
||||||
|
} else {
|
||||||
|
filterNestsAuthors(
|
||||||
|
relay = it.key,
|
||||||
|
authors = it.value.authors,
|
||||||
|
since = since?.get(it.key)?.time ?: defaultSince,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}.flatten()
|
||||||
|
}
|
||||||
+87
@@ -0,0 +1,87 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2025 Vitor Pamplona
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to use,
|
||||||
|
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||||
|
* Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||||
|
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
package com.vitorpamplona.amethyst.ui.screen.loggedIn.nests.datasource.subassemblies
|
||||||
|
|
||||||
|
import com.vitorpamplona.amethyst.model.topNavFeeds.noteBased.community.SingleCommunityTopNavPerRelayFilterSet
|
||||||
|
import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
|
||||||
|
import com.vitorpamplona.quartz.nip53LiveActivities.meetingSpaces.MeetingRoomEvent
|
||||||
|
import com.vitorpamplona.quartz.nip53LiveActivities.meetingSpaces.MeetingSpaceEvent
|
||||||
|
import com.vitorpamplona.quartz.nip72ModCommunities.approval.CommunityPostApprovalEvent
|
||||||
|
|
||||||
|
fun filterNestsByCommunity(
|
||||||
|
relay: NormalizedRelayUrl,
|
||||||
|
community: String,
|
||||||
|
authors: Set<String>?,
|
||||||
|
since: Long? = null,
|
||||||
|
): List<RelayBasedFilter> {
|
||||||
|
val authors = authors?.sorted()
|
||||||
|
return listOf(
|
||||||
|
// approved
|
||||||
|
RelayBasedFilter(
|
||||||
|
relay = relay,
|
||||||
|
filter =
|
||||||
|
Filter(
|
||||||
|
authors = authors,
|
||||||
|
kinds = CommunityPostApprovalEvent.KIND_LIST,
|
||||||
|
tags =
|
||||||
|
mapOf(
|
||||||
|
"a" to listOf(community),
|
||||||
|
"k" to listOf(MeetingSpaceEvent.KIND.toString(), MeetingRoomEvent.KIND.toString()),
|
||||||
|
),
|
||||||
|
limit = 300,
|
||||||
|
since = since,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
// not approved
|
||||||
|
RelayBasedFilter(
|
||||||
|
relay = relay,
|
||||||
|
filter =
|
||||||
|
Filter(
|
||||||
|
authors = authors,
|
||||||
|
tags = mapOf("k" to listOf("5300"), "a" to listOf(community)),
|
||||||
|
kinds = listOf(MeetingSpaceEvent.KIND, MeetingRoomEvent.KIND),
|
||||||
|
limit = 300,
|
||||||
|
since = since,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun filterNestsByCommunity(
|
||||||
|
communitySet: SingleCommunityTopNavPerRelayFilterSet,
|
||||||
|
since: SincePerRelayMap?,
|
||||||
|
defaultSince: Long? = null,
|
||||||
|
): List<RelayBasedFilter> {
|
||||||
|
if (communitySet.set.isEmpty()) return emptyList()
|
||||||
|
|
||||||
|
return communitySet.set
|
||||||
|
.mapNotNull {
|
||||||
|
filterNestsByCommunity(
|
||||||
|
relay = it.key,
|
||||||
|
community = it.value.community,
|
||||||
|
authors = it.value.authors,
|
||||||
|
since = since?.get(it.key)?.time ?: defaultSince,
|
||||||
|
)
|
||||||
|
}.flatten()
|
||||||
|
}
|
||||||
+53
@@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2025 Vitor Pamplona
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to use,
|
||||||
|
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||||
|
* Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||||
|
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
package com.vitorpamplona.amethyst.ui.screen.loggedIn.nests.datasource.subassemblies
|
||||||
|
|
||||||
|
import com.vitorpamplona.amethyst.model.topNavFeeds.allFollows.AllFollowsTopNavPerRelayFilterSet
|
||||||
|
import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
|
||||||
|
|
||||||
|
fun filterNestsByFollows(
|
||||||
|
followsSet: AllFollowsTopNavPerRelayFilterSet,
|
||||||
|
since: SincePerRelayMap?,
|
||||||
|
defaultSince: Long? = null,
|
||||||
|
): List<RelayBasedFilter> {
|
||||||
|
if (followsSet.set.isEmpty()) return emptyList()
|
||||||
|
|
||||||
|
return followsSet.set.flatMap {
|
||||||
|
val since = since?.get(it.key)?.time ?: defaultSince
|
||||||
|
val relay = it.key
|
||||||
|
|
||||||
|
listOfNotNull(
|
||||||
|
it.value.authors?.let {
|
||||||
|
filterNestsAuthors(relay, it, since)
|
||||||
|
},
|
||||||
|
it.value.geotags?.let {
|
||||||
|
filterNestsByGeohash(relay, it, since)
|
||||||
|
},
|
||||||
|
it.value.hashtags?.let {
|
||||||
|
filterNestsByHashtag(relay, it, since)
|
||||||
|
},
|
||||||
|
it.value.communities?.let {
|
||||||
|
filterNestsAllCommunities(relay, it, since)
|
||||||
|
},
|
||||||
|
).flatten()
|
||||||
|
}
|
||||||
|
}
|
||||||
+73
@@ -0,0 +1,73 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2025 Vitor Pamplona
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to use,
|
||||||
|
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||||
|
* Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||||
|
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
package com.vitorpamplona.amethyst.ui.screen.loggedIn.nests.datasource.subassemblies
|
||||||
|
|
||||||
|
import com.vitorpamplona.amethyst.model.topNavFeeds.aroundMe.LocationTopNavPerRelayFilterSet
|
||||||
|
import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
|
||||||
|
import com.vitorpamplona.quartz.nip53LiveActivities.meetingSpaces.MeetingRoomEvent
|
||||||
|
import com.vitorpamplona.quartz.nip53LiveActivities.meetingSpaces.MeetingSpaceEvent
|
||||||
|
|
||||||
|
fun filterNestsByGeohash(
|
||||||
|
relay: NormalizedRelayUrl,
|
||||||
|
geotags: Set<String>,
|
||||||
|
since: Long? = null,
|
||||||
|
): List<RelayBasedFilter> {
|
||||||
|
if (geotags.isEmpty()) return emptyList()
|
||||||
|
|
||||||
|
val geoHashes = geotags.sorted()
|
||||||
|
|
||||||
|
return listOf(
|
||||||
|
RelayBasedFilter(
|
||||||
|
relay = relay,
|
||||||
|
filter =
|
||||||
|
Filter(
|
||||||
|
kinds = listOf(MeetingSpaceEvent.KIND, MeetingRoomEvent.KIND),
|
||||||
|
tags = mapOf("g" to geoHashes),
|
||||||
|
limit = 300,
|
||||||
|
since = since,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun filterNestsByGeohash(
|
||||||
|
geoSet: LocationTopNavPerRelayFilterSet,
|
||||||
|
since: SincePerRelayMap?,
|
||||||
|
defaultSince: Long? = null,
|
||||||
|
): List<RelayBasedFilter> {
|
||||||
|
if (geoSet.set.isEmpty()) return emptyList()
|
||||||
|
|
||||||
|
return geoSet.set
|
||||||
|
.mapNotNull {
|
||||||
|
if (it.value.geotags.isEmpty()) {
|
||||||
|
null
|
||||||
|
} else {
|
||||||
|
filterNestsByGeohash(
|
||||||
|
relay = it.key,
|
||||||
|
geotags = it.value.geotags,
|
||||||
|
since = since?.get(it.key)?.time ?: defaultSince,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}.flatten()
|
||||||
|
}
|
||||||
+74
@@ -0,0 +1,74 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2025 Vitor Pamplona
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to use,
|
||||||
|
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||||
|
* Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||||
|
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
package com.vitorpamplona.amethyst.ui.screen.loggedIn.nests.datasource.subassemblies
|
||||||
|
|
||||||
|
import com.vitorpamplona.amethyst.model.topNavFeeds.hashtag.HashtagTopNavPerRelayFilterSet
|
||||||
|
import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.tags.hashtags.hashtagAlts
|
||||||
|
import com.vitorpamplona.quartz.nip53LiveActivities.meetingSpaces.MeetingRoomEvent
|
||||||
|
import com.vitorpamplona.quartz.nip53LiveActivities.meetingSpaces.MeetingSpaceEvent
|
||||||
|
|
||||||
|
fun filterNestsByHashtag(
|
||||||
|
relay: NormalizedRelayUrl,
|
||||||
|
hashtags: Set<String>,
|
||||||
|
since: Long?,
|
||||||
|
): List<RelayBasedFilter> {
|
||||||
|
if (hashtags.isEmpty()) return emptyList()
|
||||||
|
|
||||||
|
val hashtags = hashtags.flatMap(::hashtagAlts).distinct().sorted()
|
||||||
|
|
||||||
|
return listOf(
|
||||||
|
RelayBasedFilter(
|
||||||
|
relay = relay,
|
||||||
|
filter =
|
||||||
|
Filter(
|
||||||
|
kinds = listOf(MeetingSpaceEvent.KIND, MeetingRoomEvent.KIND),
|
||||||
|
tags = mapOf("t" to hashtags),
|
||||||
|
limit = 300,
|
||||||
|
since = since,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun filterNestsByHashtag(
|
||||||
|
hashSet: HashtagTopNavPerRelayFilterSet,
|
||||||
|
since: SincePerRelayMap?,
|
||||||
|
defaultSince: Long? = null,
|
||||||
|
): List<RelayBasedFilter> {
|
||||||
|
if (hashSet.set.isEmpty()) return emptyList()
|
||||||
|
|
||||||
|
return hashSet.set
|
||||||
|
.mapNotNull { relayHashSet ->
|
||||||
|
if (relayHashSet.value.hashtags.isEmpty()) {
|
||||||
|
null
|
||||||
|
} else {
|
||||||
|
filterNestsByHashtag(
|
||||||
|
relay = relayHashSet.key,
|
||||||
|
hashtags = relayHashSet.value.hashtags,
|
||||||
|
since = since?.get(relayHashSet.key)?.time ?: defaultSince,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}.flatten()
|
||||||
|
}
|
||||||
+53
@@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2025 Vitor Pamplona
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to use,
|
||||||
|
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||||
|
* Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||||
|
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
package com.vitorpamplona.amethyst.ui.screen.loggedIn.nests.datasource.subassemblies
|
||||||
|
|
||||||
|
import com.vitorpamplona.amethyst.model.topNavFeeds.global.GlobalTopNavPerRelayFilterSet
|
||||||
|
import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter
|
||||||
|
import com.vitorpamplona.quartz.nip53LiveActivities.meetingSpaces.MeetingRoomEvent
|
||||||
|
import com.vitorpamplona.quartz.nip53LiveActivities.meetingSpaces.MeetingSpaceEvent
|
||||||
|
import com.vitorpamplona.quartz.utils.TimeUtils
|
||||||
|
|
||||||
|
fun filterNestsGlobal(
|
||||||
|
relays: GlobalTopNavPerRelayFilterSet,
|
||||||
|
since: SincePerRelayMap?,
|
||||||
|
defaultSince: Long? = null,
|
||||||
|
): List<RelayBasedFilter> {
|
||||||
|
if (relays.set.isEmpty()) return emptyList()
|
||||||
|
|
||||||
|
return relays.set
|
||||||
|
.map {
|
||||||
|
val since = since?.get(it.key)?.time ?: defaultSince
|
||||||
|
listOf(
|
||||||
|
RelayBasedFilter(
|
||||||
|
relay = it.key,
|
||||||
|
filter =
|
||||||
|
Filter(
|
||||||
|
kinds = listOf(MeetingSpaceEvent.KIND, MeetingRoomEvent.KIND),
|
||||||
|
limit = 300,
|
||||||
|
since = since ?: TimeUtils.oneWeekAgo(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}.flatten()
|
||||||
|
}
|
||||||
+1
-1
@@ -143,7 +143,7 @@ private fun NestActivityBody(
|
|||||||
|
|
||||||
// Single REQ per relay covering chat, presence, reactions, admin
|
// Single REQ per relay covering chat, presence, reactions, admin
|
||||||
// commands. See NestRoomFilterAssembler for the filter shape.
|
// commands. See NestRoomFilterAssembler for the filter shape.
|
||||||
NestRoomFilterAssemblerSubscription(roomATag, localPubkey, accountViewModel)
|
NestRoomFilterAssemblerSubscription(roomATag, accountViewModel)
|
||||||
|
|
||||||
// Read side: LocalCache → VM. Each kind has its own collector
|
// Read side: LocalCache → VM. Each kind has its own collector
|
||||||
// (different VM hook per kind) plus the two eviction tickers.
|
// (different VM hook per kind) plus the two eviction tickers.
|
||||||
|
|||||||
Reference in New Issue
Block a user