43 lines
1.2 KiB
TypeScript
43 lines
1.2 KiB
TypeScript
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) : [];
|
|
},
|
|
}));
|