From fc72e424d6fd150869556a84362a8ba5a6418a45 Mon Sep 17 00:00:00 2001 From: Jannis Braun <151788261+TheZwiss@users.noreply.github.com> Date: Thu, 12 Mar 2026 00:12:33 +0100 Subject: [PATCH] refactor: rename "Server Mute/Deafen" to "Space Mute/Deafen" across entire stack MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Aligns voice moderation terminology with Backspace's "Spaces" branding. Renames WS protocol strings, backend handlers, frontend store/hooks/utils, user-facing labels, and documentation — 15 files, zero functional changes. --- CLAUDE.md | 12 ++--- packages/server/src/ws/events.ts | 46 ++++++++-------- packages/server/src/ws/handler.ts | 54 +++++++++---------- packages/shared/src/types.ts | 10 ++-- packages/web/src/audio/SpeakingDetector.ts | 6 +-- .../src/components/layout/ChannelSidebar.tsx | 36 ++++++------- .../components/voice/GlobalAudioRenderer.tsx | 6 +-- .../web/src/components/voice/VoiceChannel.tsx | 20 +++---- .../src/components/voice/VoiceControlBar.tsx | 28 +++++----- .../web/src/components/voice/VoiceUser.tsx | 16 +++--- .../components/voice/VoiceUserContextMenu.tsx | 28 +++++----- packages/web/src/hooks/useLiveKit.ts | 18 +++---- packages/web/src/hooks/useWebSocket.ts | 34 ++++++------ packages/web/src/stores/voiceStore.ts | 44 +++++++-------- packages/web/src/utils/voice.ts | 14 ++--- 15 files changed, 186 insertions(+), 186 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 0a71e443..bf3525be 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -680,8 +680,8 @@ All WebSocket messages are JSON over `/ws`. Client authenticates by sending `{ t { type: 'voice_disconnect', userId } # Voice Moderation -{ type: 'voice_server_mute', userId, muted } -{ type: 'voice_server_deafen', userId, deafened } +{ type: 'voice_space_mute', userId, muted } +{ type: 'voice_space_deafen', userId, deafened } { type: 'voice_move', userId, targetChannelId } # DM Calls @@ -731,8 +731,8 @@ All WebSocket messages are JSON over `/ws`. Client authenticates by sending `{ t { type: 'voice_state_update', channelId, userId, action: 'join' | 'leave' } { type: 'voice_status_update', userId, isMuted, isDeafened, isCameraOn, isScreenSharing } { type: 'voice_disconnected', userId, channelId } -{ type: 'voice_server_muted', userId, spaceId, muted } -{ type: 'voice_server_deafened', userId, spaceId, deafened } +{ type: 'voice_space_muted', userId, spaceId, muted } +{ type: 'voice_space_deafened', userId, spaceId, deafened } { type: 'voice_permission_muted', userId, spaceId, muted } { type: 'voice_moved', userId, oldChannelId, newChannelId } @@ -774,8 +774,8 @@ Bitwise permission engine defined in `packages/shared/src/permissions.ts`. Store | 14 | ADD_REACTIONS | Add emoji reactions | | 20 | CONNECT | Join voice channels | | 21 | SPEAK | Transmit audio in voice | -| 22 | MUTE_MEMBERS | Server-mute other members | -| 23 | DEAFEN_MEMBERS | Server-deafen other members | +| 22 | MUTE_MEMBERS | Space-mute other members | +| 23 | DEAFEN_MEMBERS | Space-deafen other members | | 24 | MOVE_MEMBERS | Move members between voice channels | | 25 | STREAM | Share screen in voice channels | | 26 | DISCONNECT_MEMBERS | Disconnect members from voice channels | diff --git a/packages/server/src/ws/events.ts b/packages/server/src/ws/events.ts index 3b6324ac..ac67ef5b 100644 --- a/packages/server/src/ws/events.ts +++ b/packages/server/src/ws/events.ts @@ -180,11 +180,11 @@ export function handleClientEvent( case 'voice_status': handleVoiceStatus(event, userId); break; - case 'voice_server_mute': - handleVoiceServerMute(event, userId); + case 'voice_space_mute': + handleVoiceSpaceMute(event, userId); break; - case 'voice_server_deafen': - handleVoiceServerDeafen(event, userId); + case 'voice_space_deafen': + handleVoiceSpaceDeafen(event, userId); break; case 'voice_move': handleVoiceMove(event, userId); @@ -470,18 +470,18 @@ function handleVoiceJoin(event: Record, userId: string): void { .all(); for (const r of restrictions) { if (r.restrictionType === 'mute') { - connectionManager.setServerMuted(spaceId, userId, true); + connectionManager.setSpaceMuted(spaceId, userId, true); connectionManager.sendToUser(userId, { - type: 'voice_server_muted', + type: 'voice_space_muted', userId, channelId, spaceId, muted: true, }); } else if (r.restrictionType === 'deafen') { - connectionManager.setServerDeafened(spaceId, userId, true); + connectionManager.setSpaceDeafened(spaceId, userId, true); connectionManager.sendToUser(userId, { - type: 'voice_server_deafened', + type: 'voice_space_deafened', userId, channelId, spaceId, @@ -569,18 +569,18 @@ function handleVoiceJoin(event: Record, userId: string): void { for (const r of restrictions) { if (r.restrictionType === 'mute') { - connectionManager.setServerMuted(spaceId, userId, true); + connectionManager.setSpaceMuted(spaceId, userId, true); connectionManager.sendToSpace(spaceId, { - type: 'voice_server_muted', + type: 'voice_space_muted', userId, channelId, spaceId, muted: true, }); } else if (r.restrictionType === 'deafen') { - connectionManager.setServerDeafened(spaceId, userId, true); + connectionManager.setSpaceDeafened(spaceId, userId, true); connectionManager.sendToSpace(spaceId, { - type: 'voice_server_deafened', + type: 'voice_space_deafened', userId, channelId, spaceId, @@ -629,8 +629,8 @@ function handleVoiceStatus(event: Record, userId: string): void let isPermMuted = false; if (userRoom.room.roomType === 'space') { const meta = userRoom.room.metadata as SpaceRoomMeta; - isSpaceMuted = connectionManager.isServerMuted(meta.spaceId, userId); - isSpaceDeafened = connectionManager.isServerDeafened(meta.spaceId, userId); + isSpaceMuted = connectionManager.isSpaceMuted(meta.spaceId, userId); + isSpaceDeafened = connectionManager.isSpaceDeafened(meta.spaceId, userId); isPermMuted = connectionManager.isPermissionMuted(meta.spaceId, userId); } @@ -1198,7 +1198,7 @@ function handleDmCallEnd(event: Record, userId: string): void { // ─── Voice Moderation Handlers ────────────────────────────────────────────── -function handleVoiceServerMute(event: Record, userId: string): void { +function handleVoiceSpaceMute(event: Record, userId: string): void { const targetUserId = event.userId as string; const muted = event.muted === true; @@ -1220,13 +1220,13 @@ function handleVoiceServerMute(event: Record, userId: string): return; } - // Cannot server-mute yourself + // Cannot space-mute yourself if (targetUserId === userId) { - connectionManager.sendToUser(userId, { type: 'error', message: 'Cannot server-mute yourself' }); + connectionManager.sendToUser(userId, { type: 'error', message: 'Cannot space-mute yourself' }); return; } - connectionManager.setServerMuted(meta.spaceId, targetUserId, muted); + connectionManager.setSpaceMuted(meta.spaceId, targetUserId, muted); // Persist to DB const db = getDb(); @@ -1250,7 +1250,7 @@ function handleVoiceServerMute(event: Record, userId: string): // Broadcast to all space members connectionManager.sendToSpace(meta.spaceId, { - type: 'voice_server_muted', + type: 'voice_space_muted', userId: targetUserId, channelId: targetRoom.roomId, spaceId: meta.spaceId, @@ -1258,7 +1258,7 @@ function handleVoiceServerMute(event: Record, userId: string): }); } -function handleVoiceServerDeafen(event: Record, userId: string): void { +function handleVoiceSpaceDeafen(event: Record, userId: string): void { const targetUserId = event.userId as string; const deafened = event.deafened === true; @@ -1280,11 +1280,11 @@ function handleVoiceServerDeafen(event: Record, userId: string) } if (targetUserId === userId) { - connectionManager.sendToUser(userId, { type: 'error', message: 'Cannot server-deafen yourself' }); + connectionManager.sendToUser(userId, { type: 'error', message: 'Cannot space-deafen yourself' }); return; } - connectionManager.setServerDeafened(meta.spaceId, targetUserId, deafened); + connectionManager.setSpaceDeafened(meta.spaceId, targetUserId, deafened); // Persist to DB const db = getDb(); @@ -1307,7 +1307,7 @@ function handleVoiceServerDeafen(event: Record, userId: string) } connectionManager.sendToSpace(meta.spaceId, { - type: 'voice_server_deafened', + type: 'voice_space_deafened', userId: targetUserId, channelId: targetRoom.roomId, spaceId: meta.spaceId, diff --git a/packages/server/src/ws/handler.ts b/packages/server/src/ws/handler.ts index acb63136..45d6bd0e 100644 --- a/packages/server/src/ws/handler.ts +++ b/packages/server/src/ws/handler.ts @@ -82,9 +82,9 @@ class ConnectionManager { private pendingOfflineTimeouts: Map = new Map(); // roomId → Timeout for ringing DM rooms (60s auto-cleanup) private ringingTimeouts: Map = new Map(); - // Server-muted/deafened users (moderator action) - private serverMutedUsers: Set = new Set(); // Stores spaceId:userId - private serverDeafenedUsers: Set = new Set(); // Stores spaceId:userId + // Space-muted/deafened users (moderator action) + private spaceMutedUsers: Set = new Set(); // Stores spaceId:userId + private spaceDeafenedUsers: Set = new Set(); // Stores spaceId:userId // Permission-muted users (SPEAK permission revoked while in voice) private permissionMutedUsers: Set = new Set(); // Stores spaceId:userId @@ -317,7 +317,7 @@ class ConnectionManager { if (room.roomType === 'space') { const meta = room.metadata as SpaceRoomMeta; - this.clearServerVoiceState(meta.spaceId, userId); + this.clearSpaceVoiceState(meta.spaceId, userId); } // Auto-cleanup empty space rooms (they're lazy-created) @@ -400,29 +400,29 @@ class ConnectionManager { this.voiceUserStates.delete(userId); } - setServerMuted(spaceId: string, userId: string, muted: boolean): void { + setSpaceMuted(spaceId: string, userId: string, muted: boolean): void { const key = `${spaceId}:${userId}`; - if (muted) this.serverMutedUsers.add(key); - else this.serverMutedUsers.delete(key); + if (muted) this.spaceMutedUsers.add(key); + else this.spaceMutedUsers.delete(key); } - isServerMuted(spaceId: string, userId: string): boolean { - return this.serverMutedUsers.has(`${spaceId}:${userId}`); + isSpaceMuted(spaceId: string, userId: string): boolean { + return this.spaceMutedUsers.has(`${spaceId}:${userId}`); } - setServerDeafened(spaceId: string, userId: string, deafened: boolean): void { + setSpaceDeafened(spaceId: string, userId: string, deafened: boolean): void { const key = `${spaceId}:${userId}`; - if (deafened) this.serverDeafenedUsers.add(key); - else this.serverDeafenedUsers.delete(key); + if (deafened) this.spaceDeafenedUsers.add(key); + else this.spaceDeafenedUsers.delete(key); } - isServerDeafened(spaceId: string, userId: string): boolean { - return this.serverDeafenedUsers.has(`${spaceId}:${userId}`); + isSpaceDeafened(spaceId: string, userId: string): boolean { + return this.spaceDeafenedUsers.has(`${spaceId}:${userId}`); } - clearServerVoiceState(spaceId: string, userId: string): void { - this.serverMutedUsers.delete(`${spaceId}:${userId}`); - this.serverDeafenedUsers.delete(`${spaceId}:${userId}`); + clearSpaceVoiceState(spaceId: string, userId: string): void { + this.spaceMutedUsers.delete(`${spaceId}:${userId}`); + this.spaceDeafenedUsers.delete(`${spaceId}:${userId}`); this.permissionMutedUsers.delete(`${spaceId}:${userId}`); } @@ -653,7 +653,7 @@ function buildReadyPayload(userId: string): { folders: SpaceFolder[]; voiceStates: Record; voiceUserStates: Record; - serverVoiceStates: Record; + spaceVoiceStates: Record; readStates: ReadState[]; activeCalls: ActiveCallInfo[]; } { @@ -966,9 +966,9 @@ function buildReadyPayload(userId: string): { } } - // Build server mute/deafen states from DB (authoritative source for all spaces the user belongs to) + // Build space mute/deafen states from DB (authoritative source for all spaces the user belongs to) // Also includes ephemeral permission-mute state from in-memory Set - const serverVoiceStates: Record = {}; + const spaceVoiceStates: Record = {}; if (spaceIds.length > 0) { const allRestrictions = db.select() .from(schema.voiceRestrictions) @@ -976,10 +976,10 @@ function buildReadyPayload(userId: string): { .all(); for (const r of allRestrictions) { const key = `${r.spaceId}:${r.userId}`; - const existing = serverVoiceStates[key] ?? { serverMuted: false, serverDeafened: false, permissionMuted: false }; - if (r.restrictionType === 'mute') existing.serverMuted = true; - if (r.restrictionType === 'deafen') existing.serverDeafened = true; - serverVoiceStates[key] = existing; + const existing = spaceVoiceStates[key] ?? { spaceMuted: false, spaceDeafened: false, permissionMuted: false }; + if (r.restrictionType === 'mute') existing.spaceMuted = true; + if (r.restrictionType === 'deafen') existing.spaceDeafened = true; + spaceVoiceStates[key] = existing; } // Include ephemeral permission-mute state for all voice participants in user's spaces for (const [roomId, room] of connectionManager.getAllRooms()) { @@ -989,9 +989,9 @@ function buildReadyPayload(userId: string): { for (const participantId of room.participants) { if (connectionManager.isPermissionMuted(meta.spaceId, participantId)) { const key = `${meta.spaceId}:${participantId}`; - const existing = serverVoiceStates[key] ?? { serverMuted: false, serverDeafened: false, permissionMuted: false }; + const existing = spaceVoiceStates[key] ?? { spaceMuted: false, spaceDeafened: false, permissionMuted: false }; existing.permissionMuted = true; - serverVoiceStates[key] = existing; + spaceVoiceStates[key] = existing; } } } @@ -1008,7 +1008,7 @@ function buildReadyPayload(userId: string): { lastReadMessageId: rs.lastReadMessageId, })); - return { user, spaces, dmChannels, folders, voiceStates, voiceUserStates, serverVoiceStates, readStates, activeCalls }; + return { user, spaces, dmChannels, folders, voiceStates, voiceUserStates, spaceVoiceStates, readStates, activeCalls }; } export async function registerWebSocket(app: FastifyInstance): Promise { diff --git a/packages/shared/src/types.ts b/packages/shared/src/types.ts index b85f6ae7..535e5b1c 100644 --- a/packages/shared/src/types.ts +++ b/packages/shared/src/types.ts @@ -247,15 +247,15 @@ export type ClientEvent = | { type: 'dm_call_reject'; dmChannelId: string } | { type: 'dm_call_end'; dmChannelId: string } | { type: 'voice_status'; isMuted: boolean; isDeafened: boolean; isCameraOn: boolean; isScreenSharing: boolean } - | { type: 'voice_server_mute'; userId: string; muted: boolean } - | { type: 'voice_server_deafen'; userId: string; deafened: boolean } + | { type: 'voice_space_mute'; userId: string; muted: boolean } + | { type: 'voice_space_deafen'; userId: string; deafened: boolean } | { type: 'voice_move'; userId: string; targetChannelId: string } | { type: 'voice_disconnect'; userId: string } | { type: 'ping' }; // Server → Client Events export type ServerEvent = - | { type: 'ready'; user: User; spaces: SpaceWithChannelsAndMembers[]; dmChannels: DmChannel[]; folders?: SpaceFolder[]; voiceStates?: Record; voiceUserStates?: Record; readStates?: ReadState[]; activeCalls?: ActiveCallInfo[]; serverVoiceStates?: Record } + | { type: 'ready'; user: User; spaces: SpaceWithChannelsAndMembers[]; dmChannels: DmChannel[]; folders?: SpaceFolder[]; voiceStates?: Record; voiceUserStates?: Record; readStates?: ReadState[]; activeCalls?: ActiveCallInfo[]; spaceVoiceStates?: Record } | { type: 'message_created'; message: MessageWithUser } | { type: 'message_updated'; message: MessageWithUser } | { type: 'message_deleted'; messageId: string; channelId: string } @@ -290,8 +290,8 @@ export type ServerEvent = | { type: 'join_request_received'; request: JoinRequest } | { type: 'join_request_accepted'; request: JoinRequest; space: SpaceWithChannelsAndMembers } | { type: 'join_request_declined'; request: JoinRequest } - | { type: 'voice_server_muted'; userId: string; channelId: string; spaceId: string; muted: boolean } - | { type: 'voice_server_deafened'; userId: string; channelId: string; spaceId: string; deafened: boolean } + | { type: 'voice_space_muted'; userId: string; channelId: string; spaceId: string; muted: boolean } + | { type: 'voice_space_deafened'; userId: string; channelId: string; spaceId: string; deafened: boolean } | { type: 'voice_permission_muted'; userId: string; spaceId: string; muted: boolean } | { type: 'voice_moved'; userId: string; oldChannelId: string; newChannelId: string } | { type: 'voice_disconnected'; userId: string; channelId: string } diff --git a/packages/web/src/audio/SpeakingDetector.ts b/packages/web/src/audio/SpeakingDetector.ts index 2d3800c3..8902c0fc 100644 --- a/packages/web/src/audio/SpeakingDetector.ts +++ b/packages/web/src/audio/SpeakingDetector.ts @@ -178,9 +178,9 @@ export class SpeakingDetector { if (spaceId) { const myOriginId = getMyUserIdForOrigin(getChannelOrigin(channelId)); if (myOriginId) { - const serverKey = `${spaceId}:${myOriginId}`; - effectiveMuted = effectiveMuted || store.serverMutedUserIds.has(serverKey); - effectiveDeafened = effectiveDeafened || store.serverDeafenedUserIds.has(serverKey); + const spaceKey = `${spaceId}:${myOriginId}`; + effectiveMuted = effectiveMuted || store.spaceMutedUserIds.has(spaceKey); + effectiveDeafened = effectiveDeafened || store.spaceDeafenedUserIds.has(spaceKey); } } } diff --git a/packages/web/src/components/layout/ChannelSidebar.tsx b/packages/web/src/components/layout/ChannelSidebar.tsx index 81130d6d..b0e513cf 100644 --- a/packages/web/src/components/layout/ChannelSidebar.tsx +++ b/packages/web/src/components/layout/ChannelSidebar.tsx @@ -36,14 +36,14 @@ export function ChannelSidebar() { const toggleDeafen = useVoiceStore((s) => s.toggleDeafen); const spaceId = useSpaceStore((s) => currentVoiceChannelId ? s.channelToSpaceMap.get(currentVoiceChannelId) : null); const myOriginId = useSpaceStore((s) => currentVoiceChannelId ? getMyUserIdForOrigin(getChannelOrigin(currentVoiceChannelId)) : s.members.find(m => m.userId === user?.id)?.userId ?? user?.id); - const serverMutedUserIds = useVoiceStore((s) => s.serverMutedUserIds); - const serverDeafenedUserIds = useVoiceStore((s) => s.serverDeafenedUserIds); + const spaceMutedUserIds = useVoiceStore((s) => s.spaceMutedUserIds); + const spaceDeafenedUserIds = useVoiceStore((s) => s.spaceDeafenedUserIds); const permissionMutedUserIds = useVoiceStore((s) => s.permissionMutedUserIds); // Drag-and-drop state for moving users between voice channels const [voiceDragState, setVoiceDragState] = useState<{ userId: string; fromChannelId: string } | null>(null); - const isServerMuted = !!(myOriginId && spaceId && serverMutedUserIds.has(`${spaceId}:${myOriginId}`)); - const isServerDeafened = !!(myOriginId && spaceId && serverDeafenedUserIds.has(`${spaceId}:${myOriginId}`)); + const isSpaceMuted = !!(myOriginId && spaceId && spaceMutedUserIds.has(`${spaceId}:${myOriginId}`)); + const isSpaceDeafened = !!(myOriginId && spaceId && spaceDeafenedUserIds.has(`${spaceId}:${myOriginId}`)); const isPermissionMuted = !!(myOriginId && spaceId && permissionMutedUserIds.has(`${spaceId}:${myOriginId}`)); const navigate = useNavigate(); const location = useLocation(); @@ -64,7 +64,7 @@ export function ChannelSidebar() { }, [setFloatingPanelHeight]); const handleMicToggle = async () => { - if (isServerMuted || isServerDeafened || isPermissionMuted) return; + if (isSpaceMuted || isSpaceDeafened || isPermissionMuted) return; const wasDeafened = useVoiceStore.getState().isDeafened; toggleMic(); broadcastVoiceStatus(); @@ -75,7 +75,7 @@ export function ChannelSidebar() { }; const handleDeafenToggle = async () => { - if (isServerDeafened) return; + if (isSpaceDeafened) return; toggleDeafen(); broadcastVoiceStatus(); broadcastDeafenViaLiveKit(); @@ -133,8 +133,8 @@ export function ChannelSidebar() { user={user} isMuted={isMuted} isDeafened={isDeafened} - isServerMuted={isServerMuted} - isServerDeafened={isServerDeafened} + isSpaceMuted={isSpaceMuted} + isSpaceDeafened={isSpaceDeafened} isPermissionMuted={isPermissionMuted} onMicToggle={handleMicToggle} onDeafenToggle={handleDeafenToggle} @@ -496,8 +496,8 @@ function UserAreaPanel({ user, isMuted, isDeafened, - isServerMuted, - isServerDeafened, + isSpaceMuted, + isSpaceDeafened, isPermissionMuted, onMicToggle, onDeafenToggle, @@ -506,8 +506,8 @@ function UserAreaPanel({ user: any; isMuted: boolean; isDeafened: boolean; - isServerMuted: boolean; - isServerDeafened: boolean; + isSpaceMuted: boolean; + isSpaceDeafened: boolean; isPermissionMuted: boolean; onMicToggle: () => void; onDeafenToggle: () => void; @@ -823,15 +823,15 @@ function UserAreaPanel({ {/* Input chevron */} @@ -851,14 +851,14 @@ function UserAreaPanel({ {/* Output chevron */} diff --git a/packages/web/src/components/voice/GlobalAudioRenderer.tsx b/packages/web/src/components/voice/GlobalAudioRenderer.tsx index b3e071b1..a08202b1 100644 --- a/packages/web/src/components/voice/GlobalAudioRenderer.tsx +++ b/packages/web/src/components/voice/GlobalAudioRenderer.tsx @@ -68,7 +68,7 @@ function AudioTrackElement({ export function GlobalAudioRenderer() { const participants = useVoiceStore((s) => s.participants); const isDeafenedIntent = useVoiceStore((s) => s.isDeafened); - const serverDeafenedUserIds = useVoiceStore((s) => s.serverDeafenedUserIds); + const spaceDeafenedUserIds = useVoiceStore((s) => s.spaceDeafenedUserIds); const currentVoiceChannelId = useVoiceStore((s) => s.currentVoiceChannelId); const outputVolume = useVoiceStore((s) => s.outputVolume); const participantVolumes = useVoiceStore((s) => s.participantVolumes); @@ -83,8 +83,8 @@ export function GlobalAudioRenderer() { // Compute effective deafened: user intent || server enforcement const spaceId = useSpaceStore((s) => currentVoiceChannelId ? s.channelToSpaceMap.get(currentVoiceChannelId) : null); const myOriginId = currentVoiceChannelId ? getMyUserIdForOrigin(getChannelOrigin(currentVoiceChannelId)) : undefined; - const serverKey = (spaceId && myOriginId) ? `${spaceId}:${myOriginId}` : ''; - const isDeafened = isDeafenedIntent || serverDeafenedUserIds.has(serverKey); + const spaceKey = (spaceId && myOriginId) ? `${spaceId}:${myOriginId}` : ''; + const isDeafened = isDeafenedIntent || spaceDeafenedUserIds.has(spaceKey); // Determine if someone is currently speaking (for stream attenuation) const someoneIsSpeaking = participants.some((p) => !p.isLocal && speakingParticipantIds.has(p.identity)); diff --git a/packages/web/src/components/voice/VoiceChannel.tsx b/packages/web/src/components/voice/VoiceChannel.tsx index b1791a0c..d2f05aa9 100644 --- a/packages/web/src/components/voice/VoiceChannel.tsx +++ b/packages/web/src/components/voice/VoiceChannel.tsx @@ -31,8 +31,8 @@ export function VoiceChannel({ channelId, channelName, onClick, locked, dragStat const localIsDeafened = useVoiceStore((s) => s.isDeafened); const localIsMuted = useVoiceStore((s) => s.isMuted); const voiceUserStates = useVoiceStore((s) => s.voiceUserStates); - const serverMutedUserIds = useVoiceStore((s) => s.serverMutedUserIds); - const serverDeafenedUserIds = useVoiceStore((s) => s.serverDeafenedUserIds); + const spaceMutedUserIds = useVoiceStore((s) => s.spaceMutedUserIds); + const spaceDeafenedUserIds = useVoiceStore((s) => s.spaceDeafenedUserIds); const permissionMutedUserIds = useVoiceStore((s) => s.permissionMutedUserIds); const participantMutes = useVoiceStore((s) => s.participantMutes); const unwatchedCameras = useVoiceStore((s) => s.unwatchedCameras); @@ -147,8 +147,8 @@ export function VoiceChannel({ channelId, channelName, onClick, locked, dragStat const hasCamera = participant?.isCameraOn ?? wsStatus?.isCameraOn ?? false; const isScreenSharing = participant?.isScreenSharing ?? wsStatus?.isScreenSharing ?? false; const spaceId = channelToSpaceMap.get(channelId); - const isServerMuted = serverMutedUserIds.has(`${spaceId}:${userId}`); - const isServerDeafened = serverDeafenedUserIds.has(`${spaceId}:${userId}`); + const isSpaceMuted = spaceMutedUserIds.has(`${spaceId}:${userId}`); + const isSpaceDeafened = spaceDeafenedUserIds.has(`${spaceId}:${userId}`); const isPermissionMuted = permissionMutedUserIds.has(`${spaceId}:${userId}`); const isDraggable = canMoveMembers && userId !== myUser?.id; @@ -181,8 +181,8 @@ export function VoiceChannel({ channelId, channelName, onClick, locked, dragStat {displayName} {/* Status badges */}
- {(isServerMuted || isServerDeafened || isPermissionMuted) && ( - + {(isSpaceMuted || isSpaceDeafened || isPermissionMuted) && ( + @@ -190,22 +190,22 @@ export function VoiceChannel({ channelId, channelName, onClick, locked, dragStat )} - {isServerDeafened && ( - + {isSpaceDeafened && ( + )} - {!isServerMuted && !isServerDeafened && !isPermissionMuted && isMuted && ( + {!isSpaceMuted && !isSpaceDeafened && !isPermissionMuted && isMuted && ( )} - {!isServerDeafened && isParticipantDeafened && ( + {!isSpaceDeafened && isParticipantDeafened && ( diff --git a/packages/web/src/components/voice/VoiceControlBar.tsx b/packages/web/src/components/voice/VoiceControlBar.tsx index 47dbe257..ec86eedb 100644 --- a/packages/web/src/components/voice/VoiceControlBar.tsx +++ b/packages/web/src/components/voice/VoiceControlBar.tsx @@ -32,10 +32,10 @@ export function VoiceControlBar() { const spaceId = useSpaceStore((s) => currentVoiceChannelId ? s.channelToSpaceMap.get(currentVoiceChannelId) : null); const voiceOrigin = currentVoiceChannelId ? getChannelOrigin(currentVoiceChannelId) : ''; const myOriginId = useSpaceStore((s) => currentVoiceChannelId ? getMyUserIdForOrigin(getChannelOrigin(currentVoiceChannelId)) : s.members.find(m => m.userId === myUser?.id)?.userId ?? myUser?.id); - const serverMutedUserIds = useVoiceStore((s) => s.serverMutedUserIds); - const serverDeafenedUserIds = useVoiceStore((s) => s.serverDeafenedUserIds); - const isServerMuted = !!(myOriginId && spaceId && serverMutedUserIds.has(`${spaceId}:${myOriginId}`)); - const isServerDeafened = !!(myOriginId && spaceId && serverDeafenedUserIds.has(`${spaceId}:${myOriginId}`)); + const spaceMutedUserIds = useVoiceStore((s) => s.spaceMutedUserIds); + const spaceDeafenedUserIds = useVoiceStore((s) => s.spaceDeafenedUserIds); + const isSpaceMuted = !!(myOriginId && spaceId && spaceMutedUserIds.has(`${spaceId}:${myOriginId}`)); + const isSpaceDeafened = !!(myOriginId && spaceId && spaceDeafenedUserIds.has(`${spaceId}:${myOriginId}`)); const activeDmCall = useVoiceStore((s) => s.activeDmCall); const channelPerms = useSpaceStore((s) => currentVoiceChannelId ? s.channelPermissions.get(currentVoiceChannelId) : undefined); const isDmCall = !!activeDmCall; @@ -45,7 +45,7 @@ export function VoiceControlBar() { const qualityBtnRef = useRef(null); const handleMute = React.useCallback(async () => { - if (isServerMuted || isServerDeafened) return; + if (isSpaceMuted || isSpaceDeafened) return; const wasDeafened = useVoiceStore.getState().isDeafened; toggleMic(); broadcastVoiceStatus(); @@ -53,14 +53,14 @@ export function VoiceControlBar() { if (wasDeafened && !useVoiceStore.getState().isDeafened) { broadcastDeafenViaLiveKit(); } - }, [isServerMuted, isServerDeafened, toggleMic]); + }, [isSpaceMuted, isSpaceDeafened, toggleMic]); const handleDeafen = React.useCallback(async () => { - if (isServerDeafened) return; + if (isSpaceDeafened) return; toggleDeafen(); broadcastVoiceStatus(); broadcastDeafenViaLiveKit(); - }, [isServerDeafened, toggleDeafen]); + }, [isSpaceDeafened, toggleDeafen]); const handleCamera = async () => { const room = getActiveRoom(); @@ -147,35 +147,35 @@ export function VoiceControlBar() { {/* Mute */} {/* Deafen */} diff --git a/packages/web/src/components/voice/VoiceUser.tsx b/packages/web/src/components/voice/VoiceUser.tsx index 618546bc..070095f5 100644 --- a/packages/web/src/components/voice/VoiceUser.tsx +++ b/packages/web/src/components/voice/VoiceUser.tsx @@ -18,8 +18,8 @@ export function VoiceUser({ tile, large }: VoiceUserProps) { const isDeafened = useVoiceStore((s) => s.isDeafened); const currentVoiceChannelId = useVoiceStore((s) => s.currentVoiceChannelId); const isSpeaking = useVoiceStore((s) => s.speakingParticipantIds.has(participant.identity)); - const serverMutedUserIds = useVoiceStore((s) => s.serverMutedUserIds); - const serverDeafenedUserIds = useVoiceStore((s) => s.serverDeafenedUserIds); + const spaceMutedUserIds = useVoiceStore((s) => s.spaceMutedUserIds); + const spaceDeafenedUserIds = useVoiceStore((s) => s.spaceDeafenedUserIds); const permissionMutedUserIds = useVoiceStore((s) => s.permissionMutedUserIds); const unwatchedCameras = useVoiceStore((s) => s.unwatchedCameras); const participantMutes = useVoiceStore((s) => s.participantMutes); @@ -123,15 +123,15 @@ export function VoiceUser({ tile, large }: VoiceUserProps) {
{(() => { - const isServerMutedUser = spaceId ? serverMutedUserIds.has(`${spaceId}:${participant.userId}`) : false; - const isServerDeafenedUser = spaceId ? serverDeafenedUserIds.has(`${spaceId}:${participant.userId}`) : false; + const isSpaceMutedUser = spaceId ? spaceMutedUserIds.has(`${spaceId}:${participant.userId}`) : false; + const isSpaceDeafenedUser = spaceId ? spaceDeafenedUserIds.has(`${spaceId}:${participant.userId}`) : false; const isPermissionMutedUser = spaceId ? permissionMutedUserIds.has(`${spaceId}:${participant.userId}`) : false; - const effectivelyMuted = participant.isMuted || isServerMutedUser || isServerDeafenedUser || isPermissionMutedUser; - const effectivelyDeafened = (isLocal ? isDeafened : participant.isDeafened) || isServerDeafenedUser; + const effectivelyMuted = participant.isMuted || isSpaceMutedUser || isSpaceDeafenedUser || isPermissionMutedUser; + const effectivelyDeafened = (isLocal ? isDeafened : participant.isDeafened) || isSpaceDeafenedUser; return ( <> {effectivelyMuted && ( -
+
)} {effectivelyDeafened && ( -
+
s.serverMutedUserIds); - const serverDeafenedUserIds = useVoiceStore((s) => s.serverDeafenedUserIds); + const spaceMutedUserIds = useVoiceStore((s) => s.spaceMutedUserIds); + const spaceDeafenedUserIds = useVoiceStore((s) => s.spaceDeafenedUserIds); const spacePermissions = useSpaceStore((s) => s.spacePermissions); const currentSpaceId = useSpaceStore((s) => s.currentSpaceId); @@ -38,18 +38,18 @@ export function VoiceModMenuItems({ targetUserId, channelId, onAction }: VoiceMo const voiceOrigin = getChannelOrigin(channelId); const spaceId = useSpaceStore((s) => s.channelToSpaceMap.get(channelId)); - const isServerMuted = serverMutedUserIds.has(`${spaceId}:${targetUserId}`); - const isServerDeafened = serverDeafenedUserIds.has(`${spaceId}:${targetUserId}`); + const isSpaceMuted = spaceMutedUserIds.has(`${spaceId}:${targetUserId}`); + const isSpaceDeafened = spaceDeafenedUserIds.has(`${spaceId}:${targetUserId}`); if (!canMuteMembers && !canDeafenMembers && !canMoveMembers && !canDisconnectMembers) return null; - const handleServerMute = () => { - wsSend({ type: 'voice_server_mute', userId: targetUserId, muted: !isServerMuted }, voiceOrigin); + const handleSpaceMute = () => { + wsSend({ type: 'voice_space_mute', userId: targetUserId, muted: !isSpaceMuted }, voiceOrigin); onAction(); }; - const handleServerDeafen = () => { - wsSend({ type: 'voice_server_deafen', userId: targetUserId, deafened: !isServerDeafened }, voiceOrigin); + const handleSpaceDeafen = () => { + wsSend({ type: 'voice_space_deafen', userId: targetUserId, deafened: !isSpaceDeafened }, voiceOrigin); onAction(); }; @@ -69,26 +69,26 @@ export function VoiceModMenuItems({ targetUserId, channelId, onAction }: VoiceMo return ( <> {canMuteMembers && ( -