Files
DemonGatanjieu-Anomalous_Mo…/web/modules/interface_settings.js
T
DemonGatanjieuandClaude Opus 5.5 00db5c6fc5 Follow a ComfyUI language change when the browser opens
With the language on "Follow ComfyUI" (the default), the browser read
ComfyUI's language only when the page loaded, and ComfyUI switches its
language without a reload. Opening the browser now takes up the current
ComfyUI language.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 12:13:57 +08:00

184 lines
7.2 KiB
JavaScript

import { app } from '../../../scripts/app.js';
import { normalizeLocale, resolveLocale, translate } from './locales.js';
export const LANGUAGE_SETTING_ID = 'Anomalous.ModelBrowser.Language';
export const ABYSSAL_SCARLET_SETTING_ID = 'Anomalous.ModelBrowser.AbyssalScarletTheme';
let defaultLang = 'zh';
try {
let comfyDetected = false;
const aglLang = localStorage.getItem('Comfy.Settings.AIGODLIKE-COMFYUI-TRANSLATION.Language');
if (aglLang) {
defaultLang = aglLang.toLowerCase().includes('en') ? 'en' : 'zh';
comfyDetected = true;
} else {
for (let i = 0; i < localStorage.length; i++) {
const key = localStorage.key(i);
if (!key || (!key.toLowerCase().includes('lang') && !key.toLowerCase().includes('locale'))) continue;
const value = localStorage.getItem(key);
if (typeof value !== 'string') continue;
const normalizedValue = value.toLowerCase();
if (normalizedValue.includes('zh') || normalizedValue.includes('chinese')) {
defaultLang = 'zh';
comfyDetected = true;
break;
}
if (normalizedValue.includes('en') || normalizedValue.includes('english')) {
defaultLang = 'en';
comfyDetected = true;
break;
}
}
}
if (!comfyDetected && navigator.language && !navigator.language.toLowerCase().startsWith('zh')) {
defaultLang = 'en';
}
} catch (_) {
if (navigator.language && !navigator.language.toLowerCase().startsWith('zh')) {
defaultLang = 'en';
}
}
let currentLang = resolveLocale(localStorage.getItem('anomalous_lang') || defaultLang);
window.anomalous_browser_lang = currentLang;
export const t = (key, params) => translate(key, params, window.anomalous_browser_lang || currentLang);
export const getCurrentLanguage = () => currentLang;
function normalizeLanguagePreference(value) {
return value === 'zh' || value === 'en' ? value : 'auto';
}
function resolveComfyLanguage() {
try {
const settings = app.extensionManager?.setting;
const locale = settings?.get('Comfy.Locale')
|| app.ui?.settings?.getSettingValue?.('Comfy.Locale')
|| app.ui?.settings?.getSettingValue?.('Comfy.Locale.Language');
return normalizeLocale(locale) || defaultLang;
} catch (_) {
return defaultLang;
}
}
function getSettingTranslationPatches() {
const category = t('mainInterfaceCategory');
return {
[LANGUAGE_SETTING_ID]: {
name: t('mainLanguageSetting'),
category: ['Anomalous Model Browser', category, 'language'],
tooltip: t('mainLanguageTooltip'),
options: [
{ value: 'auto', text: t('mainLanguageAuto') },
{ value: 'zh', text: t('mainLanguageChinese') },
{ value: 'en', text: t('mainLanguageEnglish') }
]
},
[ABYSSAL_SCARLET_SETTING_ID]: {
name: t('mainAbyssalScarletThemeSetting'),
category: ['Anomalous Model Browser', category, 'theme'],
tooltip: t('mainAbyssalScarletThemeTooltip')
}
};
}
function refreshRegisteredSettings() {
const settingsApi = app.extensionManager?.setting;
const registry = settingsApi?.settings?.value || settingsApi?.settings;
if (!registry || typeof registry !== 'object') return;
for (const [id, patch] of Object.entries(getSettingTranslationPatches())) {
if (registry[id]) registry[id] = { ...registry[id], ...patch };
}
}
/** 'auto' | 'zh' | 'en': the ComfyUI setting's change handler, also used without the settings API. */
export function applyLanguagePreference(value) {
const preference = normalizeLanguagePreference(value);
if (preference === 'auto') localStorage.removeItem('anomalous_lang');
else localStorage.setItem('anomalous_lang', preference);
const nextLanguage = preference === 'auto' ? resolveComfyLanguage() : preference;
const changed = nextLanguage !== window.anomalous_browser_lang;
currentLang = nextLanguage;
window.anomalous_browser_lang = nextLanguage;
refreshRegisteredSettings();
if (changed) {
window.dispatchEvent(new CustomEvent('anomalous-language-change', {
detail: { language: nextLanguage, preference }
}));
}
}
/**
* "Follow ComfyUI" (no language chosen here): takes up a ComfyUI language changed since the
* page loaded. Called when the browser opens, since ComfyUI switches its language without a reload.
*/
export function followComfyLanguage() {
if (!localStorage.getItem('anomalous_lang')) applyLanguagePreference('auto');
}
if (!localStorage.getItem('anomalous_lang')) {
currentLang = resolveComfyLanguage();
window.anomalous_browser_lang = currentLang;
}
function showThemeNoticeToast(isEnabled) {
document.getElementById('anomalous-theme-toast')?.remove();
const toast = document.createElement('div');
toast.id = 'anomalous-theme-toast';
toast.className = 'anomalous-theme-toast' + (isEnabled ? ' is-abyssal' : '');
toast.textContent = isEnabled ? t('themeDomainActivated') : t('themeDomainDeactivated');
document.body.appendChild(toast);
requestAnimationFrame(() => toast.classList.add('is-show'));
setTimeout(() => {
toast.classList.remove('is-show');
setTimeout(() => toast.remove(), 400);
}, 2400);
}
export function setAbyssalScarletTheme(enabled, notify = false) {
const isEnabled = Boolean(enabled);
localStorage.setItem('anomalous_theme_abyssal_scarlet', isEnabled ? 'true' : 'false');
document.documentElement.classList.toggle('theme-abyssal-scarlet', isEnabled);
document.getElementById('anomalous-modal')?.classList.toggle('theme-abyssal-scarlet', isEnabled);
document.getElementById('anomalous-container')?.classList.toggle('theme-abyssal-scarlet', isEnabled);
try {
const settings = app.extensionManager?.setting;
if (settings && typeof settings.set === 'function' && settings.get(ABYSSAL_SCARLET_SETTING_ID) !== isEnabled) {
settings.set(ABYSSAL_SCARLET_SETTING_ID, isEnabled);
}
} catch (_) {}
if (notify) showThemeNoticeToast(isEnabled);
window.dispatchEvent(new CustomEvent('anomalous-theme-change', {
detail: { theme: isEnabled ? 'abyssal-scarlet' : 'default', enabled: isEnabled }
}));
}
window.setAbyssalScarletTheme = setAbyssalScarletTheme;
setAbyssalScarletTheme(localStorage.getItem('anomalous_theme_abyssal_scarlet') === 'true', false);
export function createInterfaceSettings() {
const translations = getSettingTranslationPatches();
return [
{
id: LANGUAGE_SETTING_ID,
...translations[LANGUAGE_SETTING_ID],
type: 'combo',
defaultValue: () => normalizeLanguagePreference(localStorage.getItem('anomalous_lang')),
onChange: applyLanguagePreference
},
{
id: ABYSSAL_SCARLET_SETTING_ID,
...translations[ABYSSAL_SCARLET_SETTING_ID],
type: 'boolean',
defaultValue: () => localStorage.getItem('anomalous_theme_abyssal_scarlet') === 'true',
onChange(value) {
setAbyssalScarletTheme(Boolean(value), true);
}
}
];
}