Fix: comprehensive bug review — restore refactor regressions & fix critical/major/minor bugs
Critical:
- responseExtractor.js: fix import depth (7x ../ -> 6x) that broke the module
graph for encounters, separate/external generation, and auto-avatars
- settingsListeners.js: restore ~25 undefined functions, ~40 lost event
bindings, and the entire 'Initialize UI state' block dropped by the c14c141
refactor; add initializeSettingsUIState()
- Restore all External API mode handlers (base-url, api-key, model,
max-tokens, temperature, key-visibility, test-connection) + value init
- validator.js: convert CJS->ESM (crashed under type:module), fix
glob.sync->globSync (v13 API), fix '!key in obj' precedence bugs
Major:
- sillytavern.js: add missing updateMessageBlock import
- infoBox.js: add missing saveSettings import
- userStats.js: fix double-escaped quantity regex
Minor:
- config.js: settingsVersion 6->7, restore showLockIcons, fix apiKey comment
- events.js: off() tracking + unregister/re-register on disable/enable
- escapeHtml: escape quotes (XSS) in all 3 copies
- template.html: data-prompt dialogue-coloring -> dialogueColoring
- trackerEditor.js: stale externalApiOnly -> sendAllEnabledOnRefresh
- suppression.js: fix '[object Object]' on empty instruct value
- persistence.js: await migrateToV3JSON (loadSettings now async)
- weatherEffects.js: JSON.parse -> repairJSON
- mobile.js: fix corrupted comment line
- Add missing debugMode setting; settings.html v3.7.2 -> v3.7.4
Dead code removed:
- Unused imports/vars (promptBuilder, jsonPromptHelpers, encounterPrompts,
injector), withChangeDetection, trackJQueryHandler/cleanupJQueryEvents,
renderThoughtsSidebarOnly, updateCheckpointButtonInMenu, addDiceQuickReply,
setupRefreshButtonDrag/setupDebugButtonDrag (~430 lines)
Verified: 78/78 tests pass, style.css in sync, validator runs clean.
This commit is contained in:
@@ -55,7 +55,7 @@ import {
|
||||
clearDebugLogs
|
||||
} from './src/core/state.js';
|
||||
import { loadSettings, saveSettings, saveChatData, loadChatData, updateMessageSwipeData, commitTrackerDataFromPriorMessage } from './src/core/persistence.js';
|
||||
import { registerAllEvents, on as onEvent } from './src/core/events.js';
|
||||
import { registerAllEvents, on as onEvent, unregisterAllEvents } from './src/core/events.js';
|
||||
import { addExtensionSettings } from './src/core/settingsPanel.js';
|
||||
|
||||
// Generation & Parsing modules
|
||||
@@ -108,7 +108,6 @@ import {
|
||||
setupDiceRoller,
|
||||
setupSettingsPopup,
|
||||
updateDiceDisplay,
|
||||
addDiceQuickReply,
|
||||
getSettingsModal,
|
||||
showWelcomeModalIfNeeded,
|
||||
showDeprecationModalIfNeeded
|
||||
@@ -187,7 +186,7 @@ import {
|
||||
} from './src/systems/integration/sillytavern.js';
|
||||
|
||||
// Settings UI event listeners (extracted from initUI)
|
||||
import { bindSettingsListeners, updateWeatherSubOptionsVisibility } from './src/systems/ui/settingsListeners.js';
|
||||
import { bindSettingsListeners, initializeSettingsUIState } from './src/systems/ui/settingsListeners.js';
|
||||
|
||||
// Set up thought-based expressions refresh handler
|
||||
setThoughtBasedExpressionsRefreshHandler(() => {
|
||||
@@ -207,6 +206,71 @@ function updateDynamicLabels() {
|
||||
updateMobileTabLabels();
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers all SillyTavern event handlers for the extension.
|
||||
* Idempotent per enable cycle: call unregisterAllEvents() before re-registering
|
||||
* (e.g. when the extension is re-enabled after being disabled).
|
||||
*/
|
||||
function registerExtensionEvents() {
|
||||
registerAllEvents({
|
||||
[event_types.MESSAGE_SENT]: onMessageSent,
|
||||
[event_types.GENERATION_STARTED]: onGenerationStarted,
|
||||
[event_types.MESSAGE_RECEIVED]: onMessageReceived,
|
||||
[event_types.GENERATION_STOPPED]: onGenerationEnded,
|
||||
[event_types.GENERATION_ENDED]: onGenerationEnded,
|
||||
[event_types.CHAT_CHANGED]: [onCharacterChanged, updatePersonaAvatar, restoreCheckpointOnLoad, clearSessionAvatarPrompts, clearDebugLogs],
|
||||
[event_types.CHAT_LOADED]: onChatLoaded,
|
||||
[event_types.MESSAGE_DELETED]: onMessageDeleted,
|
||||
[event_types.MESSAGE_SWIPE_DELETED]: onMessageDeleted,
|
||||
[event_types.MESSAGE_SWIPED]: onMessageSwiped,
|
||||
[event_types.USER_MESSAGE_RENDERED]: updatePersonaAvatar,
|
||||
[event_types.SETTINGS_UPDATED]: updatePersonaAvatar
|
||||
});
|
||||
|
||||
// Use tracked event registration (onEvent) instead of direct eventSource.on()
|
||||
// This ensures all handlers are tracked for cleanup by unregisterAllEvents()
|
||||
onEvent(event_types.CHARACTER_MESSAGE_RENDERED, (messageId) => {
|
||||
if (!extensionSettings.enabled) return;
|
||||
const renderedMessage = chat[messageId];
|
||||
if (renderedMessage && !renderedMessage.is_user && !renderedMessage.is_system) {
|
||||
queueThoughtBasedExpressionsUpdate();
|
||||
}
|
||||
});
|
||||
|
||||
onEvent(event_types.MESSAGE_UPDATED, (messageId) => {
|
||||
if (!extensionSettings.enabled) return;
|
||||
const updatedMessage = chat[messageId];
|
||||
if (updatedMessage && !updatedMessage.is_user && !updatedMessage.is_system) {
|
||||
queueThoughtBasedExpressionsUpdate();
|
||||
}
|
||||
});
|
||||
|
||||
onEvent(event_types.MESSAGE_SWIPED, (messageIndex) => {
|
||||
if (!extensionSettings.enabled) return;
|
||||
const swipedMessage = chat[messageIndex];
|
||||
if (swipedMessage && !swipedMessage.is_user && !swipedMessage.is_system) {
|
||||
queueThoughtBasedExpressionsUpdate({ immediate: true });
|
||||
}
|
||||
});
|
||||
|
||||
onEvent(event_types.CHAT_CHANGED, () => {
|
||||
clearThoughtBasedExpressionsCache();
|
||||
setTimeout(() => onThoughtBasedExpressionsChatChanged(), 0);
|
||||
});
|
||||
|
||||
onEvent(event_types.MESSAGE_DELETED, () => {
|
||||
if (!extensionSettings.enabled) return;
|
||||
clearThoughtBasedExpressionsCache();
|
||||
setTimeout(() => onThoughtBasedExpressionsChatChanged(), 0);
|
||||
});
|
||||
|
||||
onEvent(event_types.MESSAGE_SWIPE_DELETED, () => {
|
||||
if (!extensionSettings.enabled) return;
|
||||
clearThoughtBasedExpressionsCache();
|
||||
setTimeout(() => onThoughtBasedExpressionsChatChanged(), 0);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the UI for the extension.
|
||||
*/
|
||||
@@ -252,6 +316,19 @@ async function initUI() {
|
||||
// Bind all settings event listeners (extracted to settingsListeners.js)
|
||||
bindSettingsListeners($);
|
||||
|
||||
// Sync settings modal inputs with saved settings, then apply startup UI state
|
||||
initializeSettingsUIState();
|
||||
updatePanelVisibility();
|
||||
updateSectionVisibility();
|
||||
updateGenerationModeUI();
|
||||
applyTheme();
|
||||
applyPanelPosition();
|
||||
toggleCustomColors();
|
||||
toggleAnimations();
|
||||
updateFeatureTogglesVisibility();
|
||||
togglePlotButtons();
|
||||
initWeatherEffects();
|
||||
|
||||
// Initialize mobile UI
|
||||
setupMobileToggle();
|
||||
constrainFabToViewport();
|
||||
@@ -305,7 +382,7 @@ jQuery(async () => {
|
||||
|
||||
// Load settings with validation
|
||||
try {
|
||||
loadSettings();
|
||||
await loadSettings();
|
||||
} catch (error) {
|
||||
console.error('[RPG Companion] Settings load failed, continuing with defaults:', error);
|
||||
}
|
||||
@@ -329,7 +406,7 @@ jQuery(async () => {
|
||||
|
||||
// Add extension settings to Extensions tab
|
||||
try {
|
||||
await addExtensionSettings($, renderExtensionTemplateAsync, clearExtensionPrompts, updateChatThoughts, cleanupCheckpointUI, clearThoughtBasedExpressionsCache, toggleDynamicWeather, initUI, loadChatData, scheduleChatStateRehydration, initThoughtBasedExpressions, injectCheckpointButton, updateAllCheckpointIndicators, removeAlternatePresentCharactersPanel);
|
||||
await addExtensionSettings($, renderExtensionTemplateAsync, clearExtensionPrompts, updateChatThoughts, cleanupCheckpointUI, clearThoughtBasedExpressionsCache, toggleDynamicWeather, initUI, loadChatData, scheduleChatStateRehydration, initThoughtBasedExpressions, injectCheckpointButton, updateAllCheckpointIndicators, removeAlternatePresentCharactersPanel, registerExtensionEvents, unregisterAllEvents, initHistoryInjection);
|
||||
} catch (error) {
|
||||
console.error('[RPG Companion] Failed to add extension settings tab:', error);
|
||||
}
|
||||
@@ -373,63 +450,7 @@ jQuery(async () => {
|
||||
|
||||
// Register all event listeners
|
||||
try {
|
||||
registerAllEvents({
|
||||
[event_types.MESSAGE_SENT]: onMessageSent,
|
||||
[event_types.GENERATION_STARTED]: onGenerationStarted,
|
||||
[event_types.MESSAGE_RECEIVED]: onMessageReceived,
|
||||
[event_types.GENERATION_STOPPED]: onGenerationEnded,
|
||||
[event_types.GENERATION_ENDED]: onGenerationEnded,
|
||||
[event_types.CHAT_CHANGED]: [onCharacterChanged, updatePersonaAvatar, restoreCheckpointOnLoad, clearSessionAvatarPrompts, clearDebugLogs],
|
||||
[event_types.CHAT_LOADED]: onChatLoaded,
|
||||
[event_types.MESSAGE_DELETED]: onMessageDeleted,
|
||||
[event_types.MESSAGE_SWIPE_DELETED]: onMessageDeleted,
|
||||
[event_types.MESSAGE_SWIPED]: onMessageSwiped,
|
||||
[event_types.USER_MESSAGE_RENDERED]: updatePersonaAvatar,
|
||||
[event_types.SETTINGS_UPDATED]: updatePersonaAvatar
|
||||
});
|
||||
|
||||
// Use tracked event registration (onEvent) instead of direct eventSource.on()
|
||||
// This ensures all handlers are tracked for cleanup by unregisterAllEvents()
|
||||
onEvent(event_types.CHARACTER_MESSAGE_RENDERED, (messageId) => {
|
||||
if (!extensionSettings.enabled) return;
|
||||
const renderedMessage = chat[messageId];
|
||||
if (renderedMessage && !renderedMessage.is_user && !renderedMessage.is_system) {
|
||||
queueThoughtBasedExpressionsUpdate();
|
||||
}
|
||||
});
|
||||
|
||||
onEvent(event_types.MESSAGE_UPDATED, (messageId) => {
|
||||
if (!extensionSettings.enabled) return;
|
||||
const updatedMessage = chat[messageId];
|
||||
if (updatedMessage && !updatedMessage.is_user && !updatedMessage.is_system) {
|
||||
queueThoughtBasedExpressionsUpdate();
|
||||
}
|
||||
});
|
||||
|
||||
onEvent(event_types.MESSAGE_SWIPED, (messageIndex) => {
|
||||
if (!extensionSettings.enabled) return;
|
||||
const swipedMessage = chat[messageIndex];
|
||||
if (swipedMessage && !swipedMessage.is_user && !swipedMessage.is_system) {
|
||||
queueThoughtBasedExpressionsUpdate({ immediate: true });
|
||||
}
|
||||
});
|
||||
|
||||
onEvent(event_types.CHAT_CHANGED, () => {
|
||||
clearThoughtBasedExpressionsCache();
|
||||
setTimeout(() => onThoughtBasedExpressionsChatChanged(), 0);
|
||||
});
|
||||
|
||||
onEvent(event_types.MESSAGE_DELETED, () => {
|
||||
if (!extensionSettings.enabled) return;
|
||||
clearThoughtBasedExpressionsCache();
|
||||
setTimeout(() => onThoughtBasedExpressionsChatChanged(), 0);
|
||||
});
|
||||
|
||||
onEvent(event_types.MESSAGE_SWIPE_DELETED, () => {
|
||||
if (!extensionSettings.enabled) return;
|
||||
clearThoughtBasedExpressionsCache();
|
||||
setTimeout(() => onThoughtBasedExpressionsChatChanged(), 0);
|
||||
});
|
||||
registerExtensionEvents();
|
||||
} catch (error) {
|
||||
console.error('[RPG Companion] Event registration failed:', error);
|
||||
throw error;
|
||||
|
||||
Reference in New Issue
Block a user