refactor(commons): move the import-clean datasource families to commons/relayClient

The datasource families whose keys are a User, an AddressableNote, a string,
or an IAccount-compatible account — chess, relay feed, NIP-66 relay info,
url, geohash, the channel assembler, communities, git repo, profile, one/my
podcast, onchain zaps and poll responses — move wholesale into
`commons/relayClient/<feature>/`, along with the pure thread filter
functions and `FilterPostsByScopes.kt` (`CommentKinds`), which those filters
share with the home feed. Three Subscription composables that never touched
`AccountViewModel` (community, repository, profile) come along; the ones
that do stay in the app.

The only seam was `LocalCache`, read for `relayHints` and
`checkGetOrCreateUser`, both already on `ICacheProvider`. The affected
assemblers take `cache: ICacheProvider` first, thread it into their
sub-assemblers, and the filter functions that need it take it as their first
parameter; `RelaySubscriptionsCoordinator` passes the cache it already holds.
`PollResponsesQueryState` is typed on `IAccount`.

The URL filter test moves to commons commonTest on `kotlin.test`. The plan
doc records what stays behind and why.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01J836W9ZjSUJUQ1d23TpiJo
This commit is contained in:
Claude
2026-09-05 20:00:10 +00:00
parent 693594a44c
commit eb76907720
73 changed files with 217 additions and 137 deletions
@@ -24,11 +24,16 @@ import com.vitorpamplona.amethyst.commons.relayClient.articles.ArticlesFilterAss
import com.vitorpamplona.amethyst.commons.relayClient.assemblers.CashuMintDirectoryFilterAssembler
import com.vitorpamplona.amethyst.commons.relayClient.badges.BadgesFilterAssembler
import com.vitorpamplona.amethyst.commons.relayClient.calendars.CalendarsFilterAssembler
import com.vitorpamplona.amethyst.commons.relayClient.channel.ChannelFilterAssembler
import com.vitorpamplona.amethyst.commons.relayClient.chess.ChessFilterAssembler
import com.vitorpamplona.amethyst.commons.relayClient.communities.CommunityFilterAssembler
import com.vitorpamplona.amethyst.commons.relayClient.communities.list.CommunitiesListFilterAssembler
import com.vitorpamplona.amethyst.commons.relayClient.discover.DiscoveryFilterAssembler
import com.vitorpamplona.amethyst.commons.relayClient.emojipacks.BrowseEmojiSetsFilterAssembler
import com.vitorpamplona.amethyst.commons.relayClient.event.EventFinderFilterAssembler
import com.vitorpamplona.amethyst.commons.relayClient.followPacks.FollowPacksFilterAssembler
import com.vitorpamplona.amethyst.commons.relayClient.geohash.GeoHashFilterAssembler
import com.vitorpamplona.amethyst.commons.relayClient.gitRepo.RepositoryFilterAssembler
import com.vitorpamplona.amethyst.commons.relayClient.gitRepositories.GitRepositoriesFilterAssembler
import com.vitorpamplona.amethyst.commons.relayClient.highlights.HighlightsFilterAssembler
import com.vitorpamplona.amethyst.commons.relayClient.livestreams.LiveStreamsFilterAssembler
@@ -40,15 +45,23 @@ import com.vitorpamplona.amethyst.commons.relayClient.nests.NestsFilterAssembler
import com.vitorpamplona.amethyst.commons.relayClient.nip47WalletConnect.NWCPaymentFilterAssembler
import com.vitorpamplona.amethyst.commons.relayClient.nsites.NsitesFilterAssembler
import com.vitorpamplona.amethyst.commons.relayClient.pictures.PicturesFilterAssembler
import com.vitorpamplona.amethyst.commons.relayClient.podcasts.MyPodcastFilterAssembler
import com.vitorpamplona.amethyst.commons.relayClient.podcasts.OnePodcastFilterAssembler
import com.vitorpamplona.amethyst.commons.relayClient.podcasts.PodcastEpisodesFilterAssembler
import com.vitorpamplona.amethyst.commons.relayClient.podcasts.PodcastsFilterAssembler
import com.vitorpamplona.amethyst.commons.relayClient.polls.PollsFilterAssembler
import com.vitorpamplona.amethyst.commons.relayClient.polls.results.PollResponsesFilterAssembler
import com.vitorpamplona.amethyst.commons.relayClient.products.ProductsFilterAssembler
import com.vitorpamplona.amethyst.commons.relayClient.profile.UserProfileFilterAssembler
import com.vitorpamplona.amethyst.commons.relayClient.publicChats.PublicChatsFilterAssembler
import com.vitorpamplona.amethyst.commons.relayClient.relay.RelayFeedFilterAssembler
import com.vitorpamplona.amethyst.commons.relayClient.relays.RelayInfoNip66FilterAssembler
import com.vitorpamplona.amethyst.commons.relayClient.shorts.ShortsFilterAssembler
import com.vitorpamplona.amethyst.commons.relayClient.softwareapps.SoftwareAppsFilterAssembler
import com.vitorpamplona.amethyst.commons.relayClient.url.UrlFilterAssembler
import com.vitorpamplona.amethyst.commons.relayClient.user.UserFinderFilterAssembler
import com.vitorpamplona.amethyst.commons.relayClient.video.VideoFilterAssembler
import com.vitorpamplona.amethyst.commons.relayClient.wallet.OnchainZapsFilterAssembler
import com.vitorpamplona.amethyst.commons.relayClient.workouts.WorkoutsFilterAssembler
import com.vitorpamplona.amethyst.model.LocalCache
import com.vitorpamplona.amethyst.service.relayClient.reqCommand.account.AccountFilterAssembler
@@ -60,7 +73,6 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.badges.profile.datasource.P
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.privateDM.datasource.ChatroomFilterAssembler
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.publicChannels.concord.datasource.ConcordChannelFilterAssembler
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.publicChannels.concord.datasource.ConcordChannelHistoryFilterAssembler
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.publicChannels.datasource.ChannelFilterAssembler
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.publicChannels.relayGroup.datasource.BuzzDmJoinedChatTailFilterAssembler
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.publicChannels.relayGroup.datasource.RelayGroupCardWarmupFilterAssembler
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.publicChannels.relayGroup.datasource.RelayGroupJoinedChatTailFilterAssembler
@@ -72,25 +84,13 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.publicChannels.relayG
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.publicChannels.relayGroup.datasource.RelayGroupsDiscoveryFilterAssembler
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.publicChannels.relayGroup.datasource.RelayGroupsOnRelayFilterAssembler
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.rooms.datasource.ChatroomListFilterAssembler
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chess.datasource.ChessFilterAssembler
import com.vitorpamplona.amethyst.ui.screen.loggedIn.communities.datasource.CommunityFilterAssembler
import com.vitorpamplona.amethyst.ui.screen.loggedIn.followPacks.feed.datasource.FollowPackFeedFilterAssembler
import com.vitorpamplona.amethyst.ui.screen.loggedIn.geohash.datasource.GeoHashFilterAssembler
import com.vitorpamplona.amethyst.ui.screen.loggedIn.gitRepo.datasource.RepositoryFilterAssembler
import com.vitorpamplona.amethyst.ui.screen.loggedIn.hashtag.datasource.HashtagFilterAssembler
import com.vitorpamplona.amethyst.ui.screen.loggedIn.home.datasource.HomeFilterAssembler
import com.vitorpamplona.amethyst.ui.screen.loggedIn.napplets.datasource.ConnectedAppsFilterAssembler
import com.vitorpamplona.amethyst.ui.screen.loggedIn.nests.datasource.NestRoomFilterAssembler
import com.vitorpamplona.amethyst.ui.screen.loggedIn.nests.datasource.NestRoomLivenessAssembler
import com.vitorpamplona.amethyst.ui.screen.loggedIn.podcasts.datasource.MyPodcastFilterAssembler
import com.vitorpamplona.amethyst.ui.screen.loggedIn.podcasts.datasource.OnePodcastFilterAssembler
import com.vitorpamplona.amethyst.ui.screen.loggedIn.polls.results.datasources.PollResponsesFilterAssembler
import com.vitorpamplona.amethyst.ui.screen.loggedIn.profile.datasource.UserProfileFilterAssembler
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relay.datasource.RelayFeedFilterAssembler
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.datasource.RelayInfoNip66FilterAssembler
import com.vitorpamplona.amethyst.ui.screen.loggedIn.threadview.datasources.ThreadFilterAssembler
import com.vitorpamplona.amethyst.ui.screen.loggedIn.url.datasource.UrlFilterAssembler
import com.vitorpamplona.amethyst.ui.screen.loggedIn.wallet.datasource.OnchainZapsFilterAssembler
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.accessories.RelayOfflineTracker
import com.vitorpamplona.quartz.nip01Core.relay.client.auth.IAuthStatus
@@ -154,10 +154,10 @@ class RelaySubscriptionsCoordinator(
val concordChannelHistory = ConcordChannelHistoryFilterAssembler(client)
val chatroom = ChatroomFilterAssembler(client)
val community = CommunityFilterAssembler(client)
val gitRepository = RepositoryFilterAssembler(client)
val community = CommunityFilterAssembler(cache, client)
val gitRepository = RepositoryFilterAssembler(cache, client)
val thread = ThreadFilterAssembler(client)
val profile = UserProfileFilterAssembler(client)
val profile = UserProfileFilterAssembler(cache, client)
val hashtags = HashtagFilterAssembler(client)
val geohashes = GeoHashFilterAssembler(client)
val urls = UrlFilterAssembler(client)
@@ -170,7 +170,7 @@ class RelaySubscriptionsCoordinator(
val polls = PollsFilterAssembler(client)
// Votes for the poll whose results screen is open.
val pollResponses = PollResponsesFilterAssembler(client)
val pollResponses = PollResponsesFilterAssembler(cache, client)
val pictures = PicturesFilterAssembler(client)
val workouts = WorkoutsFilterAssembler(client)
val gitRepositories = GitRepositoriesFilterAssembler(client)
@@ -189,8 +189,8 @@ class RelaySubscriptionsCoordinator(
val musicPlaylists = MusicPlaylistsFilterAssembler(client)
val podcastEpisodes = PodcastEpisodesFilterAssembler(client)
val podcasts = PodcastsFilterAssembler(client)
val onePodcast = OnePodcastFilterAssembler(client)
val myPodcast = MyPodcastFilterAssembler(client)
val onePodcast = OnePodcastFilterAssembler(cache, client)
val myPodcast = MyPodcastFilterAssembler(cache, client)
val softwareApps = SoftwareAppsFilterAssembler(client)
val napplets = NappletsFilterAssembler(client)
val connectedApps = ConnectedAppsFilterAssembler(client)
@@ -205,7 +205,7 @@ class RelaySubscriptionsCoordinator(
val nwc = NWCPaymentFilterAssembler(client)
// active when the wallet's on-chain transactions screen is on top.
val onchainZaps = OnchainZapsFilterAssembler(client)
val onchainZaps = OnchainZapsFilterAssembler(cache, client)
// active while the user is browsing the NIP-87 mint picker. Subscribes to
// kind:38172 cashu mint announcements + kind:38000 cashu-scoped
@@ -67,6 +67,7 @@ import com.vitorpamplona.amethyst.commons.icons.symbols.Icon
import com.vitorpamplona.amethyst.commons.icons.symbols.MaterialSymbols
import com.vitorpamplona.amethyst.commons.model.AddressableNote
import com.vitorpamplona.amethyst.commons.nip30CustomEmojis.ui.ShowEmojiSuggestionList
import com.vitorpamplona.amethyst.commons.relayClient.communities.CommunityFilterAssemblerSubscription
import com.vitorpamplona.amethyst.commons.resources.Res
import com.vitorpamplona.amethyst.commons.resources.geo_post_change_place
import com.vitorpamplona.amethyst.commons.resources.geo_post_posting_to
@@ -115,7 +116,6 @@ import com.vitorpamplona.amethyst.ui.note.creators.zapsplits.ForwardZapTo
import com.vitorpamplona.amethyst.ui.note.creators.zapsplits.ForwardZapToButton
import com.vitorpamplona.amethyst.ui.note.types.ReplyRenderType
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.screen.loggedIn.communities.datasource.CommunityFilterAssemblerSubscription
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.Size10dp
import com.vitorpamplona.amethyst.ui.theme.Size30Modifier
@@ -28,6 +28,7 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.vitorpamplona.amethyst.commons.model.Channel
import com.vitorpamplona.amethyst.commons.model.nip29RelayGroups.RelayGroupChannel
import com.vitorpamplona.amethyst.commons.model.nip53LiveActivities.LiveActivitiesChannel
import com.vitorpamplona.amethyst.commons.relayClient.channel.ChannelFilterAssembler
import com.vitorpamplona.amethyst.commons.relayClient.channel.ChannelQueryState
import com.vitorpamplona.amethyst.commons.relayClient.subscriptions.LifecycleAwareKeyDataSourceSubscription
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
@@ -25,6 +25,7 @@ import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.vitorpamplona.amethyst.commons.relayClient.chess.ChessQueryState
import com.vitorpamplona.amethyst.commons.relayClient.subscriptions.LifecycleAwareKeyDataSourceSubscription
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chess.ChessViewModelNew
@@ -44,6 +44,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import com.vitorpamplona.amethyst.commons.model.AddressableNote
import com.vitorpamplona.amethyst.commons.relayClient.communities.CommunityFilterAssemblerSubscription
import com.vitorpamplona.amethyst.commons.resources.Res
import com.vitorpamplona.amethyst.commons.resources.feed
import com.vitorpamplona.amethyst.commons.resources.mod_queue
@@ -64,7 +65,6 @@ import com.vitorpamplona.amethyst.ui.screen.RefresheableFeedView
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.screen.loggedIn.communities.dal.CommunityFeedViewModel
import com.vitorpamplona.amethyst.ui.screen.loggedIn.communities.dal.CommunityModerationFeedViewModel
import com.vitorpamplona.amethyst.ui.screen.loggedIn.communities.datasource.CommunityFilterAssemblerSubscription
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.Size35dp
import com.vitorpamplona.amethyst.ui.theme.TabRowHeight
@@ -23,6 +23,7 @@ package com.vitorpamplona.amethyst.ui.screen.loggedIn.geohash.datasource
import android.annotation.SuppressLint
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import com.vitorpamplona.amethyst.commons.relayClient.geohash.GeohashQueryState
import com.vitorpamplona.amethyst.commons.relayClient.subscriptions.LifecycleAwareKeyDataSourceSubscription
import com.vitorpamplona.amethyst.ui.navigation.routes.Route
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
@@ -65,6 +65,7 @@ import com.vitorpamplona.amethyst.commons.model.Note
import com.vitorpamplona.amethyst.commons.nip34Git.GitBrowseState
import com.vitorpamplona.amethyst.commons.nip34Git.GitRepoSnapshotCache
import com.vitorpamplona.amethyst.commons.nip34Git.GitRepositoryBrowserViewModel
import com.vitorpamplona.amethyst.commons.relayClient.gitRepo.RepositoryFilterAssemblerSubscription
import com.vitorpamplona.amethyst.commons.resources.Res
import com.vitorpamplona.amethyst.commons.resources.git_new_issue_button
import com.vitorpamplona.amethyst.commons.resources.git_repo_bookmark
@@ -96,7 +97,6 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.gitRepo.code.GitCodeTab
import com.vitorpamplona.amethyst.ui.screen.loggedIn.gitRepo.code.GitReadmeSection
import com.vitorpamplona.amethyst.ui.screen.loggedIn.gitRepo.dal.RepositoryIssuesFeedViewModel
import com.vitorpamplona.amethyst.ui.screen.loggedIn.gitRepo.dal.RepositoryPatchesFeedViewModel
import com.vitorpamplona.amethyst.ui.screen.loggedIn.gitRepo.datasource.RepositoryFilterAssemblerSubscription
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.quartz.nip01Core.core.Address
import com.vitorpamplona.quartz.nip34Git.repository.GitRepositoryEvent
@@ -20,10 +20,10 @@
*/
package com.vitorpamplona.amethyst.ui.screen.loggedIn.hashtag.datasource
import com.vitorpamplona.amethyst.commons.relayClient.nip22Comments.CommentKinds
import com.vitorpamplona.amethyst.commons.relayClient.subscriptions.ExplainedFilter
import com.vitorpamplona.amethyst.commons.relayClient.subscriptions.SubPurpose
import com.vitorpamplona.amethyst.commons.relays.SincePerRelayMap
import com.vitorpamplona.amethyst.ui.screen.loggedIn.home.datasource.nip22Comments.CommentKinds
import com.vitorpamplona.quartz.experimental.audio.header.AudioHeaderEvent
import com.vitorpamplona.quartz.experimental.audio.track.AudioTrackEvent
import com.vitorpamplona.quartz.experimental.interactiveStories.InteractiveStorySceneEvent
@@ -21,10 +21,10 @@
package com.vitorpamplona.amethyst.ui.screen.loggedIn.home.datasource.nip01Core
import com.vitorpamplona.amethyst.commons.model.topNavFeeds.aroundMe.LocationTopNavPerRelayFilterSet
import com.vitorpamplona.amethyst.commons.relayClient.nip22Comments.filterHomePostsByScopes
import com.vitorpamplona.amethyst.commons.relayClient.subscriptions.ExplainedFilter
import com.vitorpamplona.amethyst.commons.relayClient.subscriptions.SubPurpose
import com.vitorpamplona.amethyst.commons.relays.SincePerRelayMap
import com.vitorpamplona.amethyst.ui.screen.loggedIn.home.datasource.nip22Comments.filterHomePostsByScopes
import com.vitorpamplona.quartz.experimental.attestations.attestation.AttestationEvent
import com.vitorpamplona.quartz.experimental.interactiveStories.InteractiveStoryPrologueEvent
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
@@ -21,10 +21,10 @@
package com.vitorpamplona.amethyst.ui.screen.loggedIn.home.datasource.nip01Core
import com.vitorpamplona.amethyst.commons.model.topNavFeeds.hashtag.HashtagTopNavPerRelayFilterSet
import com.vitorpamplona.amethyst.commons.relayClient.nip22Comments.filterHomePostsByScopes
import com.vitorpamplona.amethyst.commons.relayClient.subscriptions.ExplainedFilter
import com.vitorpamplona.amethyst.commons.relayClient.subscriptions.SubPurpose
import com.vitorpamplona.amethyst.commons.relays.SincePerRelayMap
import com.vitorpamplona.amethyst.ui.screen.loggedIn.home.datasource.nip22Comments.filterHomePostsByScopes
import com.vitorpamplona.quartz.experimental.attestations.attestation.AttestationEvent
import com.vitorpamplona.quartz.experimental.audio.header.AudioHeaderEvent
import com.vitorpamplona.quartz.experimental.interactiveStories.InteractiveStoryPrologueEvent
@@ -21,10 +21,10 @@
package com.vitorpamplona.amethyst.ui.screen.loggedIn.home.datasource.nip65Follows
import com.vitorpamplona.amethyst.commons.model.topNavFeeds.allFollows.AllFollowsTopNavPerRelayFilterSet
import com.vitorpamplona.amethyst.commons.relayClient.nip22Comments.filterHomePostsByScopes
import com.vitorpamplona.amethyst.commons.relays.SincePerRelayMap
import com.vitorpamplona.amethyst.ui.screen.loggedIn.home.datasource.nip01Core.filterHomePostsByGeohashes
import com.vitorpamplona.amethyst.ui.screen.loggedIn.home.datasource.nip01Core.filterHomePostsByHashtags
import com.vitorpamplona.amethyst.ui.screen.loggedIn.home.datasource.nip22Comments.filterHomePostsByScopes
import com.vitorpamplona.amethyst.ui.screen.loggedIn.home.datasource.nip72Communities.filterHomePostsFromAllCommunities
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
@@ -22,6 +22,7 @@ package com.vitorpamplona.amethyst.ui.screen.loggedIn.podcasts.datasource
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import com.vitorpamplona.amethyst.commons.relayClient.podcasts.MyPodcastQueryState
import com.vitorpamplona.amethyst.commons.relayClient.subscriptions.LifecycleAwareKeyDataSourceSubscription
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
@@ -23,6 +23,7 @@ package com.vitorpamplona.amethyst.ui.screen.loggedIn.podcasts.datasource
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import com.vitorpamplona.amethyst.commons.model.User
import com.vitorpamplona.amethyst.commons.relayClient.podcasts.OnePodcastQueryState
import com.vitorpamplona.amethyst.commons.relayClient.subscriptions.LifecycleAwareKeyDataSourceSubscription
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
@@ -22,6 +22,8 @@ package com.vitorpamplona.amethyst.ui.screen.loggedIn.polls.results.datasources
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import com.vitorpamplona.amethyst.commons.relayClient.polls.results.PollResponsesFilterAssembler
import com.vitorpamplona.amethyst.commons.relayClient.polls.results.PollResponsesQueryState
import com.vitorpamplona.amethyst.commons.relayClient.subscriptions.LifecycleAwareKeyDataSourceSubscription
import com.vitorpamplona.amethyst.model.Account
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
@@ -65,6 +65,7 @@ import androidx.compose.ui.unit.IntSize
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.viewmodel.compose.viewModel
import com.vitorpamplona.amethyst.commons.model.User
import com.vitorpamplona.amethyst.commons.relayClient.profile.UserProfileFilterAssemblerSubscription
import com.vitorpamplona.amethyst.commons.resources.Res
import com.vitorpamplona.amethyst.commons.resources.gallery
import com.vitorpamplona.amethyst.commons.resources.mutual
@@ -86,7 +87,6 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.profile.bookmarks.TabBookma
import com.vitorpamplona.amethyst.ui.screen.loggedIn.profile.bookmarks.dal.UserProfileBookmarksFeedViewModel
import com.vitorpamplona.amethyst.ui.screen.loggedIn.profile.conversations.TabNotesConversations
import com.vitorpamplona.amethyst.ui.screen.loggedIn.profile.conversations.dal.UserProfileConversationsFeedViewModel
import com.vitorpamplona.amethyst.ui.screen.loggedIn.profile.datasource.UserProfileFilterAssemblerSubscription
import com.vitorpamplona.amethyst.ui.screen.loggedIn.profile.followers.FollowersTabHeader
import com.vitorpamplona.amethyst.ui.screen.loggedIn.profile.followers.TabFollowers
import com.vitorpamplona.amethyst.ui.screen.loggedIn.profile.followers.dal.UserProfileFollowersUserFeedViewModel
@@ -22,6 +22,7 @@ package com.vitorpamplona.amethyst.ui.screen.loggedIn.relay.datasource
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import com.vitorpamplona.amethyst.commons.relayClient.relay.RelayFeedQueryState
import com.vitorpamplona.amethyst.commons.relayClient.subscriptions.LifecycleAwareKeyDataSourceSubscription
import com.vitorpamplona.amethyst.ui.navigation.routes.Route
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
@@ -22,6 +22,7 @@ package com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.datasource
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import com.vitorpamplona.amethyst.commons.relayClient.relays.RelayInfoNip66QueryState
import com.vitorpamplona.amethyst.commons.relayClient.subscriptions.LifecycleAwareKeyDataSourceSubscription
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
@@ -22,6 +22,7 @@ package com.vitorpamplona.amethyst.ui.screen.loggedIn.threadview.datasources.sub
import com.vitorpamplona.amethyst.commons.model.ThreadAssembler
import com.vitorpamplona.amethyst.commons.relayClient.eoseManagers.PerUniqueIdEoseManager
import com.vitorpamplona.amethyst.commons.relayClient.thread.filterMissingEventsForThread
import com.vitorpamplona.amethyst.commons.relays.SincePerRelayMap
import com.vitorpamplona.amethyst.model.LocalCache
import com.vitorpamplona.amethyst.ui.screen.loggedIn.threadview.datasources.ThreadQueryState
@@ -48,7 +49,7 @@ class ThreadEventLoaderSubAssembler(
): List<RelayBasedFilter>? {
val branches = ThreadAssembler(LocalCache).findThreadFor(key.eventId) ?: return null
val defaultRelays = key.account.followPlusAllMineWithSearch.flow.value
return filterMissingEventsForThread(branches, defaultRelays)
return filterMissingEventsForThread(LocalCache, branches, defaultRelays)
}
override fun id(key: ThreadQueryState) = key.eventId
@@ -22,6 +22,7 @@ package com.vitorpamplona.amethyst.ui.screen.loggedIn.threadview.datasources.sub
import com.vitorpamplona.amethyst.commons.model.ThreadAssembler
import com.vitorpamplona.amethyst.commons.relayClient.eoseManagers.PerUniqueIdEoseManager
import com.vitorpamplona.amethyst.commons.relayClient.thread.filterEventsInThreadForRoot
import com.vitorpamplona.amethyst.commons.relays.SincePerRelayMap
import com.vitorpamplona.amethyst.model.LocalCache
import com.vitorpamplona.amethyst.ui.screen.loggedIn.threadview.datasources.ThreadQueryState
@@ -24,6 +24,7 @@ import android.annotation.SuppressLint
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import com.vitorpamplona.amethyst.commons.relayClient.subscriptions.LifecycleAwareKeyDataSourceSubscription
import com.vitorpamplona.amethyst.commons.relayClient.url.UrlQueryState
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
@SuppressLint("StateFlowValueCalledInComposition")
@@ -24,6 +24,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import com.vitorpamplona.amethyst.commons.model.User
import com.vitorpamplona.amethyst.commons.relayClient.subscriptions.LifecycleAwareKeyDataSourceSubscription
import com.vitorpamplona.amethyst.commons.relayClient.wallet.OnchainZapsQueryState
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
/**
@@ -662,6 +662,37 @@ recommendations, nest room, follow-pack feed, onchain zaps, NIP-66 relay
info). Many are import-clean and can follow mechanically; the `Account`-typed
ones wait on Wave 4.
### Import-clean non-top-nav datasource families landed (2026-09-05)
The families whose keys are a `User`, an `AddressableNote`, a string, or an
`IAccount`-compatible account moved wholesale into `commons/relayClient/`:
chess, relay feed, NIP-66 relay info, url, geohash, the channel assembler,
communities, git repo, profile (all 14 files), one/my podcast, onchain zaps,
poll responses, plus the pure `filterEventsInThreadForRoot` /
`filterMissingEventsForThread` functions and `FilterPostsByScopes.kt`
(`CommentKinds`), which those filters and the home feed share. The URL filter
test came along onto `kotlin.test`. Three Subscription composables that never
touched `AccountViewModel` (community, repository, profile) moved too.
The only seam was `LocalCache`, read for `relayHints` and
`checkGetOrCreateUser` — both already on `ICacheProvider` — so the affected
assemblers take `cache: ICacheProvider` as their first constructor parameter,
thread it into their sub-assemblers, and the filter functions that need it
take it as their first parameter. `RelaySubscriptionsCoordinator` passes the
cache it already holds.
Still in the app, with the reason: `hashtag/` (`FilterHashtagLabels` reads
`Account.followsPerRelay`, a per-outbox follow resolution `IAccount` lacks);
`threadview/datasources/` assembler + sub-assemblers and `apps/recommendations`,
`badges/profile`, `napplets/ConnectedApps*` (each reads one relay-list state
off `Account` — `followPlusAllMineWithSearch`, `outboxRelays` /
`defaultGlobalRelays`, `notificationRelays`, `homeRelays`; the
`SearchQueryState` recipe of carrying the flow on the key applies, one small
change each); `followPacks/feed` (dispatches to the app-side home filters);
`chats/*` (DM plumbing: `DmRelayLog`, `GeohashRelays`,
`launchChatFeedToggleObserver`); `nests/NestRoom*`, `relayGroup/*`, `concord/*`
and `home/` (`Account` + `LocalCache` live streams + `AccountViewModel`).
### Desktop `subscriptions/FilterBuilders.kt` — investigated, not migrated (2026-09-05)
The audit listed this 742-line file as a hand-rolled copy of ~34
@@ -18,7 +18,7 @@
* 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.chats.publicChannels.datasource
package com.vitorpamplona.amethyst.commons.relayClient.channel
import com.vitorpamplona.amethyst.commons.relayClient.channel.ChannelFromUserFilterSubAssembler
import com.vitorpamplona.amethyst.commons.relayClient.channel.ChannelPublicFilterSubAssembler
@@ -18,7 +18,7 @@
* 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.chess.datasource
package com.vitorpamplona.amethyst.commons.relayClient.chess
import com.vitorpamplona.amethyst.commons.relayClient.eoseManagers.PerUniqueIdEoseManager
import com.vitorpamplona.amethyst.commons.relays.SincePerRelayMap
@@ -18,7 +18,7 @@
* 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.chess.datasource
package com.vitorpamplona.amethyst.commons.relayClient.chess
import com.vitorpamplona.amethyst.commons.relayClient.composeSubscriptionManagers.ComposeSubscriptionManager
import com.vitorpamplona.quartz.nip01Core.core.Event
@@ -18,7 +18,7 @@
* 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.chess.datasource
package com.vitorpamplona.amethyst.commons.relayClient.chess
import com.vitorpamplona.amethyst.commons.nip64Chess.subscription.ChessFilterBuilder
import com.vitorpamplona.amethyst.commons.nip64Chess.subscription.ChessSubscriptionState
@@ -18,17 +18,18 @@
* 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.communities.datasource
package com.vitorpamplona.amethyst.commons.relayClient.communities
import com.vitorpamplona.amethyst.commons.model.cache.ICacheProvider
import com.vitorpamplona.amethyst.commons.relayClient.eoseManagers.SingleSubEoseManager
import com.vitorpamplona.amethyst.commons.relays.SincePerRelayMap
import com.vitorpamplona.amethyst.model.LocalCache
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
import com.vitorpamplona.quartz.nip72ModCommunities.definition.CommunityDefinitionEvent
import com.vitorpamplona.quartz.utils.mapOfSet
class CommunityFeedFilterSubAssembler(
val cache: ICacheProvider,
client: INostrClient,
allKeys: () -> Set<CommunityQueryState>,
) : SingleSubEoseManager<CommunityQueryState>(client, allKeys) {
@@ -44,7 +45,7 @@ class CommunityFeedFilterSubAssembler(
val communityRelays =
(
commEvent.relayUrls().ifEmpty {
LocalCache.relayHints.hintsForAddress(commEvent.addressTag())
cache.relayHints.hintsForAddress(commEvent.addressTag())
} + it.community.relayUrls()
).toSet()
@@ -52,7 +53,7 @@ class CommunityFeedFilterSubAssembler(
mapOfSet {
commEvent.moderatorKeys().forEach { modKey ->
// hits the relay of each moderator for approvals
LocalCache.checkGetOrCreateUser(modKey)?.outboxRelays()?.forEach { relay ->
cache.checkGetOrCreateUser(modKey)?.outboxRelays()?.forEach { relay ->
add(relay, modKey)
}
@@ -18,9 +18,10 @@
* 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.communities.datasource
package com.vitorpamplona.amethyst.commons.relayClient.communities
import com.vitorpamplona.amethyst.commons.model.AddressableNote
import com.vitorpamplona.amethyst.commons.model.cache.ICacheProvider
import com.vitorpamplona.amethyst.commons.relayClient.composeSubscriptionManagers.ComposeSubscriptionManager
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient
@@ -30,12 +31,13 @@ class CommunityQueryState(
)
class CommunityFilterAssembler(
cache: ICacheProvider,
client: INostrClient,
) : ComposeSubscriptionManager<CommunityQueryState>() {
val group =
listOf(
CommunityFeedFilterSubAssembler(client, ::allKeys),
CommunityRulesFilterSubAssembler(client, ::allKeys),
CommunityFeedFilterSubAssembler(cache, client, ::allKeys),
CommunityRulesFilterSubAssembler(cache, client, ::allKeys),
)
override fun invalidateKeys() = invalidateFilters()
@@ -18,7 +18,7 @@
* 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.communities.datasource
package com.vitorpamplona.amethyst.commons.relayClient.communities
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
@@ -18,13 +18,13 @@
* 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.communities.datasource
package com.vitorpamplona.amethyst.commons.relayClient.communities
import com.vitorpamplona.amethyst.commons.model.cache.ICacheProvider
import com.vitorpamplona.amethyst.commons.relayClient.eoseManagers.SingleSubEoseManager
import com.vitorpamplona.amethyst.commons.relayClient.subscriptions.ExplainedFilter
import com.vitorpamplona.amethyst.commons.relayClient.subscriptions.SubPurpose
import com.vitorpamplona.amethyst.commons.relays.SincePerRelayMap
import com.vitorpamplona.amethyst.model.LocalCache
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
import com.vitorpamplona.quartz.nip72ModCommunities.definition.CommunityDefinitionEvent
@@ -40,6 +40,7 @@ import com.vitorpamplona.quartz.nip72ModCommunities.rules.CommunityRulesEvent
* declared moderator are accepted, matching the trust model of NIP-72 approvals.
*/
class CommunityRulesFilterSubAssembler(
val cache: ICacheProvider,
client: INostrClient,
allKeys: () -> Set<CommunityQueryState>,
) : SingleSubEoseManager<CommunityQueryState>(client, allKeys) {
@@ -57,7 +58,7 @@ class CommunityRulesFilterSubAssembler(
val communityRelays =
(
commEvent.relayUrls().ifEmpty {
LocalCache.relayHints.hintsForAddress(commEvent.addressTag())
cache.relayHints.hintsForAddress(commEvent.addressTag())
} + key.community.relayUrls()
).toSet()
@@ -18,7 +18,7 @@
* 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.communities.datasource
package com.vitorpamplona.amethyst.commons.relayClient.communities
import com.vitorpamplona.amethyst.commons.relayClient.subscriptions.ExplainedFilter
import com.vitorpamplona.amethyst.commons.relayClient.subscriptions.SubPurpose
@@ -18,12 +18,12 @@
* 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.geohash.datasource
package com.vitorpamplona.amethyst.commons.relayClient.geohash
import com.vitorpamplona.amethyst.commons.relayClient.nip22Comments.CommentKinds
import com.vitorpamplona.amethyst.commons.relayClient.subscriptions.ExplainedFilter
import com.vitorpamplona.amethyst.commons.relayClient.subscriptions.SubPurpose
import com.vitorpamplona.amethyst.commons.relays.SincePerRelayMap
import com.vitorpamplona.amethyst.ui.screen.loggedIn.home.datasource.nip22Comments.CommentKinds
import com.vitorpamplona.quartz.experimental.audio.header.AudioHeaderEvent
import com.vitorpamplona.quartz.experimental.audio.track.AudioTrackEvent
import com.vitorpamplona.quartz.experimental.music.playlist.MusicPlaylistEvent
@@ -18,7 +18,7 @@
* 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.geohash.datasource
package com.vitorpamplona.amethyst.commons.relayClient.geohash
import com.vitorpamplona.amethyst.commons.relayClient.eoseManagers.PerUniqueIdEoseManager
import com.vitorpamplona.amethyst.commons.relays.SincePerRelayMap
@@ -18,7 +18,7 @@
* 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.geohash.datasource
package com.vitorpamplona.amethyst.commons.relayClient.geohash
import androidx.compose.runtime.Stable
import com.vitorpamplona.amethyst.commons.relayClient.composeSubscriptionManagers.ComposeSubscriptionManager
@@ -18,7 +18,7 @@
* 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.gitRepo.datasource
package com.vitorpamplona.amethyst.commons.relayClient.gitRepo
import com.vitorpamplona.amethyst.commons.relayClient.subscriptions.ExplainedFilter
import com.vitorpamplona.amethyst.commons.relayClient.subscriptions.SubPurpose
@@ -18,17 +18,18 @@
* 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.gitRepo.datasource
package com.vitorpamplona.amethyst.commons.relayClient.gitRepo
import com.vitorpamplona.amethyst.commons.model.cache.ICacheProvider
import com.vitorpamplona.amethyst.commons.relayClient.eoseManagers.SingleSubEoseManager
import com.vitorpamplona.amethyst.commons.relays.SincePerRelayMap
import com.vitorpamplona.amethyst.model.LocalCache
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.RelayUrlNormalizer
import com.vitorpamplona.quartz.nip34Git.repository.GitRepositoryEvent
class RepositoryContentSubAssembler(
val cache: ICacheProvider,
client: INostrClient,
allKeys: () -> Set<RepositoryQueryState>,
) : SingleSubEoseManager<RepositoryQueryState>(client, allKeys) {
@@ -44,7 +45,7 @@ class RepositoryContentSubAssembler(
val announcedRelays = repoEvent.relays().mapNotNull(RelayUrlNormalizer::normalizeOrNull)
val hintRelays =
if (announcedRelays.isEmpty()) {
LocalCache.relayHints.hintsForAddress(repoEvent.addressTag())
cache.relayHints.hintsForAddress(repoEvent.addressTag())
} else {
emptyList()
}
@@ -18,9 +18,10 @@
* 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.gitRepo.datasource
package com.vitorpamplona.amethyst.commons.relayClient.gitRepo
import com.vitorpamplona.amethyst.commons.model.AddressableNote
import com.vitorpamplona.amethyst.commons.model.cache.ICacheProvider
import com.vitorpamplona.amethyst.commons.relayClient.composeSubscriptionManagers.ComposeSubscriptionManager
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient
@@ -29,11 +30,12 @@ class RepositoryQueryState(
)
class RepositoryFilterAssembler(
cache: ICacheProvider,
client: INostrClient,
) : ComposeSubscriptionManager<RepositoryQueryState>() {
val group =
listOf(
RepositoryContentSubAssembler(client, ::allKeys),
RepositoryContentSubAssembler(cache, client, ::allKeys),
)
override fun invalidateKeys() = invalidateFilters()
@@ -18,7 +18,7 @@
* 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.gitRepo.datasource
package com.vitorpamplona.amethyst.commons.relayClient.gitRepo
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
@@ -18,7 +18,7 @@
* 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.home.datasource.nip22Comments
package com.vitorpamplona.amethyst.commons.relayClient.nip22Comments
import com.vitorpamplona.amethyst.commons.relayClient.subscriptions.ExplainedFilter
import com.vitorpamplona.amethyst.commons.relayClient.subscriptions.SubPurpose
@@ -18,13 +18,13 @@
* 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.podcasts.datasource
package com.vitorpamplona.amethyst.commons.relayClient.podcasts
import com.vitorpamplona.amethyst.commons.model.User
import com.vitorpamplona.amethyst.commons.model.cache.ICacheProvider
import com.vitorpamplona.amethyst.commons.relayClient.subscriptions.ExplainedFilter
import com.vitorpamplona.amethyst.commons.relayClient.subscriptions.SubPurpose
import com.vitorpamplona.amethyst.commons.relays.SincePerRelayMap
import com.vitorpamplona.amethyst.model.LocalCache
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
import com.vitorpamplona.quartz.nip78AppData.AppSpecificDataEvent
import com.vitorpamplona.quartz.nipXXPodcasting20.episode.Podcasting20EpisodeEvent
@@ -44,12 +44,13 @@ import com.vitorpamplona.quartz.nipXXPodcasting20.trailer.Podcasting20TrailerEve
* filter, since each episode/trailer carries its own `d` tag — a combined `#d` would match nothing.
*/
fun filterMyPodcast(
cache: ICacheProvider,
user: User,
since: SincePerRelayMap?,
): List<RelayBasedFilter> {
val relays =
user.outboxRelays()?.ifEmpty { null }
?: (user.allUsedRelays() + LocalCache.relayHints.hintsForKey(user.pubkeyHex))
?: (user.allUsedRelays() + cache.relayHints.hintsForKey(user.pubkeyHex))
val authors = listOf(user.pubkeyHex)
@@ -18,13 +18,13 @@
* 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.podcasts.datasource
package com.vitorpamplona.amethyst.commons.relayClient.podcasts
import com.vitorpamplona.amethyst.commons.model.User
import com.vitorpamplona.amethyst.commons.model.cache.ICacheProvider
import com.vitorpamplona.amethyst.commons.relayClient.subscriptions.ExplainedFilter
import com.vitorpamplona.amethyst.commons.relayClient.subscriptions.SubPurpose
import com.vitorpamplona.amethyst.commons.relays.SincePerRelayMap
import com.vitorpamplona.amethyst.model.LocalCache
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
import com.vitorpamplona.quartz.nip78AppData.AppSpecificDataEvent
import com.vitorpamplona.quartz.nipF4Podcasts.episode.PodcastEpisodeEvent
@@ -45,6 +45,7 @@ private val OnePodcastKinds =
)
fun filterOnePodcast(
cache: ICacheProvider,
user: User,
since: SincePerRelayMap?,
): List<RelayBasedFilter> {
@@ -52,7 +53,7 @@ fun filterOnePodcast(
// we've seen the key on plus stored hints when no NIP-65 list is known.
val relays =
user.outboxRelays()?.ifEmpty { null }
?: (user.allUsedRelays() + LocalCache.relayHints.hintsForKey(user.pubkeyHex))
?: (user.allUsedRelays() + cache.relayHints.hintsForKey(user.pubkeyHex))
return relays.flatMap { relay ->
listOf(
@@ -18,21 +18,23 @@
* 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.podcasts.datasource
package com.vitorpamplona.amethyst.commons.relayClient.podcasts
import com.vitorpamplona.amethyst.commons.model.cache.ICacheProvider
import com.vitorpamplona.amethyst.commons.relayClient.eoseManagers.PerUserEoseManager
import com.vitorpamplona.amethyst.commons.relays.SincePerRelayMap
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
class MyPodcastFeedSubAssembler(
val cache: ICacheProvider,
client: INostrClient,
allKeys: () -> Set<MyPodcastQueryState>,
) : PerUserEoseManager<MyPodcastQueryState>(client, allKeys) {
override fun updateFilter(
key: MyPodcastQueryState,
since: SincePerRelayMap?,
): List<RelayBasedFilter> = filterMyPodcast(user(key), since)
): List<RelayBasedFilter> = filterMyPodcast(cache, user(key), since)
override fun user(key: MyPodcastQueryState) = key.user
}
@@ -18,9 +18,10 @@
* 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.podcasts.datasource
package com.vitorpamplona.amethyst.commons.relayClient.podcasts
import com.vitorpamplona.amethyst.commons.model.User
import com.vitorpamplona.amethyst.commons.model.cache.ICacheProvider
import com.vitorpamplona.amethyst.commons.relayClient.composeSubscriptionManagers.ComposeSubscriptionManager
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient
@@ -31,11 +32,12 @@ class MyPodcastQueryState(
)
class MyPodcastFilterAssembler(
cache: ICacheProvider,
client: INostrClient,
) : ComposeSubscriptionManager<MyPodcastQueryState>() {
val group =
listOf(
MyPodcastFeedSubAssembler(client, ::allKeys),
MyPodcastFeedSubAssembler(cache, client, ::allKeys),
)
override fun invalidateKeys() = invalidateFilters()
@@ -18,21 +18,23 @@
* 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.podcasts.datasource
package com.vitorpamplona.amethyst.commons.relayClient.podcasts
import com.vitorpamplona.amethyst.commons.model.cache.ICacheProvider
import com.vitorpamplona.amethyst.commons.relayClient.eoseManagers.PerUserEoseManager
import com.vitorpamplona.amethyst.commons.relays.SincePerRelayMap
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
class OnePodcastFeedSubAssembler(
val cache: ICacheProvider,
client: INostrClient,
allKeys: () -> Set<OnePodcastQueryState>,
) : PerUserEoseManager<OnePodcastQueryState>(client, allKeys) {
override fun updateFilter(
key: OnePodcastQueryState,
since: SincePerRelayMap?,
): List<RelayBasedFilter> = filterOnePodcast(user(key), since)
): List<RelayBasedFilter> = filterOnePodcast(cache, user(key), since)
override fun user(key: OnePodcastQueryState) = key.user
}
@@ -18,9 +18,10 @@
* 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.podcasts.datasource
package com.vitorpamplona.amethyst.commons.relayClient.podcasts
import com.vitorpamplona.amethyst.commons.model.User
import com.vitorpamplona.amethyst.commons.model.cache.ICacheProvider
import com.vitorpamplona.amethyst.commons.relayClient.composeSubscriptionManagers.ComposeSubscriptionManager
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient
@@ -31,11 +32,12 @@ class OnePodcastQueryState(
)
class OnePodcastFilterAssembler(
cache: ICacheProvider,
client: INostrClient,
) : ComposeSubscriptionManager<OnePodcastQueryState>() {
val group =
listOf(
OnePodcastFeedSubAssembler(client, ::allKeys),
OnePodcastFeedSubAssembler(cache, client, ::allKeys),
)
override fun invalidateKeys() = invalidateFilters()
@@ -18,7 +18,7 @@
* 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.polls.results.datasources.subassembies
package com.vitorpamplona.amethyst.commons.relayClient.polls.results
import com.vitorpamplona.amethyst.commons.model.Note
import com.vitorpamplona.amethyst.commons.relayClient.subscriptions.ExplainedFilter
@@ -18,16 +18,15 @@
* 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.polls.results.datasources
package com.vitorpamplona.amethyst.commons.relayClient.polls.results
import androidx.compose.runtime.Stable
import com.vitorpamplona.amethyst.commons.model.IAccount
import com.vitorpamplona.amethyst.commons.model.cache.ICacheProvider
import com.vitorpamplona.amethyst.commons.relayClient.AccountScopedQuery
import com.vitorpamplona.amethyst.commons.relayClient.composeSubscriptionManagers.ComposeSubscriptionManager
import com.vitorpamplona.amethyst.commons.relayClient.eoseManagers.PerUniqueIdEoseManager
import com.vitorpamplona.amethyst.commons.relays.SincePerRelayMap
import com.vitorpamplona.amethyst.model.Account
import com.vitorpamplona.amethyst.model.LocalCache
import com.vitorpamplona.amethyst.ui.screen.loggedIn.polls.results.datasources.subassembies.filterPollResponses
import com.vitorpamplona.quartz.nip01Core.core.HexKey
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
@@ -36,7 +35,7 @@ import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
@Stable
class PollResponsesQueryState(
val pollId: HexKey,
override val account: Account,
override val account: IAccount,
) : AccountScopedQuery
/**
@@ -51,9 +50,10 @@ class PollResponsesQueryState(
*/
@Stable
class PollResponsesFilterAssembler(
cache: ICacheProvider,
client: INostrClient,
) : ComposeSubscriptionManager<PollResponsesQueryState>() {
val group = listOf(PollResponsesSubAssembler(client, ::allKeys))
val group = listOf(PollResponsesSubAssembler(cache, client, ::allKeys))
override fun invalidateKeys() = invalidateFilters()
@@ -63,6 +63,7 @@ class PollResponsesFilterAssembler(
}
class PollResponsesSubAssembler(
val cache: ICacheProvider,
client: INostrClient,
allKeys: () -> Set<PollResponsesQueryState>,
) : PerUniqueIdEoseManager<PollResponsesQueryState, HexKey>(client, allKeys) {
@@ -72,7 +73,7 @@ class PollResponsesSubAssembler(
): List<RelayBasedFilter>? {
// The poll event carries the relays to ask; on a deep link it may still be in flight, in
// which case there is nothing to ask yet and the filter re-assembles when it lands.
val poll = LocalCache.getNoteIfExists(key.pollId) ?: return null
val poll = cache.getNoteIfExists(key.pollId) ?: return null
return filterPollResponses(poll, since)
}
@@ -18,26 +18,27 @@
* 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.profile.datasource
package com.vitorpamplona.amethyst.commons.relayClient.profile
import com.vitorpamplona.amethyst.commons.model.User
import com.vitorpamplona.amethyst.commons.model.cache.ICacheProvider
import com.vitorpamplona.amethyst.commons.relayClient.subscriptions.ExplainedFilter
import com.vitorpamplona.amethyst.commons.relayClient.subscriptions.SubPurpose
import com.vitorpamplona.amethyst.commons.relays.SincePerRelayMap
import com.vitorpamplona.amethyst.model.LocalCache
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
import com.vitorpamplona.quartz.nip02FollowList.ContactListEvent
val UserProfileFollowersKinds = listOf(ContactListEvent.KIND)
fun filterUserProfileFollowers(
cache: ICacheProvider,
user: User,
since: SincePerRelayMap?,
): List<RelayBasedFilter> {
val relays =
user.inboxRelays()?.ifEmpty { null }
?: user.allUsedRelaysOrNull()
?: LocalCache.relayHints.hintsForKey(user.pubkeyHex)
?: cache.relayHints.hintsForKey(user.pubkeyHex)
return relays.map {
RelayBasedFilter(
@@ -18,7 +18,7 @@
* 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.profile.datasource
package com.vitorpamplona.amethyst.commons.relayClient.profile
import com.vitorpamplona.amethyst.commons.relayClient.subscriptions.ExplainedFilter
import com.vitorpamplona.amethyst.commons.relayClient.subscriptions.SubPurpose
@@ -18,7 +18,7 @@
* 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.profile.datasource
package com.vitorpamplona.amethyst.commons.relayClient.profile
import com.vitorpamplona.amethyst.commons.relayClient.subscriptions.ExplainedFilter
import com.vitorpamplona.amethyst.commons.relayClient.subscriptions.SubPurpose
@@ -18,13 +18,13 @@
* 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.profile.datasource
package com.vitorpamplona.amethyst.commons.relayClient.profile
import com.vitorpamplona.amethyst.commons.model.User
import com.vitorpamplona.amethyst.commons.model.cache.ICacheProvider
import com.vitorpamplona.amethyst.commons.relayClient.subscriptions.ExplainedFilter
import com.vitorpamplona.amethyst.commons.relayClient.subscriptions.SubPurpose
import com.vitorpamplona.amethyst.commons.relays.SincePerRelayMap
import com.vitorpamplona.amethyst.model.LocalCache
import com.vitorpamplona.quartz.experimental.profileGallery.ProfileGalleryEntryEvent
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
import com.vitorpamplona.quartz.nip53LiveActivities.clip.LiveActivitiesClipEvent
@@ -45,13 +45,14 @@ val UserProfileMediaKinds =
)
fun filterUserProfileMedia(
cache: ICacheProvider,
user: User,
since: SincePerRelayMap?,
): List<RelayBasedFilter> {
val relays =
user.outboxRelays()?.ifEmpty { null }
?: user.allUsedRelaysOrNull()
?: LocalCache.relayHints.hintsForKey(user.pubkeyHex)
?: cache.relayHints.hintsForKey(user.pubkeyHex)
return relays.flatMap { relay ->
listOf(
@@ -18,7 +18,7 @@
* 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.profile.datasource
package com.vitorpamplona.amethyst.commons.relayClient.profile
import com.vitorpamplona.amethyst.commons.relayClient.subscriptions.ExplainedFilter
import com.vitorpamplona.amethyst.commons.relayClient.subscriptions.SubPurpose
@@ -20,13 +20,13 @@
*/
@file:Suppress("DEPRECATION")
package com.vitorpamplona.amethyst.ui.screen.loggedIn.profile.datasource
package com.vitorpamplona.amethyst.commons.relayClient.profile
import com.vitorpamplona.amethyst.commons.model.User
import com.vitorpamplona.amethyst.commons.model.cache.ICacheProvider
import com.vitorpamplona.amethyst.commons.relayClient.subscriptions.ExplainedFilter
import com.vitorpamplona.amethyst.commons.relayClient.subscriptions.SubPurpose
import com.vitorpamplona.amethyst.commons.relays.SincePerRelayMap
import com.vitorpamplona.amethyst.model.LocalCache
import com.vitorpamplona.quartz.experimental.attestations.attestation.AttestationEvent
import com.vitorpamplona.quartz.experimental.birdstar.BirdDetectionEvent
import com.vitorpamplona.quartz.experimental.birdstar.BirdexEvent
@@ -92,12 +92,13 @@ val UserProfileAppKinds =
)
fun filterUserProfilePosts(
cache: ICacheProvider,
user: User,
since: SincePerRelayMap?,
): List<RelayBasedFilter> {
val relays =
user.outboxRelays()?.ifEmpty { null }
?: (user.allUsedRelays() + LocalCache.relayHints.hintsForKey(user.pubkeyHex))
?: (user.allUsedRelays() + cache.relayHints.hintsForKey(user.pubkeyHex))
return relays.flatMap { relay ->
listOf(
@@ -18,13 +18,13 @@
* 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.profile.datasource
package com.vitorpamplona.amethyst.commons.relayClient.profile
import com.vitorpamplona.amethyst.commons.model.User
import com.vitorpamplona.amethyst.commons.model.cache.ICacheProvider
import com.vitorpamplona.amethyst.commons.relayClient.subscriptions.ExplainedFilter
import com.vitorpamplona.amethyst.commons.relayClient.subscriptions.SubPurpose
import com.vitorpamplona.amethyst.commons.relays.SincePerRelayMap
import com.vitorpamplona.amethyst.model.LocalCache
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.zap.Bolt12ZapEvent
@@ -33,13 +33,14 @@ import com.vitorpamplona.quartz.nipBCOnchainZaps.zap.OnchainZapEvent
val UserProfileZapReceiverKinds = listOf(LnZapEvent.KIND, OnchainZapEvent.KIND, Bolt12ZapEvent.KIND)
fun filterUserProfileZapsReceived(
cache: ICacheProvider,
user: User,
since: SincePerRelayMap?,
): List<RelayBasedFilter> {
val relays =
user.inboxRelays()?.ifEmpty { null }
?: user.allUsedRelaysOrNull()
?: LocalCache.relayHints.hintsForKey(user.pubkeyHex)
?: cache.relayHints.hintsForKey(user.pubkeyHex)
return relays.map { relay ->
RelayBasedFilter(
@@ -18,9 +18,10 @@
* 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.profile.datasource
package com.vitorpamplona.amethyst.commons.relayClient.profile
import com.vitorpamplona.amethyst.commons.model.User
import com.vitorpamplona.amethyst.commons.model.cache.ICacheProvider
import com.vitorpamplona.amethyst.commons.relayClient.composeSubscriptionManagers.ComposeSubscriptionManager
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient
@@ -32,16 +33,17 @@ class UserProfileQueryState(
)
class UserProfileFilterAssembler(
cache: ICacheProvider,
client: INostrClient,
) : ComposeSubscriptionManager<UserProfileQueryState>() {
val group =
listOf(
// 5 subs per visible user profile screen.
UserProfileMetadataFilterSubAssembler(client, ::allKeys),
UserProfilePostsFilterSubAssembler(client, ::allKeys),
UserProfileMediaFilterSubAssembler(client, ::allKeys),
UserProfileFollowersFilterSubAssembler(client, ::allKeys),
UserProfileZapsFilterSubAssembler(client, ::allKeys),
UserProfileMetadataFilterSubAssembler(cache, client, ::allKeys),
UserProfilePostsFilterSubAssembler(cache, client, ::allKeys),
UserProfileMediaFilterSubAssembler(cache, client, ::allKeys),
UserProfileFollowersFilterSubAssembler(cache, client, ::allKeys),
UserProfileZapsFilterSubAssembler(cache, client, ::allKeys),
)
override fun invalidateFilters() = group.forEach { it.invalidateFilters() }
@@ -18,7 +18,7 @@
* 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.profile.datasource
package com.vitorpamplona.amethyst.commons.relayClient.profile
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
@@ -18,14 +18,16 @@
* 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.profile.datasource
package com.vitorpamplona.amethyst.commons.relayClient.profile
import com.vitorpamplona.amethyst.commons.model.cache.ICacheProvider
import com.vitorpamplona.amethyst.commons.relayClient.eoseManagers.PerUserEoseManager
import com.vitorpamplona.amethyst.commons.relays.SincePerRelayMap
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
class UserProfileFollowersFilterSubAssembler(
val cache: ICacheProvider,
client: INostrClient,
allKeys: () -> Set<UserProfileQueryState>,
) : PerUserEoseManager<UserProfileQueryState>(client, allKeys) {
@@ -34,7 +36,7 @@ class UserProfileFollowersFilterSubAssembler(
since: SincePerRelayMap?,
): List<RelayBasedFilter> =
if (key.loadFollowers) {
filterUserProfileFollowers(user(key), since)
filterUserProfileFollowers(cache, user(key), since)
} else {
emptyList()
}
@@ -18,21 +18,23 @@
* 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.profile.datasource
package com.vitorpamplona.amethyst.commons.relayClient.profile
import com.vitorpamplona.amethyst.commons.model.cache.ICacheProvider
import com.vitorpamplona.amethyst.commons.relayClient.eoseManagers.PerUserEoseManager
import com.vitorpamplona.amethyst.commons.relays.SincePerRelayMap
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
class UserProfileMediaFilterSubAssembler(
val cache: ICacheProvider,
client: INostrClient,
allKeys: () -> Set<UserProfileQueryState>,
) : PerUserEoseManager<UserProfileQueryState>(client, allKeys) {
override fun updateFilter(
key: UserProfileQueryState,
since: SincePerRelayMap?,
): List<RelayBasedFilter> = filterUserProfileMedia(user(key), since)
): List<RelayBasedFilter> = filterUserProfileMedia(cache, user(key), since)
override fun user(key: UserProfileQueryState) = key.user
}
@@ -18,16 +18,17 @@
* 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.profile.datasource
package com.vitorpamplona.amethyst.commons.relayClient.profile
import com.vitorpamplona.amethyst.commons.model.cache.ICacheProvider
import com.vitorpamplona.amethyst.commons.relayClient.eoseManagers.SingleSubEoseManager
import com.vitorpamplona.amethyst.commons.relays.SincePerRelayMap
import com.vitorpamplona.amethyst.model.LocalCache
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
import com.vitorpamplona.quartz.utils.mapOfSet
class UserProfileMetadataFilterSubAssembler(
val cache: ICacheProvider,
client: INostrClient,
allKeys: () -> Set<UserProfileQueryState>,
) : SingleSubEoseManager<UserProfileQueryState>(client, allKeys) {
@@ -41,7 +42,7 @@ class UserProfileMetadataFilterSubAssembler(
val relays =
user.outboxRelays()?.ifEmpty { null }
?: user.allUsedRelaysOrNull()
?: LocalCache.relayHints.hintsForKey(user.pubkeyHex)
?: cache.relayHints.hintsForKey(user.pubkeyHex)
relays.forEach { relay ->
add(relay, user.pubkeyHex)
@@ -18,21 +18,23 @@
* 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.profile.datasource
package com.vitorpamplona.amethyst.commons.relayClient.profile
import com.vitorpamplona.amethyst.commons.model.cache.ICacheProvider
import com.vitorpamplona.amethyst.commons.relayClient.eoseManagers.PerUserEoseManager
import com.vitorpamplona.amethyst.commons.relays.SincePerRelayMap
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
class UserProfilePostsFilterSubAssembler(
val cache: ICacheProvider,
client: INostrClient,
allKeys: () -> Set<UserProfileQueryState>,
) : PerUserEoseManager<UserProfileQueryState>(client, allKeys) {
override fun updateFilter(
key: UserProfileQueryState,
since: SincePerRelayMap?,
): List<RelayBasedFilter> = filterUserProfilePosts(user(key), since)
): List<RelayBasedFilter> = filterUserProfilePosts(cache, user(key), since)
override fun user(key: UserProfileQueryState) = key.user
}
@@ -18,14 +18,16 @@
* 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.profile.datasource
package com.vitorpamplona.amethyst.commons.relayClient.profile
import com.vitorpamplona.amethyst.commons.model.cache.ICacheProvider
import com.vitorpamplona.amethyst.commons.relayClient.eoseManagers.PerUserEoseManager
import com.vitorpamplona.amethyst.commons.relays.SincePerRelayMap
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
class UserProfileZapsFilterSubAssembler(
val cache: ICacheProvider,
client: INostrClient,
allKeys: () -> Set<UserProfileQueryState>,
) : PerUserEoseManager<UserProfileQueryState>(client, allKeys) {
@@ -35,7 +37,7 @@ class UserProfileZapsFilterSubAssembler(
): List<RelayBasedFilter> =
if (key.loadZapsReceived) {
listOfNotNull(
filterUserProfileZapsReceived(user(key), since),
filterUserProfileZapsReceived(cache, user(key), since),
).flatten()
} else {
emptyList()
@@ -18,7 +18,7 @@
* 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.relay.datasource
package com.vitorpamplona.amethyst.commons.relayClient.relay
import com.vitorpamplona.amethyst.commons.relayClient.subscriptions.ExplainedFilter
import com.vitorpamplona.amethyst.commons.relayClient.subscriptions.SubPurpose
@@ -18,7 +18,7 @@
* 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.relay.datasource
package com.vitorpamplona.amethyst.commons.relayClient.relay
import com.vitorpamplona.amethyst.commons.relayClient.composeSubscriptionManagers.ComposeSubscriptionManager
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient
@@ -18,7 +18,7 @@
* 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.relay.datasource
package com.vitorpamplona.amethyst.commons.relayClient.relay
import com.vitorpamplona.amethyst.commons.relayClient.eoseManagers.PerUniqueIdEoseManager
import com.vitorpamplona.amethyst.commons.relays.SincePerRelayMap
@@ -18,7 +18,7 @@
* 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.relays.datasource
package com.vitorpamplona.amethyst.commons.relayClient.relays
import com.vitorpamplona.amethyst.commons.relayClient.composeSubscriptionManagers.ComposeSubscriptionManager
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient
@@ -18,7 +18,7 @@
* 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.relays.datasource
package com.vitorpamplona.amethyst.commons.relayClient.relays
import com.vitorpamplona.amethyst.commons.relayClient.eoseManagers.PerUniqueIdEoseManager
import com.vitorpamplona.amethyst.commons.relayClient.subscriptions.ExplainedFilter
@@ -18,7 +18,7 @@
* 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.threadview.datasources.subassembies
package com.vitorpamplona.amethyst.commons.relayClient.thread
import com.vitorpamplona.amethyst.commons.model.AddressableNote
import com.vitorpamplona.amethyst.commons.model.Note
@@ -18,34 +18,35 @@
* 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.threadview.datasources.subassembies
package com.vitorpamplona.amethyst.commons.relayClient.thread
import com.vitorpamplona.amethyst.commons.model.AddressableNote
import com.vitorpamplona.amethyst.commons.model.ThreadAssembler
import com.vitorpamplona.amethyst.commons.model.cache.ICacheProvider
import com.vitorpamplona.amethyst.commons.relayClient.event.loaders.filterMissingAddressables
import com.vitorpamplona.amethyst.commons.relayClient.event.loaders.filterMissingEvents
import com.vitorpamplona.amethyst.commons.relayClient.event.loaders.potentialRelaysToFindAddress
import com.vitorpamplona.amethyst.commons.relayClient.event.loaders.potentialRelaysToFindEvent
import com.vitorpamplona.amethyst.model.LocalCache
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
import com.vitorpamplona.quartz.utils.mapOfSet
fun filterMissingEventsForThread(
cache: ICacheProvider,
threadInfo: ThreadAssembler.ThreadInfo,
defaultRelays: Set<NormalizedRelayUrl>,
): List<RelayBasedFilter> {
val missingEvents =
mapOfSet {
if (threadInfo.root.event == null && threadInfo.root !is AddressableNote) {
potentialRelaysToFindEvent(LocalCache, threadInfo.root).ifEmpty { defaultRelays }.forEach { relayUrl ->
potentialRelaysToFindEvent(cache, threadInfo.root).ifEmpty { defaultRelays }.forEach { relayUrl ->
add(relayUrl, threadInfo.root.idHex)
}
}
threadInfo.allNotes.forEach {
if (it !is AddressableNote && it.event == null) {
potentialRelaysToFindEvent(LocalCache, it).ifEmpty { defaultRelays }.forEach { relayUrl ->
potentialRelaysToFindEvent(cache, it).ifEmpty { defaultRelays }.forEach { relayUrl ->
add(relayUrl, it.idHex)
}
}
@@ -60,14 +61,14 @@ fun filterMissingEventsForThread(
// note's aTag idHex into the hex-keyed event-hint index, which throws
// on the non-hex string and kills the whole filter build — leaving a
// thread opened on an uncached naddr permanently unfetched.
potentialRelaysToFindAddress(LocalCache, rootNote).ifEmpty { defaultRelays }.forEach { relayUrl ->
potentialRelaysToFindAddress(cache, rootNote).ifEmpty { defaultRelays }.forEach { relayUrl ->
add(relayUrl, rootNote.address)
}
}
threadInfo.allNotes.forEach {
if (it is AddressableNote && it.event == null) {
potentialRelaysToFindAddress(LocalCache, it).ifEmpty { defaultRelays }.forEach { relayUrl ->
potentialRelaysToFindAddress(cache, it).ifEmpty { defaultRelays }.forEach { relayUrl ->
add(relayUrl, it.address)
}
}
@@ -18,12 +18,12 @@
* 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.url.datasource
package com.vitorpamplona.amethyst.commons.relayClient.url
import com.vitorpamplona.amethyst.commons.relayClient.nip22Comments.CommentKinds
import com.vitorpamplona.amethyst.commons.relayClient.subscriptions.ExplainedFilter
import com.vitorpamplona.amethyst.commons.relayClient.subscriptions.SubPurpose
import com.vitorpamplona.amethyst.commons.relays.SincePerRelayMap
import com.vitorpamplona.amethyst.ui.screen.loggedIn.home.datasource.nip22Comments.CommentKinds
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
import com.vitorpamplona.quartz.nip73ExternalIds.urls.UrlId
@@ -18,7 +18,7 @@
* 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.url.datasource
package com.vitorpamplona.amethyst.commons.relayClient.url
import com.vitorpamplona.amethyst.commons.relayClient.eoseManagers.PerUniqueIdEoseManager
import com.vitorpamplona.amethyst.commons.relays.SincePerRelayMap
@@ -18,7 +18,7 @@
* 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.url.datasource
package com.vitorpamplona.amethyst.commons.relayClient.url
import androidx.compose.runtime.Stable
import com.vitorpamplona.amethyst.commons.relayClient.composeSubscriptionManagers.ComposeSubscriptionManager
@@ -18,15 +18,15 @@
* 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.wallet.datasource
package com.vitorpamplona.amethyst.commons.relayClient.wallet
import com.vitorpamplona.amethyst.commons.model.User
import com.vitorpamplona.amethyst.commons.model.cache.ICacheProvider
import com.vitorpamplona.amethyst.commons.relayClient.composeSubscriptionManagers.ComposeSubscriptionManager
import com.vitorpamplona.amethyst.commons.relayClient.eoseManagers.SingleSubEoseManager
import com.vitorpamplona.amethyst.commons.relayClient.subscriptions.ExplainedFilter
import com.vitorpamplona.amethyst.commons.relayClient.subscriptions.SubPurpose
import com.vitorpamplona.amethyst.commons.relays.SincePerRelayMap
import com.vitorpamplona.amethyst.model.LocalCache
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
@@ -97,6 +97,7 @@ private fun filterOnchainZaps(
}
class OnchainZapsFilterSubAssembler(
val cache: ICacheProvider,
client: INostrClient,
allKeys: () -> Set<OnchainZapsQueryState>,
) : SingleSubEoseManager<OnchainZapsQueryState>(client, allKeys) {
@@ -110,7 +111,7 @@ class OnchainZapsFilterSubAssembler(
user.inboxRelays()?.ifEmpty { null }
?: user.outboxRelays()?.ifEmpty { null }
?: user.allUsedRelaysOrNull()
?: LocalCache.relayHints.hintsForKey(user.pubkeyHex)
?: cache.relayHints.hintsForKey(user.pubkeyHex)
if (relays.isEmpty()) return emptyList()
// Take the tightest window across all live keys — if any subscriber
@@ -128,9 +129,10 @@ class OnchainZapsFilterSubAssembler(
}
class OnchainZapsFilterAssembler(
cache: ICacheProvider,
client: INostrClient,
) : ComposeSubscriptionManager<OnchainZapsQueryState>() {
private val sub = OnchainZapsFilterSubAssembler(client, ::allKeys)
private val sub = OnchainZapsFilterSubAssembler(cache, client, ::allKeys)
override fun invalidateFilters() = sub.invalidateFilters()
@@ -18,13 +18,13 @@
* 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.url.datasource
package com.vitorpamplona.amethyst.commons.relayClient.url
import com.vitorpamplona.amethyst.ui.screen.loggedIn.home.datasource.nip22Comments.CommentKinds
import com.vitorpamplona.amethyst.commons.relayClient.nip22Comments.CommentKinds
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Test
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertTrue
class FilterPostsByUrlTest {
@Test