Merge pull request #3561 from SillyTavern/fix-syncing-swipe-data Fix syncing swipe data on reasoning parse & utility function to sync swipe data
Signed| @@ -6086,17 +6086,52 @@ export async function saveReply(type, getMessage, fromStreaming, title, swipes, | ||
| 6086 | 6086 | return { type, getMessage }; |
| 6087 | 6087 | } |
| 6088 | 6088 | |
| 6089 | -export function syncCurrentSwipeInfoExtras() { | |
| 6089 | +/** | |
| 6090 | + * Syncs the current message and all its data into the swipe data at the given message ID (or the last message if no ID is given). | |
| 6091 | + * | |
| 6092 | + * If the swipe data is invalid in some way, this function will exit out without doing anything. | |
| 6093 | + * @param {number?} [messageId=null] - The ID of the message to sync with the swipe data. If no ID is given, the last message is used. | |
| 6094 | + * @returns {boolean} Whether the message was successfully synced | |
| 6095 | + */ | |
| 6096 | +export function syncMesToSwipe(messageId = null) { | |
| 6090 | 6097 | if (!chat.length) { |
| 6091 | 6098 | return false; |
| 6092 | 6099 | } |
| 6093 | - const currentMessage = chat[chat.length - 1]; | |
| 6100 | + | |
| 6094 | - if (currentMessage && Array.isArray(currentMessage.swipe_info) && typeof currentMessage.swipe_id === 'number') { | |
| 6101 | + const targetMessageId = messageId ?? chat.length - 1; | |
| 6095 | - const swipeInfo = currentMessage.swipe_info[currentMessage.swipe_id]; | |
| 6102 | + if (chat.length > targetMessageId || targetMessageId < 0) { | |
| 6096 | - if (swipeInfo && typeof swipeInfo === 'object') { | |
| 6103 | + console.warn(`[syncMesToSwipe] Invalid message ID: ${messageId}`); | |
| 6097 | - swipeInfo.extra = structuredClone(currentMessage.extra); | |
| 6104 | + return false; | |
| 6098 | 6105 | } |
| 6106 | + | |
| 6107 | + const targetMessage = chat[targetMessageId]; | |
| 6108 | + | |
| 6109 | + // No swipe data there yet, exit out | |
| 6110 | + if (typeof targetMessage.swipe_id !== 'number') { | |
| 6111 | + return false; | |
| 6099 | 6112 | } |
| 6113 | + // If swipes structure is invalid, exit out (for now?) | |
| 6114 | + if (!Array.isArray(targetMessage.swipe_info) || !Array.isArray(targetMessage.swipes)) { | |
| 6115 | + return false; | |
| 6116 | + } | |
| 6117 | + // If the swipe is not present yet, exit out (will likely be copied later) | |
| 6118 | + if (!targetMessage.swipes[targetMessage.swipe_id] || !targetMessage.swipe_info[targetMessage.swipe_id]) { | |
| 6119 | + return false; | |
| 6120 | + } | |
| 6121 | + | |
| 6122 | + const targetSwipeInfo = targetMessage.swipe_info[targetMessage.swipe_id]; | |
| 6123 | + if (typeof targetSwipeInfo !== 'object') { | |
| 6124 | + return false; | |
| 6125 | + } | |
| 6126 | + | |
| 6127 | + targetMessage.swipes[targetMessage.swipe_id] = targetMessage.mes; | |
| 6128 | + | |
| 6129 | + targetSwipeInfo.send_date = targetMessage.send_date; | |
| 6130 | + targetSwipeInfo.gen_started = targetMessage.gen_started; | |
| 6131 | + targetSwipeInfo.gen_finished = targetMessage.gen_finished; | |
| 6132 | + targetSwipeInfo.extra = structuredClone(targetMessage.extra); | |
| 6133 | + | |
| 6134 | + return true; | |
| 6100 | 6135 | } |
| 6101 | 6136 | |
| 6102 | 6137 | function saveImageToMessage(img, mes) { |
| @@ -6401,6 +6436,7 @@ export function saveChatDebounced() { | ||
| 6401 | 6436 | if (chatSaveTimeout) { |
| 6402 | 6437 | console.debug('Clearing chat save timeout'); |
| 6403 | 6438 | clearTimeout(chatSaveTimeout); |
| 6439 | + chatSaveTimeout = null; | |
| 6404 | 6440 | } |
| 6405 | 6441 | |
| 6406 | 6442 | chatSaveTimeout = setTimeout(async () => { |
| @@ -6417,7 +6453,7 @@ export function saveChatDebounced() { | ||
| 6417 | 6453 | console.debug('Chat save timeout triggered'); |
| 6418 | 6454 | await saveChatConditional(); |
| 6419 | 6455 | console.debug('Chat saved'); |
| 6420 | 6456 | }, 1000DEFAULT_SAVE_EDIT_TIMEOUT); |
| 6421 | 6457 | } |
| 6422 | 6458 | |
| 6423 | 6459 | export async function saveChat(chatName, withMetadata, mesId) { |
| @@ -8032,6 +8068,12 @@ export async function saveChatConditional() { | ||
| 8032 | 8068 | } |
| 8033 | 8069 | |
| 8034 | 8070 | try { |
| 8071 | + if (chatSaveTimeout) { | |
| 8072 | + console.debug('Debounced chat save canceled'); | |
| 8073 | + clearTimeout(chatSaveTimeout); | |
| 8074 | + chatSaveTimeout = null; | |
| 8075 | + } | |
| 8076 | + | |
| 8035 | 8077 | isChatSaving = true; |
| 8036 | 8078 | |
| 8037 | 8079 | if (selected_group) { |
| @@ -8568,7 +8610,7 @@ function swipe_left() { // when we swipe left..but no generation. | ||
| 8568 | 8610 | } |
| 8569 | 8611 | |
| 8570 | 8612 | // Make sure ad-hoc changes to extras are saved before swiping away |
| 8571 | 8613 | syncCurrentSwipeInfoExtrassyncMesToSwipe(); |
| 8572 | 8614 | |
| 8573 | 8615 | const swipe_duration = 120; |
| 8574 | 8616 | const swipe_range = '700px'; |
| @@ -8706,7 +8748,7 @@ const swipe_right = () => { | ||
| 8706 | 8748 | } |
| 8707 | 8749 | |
| 8708 | 8750 | // Make sure ad-hoc changes to extras are saved before swiping away |
| 8709 | 8751 | syncCurrentSwipeInfoExtrassyncMesToSwipe(); |
| 8710 | 8752 | |
| 8711 | 8753 | const swipe_duration = 200; |
| 8712 | 8754 | const swipe_range = 700; |
| @@ -1,7 +1,7 @@ | ||
| 1 | 1 | import { |
| 2 | 2 | moment, |
| 3 | 3 | } from '../lib.js'; |
| 4 | 4 | import { chat, closeMessageEditor, event_types, eventSource, main_api, messageFormatting, saveChatConditional, saveChatDebounced, saveSettingsDebounced, substituteParams, syncMesToSwipe, updateMessageBlock } from '../script.js'; |
| 5 | 5 | import { getRegexedString, regex_placement } from './extensions/regex/engine.js'; |
| 6 | 6 | import { getCurrentLocale, t, translate } from './i18n.js'; |
| 7 | 7 | import { MacrosParser } from './macros.js'; |
| @@ -1046,8 +1046,11 @@ function registerReasoningAppEvents() { | ||
| 1046 | 1046 | message.mes = parsedReasoning.content; |
| 1047 | 1047 | } |
| 1048 | 1048 | |
| 1049 | - // Find if a message already exists in DOM and must be updated | |
| 1050 | 1049 | if (contentUpdated) { |
| 1050 | + syncMesToSwipe(); | |
| 1051 | + saveChatDebounced(); | |
| 1052 | + | |
| 1053 | + // Find if a message already exists in DOM and must be updated | |
| 1051 | 1054 | const messageRendered = document.querySelector(`.mes[mesid="${idx}"]`) !== null; |
| 1052 | 1055 | if (messageRendered) { |
| 1053 | 1056 | console.debug('[Reasoning] Updating message block', idx); |
| @@ -42,7 +42,7 @@ import { | ||
| 42 | 42 | showMoreMessages, |
| 43 | 43 | stopGeneration, |
| 44 | 44 | substituteParams, |
| 45 | 45 | syncCurrentSwipeInfoExtrassyncMesToSwipe, |
| 46 | 46 | system_avatar, |
| 47 | 47 | system_message_types, |
| 48 | 48 | this_chid, |
| @@ -2921,7 +2921,7 @@ async function addSwipeCallback(args, value) { | ||
| 2921 | 2921 | |
| 2922 | 2922 | if (isTrueBoolean(args.switch)) { |
| 2923 | 2923 | // Make sure ad-hoc changes to extras are saved before swiping away |
| 2924 | 2924 | syncCurrentSwipeInfoExtrassyncMesToSwipe(); |
| 2925 | 2925 | lastMessage.swipe_id = newSwipeId; |
| 2926 | 2926 | lastMessage.mes = lastMessage.swipes[newSwipeId]; |
| 2927 | 2927 | lastMessage.extra = structuredClone(lastMessage.swipe_info?.[newSwipeId]?.extra ?? lastMessage.extra ?? {}); |