mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2026-08-10 08:27:04 +00:00
Merge
This commit is contained in:
+13
-11
@@ -56,6 +56,7 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import coil3.compose.AsyncImage
|
||||
import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.commons.ui.feeds.FeedState
|
||||
import com.vitorpamplona.amethyst.model.AddressableNote
|
||||
import com.vitorpamplona.amethyst.model.LocalCache
|
||||
import com.vitorpamplona.amethyst.model.Note
|
||||
import com.vitorpamplona.amethyst.service.relayClient.reqCommand.event.observeNoteAndMap
|
||||
@@ -176,6 +177,7 @@ private fun NestFeedCard(
|
||||
true
|
||||
}
|
||||
}
|
||||
val addressableNote = baseNote as? AddressableNote ?: return
|
||||
|
||||
val onClick =
|
||||
remember(meetingEvent, isUiClosed) {
|
||||
@@ -205,7 +207,7 @@ private fun NestFeedCard(
|
||||
note = baseNote,
|
||||
accountViewModel = accountViewModel,
|
||||
) {
|
||||
ObserveAndRenderSpace(baseNote, accountViewModel, nav)
|
||||
ObserveAndRenderSpace(addressableNote, accountViewModel, nav)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -213,7 +215,7 @@ private fun NestFeedCard(
|
||||
|
||||
@Composable
|
||||
fun ObserveAndRenderSpace(
|
||||
baseNote: Note,
|
||||
baseNote: AddressableNote,
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: INav,
|
||||
) {
|
||||
@@ -284,14 +286,14 @@ private const val PRESENCE_FRESHNESS_WINDOW_SECONDS = 180L
|
||||
*/
|
||||
@Composable
|
||||
private fun RenderLiveOrEndedFromPresence(
|
||||
address: Address?,
|
||||
note: AddressableNote?,
|
||||
accountViewModel: AccountViewModel,
|
||||
) {
|
||||
if (address == null) {
|
||||
if (note == null) {
|
||||
LiveFlag()
|
||||
return
|
||||
}
|
||||
val latestPresence by observeRoomLatestPresence(address, accountViewModel)
|
||||
val latestPresence by observeRoomLatestPresence(note, accountViewModel)
|
||||
val fresh = latestPresence == null || latestPresence!! > TimeUtils.now() - PRESENCE_FRESHNESS_WINDOW_SECONDS
|
||||
if (fresh) LiveFlag() else EndedFlag()
|
||||
}
|
||||
@@ -310,12 +312,12 @@ private fun RenderLiveOrEndedFromPresence(
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
@Composable
|
||||
private fun observeRoomLatestPresence(
|
||||
address: Address,
|
||||
note: AddressableNote,
|
||||
accountViewModel: AccountViewModel,
|
||||
): State<Long?> {
|
||||
NestRoomFilterAssemblerSubscription(address.toValue(), accountViewModel)
|
||||
NestRoomFilterAssemblerSubscription(note, accountViewModel)
|
||||
|
||||
val channel = remember(address) { LocalCache.getOrCreateLiveChannel(address) }
|
||||
val channel = remember(note.idHex) { LocalCache.getOrCreateLiveChannel(note.address) }
|
||||
val flow =
|
||||
remember(channel) {
|
||||
channel
|
||||
@@ -340,7 +342,7 @@ private fun observeRoomLatestPresence(
|
||||
@Composable
|
||||
fun RenderLiveSpacesThumb(
|
||||
card: NestCard,
|
||||
baseNote: Note,
|
||||
baseNote: AddressableNote,
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: INav,
|
||||
) {
|
||||
@@ -370,7 +372,7 @@ fun RenderLiveSpacesThumb(
|
||||
CrossfadeIfEnabled(targetState = card.status, accountViewModel = accountViewModel) {
|
||||
when (it) {
|
||||
StatusTag.STATUS.LIVE -> {
|
||||
RenderLiveOrEndedFromPresence(card.id, accountViewModel)
|
||||
RenderLiveOrEndedFromPresence(baseNote, accountViewModel)
|
||||
}
|
||||
|
||||
StatusTag.STATUS.ENDED -> {
|
||||
@@ -419,7 +421,7 @@ fun RenderLiveSpacesThumb(
|
||||
@Composable
|
||||
fun SpaceHostAndReactions(
|
||||
name: String?,
|
||||
baseNote: Note,
|
||||
baseNote: AddressableNote,
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: INav,
|
||||
) {
|
||||
|
||||
+13
-10
@@ -26,6 +26,7 @@ import androidx.compose.runtime.remember
|
||||
import com.vitorpamplona.amethyst.commons.relayClient.composeSubscriptionManagers.ComposeSubscriptionManager
|
||||
import com.vitorpamplona.amethyst.commons.relayClient.subscriptions.KeyDataSourceSubscription
|
||||
import com.vitorpamplona.amethyst.model.Account
|
||||
import com.vitorpamplona.amethyst.model.AddressableNote
|
||||
import com.vitorpamplona.amethyst.service.relayClient.eoseManagers.PerUniqueIdEoseManager
|
||||
import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
@@ -35,6 +36,7 @@ import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter
|
||||
import com.vitorpamplona.quartz.nip25Reactions.ReactionEvent
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.chat.LiveActivitiesChatMessageEvent
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.meetingSpaces.MeetingSpaceEvent
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.presence.MeetingRoomPresenceEvent
|
||||
|
||||
/**
|
||||
@@ -46,7 +48,7 @@ import com.vitorpamplona.quartz.nip53LiveActivities.presence.MeetingRoomPresence
|
||||
*/
|
||||
@Stable
|
||||
class NestRoomQueryState(
|
||||
val roomATag: String,
|
||||
val note: AddressableNote,
|
||||
val account: Account,
|
||||
)
|
||||
|
||||
@@ -79,7 +81,8 @@ class NestRoomFilterSubAssembler(
|
||||
key: NestRoomQueryState,
|
||||
since: SincePerRelayMap?,
|
||||
): List<RelayBasedFilter> {
|
||||
val relays = key.account.outboxRelays.flow.value
|
||||
val relays = key.account.outboxRelays.flow.value + key.note.relays + ((key.note.event as? MeetingSpaceEvent)?.relays()?.toSet() ?: emptySet())
|
||||
|
||||
return relays.flatMap { relay ->
|
||||
listOf(
|
||||
RelayBasedFilter(
|
||||
@@ -92,7 +95,7 @@ class NestRoomFilterSubAssembler(
|
||||
MeetingRoomPresenceEvent.KIND,
|
||||
ReactionEvent.KIND,
|
||||
),
|
||||
tags = mapOf("a" to listOf(key.roomATag)),
|
||||
tags = mapOf("a" to listOf(key.note.idHex)),
|
||||
since = since?.get(relay)?.time,
|
||||
),
|
||||
),
|
||||
@@ -101,7 +104,7 @@ class NestRoomFilterSubAssembler(
|
||||
filter =
|
||||
Filter(
|
||||
kinds = listOf(AdminCommandEvent.KIND),
|
||||
tags = mapOf("a" to listOf(key.roomATag), "p" to listOf(key.account.pubKey)),
|
||||
tags = mapOf("a" to listOf(key.note.idHex), "p" to listOf(key.account.pubKey)),
|
||||
since = since?.get(relay)?.time,
|
||||
),
|
||||
),
|
||||
@@ -109,7 +112,7 @@ class NestRoomFilterSubAssembler(
|
||||
}
|
||||
}
|
||||
|
||||
override fun id(key: NestRoomQueryState): String = key.roomATag
|
||||
override fun id(key: NestRoomQueryState): String = key.note.idHex
|
||||
}
|
||||
|
||||
@Stable
|
||||
@@ -135,23 +138,23 @@ class NestRoomFilterAssembler(
|
||||
*/
|
||||
@Composable
|
||||
fun NestRoomFilterAssemblerSubscription(
|
||||
roomATag: String,
|
||||
note: AddressableNote,
|
||||
accountViewModel: AccountViewModel,
|
||||
) = NestRoomFilterAssemblerSubscription(
|
||||
roomATag,
|
||||
note,
|
||||
accountViewModel.account,
|
||||
accountViewModel.dataSources().nestRoom,
|
||||
)
|
||||
|
||||
@Composable
|
||||
fun NestRoomFilterAssemblerSubscription(
|
||||
roomATag: String,
|
||||
note: AddressableNote,
|
||||
account: Account,
|
||||
filterAssembler: NestRoomFilterAssembler,
|
||||
) {
|
||||
val state =
|
||||
remember(roomATag, account.pubKey) {
|
||||
NestRoomQueryState(roomATag, account)
|
||||
remember(note, account.pubKey) {
|
||||
NestRoomQueryState(note, account)
|
||||
}
|
||||
KeyDataSourceSubscription(state, filterAssembler)
|
||||
}
|
||||
|
||||
+1
-1
@@ -161,7 +161,7 @@ private fun NestActivityBody(
|
||||
|
||||
// Single REQ per relay covering chat, presence, reactions, admin
|
||||
// commands. See NestRoomFilterAssembler for the filter shape.
|
||||
NestRoomFilterAssemblerSubscription(roomATag, accountViewModel)
|
||||
NestRoomFilterAssemblerSubscription(roomNote, accountViewModel)
|
||||
|
||||
// Read side: LocalCache → VM. Each kind has its own collector
|
||||
// (different VM hook per kind) plus the two eviction tickers.
|
||||
|
||||
+4
-2
@@ -62,6 +62,7 @@ import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import coil3.compose.AsyncImage
|
||||
import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.model.AddressableNote
|
||||
import com.vitorpamplona.amethyst.model.LocalCache
|
||||
import com.vitorpamplona.amethyst.model.Note
|
||||
import com.vitorpamplona.amethyst.ui.navigation.navs.INav
|
||||
@@ -122,7 +123,7 @@ fun NestLobbyScreen(
|
||||
LoadAddressableNote(address, accountViewModel) { addressableNote ->
|
||||
addressableNote ?: return@LoadAddressableNote
|
||||
val event = addressableNote.event as? MeetingSpaceEvent ?: return@LoadAddressableNote
|
||||
NestLobbyContent(event, accountViewModel, nav)
|
||||
NestLobbyContent(event, addressableNote, accountViewModel, nav)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -130,6 +131,7 @@ fun NestLobbyScreen(
|
||||
@Composable
|
||||
private fun NestLobbyContent(
|
||||
event: MeetingSpaceEvent,
|
||||
addressableNote: AddressableNote,
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: INav,
|
||||
) {
|
||||
@@ -137,7 +139,7 @@ private fun NestLobbyContent(
|
||||
|
||||
// Keep cached chat / presence warm while the user is on the lobby.
|
||||
// No MoQ session is opened — that's gated behind the Open action.
|
||||
NestRoomFilterAssemblerSubscription(roomATag, accountViewModel)
|
||||
NestRoomFilterAssemblerSubscription(addressableNote, accountViewModel)
|
||||
|
||||
// Composer for kind-1311 chat. Same widget the in-room screen uses,
|
||||
// so the user gets @-mention picker, file uploads, draft auto-save,
|
||||
|
||||
Reference in New Issue
Block a user