first
This commit is contained in:
@@ -0,0 +1,283 @@
|
||||
// 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(),
|
||||
}),
|
||||
}))
|
||||
Reference in New Issue
Block a user