import { create } from "zustand"; import { readChat, addMessage, updateChatName as updateChatNameInStorage, deleteChat as deleteChatInStorage, removeMessage, } from "@/lib/storage"; import type { Chat, Message } from "@/lib/types"; import { chatEventEmitter, CHAT_UPDATED_EVENT, CHAT_RENAMED_EVENT, } from "@/lib/chatEventEmitter"; import { downloadChatAsMarkdown } from "@/lib/markdownDownload"; interface ChatStore { selectedChat: Chat | null; selectedChatId: string | null; loadChat: (chatId: string) => Promise; clearSelectedChat: () => void; sendMessage: (message: Omit) => Promise; removeMessage: (messageId: string) => Promise; updateChatName: (chatId: string, name: string) => Promise; deleteChat: (chatId: string) => Promise; downloadChat: () => Promise; } export const useChatStore = create((set, get) => ({ selectedChat: null, selectedChatId: null, loadChat: async (chatId: string) => { const chat = await readChat(chatId); if (chat) { set({ selectedChat: chat, selectedChatId: chatId }); return chat; } throw new Error("Chat not found"); }, clearSelectedChat: () => { set({ selectedChat: null, selectedChatId: null }); }, sendMessage: async (message: Omit) => { const { selectedChat } = get(); if (!selectedChat) return ""; console.log("Sending message", message); const updatedChat = await addMessage(selectedChat.id, message); if (updatedChat) { // getting the id of the last message const lastMessageId = updatedChat.messages[updatedChat.messages.length - 1].id; set({ selectedChat: updatedChat }); chatEventEmitter.emit(CHAT_UPDATED_EVENT); // returning the id of the last message return lastMessageId; } return ""; }, removeMessage: async (messageId: string) => { const { selectedChat } = get(); if (!selectedChat) return; const updatedChat = await removeMessage(selectedChat.id, messageId); if (updatedChat) { set({ selectedChat: updatedChat }); chatEventEmitter.emit(CHAT_UPDATED_EVENT); } }, updateChatName: async (chatId: string, name: string) => { const success = await updateChatNameInStorage(chatId, name); if (success) { const { selectedChat } = get(); if (selectedChat && selectedChat.id === chatId) { set({ selectedChat: { ...selectedChat, title: name } }); chatEventEmitter.emit(CHAT_RENAMED_EVENT); } } return success; }, deleteChat: async (chatId: string) => { const success = await deleteChatInStorage(chatId); if (success) { const { selectedChat } = get(); if (selectedChat && selectedChat.id === chatId) { get().clearSelectedChat(); } chatEventEmitter.emit(CHAT_UPDATED_EVENT); } return success; }, downloadChat: async () => { const { selectedChat } = get(); if (!selectedChat) { throw new Error("No chat selected"); } try { await downloadChatAsMarkdown(selectedChat); } catch (error) { console.error("Failed to download chat:", error); throw error; } }, }));