Gate below-chat expression sync and localize inline thoughts

This commit is contained in:
Tremendoussly
2026-03-15 16:51:20 +01:00
parent 4d2afafbaf
commit 1d297aeecf
7 changed files with 60 additions and 26 deletions
+2
View File
@@ -139,6 +139,7 @@ import {
initExpressionSync, initExpressionSync,
queueExpressionCaptureForSpeaker, queueExpressionCaptureForSpeaker,
onExpressionSyncSettingChanged, onExpressionSyncSettingChanged,
onAlternatePresentCharactersVisibilityChanged,
onHideDefaultExpressionDisplaySettingChanged, onHideDefaultExpressionDisplaySettingChanged,
clearExpressionSyncCache, clearExpressionSyncCache,
onExpressionSyncChatChanged onExpressionSyncChatChanged
@@ -358,6 +359,7 @@ async function initUI() {
extensionSettings.showAlternatePresentCharactersPanel = $(this).prop('checked'); extensionSettings.showAlternatePresentCharactersPanel = $(this).prop('checked');
saveSettings(); saveSettings();
renderThoughts(); renderThoughts();
onAlternatePresentCharactersVisibilityChanged();
}); });
$('#rpg-toggle-sync-expressions').on('change', function() { $('#rpg-toggle-sync-expressions').on('change', function() {
+2
View File
@@ -50,6 +50,8 @@
"template.settingsModal.display.showLockIconsNote": "Display lock/unlock icons on tracker items to prevent AI from modifying them.", "template.settingsModal.display.showLockIconsNote": "Display lock/unlock icons on tracker items to prevent AI from modifying them.",
"template.settingsModal.display.showThoughtsInChat": "Show Thoughts", "template.settingsModal.display.showThoughtsInChat": "Show Thoughts",
"template.settingsModal.display.showThoughtsInChatNote": "Display character thoughts as overlay bubbles next to their messages.", "template.settingsModal.display.showThoughtsInChatNote": "Display character thoughts as overlay bubbles next to their messages.",
"template.settingsModal.display.showInlineThoughts": "Show Thoughts Below Message Text",
"template.settingsModal.display.showInlineThoughtsNote": "Switch between the default corner thought bubbles and thought cards below the message text.",
"template.settingsModal.display.alwaysShowThoughtBubble": "Always Show Thought Bubble", "template.settingsModal.display.alwaysShowThoughtBubble": "Always Show Thought Bubble",
"template.settingsModal.display.alwaysShowThoughtBubbleNote": "Auto-expand thought bubble without clicking the icon first", "template.settingsModal.display.alwaysShowThoughtBubbleNote": "Auto-expand thought bubble without clicking the icon first",
"template.settingsModal.display.enableAnimations": "Enable Animations", "template.settingsModal.display.enableAnimations": "Enable Animations",
+2
View File
@@ -51,6 +51,8 @@
"template.settingsModal.display.showLockIconsNote": "Afficher les icônes de verrouillage/déverrouillage sur les éléments de suivi pour empêcher l'IA de les modifier.", "template.settingsModal.display.showLockIconsNote": "Afficher les icônes de verrouillage/déverrouillage sur les éléments de suivi pour empêcher l'IA de les modifier.",
"template.settingsModal.display.showThoughtsInChat": "Afficher Pensées", "template.settingsModal.display.showThoughtsInChat": "Afficher Pensées",
"template.settingsModal.display.showThoughtsInChatNote": "Afficher les pensées des personnages sous forme de bulles superposées à côté de leurs messages.", "template.settingsModal.display.showThoughtsInChatNote": "Afficher les pensées des personnages sous forme de bulles superposées à côté de leurs messages.",
"template.settingsModal.display.showInlineThoughts": "Afficher les pensées sous le texte du message",
"template.settingsModal.display.showInlineThoughtsNote": "Basculer entre les bulles de pensée dans le coin par défaut et des cartes de pensée sous le texte du message.",
"template.settingsModal.display.alwaysShowThoughtBubble": "Toujours Afficher Bulle Pensée", "template.settingsModal.display.alwaysShowThoughtBubble": "Toujours Afficher Bulle Pensée",
"template.settingsModal.display.alwaysShowThoughtBubbleNote": "Développer automatiquement la bulle de pensée sans cliquer sur l'icône d'abord", "template.settingsModal.display.alwaysShowThoughtBubbleNote": "Développer automatiquement la bulle de pensée sans cliquer sur l'icône d'abord",
"template.settingsModal.display.enableAnimations": "Activer Animations", "template.settingsModal.display.enableAnimations": "Activer Animations",
+2
View File
@@ -50,6 +50,8 @@
"template.settingsModal.display.showLockIconsNote": "Отображать значки блокировки/разблокировки на элементах трекера, чтобы предотвратить их изменение ИИ.", "template.settingsModal.display.showLockIconsNote": "Отображать значки блокировки/разблокировки на элементах трекера, чтобы предотвратить их изменение ИИ.",
"template.settingsModal.display.showThoughtsInChat": "Показывать мысли", "template.settingsModal.display.showThoughtsInChat": "Показывать мысли",
"template.settingsModal.display.showThoughtsInChatNote": "Отображать мысли персонажей в виде всплывающих пузырьков рядом с их сообщениями.", "template.settingsModal.display.showThoughtsInChatNote": "Отображать мысли персонажей в виде всплывающих пузырьков рядом с их сообщениями.",
"template.settingsModal.display.showInlineThoughts": "Показывать мысли под текстом сообщения",
"template.settingsModal.display.showInlineThoughtsNote": "Переключает между стандартными угловыми пузырями мыслей и карточками мыслей под текстом сообщения.",
"template.settingsModal.display.alwaysShowThoughtBubble": "Всегда показывать пузырь мыслей", "template.settingsModal.display.alwaysShowThoughtBubble": "Всегда показывать пузырь мыслей",
"template.settingsModal.display.alwaysShowThoughtBubbleNote": "Автоматически раскрывать пузырь мыслей без предварительного нажатия на значок", "template.settingsModal.display.alwaysShowThoughtBubbleNote": "Автоматически раскрывать пузырь мыслей без предварительного нажатия на значок",
"template.settingsModal.display.enableAnimations": "Включить анимации", "template.settingsModal.display.enableAnimations": "Включить анимации",
+2
View File
@@ -41,6 +41,8 @@
"template.settingsModal.display.showLockIconsNote": "在追蹤器項目上顯示鎖定/解鎖圖示,以防止 AI 修改它們。", "template.settingsModal.display.showLockIconsNote": "在追蹤器項目上顯示鎖定/解鎖圖示,以防止 AI 修改它們。",
"template.settingsModal.display.showThoughtsInChat": "在聊天中顯示想法", "template.settingsModal.display.showThoughtsInChat": "在聊天中顯示想法",
"template.settingsModal.display.showThoughtsInChatNote": "將角色想法顯示為其訊息旁的泡泡", "template.settingsModal.display.showThoughtsInChatNote": "將角色想法顯示為其訊息旁的泡泡",
"template.settingsModal.display.showInlineThoughts": "在訊息文字下方顯示想法",
"template.settingsModal.display.showInlineThoughtsNote": "在預設角落想法泡泡與顯示在訊息文字下方的想法卡片之間切換。",
"template.settingsModal.display.alwaysShowThoughtBubble": "始終顯示想法泡泡", "template.settingsModal.display.alwaysShowThoughtBubble": "始終顯示想法泡泡",
"template.settingsModal.display.alwaysShowThoughtBubbleNote": "自動展開想法泡泡", "template.settingsModal.display.alwaysShowThoughtBubbleNote": "自動展開想法泡泡",
"template.settingsModal.display.enableAnimations": "啟用動畫", "template.settingsModal.display.enableAnimations": "啟用動畫",
+47 -24
View File
@@ -139,11 +139,14 @@ function shouldHideNativeExpressionDisplay() {
return extensionSettings.enabled === true && extensionSettings.hideDefaultExpressionDisplay === true; return extensionSettings.enabled === true && extensionSettings.hideDefaultExpressionDisplay === true;
} }
function shouldSyncExpressionPortraits() {
return extensionSettings.enabled === true
&& extensionSettings.syncExpressionsToPresentCharacters === true
&& extensionSettings.showAlternatePresentCharactersPanel === true;
}
function shouldRunExpressionObservers() { function shouldRunExpressionObservers() {
return extensionSettings.enabled === true && ( return shouldSyncExpressionPortraits() || shouldHideNativeExpressionDisplay();
extensionSettings.syncExpressionsToPresentCharacters === true
|| extensionSettings.hideDefaultExpressionDisplay === true
);
} }
function isExpressionContainerNode(node) { function isExpressionContainerNode(node) {
@@ -392,8 +395,17 @@ function teardownExpressionObservers() {
observedExpressionImage = null; observedExpressionImage = null;
} }
function resetPendingExpressionCaptureState() {
clearScheduledCaptures();
pendingCaptureRequestId += 1;
pendingSpeakerName = null;
pendingSpeakerBaselineSignature = null;
pendingSpeakerQueuedAt = 0;
lastCapturedExpressionSrc = null;
}
function captureExpressionForSpeaker(speakerName, expectedRequestId = null) { function captureExpressionForSpeaker(speakerName, expectedRequestId = null) {
if (!extensionSettings.enabled || !extensionSettings.syncExpressionsToPresentCharacters) { if (!shouldSyncExpressionPortraits()) {
return false; return false;
} }
if (expectedRequestId !== null && expectedRequestId !== pendingCaptureRequestId) { if (expectedRequestId !== null && expectedRequestId !== pendingCaptureRequestId) {
@@ -466,7 +478,8 @@ function ensureExpressionObservers() {
if (!shouldRunExpressionObservers()) { if (!shouldRunExpressionObservers()) {
teardownExpressionObservers(); teardownExpressionObservers();
return; resetPendingExpressionCaptureState();
return false;
} }
const currentImg = findExpressionImageElement(pendingSpeakerName); const currentImg = findExpressionImageElement(pendingSpeakerName);
@@ -506,6 +519,8 @@ function ensureExpressionObservers() {
childList: true, childList: true,
subtree: true subtree: true
}); });
return true;
} }
function clearScheduledCaptures() { function clearScheduledCaptures() {
@@ -517,7 +532,7 @@ function clearScheduledCaptures() {
} }
export function queueExpressionCaptureForSpeaker(speakerName) { export function queueExpressionCaptureForSpeaker(speakerName) {
if (!extensionSettings.enabled || !extensionSettings.syncExpressionsToPresentCharacters) { if (!shouldSyncExpressionPortraits()) {
return; return;
} }
@@ -543,7 +558,7 @@ export function queueExpressionCaptureForSpeaker(speakerName) {
} }
export function syncExpressionFromLatestMessage() { export function syncExpressionFromLatestMessage() {
if (!extensionSettings.enabled || !extensionSettings.syncExpressionsToPresentCharacters) { if (!shouldSyncExpressionPortraits()) {
return; return;
} }
@@ -557,7 +572,7 @@ export function initExpressionSync() {
ensureExpressionObservers(); ensureExpressionObservers();
if (extensionSettings.syncExpressionsToPresentCharacters) { if (shouldSyncExpressionPortraits()) {
syncExpressionFromLatestMessage(); syncExpressionFromLatestMessage();
} }
} }
@@ -578,7 +593,7 @@ export function onExpressionSyncChatChanged() {
setTimeout(() => { setTimeout(() => {
ensureExpressionObservers(); ensureExpressionObservers();
syncNativeExpressionDisplayVisibility(); syncNativeExpressionDisplayVisibility();
if (extensionSettings.syncExpressionsToPresentCharacters) { if (shouldSyncExpressionPortraits()) {
syncExpressionFromLatestMessage(); syncExpressionFromLatestMessage();
} else { } else {
refreshExpressionConsumers(); refreshExpressionConsumers();
@@ -594,18 +609,31 @@ export function onExpressionSyncSettingChanged(enabled) {
if (!purged) { if (!purged) {
refreshExpressionConsumers(); refreshExpressionConsumers();
} }
if (shouldSyncExpressionPortraits()) {
syncExpressionFromLatestMessage();
}
return;
}
const observersActive = ensureExpressionObservers();
if (observersActive) {
resetPendingExpressionCaptureState();
}
refreshExpressionConsumers();
}
export function onAlternatePresentCharactersVisibilityChanged() {
const shouldSyncPortraits = shouldSyncExpressionPortraits();
const observersActive = ensureExpressionObservers();
if (shouldSyncPortraits) {
syncExpressionFromLatestMessage(); syncExpressionFromLatestMessage();
return; return;
} }
ensureExpressionObservers(); if (observersActive) {
clearScheduledCaptures(); resetPendingExpressionCaptureState();
pendingCaptureRequestId += 1; }
pendingSpeakerName = null;
pendingSpeakerBaselineSignature = null;
pendingSpeakerQueuedAt = 0;
lastCapturedExpressionSrc = null;
refreshExpressionConsumers();
} }
export function onHideDefaultExpressionDisplaySettingChanged(enabled) { export function onHideDefaultExpressionDisplaySettingChanged(enabled) {
@@ -617,12 +645,7 @@ export function onHideDefaultExpressionDisplaySettingChanged(enabled) {
} }
export function clearExpressionSyncCache() { export function clearExpressionSyncCache() {
clearScheduledCaptures(); resetPendingExpressionCaptureState();
pendingCaptureRequestId += 1;
pendingSpeakerName = null;
pendingSpeakerBaselineSignature = null;
pendingSpeakerQueuedAt = 0;
lastCapturedExpressionSrc = null;
teardownExpressionObservers(); teardownExpressionObservers();
showNativeExpressionDisplay(); showNativeExpressionDisplay();
} }
+3 -2
View File
@@ -396,9 +396,10 @@
<label class="checkbox_label"> <label class="checkbox_label">
<input type="checkbox" id="rpg-toggle-inline-thoughts" /> <input type="checkbox" id="rpg-toggle-inline-thoughts" />
<span>Show Thoughts Below Message Text</span> <span data-i18n-key="template.settingsModal.display.showInlineThoughts">Show Thoughts Below Message Text</span>
</label> </label>
<small style="display: block; margin-left: 24px; margin-top: -8px; color: #888; font-size: 11px;"> <small style="display: block; margin-left: 24px; margin-top: -8px; color: #888; font-size: 11px;"
data-i18n-key="template.settingsModal.display.showInlineThoughtsNote">
Switch between the default corner thought bubbles and thought cards below the message text. Switch between the default corner thought bubbles and thought cards below the message text.
</small> </small>