diff --git a/modules/story-summary/story-summary.js b/modules/story-summary/story-summary.js index 9f6070f..995060a 100644 --- a/modules/story-summary/story-summary.js +++ b/modules/story-summary/story-summary.js @@ -10,7 +10,6 @@ import { getContext } from "../../../../../extensions.js"; import { - eventSource, event_types, extension_prompts, extension_prompt_types, @@ -18,6 +17,7 @@ import { } from "../../../../../../script.js"; import { extensionFolderPath } from "../../core/constants.js"; import { xbLog, CacheRegistry } from "../../core/debug-core.js"; +import { createModuleEvents } from "../../core/event-manager.js"; import { postToIframe, isTrustedMessage } from "../../core/iframe-messaging.js"; import { CommonSettingStorage } from "../../core/server-storage.js"; @@ -111,7 +111,9 @@ let overlayCreated = false; let frameReady = false; let currentMesId = null; let pendingFrameMessages = []; -let eventsRegistered = false; +/** @type {ReturnType|null} */ +let events = null; +let activeChatId = null; let vectorCancelled = false; let vectorAbortController = null; @@ -1371,7 +1373,9 @@ async function handleManualGenerate(mesId, config) { // ═══════════════════════════════════════════════════════════════════════════ async function handleChatChanged() { + if (!events) return; const { chat } = getContext(); + activeChatId = getContext().chatId || null; const newLength = Array.isArray(chat) ? chat.length : 0; await rollbackSummaryIfNeeded(); @@ -1405,7 +1409,8 @@ async function handleChatChanged() { setTimeout(() => checkVectorIntegrityAndWarn(), 2000); } -async function handleMessageDeleted() { +async function handleMessageDeleted(scheduledChatId) { + if (isChatStale(scheduledChatId)) return; const { chat, chatId } = getContext(); const newLength = chat?.length || 0; @@ -1426,7 +1431,8 @@ async function handleMessageDeleted() { applyHideStateDebounced(); } -async function handleMessageSwiped() { +async function handleMessageSwiped(scheduledChatId) { + if (isChatStale(scheduledChatId)) return; const { chat, chatId } = getContext(); const lastFloor = (chat?.length || 1) - 1; @@ -1447,7 +1453,8 @@ async function handleMessageSwiped() { await sendVectorStatsToFrame(); } -async function handleMessageReceived() { +async function handleMessageReceived(scheduledChatId) { + if (isChatStale(scheduledChatId)) return; const { chat, chatId } = getContext(); const lastFloor = (chat?.length || 1) - 1; const message = chat?.[lastFloor]; @@ -1480,12 +1487,14 @@ async function handleMessageReceived() { setTimeout(() => maybeAutoExtractL0(), 2000); } -function handleMessageSent() { +function handleMessageSent(scheduledChatId) { + if (isChatStale(scheduledChatId)) return; initButtonsForAll(); setTimeout(() => maybeAutoRunSummary("before_user"), 1000); } -async function handleMessageUpdated() { +async function handleMessageUpdated(scheduledChatId) { + if (isChatStale(scheduledChatId)) return; await rollbackSummaryIfNeeded(); initButtonsForAll(); applyHideStateDebounced(); @@ -1601,25 +1610,21 @@ async function handleGenerationStarted(type, _params, isDryRun) { // 事件注册 // ═══════════════════════════════════════════════════════════════════════════ -const boundHandlers = { - chatChanged: () => setTimeout(handleChatChanged, 80), - messageDeleted: () => setTimeout(handleMessageDeleted, 50), - messageReceived: () => setTimeout(handleMessageReceived, 150), - messageSent: () => setTimeout(handleMessageSent, 150), - messageSentRecall: handleMessageSentForRecall, - messageSwiped: () => setTimeout(handleMessageSwiped, 100), - messageUpdated: () => setTimeout(handleMessageUpdated, 100), - messageEdited: () => setTimeout(handleMessageUpdated, 100), - userRendered: (data) => setTimeout(() => handleMessageRendered(data), 50), - charRendered: (data) => setTimeout(() => handleMessageRendered(data), 50), - genStarted: handleGenerationStarted, - genStopped: clearExtensionPrompt, - genEnded: clearExtensionPrompt, -}; +function scheduleWithChatGuard(fn, delay = 0) { + const scheduledChatId = getContext().chatId; + setTimeout(() => fn(scheduledChatId), delay); +} + +function isChatStale(scheduledChatId) { + if (!scheduledChatId || scheduledChatId !== activeChatId) return true; + const { chatId } = getContext(); + return chatId !== scheduledChatId; +} function registerEvents() { - if (eventsRegistered) return; - eventsRegistered = true; + if (events) return; + events = createModuleEvents(MODULE_ID); + activeChatId = getContext().chatId || null; CacheRegistry.register(MODULE_ID, { name: "待发送消息队列", @@ -1639,44 +1644,36 @@ function registerEvents() { initButtonsForAll(); - eventSource.on(event_types.CHAT_CHANGED, boundHandlers.chatChanged); - eventSource.on(event_types.MESSAGE_DELETED, boundHandlers.messageDeleted); - eventSource.on(event_types.MESSAGE_RECEIVED, boundHandlers.messageReceived); - eventSource.on(event_types.MESSAGE_SENT, boundHandlers.messageSent); - eventSource.on(event_types.MESSAGE_SENT, boundHandlers.messageSentRecall); - eventSource.on(event_types.MESSAGE_SWIPED, boundHandlers.messageSwiped); - eventSource.on(event_types.MESSAGE_UPDATED, boundHandlers.messageUpdated); - eventSource.on(event_types.MESSAGE_EDITED, boundHandlers.messageEdited); - eventSource.on(event_types.USER_MESSAGE_RENDERED, boundHandlers.userRendered); - eventSource.on(event_types.CHARACTER_MESSAGE_RENDERED, boundHandlers.charRendered); + events.on(event_types.CHAT_CHANGED, () => { + activeChatId = getContext().chatId || null; + scheduleWithChatGuard(handleChatChanged, 80); + }); + events.on(event_types.MESSAGE_DELETED, () => scheduleWithChatGuard(handleMessageDeleted, 50)); + events.on(event_types.MESSAGE_RECEIVED, () => scheduleWithChatGuard(handleMessageReceived, 150)); + events.on(event_types.MESSAGE_SENT, () => scheduleWithChatGuard(handleMessageSent, 150)); + events.on(event_types.MESSAGE_SENT, handleMessageSentForRecall); + events.on(event_types.MESSAGE_SWIPED, () => scheduleWithChatGuard(handleMessageSwiped, 100)); + events.on(event_types.MESSAGE_UPDATED, () => scheduleWithChatGuard(handleMessageUpdated, 100)); + events.on(event_types.MESSAGE_EDITED, () => scheduleWithChatGuard(handleMessageUpdated, 100)); + events.on(event_types.USER_MESSAGE_RENDERED, (data) => setTimeout(() => handleMessageRendered(data), 50)); + events.on(event_types.CHARACTER_MESSAGE_RENDERED, (data) => setTimeout(() => handleMessageRendered(data), 50)); // 用户输入捕获(原生捕获阶段) document.addEventListener("pointerdown", onSendPointerdown, true); document.addEventListener("keydown", onSendKeydown, true); // 注入链路 - eventSource.on(event_types.GENERATION_STARTED, boundHandlers.genStarted); - eventSource.on(event_types.GENERATION_STOPPED, boundHandlers.genStopped); - eventSource.on(event_types.GENERATION_ENDED, boundHandlers.genEnded); + events.on(event_types.GENERATION_STARTED, handleGenerationStarted); + events.on(event_types.GENERATION_STOPPED, clearExtensionPrompt); + events.on(event_types.GENERATION_ENDED, clearExtensionPrompt); } function unregisterEvents() { + if (!events) return; CacheRegistry.unregister(MODULE_ID); - eventsRegistered = false; - - eventSource.off(event_types.CHAT_CHANGED, boundHandlers.chatChanged); - eventSource.off(event_types.MESSAGE_DELETED, boundHandlers.messageDeleted); - eventSource.off(event_types.MESSAGE_RECEIVED, boundHandlers.messageReceived); - eventSource.off(event_types.MESSAGE_SENT, boundHandlers.messageSent); - eventSource.off(event_types.MESSAGE_SENT, boundHandlers.messageSentRecall); - eventSource.off(event_types.MESSAGE_SWIPED, boundHandlers.messageSwiped); - eventSource.off(event_types.MESSAGE_UPDATED, boundHandlers.messageUpdated); - eventSource.off(event_types.MESSAGE_EDITED, boundHandlers.messageEdited); - eventSource.off(event_types.USER_MESSAGE_RENDERED, boundHandlers.userRendered); - eventSource.off(event_types.CHARACTER_MESSAGE_RENDERED, boundHandlers.charRendered); - eventSource.off(event_types.GENERATION_STARTED, boundHandlers.genStarted); - eventSource.off(event_types.GENERATION_STOPPED, boundHandlers.genStopped); - eventSource.off(event_types.GENERATION_ENDED, boundHandlers.genEnded); + events.cleanup(); + events = null; + activeChatId = null; $(".xiaobaix-story-summary-btn").remove(); hideOverlay(); @@ -1710,4 +1707,4 @@ jQuery(() => { initStateIntegration(); maybePreloadTokenizer(); -}); \ No newline at end of file +});