fix(nests): preserve relays tag on participant updates + sync action bar with stage grid
Two related bugs the user hit while testing against nostrnests:
1. Approving a hand-raise made the Hands tab disappear (the host's
local app saw the role grant) but the audience member did not
appear on stage anywhere else.
Cause: RoomParticipantActions.rebuild() rebuilt the kind-30312
without the original room's `relays` tag. The recently-added
broadcast fan-out path (Account.computeRelayListToBroadcast) keys
off `event.allRelayUrls()` for kind 30312, so a republished room
event with no relays tag only reaches the host's outbox — not
nostrnests's fixed five reads or the audience member subscribing
on those reads. The audience member never sees their SPEAKER tag
and stays absent from the participant list.
Fix: copy `original.relays()` into the rebuild so every republish
(approve, demote, kick → re-broadcast) keeps the relay routing
that lets the room reach its full audience.
2. Tapping "Leave Stage" as the host emptied the StageGrid
("Waiting for speakers…") but the action bar still showed the
Talk + Leave Stage cluster.
Cause: two different definitions of "on stage" were in play.
StageGrid uses ParticipantGrid (role + presence.onstage flag),
so flipping onStageNow=false drops the host out. The action bar
gated on the role-only `onStage: List<ParticipantTag>` (the
host's HOST tag never goes away), so the cluster stayed.
Fix: derive isOnStageMe from participantGrid.onStage so both
surfaces share the same "stepped off" semantics. The host who
taps Leave Stage now drops to the audience-style mute toggle
and can rejoin (kind-10312 onstage flips back to 1) without
the controls lying about their state.
https://claude.ai/code/session_016G7oP5BotPjUBgvMYrrrxh
This commit is contained in:
+9
@@ -25,6 +25,7 @@ import com.vitorpamplona.quartz.nip53LiveActivities.meetingSpaces.MeetingSpaceEv
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.meetingSpaces.endpoint
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.meetingSpaces.image
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.meetingSpaces.participants
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.meetingSpaces.relays
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.meetingSpaces.summary
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.meetingSpaces.tags.StatusTag
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.streaming.tags.ParticipantTag
|
||||
@@ -132,6 +133,14 @@ internal object RoomParticipantActions {
|
||||
original.endpoint()?.let { endpoint(it) }
|
||||
original.summary()?.takeIf { it.isNotBlank() }?.let { summary(it) }
|
||||
original.image()?.takeIf { it.isNotBlank() }?.let { image(it) }
|
||||
// Preserve the room's `relays` tag — without it, the
|
||||
// republished kind-30312 fans out only to the host's
|
||||
// outbox, never reaching the room's own relay set
|
||||
// (e.g. nostrnests's fixed five reads). The audience
|
||||
// member would then never see their role grant and
|
||||
// wouldn't appear on stage for any other participant
|
||||
// listening on those relays.
|
||||
original.relays().takeIf { it.isNotEmpty() }?.let { relays(it) }
|
||||
if (others.isNotEmpty()) participants(others)
|
||||
}
|
||||
}
|
||||
|
||||
+11
-1
@@ -135,7 +135,6 @@ internal fun NestFullScreen(
|
||||
|
||||
val isHost = accountViewModel.account.signer.pubKey == event.pubKey
|
||||
val myPubkey = accountViewModel.account.signer.pubKey
|
||||
val isOnStageMe = remember(onStage, myPubkey) { onStage.any { it.pubKey == myPubkey } }
|
||||
val leaveScope = rememberCoroutineScope()
|
||||
val topBarContext = LocalContext.current
|
||||
|
||||
@@ -152,6 +151,17 @@ internal fun NestFullScreen(
|
||||
presences = presences,
|
||||
)
|
||||
}
|
||||
// Tie the action bar's "am I on stage" gate to the same data
|
||||
// source the StageGrid uses (role + presence.onstage flag),
|
||||
// not just the kind-30312 role tag. Otherwise a host who taps
|
||||
// "Leave Stage" flips presence to onstage=0 and disappears
|
||||
// from the StageGrid, but the action bar keeps showing the
|
||||
// Talk + Leave Stage cluster because it's still gated on
|
||||
// role-only.
|
||||
val isOnStageMe =
|
||||
remember(participantGrid, myPubkey) {
|
||||
participantGrid.onStage.any { it.pubkey == myPubkey }
|
||||
}
|
||||
// Same logic HandRaiseQueueSection uses internally — duplicated
|
||||
// here so the tab label can show a count without coupling the
|
||||
// section to the screen.
|
||||
|
||||
Reference in New Issue
Block a user