Files
mesh/client/src/stores/roomStore.ts
T
Gilles Soulier 1d177e96a6 first
2026-01-05 13:20:54 +01:00

284 lines
6.7 KiB
TypeScript

// 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<string, RoomInfo>
// Actions - Room courante
setCurrentRoom: (roomId: string, roomInfo: Partial<RoomInfo>) => 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<RoomInfo>) => void
clearCache: () => void
}
/**
* Store pour la gestion des rooms et messages.
*/
export const useRoomStore = create<RoomState>((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(),
}),
}))