From 18e3f1951292b3912b61d550a601e366d4b9a469 Mon Sep 17 00:00:00 2001 From: Andrew Pareles Date: Wed, 4 Dec 2024 23:49:45 -0800 Subject: [PATCH] inputbox ref is now an internal widget (and works better!) --- .../react/src/sidebar-tsx/InputBox.tsx | 79 ++++++++++++------- .../react/src/sidebar-tsx/SidebarChat.tsx | 33 +++++--- 2 files changed, 71 insertions(+), 41 deletions(-) diff --git a/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/InputBox.tsx b/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/InputBox.tsx index b84a506a..b90e218d 100644 --- a/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/InputBox.tsx +++ b/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/InputBox.tsx @@ -1,36 +1,59 @@ -// import { useEffect, useRef } from 'react' -// import { HistoryInputBox } from '../../../../../../../base/browser/ui/inputbox/inputBox.js' -// import { useService } from '../util/services.js' -// import { defaultInputBoxStyles } from '../../../../../../../platform/theme/browser/defaultStyles.js' +import React, { useEffect, useRef } from 'react'; +import { useService } from '../util/services.js'; +import { HistoryInputBox } from '../../../../../../../base/browser/ui/inputbox/inputBox.js'; +import { defaultInputBoxStyles } from '../../../../../../../platform/theme/browser/defaultStyles.js'; -// export const InputBox = ({ onChangeText, placeholder, className }: { onChangeText: (value: string) => void, placeholder: string, className: string }) => { +export const InputBox = ({ onChangeText, placeholder, historyInputBoxRef, }: { + onChangeText: (value: string) => void; + placeholder: string; + historyInputBoxRef: React.MutableRefObject; // update this whenever historyInputBoxRef.current changes +}) => { + const contextViewProvider = useService('contextViewService'); -// const domNodeRef = useRef(null) + const containerRef = useRef(null); -// const contextViewProvider = useService('contextViewService') + useEffect(() => { + if (!containerRef.current) return; + + // create and mount the HistoryInputBox + historyInputBoxRef.current = new HistoryInputBox( + containerRef.current, + contextViewProvider, + { + inputBoxStyles: { + ...defaultInputBoxStyles, + inputBackground: 'transparent', + }, + placeholder, + history: [], + flexibleHeight: true, + flexibleMaxHeight: 500, + flexibleWidth: false, + } + ); -// useEffect(() => { + historyInputBoxRef.current.onDidChange((newStr) => { + onChangeText(newStr) + }) -// const htmlNode = domNodeRef.current -// if (!htmlNode) return + // historyInputBoxRef.current.onDidHeightChange((newHeight) => { + // console.log('CHANGE height', newHeight); + // }) + // cleanup + return () => { + if (historyInputBoxRef.current) { + historyInputBoxRef.current.dispose(); + if (containerRef.current) { + while (containerRef.current.firstChild) { + containerRef.current.removeChild(containerRef.current.firstChild); + } + } + historyInputBoxRef.current = null; + } + }; + }, [onChangeText, placeholder, contextViewProvider]); // Empty dependency array since we only want to mount/unmount once -// console.log('creating inputbox') -// const widget = new HistoryInputBox(htmlNode, contextViewProvider, { -// inputBoxStyles: defaultInputBoxStyles, -// placeholder, -// history: [], -// }) - - -// widget.onDidChange((newStr) => { onChangeText(newStr) }) - -// return () => { -// console.log('disposing inputbox') -// widget.dispose() -// } -// }, [onChangeText, contextViewProvider, placeholder]) - -// return
-// } + return
; +}; diff --git a/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/SidebarChat.tsx b/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/SidebarChat.tsx index 31909bba..df90ba48 100644 --- a/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/SidebarChat.tsx +++ b/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/SidebarChat.tsx @@ -19,6 +19,8 @@ import { IDisposable } from '../../../../../../../base/common/lifecycle.js'; import { ErrorDisplay } from './ErrorDisplay.js'; import { LLMMessageServiceParams } from '../../../../../../../platform/void/common/llmMessageTypes.js'; import { getCmdKey } from '../../../getCmdKey.js' +import { InputBox } from './InputBox.js'; +import { HistoryInputBox } from '../../../../../../../base/browser/ui/inputbox/inputBox.js'; // read files from VSCode const VSReadFile = async (modelService: IModelService, uri: URI): Promise => { @@ -147,8 +149,6 @@ export const SidebarChat = () => { const threadsStateService = useService('threadsStateService') // ----- SIDEBAR CHAT state (local) ----- - // state of current message - const [instructions, setInstructions] = useState('') // the user's instructions // state of chat const [messageStream, setMessageStream] = useState(null) @@ -159,9 +159,14 @@ export const SidebarChat = () => { const sendLLMMessageService = useService('sendLLMMessageService') - const isDisabled = !instructions + // state of current message + const [instructions, setInstructions] = useState('') // the user's instructions + const onChangeText = useCallback((newStr: string) => { setInstructions(newStr) }, [setInstructions]) + const isDisabled = !instructions const formRef = useRef(null) + const inputBoxRef: React.MutableRefObject = useRef(null); + const onSubmit = async (e: FormEvent) => { e.preventDefault() @@ -223,8 +228,10 @@ export const SidebarChat = () => { setIsLoading(true) - setInstructions(''); - formRef.current?.reset(); // reset the form's text when clear instructions or unexpected behavior happens + if (inputBoxRef.current) { + inputBoxRef.current.value = ''; // this triggers onDidChangeText + inputBoxRef.current.blur(); + } threadsStateService.setStaging([]) // clear staging setLatestError(null) @@ -257,7 +264,7 @@ export const SidebarChat = () => { )} {/* message stream */} - +
{/* chatbar */}
@@ -288,20 +295,20 @@ export const SidebarChat = () => { }}> {/* input */} - {/* { setInstructions(newStr) }} - className='w-full p-2 leading-tight resize-none max-h-[50vh] overflow-auto bg-transparent border-none !outline-none' - /> */} + onChangeText={onChangeText} + historyInputBoxRef={inputBoxRef} + /> -