Skip to content

Commit 7c3d763

Browse files
committed
easier approach
1 parent 7db7a63 commit 7c3d763

File tree

4 files changed

+17
-37
lines changed

4 files changed

+17
-37
lines changed

tools/server/public/index.html.gz

-329 Bytes
Binary file not shown.

tools/server/webui/src/components/ChatScreen.tsx

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
1+
import { useEffect, useMemo, useState } from 'react';
22
import { CallbackGeneratedChunk, useAppContext } from '../utils/app.context';
33
import ChatMessage from './ChatMessage';
44
import { CanvasType, Message, PendingMessage } from '../utils/types';
@@ -103,6 +103,10 @@ export default function ChatScreen() {
103103

104104
const textarea: ChatTextareaApi = useChatTextarea(prefilledMsg.content());
105105

106+
const { extraContext, clearExtraContext } = useVSCodeContext(textarea);
107+
// TODO: improve this when we have "upload file" feature
108+
const currExtra: Message['extra'] = extraContext ? [extraContext] : undefined;
109+
106110
// keep track of leaf node for rendering
107111
const [currNodeId, setCurrNodeId] = useState<number>(-1);
108112
const messages: MessageDisplay[] = useMemo(() => {
@@ -128,7 +132,7 @@ export default function ChatScreen() {
128132
scrollToBottom(true);
129133
};
130134

131-
const sendNewMessage = useCallback(async () => {
135+
const sendNewMessage = async () => {
132136
const lastInpMsg = textarea.value();
133137
if (lastInpMsg.trim().length === 0 || isGenerating(currConvId ?? ''))
134138
return;
@@ -137,10 +141,6 @@ export default function ChatScreen() {
137141
setCurrNodeId(-1);
138142
// get the last message node
139143
const lastMsgNodeId = messages.at(-1)?.msg.id ?? null;
140-
// TODO: improve this when we have "upload file" feature
141-
const currExtra = extraContextRef.current
142-
? [extraContextRef.current]
143-
: undefined;
144144
if (
145145
!(await sendMessage(
146146
currConvId,
@@ -155,17 +155,10 @@ export default function ChatScreen() {
155155
}
156156
// OK
157157
clearExtraContext();
158-
}, [textarea, currConvId, isGenerating, messages, sendMessage, onChunk]);
159-
160-
const { extraContext, clearExtraContext } = useVSCodeContext(
161-
textarea,
162-
sendNewMessage
163-
);
164-
const extraContextRef = useRef(extraContext);
158+
};
165159

166-
useEffect(() => {
167-
extraContextRef.current = extraContext;
168-
}, [extraContext]);
160+
// for vscode context
161+
textarea.refOnSubmit.current = sendNewMessage;
169162

170163
const handleEditMessage = async (msg: Message, content: string) => {
171164
if (!viewingChat) return;

tools/server/webui/src/components/useChatTextarea.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ export interface ChatTextareaApi {
3737
setValue: (value: string) => void;
3838
focus: () => void;
3939
ref: React.RefObject<HTMLTextAreaElement>;
40+
refOnSubmit: React.MutableRefObject<(() => void) | null>; // Submit handler
4041
onInput: (event: React.FormEvent<HTMLTextAreaElement>) => void; // Input handler
4142
}
4243

@@ -46,6 +47,7 @@ export interface ChatTextareaApi {
4647
export function useChatTextarea(initValue: string): ChatTextareaApi {
4748
const [savedInitValue, setSavedInitValue] = useState<string>(initValue);
4849
const textareaRef = useRef<HTMLTextAreaElement>(null);
50+
const onSubmitRef = useRef<(() => void) | null>(null);
4951

5052
// Effect to set initial value and height on mount or when initValue changes
5153
useEffect(() => {
@@ -91,6 +93,7 @@ export function useChatTextarea(initValue: string): ChatTextareaApi {
9193
}
9294
},
9395
ref: textareaRef,
96+
refOnSubmit: onSubmitRef,
9497
onInput: handleInput,
9598
};
9699
}

tools/server/webui/src/utils/llama-vscode.ts

Lines changed: 5 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useEffect, useRef, useState } from 'react';
1+
import { useEffect, useState } from 'react';
22
import { MessageExtraContext } from './types';
33
import { ChatTextareaApi } from '../components/useChatTextarea.ts';
44

@@ -15,25 +15,14 @@ interface SetTextEvData {
1515
* window.postMessage({ command: 'setText', text: 'Spot the syntax error', context: 'def test()\n return 123' }, '*');
1616
*/
1717

18-
export const useVSCodeContext = (
19-
textarea: ChatTextareaApi,
20-
onSend?: () => void
21-
) => {
22-
const [extraContext, _setExtraContext] = useState<MessageExtraContext | null>(
18+
export const useVSCodeContext = (textarea: ChatTextareaApi) => {
19+
const [extraContext, setExtraContext] = useState<MessageExtraContext | null>(
2320
null
2421
);
2522

26-
// Use ref to store the latest value
27-
const extraContextRef = useRef(extraContext);
28-
29-
const setExtraContext = (value: MessageExtraContext | null) => {
30-
extraContextRef.current = value;
31-
_setExtraContext(value);
32-
};
3323
// Accept setText message from a parent window and set inputMsg and extraContext
3424
useEffect(() => {
3525
const handleMessage = (event: MessageEvent) => {
36-
if (event.source !== window.parent) return;
3726
if (event.data?.command === 'setText') {
3827
const data: SetTextEvData = event.data;
3928
textarea.setValue(data?.text);
@@ -44,18 +33,13 @@ export const useVSCodeContext = (
4433
});
4534
}
4635
textarea.focus();
47-
if (onSend && data?.text) {
48-
// Use setTimeout to ensure state updates are processed
49-
setTimeout(() => {
50-
onSend();
51-
}, 50);
52-
}
36+
textarea.refOnSubmit.current?.();
5337
}
5438
};
5539

5640
window.addEventListener('message', handleMessage);
5741
return () => window.removeEventListener('message', handleMessage);
58-
}, [textarea, onSend]);
42+
}, [textarea]);
5943

6044
// Add a keydown listener that sends the "escapePressed" message to the parent window
6145
useEffect(() => {

0 commit comments

Comments
 (0)