fix(story-summary): guard delayed handlers by chatId and use module event wrapper
This commit is contained in:
@@ -10,7 +10,6 @@
|
|||||||
|
|
||||||
import { getContext } from "../../../../../extensions.js";
|
import { getContext } from "../../../../../extensions.js";
|
||||||
import {
|
import {
|
||||||
eventSource,
|
|
||||||
event_types,
|
event_types,
|
||||||
extension_prompts,
|
extension_prompts,
|
||||||
extension_prompt_types,
|
extension_prompt_types,
|
||||||
@@ -18,6 +17,7 @@ import {
|
|||||||
} from "../../../../../../script.js";
|
} from "../../../../../../script.js";
|
||||||
import { extensionFolderPath } from "../../core/constants.js";
|
import { extensionFolderPath } from "../../core/constants.js";
|
||||||
import { xbLog, CacheRegistry } from "../../core/debug-core.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 { postToIframe, isTrustedMessage } from "../../core/iframe-messaging.js";
|
||||||
import { CommonSettingStorage } from "../../core/server-storage.js";
|
import { CommonSettingStorage } from "../../core/server-storage.js";
|
||||||
|
|
||||||
@@ -111,7 +111,9 @@ let overlayCreated = false;
|
|||||||
let frameReady = false;
|
let frameReady = false;
|
||||||
let currentMesId = null;
|
let currentMesId = null;
|
||||||
let pendingFrameMessages = [];
|
let pendingFrameMessages = [];
|
||||||
let eventsRegistered = false;
|
/** @type {ReturnType<typeof createModuleEvents>|null} */
|
||||||
|
let events = null;
|
||||||
|
let activeChatId = null;
|
||||||
let vectorCancelled = false;
|
let vectorCancelled = false;
|
||||||
let vectorAbortController = null;
|
let vectorAbortController = null;
|
||||||
|
|
||||||
@@ -1371,7 +1373,9 @@ async function handleManualGenerate(mesId, config) {
|
|||||||
// ═══════════════════════════════════════════════════════════════════════════
|
// ═══════════════════════════════════════════════════════════════════════════
|
||||||
|
|
||||||
async function handleChatChanged() {
|
async function handleChatChanged() {
|
||||||
|
if (!events) return;
|
||||||
const { chat } = getContext();
|
const { chat } = getContext();
|
||||||
|
activeChatId = getContext().chatId || null;
|
||||||
const newLength = Array.isArray(chat) ? chat.length : 0;
|
const newLength = Array.isArray(chat) ? chat.length : 0;
|
||||||
|
|
||||||
await rollbackSummaryIfNeeded();
|
await rollbackSummaryIfNeeded();
|
||||||
@@ -1405,7 +1409,8 @@ async function handleChatChanged() {
|
|||||||
setTimeout(() => checkVectorIntegrityAndWarn(), 2000);
|
setTimeout(() => checkVectorIntegrityAndWarn(), 2000);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function handleMessageDeleted() {
|
async function handleMessageDeleted(scheduledChatId) {
|
||||||
|
if (isChatStale(scheduledChatId)) return;
|
||||||
const { chat, chatId } = getContext();
|
const { chat, chatId } = getContext();
|
||||||
const newLength = chat?.length || 0;
|
const newLength = chat?.length || 0;
|
||||||
|
|
||||||
@@ -1426,7 +1431,8 @@ async function handleMessageDeleted() {
|
|||||||
applyHideStateDebounced();
|
applyHideStateDebounced();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function handleMessageSwiped() {
|
async function handleMessageSwiped(scheduledChatId) {
|
||||||
|
if (isChatStale(scheduledChatId)) return;
|
||||||
const { chat, chatId } = getContext();
|
const { chat, chatId } = getContext();
|
||||||
const lastFloor = (chat?.length || 1) - 1;
|
const lastFloor = (chat?.length || 1) - 1;
|
||||||
|
|
||||||
@@ -1447,7 +1453,8 @@ async function handleMessageSwiped() {
|
|||||||
await sendVectorStatsToFrame();
|
await sendVectorStatsToFrame();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function handleMessageReceived() {
|
async function handleMessageReceived(scheduledChatId) {
|
||||||
|
if (isChatStale(scheduledChatId)) return;
|
||||||
const { chat, chatId } = getContext();
|
const { chat, chatId } = getContext();
|
||||||
const lastFloor = (chat?.length || 1) - 1;
|
const lastFloor = (chat?.length || 1) - 1;
|
||||||
const message = chat?.[lastFloor];
|
const message = chat?.[lastFloor];
|
||||||
@@ -1480,12 +1487,14 @@ async function handleMessageReceived() {
|
|||||||
setTimeout(() => maybeAutoExtractL0(), 2000);
|
setTimeout(() => maybeAutoExtractL0(), 2000);
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleMessageSent() {
|
function handleMessageSent(scheduledChatId) {
|
||||||
|
if (isChatStale(scheduledChatId)) return;
|
||||||
initButtonsForAll();
|
initButtonsForAll();
|
||||||
setTimeout(() => maybeAutoRunSummary("before_user"), 1000);
|
setTimeout(() => maybeAutoRunSummary("before_user"), 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function handleMessageUpdated() {
|
async function handleMessageUpdated(scheduledChatId) {
|
||||||
|
if (isChatStale(scheduledChatId)) return;
|
||||||
await rollbackSummaryIfNeeded();
|
await rollbackSummaryIfNeeded();
|
||||||
initButtonsForAll();
|
initButtonsForAll();
|
||||||
applyHideStateDebounced();
|
applyHideStateDebounced();
|
||||||
@@ -1601,25 +1610,21 @@ async function handleGenerationStarted(type, _params, isDryRun) {
|
|||||||
// 事件注册
|
// 事件注册
|
||||||
// ═══════════════════════════════════════════════════════════════════════════
|
// ═══════════════════════════════════════════════════════════════════════════
|
||||||
|
|
||||||
const boundHandlers = {
|
function scheduleWithChatGuard(fn, delay = 0) {
|
||||||
chatChanged: () => setTimeout(handleChatChanged, 80),
|
const scheduledChatId = getContext().chatId;
|
||||||
messageDeleted: () => setTimeout(handleMessageDeleted, 50),
|
setTimeout(() => fn(scheduledChatId), delay);
|
||||||
messageReceived: () => setTimeout(handleMessageReceived, 150),
|
}
|
||||||
messageSent: () => setTimeout(handleMessageSent, 150),
|
|
||||||
messageSentRecall: handleMessageSentForRecall,
|
function isChatStale(scheduledChatId) {
|
||||||
messageSwiped: () => setTimeout(handleMessageSwiped, 100),
|
if (!scheduledChatId || scheduledChatId !== activeChatId) return true;
|
||||||
messageUpdated: () => setTimeout(handleMessageUpdated, 100),
|
const { chatId } = getContext();
|
||||||
messageEdited: () => setTimeout(handleMessageUpdated, 100),
|
return chatId !== scheduledChatId;
|
||||||
userRendered: (data) => setTimeout(() => handleMessageRendered(data), 50),
|
}
|
||||||
charRendered: (data) => setTimeout(() => handleMessageRendered(data), 50),
|
|
||||||
genStarted: handleGenerationStarted,
|
|
||||||
genStopped: clearExtensionPrompt,
|
|
||||||
genEnded: clearExtensionPrompt,
|
|
||||||
};
|
|
||||||
|
|
||||||
function registerEvents() {
|
function registerEvents() {
|
||||||
if (eventsRegistered) return;
|
if (events) return;
|
||||||
eventsRegistered = true;
|
events = createModuleEvents(MODULE_ID);
|
||||||
|
activeChatId = getContext().chatId || null;
|
||||||
|
|
||||||
CacheRegistry.register(MODULE_ID, {
|
CacheRegistry.register(MODULE_ID, {
|
||||||
name: "待发送消息队列",
|
name: "待发送消息队列",
|
||||||
@@ -1639,44 +1644,36 @@ function registerEvents() {
|
|||||||
|
|
||||||
initButtonsForAll();
|
initButtonsForAll();
|
||||||
|
|
||||||
eventSource.on(event_types.CHAT_CHANGED, boundHandlers.chatChanged);
|
events.on(event_types.CHAT_CHANGED, () => {
|
||||||
eventSource.on(event_types.MESSAGE_DELETED, boundHandlers.messageDeleted);
|
activeChatId = getContext().chatId || null;
|
||||||
eventSource.on(event_types.MESSAGE_RECEIVED, boundHandlers.messageReceived);
|
scheduleWithChatGuard(handleChatChanged, 80);
|
||||||
eventSource.on(event_types.MESSAGE_SENT, boundHandlers.messageSent);
|
});
|
||||||
eventSource.on(event_types.MESSAGE_SENT, boundHandlers.messageSentRecall);
|
events.on(event_types.MESSAGE_DELETED, () => scheduleWithChatGuard(handleMessageDeleted, 50));
|
||||||
eventSource.on(event_types.MESSAGE_SWIPED, boundHandlers.messageSwiped);
|
events.on(event_types.MESSAGE_RECEIVED, () => scheduleWithChatGuard(handleMessageReceived, 150));
|
||||||
eventSource.on(event_types.MESSAGE_UPDATED, boundHandlers.messageUpdated);
|
events.on(event_types.MESSAGE_SENT, () => scheduleWithChatGuard(handleMessageSent, 150));
|
||||||
eventSource.on(event_types.MESSAGE_EDITED, boundHandlers.messageEdited);
|
events.on(event_types.MESSAGE_SENT, handleMessageSentForRecall);
|
||||||
eventSource.on(event_types.USER_MESSAGE_RENDERED, boundHandlers.userRendered);
|
events.on(event_types.MESSAGE_SWIPED, () => scheduleWithChatGuard(handleMessageSwiped, 100));
|
||||||
eventSource.on(event_types.CHARACTER_MESSAGE_RENDERED, boundHandlers.charRendered);
|
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("pointerdown", onSendPointerdown, true);
|
||||||
document.addEventListener("keydown", onSendKeydown, true);
|
document.addEventListener("keydown", onSendKeydown, true);
|
||||||
|
|
||||||
// 注入链路
|
// 注入链路
|
||||||
eventSource.on(event_types.GENERATION_STARTED, boundHandlers.genStarted);
|
events.on(event_types.GENERATION_STARTED, handleGenerationStarted);
|
||||||
eventSource.on(event_types.GENERATION_STOPPED, boundHandlers.genStopped);
|
events.on(event_types.GENERATION_STOPPED, clearExtensionPrompt);
|
||||||
eventSource.on(event_types.GENERATION_ENDED, boundHandlers.genEnded);
|
events.on(event_types.GENERATION_ENDED, clearExtensionPrompt);
|
||||||
}
|
}
|
||||||
|
|
||||||
function unregisterEvents() {
|
function unregisterEvents() {
|
||||||
|
if (!events) return;
|
||||||
CacheRegistry.unregister(MODULE_ID);
|
CacheRegistry.unregister(MODULE_ID);
|
||||||
eventsRegistered = false;
|
events.cleanup();
|
||||||
|
events = null;
|
||||||
eventSource.off(event_types.CHAT_CHANGED, boundHandlers.chatChanged);
|
activeChatId = null;
|
||||||
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);
|
|
||||||
|
|
||||||
$(".xiaobaix-story-summary-btn").remove();
|
$(".xiaobaix-story-summary-btn").remove();
|
||||||
hideOverlay();
|
hideOverlay();
|
||||||
|
|||||||
Reference in New Issue
Block a user