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 | return { type, getMessage }; | 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 | if (!chat.length) { | 6097 | if (!chat.length) { |
| 6091 | return; | 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 | function saveImageToMessage(img, mes) { | 6137 | function saveImageToMessage(img, mes) { |
| @@ -6401,6 +6436,7 @@ export function saveChatDebounced() { | |||
| 6401 | if (chatSaveTimeout) { | 6436 | if (chatSaveTimeout) { |
| 6402 | console.debug('Clearing chat save timeout'); | 6437 | console.debug('Clearing chat save timeout'); |
| 6403 | clearTimeout(chatSaveTimeout); | 6438 | clearTimeout(chatSaveTimeout); |
| 6439 | chatSaveTimeout = null; | ||
| 6404 | } | 6440 | } |
| 6405 | 6441 | ||
| 6406 | chatSaveTimeout = setTimeout(async () => { | 6442 | chatSaveTimeout = setTimeout(async () => { |
| @@ -6417,7 +6453,7 @@ export function saveChatDebounced() { | |||
| 6417 | console.debug('Chat save timeout triggered'); | 6453 | console.debug('Chat save timeout triggered'); |
| 6418 | await saveChatConditional(); | 6454 | await saveChatConditional(); |
| 6419 | console.debug('Chat saved'); | 6455 | console.debug('Chat saved'); |
| 6420 | }, 1000); | 6456 | }, DEFAULT_SAVE_EDIT_TIMEOUT); |
| 6421 | } | 6457 | } |
| 6422 | 6458 | ||
| 6423 | export async function saveChat(chatName, withMetadata, mesId) { | 6459 | export async function saveChat(chatName, withMetadata, mesId) { |
| @@ -8032,6 +8068,12 @@ export async function saveChatConditional() { | |||
| 8032 | } | 8068 | } |
| 8033 | 8069 | ||
| 8034 | try { | 8070 | try { |
| 8071 | if (chatSaveTimeout) { | ||
| 8072 | console.debug('Debounced chat save canceled'); | ||
| 8073 | clearTimeout(chatSaveTimeout); | ||
| 8074 | chatSaveTimeout = null; | ||
| 8075 | } | ||
| 8076 | |||
| 8035 | isChatSaving = true; | 8077 | isChatSaving = true; |
| 8036 | 8078 | ||
| 8037 | if (selected_group) { | 8079 | if (selected_group) { |
| @@ -8568,7 +8610,7 @@ function swipe_left() { // when we swipe left..but no generation. | |||
| 8568 | } | 8610 | } |
| 8569 | 8611 | ||
| 8570 | // Make sure ad-hoc changes to extras are saved before swiping away | 8612 | // Make sure ad-hoc changes to extras are saved before swiping away |
| 8571 | syncCurrentSwipeInfoExtras(); | 8613 | syncMesToSwipe(); |
| 8572 | 8614 | ||
| 8573 | const swipe_duration = 120; | 8615 | const swipe_duration = 120; |
| 8574 | const swipe_range = '700px'; | 8616 | const swipe_range = '700px'; |
| @@ -8706,7 +8748,7 @@ const swipe_right = () => { | |||
| 8706 | } | 8748 | } |
| 8707 | 8749 | ||
| 8708 | // Make sure ad-hoc changes to extras are saved before swiping away | 8750 | // Make sure ad-hoc changes to extras are saved before swiping away |
| 8709 | syncCurrentSwipeInfoExtras(); | 8751 | syncMesToSwipe(); |
| 8710 | 8752 | ||
| 8711 | const swipe_duration = 200; | 8753 | const swipe_duration = 200; |
| 8712 | const swipe_range = 700; | 8754 | const swipe_range = 700; |
| @@ -1,7 +1,7 @@ | |||
| 1 | import { | 1 | import { |
| 2 | moment, | 2 | moment, |
| 3 | } from '../lib.js'; | 3 | } from '../lib.js'; |
| 4 | import { chat, closeMessageEditor, event_types, eventSource, main_api, messageFormatting, saveChatConditional, saveChatDebounced, saveSettingsDebounced, substituteParams, updateMessageBlock } from '../script.js'; | 4 | import { chat, closeMessageEditor, event_types, eventSource, main_api, messageFormatting, saveChatConditional, saveChatDebounced, saveSettingsDebounced, substituteParams, syncMesToSwipe, updateMessageBlock } from '../script.js'; |
| 5 | import { getRegexedString, regex_placement } from './extensions/regex/engine.js'; | 5 | import { getRegexedString, regex_placement } from './extensions/regex/engine.js'; |
| 6 | import { getCurrentLocale, t, translate } from './i18n.js'; | 6 | import { getCurrentLocale, t, translate } from './i18n.js'; |
| 7 | import { MacrosParser } from './macros.js'; | 7 | import { MacrosParser } from './macros.js'; |
| @@ -1046,8 +1046,11 @@ function registerReasoningAppEvents() { | |||
| 1046 | message.mes = parsedReasoning.content; | 1046 | message.mes = parsedReasoning.content; |
| 1047 | } | 1047 | } |
| 1048 | 1048 | ||
| 1049 | // Find if a message already exists in DOM and must be updated | ||
| 1050 | if (contentUpdated) { | 1049 | if (contentUpdated) { |
| 1050 | syncMesToSwipe(); | ||
| 1051 | saveChatDebounced(); | ||
| 1052 | |||
| 1053 | // Find if a message already exists in DOM and must be updated | ||
| 1051 | const messageRendered = document.querySelector(`.mes[mesid="${idx}"]`) !== null; | 1054 | const messageRendered = document.querySelector(`.mes[mesid="${idx}"]`) !== null; |
| 1052 | if (messageRendered) { | 1055 | if (messageRendered) { |
| 1053 | console.debug('[Reasoning] Updating message block', idx); | 1056 | console.debug('[Reasoning] Updating message block', idx); |
| @@ -42,7 +42,7 @@ import { | |||
| 42 | showMoreMessages, | 42 | showMoreMessages, |
| 43 | stopGeneration, | 43 | stopGeneration, |
| 44 | substituteParams, | 44 | substituteParams, |
| 45 | syncCurrentSwipeInfoExtras, | 45 | syncMesToSwipe, |
| 46 | system_avatar, | 46 | system_avatar, |
| 47 | system_message_types, | 47 | system_message_types, |
| 48 | this_chid, | 48 | this_chid, |
| @@ -2921,7 +2921,7 @@ async function addSwipeCallback(args, value) { | |||
| 2921 | 2921 | ||
| 2922 | if (isTrueBoolean(args.switch)) { | 2922 | if (isTrueBoolean(args.switch)) { |
| 2923 | // Make sure ad-hoc changes to extras are saved before swiping away | 2923 | // Make sure ad-hoc changes to extras are saved before swiping away |
| 2924 | syncCurrentSwipeInfoExtras(); | 2924 | syncMesToSwipe(); |
| 2925 | lastMessage.swipe_id = newSwipeId; | 2925 | lastMessage.swipe_id = newSwipeId; |
| 2926 | lastMessage.mes = lastMessage.swipes[newSwipeId]; | 2926 | lastMessage.mes = lastMessage.swipes[newSwipeId]; |
| 2927 | lastMessage.extra = structuredClone(lastMessage.swipe_info?.[newSwipeId]?.extra ?? lastMessage.extra ?? {}); | 2927 | lastMessage.extra = structuredClone(lastMessage.swipe_info?.[newSwipeId]?.extra ?? lastMessage.extra ?? {}); |