diff --git a/index.js b/index.js index fae72aa..288a562 100644 --- a/index.js +++ b/index.js @@ -105,7 +105,8 @@ import { setupMobileTabs, removeMobileTabs, setupMobileKeyboardHandling, - setupContentEditableScrolling + setupContentEditableScrolling, + updateMobileTabLabels } from './src/systems/ui/mobile.js'; import { setupDesktopTabs, @@ -153,6 +154,24 @@ import { // (setupMobileToggle, constrainFabToViewport, setupMobileTabs, removeMobileTabs, // setupMobileKeyboardHandling, setupContentEditableScrolling) +/** + * Updates UI elements that are dynamically generated and not covered by data-i18n-key. + */ +function updateDynamicLabels() { + // Update "Refresh RPG Info" button, but only if it's not disabled + const refreshBtn = document.getElementById('rpg-manual-update'); + if (refreshBtn && !refreshBtn.disabled) { + const refreshText = i18n.getTranslation('template.mainPanel.refreshRpgInfo') || 'Refresh RPG Info'; + refreshBtn.innerHTML = ` ${refreshText}`; + } + + // Update "Last Roll" label + updateDiceDisplay(); + + // Update mobile tab labels + updateMobileTabLabels(); +} + /** * Adds the extension settings to the Extensions tab. */ @@ -596,6 +615,9 @@ jQuery(async () => { // Initialize i18n early for the settings panel await i18n.init(); + // Set up a central listener for language changes to update dynamic UI parts + i18n.addEventListener('languageChanged', updateDynamicLabels); + // Add extension settings to Extensions tab try { await addExtensionSettings(); diff --git a/src/i18n/en.json b/src/i18n/en.json index 10835b6..8e7f0fd 100644 --- a/src/i18n/en.json +++ b/src/i18n/en.json @@ -110,6 +110,7 @@ "template.mainPanel.clearLastRoll": "Clear last roll", "template.mainPanel.enableImmersiveHtml": "Enable Immersive HTML", "template.mainPanel.refreshRpgInfo": "Refresh RPG Info", + "template.mainPanel.updating": "Updating...", "template.mainPanel.editTrackersButton": "Edit Trackers", "template.mainPanel.settingsButton": "Settings", "global.none": "None", diff --git a/src/i18n/zh-tw.json b/src/i18n/zh-tw.json index 3714b09..d197716 100644 --- a/src/i18n/zh-tw.json +++ b/src/i18n/zh-tw.json @@ -110,6 +110,7 @@ "template.mainPanel.clearLastRoll": "清除上次擲骰", "template.mainPanel.enableImmersiveHtml": "啟用沉浸式 HTML", "template.mainPanel.refreshRpgInfo": "刷新資訊", + "template.mainPanel.updating": "更新中...", "template.mainPanel.editTrackersButton": "追蹤器編輯", "template.mainPanel.settingsButton": "設定", "global.none": "None", diff --git a/src/systems/features/dice.js b/src/systems/features/dice.js index 3e452d1..fe5a0c4 100644 --- a/src/systems/features/dice.js +++ b/src/systems/features/dice.js @@ -115,6 +115,3 @@ export function addDiceQuickReply() { // For now, the dice display in the sidebar serves as the button } } - -// Add event listener to update display on language change -i18n.addEventListener('languageChanged', updateDiceDisplay); diff --git a/src/systems/generation/apiClient.js b/src/systems/generation/apiClient.js index a279983..fa155bd 100644 --- a/src/systems/generation/apiClient.js +++ b/src/systems/generation/apiClient.js @@ -22,6 +22,7 @@ import { renderInfoBox } from '../rendering/infoBox.js'; import { renderThoughts } from '../rendering/thoughts.js'; import { renderInventory } from '../rendering/inventory.js'; import { renderQuests } from '../rendering/quests.js'; +import { i18n } from '../../core/i18n.js'; // Store the original preset name to restore after tracker generation let originalPresetName = null; @@ -104,8 +105,8 @@ export async function updateRPGData(renderUserStats, renderInfoBox, renderThough // Update button to show "Updating..." state const $updateBtn = $('#rpg-manual-update'); - const originalHtml = $updateBtn.html(); - $updateBtn.html(' Updating...').prop('disabled', true); + const updatingText = i18n.getTranslation('template.mainPanel.updating') || 'Updating...'; + $updateBtn.html(` ${updatingText}`).prop('disabled', true); // Save current preset name before switching (if we're going to switch) if (extensionSettings.useSeparatePreset) { @@ -229,7 +230,8 @@ export async function updateRPGData(renderUserStats, renderInfoBox, renderThough // Restore button to original state const $updateBtn = $('#rpg-manual-update'); - $updateBtn.html(' Refresh RPG Info').prop('disabled', false); + const refreshText = i18n.getTranslation('template.mainPanel.refreshRpgInfo') || 'Refresh RPG Info'; + $updateBtn.html(` ${refreshText}`).prop('disabled', false); // Reset the flag after tracker generation completes // This ensures the flag persists through both main generation AND tracker generation diff --git a/src/systems/ui/mobile.js b/src/systems/ui/mobile.js index 5977ef8..2a8be3b 100644 --- a/src/systems/ui/mobile.js +++ b/src/systems/ui/mobile.js @@ -9,50 +9,47 @@ import { closeMobilePanelWithAnimation, updateCollapseToggleIcon } from './layou import { setupDesktopTabs, removeDesktopTabs } from './desktop.js'; import { i18n } from '../../core/i18n.js'; +/** + * Updates the text labels of the mobile navigation tabs based on the current language. + */ +export function updateMobileTabLabels() { + const $tabs = $('.rpg-mobile-tabs .rpg-mobile-tab'); + if ($tabs.length === 0) return; + + $tabs.each(function() { + const $tab = $(this); + const tabName = $tab.data('tab'); + let translationKey = ''; + + switch (tabName) { + case 'stats': + translationKey = 'global.status'; + break; + case 'info': + translationKey = 'global.info'; + break; + case 'inventory': + translationKey = 'global.inventory'; + break; + case 'quests': + translationKey = 'global.quests'; + break; + } + + if (translationKey) { + const translation = i18n.getTranslation(translationKey); + if (translation) { + $tab.find('span').text(translation); + } + } + }); +} + /** * Sets up the mobile toggle button (FAB) with drag functionality. * Handles touch/mouse events for positioning and panel toggling. */ export function setupMobileToggle() { - /** - * Updates the text labels of the mobile navigation tabs based on the current language. - */ - function updateMobileTabLabels() { - const $tabs = $('.rpg-mobile-tabs .rpg-mobile-tab'); - if ($tabs.length === 0) return; - - $tabs.each(function() { - const $tab = $(this); - const tabName = $tab.data('tab'); - let translationKey = ''; - - switch (tabName) { - case 'stats': - translationKey = 'global.status'; - break; - case 'info': - translationKey = 'global.info'; - break; - case 'inventory': - translationKey = 'global.inventory'; - break; - case 'quests': - translationKey = 'global.quests'; - break; - } - - if (translationKey) { - const translation = i18n.getTranslation(translationKey); - if (translation) { - $tab.find('span').text(translation); - } - } - }); - } - - // Listen for language changes to update tab labels dynamically - i18n.addEventListener('languageChanged', updateMobileTabLabels); - const $mobileToggle = $('#rpg-mobile-toggle'); const $panel = $('#rpg-companion-panel'); const $overlay = $('
');