feat(nests): empty-stage hint, local hush, moderator/force-mute moderation
Three improvements stacked into one commit since they share files: #3 Empty-stage hint: StageGrid no longer disappears when nobody is on stage. The "Stage" label stays and a quiet "Waiting for speakers…" line keeps the strip visible so the room doesn't look broken before the first speaker arrives. #5 Local per-speaker hush: AudioPlayer gains a setVolume(Float) default-no-op method; AudioTrackPlayer composes mute and volume multiplicatively into AudioTrack.setVolume so a hushed stream stays silent regardless of mute state. NestViewModel exposes locallyHushed: ImmutableSet<String> in NestUiState plus setLocalHushed(pubkey, hushed) — applied at attach time so a re-subscribe of an already-hushed speaker stays silent. New "Hush this speaker" / "Restore this speaker" row in ParticipantHostActionsSheet, available to anyone (it affects only our own playback, nothing on the wire). #4 Host moderation gaps: wires Promote-to-Moderator using the existing RoomParticipantActions.setRole(ROLE.MODERATOR) builder — UI gap only, no protocol change. Adds a new AdminCommandEvent.Action.MUTE variant + AdminCommandEvent.forceMute(room, target) builder; the sheet emits it on "Force-mute speaker" and the AdminCommandsCollector dispatches incoming MUTE actions to a new NestViewModel.onForceMuted() that routes through the existing setMicMuted(true) path. Honor-based, same trust model as KICK — relays don't enforce signer authority, the client checks the signer is host or moderator on the active kind-30312.
This commit is contained in:
@@ -121,6 +121,21 @@ interface AudioPlayer {
|
||||
*/
|
||||
fun setMuted(muted: Boolean)
|
||||
|
||||
/**
|
||||
* Per-stream output gain, range `[0.0, 1.0]`. 1.0 is the device
|
||||
* default; 0.0 silences this stream while leaving any other
|
||||
* concurrent players untouched. Used to "hush" one speaker
|
||||
* locally without affecting the rest of the room.
|
||||
*
|
||||
* Independent of [setMuted]: muted streams are silent regardless of
|
||||
* gain, and an unmuted stream at gain 0 is still silent. The two
|
||||
* controls compose multiplicatively. Default gain is 1.0.
|
||||
*
|
||||
* Default implementation is a no-op so existing fakes / capture-only
|
||||
* actuals don't have to grow a method they'll never use.
|
||||
*/
|
||||
fun setVolume(volume: Float) {}
|
||||
|
||||
/** Stop playback and release resources. After this, the player is unusable. */
|
||||
fun stop()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user