diff --git a/app/components/chat.tsx b/app/components/chat.tsx index b80bf5a18b1..39f171edb51 100644 --- a/app/components/chat.tsx +++ b/app/components/chat.tsx @@ -421,9 +421,104 @@ export function ChatActions(props: { ); } -export function Chat() { - type RenderMessage = Message & { preview?: boolean }; +type RenderMessage = Message & { preview?: boolean }; + +export function ChatItem(props: { + message: RenderMessage; + i: number; + fontSize: number; + onUserStop: any; + onDelete: any; + onResend: any; + onRightClick: any; + onDoubleClickCapture: any; + scrollRef: any; +}) { + const message = props.message; + const i = props.i; + const isUser = message.role === "user"; + const showActions = + i > 0 && !(message.preview || message.content.length === 0); + const showTyping = message.preview || message.streaming; + return ( +
+
+
+ +
+ {showTyping && ( +
+ {Locale.Chat.Typing} +
+ )} +
+ {showActions && ( +
+ {message.streaming ? ( +
props.onUserStop(message.id ?? i)} + > + {Locale.Chat.Actions.Stop} +
+ ) : ( + <> +
props.onDelete(i)} + > + {Locale.Chat.Actions.Delete} +
+ {!isUser && ( +
props.onResend(message.id ?? i)} + > + {Locale.Chat.Actions.Retry} +
+ )} + + )} + +
copyToClipboard(message.content)} + > + {Locale.Chat.Actions.Copy} +
+
+ )} + props.onRightClick(e, message)} + onDoubleClickCapture={() => + props.onDoubleClickCapture(message.content) + } + fontSize={props.fontSize} + parentRef={props.scrollRef} + /> +
+ {!isUser && !message.preview && ( +
+
+ {message.date.toLocaleString()} +
+
+ )} +
+
+ ); +} + +export function Chat() { const chatStore = useChatStore(); const [session, sessionIndex] = useChatStore((state) => [ state.currentSession(), @@ -497,7 +592,7 @@ export function Chat() { } else if (!config.disablePromptHint && n < SEARCH_TEXT_LIMIT) { // check if need to trigger auto completion if (text.startsWith("/")) { - let searchText = text.slice(1); + const searchText = text.slice(1); onSearch(searchText); } } @@ -505,7 +600,7 @@ export function Chat() { // submit user input const onUserSubmit = () => { - if (userInput.length <= 0) return; + if (userInput.length <= 0 || isLoading) return; setIsLoading(true); chatStore.onUserInput(userInput).then(() => setIsLoading(false)); setBeforeInput(userInput); @@ -561,16 +656,16 @@ export function Chat() { return lastUserMessageIndex; }; - const deleteMessage = (userIndex: number) => { + const deleteMessage = (messageIndex: number) => { chatStore.updateCurrentSession((session) => - session.messages.splice(userIndex, 2), + session.messages.splice(messageIndex, 1), ); }; - const onDelete = (botMessageId: number) => { - const userIndex = findLastUserIndex(botMessageId); - if (userIndex === null) return; - deleteMessage(userIndex); + const onDelete = (messageIndex: number) => { + if (messageIndex > 0) { + deleteMessage(messageIndex - 1); + } }; const onResend = (botMessageId: number) => { @@ -585,8 +680,12 @@ export function Chat() { inputRef.current?.focus(); }; - const context: RenderMessage[] = session.context.slice(); + const onDoubleClickCapture = (content: string) => { + if (!isMobileScreen) return; + setUserInput(content); + }; + const context: RenderMessage[] = session.context.slice(); const accessStore = useAccessStore(); if ( @@ -722,91 +821,20 @@ export function Chat() { setAutoScroll(false); }} > - {messages.map((message, i) => { - const isUser = message.role === "user"; - const showActions = - !isUser && - i > 0 && - !(message.preview || message.content.length === 0); - const showTyping = message.preview || message.streaming; - - return ( -
-
-
- -
- {showTyping && ( -
- {Locale.Chat.Typing} -
- )} -
- {showActions && ( -
- {message.streaming ? ( -
onUserStop(message.id ?? i)} - > - {Locale.Chat.Actions.Stop} -
- ) : ( - <> -
onDelete(message.id ?? i)} - > - {Locale.Chat.Actions.Delete} -
-
onResend(message.id ?? i)} - > - {Locale.Chat.Actions.Retry} -
- - )} - -
copyToClipboard(message.content)} - > - {Locale.Chat.Actions.Copy} -
-
- )} - onRightClick(e, message)} - onDoubleClickCapture={() => { - if (!isMobileScreen) return; - setUserInput(message.content); - }} - fontSize={fontSize} - parentRef={scrollRef} - /> -
- {!isUser && !message.preview && ( -
-
- {message.date.toLocaleString()} -
-
- )} -
-
- ); - })} + {messages.map((message, i) => ( + + ))}