feat(i18n): Enhance internationalization support by updating storage retrieval and translation handling

This commit is contained in:
Will Miao
2025-08-30 17:29:04 +08:00
parent 29160bd6e5
commit 401200050b
4 changed files with 31 additions and 40 deletions

View File

@@ -3,6 +3,7 @@ import { toggleTheme } from '../utils/uiHelpers.js';
import { SearchManager } from '../managers/SearchManager.js'; import { SearchManager } from '../managers/SearchManager.js';
import { FilterManager } from '../managers/FilterManager.js'; import { FilterManager } from '../managers/FilterManager.js';
import { initPageState } from '../state/index.js'; import { initPageState } from '../state/index.js';
import { getStorageItem } from '../utils/storageHelpers.js';
import { updateSearchPlaceholder } from '../utils/i18nHelpers.js'; import { updateSearchPlaceholder } from '../utils/i18nHelpers.js';
/** /**
@@ -49,7 +50,7 @@ export class HeaderManager {
const themeToggle = document.querySelector('.theme-toggle'); const themeToggle = document.querySelector('.theme-toggle');
if (themeToggle) { if (themeToggle) {
// Set initial state based on current theme // Set initial state based on current theme
const currentTheme = localStorage.getItem('lm_theme') || 'auto'; const currentTheme = getStorageItem('theme') || 'auto';
themeToggle.classList.add(`theme-${currentTheme}`); themeToggle.classList.add(`theme-${currentTheme}`);
// Set initial tooltip text // Set initial tooltip text
@@ -157,8 +158,6 @@ export class HeaderManager {
if (currentTheme === 'light') { if (currentTheme === 'light') {
themeToggle.title = window.i18n.t('header.theme.switchToDark'); themeToggle.title = window.i18n.t('header.theme.switchToDark');
} else if (currentTheme === 'dark') { } else if (currentTheme === 'dark') {
themeToggle.title = window.i18n.t('header.theme.switchToAuto');
} else {
themeToggle.title = window.i18n.t('header.theme.switchToLight'); themeToggle.title = window.i18n.t('header.theme.switchToLight');
} }
} }

View File

@@ -2,7 +2,6 @@
import { getCurrentPageState, setCurrentPageType } from '../../state/index.js'; import { getCurrentPageState, setCurrentPageType } from '../../state/index.js';
import { getStorageItem, setStorageItem, getSessionItem, setSessionItem } from '../../utils/storageHelpers.js'; import { getStorageItem, setStorageItem, getSessionItem, setSessionItem } from '../../utils/storageHelpers.js';
import { showToast } from '../../utils/uiHelpers.js'; import { showToast } from '../../utils/uiHelpers.js';
import { SidebarManager } from '../SidebarManager.js';
import { sidebarManager } from '../SidebarManager.js'; import { sidebarManager } from '../SidebarManager.js';
/** /**

View File

@@ -8,45 +8,38 @@ import { i18n } from '../i18n/index.js';
* Uses data-i18n attribute to specify translation keys * Uses data-i18n attribute to specify translation keys
*/ */
export function translateDOM() { export function translateDOM() {
// Find all elements with data-i18n attribute if (!window.i18n) return;
// Select all elements with data-i18n attributes, including optgroups and options
const elements = document.querySelectorAll('[data-i18n]'); const elements = document.querySelectorAll('[data-i18n]');
elements.forEach(element => { elements.forEach(element => {
const key = element.getAttribute('data-i18n'); const key = element.getAttribute('data-i18n');
const params = element.getAttribute('data-i18n-params');
let parsedParams = {};
if (params) {
try {
parsedParams = JSON.parse(params);
} catch (e) {
console.warn(`Invalid JSON in data-i18n-params for key ${key}:`, params);
}
}
// Get translated text
const translatedText = i18n.t(key, parsedParams);
// Handle different translation targets
const target = element.getAttribute('data-i18n-target') || 'textContent'; const target = element.getAttribute('data-i18n-target') || 'textContent';
switch (target) { if (key) {
case 'placeholder': const translation = window.i18n.t(key);
element.placeholder = translatedText;
break; // Handle different target attributes
case 'title': switch (target) {
element.title = translatedText; case 'placeholder':
break; element.placeholder = translation;
case 'alt': break;
element.alt = translatedText; case 'title':
break; element.title = translation;
case 'innerHTML': break;
element.innerHTML = translatedText; case 'label':
break; // For optgroup elements
case 'textContent': element.label = translation;
default: break;
element.textContent = translatedText; case 'value':
break; element.value = translation;
break;
case 'textContent':
default:
element.textContent = translation;
break;
}
} }
}); });
} }

View File

@@ -3,15 +3,15 @@
<div class="action-buttons"> <div class="action-buttons">
<div data-i18n="loras.controls.sort.title" data-i18n-target="title" title="Sort models by..." class="control-group"> <div data-i18n="loras.controls.sort.title" data-i18n-target="title" title="Sort models by..." class="control-group">
<select id="sortSelect"> <select id="sortSelect">
<optgroup data-i18n="loras.controls.sort.name" label="Name"> <optgroup data-i18n="loras.controls.sort.name" data-i18n-target="label" label="Name">
<option value="name:asc" data-i18n="loras.controls.sort.nameAsc">A - Z</option> <option value="name:asc" data-i18n="loras.controls.sort.nameAsc">A - Z</option>
<option value="name:desc" data-i18n="loras.controls.sort.nameDesc">Z - A</option> <option value="name:desc" data-i18n="loras.controls.sort.nameDesc">Z - A</option>
</optgroup> </optgroup>
<optgroup data-i18n="loras.controls.sort.date" label="Date Added"> <optgroup data-i18n="loras.controls.sort.date" data-i18n-target="label" label="Date Added">
<option value="date:desc" data-i18n="loras.controls.sort.dateDesc">Newest</option> <option value="date:desc" data-i18n="loras.controls.sort.dateDesc">Newest</option>
<option value="date:asc" data-i18n="loras.controls.sort.dateAsc">Oldest</option> <option value="date:asc" data-i18n="loras.controls.sort.dateAsc">Oldest</option>
</optgroup> </optgroup>
<optgroup data-i18n="loras.controls.sort.size" label="File Size"> <optgroup data-i18n="loras.controls.sort.size" data-i18n-target="label" label="File Size">
<option value="size:desc" data-i18n="loras.controls.sort.sizeDesc">Largest</option> <option value="size:desc" data-i18n="loras.controls.sort.sizeDesc">Largest</option>
<option value="size:asc" data-i18n="loras.controls.sort.sizeAsc">Smallest</option> <option value="size:asc" data-i18n="loras.controls.sort.sizeAsc">Smallest</option>
</optgroup> </optgroup>