From b2e3631a295f810d6f66523a6c84dabf51d9c285 Mon Sep 17 00:00:00 2001 From: Will Chen Date: Fri, 18 Apr 2025 12:32:57 -0700 Subject: [PATCH] Refactor chat input & properly update state for proposal --- src/atoms/chatAtoms.ts | 1 + src/atoms/proposalAtoms.ts | 4 ++ src/components/chat/ChatInput.tsx | 35 ++++++---- src/components/chat/HomeChatInput.tsx | 85 ++++++++++++++++++++++++ src/hooks/useProposal.ts | 28 ++++---- src/hooks/useStreamChat.ts | 3 +- src/ipc/handlers/chat_stream_handlers.ts | 10 +-- src/ipc/ipc_client.ts | 8 +-- src/lib/schemas.ts | 5 ++ src/pages/home.tsx | 9 ++- 10 files changed, 140 insertions(+), 48 deletions(-) create mode 100644 src/atoms/proposalAtoms.ts create mode 100644 src/components/chat/HomeChatInput.tsx diff --git a/src/atoms/chatAtoms.ts b/src/atoms/chatAtoms.ts index 6a26399..36aac80 100644 --- a/src/atoms/chatAtoms.ts +++ b/src/atoms/chatAtoms.ts @@ -11,6 +11,7 @@ export const selectedChatIdAtom = atom(null); export const isStreamingAtom = atom(false); export const chatInputValueAtom = atom(""); +export const homeChatInputValueAtom = atom(""); // Atoms for chat list management export const chatsAtom = atom([]); diff --git a/src/atoms/proposalAtoms.ts b/src/atoms/proposalAtoms.ts new file mode 100644 index 0000000..d9f19ae --- /dev/null +++ b/src/atoms/proposalAtoms.ts @@ -0,0 +1,4 @@ +import { atom } from "jotai"; +import type { Proposal, ProposalResult } from "@/lib/schemas"; + +export const proposalResultAtom = atom(null); diff --git a/src/components/chat/ChatInput.tsx b/src/components/chat/ChatInput.tsx index 8c24a52..f347c71 100644 --- a/src/components/chat/ChatInput.tsx +++ b/src/components/chat/ChatInput.tsx @@ -11,12 +11,12 @@ import { Loader2, } from "lucide-react"; import type React from "react"; -import { useEffect, useRef, useState } from "react"; +import { useCallback, useEffect, useRef, useState } from "react"; import { ModelPicker } from "@/components/ModelPicker"; import { useSettings } from "@/hooks/useSettings"; import { IpcClient } from "@/ipc/ipc_client"; -import { chatInputValueAtom } from "@/atoms/chatAtoms"; -import { useAtom } from "jotai"; +import { chatInputValueAtom, chatMessagesAtom } from "@/atoms/chatAtoms"; +import { useAtom, useSetAtom } from "jotai"; import { useStreamChat } from "@/hooks/useStreamChat"; import { useChats } from "@/hooks/useChats"; import { selectedAppIdAtom } from "@/atoms/appAtoms"; @@ -26,7 +26,8 @@ import { Label } from "@/components/ui/label"; import { Switch } from "@/components/ui/switch"; import { useProposal } from "@/hooks/useProposal"; import { Proposal } from "@/lib/schemas"; - +import type { Message } from "@/ipc/ipc_types"; +import { isPreviewOpenAtom } from "@/atoms/viewAtoms"; interface ChatInputActionsProps { proposal: Proposal; onApprove: () => void; @@ -36,12 +37,7 @@ interface ChatInputActionsProps { isRejecting: boolean; // State for rejecting } -interface ChatInputProps { - chatId?: number; - onSubmit?: () => void; -} - -export function ChatInput({ chatId, onSubmit }: ChatInputProps) { +export function ChatInput({ chatId }: { chatId?: number }) { const [inputValue, setInputValue] = useAtom(chatInputValueAtom); const textareaRef = useRef(null); const { settings, updateSettings, isAnyProviderSetup } = useSettings(); @@ -51,6 +47,8 @@ export function ChatInput({ chatId, onSubmit }: ChatInputProps) { const [showError, setShowError] = useState(true); const [isApproving, setIsApproving] = useState(false); // State for approving const [isRejecting, setIsRejecting] = useState(false); // State for rejecting + const [messages, setMessages] = useAtom(chatMessagesAtom); + const setIsPreviewOpen = useSetAtom(isPreviewOpenAtom); // Use the hook to fetch the proposal const { @@ -80,10 +78,19 @@ export function ChatInput({ chatId, onSubmit }: ChatInputProps) { } }, [error]); + const fetchChatMessages = useCallback(async () => { + if (!chatId) { + setMessages([]); + return; + } + const chat = await IpcClient.getInstance().getChat(chatId); + setMessages(chat.messages); + }, [chatId, setMessages]); + const handleKeyPress = (e: React.KeyboardEvent) => { if (e.key === "Enter" && !e.shiftKey) { e.preventDefault(); - submitHandler(); + handleSubmit(); } }; @@ -96,7 +103,6 @@ export function ChatInput({ chatId, onSubmit }: ChatInputProps) { setInputValue(""); await streamMessage({ prompt: currentInput, chatId }); }; - const submitHandler = onSubmit ? onSubmit : handleSubmit; const handleCancel = () => { if (chatId) { @@ -133,7 +139,9 @@ export function ChatInput({ chatId, onSubmit }: ChatInputProps) { setError((err as Error)?.message || "An error occurred while approving"); } finally { setIsApproving(false); + setIsPreviewOpen(true); refreshProposal(); + fetchChatMessages(); } }; @@ -162,6 +170,7 @@ export function ChatInput({ chatId, onSubmit }: ChatInputProps) { } finally { setIsRejecting(false); refreshProposal(); + fetchChatMessages(); } }; @@ -236,7 +245,7 @@ export function ChatInput({ chatId, onSubmit }: ChatInputProps) { ) : (