From bd8d7a019f9a3f43619332a41bf1e48811feab41 Mon Sep 17 00:00:00 2001 From: "alexei.dolgolyov" Date: Sat, 28 Feb 2026 12:12:37 +0300 Subject: [PATCH] Codebase review: stability, performance, usability, and i18n fixes Stability: - Fix race condition: set _is_running before create_task in target processors - Await probe task after cancel in wled_target_processor - Replace raw fetch() with fetchWithAuth() across devices, kc-targets, pattern-templates - Add try/catch to showTestTemplateModal in streams.js - Wrap blocking I/O in asyncio.to_thread (picture_targets, system restore) - Fix dashboardStopAll to filter only running targets with ok guard Performance: - Vectorize fire effect spark loop with numpy in effect_stream - Vectorize FFT band binning with cumulative sum in analysis.py - Rewrite pixel_processor with vectorized numpy (accept ndarray or list) - Add httpx.AsyncClient connection pooling with lock in wled_provider - Optimize _send_pixels_http to avoid np.hstack allocation in wled_client - Mutate chart arrays in-place in dashboard, perf-charts, targets - Merge dashboard 2-batch fetch into single Promise.all - Hoist frame_time outside loop in mapped_stream Usability: - Fix health check interval load/save in device settings - Swap confirm modal button classes (No=secondary, Yes=danger) - Add aria-modal to audio/value source editors, fix close button aria-labels - Add modal footer close button to settings modal - Add dedicated calibration LED count validation error keys i18n: - Replace ~50 hardcoded English strings with t() calls across 12 JS files - Add 50 new keys to en.json, ru.json, zh.json - Localize inline toasts in index.html with window.t fallback - Add data-i18n to command palette footer - Add localization policy to CLAUDE.md Co-Authored-By: Claude Opus 4.6 --- CLAUDE.md | 9 ++ .../api/routes/picture_targets.py | 6 +- .../src/wled_controller/api/routes/system.py | 22 ++-- .../wled_controller/core/audio/analysis.py | 20 +++- .../core/capture/pixel_processor.py | 104 ++++++++---------- .../core/devices/wled_client.py | 9 +- .../core/devices/wled_provider.py | 79 ++++++++----- .../core/processing/effect_stream.py | 13 ++- .../core/processing/kc_target_processor.py | 2 +- .../core/processing/mapped_stream.py | 2 +- .../core/processing/wled_target_processor.py | 6 +- .../static/js/features/audio-sources.js | 5 +- .../static/js/features/calibration.js | 27 ++--- .../static/js/features/color-strips.js | 8 +- .../static/js/features/dashboard.js | 53 +++++---- .../static/js/features/device-discovery.js | 8 +- .../static/js/features/devices.js | 44 ++++---- .../static/js/features/kc-targets.js | 12 +- .../static/js/features/pattern-templates.js | 14 +-- .../static/js/features/perf-charts.js | 10 +- .../static/js/features/streams.js | 35 +++--- .../static/js/features/targets.js | 26 +++-- .../static/js/features/value-sources.js | 5 +- .../wled_controller/static/locales/en.json | 51 ++++++++- .../wled_controller/static/locales/ru.json | 51 ++++++++- .../wled_controller/static/locales/zh.json | 51 ++++++++- .../src/wled_controller/templates/index.html | 6 +- .../templates/modals/audio-source-editor.html | 4 +- .../templates/modals/confirm.html | 4 +- .../templates/modals/settings.html | 3 + .../templates/modals/value-source-editor.html | 4 +- 31 files changed, 460 insertions(+), 233 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index bfc4958..0eba926 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -191,6 +191,15 @@ The app has an interactive tutorial system (`static/js/features/tutorials.js`) w When adding **new tabs, sections, or major UI elements**, update the corresponding tutorial step array in `tutorials.js` and add `tour.*` i18n keys to all 3 locale files (`en.json`, `ru.json`, `zh.json`). +## Localization (i18n) + +**Every user-facing string must be localized.** Never use hardcoded English strings in `showToast()`, `error.textContent`, modal messages, or any other UI-visible text. Always use `t('key')` from `../core/i18n.js` and add the corresponding key to **all three** locale files (`en.json`, `ru.json`, `zh.json`). + +- In JS modules: `import { t } from '../core/i18n.js';` then `showToast(t('my.key'), 'error')` +- In inline `