Filter audio devices by engine type and update tutorial steps

- Add enumerate_devices_by_engine() returning per-engine device lists
  without cross-engine dedup so frontend can filter correctly
- API /audio-devices now includes by_engine dict alongside flat list
- Frontend caches per-engine data, filters device dropdown by selected
  template's engine_type, refreshes on template change
- Reorder getting-started tutorial: add API docs and accent color steps
- Fix tutorial trigger button focus outline persisting on step 2
- Use accent color variable for tutorial pulse ring animation

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-27 21:43:37 +03:00
parent efb05eba77
commit 49c985e5c5
8 changed files with 97 additions and 18 deletions

View File

@@ -24,12 +24,14 @@ 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-profiles', textKey: 'tour.profiles', 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: 'a.header-link[href="/docs"]', textKey: 'tour.api', position: 'bottom' },
{ selector: '[onclick*="openCommandPalette"]', textKey: 'tour.search', position: 'bottom' },
{ selector: '[onclick*="toggleTheme"]', textKey: 'tour.theme', position: 'bottom' },
{ selector: '#cp-wrap-accent', textKey: 'tour.accent', position: 'bottom' },
{ selector: '[onclick*="openSettingsModal"]', textKey: 'tour.settings', position: 'bottom' },
{ selector: '#locale-select', textKey: 'tour.language', position: 'bottom' }
];
@@ -83,6 +85,8 @@ const deviceTutorialSteps = [
export function startTutorial(config) {
closeTutorial();
// Remove focus from the trigger button so its outline doesn't persist
if (document.activeElement) document.activeElement.blur();
const overlay = document.getElementById(config.overlayId);
if (!overlay) return;