diff --git a/extensions/void/src/extension.ts b/extensions/void/src/extension.ts index 71c2426a..175bbf02 100644 --- a/extensions/void/src/extension.ts +++ b/extensions/void/src/extension.ts @@ -143,6 +143,7 @@ export function activate(context: vscode.ExtensionContext) { await approvalCodeLensProvider.addNewApprovals(editor, suggestedEdits) } else if (m.type === 'getApiConfig') { + context.workspaceState.update('allThreads', {}) const apiConfig = getApiConfig() console.log('Api config:', apiConfig) diff --git a/extensions/void/src/sidebar/Sidebar.tsx b/extensions/void/src/sidebar/Sidebar.tsx index 18540b99..807f1907 100644 --- a/extensions/void/src/sidebar/Sidebar.tsx +++ b/extensions/void/src/sidebar/Sidebar.tsx @@ -109,11 +109,7 @@ const ThreadSelector = ({ onClose }: { onClose: () => void }) => { const Sidebar = () => { - const { - currentThread, - addMessageToHistory, - startNewThread, - } = useChat() + const { allThreads, currentThread, addMessageToHistory, startNewThread, } = useChat() // state of current message const [selection, setSelection] = useState(null) // the code the user is selecting diff --git a/extensions/void/src/sidebar/chatContext.tsx b/extensions/void/src/sidebar/chatContext.tsx index 96bf02f8..4962c45d 100644 --- a/extensions/void/src/sidebar/chatContext.tsx +++ b/extensions/void/src/sidebar/chatContext.tsx @@ -1,11 +1,11 @@ -import React, { ReactNode, createContext, useContext, useEffect, useState, } from "react" +import React, { ReactNode, createContext, useCallback, useContext, useEffect, useRef, useState, } from "react" import { ChatMessage, ChatThreads } from "../shared_types" import { awaitVSCodeResponse, getVSCodeAPI } from "./getVscodeApi" type ChatContextValue = { - allThreads: ChatThreads | null, - currentThread: ChatThreads[string] | null; + readonly allThreads: ChatThreads | null, + readonly currentThread: ChatThreads[string] | null; addMessageToHistory: (message: ChatMessage) => void; switchToThread: (threadId: string) => void; startNewThread: () => void; @@ -20,43 +20,69 @@ const createNewThread = () => ({ }) +// const [stateRef, setState] = useInstantState(initVal) +// setState instantly changes the value of stateRef instead of having to wait until the next render +const useInstantState = (initVal: T) => { + const stateRef = useRef(initVal) + const [_, setS] = useState(initVal) + const setState = useCallback((newVal: T) => { + setS(newVal); + stateRef.current = newVal; + }, []) + return [stateRef as React.RefObject, setState] as const // make s.current readonly - setState handles all changes +} + + function ChatProvider({ children }: { children: ReactNode }) { - const [allThreads, setAllThreads] = useState({}) - const [currentThreadId, setCurrentThreadId] = useState(null) + const [allThreads, setAllThreads] = useInstantState({}) + const [currentThreadId, setCurrentThreadId] = useInstantState(null) // this loads allThreads in on mount useEffect(() => { getVSCodeAPI().postMessage({ type: "getAllThreads" }) awaitVSCodeResponse('allThreads') .then(response => { setAllThreads(response.threads) }) - }, []) - - + }, [setAllThreads]) return ( { - let currentThread = currentThreadId === null ? createNewThread() : allThreads[currentThreadId] - setAllThreads((threads) => ({ - ...threads, + let currentThread: ChatThreads[string] + if (!(currentThreadId.current === null || allThreads.current === null)) { + currentThread = allThreads.current[currentThreadId.current] + } + else { + currentThread = createNewThread() + setCurrentThreadId(currentThread.id) + } + + console.log('adding message: ', currentThreadId, currentThread.id, message.displayContent) + console.log('allThreads', allThreads) + + setAllThreads({ + ...allThreads.current, [currentThread.id]: { ...currentThread, messages: [...currentThread.messages, message], } - })) + }) + getVSCodeAPI().postMessage({ type: "persistThread", thread: currentThread }) }, - currentThread: currentThreadId !== null ? allThreads[currentThreadId] : null, - switchToThread: (threadId: string) => { setCurrentThreadId(threadId); }, + switchToThread: (threadId: string) => { + setCurrentThreadId(threadId); + }, startNewThread: () => { const newThread = createNewThread() - setAllThreads(threads => ({ - ...threads, + setAllThreads({ + ...allThreads.current, [newThread.id]: newThread - })) + }) + setCurrentThreadId(newThread.id) }, }} >