// Created by: Claude // Date: 2026-01-03 // Purpose: Store Zustand pour la gestion des rooms et messages // Refs: client/CLAUDE.md import { create } from 'zustand' /** * Message dans une room. */ export interface Message { message_id: string room_id: string user_id: string from_username: string content: string created_at: string } /** * Membre d'une room. */ export interface RoomMember { user_id: string username: string peer_id?: string role: 'owner' | 'member' | 'guest' presence: 'online' | 'busy' | 'offline' } /** * Informations sur une room. */ export interface RoomInfo { room_id: string name: string owner_user_id: string created_at: string members: RoomMember[] messages: Message[] } /** * État de la room courante. */ interface RoomState { // Room courante currentRoomId: string | null currentRoom: RoomInfo | null // Cache des rooms rooms: Map // Actions - Room courante setCurrentRoom: (roomId: string, roomInfo: Partial) => void clearCurrentRoom: () => void // Actions - Messages addMessage: (roomId: string, message: Message) => void setMessages: (roomId: string, messages: Message[]) => void // Actions - Membres addMember: (roomId: string, member: RoomMember) => void removeMember: (roomId: string, userId: string) => void updateMemberPresence: (roomId: string, userId: string, presence: 'online' | 'busy' | 'offline') => void setMembers: (roomId: string, members: RoomMember[]) => void // Actions - Cache updateRoomCache: (roomId: string, updates: Partial) => void clearCache: () => void } /** * Store pour la gestion des rooms et messages. */ export const useRoomStore = create((set, get) => ({ // État initial currentRoomId: null, currentRoom: null, rooms: new Map(), // Définir la room courante setCurrentRoom: (roomId, roomInfo) => { const existingRoom = get().rooms.get(roomId) const room: RoomInfo = { room_id: roomId, name: roomInfo.name || existingRoom?.name || 'Unknown Room', owner_user_id: roomInfo.owner_user_id || existingRoom?.owner_user_id || '', created_at: roomInfo.created_at || existingRoom?.created_at || new Date().toISOString(), members: roomInfo.members || existingRoom?.members || [], messages: roomInfo.messages || existingRoom?.messages || [], } set((state) => { const newRooms = new Map(state.rooms) newRooms.set(roomId, room) return { currentRoomId: roomId, currentRoom: room, rooms: newRooms, } }) }, // Effacer la room courante clearCurrentRoom: () => set({ currentRoomId: null, currentRoom: null, }), // Ajouter un message addMessage: (roomId, message) => { set((state) => { const room = state.rooms.get(roomId) if (!room) return state const updatedRoom = { ...room, messages: [...room.messages, message], } const newRooms = new Map(state.rooms) newRooms.set(roomId, updatedRoom) return { rooms: newRooms, currentRoom: state.currentRoomId === roomId ? updatedRoom : state.currentRoom, } }) }, // Définir tous les messages d'une room setMessages: (roomId, messages) => { set((state) => { const room = state.rooms.get(roomId) if (!room) return state const updatedRoom = { ...room, messages, } const newRooms = new Map(state.rooms) newRooms.set(roomId, updatedRoom) return { rooms: newRooms, currentRoom: state.currentRoomId === roomId ? updatedRoom : state.currentRoom, } }) }, // Ajouter un membre addMember: (roomId, member) => { set((state) => { const room = state.rooms.get(roomId) if (!room) return state // Vérifier si le membre existe déjà const existingIndex = room.members.findIndex((m) => m.user_id === member.user_id) let updatedMembers if (existingIndex >= 0) { // Mettre à jour le membre existant updatedMembers = [...room.members] updatedMembers[existingIndex] = { ...updatedMembers[existingIndex], ...member } } else { // Ajouter un nouveau membre updatedMembers = [...room.members, member] } const updatedRoom = { ...room, members: updatedMembers, } const newRooms = new Map(state.rooms) newRooms.set(roomId, updatedRoom) return { rooms: newRooms, currentRoom: state.currentRoomId === roomId ? updatedRoom : state.currentRoom, } }) }, // Retirer un membre removeMember: (roomId, userId) => { set((state) => { const room = state.rooms.get(roomId) if (!room) return state const updatedRoom = { ...room, members: room.members.filter((m) => m.user_id !== userId), } const newRooms = new Map(state.rooms) newRooms.set(roomId, updatedRoom) return { rooms: newRooms, currentRoom: state.currentRoomId === roomId ? updatedRoom : state.currentRoom, } }) }, // Mettre à jour la présence d'un membre updateMemberPresence: (roomId, userId, presence) => { set((state) => { const room = state.rooms.get(roomId) if (!room) return state const updatedMembers = room.members.map((m) => m.user_id === userId ? { ...m, presence } : m ) const updatedRoom = { ...room, members: updatedMembers, } const newRooms = new Map(state.rooms) newRooms.set(roomId, updatedRoom) return { rooms: newRooms, currentRoom: state.currentRoomId === roomId ? updatedRoom : state.currentRoom, } }) }, // Définir tous les membres setMembers: (roomId, members) => { set((state) => { const room = state.rooms.get(roomId) if (!room) return state const updatedRoom = { ...room, members, } const newRooms = new Map(state.rooms) newRooms.set(roomId, updatedRoom) return { rooms: newRooms, currentRoom: state.currentRoomId === roomId ? updatedRoom : state.currentRoom, } }) }, // Mettre à jour le cache d'une room updateRoomCache: (roomId, updates) => { set((state) => { const room = state.rooms.get(roomId) if (!room) return state const updatedRoom = { ...room, ...updates, } const newRooms = new Map(state.rooms) newRooms.set(roomId, updatedRoom) return { rooms: newRooms, currentRoom: state.currentRoomId === roomId ? updatedRoom : state.currentRoom, } }) }, // Vider le cache clearCache: () => set({ currentRoomId: null, currentRoom: null, rooms: new Map(), }), }))