first try i18n base ok
This commit is contained in:
@@ -5,6 +5,7 @@ import { power_user } from '../../../power-user.js';
|
|||||||
|
|
||||||
// Core modules
|
// Core modules
|
||||||
import { extensionName, extensionFolderPath } from './src/core/config.js';
|
import { extensionName, extensionFolderPath } from './src/core/config.js';
|
||||||
|
import { i18n } from './src/core/i18n.js';
|
||||||
import {
|
import {
|
||||||
extensionSettings,
|
extensionSettings,
|
||||||
lastGeneratedData,
|
lastGeneratedData,
|
||||||
@@ -155,32 +156,9 @@ import {
|
|||||||
/**
|
/**
|
||||||
* Adds the extension settings to the Extensions tab.
|
* Adds the extension settings to the Extensions tab.
|
||||||
*/
|
*/
|
||||||
function addExtensionSettings() {
|
async function addExtensionSettings() {
|
||||||
const settingsHtml = `
|
// Load the HTML template for the settings
|
||||||
<div class="inline-drawer">
|
const settingsHtml = await renderExtensionTemplateAsync(extensionName, 'settings');
|
||||||
<div class="inline-drawer-toggle inline-drawer-header">
|
|
||||||
<b><i class="fa-solid fa-dice-d20"></i> RPG Companion</b>
|
|
||||||
<div class="inline-drawer-icon fa-solid fa-circle-chevron-down down"></div>
|
|
||||||
</div>
|
|
||||||
<div class="inline-drawer-content">
|
|
||||||
<label class="checkbox_label" for="rpg-extension-enabled">
|
|
||||||
<input type="checkbox" id="rpg-extension-enabled" />
|
|
||||||
<span>Enable RPG Companion</span>
|
|
||||||
</label>
|
|
||||||
<small class="notes">Toggle to enable/disable the RPG Companion extension. Configure additional settings within the panel itself.</small>
|
|
||||||
|
|
||||||
<div style="margin-top: 10px; display: flex; gap: 10px;">
|
|
||||||
<a href="https://discord.com/invite/KdAkTg94ME" target="_blank" class="menu_button" style="flex: 1; text-align: center; text-decoration: none;">
|
|
||||||
<i class="fa-brands fa-discord"></i> Discord
|
|
||||||
</a>
|
|
||||||
<a href="https://ko-fi.com/marinara_spaghetti" target="_blank" class="menu_button" style="flex: 1; text-align: center; text-decoration: none;">
|
|
||||||
<i class="fa-solid fa-heart"></i> Support Creator
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
|
|
||||||
$('#extensions_settings2').append(settingsHtml);
|
$('#extensions_settings2').append(settingsHtml);
|
||||||
|
|
||||||
// Set up the enable/disable toggle
|
// Set up the enable/disable toggle
|
||||||
@@ -210,12 +188,27 @@ function addExtensionSettings() {
|
|||||||
// Update Memory Recollection button visibility
|
// Update Memory Recollection button visibility
|
||||||
updateMemoryRecollectionButton();
|
updateMemoryRecollectionButton();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Set up language selector
|
||||||
|
const langSelect = $('#rpg-companion-language-select');
|
||||||
|
if (langSelect.length) {
|
||||||
|
langSelect.val(i18n.currentLanguage);
|
||||||
|
langSelect.on('change', async function() {
|
||||||
|
const selectedLanguage = $(this).val();
|
||||||
|
await i18n.setLanguage(selectedLanguage);
|
||||||
|
// We need to re-apply translations to the settings panel specifically
|
||||||
|
i18n.applyTranslations(document.getElementById('extensions_settings2'));
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes the UI for the extension.
|
* Initializes the UI for the extension.
|
||||||
*/
|
*/
|
||||||
async function initUI() {
|
async function initUI() {
|
||||||
|
// Initialize i18n
|
||||||
|
await i18n.init();
|
||||||
|
|
||||||
// Only initialize UI if extension is enabled
|
// Only initialize UI if extension is enabled
|
||||||
if (!extensionSettings.enabled) {
|
if (!extensionSettings.enabled) {
|
||||||
console.log('[RPG Companion] Extension disabled - skipping UI initialization');
|
console.log('[RPG Companion] Extension disabled - skipping UI initialization');
|
||||||
@@ -249,6 +242,9 @@ async function initUI() {
|
|||||||
setInventoryContainer($('#rpg-inventory'));
|
setInventoryContainer($('#rpg-inventory'));
|
||||||
setQuestsContainer($('#rpg-quests'));
|
setQuestsContainer($('#rpg-quests'));
|
||||||
|
|
||||||
|
// Re-apply translations to the entire body to catch all new elements from the template
|
||||||
|
i18n.applyTranslations(document.body);
|
||||||
|
|
||||||
// Set up event listeners (enable/disable is handled in Extensions tab)
|
// Set up event listeners (enable/disable is handled in Extensions tab)
|
||||||
$('#rpg-toggle-auto-update').on('change', function() {
|
$('#rpg-toggle-auto-update').on('change', function() {
|
||||||
extensionSettings.autoUpdate = $(this).prop('checked');
|
extensionSettings.autoUpdate = $(this).prop('checked');
|
||||||
@@ -597,9 +593,12 @@ jQuery(async () => {
|
|||||||
console.error('[RPG Companion] Settings load failed, continuing with defaults:', error);
|
console.error('[RPG Companion] Settings load failed, continuing with defaults:', error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Initialize i18n early for the settings panel
|
||||||
|
await i18n.init();
|
||||||
|
|
||||||
// Add extension settings to Extensions tab
|
// Add extension settings to Extensions tab
|
||||||
try {
|
try {
|
||||||
addExtensionSettings();
|
await addExtensionSettings();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('[RPG Companion] Failed to add extension settings tab:', error);
|
console.error('[RPG Companion] Failed to add extension settings tab:', error);
|
||||||
// Don't throw - extension can still work without settings tab
|
// Don't throw - extension can still work without settings tab
|
||||||
|
|||||||
@@ -9,6 +9,15 @@
|
|||||||
<input type="checkbox" id="rpg-extension-enabled" />
|
<input type="checkbox" id="rpg-extension-enabled" />
|
||||||
<span>Enable RPG Companion</span>
|
<span>Enable RPG Companion</span>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
|
<div class="form-group" style="margin-top: 10px;">
|
||||||
|
<label for="rpg-companion-language-select" data-i18n-key="settings.language.label">Language</label>
|
||||||
|
<select id="rpg-companion-language-select" class="text_pole">
|
||||||
|
<option value="en" data-i18n-key="settings.language.option.en">English</option>
|
||||||
|
<option value="zh-tw" data-i18n-key="settings.language.option.zh-tw">繁體中文</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
<small class="notes">Toggle to enable/disable the RPG Companion extension. Configure additional settings within the panel itself.</small>
|
<small class="notes">Toggle to enable/disable the RPG Companion extension. Configure additional settings within the panel itself.</small>
|
||||||
|
|
||||||
<div style="margin-top: 10px; display: flex; gap: 10px;">
|
<div style="margin-top: 10px; display: flex; gap: 10px;">
|
||||||
|
|||||||
@@ -0,0 +1,66 @@
|
|||||||
|
//- No-op in case this is running outside of SillyTavern
|
||||||
|
const { extension_settings } = typeof self.SillyTavern !== 'undefined' ? self.SillyTavern.getContext() : { extension_settings: {} };
|
||||||
|
|
||||||
|
class Internationalization {
|
||||||
|
constructor() {
|
||||||
|
this.currentLanguage = 'en';
|
||||||
|
this.translations = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
async init() {
|
||||||
|
const savedLanguage = localStorage.getItem('rpgCompanionLanguage') || 'en';
|
||||||
|
this.currentLanguage = savedLanguage;
|
||||||
|
|
||||||
|
await this.loadTranslations(this.currentLanguage);
|
||||||
|
this.applyTranslations(document.body);
|
||||||
|
|
||||||
|
const langSelect = document.getElementById('rpg-companion-language-select');
|
||||||
|
if (langSelect) {
|
||||||
|
langSelect.value = this.currentLanguage;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async loadTranslations(lang) {
|
||||||
|
const fetchUrl = `/scripts/extensions/third-party/rpg-companion-sillytavern/src/i18n/${lang}.json`;
|
||||||
|
try {
|
||||||
|
const response = await fetch(fetchUrl);
|
||||||
|
if (!response.ok) {
|
||||||
|
console.error(`[RPG-Companion-i18n] Failed to load translation file for ${lang}. Status: ${response.status}`);
|
||||||
|
if (lang !== 'en') {
|
||||||
|
return this.loadTranslations('en');
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.translations = await response.json();
|
||||||
|
} catch (error) {
|
||||||
|
console.error('[RPG-Companion-i18n] CRITICAL error loading translation file:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
applyTranslations(rootElement) {
|
||||||
|
if (!rootElement) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const elements = rootElement.querySelectorAll('[data-i18n-key]');
|
||||||
|
elements.forEach(element => {
|
||||||
|
const key = element.dataset.i18nKey;
|
||||||
|
const translation = this.getTranslation(key);
|
||||||
|
if (translation) {
|
||||||
|
element.textContent = translation;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
getTranslation(key) {
|
||||||
|
return this.translations[key] || null;
|
||||||
|
}
|
||||||
|
|
||||||
|
async setLanguage(lang) {
|
||||||
|
this.currentLanguage = lang;
|
||||||
|
localStorage.setItem('rpgCompanionLanguage', lang);
|
||||||
|
await this.loadTranslations(lang);
|
||||||
|
this.applyTranslations(document.body);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const i18n = new Internationalization();
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"settings.language.label": "Language",
|
||||||
|
"settings.language.option.en": "English",
|
||||||
|
"settings.language.option.zh-tw": "繁體中文",
|
||||||
|
"template.settingsTitle": "RPG Companion Settings"
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"settings.language.label": "語言",
|
||||||
|
"settings.language.option.en": "English",
|
||||||
|
"settings.language.option.zh-tw": "繁體中文",
|
||||||
|
"template.settingsTitle": "RPG Companion 設定"
|
||||||
|
}
|
||||||
+1
-1
@@ -92,7 +92,7 @@
|
|||||||
<header class="rpg-settings-popup-header">
|
<header class="rpg-settings-popup-header">
|
||||||
<h3 id="rpg-settings-title">
|
<h3 id="rpg-settings-title">
|
||||||
<i class="fa-solid fa-gear" aria-hidden="true"></i>
|
<i class="fa-solid fa-gear" aria-hidden="true"></i>
|
||||||
<span>RPG Companion Settings</span>
|
<span data-i18n-key="template.settingsTitle">RPG Companion Settings</span>
|
||||||
</h3>
|
</h3>
|
||||||
<button id="rpg-close-settings" class="rpg-popup-close" type="button" aria-label="Close settings">×</button>
|
<button id="rpg-close-settings" class="rpg-popup-close" type="button" aria-label="Close settings">×</button>
|
||||||
</header>
|
</header>
|
||||||
|
|||||||
Reference in New Issue
Block a user