2026.7.18
Pre-releaseTestFlight build 16 — 2026-07-18
What to Test:
What's new:
Home hero: smoother page-to-page animation, tidier spacing, and a lighter left-edge scrim. Play/Resume buttons now name the episode they'll play (e.g. "Play S21, E8", or a resume bar showing "S5, E12 - 43m"). Logos fade in instead of popping.
Playback: Dolby Vision / direct-file HDR now carries correctly across back-to-back episodes, with display sync fixed. Fixed seeking-during-load snapping back to the start (notably DV over SMB). Cleaner startup - the spinner holds until the picture is really on screen, loading messages are paced better, and network files start faster. Fixed an end-of-file glitch when seeking near the end of a network file.
Player controls: the control bar now auto-hides when idle (stays up while a menu is open).
Settings: new Home Performance Overlay toggle under Help & Diagnostics. Added NFO / local sidecar metadata support.
Please test: episode playback and HDR across consecutive episodes, seeking over network shares and on Dolby Vision, control-bar auto-hide, and the Home hero.
Changes (91):
- Settings: wire up the Home Performance Overlay toggle
- Hero/detail Play buttons: name the episode that will play
- Hero scrim: extend fade 40pt past center (960 -> 1000)
- UIKit hero: narrow content column 80pt (576 -> 496)
- Hero scrim: soften to 0.55 and extend fade to screen center
- Hero scrim: horizontal left->right wash, clear ~40pt shy of center
- UIKit hero: shift column up another 20pt (net drop 60 -> 40)
- UIKit hero: shift column up 20pt for air above Continue Watching
- UIKit hero: widen buttons-to-pagination gap 20pt -> 40pt
- UIKit hero: lower content column 80pt; +20pt buttons-to-pagination gap
- Hero pills: flat-capsule border 2px @ 0.10 opacity
- Hero pills: raise flat-capsule border opacity 0.08 -> 0.13
- Hero wipe: speed the whole transition up a little (1.20s -> 1.05s)
- Hero wipe: speed the leaving-image trail back up (was too slow)
- Hero wipe: decouple curves — fast wipe, leaving image trails a little
- Hero wipe: soften shared curve expo-out -> ease-in-out (less rushed)
- Hero wipe: increase leaving-image drift to ~1200pt (0.625 of width)
- Hero wipe: drift the leaving image half the screen (as a width fraction)
- Hero wipe: sync the leaving-image drift to the wipe curve; +0.25s overall
- Hero backdrop wipe: slow ~0.1s and make the leaving image drift immediately
- Hero A/B toggle: move flip to a Settings debug row (Play/Pause conflicted)
- Home hero: DEBUG live UIKit<->SwiftUI foreground A/B toggle
- UIKit hero: cross-dissolve late-resolved logos instead of snapping
- MediaShareRuntimeFacet: internal quality fixes + monotonic-revision test
- IdentityIndexModel: cover the warm-lifecycle concurrency guards (tests only)
- ProfileFlowModel: re-apply Plex identity when the active profile is removed
- PlexHomeUsersModel: guard stale background Plex-token refresh (+ log fetch error)
- MainTabView: collapse the wide init via facet + SyncServices bundle (Stage 2)
- MainTabView: split the 2,429-line file into per-type files (Stage 1)
- arch-guard: multi-category observable classifier (truthful fan-out)
- Extract ProfileFlowModel facet from AppState (Batch 6)
- AccountsProvidersModel: filter per-profile active ids, log resolution errors, unit-test active-set matrix
- Extract MediaShareRuntimeFacet from AppState (Batch 5)
- Extract PlexHomeUsersModel facet from AppState (Batch 4)
- Dedupe ProfileSettingsModel construction and make all 18 sub-models injectable
- Extract AccountsProvidersModel hub from AppState (Batch 3)
- Extract IdentityIndexModel facet from AppState (Batch 2)
- Extract ProfileSettingsModel facet from AppState + add observable fan-out guard
- FeaturePlayback: split PlayerView body to cut type-check time
- MetadataKit: speed up TVDBClient.tokens type-checking
- Pin AetherEngine to plozz-pin-5.6.1-seekfixes-atmos (ffaac10)
- Refine loading-message pacing and animation
- Start windowed prefetch after neighbor resolution
- Publish Plozzigen range after load readiness
- perf(transport): read-ahead window in TransportIOReader to cut cold-start latency
- Preserve direct-file HDR across episode handoff
- fix(playback): hold bring-up spinner until the picture is genuinely on screen
- Fence stale playback before engine commit
- Fix direct-file HDR display synchronization
- Extract ControlsAutoHidePolicy to pin the auto-hide semantics under test
- Fix DV/SMB seek-during-load snapping playback back to start
- ProviderShare: collapse coordinator per-account maps into ShareCatalogRuntime (Batch 18)
- Auto-hide 1s after load, but never sooner than 4s after the last input
- refactor: extract share catalog read queries from the store
- Auto-hide the control bar when idle (keep pinned only while a menu is open)
- Auto-hide: gate the idle countdown on real playback, not a status blip
- refactor: extract share enrichment persistence repository
- refactor: extract local sidecar metadata repository
- Fix auto-hide ordering: 4s idle window starts after playback presents
- refactor: extract scan catalog writer from share store
- Keep transport open while video is still loading
- Clamp committed seeks below EOF to stop network-file end-fault
- refactor: lift catalog DTOs out of ShareCatalogStore namespace
- refactor: narrow share provider runtime capabilities
- refactor: make media share runtime ownership atomic
- refactor: inject share metadata pipeline construction
- fix: scope detail snapshots to effective content identity
- perf: coalesce detail-cache pruning and modernize artwork cache
- perf: move metadata cache I/O off actor execution
- fix: enforce NFO semantics and private catalog ordering
- fix: prune orphan share metadata transactionally
- Extract ForegroundReloadCoordinator from PlayerViewModel
- Extract PlayerMenuRowStack + Audio/Speed/Sync panes
- Extract SubtitleDownloadScreen and SubtitleSyncScreen
- Extract SubtitleStylePanel from PlayerControls
- Extract InfoPanelView from PlayerControls
- Split PlayerControls support types into PlayerControlsSupport.swift
- refactor: split share catalog persistence responsibilities
- refactor(FeaturePlayback): extract UpNextPresentationDecision + PlaybackClockReconciler
- refactor(FeaturePlayback): extract ScrubGestureInterpreter from PlayerInputViewController
- refactor(FeaturePlayback): extract EngineHandoffCoordinator from PlayerViewModel
- fix: close arbiter retirement admission races and reason leak
- fix: record current scan completion and retire arbiters
- fix: never reconnect on cancellation and classify mapped cancelled reads
- fix: fence metadata scheduling generations and cancellation
- fix: remove force-close minimum floor; honor the literal absolute deadline
- fix: absolute transition deadline and cancel-independent force-close
- fix: bound media I/O transitions and prioritize playback
- test: characterize metadata foundation remediation
- Decompose local metadata policies
- Add NFO metadata enrichment