From 95326ce02ff304bf7fb7864d41e480fe9d0e4d99 Mon Sep 17 00:00:00 2001 From: dwrz Date: Tue, 30 Jun 2026 11:44:19 +0000 Subject: [PATCH] Fix interrupted streaming message deletion --- internal/service/static/main.js | 56 ++++++++++--------- .../service/templates/static/templates.gohtml | 10 ++++ 2 files changed, 40 insertions(+), 26 deletions(-) diff --git a/internal/service/static/main.js b/internal/service/static/main.js index 3acb223..2a69543 100644 --- a/internal/service/static/main.js +++ b/internal/service/static/main.js @@ -1511,6 +1511,7 @@ class Odidere { this.currentController = new AbortController(); let streamingMessage = null; + let done = false; try { const hasNewInput = @@ -1638,8 +1639,7 @@ class Odidere { // Handle errors sent mid-stream. if (event.error) { - this.#renderError(event.error); - continue; + throw new Error(event.error); } if ( @@ -1786,36 +1786,35 @@ class Odidere { } } + done = true; this.#setLoadingState(false); } catch (e) { - if (e.name === 'AbortError') { - console.debug('request aborted'); - if (streamingMessage) { - const $msg = streamingMessage.$el; - const $deleteBtn = document.createElement('button'); - $deleteBtn.type = 'button'; - $deleteBtn.className = - 'message__action-btn message__action-btn--delete'; - $deleteBtn.dataset.action = 'delete'; - $deleteBtn.setAttribute('aria-label', 'Delete message'); - $deleteBtn.innerHTML = ``; - $deleteBtn.addEventListener('click', (e) => - this.#handleDeleteClick(e, streamingMessage.message.id), - ); - $msg - .querySelector('.message__actions-buttons') - .insertBefore( - $deleteBtn, - $msg.querySelector('.message__actions-buttons').firstChild, - ); - } - return; + if (e.name !== 'AbortError') { + console.error('failed to send request:', e); + this.#renderError(`Error: ${e.message}`); } - console.error('failed to send request:', e); - this.#renderError(`Error: ${e.message}`); this.#setLoadingState(false); } finally { this.currentController = null; + if (!done && streamingMessage) { + const $msg = streamingMessage.$el; + const $deleteBtn = document.createElement('button'); + $deleteBtn.type = 'button'; + $deleteBtn.className = + 'message__action-btn message__action-btn--delete'; + $deleteBtn.dataset.action = 'delete'; + $deleteBtn.setAttribute('aria-label', 'Delete message'); + $deleteBtn.innerHTML = ``; + $deleteBtn.addEventListener('click', (e) => + this.#handleDeleteClick(e, streamingMessage.message.id), + ); + $msg + .querySelector('.message__actions-buttons') + .insertBefore( + $deleteBtn, + $msg.querySelector('.message__actions-buttons').firstChild, + ); + } } } @@ -2735,6 +2734,11 @@ class Odidere { this.$tplErrorMessage.content.cloneNode(true).firstElementChild; $msg.querySelector('.message__content').textContent = message; + const $delete = $msg.querySelector('[data-action="delete"]'); + if ($delete) { + $delete.addEventListener('click', () => $msg.remove()); + } + this.$chat.insertBefore($msg, this.$chatLoading); this.#scrollToBottom(); } diff --git a/internal/service/templates/static/templates.gohtml b/internal/service/templates/static/templates.gohtml index e5c80f5..a4103a5 100644 --- a/internal/service/templates/static/templates.gohtml +++ b/internal/service/templates/static/templates.gohtml @@ -95,6 +95,16 @@
+
+ +