Extract MainWindowViewModel from MainWindow#34
Merged
Conversation
This was referenced Jun 18, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Splits the 996-line
MainWindowgod-object into a dedicatedMainWindowViewModelplus a thin view shell, then adds unit tests for the extracted logic.Before
MainWindow.xaml.cs(996 lines) was simultaneously theWindow, the view-model ([INotifyPropertyChanged]+DataContext = this), the playback orchestrator, the update checker, the FFmpeg prompt host, the clip loader, the keyboard handler, and the shell-action host. None of that logic was unit-testable, because you can't instantiate a WPFWindowin a test.After
MainWindowViewModel.cs(new) — all observable state, computed properties, commands, clip loading, playback orchestration, update checks, FFmpeg prompts, the error-overlay state machine, and keyboard handling.MainWindow.xaml.cs(996 → 227 lines) — only genuine view concerns: window lifecycle/shutdown, the Flyleaf host-layout engine (reparents named controls), seek-slider input plumbing, search-box focus, and hyperlink navigation.MainWindow.xaml— only the design-timed:DataContexttype changed.Seams used to keep them decoupled
Func<VideoPlayerController>factory closing over the namedFlyleafHostcontrols, so the VM owns the controller without referencing any control.SearchBoxFocusRequested; the view handles focus.SelectedCameraViewchanges to drive host layout.Tests
Adds
MainWindowViewModelTests(27 new cases) covering logic that previously had zero coverage: camera-view selection, about toggle, the overlay/visibility state machine, play/stop enablement, loading/render text, the update badge, the search-focus keyboard shortcut, and error dismissal.Full suite: 81 passing (was 54).
Behavior
No intended runtime change. Verified locally: builds clean, all tests pass, and a startup smoke-run produces the identical initialization sequence (init → FFmpeg check → prompt). Manually confirmed working by the maintainer.
Notes / follow-ups
FilteredClipsfiltering, seek math, and the clip→auto-play path need a small DI seam or a pumped dispatcher to test cleanly — deferred.