mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2026-08-09 16:14:40 +00:00
refactor: rename relay-group REQ assemblers by when they run
The assembler names didn't say when each is active — most confusingly, a "Threads" assembler with no matching "chat" one, because group chat (kind-9) is served by the shared `channel` assembler, not a group-specific one. Rename the four group-specific families for their surface, and document that chat has no dedicated assembler: relayGroupDirectory -> relayGroupsOnRelay (browsing one relay's channels) relayGroupRoster -> relayGroupMyJoinedGroups (metadata+rosters of joined groups) relayGroupThreads -> relayGroupThreadFeed (a group's forum-threads tab) relayGroupPreview -> relayGroupWarmup (prefetch before a group opens) Each family's FilterAssembler / QueryState / SubAssembler / Subscription + file renamed to match. relayGroupsDiscovery is left as-is: it already names the Discover feed and shares its token namespace with the screen/DAL/settings, so a rename would either collide with RelayGroupDiscoveryFeedFilter or corrupt those. Pure rename; no behavior change. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01B5MLY4hq5LXJ2D5WeLRyXj
This commit is contained in:
+18
-13
@@ -37,11 +37,11 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.badges.profile.datasource.P
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.calendars.datasource.CalendarsFilterAssembler
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.privateDM.datasource.ChatroomFilterAssembler
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.publicChannels.datasource.ChannelFilterAssembler
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.publicChannels.relayGroup.datasource.RelayGroupDirectoryFilterAssembler
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.publicChannels.relayGroup.datasource.RelayGroupPreviewFilterAssembler
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.publicChannels.relayGroup.datasource.RelayGroupRosterFilterAssembler
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.publicChannels.relayGroup.datasource.RelayGroupThreadsFilterAssembler
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.publicChannels.relayGroup.datasource.RelayGroupMyJoinedGroupsFilterAssembler
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.publicChannels.relayGroup.datasource.RelayGroupThreadFeedFilterAssembler
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.publicChannels.relayGroup.datasource.RelayGroupWarmupFilterAssembler
|
||||
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
|
||||
@@ -118,11 +118,16 @@ class RelaySubscriptionsCoordinator(
|
||||
|
||||
// active depending on the screen.
|
||||
val channel = ChannelFilterAssembler(client)
|
||||
val relayGroupDirectory = RelayGroupDirectoryFilterAssembler(client)
|
||||
val relayGroupRoster = RelayGroupRosterFilterAssembler(client)
|
||||
val relayGroupThreads = RelayGroupThreadsFilterAssembler(client)
|
||||
val relayGroupPreview = RelayGroupPreviewFilterAssembler(client)
|
||||
val relayGroupsDiscovery = RelayGroupsDiscoveryFilterAssembler(client)
|
||||
|
||||
// NIP-29 relay-group REQ assemblers, each named for WHEN it runs. There is deliberately no
|
||||
// "group chat" assembler: a group's kind-9 chat timeline is served by the shared [channel]
|
||||
// assembler above (same as NIP-28 public chats), so only the group-specific surfaces get their
|
||||
// own here.
|
||||
val relayGroupsOnRelay = RelayGroupsOnRelayFilterAssembler(client) // browsing one relay's channel list
|
||||
val relayGroupMyJoinedGroups = RelayGroupMyJoinedGroupsFilterAssembler(client) // metadata+rosters of groups I've joined
|
||||
val relayGroupThreadFeed = RelayGroupThreadFeedFilterAssembler(client) // a group's forum-threads tab
|
||||
val relayGroupWarmup = RelayGroupWarmupFilterAssembler(client) // prefetching a group before it's opened
|
||||
val relayGroupsDiscovery = RelayGroupsDiscoveryFilterAssembler(client) // the cross-relay Discover feed
|
||||
val chatroom = ChatroomFilterAssembler(client)
|
||||
val community = CommunityFilterAssembler(client)
|
||||
val gitRepository = RepositoryFilterAssembler(client)
|
||||
@@ -184,10 +189,10 @@ class RelaySubscriptionsCoordinator(
|
||||
|
||||
val all =
|
||||
listOf(
|
||||
relayGroupDirectory,
|
||||
relayGroupRoster,
|
||||
relayGroupThreads,
|
||||
relayGroupPreview,
|
||||
relayGroupsOnRelay,
|
||||
relayGroupMyJoinedGroups,
|
||||
relayGroupThreadFeed,
|
||||
relayGroupWarmup,
|
||||
relayGroupsDiscovery,
|
||||
account,
|
||||
accountForeground,
|
||||
|
||||
@@ -53,7 +53,7 @@ import com.vitorpamplona.amethyst.ui.navigation.navs.INav
|
||||
import com.vitorpamplona.amethyst.ui.navigation.routes.Route
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.publicChannels.relayGroup.LoadRelayGroupChannel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.publicChannels.relayGroup.datasource.RelayGroupPreviewSubscription
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.publicChannels.relayGroup.datasource.RelayGroupWarmupSubscription
|
||||
import com.vitorpamplona.amethyst.ui.stringRes
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.displayUrl
|
||||
import com.vitorpamplona.quartz.nip29RelayGroups.GroupInviteLink
|
||||
@@ -93,7 +93,7 @@ private fun RelayGroupCardContent(
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: INav,
|
||||
) {
|
||||
RelayGroupPreviewSubscription(baseChannel, accountViewModel.dataSources().relayGroupPreview, accountViewModel)
|
||||
RelayGroupWarmupSubscription(baseChannel, accountViewModel.dataSources().relayGroupWarmup, accountViewModel)
|
||||
|
||||
// Recompose in place when the relay-signed metadata / roster changes.
|
||||
val channelState by baseChannel
|
||||
|
||||
+2
-2
@@ -29,7 +29,7 @@ import com.vitorpamplona.amethyst.ui.navigation.bottombars.NavBarItem
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.articles.datasource.ArticlesFilterAssemblerSubscription
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.badges.datasource.BadgesFilterAssemblerSubscription
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.calendars.datasource.CalendarsFilterAssemblerSubscription
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.publicChannels.relayGroup.datasource.RelayGroupRosterSubscription
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.publicChannels.relayGroup.datasource.RelayGroupMyJoinedGroupsSubscription
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.rooms.datasource.ChatroomListFilterAssemblerSubscription
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.communities.list.datasource.CommunitiesListFilterAssemblerSubscription
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.discover.datasource.DiscoveryFilterAssemblerSubscription
|
||||
@@ -132,7 +132,7 @@ private fun PreloadFor(
|
||||
|
||||
NavBarItem.PUBLIC_CHATS -> PublicChatsFilterAssemblerSubscription(accountViewModel)
|
||||
|
||||
NavBarItem.RELAY_GROUPS -> RelayGroupRosterSubscription(accountViewModel.dataSources().relayGroupRoster, accountViewModel)
|
||||
NavBarItem.RELAY_GROUPS -> RelayGroupMyJoinedGroupsSubscription(accountViewModel.dataSources().relayGroupMyJoinedGroups, accountViewModel)
|
||||
|
||||
NavBarItem.FOLLOW_PACKS -> FollowPacksFilterAssemblerSubscription(accountViewModel)
|
||||
|
||||
|
||||
+3
-3
@@ -60,7 +60,7 @@ import com.vitorpamplona.amethyst.ui.navigation.routes.Route
|
||||
import com.vitorpamplona.amethyst.ui.navigation.routes.routeFor
|
||||
import com.vitorpamplona.amethyst.ui.navigation.topbars.TopBarExtensibleWithBackButton
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.publicChannels.relayGroup.datasource.RelayGroupDirectorySubscription
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.publicChannels.relayGroup.datasource.RelayGroupsOnRelaySubscription
|
||||
import com.vitorpamplona.amethyst.ui.stringRes
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.RelayUrlNormalizer
|
||||
@@ -70,7 +70,7 @@ import com.vitorpamplona.quartz.nip29RelayGroups.metadata.GroupMetadataEvent
|
||||
/**
|
||||
* Lists every channel a relay hosts (its kind 39000-39003 directory), so the user
|
||||
* can browse and open channels on that relay. The relay's directory is streamed by
|
||||
* [RelayGroupDirectorySubscription] and consumed into per-group channels; this
|
||||
* [RelayGroupsOnRelaySubscription] and consumed into per-group channels; this
|
||||
* screen reads them back for the relay and renders them.
|
||||
*/
|
||||
@Composable
|
||||
@@ -81,7 +81,7 @@ fun RelayGroupChannelListScreen(
|
||||
) {
|
||||
val relay = remember(relayUrl) { RelayUrlNormalizer.normalizeOrNull(relayUrl) } ?: return
|
||||
|
||||
RelayGroupDirectorySubscription(relay, accountViewModel.dataSources().relayGroupDirectory, accountViewModel)
|
||||
RelayGroupsOnRelaySubscription(relay, accountViewModel.dataSources().relayGroupsOnRelay, accountViewModel)
|
||||
|
||||
// Re-read the relay's channels whenever a group-metadata (kind 39000) event lands in
|
||||
// the cache — driven by LocalCache.observeEvents rather than a timer, so the list
|
||||
|
||||
+5
-5
@@ -75,8 +75,8 @@ import com.vitorpamplona.amethyst.ui.navigation.topbars.UserDrawerSearchTopBar
|
||||
import com.vitorpamplona.amethyst.ui.note.UserPicture
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.publicChannels.relayGroup.dal.relayGroupDiscoveryChannelFor
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.publicChannels.relayGroup.datasource.RelayGroupPreviewSubscription
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.publicChannels.relayGroup.datasource.RelayGroupRosterSubscription
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.publicChannels.relayGroup.datasource.RelayGroupMyJoinedGroupsSubscription
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.publicChannels.relayGroup.datasource.RelayGroupWarmupSubscription
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.publicChannels.relayGroup.datasource.RelayGroupsDiscoveryFilterAssemblerSubscription
|
||||
import com.vitorpamplona.amethyst.ui.stringRes
|
||||
import com.vitorpamplona.amethyst.ui.theme.FeedPadding
|
||||
@@ -116,7 +116,7 @@ fun RelayGroupDiscoveryScreen(
|
||||
RelayGroupsDiscoveryFilterAssemblerSubscription(accountViewModel)
|
||||
// Keep the joined groups' metadata + rosters live so the "My Groups" filter can list them
|
||||
// (their host relays aren't fetched by the discovery filter set).
|
||||
RelayGroupRosterSubscription(accountViewModel.dataSources().relayGroupRoster, accountViewModel)
|
||||
RelayGroupMyJoinedGroupsSubscription(accountViewModel.dataSources().relayGroupMyJoinedGroups, accountViewModel)
|
||||
|
||||
DisappearingScaffold(
|
||||
isInvertedLayout = false,
|
||||
@@ -242,7 +242,7 @@ private fun RelayGroupDiscoveryRow(
|
||||
// Prefetch the group's recent content so opening the card lands on a populated screen. The
|
||||
// metadata/rosters are already streaming from the directory subscription, so only ask for
|
||||
// content here (contentOnly) instead of re-requesting 39000-39003 per visible row.
|
||||
RelayGroupPreviewSubscription(baseChannel, accountViewModel.dataSources().relayGroupPreview, accountViewModel, contentOnly = true)
|
||||
RelayGroupWarmupSubscription(baseChannel, accountViewModel.dataSources().relayGroupWarmup, accountViewModel, contentOnly = true)
|
||||
|
||||
val channelState by baseChannel
|
||||
.flow()
|
||||
@@ -535,7 +535,7 @@ private fun FollowsInGroupRow(
|
||||
|
||||
/**
|
||||
* Display cap for the loaded-message counter — kept in step with the discovery preview's fetch
|
||||
* limit (RELAY_GROUP_PREVIEW_LIMIT), so a chat that returns the full page reads as "50+ messages".
|
||||
* limit (RELAY_GROUP_WARMUP_LIMIT), so a chat that returns the full page reads as "50+ messages".
|
||||
*/
|
||||
private const val DISCOVERY_MESSAGE_CAP = 50
|
||||
|
||||
|
||||
+2
-2
@@ -63,7 +63,7 @@ import com.vitorpamplona.amethyst.ui.navigation.topbars.TopBarExtensibleWithBack
|
||||
import com.vitorpamplona.amethyst.ui.note.UserPicture
|
||||
import com.vitorpamplona.amethyst.ui.note.UsernameDisplay
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.publicChannels.relayGroup.datasource.RelayGroupPreviewSubscription
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.publicChannels.relayGroup.datasource.RelayGroupWarmupSubscription
|
||||
import com.vitorpamplona.amethyst.ui.stringRes
|
||||
import com.vitorpamplona.amethyst.ui.theme.Size35dp
|
||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
@@ -107,7 +107,7 @@ private fun RelayGroupMembers(
|
||||
// standalone screen is open. observeChannel alone does NOT do this for a relay group
|
||||
// (its finder only handles public-chat / live-activity channels), so without this the
|
||||
// screen would only show whatever the chat screen happened to cache.
|
||||
RelayGroupPreviewSubscription(baseChannel, accountViewModel.dataSources().relayGroupPreview, accountViewModel)
|
||||
RelayGroupWarmupSubscription(baseChannel, accountViewModel.dataSources().relayGroupWarmup, accountViewModel)
|
||||
|
||||
// Recompose when the relay-signed roster (39001/39002) changes.
|
||||
val channelState by observeChannel(baseChannel, accountViewModel)
|
||||
|
||||
+2
-2
@@ -69,7 +69,7 @@ import com.vitorpamplona.amethyst.ui.navigation.routes.Route
|
||||
import com.vitorpamplona.amethyst.ui.navigation.topbars.CreatingTopBar
|
||||
import com.vitorpamplona.amethyst.ui.navigation.topbars.SavingTopBar
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.publicChannels.relayGroup.datasource.RelayGroupPreviewSubscription
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.publicChannels.relayGroup.datasource.RelayGroupWarmupSubscription
|
||||
import com.vitorpamplona.amethyst.ui.stringRes
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.RelayUrlNormalizer
|
||||
import com.vitorpamplona.quartz.nip29RelayGroups.GroupId
|
||||
@@ -115,7 +115,7 @@ fun RelayGroupEditScreen(
|
||||
|
||||
LoadRelayGroupChannel(groupId, accountViewModel) { channel ->
|
||||
// Keep the relay-signed metadata fresh while editing so a late load prefills.
|
||||
RelayGroupPreviewSubscription(channel, accountViewModel.dataSources().relayGroupPreview, accountViewModel)
|
||||
RelayGroupWarmupSubscription(channel, accountViewModel.dataSources().relayGroupWarmup, accountViewModel)
|
||||
|
||||
val channelState by channel
|
||||
.flow()
|
||||
|
||||
+3
-3
@@ -58,7 +58,7 @@ import com.vitorpamplona.amethyst.ui.navigation.topbars.TopBarExtensibleWithBack
|
||||
import com.vitorpamplona.amethyst.ui.note.UserPicture
|
||||
import com.vitorpamplona.amethyst.ui.note.UsernameDisplay
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.publicChannels.relayGroup.datasource.RelayGroupThreadsSubscription
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.publicChannels.relayGroup.datasource.RelayGroupThreadFeedSubscription
|
||||
import com.vitorpamplona.amethyst.ui.stringRes
|
||||
import com.vitorpamplona.amethyst.ui.theme.Size35dp
|
||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
@@ -69,7 +69,7 @@ import com.vitorpamplona.quartz.nip7DThreads.ThreadEvent
|
||||
/**
|
||||
* A group's forum-style threads (kind 11) — the secondary content type kept out of
|
||||
* the kind-9 chat feed. Streams the group's threads + their comments via
|
||||
* [RelayGroupThreadsSubscription]; tapping a thread opens the generic thread view
|
||||
* [RelayGroupThreadFeedSubscription]; tapping a thread opens the generic thread view
|
||||
* ([Route.Note]) with its comment tree. Members can start a new thread.
|
||||
*/
|
||||
@Composable
|
||||
@@ -93,7 +93,7 @@ private fun RelayGroupThreads(
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: INav,
|
||||
) {
|
||||
RelayGroupThreadsSubscription(channel, accountViewModel.dataSources().relayGroupThreads, accountViewModel)
|
||||
RelayGroupThreadFeedSubscription(channel, accountViewModel.dataSources().relayGroupThreadFeed, accountViewModel)
|
||||
|
||||
val threads by channel.threads.collectAsStateWithLifecycle()
|
||||
|
||||
|
||||
+1
-1
@@ -88,7 +88,7 @@ class RelayGroupDiscoveryFeedFilter(
|
||||
*
|
||||
* These live on their host relays (from kind 10009), not my outbox, so the standard
|
||||
* [TopFilter.Mine] relay-set resolution wouldn't reach them. The joined groups' metadata +
|
||||
* rosters are kept in cache by RelayGroupRosterSubscription mounted on the screen.
|
||||
* rosters are kept in cache by RelayGroupMyJoinedGroupsSubscription mounted on the screen.
|
||||
*/
|
||||
private fun isMine(): Boolean = followList() is TopFilter.Mine
|
||||
|
||||
|
||||
+9
-9
@@ -33,7 +33,7 @@ import com.vitorpamplona.quartz.nip29RelayGroups.metadata.GroupMembersEvent
|
||||
import com.vitorpamplona.quartz.nip29RelayGroups.metadata.GroupMetadataEvent
|
||||
|
||||
/** One screen's request to keep the roster of the user's joined groups fresh. */
|
||||
class RelayGroupRosterQueryState(
|
||||
class RelayGroupMyJoinedGroupsQueryState(
|
||||
val account: Account,
|
||||
)
|
||||
|
||||
@@ -59,12 +59,12 @@ private val RELAY_GROUP_ROSTER_KINDS =
|
||||
* One subscription per host relay, scoped by `#d` to just that relay's joined
|
||||
* group ids — so we don't pull a relay's whole directory, only what we're in.
|
||||
*/
|
||||
class RelayGroupRosterFilterAssembler(
|
||||
class RelayGroupMyJoinedGroupsFilterAssembler(
|
||||
client: INostrClient,
|
||||
) : ComposeSubscriptionManager<RelayGroupRosterQueryState>() {
|
||||
) : ComposeSubscriptionManager<RelayGroupMyJoinedGroupsQueryState>() {
|
||||
val group =
|
||||
listOf(
|
||||
RelayGroupRosterSubAssembler(client, ::allKeys),
|
||||
RelayGroupMyJoinedGroupsSubAssembler(client, ::allKeys),
|
||||
)
|
||||
|
||||
override fun invalidateKeys() = invalidateFilters()
|
||||
@@ -74,12 +74,12 @@ class RelayGroupRosterFilterAssembler(
|
||||
override fun destroy() = group.forEach { it.destroy() }
|
||||
}
|
||||
|
||||
class RelayGroupRosterSubAssembler(
|
||||
class RelayGroupMyJoinedGroupsSubAssembler(
|
||||
client: INostrClient,
|
||||
allKeys: () -> Set<RelayGroupRosterQueryState>,
|
||||
) : PerUniqueIdEoseManager<RelayGroupRosterQueryState, Account>(client, allKeys) {
|
||||
allKeys: () -> Set<RelayGroupMyJoinedGroupsQueryState>,
|
||||
) : PerUniqueIdEoseManager<RelayGroupMyJoinedGroupsQueryState, Account>(client, allKeys) {
|
||||
override fun updateFilter(
|
||||
key: RelayGroupRosterQueryState,
|
||||
key: RelayGroupMyJoinedGroupsQueryState,
|
||||
since: SincePerRelayMap?,
|
||||
): List<RelayBasedFilter>? {
|
||||
val joined = key.account.relayGroupList.liveRelayGroupList.value
|
||||
@@ -102,5 +102,5 @@ class RelayGroupRosterSubAssembler(
|
||||
}
|
||||
}
|
||||
|
||||
override fun id(key: RelayGroupRosterQueryState) = key.account
|
||||
override fun id(key: RelayGroupMyJoinedGroupsQueryState) = key.account
|
||||
}
|
||||
+3
-3
@@ -39,13 +39,13 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
* the new group's roster (critical for confirming admission to a closed group).
|
||||
*/
|
||||
@Composable
|
||||
fun RelayGroupRosterSubscription(
|
||||
dataSource: RelayGroupRosterFilterAssembler,
|
||||
fun RelayGroupMyJoinedGroupsSubscription(
|
||||
dataSource: RelayGroupMyJoinedGroupsFilterAssembler,
|
||||
accountViewModel: AccountViewModel,
|
||||
) {
|
||||
val state =
|
||||
remember(accountViewModel.account) {
|
||||
RelayGroupRosterQueryState(accountViewModel.account)
|
||||
RelayGroupMyJoinedGroupsQueryState(accountViewModel.account)
|
||||
}
|
||||
|
||||
val joined by accountViewModel.account.relayGroupList.liveRelayGroupList
|
||||
+9
-9
@@ -32,7 +32,7 @@ import com.vitorpamplona.quartz.nip29RelayGroups.GroupId
|
||||
import com.vitorpamplona.quartz.nip7DThreads.ThreadEvent
|
||||
|
||||
/** One threads-screen's request for a single group's kind-11 threads. */
|
||||
class RelayGroupThreadsQueryState(
|
||||
class RelayGroupThreadFeedQueryState(
|
||||
val channel: RelayGroupChannel,
|
||||
)
|
||||
|
||||
@@ -43,12 +43,12 @@ class RelayGroupThreadsQueryState(
|
||||
* kind-9 chat, so we don't pay for them until asked). Fetching the comments here
|
||||
* too means opening a thread from the list has its replies already cached.
|
||||
*/
|
||||
class RelayGroupThreadsFilterAssembler(
|
||||
class RelayGroupThreadFeedFilterAssembler(
|
||||
client: INostrClient,
|
||||
) : ComposeSubscriptionManager<RelayGroupThreadsQueryState>() {
|
||||
) : ComposeSubscriptionManager<RelayGroupThreadFeedQueryState>() {
|
||||
val group =
|
||||
listOf(
|
||||
RelayGroupThreadsSubAssembler(client, ::allKeys),
|
||||
RelayGroupThreadFeedSubAssembler(client, ::allKeys),
|
||||
)
|
||||
|
||||
override fun invalidateKeys() = invalidateFilters()
|
||||
@@ -58,12 +58,12 @@ class RelayGroupThreadsFilterAssembler(
|
||||
override fun destroy() = group.forEach { it.destroy() }
|
||||
}
|
||||
|
||||
class RelayGroupThreadsSubAssembler(
|
||||
class RelayGroupThreadFeedSubAssembler(
|
||||
client: INostrClient,
|
||||
allKeys: () -> Set<RelayGroupThreadsQueryState>,
|
||||
) : PerUniqueIdEoseManager<RelayGroupThreadsQueryState, GroupId>(client, allKeys) {
|
||||
allKeys: () -> Set<RelayGroupThreadFeedQueryState>,
|
||||
) : PerUniqueIdEoseManager<RelayGroupThreadFeedQueryState, GroupId>(client, allKeys) {
|
||||
override fun updateFilter(
|
||||
key: RelayGroupThreadsQueryState,
|
||||
key: RelayGroupThreadFeedQueryState,
|
||||
since: SincePerRelayMap?,
|
||||
): List<RelayBasedFilter> {
|
||||
val groupId = key.channel.groupId
|
||||
@@ -80,5 +80,5 @@ class RelayGroupThreadsSubAssembler(
|
||||
)
|
||||
}
|
||||
|
||||
override fun id(key: RelayGroupThreadsQueryState) = key.channel.groupId
|
||||
override fun id(key: RelayGroupThreadFeedQueryState) = key.channel.groupId
|
||||
}
|
||||
+3
-3
@@ -28,14 +28,14 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
|
||||
/** Mount on a group's Threads screen to stream its kind-11 threads + 1111 comments. */
|
||||
@Composable
|
||||
fun RelayGroupThreadsSubscription(
|
||||
fun RelayGroupThreadFeedSubscription(
|
||||
channel: RelayGroupChannel,
|
||||
dataSource: RelayGroupThreadsFilterAssembler,
|
||||
dataSource: RelayGroupThreadFeedFilterAssembler,
|
||||
accountViewModel: AccountViewModel,
|
||||
) {
|
||||
val state =
|
||||
remember(channel.groupId) {
|
||||
RelayGroupThreadsQueryState(channel)
|
||||
RelayGroupThreadFeedQueryState(channel)
|
||||
}
|
||||
|
||||
LifecycleAwareKeyDataSourceSubscription(state, dataSource)
|
||||
+13
-13
@@ -36,14 +36,14 @@ import com.vitorpamplona.quartz.nip88Polls.poll.PollEvent
|
||||
import com.vitorpamplona.quartz.nipC7Chats.ChatEvent
|
||||
|
||||
/** One on-screen group card's request to warm a single group. */
|
||||
class RelayGroupPreviewQueryState(
|
||||
class RelayGroupWarmupQueryState(
|
||||
val channel: RelayGroupChannel,
|
||||
/** When true, prefetch only recent content — the caller's screen already streams metadata. */
|
||||
val contentOnly: Boolean = false,
|
||||
)
|
||||
|
||||
/** Newest content kinds we prefetch so opening the card lands on populated screens. */
|
||||
private val RELAY_GROUP_PREVIEW_CONTENT_KINDS =
|
||||
private val RELAY_GROUP_WARMUP_CONTENT_KINDS =
|
||||
listOf(ChatEvent.KIND, PollEvent.KIND, ThreadEvent.KIND, CommentEvent.KIND)
|
||||
|
||||
/**
|
||||
@@ -51,7 +51,7 @@ private val RELAY_GROUP_PREVIEW_CONTENT_KINDS =
|
||||
* discovery card's "50+ messages" activity signal (a chat that returns the full page reads as
|
||||
* "50+"; fewer shows the exact loaded count).
|
||||
*/
|
||||
private const val RELAY_GROUP_PREVIEW_LIMIT = 50
|
||||
private const val RELAY_GROUP_WARMUP_LIMIT = 50
|
||||
|
||||
/**
|
||||
* Warms a NIP-29 group referenced inline (a group-link card) without opening it:
|
||||
@@ -60,12 +60,12 @@ private const val RELAY_GROUP_PREVIEW_LIMIT = 50
|
||||
* messages and threads so tapping the card lands on already-cached content. Both are
|
||||
* pinned to the group's single host relay. Active only while the card is on-screen.
|
||||
*/
|
||||
class RelayGroupPreviewFilterAssembler(
|
||||
class RelayGroupWarmupFilterAssembler(
|
||||
client: INostrClient,
|
||||
) : ComposeSubscriptionManager<RelayGroupPreviewQueryState>() {
|
||||
) : ComposeSubscriptionManager<RelayGroupWarmupQueryState>() {
|
||||
val group =
|
||||
listOf(
|
||||
RelayGroupPreviewSubAssembler(client, ::allKeys),
|
||||
RelayGroupWarmupSubAssembler(client, ::allKeys),
|
||||
)
|
||||
|
||||
override fun invalidateKeys() = invalidateFilters()
|
||||
@@ -75,12 +75,12 @@ class RelayGroupPreviewFilterAssembler(
|
||||
override fun destroy() = group.forEach { it.destroy() }
|
||||
}
|
||||
|
||||
class RelayGroupPreviewSubAssembler(
|
||||
class RelayGroupWarmupSubAssembler(
|
||||
client: INostrClient,
|
||||
allKeys: () -> Set<RelayGroupPreviewQueryState>,
|
||||
) : PerUniqueIdEoseManager<RelayGroupPreviewQueryState, GroupId>(client, allKeys) {
|
||||
allKeys: () -> Set<RelayGroupWarmupQueryState>,
|
||||
) : PerUniqueIdEoseManager<RelayGroupWarmupQueryState, GroupId>(client, allKeys) {
|
||||
override fun updateFilter(
|
||||
key: RelayGroupPreviewQueryState,
|
||||
key: RelayGroupWarmupQueryState,
|
||||
since: SincePerRelayMap?,
|
||||
): List<RelayBasedFilter> {
|
||||
val groupId = key.channel.groupId
|
||||
@@ -90,13 +90,13 @@ class RelayGroupPreviewSubAssembler(
|
||||
relay = groupId.relayUrl,
|
||||
filter =
|
||||
Filter(
|
||||
kinds = RELAY_GROUP_PREVIEW_CONTENT_KINDS,
|
||||
kinds = RELAY_GROUP_WARMUP_CONTENT_KINDS,
|
||||
tags = mapOf(GroupIdTag.TAG_NAME to listOf(groupId.id)),
|
||||
limit = RELAY_GROUP_PREVIEW_LIMIT,
|
||||
limit = RELAY_GROUP_WARMUP_LIMIT,
|
||||
since = since?.get(groupId.relayUrl)?.time,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
override fun id(key: RelayGroupPreviewQueryState) = key.channel.groupId
|
||||
override fun id(key: RelayGroupWarmupQueryState) = key.channel.groupId
|
||||
}
|
||||
+3
-3
@@ -32,15 +32,15 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
* subscription already streams that for the whole relay, so each visible row asks for content only.
|
||||
*/
|
||||
@Composable
|
||||
fun RelayGroupPreviewSubscription(
|
||||
fun RelayGroupWarmupSubscription(
|
||||
channel: RelayGroupChannel,
|
||||
dataSource: RelayGroupPreviewFilterAssembler,
|
||||
dataSource: RelayGroupWarmupFilterAssembler,
|
||||
accountViewModel: AccountViewModel,
|
||||
contentOnly: Boolean = false,
|
||||
) {
|
||||
val state =
|
||||
remember(channel.groupId, contentOnly) {
|
||||
RelayGroupPreviewQueryState(channel, contentOnly)
|
||||
RelayGroupWarmupQueryState(channel, contentOnly)
|
||||
}
|
||||
|
||||
LifecycleAwareKeyDataSourceSubscription(state, dataSource)
|
||||
+9
-9
@@ -34,7 +34,7 @@ import com.vitorpamplona.quartz.nip29RelayGroups.metadata.GroupMetadataEvent
|
||||
import com.vitorpamplona.quartz.nip29RelayGroups.metadata.SupportedRolesEvent
|
||||
|
||||
/** One screen's request for the full channel directory of a single relay. */
|
||||
class RelayGroupDirectoryQueryState(
|
||||
class RelayGroupsOnRelayQueryState(
|
||||
val relay: NormalizedRelayUrl,
|
||||
val account: Account,
|
||||
)
|
||||
@@ -54,12 +54,12 @@ private val RELAY_GROUP_DIRECTORY_KINDS =
|
||||
* the whole directory. Consumed into per-group [com.vitorpamplona.amethyst.commons.model.nip29RelayGroups.RelayGroupChannel]s
|
||||
* keyed by (relay + group id).
|
||||
*/
|
||||
class RelayGroupDirectoryFilterAssembler(
|
||||
class RelayGroupsOnRelayFilterAssembler(
|
||||
client: INostrClient,
|
||||
) : ComposeSubscriptionManager<RelayGroupDirectoryQueryState>() {
|
||||
) : ComposeSubscriptionManager<RelayGroupsOnRelayQueryState>() {
|
||||
val group =
|
||||
listOf(
|
||||
RelayGroupDirectorySubAssembler(client, ::allKeys),
|
||||
RelayGroupsOnRelaySubAssembler(client, ::allKeys),
|
||||
)
|
||||
|
||||
override fun invalidateKeys() = invalidateFilters()
|
||||
@@ -69,12 +69,12 @@ class RelayGroupDirectoryFilterAssembler(
|
||||
override fun destroy() = group.forEach { it.destroy() }
|
||||
}
|
||||
|
||||
class RelayGroupDirectorySubAssembler(
|
||||
class RelayGroupsOnRelaySubAssembler(
|
||||
client: INostrClient,
|
||||
allKeys: () -> Set<RelayGroupDirectoryQueryState>,
|
||||
) : PerUniqueIdEoseManager<RelayGroupDirectoryQueryState, NormalizedRelayUrl>(client, allKeys) {
|
||||
allKeys: () -> Set<RelayGroupsOnRelayQueryState>,
|
||||
) : PerUniqueIdEoseManager<RelayGroupsOnRelayQueryState, NormalizedRelayUrl>(client, allKeys) {
|
||||
override fun updateFilter(
|
||||
key: RelayGroupDirectoryQueryState,
|
||||
key: RelayGroupsOnRelayQueryState,
|
||||
since: SincePerRelayMap?,
|
||||
): List<RelayBasedFilter> =
|
||||
listOf(
|
||||
@@ -89,5 +89,5 @@ class RelayGroupDirectorySubAssembler(
|
||||
),
|
||||
)
|
||||
|
||||
override fun id(key: RelayGroupDirectoryQueryState) = key.relay
|
||||
override fun id(key: RelayGroupsOnRelayQueryState) = key.relay
|
||||
}
|
||||
+3
-3
@@ -27,14 +27,14 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
|
||||
|
||||
@Composable
|
||||
fun RelayGroupDirectorySubscription(
|
||||
fun RelayGroupsOnRelaySubscription(
|
||||
relay: NormalizedRelayUrl,
|
||||
dataSource: RelayGroupDirectoryFilterAssembler,
|
||||
dataSource: RelayGroupsOnRelayFilterAssembler,
|
||||
accountViewModel: AccountViewModel,
|
||||
) {
|
||||
val state =
|
||||
remember(accountViewModel.account, relay) {
|
||||
RelayGroupDirectoryQueryState(relay, accountViewModel.account)
|
||||
RelayGroupsOnRelayQueryState(relay, accountViewModel.account)
|
||||
}
|
||||
|
||||
LifecycleAwareKeyDataSourceSubscription(state, dataSource)
|
||||
+2
-2
@@ -43,7 +43,7 @@ import com.vitorpamplona.amethyst.ui.navigation.topbars.UserDrawerSearchTopBar
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.publicChannels.relayGroup.RelayGroupServerList
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.publicChannels.relayGroup.RelayGroupViewModeToggle
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.publicChannels.relayGroup.datasource.RelayGroupRosterSubscription
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.publicChannels.relayGroup.datasource.RelayGroupMyJoinedGroupsSubscription
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.rooms.ChannelFabColumn
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.rooms.datasource.ChatroomListFilterAssemblerSubscription
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.rooms.feed.MessagesPager
|
||||
@@ -109,7 +109,7 @@ fun MessagesSinglePane(
|
||||
|
||||
// Keep joined groups' rosters live while the messages list is on top, so
|
||||
// membership/pending state is accurate inline without opening each chat.
|
||||
RelayGroupRosterSubscription(accountViewModel.dataSources().relayGroupRoster, accountViewModel)
|
||||
RelayGroupMyJoinedGroupsSubscription(accountViewModel.dataSources().relayGroupMyJoinedGroups, accountViewModel)
|
||||
|
||||
Column {
|
||||
RelayGroupViewModeToggle(accountViewModel)
|
||||
|
||||
+2
-2
@@ -53,7 +53,7 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.privateDM.ChatroomVie
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.publicChannels.nip28PublicChat.PublicChatChannelView
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.publicChannels.relayGroup.RelayGroupServerList
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.publicChannels.relayGroup.RelayGroupViewModeToggle
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.publicChannels.relayGroup.datasource.RelayGroupRosterSubscription
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.publicChannels.relayGroup.datasource.RelayGroupMyJoinedGroupsSubscription
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.rooms.ChannelFabColumn
|
||||
import com.vitorpamplona.amethyst.ui.theme.Size20dp
|
||||
|
||||
@@ -103,7 +103,7 @@ fun MessagesTwoPane(
|
||||
val viewMode by accountViewModel.account.settings.relayGroupViewMode
|
||||
.collectAsStateWithLifecycle()
|
||||
|
||||
RelayGroupRosterSubscription(accountViewModel.dataSources().relayGroupRoster, accountViewModel)
|
||||
RelayGroupMyJoinedGroupsSubscription(accountViewModel.dataSources().relayGroupMyJoinedGroups, accountViewModel)
|
||||
|
||||
Column(Modifier.fillMaxSize()) {
|
||||
RelayGroupViewModeToggle(accountViewModel)
|
||||
|
||||
Reference in New Issue
Block a user