Refactor: Remove redundant message state sync in ChatContainer (#4941)

* remove redundant message state sync in ChatContainer

* small lint

---------

Co-authored-by: Timothy Carambat <rambat1010@gmail.com>
This commit is contained in:
Sean Hatfield 2026-02-09 12:54:40 -08:00 committed by GitHub
parent 0da728fc50
commit 4a61008b72
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 8 additions and 27 deletions

View File

@ -32,7 +32,6 @@ const MAX_EDIT_STACK_SIZE = 100;
export default function PromptInput({
submit,
onChange,
isStreaming,
sendCommand,
attachments = [],
@ -51,7 +50,6 @@ export default function PromptInput({
// Synchronizes prompt input value with localStorage, scoped to the current thread.
usePromptInputStorage({
onChange,
promptInput,
setPromptInput,
});
@ -228,7 +226,6 @@ export default function PromptInput({
pasteText +
promptInput.substring(end);
setPromptInput(newPromptInput);
onChange({ target: { value: newPromptInput } });
// Set the cursor position after the pasted text
// we need to use setTimeout to prevent the cursor from being set to the end of the text
@ -243,7 +240,6 @@ export default function PromptInput({
function handleChange(e) {
debouncedSaveState(-1);
onChange(e);
watchForSlash(e);
watchForAt(e);
adjustTextArea(e);

View File

@ -26,7 +26,6 @@ import useChatContainerQuickScroll from "@/hooks/useChatContainerQuickScroll";
export default function ChatContainer({ workspace, knownHistory = [] }) {
const { threadSlug = null } = useParams();
const [message, setMessage] = useState("");
const [loadingResponse, setLoadingResponse] = useState(false);
const [chatHistory, setChatHistory] = useState(knownHistory);
const [socketId, setSocketId] = useState(null);
@ -34,11 +33,6 @@ export default function ChatContainer({ workspace, knownHistory = [] }) {
const { files, parseAttachments } = useContext(DndUploaderContext);
const { chatHistoryRef } = useChatContainerQuickScroll();
// Maintain state of message from whatever is in PromptInput
const handleMessageChange = (event) => {
setMessage(event.target.value);
};
const { listening, resetTranscript } = useSpeechRecognition({
clearTranscriptOnListen: true,
});
@ -50,10 +44,6 @@ export default function ChatContainer({ workspace, knownHistory = [] }) {
* @param {'replace' | 'append'} writeMode - Replace current text or append to existing text (default: replace)
*/
function setMessageEmit(messageContent = "", writeMode = "replace") {
if (writeMode === "append") setMessage((prev) => prev + messageContent);
else setMessage(messageContent ?? "");
// Push the update to the PromptInput component (same logic as above to keep in sync)
window.dispatchEvent(
new CustomEvent(PROMPT_INPUT_EVENT, {
detail: { messageContent, writeMode },
@ -63,11 +53,14 @@ export default function ChatContainer({ workspace, knownHistory = [] }) {
const handleSubmit = async (event) => {
event.preventDefault();
if (!message || message === "") return false;
const currentMessage =
document.getElementById(PROMPT_INPUT_ID)?.value || "";
if (!currentMessage) return false;
const prevChatHistory = [
...chatHistory,
{
content: message,
content: currentMessage,
role: "user",
attachments: parseAttachments(),
},
@ -75,7 +68,7 @@ export default function ChatContainer({ workspace, knownHistory = [] }) {
content: "",
role: "assistant",
pending: true,
userMessage: message,
userMessage: currentMessage,
animate: true,
},
];
@ -137,7 +130,7 @@ export default function ChatContainer({ workspace, knownHistory = [] }) {
// @note: `message` will not work here since it is not updated yet.
// If text is still empty, after this, then we should just return.
if (writeMode === "append") {
const currentText = document.getElementById(PROMPT_INPUT_ID)?.value;
const currentText = document.getElementById(PROMPT_INPUT_ID)?.value ?? "";
text = currentText + text;
}
@ -321,7 +314,6 @@ export default function ChatContainer({ workspace, knownHistory = [] }) {
</MetricsProvider>
<PromptInput
submit={handleSubmit}
onChange={handleMessageChange}
isStreaming={loadingResponse}
sendCommand={sendCommand}
attachments={files}

View File

@ -20,16 +20,11 @@ import { safeJsonParse } from "@/utils/request";
* ```
*
* @param {Object} props
* @param {Function} props.onChange - Callback invoked when restoring saved value, receives `{ target: { value: string } }`
* @param {string} props.promptInput - Current prompt input value to sync
* @param {Function} props.setPromptInput - State setter function for prompt input
* @returns {void}
*/
export default function usePromptInputStorage({
onChange,
promptInput,
setPromptInput,
}) {
export default function usePromptInputStorage({ promptInput, setPromptInput }) {
const { threadSlug = null, slug: workspaceSlug } = useParams();
useEffect(() => {
const serializedPromptInputMap =
@ -40,8 +35,6 @@ export default function usePromptInputStorage({
const userPromptInputValue = promptInputMap[threadSlug ?? workspaceSlug];
if (userPromptInputValue) {
setPromptInput(userPromptInputValue);
// Notify parent component so message state is synchronized
onChange({ target: { value: userPromptInputValue } });
}
}, []);