From dcb708758dd9812030214c7e903f835de1e8737d Mon Sep 17 00:00:00 2001 From: Mathew Pareles Date: Wed, 1 Jan 2025 21:29:56 -0500 Subject: [PATCH] fix input resize --- src/vs/base/browser/ui/inputbox/inputBox.ts | 2 +- .../browser/react/src/markdown/BlockCode.tsx | 2 +- .../browser/react/src/sidebar-tsx/Sidebar.tsx | 2 +- .../react/src/sidebar-tsx/SidebarChat.tsx | 83 +++++++++++++++++-- .../void/browser/react/src/util/inputs.tsx | 3 +- 5 files changed, 80 insertions(+), 12 deletions(-) diff --git a/src/vs/base/browser/ui/inputbox/inputBox.ts b/src/vs/base/browser/ui/inputbox/inputBox.ts index 990ee808..5751fb8d 100644 --- a/src/vs/base/browser/ui/inputbox/inputBox.ts +++ b/src/vs/base/browser/ui/inputbox/inputBox.ts @@ -159,7 +159,7 @@ export class InputBox extends Widget { this.scrollableElement = new ScrollableElement(this.element, { vertical: ScrollbarVisibility.Auto }); if (this.options.flexibleWidth) { - this.input.setAttribute('wrap', 'off'); + this.input.setAttribute('wrap', 'on'); this.mirror.style.whiteSpace = 'pre'; this.mirror.style.wordWrap = 'initial'; } diff --git a/src/vs/workbench/contrib/void/browser/react/src/markdown/BlockCode.tsx b/src/vs/workbench/contrib/void/browser/react/src/markdown/BlockCode.tsx index d3e5e5ed..beb878a2 100644 --- a/src/vs/workbench/contrib/void/browser/react/src/markdown/BlockCode.tsx +++ b/src/vs/workbench/contrib/void/browser/react/src/markdown/BlockCode.tsx @@ -83,7 +83,7 @@ export function getLanguageFromFileName(fileName: string): string { export const BlockCode = ({ text, buttonsOnHover, language }: { text: string, buttonsOnHover?: ReactNode, language?: string }) => { return (<> -
+
{buttonsOnHover === null ? null : (
diff --git a/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/Sidebar.tsx b/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/Sidebar.tsx index 65438c8d..72902c87 100644 --- a/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/Sidebar.tsx +++ b/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/Sidebar.tsx @@ -22,7 +22,7 @@ export const Sidebar = ({ className }: { className: string }) => { const { isHistoryOpen, currentTab: tab } = sidebarState const isDark = useIsDark() - 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 8d65745e..19d9a8df 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 @@ -109,6 +109,65 @@ export const IconWarning = ({ size, className = '' }: { size: number, className? ); }; + +export const IconLoading = ({ className = '' }: { className?: string }) => { + + const [loadingText, setLoadingText] = useState('.'); + + useEffect(() => { + let intervalId; + + // Function to handle the animation + const toggleLoadingText = () => { + if (loadingText === '...') { + setLoadingText('.'); + } else { + setLoadingText(loadingText + '.'); + } + }; + + // Start the animation loop + intervalId = setInterval(toggleLoadingText, 300); + + // Cleanup function to clear the interval when component unmounts + return () => clearInterval(intervalId); + }, [loadingText, setLoadingText]); + + return
{loadingText}
; + +} + +const useResizeObserver = () => { + const ref = useRef(null); + const [dimensions, setDimensions] = useState({ height: 0, width: 0 }); + + useEffect(() => { + if (ref.current) { + const resizeObserver = new ResizeObserver((entries) => { + if (entries.length > 0) { + const entry = entries[0]; + setDimensions({ + height: entry.contentRect.height, + width: entry.contentRect.width + }); + } + }); + + resizeObserver.observe(ref.current); + + return () => { + if (ref.current) + resizeObserver.unobserve(ref.current); + }; + } + }, []); + + return [ref, dimensions] as const; +}; + + + + type ButtonProps = ButtonHTMLAttributes const DEFAULT_BUTTON_SIZE = 20; export const ButtonSubmit = ({ className, disabled, ...props }: ButtonProps & Required>) => { @@ -301,8 +360,9 @@ export const SelectedFiles = ( } -const ChatBubble = ({ chatMessage }: { - chatMessage: ChatMessage +const ChatBubble = ({ chatMessage, isLoading }: { + chatMessage: ChatMessage, + isLoading?: boolean, }) => { const role = chatMessage.role @@ -325,6 +385,7 @@ const ChatBubble = ({ chatMessage }: { return
{chatbubbleContents} + {isLoading && }
} @@ -369,8 +430,12 @@ export const SidebarChat = () => { // state of current message const [instructions, setInstructions] = useState('') // the user's instructions const isDisabled = !instructions.trim() - const [formHeight, setFormHeight] = useState(0) // TODO should use resize observer instead - const [sidebarHeight, setSidebarHeight] = useState(0) + + const [sidebarRef, sidebarDimensions] = useResizeObserver() + const [formRef, formDimensions] = useResizeObserver() + + // const [formHeight, setFormHeight] = useState(0) // TODO should use resize observer instead + // const [sidebarHeight, setSidebarHeight] = useState(0) const onChangeText = useCallback((newStr: string) => { setInstructions(newStr) }, [setInstructions]) @@ -455,6 +520,8 @@ export const SidebarChat = () => { threadsStateService.setStaging([]) // clear staging + inputBoxRef.current?.focus() // focus input after submit + } const onAbort = () => { @@ -481,18 +548,18 @@ export const SidebarChat = () => { // const [_test_messages, _set_test_messages] = useState([]) return
{ if (ref) { setSidebarHeight(ref.clientHeight); } }} + ref={sidebarRef} className={`w-full h-full`} > {/* previous messages */} {previousMessages.map((message, i) => )} {/* message stream */} - + {/* {_test_messages.map((_, i) =>
div {i}
)}
{`totalHeight: ${sidebarHeight - formHeight - 30}`}
@@ -508,7 +575,7 @@ export const SidebarChat = () => { className={`right-0 left-0 m-2 z-[999] overflow-hidden ${previousMessages.length > 0 ? 'absolute bottom-0' : ''}`} >
{ if (ref) { setFormHeight(ref.clientHeight); } }} + ref={formRef} className={` flex flex-col gap-2 p-2 relative input text-left shrink-0 transition-all duration-200 diff --git a/src/vs/workbench/contrib/void/browser/react/src/util/inputs.tsx b/src/vs/workbench/contrib/void/browser/react/src/util/inputs.tsx index 59a5edb0..e89ac700 100644 --- a/src/vs/workbench/contrib/void/browser/react/src/util/inputs.tsx +++ b/src/vs/workbench/contrib/void/browser/react/src/util/inputs.tsx @@ -66,6 +66,7 @@ export const VoidInputBox = ({ onChangeText, onCreateInstance, inputBoxRef, plac { inputBoxStyles: { ...defaultInputBoxStyles, + inputForeground: "var(--vscode-foreground)", // inputBackground: 'transparent', // inputBorder: 'none', ...styles, @@ -74,7 +75,7 @@ export const VoidInputBox = ({ onChangeText, onCreateInstance, inputBoxRef, plac tooltip: '', flexibleHeight: multiline, flexibleMaxHeight: 500, - flexibleWidth: true, + flexibleWidth: false, } ] as const, [contextViewProvider, placeholder, multiline])} dispose={useCallback((instance: InputBox) => {