import { create } from 'zustand'; import { devtools, persist, createJSONStorage } from 'zustand/middleware'; import { getSafeStorage } from './utils/safeStorage'; import type { AttachedFile } from './types/sessionTypes'; import { updateDesktopSettings } from '@/lib/persistence'; export interface QueuedMessage { id: string; content: string; attachments?: AttachedFile[]; createdAt: number; } interface MessageQueueState { queuedMessages: Record; // sessionId → queue queueModeEnabled: boolean; // global toggle } interface MessageQueueActions { addToQueue: (sessionId: string, message: Omit) => void; removeFromQueue: (sessionId: string, messageId: string) => void; popToInput: (sessionId: string, messageId: string) => QueuedMessage | null; clearQueue: (sessionId: string) => void; clearAllQueues: () => void; setQueueMode: (enabled: boolean) => void; getQueueForSession: (sessionId: string) => QueuedMessage[]; } type MessageQueueStore = MessageQueueState & MessageQueueActions; export const useMessageQueueStore = create()( devtools( persist( (set, get) => ({ queuedMessages: {}, queueModeEnabled: true, addToQueue: (sessionId, message) => { const id = `queued-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`; const queuedMessage: QueuedMessage = { id, content: message.content, attachments: message.attachments, createdAt: Date.now(), }; set((state) => { const currentQueue = state.queuedMessages[sessionId] ?? []; return { queuedMessages: { ...state.queuedMessages, [sessionId]: [...currentQueue, queuedMessage], }, }; }); }, removeFromQueue: (sessionId, messageId) => { set((state) => { const currentQueue = state.queuedMessages[sessionId] ?? []; const newQueue = currentQueue.filter((m) => m.id !== messageId); if (newQueue.length === 0) { const { [sessionId]: _removed, ...rest } = state.queuedMessages; void _removed; return { queuedMessages: rest }; } return { queuedMessages: { ...state.queuedMessages, [sessionId]: newQueue, }, }; }); }, popToInput: (sessionId, messageId) => { const state = get(); const currentQueue = state.queuedMessages[sessionId] ?? []; const message = currentQueue.find((m) => m.id === messageId); if (!message) { return null; } // Remove from queue set((prevState) => { const queue = prevState.queuedMessages[sessionId] ?? []; const newQueue = queue.filter((m) => m.id !== messageId); if (newQueue.length === 0) { const { [sessionId]: _removed, ...rest } = prevState.queuedMessages; void _removed; return { queuedMessages: rest }; } return { queuedMessages: { ...prevState.queuedMessages, [sessionId]: newQueue, }, }; }); return message; }, clearQueue: (sessionId) => { set((state) => { const { [sessionId]: _removed, ...rest } = state.queuedMessages; void _removed; return { queuedMessages: rest }; }); }, clearAllQueues: () => { set({ queuedMessages: {} }); }, setQueueMode: (enabled) => { set({ queueModeEnabled: enabled }); // Persist to settings.json (async, fire-and-forget) void updateDesktopSettings({ queueModeEnabled: enabled }); }, getQueueForSession: (sessionId) => { return get().queuedMessages[sessionId] ?? []; }, }), { name: 'message-queue-store', storage: createJSONStorage(() => getSafeStorage()), partialize: (state) => ({ queuedMessages: state.queuedMessages, queueModeEnabled: state.queueModeEnabled, }), } ), { name: 'message-queue-store', } ) );