// sessions.js - Session list management import { send, on } from './ws.js'; import { showContextMenu } from './ui.js'; import { showShareModal } from './modals.js'; export let sessions = []; export let currentSessionId = null; const sessionListeners = new Set(); export function onSessionChange(fn) { sessionListeners.add(fn); return () => sessionListeners.delete(fn); } function notify(event, data) { sessionListeners.forEach(fn => fn(event, data)); } // ── Server events ───────────────────────────────────────────────────────── on('sessions:list', (msg) => { sessions = msg.sessions || []; renderSessions(); }); on('sessions:created', (msg) => { const existing = sessions.findIndex(s => s.id === msg.session.id); if (existing === -1) sessions.unshift(msg.session); else sessions[existing] = msg.session; renderSessions(); notify('created', msg.session); }); on('sessions:deleted', (msg) => { sessions = sessions.filter(s => s.id !== msg.sessionId); if (currentSessionId === msg.sessionId) { currentSessionId = sessions[0]?.id || null; notify('switched', currentSessionId); } renderSessions(); }); on('sessions:deletedAll', () => { sessions = []; currentSessionId = null; renderSessions(); notify('switched', null); }); on('sessions:renamed', (msg) => { const s = sessions.find(s => s.id === msg.sessionId); if (s) s.name = msg.name; renderSessions(); }); on('sessions:data', (msg) => { const existing = sessions.findIndex(s => s.id === msg.session.id); if (existing >= 0) sessions[existing] = msg.session; notify('data', msg.session); }); on('auth:ok', (msg) => { sessions = msg.sessions || []; renderSessions(); if (sessions.length > 0 && !currentSessionId) { switchSession(sessions[0].id); } }); on('auth:guestOk', (msg) => { sessions = msg.sessions || []; renderSessions(); if (sessions.length === 0) { createNewSession(); } else { switchSession(sessions[0].id); } }); on('chat:done', (msg) => { const s = sessions.find(s => s.id === msg.sessionId); if (s) { s.history = msg.history; if (msg.name) s.name = msg.name; sessions.sort((a, b) => { const aTime = a.history?.at(-1)?.timestamp || a.created; const bTime = b.history?.at(-1)?.timestamp || b.created; return bTime - aTime; }); renderSessions(); } }); on('sessions:imported', (msg) => { sessions.unshift(msg.session); renderSessions(); switchSession(msg.session.id); }); // ── Actions ─────────────────────────────────────────────────────────────── export function createNewSession() { send({ type: 'sessions:create' }); } export function switchSession(id) { currentSessionId = id; renderSessions(); send({ type: 'sessions:get', sessionId: id }); notify('switched', id); } export function deleteSession(id) { send({ type: 'sessions:delete', sessionId: id }); } export function deleteAllSessions() { send({ type: 'sessions:deleteAll' }); } export function renameSession(id, name) { send({ type: 'sessions:rename', sessionId: id, name }); const s = sessions.find(s => s.id === id); if (s) s.name = name; renderSessions(); } export function requestSessions() { send({ type: 'sessions:list' }); } export function getCurrentSession() { return sessions.find(s => s.id === currentSessionId) || null; } // ── Render ──────────────────────────────────────────────────────────────── function renderSessions() { const list = document.getElementById('session-list'); if (!list) return; if (sessions.length === 0) { list.innerHTML = `