fix for duplicate user message

frdel committed Sep 3, 2025 at 21:03 UTC 739bfe98308dfb54ff1ba1f5ba7f3bacb73aab66
1 file changed +43 -20
webui/js/messages.js
+43 -20
@@ -402,31 +402,55 @@ export function drawMessageUser(
402 kvps = null,
403 latex = false
404 ) {
405 - const messageDiv = document.createElement("div");
406 - messageDiv.classList.add("message", "message-user");
405 + // Find existing message div or create new one
406 + let messageDiv = messageContainer.querySelector(".message");
407 + if (!messageDiv) {
408 + messageDiv = document.createElement("div");
409 + messageDiv.classList.add("message", "message-user");
410 + messageContainer.appendChild(messageDiv);
411 + } else {
412 + // Ensure it has the correct classes if it already exists
413 + messageDiv.className = "message message-user";
414 + }
415
408 - const headingElement = document.createElement("h4");
409 - headingElement.classList.add("msg-heading");
416 + // Handle heading
417 + let headingElement = messageDiv.querySelector(".msg-heading");
418 + if (!headingElement) {
419 + headingElement = document.createElement("h4");
420 + headingElement.classList.add("msg-heading");
421 + messageDiv.insertBefore(headingElement, messageDiv.firstChild);
422 + }
423 headingElement.innerHTML = `${heading} <span class='icon material-symbols-outlined'>person</span>`;
411 - messageDiv.appendChild(headingElement);
424
425 + // Handle content
426 + let textDiv = messageDiv.querySelector(".message-text");
427 if (content && content.trim().length > 0) {
414 - const textDiv = document.createElement("div");
415 - textDiv.classList.add("message-text");
416 -
417 - // Create a span for the content
418 - const spanElement = document.createElement("pre");
428 + if (!textDiv) {
429 + textDiv = document.createElement("div");
430 + textDiv.classList.add("message-text");
431 + messageDiv.appendChild(textDiv);
432 + }
433 + let spanElement = textDiv.querySelector("pre");
434 + if (!spanElement) {
435 + spanElement = document.createElement("pre");
436 + textDiv.appendChild(spanElement);
437 + }
438 spanElement.innerHTML = escapeHTML(content);
420 - textDiv.appendChild(spanElement);
421 -
439 addActionButtonsToElement(textDiv);
423 - messageDiv.appendChild(textDiv);
440 + } else {
441 + if (textDiv) textDiv.remove();
442 }
443
444 // Handle attachments
445 + let attachmentsContainer = messageDiv.querySelector(".attachments-container");
446 if (kvps && kvps.attachments && kvps.attachments.length > 0) {
428 - const attachmentsContainer = document.createElement("div");
429 - attachmentsContainer.classList.add("attachments-container");
447 + if (!attachmentsContainer) {
448 + attachmentsContainer = document.createElement("div");
449 + attachmentsContainer.classList.add("attachments-container");
450 + messageDiv.appendChild(attachmentsContainer);
451 + }
452 + // Important: Clear existing attachments to re-render, preventing duplicates on update
453 + attachmentsContainer.innerHTML = "";
454
455 kvps.attachments.forEach((attachment) => {
456 const attachmentDiv = document.createElement("div");
@@ -472,11 +496,10 @@ export function drawMessageUser(
496
497 attachmentsContainer.appendChild(attachmentDiv);
498 });
475 -
476 - messageDiv.appendChild(attachmentsContainer);
499 + } else {
500 + if (attachmentsContainer) attachmentsContainer.remove();
501 }
478 -
479 - messageContainer.appendChild(messageDiv);
502 + // The messageDiv is already appended or updated, no need to append again
503 }
504
505 export function drawMessageTool(
@@ -984,4 +1007,4 @@ class Scroller {
1007 reApplyScroll() {
1008 if (this.wasAtBottom) this.element.scrollTop = this.element.scrollHeight;
1009 }
987 -}
1010 +}
\ No newline at end of file