From a82d8cfb05b57a1c2e6a571104b08c9f8ba7fdcf Mon Sep 17 00:00:00 2001 From: Meleki Date: Sat, 7 Mar 2026 18:53:45 +0100 Subject: [PATCH] Add missing message actions to archive messages - Archive messages (loadLatestArchive) now render reply, delete, mark and share buttons, matching the behavior of _renderMessagesIntoFragment - Add review-bubble and preparer-bubble detection for archive messages - Add data-role, data-timestamp attributes for proper reply quoting - Add isMarked/deletedOn CSS class handling for archive messages - Also add [Preparer:] to isReviewMsg check in _renderMessagesIntoFragment for consistency --- wwwroot/js/history.js | 42 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 36 insertions(+), 6 deletions(-) diff --git a/wwwroot/js/history.js b/wwwroot/js/history.js index 5b7d032..9b88e2d 100644 --- a/wwwroot/js/history.js +++ b/wwwroot/js/history.js @@ -180,7 +180,7 @@ function _renderMessagesIntoFragment(fragment, msgs, imageMessageIds) { const div = document.createElement('div'); switch (msg.type) { case 'text': { - const isReviewMsg = msg.content && (msg.content.startsWith('[Review:') || msg.content.startsWith('[Review-Feedback') || msg.content.startsWith('[Finalizer:')); + const isReviewMsg = msg.content && (msg.content.startsWith('[Review:') || msg.content.startsWith('[Review-Feedback') || msg.content.startsWith('[Finalizer:') || msg.content.startsWith('[Preparer:')); if (msg.role === 'user' && !isReviewMsg) { div.className = 'msg user markdown' + (msg.isMarked ? ' marked' : ''); if (msg.deletedOn) div.classList.add(isDeletedVisible() ? 'msg-deleted' : 'msg-deleted-hidden'); @@ -472,17 +472,46 @@ async function loadLatestArchive() { for (const msg of mergedMsgs) { const div = document.createElement('div'); switch (msg.type) { - case 'text': - if (msg.role === 'user') { - div.className = 'msg user markdown archived'; + case 'text': { + const isReviewMsg = msg.content && (msg.content.startsWith('[Review:') || msg.content.startsWith('[Review-Feedback') || msg.content.startsWith('[Finalizer:') || msg.content.startsWith('[Preparer:')); + if (msg.role === 'user' && !isReviewMsg) { + div.className = 'msg user markdown archived' + (msg.isMarked ? ' marked' : ''); + if (msg.deletedOn) div.classList.add(isDeletedVisible() ? 'msg-deleted' : 'msg-deleted-hidden'); + div.dataset.role = 'user'; + div.dataset.timestamp = msg.createdAt || ''; if (msg.id) div.dataset.messageId = msg.id; renderUserContent(div, msg.content); _addTimestamp(div, msg.createdAt); - } else { - div.className = 'msg assistant markdown archived'; + _addReplyButton(div); + _addDeleteButton(div, msg.id, msg.deletedOn); + _addMarkButton(div, msg.id, msg.isMarked); + _addShareButton(div, msg.id); + } else if (isReviewMsg) { + div.className = 'msg review-bubble markdown archived' + (msg.isMarked ? ' marked' : ''); + if (msg.deletedOn) div.classList.add(isDeletedVisible() ? 'msg-deleted' : 'msg-deleted-hidden'); + div.dataset.role = msg.role; + div.dataset.timestamp = msg.createdAt || ''; + if (msg.id) div.dataset.messageId = msg.id; div.innerHTML = renderMarkdown(msg.content); parseFluentEmojis(div); _addTimestamp(div, msg.createdAt); + _addReplyButton(div); + _addDeleteButton(div, msg.id, msg.deletedOn); + _addMarkButton(div, msg.id, msg.isMarked); + _addShareButton(div, msg.id); + } else if (msg.role === 'assistant') { + div.className = 'msg assistant markdown archived' + (msg.isMarked ? ' marked' : ''); + if (msg.deletedOn) div.classList.add(isDeletedVisible() ? 'msg-deleted' : 'msg-deleted-hidden'); + div.dataset.role = 'assistant'; + div.dataset.timestamp = msg.createdAt || ''; + if (msg.id) div.dataset.messageId = msg.id; + div.innerHTML = renderMarkdown(msg.content); + parseFluentEmojis(div); + _addTimestamp(div, msg.createdAt); + _addReplyButton(div); + _addDeleteButton(div, msg.id, msg.deletedOn); + _addMarkButton(div, msg.id, msg.isMarked); + _addShareButton(div, msg.id); } if (msg.role === 'user' && msg.attachmentCount > 0) { if (/\[Bild: [^\]]+\]/.test(msg.content)) archiveImageIds.push(msg.id); @@ -498,6 +527,7 @@ async function loadLatestArchive() { div.appendChild(ind); } break; + } case 'tool_use': if (!isToolVisible(msg.toolName)) continue; div.className = 'tool-box archived';