diff --git a/extensions/void/src/sidebar/Sidebar.tsx b/extensions/void/src/sidebar/Sidebar.tsx index ddcf658b..41b3836c 100644 --- a/extensions/void/src/sidebar/Sidebar.tsx +++ b/extensions/void/src/sidebar/Sidebar.tsx @@ -9,6 +9,7 @@ import { MarkdownRender, BlockCode } from "./MarkdownRender"; import * as vscode from 'vscode' import { FilesSelector, IncludedFiles } from "./components/Files"; import { useChat } from "./context"; +import ThreadHistory from "./components/ThreadHistory"; const filesStr = (fullFiles: File[]) => { @@ -83,7 +84,7 @@ const useInstantState = (initVal: T) => { const Sidebar = () => { - const { chatMessageHistory, addMessageToHistory, setPreviousThreads } = useChat() + const { chatMessageHistory, addMessageToHistory, setPreviousThreads, previousThreads } = useChat() // state of current message const [selection, setSelection] = useState(null) // the code the user is selecting @@ -128,7 +129,7 @@ const Sidebar = () => { setApiConfig(m.apiConfig) } - // when get apiConfig, set + // incoming thread history else if (m.type === 'threadHistory') { setPreviousThreads(m.threads) } @@ -268,6 +269,7 @@ const Sidebar = () => { } + {!!previousThreads.length && } diff --git a/extensions/void/src/sidebar/context.tsx b/extensions/void/src/sidebar/context.tsx index dabb836b..39cd0586 100644 --- a/extensions/void/src/sidebar/context.tsx +++ b/extensions/void/src/sidebar/context.tsx @@ -5,31 +5,45 @@ import React, { useEffect, useState, } from "react" -import * as vscode from "vscode" -import { ChatMessage, ChatThread, Selection } from "../shared_types" +import { ChatMessage, ChatThread } from "../shared_types" import { getVSCodeAPI } from "./getVscodeApi" +const createEmptyThread = () => ({ + id: "", + createdAt: "", + messages: [], +}) + +const createNewThread = () => ({ + id: new Date().getTime().toString(), + createdAt: new Date().toISOString(), + messages: [], +}) + interface IChatProviderProps { chatMessageHistory: ChatMessage[] addMessageToHistory: (message: ChatMessage) => void setPreviousThreads: (threads: any) => void + previousThreads: ChatThread[] + selectThread: (thread: ChatThread) => void } const defaults = { chatMessageHistory: [], addMessageToHistory: () => {}, setPreviousThreads: () => {}, - thread: { - id: "", - createdAt: "", - messages: [], - }, + // placeholder for thread until first message is sent so that createdAt date is accurate + thread: createEmptyThread(), + previousThreads: [], + selectThread: () => {}, } const ChatContext = createContext(defaults) function ChatProvider({ children }: { children: ReactNode }) { - const [previousThreads, setPreviousThreads] = useState([]) + const [previousThreads, setPreviousThreads] = useState( + defaults.previousThreads + ) const [thread, setThread] = useState(defaults.thread) useEffect(() => { @@ -45,20 +59,28 @@ function ChatProvider({ children }: { children: ReactNode }) { const addMessageToHistory = (message: ChatMessage) => { setThread((prev) => ({ ...prev, - ...(!thread.id && { - id: new Date().getTime().toString(), - createdAt: new Date().toISOString(), - }), + // if there is no thread, create a new one with current timestamp + ...(!thread.id && createNewThread()), messages: [...prev.messages, message], })) } + const handleReceiveThreadHistory = (threads: ChatThread[]) => + setPreviousThreads( + threads.sort( + (a, b) => + new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime() + ) + ) + return ( {children}