diff --git a/docs/superpowers/plans/2026-05-07-teamsiso-phase-c-wpf-ui.md b/docs/superpowers/plans/2026-05-07-teamsiso-phase-c-wpf-ui.md new file mode 100644 index 0000000..1dbff3c --- /dev/null +++ b/docs/superpowers/plans/2026-05-07-teamsiso-phase-c-wpf-ui.md @@ -0,0 +1,43 @@ +# TeamsISO Phase C — WPF MVVM UI Plan + +**Goal:** Operator-facing WPF UI bound to `IIsoController`. Displays the live participant list, lets operators enable/disable per-participant ISO outputs, set the global framerate / resolution / aspect / audio mode, view engine alerts, and see basic system health. Plus a WiX MSI installer and a release CI pipeline. + +**Architecture:** MVVM with no third-party MVVM framework — small managed `ObservableObject` and `RelayCommand` helpers. The view models bind directly to `IIsoController`'s observables. UI runs on the WPF dispatcher; observable subscriptions marshal back via a captured `SynchronizationContext`. App.xaml.cs constructs the engine on startup and disposes on exit. + +**Tech stack:** WPF on .NET 8, MVVM hand-rolled, no external UI library yet (MaterialDesignThemes can be added in a polish pass). + +## File structure additions + +``` +src/TeamsISO.App/ +├── App.xaml / App.xaml.cs (DI bootstrap) +├── MainWindow.xaml / MainWindow.xaml.cs +├── ViewModels/ +│ ├── ObservableObject.cs +│ ├── RelayCommand.cs +│ ├── MainViewModel.cs +│ ├── ParticipantViewModel.cs +│ ├── GlobalSettingsViewModel.cs +│ └── AlertBannerViewModel.cs +├── Converters/ +│ ├── BoolToVisibilityConverter.cs +│ └── EnumDescriptionConverter.cs +└── TeamsISO.App.csproj + +src/TeamsISO.Installer/ +└── TeamsISO.Installer.wixproj (MSI installer; v5) +``` + +## Tasks + +1. **MVVM helpers** — `ObservableObject` base implementing `INotifyPropertyChanged`; `RelayCommand` and `AsyncRelayCommand`. +2. **GlobalSettingsViewModel** — exposes Framerate, Resolution, Aspect, Audio as bindable selected values; `Apply` command calls `controller.SetGlobalSettingsAsync`. +3. **ParticipantViewModel** — wraps a `Participant`, exposes IsEnabled, CustomOutputName, and current status; `EnableCommand` and `DisableCommand` call the controller. +4. **AlertBannerViewModel** — collects `EngineAlert`s and exposes the most recent one with a "dismiss" command. +5. **MainViewModel** — top-level. Owns the controller. Exposes `ObservableCollection`, the settings VM, and the banner VM. +6. **MainWindow.xaml** — DataGrid for participants with toggle column, settings panel docked to the right, alert banner docked top. +7. **Converters** — bool→visibility, enum→display string. +8. **App.xaml.cs** — wires DI: build engine + controller + main view model, set MainWindow's DataContext, dispose on exit. +9. **WiX installer (Phase C-2)** — separate task; can ship after the UI is alive. + +Each step ships as its own commit. Tag `phase-c-complete` after MainWindow renders and the controller is bound.