fix(voice): broadcast VOICE_JOIN/LEAVE via ws, show participants in sidebar for all users
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
import { create } from 'zustand';
|
||||
|
||||
export interface VoicePresenceEntry {
|
||||
userId: string;
|
||||
username: string;
|
||||
channelId: string;
|
||||
}
|
||||
|
||||
interface VoicePresenceState {
|
||||
// channelId -> userId -> entry
|
||||
presence: Record<string, Record<string, VoicePresenceEntry>>;
|
||||
_handleJoin: (entry: VoicePresenceEntry) => void;
|
||||
_handleLeave: (userId: string, channelId: string) => void;
|
||||
getParticipants: (channelId: string) => VoicePresenceEntry[];
|
||||
}
|
||||
|
||||
export const useVoicePresenceStore = create<VoicePresenceState>((set, get) => ({
|
||||
presence: {},
|
||||
|
||||
_handleJoin: (entry) => {
|
||||
set((state) => {
|
||||
const room = { ...(state.presence[entry.channelId] || {}) };
|
||||
room[entry.userId] = entry;
|
||||
return { presence: { ...state.presence, [entry.channelId]: room } };
|
||||
});
|
||||
},
|
||||
|
||||
_handleLeave: (userId, channelId) => {
|
||||
set((state) => {
|
||||
const room = { ...(state.presence[channelId] || {}) };
|
||||
delete room[userId];
|
||||
const next = { ...state.presence, [channelId]: room };
|
||||
if (Object.keys(room).length === 0) delete next[channelId];
|
||||
return { presence: next };
|
||||
});
|
||||
},
|
||||
|
||||
getParticipants: (channelId) => {
|
||||
const room = get().presence[channelId];
|
||||
return room ? Object.values(room) : [];
|
||||
},
|
||||
}));
|
||||
Reference in New Issue
Block a user