Fix localization: Update dynamic content when language changes
Some checks failed
Validate / validate (push) Failing after 9s

Fixed issues where device details and display badges were not updating
when switching languages:

Changes:
- Updated updateAllText() to reload displays and devices when language changes
- Added translations to createDeviceCard() for all dynamic text:
  * Device status badges (Processing/Idle)
  * Device info labels (URL, LED Count, Display)
  * Metrics labels (Actual FPS, Target FPS, Frames, Errors)
  * Button labels (Start, Stop, Settings, Calibrate, Remove)
- Updated loadDevices() error messages to use translations
- Added missing translations to locale files:
  * device.metrics.actual_fps, target_fps, frames, errors

Now when switching between English and Russian, all device cards and
display information updates correctly, including:
- Primary/Secondary display badges
- Device status badges
- All labels and button text
- Metrics labels when processing

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-02-06 17:14:06 +03:00
parent 38018750ed
commit c40c8b9d26
3 changed files with 31 additions and 16 deletions

View File

@@ -120,6 +120,12 @@ function updateAllText() {
const key = el.getAttribute('data-i18n-title'); const key = el.getAttribute('data-i18n-title');
el.title = t(key); el.title = t(key);
}); });
// Re-render dynamic content with new translations
if (apiKey) {
loadDisplays();
loadDevices();
}
} }
// Initialize app // Initialize app
@@ -360,7 +366,7 @@ async function loadDevices() {
const container = document.getElementById('devices-list'); const container = document.getElementById('devices-list');
if (!devices || devices.length === 0) { if (!devices || devices.length === 0) {
container.innerHTML = '<div class="loading">No devices attached</div>'; container.innerHTML = `<div class="loading">${t('devices.none')}</div>`;
return; return;
} }
@@ -395,7 +401,7 @@ async function loadDevices() {
} catch (error) { } catch (error) {
console.error('Failed to load devices:', error); console.error('Failed to load devices:', error);
document.getElementById('devices-list').innerHTML = document.getElementById('devices-list').innerHTML =
'<div class="loading">Failed to load devices</div>'; `<div class="loading">${t('devices.failed')}</div>`;
} }
} }
@@ -405,44 +411,45 @@ function createDeviceCard(device) {
const settings = device.settings || {}; const settings = device.settings || {};
const isProcessing = state.processing || false; const isProcessing = state.processing || false;
const statusKey = isProcessing ? 'device.status.processing' : 'device.status.idle';
const status = isProcessing ? 'processing' : 'idle'; const status = isProcessing ? 'processing' : 'idle';
return ` return `
<div class="card" data-device-id="${device.id}"> <div class="card" data-device-id="${device.id}">
<div class="card-header"> <div class="card-header">
<div class="card-title">${device.name || device.id}</div> <div class="card-title">${device.name || device.id}</div>
<span class="badge ${status}">${status.toUpperCase()}</span> <span class="badge ${status}">${t(statusKey)}</span>
</div> </div>
<div class="card-content"> <div class="card-content">
<div class="info-row"> <div class="info-row">
<span class="info-label">URL:</span> <span class="info-label">${t('device.url')}</span>
<span class="info-value">${device.url || 'N/A'}</span> <span class="info-value">${device.url || 'N/A'}</span>
</div> </div>
<div class="info-row"> <div class="info-row">
<span class="info-label">LED Count:</span> <span class="info-label">${t('device.led_count')}</span>
<span class="info-value">${device.led_count || 0}</span> <span class="info-value">${device.led_count || 0}</span>
</div> </div>
<div class="info-row"> <div class="info-row">
<span class="info-label">Display:</span> <span class="info-label">${t('device.display')}</span>
<span class="info-value">Display ${settings.display_index !== undefined ? settings.display_index : 0}</span> <span class="info-value">${settings.display_index !== undefined ? settings.display_index : 0}</span>
</div> </div>
${isProcessing ? ` ${isProcessing ? `
<div class="metrics-grid"> <div class="metrics-grid">
<div class="metric"> <div class="metric">
<div class="metric-value">${state.fps_actual?.toFixed(1) || '0.0'}</div> <div class="metric-value">${state.fps_actual?.toFixed(1) || '0.0'}</div>
<div class="metric-label">Actual FPS</div> <div class="metric-label">${t('device.metrics.actual_fps')}</div>
</div> </div>
<div class="metric"> <div class="metric">
<div class="metric-value">${state.fps_target || 0}</div> <div class="metric-value">${state.fps_target || 0}</div>
<div class="metric-label">Target FPS</div> <div class="metric-label">${t('device.metrics.target_fps')}</div>
</div> </div>
<div class="metric"> <div class="metric">
<div class="metric-value">${metrics.frames_processed || 0}</div> <div class="metric-value">${metrics.frames_processed || 0}</div>
<div class="metric-label">Frames</div> <div class="metric-label">${t('device.metrics.frames')}</div>
</div> </div>
<div class="metric"> <div class="metric">
<div class="metric-value">${metrics.errors_count || 0}</div> <div class="metric-value">${metrics.errors_count || 0}</div>
<div class="metric-label">Errors</div> <div class="metric-label">${t('device.metrics.errors')}</div>
</div> </div>
</div> </div>
` : ''} ` : ''}
@@ -450,21 +457,21 @@ function createDeviceCard(device) {
<div class="card-actions"> <div class="card-actions">
${isProcessing ? ` ${isProcessing ? `
<button class="btn btn-danger" onclick="stopProcessing('${device.id}')"> <button class="btn btn-danger" onclick="stopProcessing('${device.id}')">
Stop Processing ${t('device.button.stop')}
</button> </button>
` : ` ` : `
<button class="btn btn-primary" onclick="startProcessing('${device.id}')"> <button class="btn btn-primary" onclick="startProcessing('${device.id}')">
Start Processing ${t('device.button.start')}
</button> </button>
`} `}
<button class="btn btn-secondary" onclick="showSettings('${device.id}')"> <button class="btn btn-secondary" onclick="showSettings('${device.id}')">
Settings ${t('device.button.settings')}
</button> </button>
<button class="btn btn-secondary" onclick="showCalibration('${device.id}')"> <button class="btn btn-secondary" onclick="showCalibration('${device.id}')">
Calibrate ${t('device.button.calibrate')}
</button> </button>
<button class="btn btn-danger" onclick="removeDevice('${device.id}')"> <button class="btn btn-danger" onclick="removeDevice('${device.id}')">
Remove ${t('device.button.remove')}
</button> </button>
</div> </div>
</div> </div>

View File

@@ -64,6 +64,10 @@
"device.removed": "Device removed successfully", "device.removed": "Device removed successfully",
"device.started": "Processing started", "device.started": "Processing started",
"device.stopped": "Processing stopped", "device.stopped": "Processing stopped",
"device.metrics.actual_fps": "Actual FPS",
"device.metrics.target_fps": "Target FPS",
"device.metrics.frames": "Frames",
"device.metrics.errors": "Errors",
"settings.title": "Device Settings", "settings.title": "Device Settings",
"settings.brightness": "Brightness:", "settings.brightness": "Brightness:",
"settings.brightness.hint": "Global brightness for this WLED device (0-100%)", "settings.brightness.hint": "Global brightness for this WLED device (0-100%)",

View File

@@ -64,6 +64,10 @@
"device.removed": "Устройство успешно удалено", "device.removed": "Устройство успешно удалено",
"device.started": "Обработка запущена", "device.started": "Обработка запущена",
"device.stopped": "Обработка остановлена", "device.stopped": "Обработка остановлена",
"device.metrics.actual_fps": "Факт. FPS",
"device.metrics.target_fps": "Целев. FPS",
"device.metrics.frames": "Кадры",
"device.metrics.errors": "Ошибки",
"settings.title": "Настройки Устройства", "settings.title": "Настройки Устройства",
"settings.brightness": "Яркость:", "settings.brightness": "Яркость:",
"settings.brightness.hint": "Общая яркость для этого WLED устройства (0-100%)", "settings.brightness.hint": "Общая яркость для этого WLED устройства (0-100%)",