diff --git a/server/src/wled_controller/static/js/app.js b/server/src/wled_controller/static/js/app.js index 9b6c7bd..2cbde51 100644 --- a/server/src/wled_controller/static/js/app.js +++ b/server/src/wled_controller/static/js/app.js @@ -22,7 +22,7 @@ import { openDisplayPicker, closeDisplayPicker, selectDisplay, formatDisplayLabel, } from './features/displays.js'; import { - startCalibrationTutorial, startDeviceTutorial, + startCalibrationTutorial, startDeviceTutorial, startGettingStartedTutorial, closeTutorial, tutorialNext, tutorialPrev, } from './features/tutorials.js'; @@ -174,6 +174,7 @@ Object.assign(window, { // tutorials startCalibrationTutorial, startDeviceTutorial, + startGettingStartedTutorial, closeTutorial, tutorialNext, tutorialPrev, @@ -502,4 +503,9 @@ document.addEventListener('DOMContentLoaded', async () => { // Start global events WebSocket and auto-refresh startEventsWS(); startAutoRefresh(); + + // Show getting-started tutorial on first visit + if (!localStorage.getItem('tour_completed')) { + setTimeout(() => startGettingStartedTutorial(), 600); + } }); diff --git a/server/src/wled_controller/static/js/features/tutorials.js b/server/src/wled_controller/static/js/features/tutorials.js index a43299f..8c19c3d 100644 --- a/server/src/wled_controller/static/js/features/tutorials.js +++ b/server/src/wled_controller/static/js/features/tutorials.js @@ -19,6 +19,20 @@ const calibrationTutorialSteps = [ { selector: '#cal-skip-end', textKey: 'calibration.tip.skip_leds_end', position: 'top' } ]; +const TOUR_KEY = 'tour_completed'; + +const gettingStartedSteps = [ + { selector: 'header .header-title', textKey: 'tour.welcome', position: 'bottom' }, + { selector: '#tab-btn-dashboard', textKey: 'tour.dashboard', position: 'bottom' }, + { selector: '#tab-btn-targets', textKey: 'tour.targets', position: 'bottom' }, + { selector: '#tab-btn-streams', textKey: 'tour.sources', position: 'bottom' }, + { selector: '#tab-btn-profiles', textKey: 'tour.profiles', position: 'bottom' }, + { selector: '[onclick*="openSettingsModal"]', textKey: 'tour.settings', position: 'bottom' }, + { selector: '[onclick*="openCommandPalette"]', textKey: 'tour.search', position: 'bottom' }, + { selector: '.theme-toggle', textKey: 'tour.theme', position: 'bottom' }, + { selector: '#locale-select', textKey: 'tour.language', position: 'bottom' } +]; + const deviceTutorialSteps = [ { selector: '.card-subtitle', textKey: 'device.tip.metadata', position: 'bottom' }, { selector: '.brightness-control', textKey: 'device.tip.brightness', position: 'bottom' }, @@ -40,7 +54,8 @@ export function startTutorial(config) { mode: config.mode, step: 0, resolveTarget: config.resolveTarget, - container: config.container + container: config.container, + onClose: config.onClose || null }); overlay.classList.add('active'); @@ -86,8 +101,20 @@ export function startDeviceTutorial(deviceId) { }); } +export function startGettingStartedTutorial() { + startTutorial({ + steps: gettingStartedSteps, + overlayId: 'getting-started-overlay', + mode: 'fixed', + container: null, + resolveTarget: (step) => document.querySelector(step.selector) || null, + onClose: () => localStorage.setItem(TOUR_KEY, '1') + }); +} + export function closeTutorial() { if (!activeTutorial) return; + const onClose = activeTutorial.onClose; activeTutorial.overlay.classList.remove('active'); document.querySelectorAll('.tutorial-target').forEach(el => { el.classList.remove('tutorial-target'); @@ -95,6 +122,7 @@ export function closeTutorial() { }); document.removeEventListener('keydown', handleTutorialKey); setActiveTutorial(null); + if (onClose) onClose(); } export function tutorialNext() { diff --git a/server/src/wled_controller/static/locales/en.json b/server/src/wled_controller/static/locales/en.json index 853b8ae..9e8addf 100644 --- a/server/src/wled_controller/static/locales/en.json +++ b/server/src/wled_controller/static/locales/en.json @@ -214,6 +214,16 @@ "calibration.tip.border_width": "How many pixels from the screen edge to sample for LED colors", "calibration.tip.skip_leds_start": "Skip LEDs at the start of the strip — skipped LEDs stay off", "calibration.tip.skip_leds_end": "Skip LEDs at the end of the strip — skipped LEDs stay off", + "tour.welcome": "Welcome to LED Grab! This quick tour will show you around the interface. Use arrow keys or buttons to navigate.", + "tour.dashboard": "Dashboard — live overview of running targets, profiles, and device health at a glance.", + "tour.targets": "Targets — add WLED devices, configure LED targets with capture settings and calibration.", + "tour.sources": "Sources — manage capture templates, picture sources, audio sources, and color strips.", + "tour.profiles": "Profiles — group targets and automate switching with time, audio, or value conditions.", + "tour.settings": "Settings — backup and restore configuration, manage auto-backups.", + "tour.search": "Search — quickly find and navigate to any entity with Ctrl+K.", + "tour.theme": "Theme — switch between dark and light mode.", + "tour.language": "Language — choose your preferred interface language.", + "tour.restart": "Restart tutorial", "calibration.tutorial.start": "Start tutorial", "calibration.overlay_toggle": "Overlay", "calibration.start_position": "Starting Position:", diff --git a/server/src/wled_controller/static/locales/ru.json b/server/src/wled_controller/static/locales/ru.json index fc49e4e..d050133 100644 --- a/server/src/wled_controller/static/locales/ru.json +++ b/server/src/wled_controller/static/locales/ru.json @@ -214,6 +214,16 @@ "calibration.tip.border_width": "Сколько пикселей от края экрана использовать для цветов LED", "calibration.tip.skip_leds_start": "Пропуск LED в начале ленты — пропущенные LED остаются выключенными", "calibration.tip.skip_leds_end": "Пропуск LED в конце ленты — пропущенные LED остаются выключенными", + "tour.welcome": "Добро пожаловать в LED Grab! Этот краткий тур познакомит вас с интерфейсом. Используйте стрелки или кнопки для навигации.", + "tour.dashboard": "Дашборд — обзор запущенных целей, профилей и состояния устройств.", + "tour.targets": "Цели — добавляйте WLED-устройства, настраивайте LED-цели с захватом и калибровкой.", + "tour.sources": "Источники — управление шаблонами захвата, источниками изображений, звука и цветовых полос.", + "tour.profiles": "Профили — группируйте цели и автоматизируйте переключение по расписанию, звуку или значениям.", + "tour.settings": "Настройки — резервное копирование и восстановление конфигурации.", + "tour.search": "Поиск — быстрый поиск и переход к любому объекту по Ctrl+K.", + "tour.theme": "Тема — переключение между тёмной и светлой темой.", + "tour.language": "Язык — выберите предпочитаемый язык интерфейса.", + "tour.restart": "Запустить тур заново", "calibration.tutorial.start": "Начать обучение", "calibration.overlay_toggle": "Оверлей", "calibration.start_position": "Начальная Позиция:", diff --git a/server/src/wled_controller/static/locales/zh.json b/server/src/wled_controller/static/locales/zh.json index e146415..6f6ce4d 100644 --- a/server/src/wled_controller/static/locales/zh.json +++ b/server/src/wled_controller/static/locales/zh.json @@ -214,6 +214,16 @@ "calibration.tip.border_width": "从屏幕边缘采样多少像素来确定 LED 颜色", "calibration.tip.skip_leds_start": "跳过灯带起始端的 LED — 被跳过的 LED 保持关闭", "calibration.tip.skip_leds_end": "跳过灯带末尾端的 LED — 被跳过的 LED 保持关闭", + "tour.welcome": "欢迎使用 LED Grab!快速导览将带您了解界面。使用方向键或按钮进行导航。", + "tour.dashboard": "仪表盘 — 实时查看运行中的目标、配置文件和设备状态。", + "tour.targets": "目标 — 添加 WLED 设备,配置 LED 目标的捕获设置和校准。", + "tour.sources": "来源 — 管理捕获模板、图片来源、音频来源和色带。", + "tour.profiles": "配置文件 — 将目标分组,并通过时间、音频或数值条件自动切换。", + "tour.settings": "设置 — 备份和恢复配置,管理自动备份。", + "tour.search": "搜索 — 使用 Ctrl+K 快速查找并导航到任意实体。", + "tour.theme": "主题 — 在深色和浅色模式之间切换。", + "tour.language": "语言 — 选择您偏好的界面语言。", + "tour.restart": "重新开始导览", "calibration.tutorial.start": "开始教程", "calibration.overlay_toggle": "叠加层", "calibration.start_position": "起始位置:", diff --git a/server/src/wled_controller/templates/index.html b/server/src/wled_controller/templates/index.html index 622d26c..57436bf 100644 --- a/server/src/wled_controller/templates/index.html +++ b/server/src/wled_controller/templates/index.html @@ -28,6 +28,9 @@
API + diff --git a/server/src/wled_controller/templates/partials/tutorial-overlay.html b/server/src/wled_controller/templates/partials/tutorial-overlay.html index a7659fe..0189794 100644 --- a/server/src/wled_controller/templates/partials/tutorial-overlay.html +++ b/server/src/wled_controller/templates/partials/tutorial-overlay.html @@ -1,3 +1,20 @@ + + +