File size: 3,239 Bytes
e454383 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | 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<Chat>;
clearSelectedChat: () => void;
sendMessage: (message: Omit<Message, "id">) => Promise<string>;
removeMessage: (messageId: string) => Promise<void>;
updateChatName: (chatId: string, name: string) => Promise<boolean>;
deleteChat: (chatId: string) => Promise<boolean>;
downloadChat: () => Promise<void>;
}
export const useChatStore = create<ChatStore>((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<Message, "id">) => {
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;
}
},
}));
|