summaryrefslogtreecommitdiff
path: root/examples/server/webui/src/components/ChatScreen.tsx
diff options
context:
space:
mode:
authorfirecoperana <xuqiaowei1124@gmail.com>2025-07-20 05:33:55 -0500
committerGitHub <noreply@github.com>2025-07-20 12:33:55 +0200
commitd44c2d3f5aeab25a9405896f48a36082cee5d8ac (patch)
tree6768d4d8c72fb0b5c7b4a5a4187d2eccb292f0ad /examples/server/webui/src/components/ChatScreen.tsx
parentf989fb03bd12752ad6e93717ca4bd298d5001d99 (diff)
Webui: New Features for Conversations, Settings, and Chat Messages (#618)main
* Webui: add Rename/Upload conversation in header and sidebar webui: don't change modified date when renaming conversation * webui: add a preset feature to the settings #14649 * webui: Add editing assistant messages #13522 Webui: keep the following message while editing assistance response. webui: change icon to edit message * webui: DB import and export #14347 * webui: Wrap long numbers instead of infinite horizontal scroll (#14062) fix sidebar being covered by main content #14082 --------- Co-authored-by: firecoperana <firecoperana>
Diffstat (limited to 'examples/server/webui/src/components/ChatScreen.tsx')
-rw-r--r--examples/server/webui/src/components/ChatScreen.tsx57
1 files changed, 45 insertions, 12 deletions
diff --git a/examples/server/webui/src/components/ChatScreen.tsx b/examples/server/webui/src/components/ChatScreen.tsx
index 29ab5ea6..9bb333de 100644
--- a/examples/server/webui/src/components/ChatScreen.tsx
+++ b/examples/server/webui/src/components/ChatScreen.tsx
@@ -99,6 +99,7 @@ export default function ChatScreen() {
pendingMessages,
canvasData,
replaceMessageAndGenerate,
+ continueMessageAndGenerate,
} = useAppContext();
const textarea: ChatTextareaApi = useChatTextarea(prefilledMsg.content());
@@ -187,6 +188,20 @@ export default function ChatScreen() {
scrollToBottom(false);
};
+ const handleContinueMessage = async (msg: Message, content: string) => {
+ if (!viewingChat || !continueMessageAndGenerate) return;
+ setCurrNodeId(msg.id);
+ scrollToBottom(false);
+ await continueMessageAndGenerate(
+ viewingChat.conv.id,
+ msg.id,
+ content,
+ onChunk
+ );
+ setCurrNodeId(-1);
+ scrollToBottom(false);
+ };
+
const hasCanvas = !!canvasData;
useEffect(() => {
@@ -204,7 +219,7 @@ export default function ChatScreen() {
// due to some timing issues of StorageUtils.appendMsg(), we need to make sure the pendingMsg is not duplicated upon rendering (i.e. appears once in the saved conversation and once in the pendingMsg)
const pendingMsgDisplay: MessageDisplay[] =
- pendingMsg && messages.at(-1)?.msg.id !== pendingMsg.id
+ pendingMsg && !messages.some((m) => m.msg.id === pendingMsg.id) // Only show if pendingMsg is not an existing message being continued
? [
{
msg: pendingMsg,
@@ -236,17 +251,35 @@ export default function ChatScreen() {
{/* placeholder to shift the message to the bottom */}
{viewingChat ? '' : 'Send a message to start'}
</div>
- {[...messages, ...pendingMsgDisplay].map((msg) => (
- <ChatMessage
- key={msg.msg.id}
- msg={msg.msg}
- siblingLeafNodeIds={msg.siblingLeafNodeIds}
- siblingCurrIdx={msg.siblingCurrIdx}
- onRegenerateMessage={handleRegenerateMessage}
- onEditMessage={handleEditMessage}
- onChangeSibling={setCurrNodeId}
- />
- ))}
+ {[...messages, ...pendingMsgDisplay].map((msgDisplay) => {
+ const actualMsgObject = msgDisplay.msg;
+ // Check if the current message from the list is the one actively being generated/continued
+ const isThisMessageTheActivePendingOne =
+ pendingMsg?.id === actualMsgObject.id;
+
+ return (
+ <ChatMessage
+ key={actualMsgObject.id}
+ // If this message is the active pending one, use the live object from pendingMsg state (which has streamed content).
+ // Otherwise, use the version from the messages array (from storage).
+ msg={
+ isThisMessageTheActivePendingOne
+ ? pendingMsg
+ : actualMsgObject
+ }
+ siblingLeafNodeIds={msgDisplay.siblingLeafNodeIds}
+ siblingCurrIdx={msgDisplay.siblingCurrIdx}
+ onRegenerateMessage={handleRegenerateMessage}
+ onEditMessage={handleEditMessage}
+ onChangeSibling={setCurrNodeId}
+ // A message is pending if it's the actively streaming one OR if it came from pendingMsgDisplay (for new messages)
+ isPending={
+ isThisMessageTheActivePendingOne || msgDisplay.isPending
+ }
+ onContinueMessage={handleContinueMessage}
+ />
+ );
+ })}
</div>
{/* chat input */}