Receive real-time events from games (CS2, Dota 2, LoL, etc.) and drive LED effects through the existing color strip and value source pipelines. Core: - GameEventBus (thread-safe pub/sub) with standardized 23-type event vocabulary - GameAdapter ABC + AdapterRegistry + MappingAdapter (YAML-driven) - Built-in adapters: CS2 GSI, Dota 2 GSI, LoL Live Client, Generic Webhook - Community YAML adapters: Minecraft, Valorant, Rocket League - GameEventColorStripStream with 5 effects (flash/pulse/sweep/color_shift/breathing) - GameEventValueSource with EMA smoothing and timeout - 4 built-in effect presets (FPS Combat, MOBA Health, Racing, Generic Alert) - Auto-setup for Valve GSI games (Steam path detection, cfg file writing) - Demo capture engine exposed to non-demo mode Frontend: - Game tab in Streams tree navigation with integration cards - Game integration editor modal with adapter picker, config fields, event mappings - game_event source type in CSS and ValueSource editors - Setup instructions overlay (markdown rendered) - Live event monitor and connection test API: - Full CRUD for game integrations - Event ingestion endpoint (adapter-level auth) - Adapter metadata, presets, auto-setup, status/diagnostics endpoints
7.9 KiB
Phase 6: Frontend — Game Integration Management UI
Status: ✅ Complete Parent plan: PLAN.md Domain: frontend
Objective
Build the UI for creating, configuring, and monitoring game integrations. Users pick a game from a visual grid, configure adapter settings with guided instructions, set up event-to-effect mappings visually, and monitor live events.
Tasks
- Task 1: Add "Game" tab/group to Streams tree navigation in streams.ts
- New tree group with game controller icon
- Children: game integrations list, game adapters info
- Task 2: Create game integration cards in the Streams tab
- CardSection instance for game integrations
- Card shows: game name/icon, adapter type badge, status indicator (connected/waiting/error), last event timestamp, event count
- Status indicator: green dot = events received recently, yellow = waiting, red = error/timeout
- Task 3: Create game integration editor modal (
templates/modals/game-integration-editor.html)- Step 1: Game picker — searchable grid of available adapters with game icons (IconSelect pattern)
- Step 2: Adapter config — auto-generated fields from adapter's config_schema (text inputs for auth tokens, number inputs for intervals)
- Step 3: Setup instructions — per-game markdown instructions (e.g. CS2 cfg file content)
- Step 4: Event mapping editor — visual grid of standard event categories
- Each mapping row: event type (dropdown), effect type (IconSelect: flash/pulse/sweep/color_shift/breathing), color picker, duration slider, intensity slider, priority
- Effect preset selector at top of mapping editor (dropdown: "FPS Combat", "MOBA Health", etc.)
- Name, description, tags fields
- Task 4: Create TypeScript module
static/js/features/game-integration.ts- CRUD functions using fetchWithAuth
- Cache for game integrations data
- Cache for game adapters metadata
- Card rendering functions
- Modal open/save/delete handlers
- Event mapping editor logic (add/remove/reorder mappings)
- Task 5: Game adapter icons — add SVG icons for supported games in
core/icons.ts- Generic gamepad icon for unknown games
- Stylized icons for CS2, LoL, Dota 2, Minecraft, Valorant, Rocket League
- Task 6: Live event monitor panel
- Expandable panel on the game integration card (or modal tab)
- Shows real-time feed of incoming events: timestamp, event_type, value, color-coded by category
- Fetches from GET /api/v1/game-integrations/{id}/events (polling every 2s or WebSocket later)
- Useful for debugging: "is my game sending data?"
- Task 7: Connection test button
- Button in modal that opens a test panel showing "Waiting for events..."
- When first event arrives, shows success with event details
- Helps users verify their game config is correct
- Task 8: Add i18n keys for all new strings (en.json, ru.json, zh.json)
- Game integration section titles, modal labels, status messages, event category names, effect type names, error messages
- Task 9: CSS styles for game integration cards and modal (
static/css/game-integration.css)- Game picker grid layout
- Event mapping editor rows
- Status indicators (colored dots)
- Live event monitor feed
- Task 10: Wire into app.ts — import module, add to window exports for onclick handlers
- Task 11: Wire into streams.ts — add cache, load function, CardSection, tree nav integration
Files to Modify/Create
server/src/wled_controller/static/js/features/game-integration.ts— main moduleserver/src/wled_controller/static/js/features/streams.ts— add game tab, cache, card sectionserver/src/wled_controller/static/js/app.ts— import and window exportsserver/src/wled_controller/static/js/core/icons.ts— game iconsserver/src/wled_controller/static/js/types.ts— TypeScript types for game integrationserver/src/wled_controller/static/css/game-integration.css— stylesserver/src/wled_controller/templates/modals/game-integration-editor.html— modal templateserver/src/wled_controller/templates/index.html— include modal templateserver/src/wled_controller/static/locales/en.json— i18n keysserver/src/wled_controller/static/locales/ru.json— i18n keysserver/src/wled_controller/static/locales/zh.json— i18n keys
Acceptance Criteria
- Game integration tab appears in Streams tree navigation
- Cards display with correct status indicators and game icons
- Modal wizard guides user through game selection → config → mapping
- Adapter-specific config fields are auto-generated from schema
- Setup instructions display per game
- Event mapping editor allows visual configuration with effect previews
- Effect presets populate mapping editor with sensible defaults
- Live event monitor shows incoming events
- Connection test provides clear feedback
- All i18n keys present in all 3 languages
- UI follows existing project conventions (no emoji, SVG icons, IconSelect/EntitySelect)
Notes
- Follow existing modal patterns: Modal base class, snapshotValues() for dirty check
- Follow CardSection pattern for entity list with reconciliation
- Use fetchWithAuth for ALL API calls
- Icons must be SVG paths in icons.ts — NEVER emoji
- Use IconSelect for game picker and effect type selector
- Use EntitySelect for game_integration_id references
- The event mapping editor is the most complex UI piece — consider a sub-component approach
Review Checklist
- All tasks completed
- Code follows frontend conventions
- No unintended side effects
- TypeScript compiles without errors (only pre-existing SystemMetricsValueSource error remains)
- Bundle builds successfully
Handoff to Next Phase
All 11 tasks implemented. Key implementation details:
Files created:
server/src/wled_controller/static/js/features/game-integration.ts— main module (CRUD, cards, modal handlers, event monitor, connection test)server/src/wled_controller/static/css/game-integration.css— styles for mapping editor, event feed, status indicators, connection test panelserver/src/wled_controller/templates/modals/game-integration-editor.html— modal with adapter picker, config fields, mapping editor, live events, connection test
Files modified:
icon-paths.ts— added gamepad2, crosshair, swords, shield, pickaxe, rocketIcon, circleDoticons.ts— added ICON_GAMEPAD, ICON_CROSSHAIR, ICON_SWORDS, ICON_SHIELD, ICON_PICKAXE, ICON_ROCKET_ICON, ICON_CIRCLE_DOT, getGameAdapterIcon()types.ts— added GameIntegration, GameAdapterInfo, GameEventMapping, GameEventRecord, GameIntegrationStatusstate.ts— added gameIntegrationsCache, gameAdaptersCache, _cachedGameIntegrations, _cachedGameAdaptersstreams.ts— added game tab to tree nav (under Integrations group), CardSection, cache fetching, reconciliationapp.ts— imported and wired all game integration functions to windowglobal.d.ts— added window type declarations for game integration functionsindex.html— included game-integration-editor.html modalall.css— imported game-integration.cssen.json,ru.json,zh.json— added ~50 i18n keys each
API endpoints consumed: GET/POST/PUT/DELETE /game-integrations, GET /game-adapters, GET /game-integrations/{id}/events, GET /game-integrations/{id}/status
Conventions followed: No emoji (SVG icons only), fetchWithAuth for all API calls, IconSelect for adapter picker, Modal subclass with snapshotValues() dirty check, TagInput for tags, CardSection with reconciliation, cache.invalidate() before reload, all strings via t() with i18n keys in 3 locales.
Note: The mapping editor uses plain <select> for event_type (since the available events are dynamic per adapter and may be unknown user-defined strings). Effect type selector has a select element that could be upgraded to IconSelect in a follow-up if desired. The preset selector is intentionally a plain select since it is a simple action trigger, not a form value.