diff --git a/public/script.js b/public/script.js index 6a3844fc5..17ec1b211 100644 --- a/public/script.js +++ b/public/script.js @@ -2800,6 +2800,8 @@ class StreamingProcessor { this.messageDom = null; this.messageTextDom = null; this.messageTimerDom = null; + this.messageTokenCounterDom = null; + /** @type {HTMLTextAreaElement} */ this.sendTextarea = document.querySelector('#send_textarea'); this.type = type; this.force_name2 = force_name2; @@ -2815,6 +2817,15 @@ class StreamingProcessor { this.messageLogprobs = []; } + #checkDomElements(messageId) { + if (this.messageDom === null || this.messageTextDom === null) { + this.messageDom = document.querySelector(`#chat .mes[mesid="${messageId}"]`); + this.messageTextDom = this.messageDom?.querySelector('.mes_text'); + this.messageTimerDom = this.messageDom?.querySelector('.mes_timer'); + this.messageTokenCounterDom = this.messageDom?.querySelector('.tokenCounterDisplay'); + } + } + showMessageButtons(messageId) { if (messageId == -1) { return; @@ -2843,9 +2854,7 @@ class StreamingProcessor { else { await saveReply(this.type, text, true); messageId = chat.length - 1; - this.messageDom = document.querySelector(`#chat .mes[mesid="${messageId}"]`); - this.messageTextDom = this.messageDom.querySelector('.mes_text'); - this.messageTimerDom = this.messageDom.querySelector('.mes_timer'); + this.#checkDomElements(messageId); this.showMessageButtons(messageId); } @@ -2881,9 +2890,10 @@ class StreamingProcessor { this.sendTextarea.dispatchEvent(new Event('input', { bubbles: true })); } else { - let currentTime = new Date(); + this.#checkDomElements(messageId); + const currentTime = new Date(); // Don't waste time calculating token count for streaming - let currentTokenCount = isFinal && power_user.message_token_count_enabled ? getTokenCount(processedText, 0) : 0; + const currentTokenCount = isFinal && power_user.message_token_count_enabled ? getTokenCount(processedText, 0) : 0; const timePassed = formatGenerationTimer(this.timeStarted, currentTime, currentTokenCount); chat[messageId]['mes'] = processedText; chat[messageId]['gen_started'] = this.timeStarted; @@ -2895,8 +2905,9 @@ class StreamingProcessor { } chat[messageId]['extra']['token_count'] = currentTokenCount; - const tokenCounter = $(`#chat .mes[mesid="${messageId}"] .tokenCounterDisplay`); - tokenCounter.text(`${currentTokenCount}t`); + if (this.messageTokenCounterDom instanceof HTMLElement) { + this.messageTokenCounterDom.textContent = `${currentTokenCount}t`; + } } if ((this.type == 'swipe' || this.type === 'continue') && Array.isArray(chat[messageId]['swipes'])) { @@ -2904,16 +2915,20 @@ class StreamingProcessor { chat[messageId]['swipe_info'][chat[messageId]['swipe_id']] = { 'send_date': chat[messageId]['send_date'], 'gen_started': chat[messageId]['gen_started'], 'gen_finished': chat[messageId]['gen_finished'], 'extra': JSON.parse(JSON.stringify(chat[messageId]['extra'])) }; } - let formattedText = messageFormatting( + const formattedText = messageFormatting( processedText, chat[messageId].name, chat[messageId].is_system, chat[messageId].is_user, messageId, ); - this.messageTextDom.innerHTML = formattedText; - this.messageTimerDom.textContent = timePassed.timerValue; - this.messageTimerDom.title = timePassed.timerTitle; + if (this.messageTextDom instanceof HTMLElement) { + this.messageTextDom.innerHTML = formattedText; + } + if (this.messageTimerDom instanceof HTMLElement) { + this.messageTimerDom.textContent = timePassed.timerValue; + this.messageTimerDom.title = timePassed.timerTitle; + } this.setFirstSwipe(messageId); } @@ -3199,6 +3214,23 @@ function restoreResponseLength(api, responseLength) { } } +/** + * Removes last message from the chat DOM. + * @returns {Promise} Resolves when the message is removed. + */ +function removeLastMessage() { + return new Promise((resolve) => { + const lastMes = $('#chat').children('.mes').last(); + if (lastMes.length === 0) { + return resolve(); + } + lastMes.hide(animation_duration, function () { + $(this).remove(); + resolve(); + }); + }); +} + /** * Runs a generation using the current chat context. * @param {string} type Generation type @@ -3331,9 +3363,7 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro } else if (type !== 'quiet' && type !== 'swipe' && !isImpersonate && !dryRun && chat.length) { chat.length = chat.length - 1; - $('#chat').children().last().hide(250, function () { - $(this).remove(); - }); + await removeLastMessage(); await eventSource.emit(event_types.MESSAGE_DELETED, chat.length); } } diff --git a/public/scripts/bookmarks.js b/public/scripts/bookmarks.js index 14ba977f8..77bb87cca 100644 --- a/public/scripts/bookmarks.js +++ b/public/scripts/bookmarks.js @@ -14,7 +14,7 @@ import { saveChatConditional, saveItemizedPrompts, } from '../script.js'; -import { humanizedDateTime } from './RossAscends-mods.js'; +import { humanizedDateTime, getMessageTimeStamp } from './RossAscends-mods.js'; import { getGroupPastChats, group_activation_strategy, @@ -297,7 +297,7 @@ async function convertSoloToGroupChat() { if (groupChat.length === 0) { const newMessage = { ...system_messages[system_message_types.GROUP], - send_date: humanizedDateTime(), + send_date: getMessageTimeStamp(), extra: { type: system_message_types.GROUP }, }; groupChat.push(newMessage);