feat(meetings): in-meeting chat — Everyone or direct-to-participant, brand-styled (batch73)
Adds an ephemeral chat inside meetings (relayed over the meeting signaling socket, not persisted). A chat button in the meeting bar (with an unread badge) opens a brand-styled panel: pick "Everyone" or a specific participant (private), send with Enter/Send. Direct messages are marked private on both sides. Works for guests too. Chat state resets when you leave the call. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -153,6 +153,17 @@ function handle(ws, m, req) {
|
||||
if (target && target.ws.readyState === 1) target.ws.send(JSON.stringify({ type: 'meeting-signal', from: ws._peerId, data: m.data }));
|
||||
break;
|
||||
}
|
||||
// In-meeting chat: relay a message to EVERYONE (m.to empty) or DIRECT to one peer (m.to = peerId).
|
||||
// Ephemeral (not persisted) — it lives only for the duration of the call.
|
||||
case 'meeting-chat': {
|
||||
const peers = ws._meetingRoom && meetingRooms.get(ws._meetingRoom);
|
||||
if (!peers) return;
|
||||
const text = String(m.text || '').slice(0, 2000); if (!text) return;
|
||||
const base = { type: 'meeting-chat', from: ws._peerId, name: ws._peerName || 'Guest', text, at: Date.now() };
|
||||
if (m.to) { const target = peers.get(m.to); if (target && target.ws.readyState === 1) target.ws.send(JSON.stringify({ ...base, to: m.to, direct: true })); }
|
||||
else { for (const [id, p] of peers) { if (id !== ws._peerId && p.ws.readyState === 1) p.ws.send(JSON.stringify(base)); } }
|
||||
break;
|
||||
}
|
||||
// Relay a peer's mic/cam state to everyone else in the room (for the tile mute icon).
|
||||
case 'meeting-state': {
|
||||
const peers = ws._meetingRoom && meetingRooms.get(ws._meetingRoom);
|
||||
|
||||
Reference in New Issue
Block a user