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 <noreply@anthropic.com>
This commit is contained in:
@@ -242,19 +242,26 @@ function restoreCaptureDuration() {
|
||||
}
|
||||
|
||||
export async function showTestTemplateModal(templateId) {
|
||||
const templates = await fetchWithAuth('/capture-templates').then(r => r.json());
|
||||
const template = templates.templates.find(t => t.id === templateId);
|
||||
try {
|
||||
const resp = await fetchWithAuth('/capture-templates');
|
||||
if (!resp.ok) throw new Error(`HTTP ${resp.status}`);
|
||||
const data = await resp.json();
|
||||
const template = (data.templates || []).find(tp => tp.id === templateId);
|
||||
|
||||
if (!template) {
|
||||
if (!template) {
|
||||
showToast(t('templates.error.load'), 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
window.currentTestingTemplate = template;
|
||||
await loadDisplaysForTest();
|
||||
restoreCaptureDuration();
|
||||
|
||||
testTemplateModal.open();
|
||||
} catch (error) {
|
||||
if (error.isAuth) return;
|
||||
showToast(t('templates.error.load'), 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
window.currentTestingTemplate = template;
|
||||
await loadDisplaysForTest();
|
||||
restoreCaptureDuration();
|
||||
|
||||
testTemplateModal.open();
|
||||
}
|
||||
|
||||
export function closeTestTemplateModal() {
|
||||
@@ -871,7 +878,7 @@ export async function cloneAudioTemplate(templateId) {
|
||||
} catch (error) {
|
||||
if (error.isAuth) return;
|
||||
console.error('Failed to clone audio template:', error);
|
||||
showToast('Failed to clone audio template', 'error');
|
||||
showToast(t('audio_template.error.clone_failed'), 'error');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2213,7 +2220,7 @@ export async function cloneStream(streamId) {
|
||||
} catch (error) {
|
||||
if (error.isAuth) return;
|
||||
console.error('Failed to clone stream:', error);
|
||||
showToast('Failed to clone picture source', 'error');
|
||||
showToast(t('stream.error.clone_picture_failed'), 'error');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2226,7 +2233,7 @@ export async function cloneCaptureTemplate(templateId) {
|
||||
} catch (error) {
|
||||
if (error.isAuth) return;
|
||||
console.error('Failed to clone capture template:', error);
|
||||
showToast('Failed to clone capture template', 'error');
|
||||
showToast(t('stream.error.clone_capture_failed'), 'error');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2239,7 +2246,7 @@ export async function clonePPTemplate(templateId) {
|
||||
} catch (error) {
|
||||
if (error.isAuth) return;
|
||||
console.error('Failed to clone PP template:', error);
|
||||
showToast('Failed to clone postprocessing template', 'error');
|
||||
showToast(t('stream.error.clone_pp_failed'), 'error');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user