mirror of
https://github.com/voideditor/void
synced 2026-05-24 09:58:23 +00:00
fix thread history persistence
This commit is contained in:
parent
8c9eeaa133
commit
fb69afd5c4
5 changed files with 28 additions and 23 deletions
|
|
@ -20,6 +20,7 @@ export class SidebarWebviewProvider implements vscode.WebviewViewProvider {
|
|||
private readonly _extensionUri: vscode.Uri
|
||||
|
||||
private _webviewView?: vscode.WebviewView; // only used inside onDidChangeConfiguration
|
||||
private _webviewDeps: string[] = [];
|
||||
|
||||
constructor(context: vscode.ExtensionContext) {
|
||||
// const extensionPath = context.extensionPath // the directory where the extension is installed, might be useful later... was included in webviewProvider code
|
||||
|
|
@ -30,8 +31,10 @@ export class SidebarWebviewProvider implements vscode.WebviewViewProvider {
|
|||
if (!temp_res) throw new Error("sidebar provider: resolver was undefined")
|
||||
this._res = temp_res
|
||||
|
||||
// if it affects one of the config items webview depends on, update the webview
|
||||
// TODO should be able to move this entirely to React - make updateWebviewHTML mount once, and then send updates via postMessage from then on
|
||||
vscode.workspace.onDidChangeConfiguration(event => {
|
||||
if (event.affectsConfiguration('void.ollama.endpoint')) {
|
||||
if (this._webviewDeps.map(dep => event.affectsConfiguration(dep)).some(v => !!v)) {
|
||||
if (this._webviewView) {
|
||||
this.updateWebviewHTML(this._webviewView.webview);
|
||||
}
|
||||
|
|
@ -39,12 +42,18 @@ export class SidebarWebviewProvider implements vscode.WebviewViewProvider {
|
|||
});
|
||||
}
|
||||
|
||||
// this is updated
|
||||
private updateWebviewHTML(webview: vscode.Webview) {
|
||||
const allowed_urls = ['https://api.anthropic.com', 'https://api.openai.com', 'https://api.greptile.com'];
|
||||
this._webviewDeps = []
|
||||
|
||||
const ollamaEndpoint: string | undefined = vscode.workspace.getConfiguration('void.ollama').get('endpoint');
|
||||
this._webviewDeps.push('void.ollama.endpoint');
|
||||
if (ollamaEndpoint)
|
||||
allowed_urls.push(ollamaEndpoint);
|
||||
|
||||
const openAICompatibleEndpoint: string | undefined = vscode.workspace.getConfiguration('void.openAICompatible').get('endpoint');
|
||||
this._webviewDeps.push('void.openAICompatible.endpoint');
|
||||
if (openAICompatibleEndpoint)
|
||||
allowed_urls.push(openAICompatibleEndpoint);
|
||||
|
||||
|
|
|
|||
|
|
@ -143,13 +143,8 @@ 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)
|
||||
|
||||
webview.postMessage({ type: 'apiConfig', apiConfig } satisfies WebviewMessage)
|
||||
|
||||
}
|
||||
else if (m.type === 'getAllThreads') {
|
||||
const threads: ChatThreads = context.workspaceState.get('allThreads') ?? {}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import BlockCode from "./markdown/BlockCode";
|
|||
|
||||
import * as vscode from 'vscode'
|
||||
import { SelectedFiles } from "./components/SelectedFiles";
|
||||
import { useChat } from "./chatContext";
|
||||
import { useThreads } from "./threadsContext";
|
||||
|
||||
|
||||
const filesStr = (fullFiles: File[]) => {
|
||||
|
|
@ -69,7 +69,7 @@ const ChatBubble = ({ chatMessage }: { chatMessage: ChatMessage }) => {
|
|||
}
|
||||
|
||||
const ThreadSelector = ({ onClose }: { onClose: () => void }) => {
|
||||
const { allThreads, currentThread, switchToThread } = useChat()
|
||||
const { allThreads, currentThread, switchToThread } = useThreads()
|
||||
return (
|
||||
<div className="flex flex-col space-y-1">
|
||||
<div className="text-right">
|
||||
|
|
@ -109,7 +109,7 @@ const ThreadSelector = ({ onClose }: { onClose: () => void }) => {
|
|||
|
||||
|
||||
const Sidebar = () => {
|
||||
const { allThreads, currentThread, addMessageToHistory, startNewThread, } = useChat()
|
||||
const { allThreads, currentThread, addMessageToHistory, startNewThread, } = useThreads()
|
||||
|
||||
// state of current message
|
||||
const [selection, setSelection] = useState<Selection | null>(null) // the code the user is selecting
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import * as React from "react"
|
||||
import * as ReactDOM from "react-dom/client"
|
||||
import Sidebar from "./Sidebar"
|
||||
import { ChatProvider } from "./chatContext"
|
||||
import { ThreadsProvider } from "./threadsContext"
|
||||
|
||||
// mount the sidebar on the id="root" element
|
||||
if (typeof document === "undefined") {
|
||||
|
|
@ -9,12 +9,12 @@ if (typeof document === "undefined") {
|
|||
}
|
||||
|
||||
const rootElement = document.getElementById("root")!
|
||||
console.log("root Element", rootElement)
|
||||
console.log("Void root Element:", rootElement)
|
||||
|
||||
const extension = (
|
||||
<ChatProvider>
|
||||
<ThreadsProvider>
|
||||
<Sidebar />
|
||||
</ChatProvider>
|
||||
</ThreadsProvider>
|
||||
)
|
||||
const root = ReactDOM.createRoot(rootElement)
|
||||
root.render(extension)
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import { ChatMessage, ChatThreads } from "../shared_types"
|
|||
import { awaitVSCodeResponse, getVSCodeAPI } from "./getVscodeApi"
|
||||
|
||||
|
||||
type ChatContextValue = {
|
||||
type ThreadsContextValue = {
|
||||
readonly allThreads: ChatThreads | null,
|
||||
readonly currentThread: ChatThreads[string] | null;
|
||||
addMessageToHistory: (message: ChatMessage) => void;
|
||||
|
|
@ -11,7 +11,7 @@ type ChatContextValue = {
|
|||
startNewThread: () => void;
|
||||
}
|
||||
|
||||
const ChatContext = createContext<ChatContextValue>({} as ChatContextValue)
|
||||
const ThreadsContext = createContext<ThreadsContextValue>(undefined as unknown as ThreadsContextValue)
|
||||
|
||||
const createNewThread = () => ({
|
||||
id: new Date().getTime().toString(),
|
||||
|
|
@ -33,7 +33,7 @@ const useInstantState = <T,>(initVal: T) => {
|
|||
}
|
||||
|
||||
|
||||
function ChatProvider({ children }: { children: ReactNode }) {
|
||||
export function ThreadsProvider({ children }: { children: ReactNode }) {
|
||||
const [allThreads, setAllThreads] = useInstantState<ChatThreads>({})
|
||||
const [currentThreadId, setCurrentThreadId] = useInstantState<string | null>(null)
|
||||
|
||||
|
|
@ -41,12 +41,14 @@ function ChatProvider({ children }: { children: ReactNode }) {
|
|||
useEffect(() => {
|
||||
getVSCodeAPI().postMessage({ type: "getAllThreads" })
|
||||
awaitVSCodeResponse('allThreads')
|
||||
.then(response => { setAllThreads(response.threads) })
|
||||
.then(response => {
|
||||
setAllThreads(response.threads)
|
||||
})
|
||||
}, [setAllThreads])
|
||||
|
||||
|
||||
return (
|
||||
<ChatContext.Provider
|
||||
<ThreadsContext.Provider
|
||||
value={{
|
||||
allThreads: allThreads.current,
|
||||
currentThread: currentThreadId.current === null || allThreads.current === null ? null : allThreads.current[currentThreadId.current],
|
||||
|
|
@ -84,16 +86,15 @@ function ChatProvider({ children }: { children: ReactNode }) {
|
|||
}}
|
||||
>
|
||||
{children}
|
||||
</ChatContext.Provider>
|
||||
</ThreadsContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
function useChat(): ChatContextValue {
|
||||
const context = useContext<ChatContextValue>(ChatContext)
|
||||
export function useThreads(): ThreadsContextValue {
|
||||
const context = useContext<ThreadsContextValue>(ThreadsContext)
|
||||
if (context === undefined) {
|
||||
throw new Error("useChat must be used within a ChatProvider")
|
||||
throw new Error("useThreads must be used within a ThreadsProvider")
|
||||
}
|
||||
return context
|
||||
}
|
||||
|
||||
export { ChatProvider, useChat }
|
||||
Loading…
Reference in a new issue