fix ref issues with useInstantState

This commit is contained in:
Andrew 2024-10-11 19:18:28 -07:00
parent 3e308f2082
commit 0158e2fd5d
3 changed files with 46 additions and 23 deletions

View file

@ -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)

View file

@ -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<Selection | null>(null) // the code the user is selecting

View file

@ -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 = <T,>(initVal: T) => {
const stateRef = useRef<T>(initVal)
const [_, setS] = useState<T>(initVal)
const setState = useCallback((newVal: T) => {
setS(newVal);
stateRef.current = newVal;
}, [])
return [stateRef as React.RefObject<T>, setState] as const // make s.current readonly - setState handles all changes
}
function ChatProvider({ children }: { children: ReactNode }) {
const [allThreads, setAllThreads] = useState<ChatThreads>({})
const [currentThreadId, setCurrentThreadId] = useState<string | null>(null)
const [allThreads, setAllThreads] = useInstantState<ChatThreads>({})
const [currentThreadId, setCurrentThreadId] = useInstantState<string | null>(null)
// this loads allThreads in on mount
useEffect(() => {
getVSCodeAPI().postMessage({ type: "getAllThreads" })
awaitVSCodeResponse('allThreads')
.then(response => { setAllThreads(response.threads) })
}, [])
}, [setAllThreads])
return (
<ChatContext.Provider
value={{
allThreads,
allThreads: allThreads.current,
currentThread: currentThreadId.current === null || allThreads.current === null ? null : allThreads.current[currentThreadId.current],
addMessageToHistory: (message: ChatMessage) => {
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)
},
}}
>