Each playlist card in the left rail is now a drag-drop target. Dragging a
track from the right rail (PointerPressed starts DragDrop.DoDragDropAsync
with a TrackListPayload) over a playlist card highlights it with the
accent color (MultiBinding + PlaylistDropHighlightConverter comparing
each Playlist's Id to the VM's HoveredPlaylist).
After a 300ms dwell (Zune's signature hover pause), the hover-swap popup
appears next to the hovered playlist listing the OTHER playlists; hovering
each one swaps the drop target via SwapHoverTargetCommand (the user's
'hover-swap-icon' affordance from the r/Zune quote). Releasing the drag
on the current hover target fires AddTracksToPlaylistCommand which
calls the existing IMediaLibraryService.AddTrackToPlaylistAsync per
track, sets a status message, and reloads the current tracklist.
Nine new VM-level tests cover: EnterPlaylistDropZone / Leave / Refresh,
ClearPlaylistHover, HoverSwapAlternatives filtering, SwapHoverTargetCommand,
AddTracksToPlaylistCommand payload + status message, and HoverSwapPlaylistName
mirroring.
Smart DJ now matches the Zune 4.8 fan-loved behavior: favorites surface
first in the mix regardless of similarity to the seed; broken hearts
are ALWAYS filtered even when the seed context (album/artist/genre match)
would otherwise pull them in.
Scoring weights tuned so a heart in any context outranks a non-heart:
AlbumMatchWeight = 12, ArtistMatchWeight = 10, GenreMatchWeight = 5,
HeartBonus = 25, RandomJitter = 3. The favorites-first OrderBy keeps the
ordering stable + testable; a secondary OrderBy by Title makes the output
deterministic.
The ExcludeDisliked flag on SmartDJSeed is preserved for backward
compatibility but is no longer the gate — broken hearts are filtered
unconditionally, which matches the xune-HD canon and the disassembly's
Smart DJ behavior.
Tier A1: Tap-the-cut-off-header-to-go-back. The Zune 4.8 iconic navigation
where the current page title bleeds off the left edge of the window and
clicking it pops back to the parent pivot. MainShellViewModel exposes
CroppedHeaderTitle (pivot name or wizard StepTitle), IsCroppedHeaderBack
(click → GoBack), and IsCroppedHeaderDetail (hides brand wordmark in
detail mode). PointerPressed sets e.Handled so the title-bar drag handler
doesn't fire.
Tier A2: PivotParallaxTransition (IPageTransition implementation) gives
each pivot change a 420ms slide + scale + fade with CubicEaseOut.
Quickplay variant tightens to 320ms / 0.85 scale for the 'left and rear'
recess feel. Wired into TransitioningContentControl.
Tier A3: Now Playing idle screensaver. After 3.5s of inactivity in
Now Playing, text drifts left (TranslateTransform.X driven by
IdleDriftConverter on NowPlayingIdleProgress 0..1) and the giant
artist watermark rotates slowly around the Y axis (Rotate3DTransform
on NowPlayingArtRotation, one revolution every 90s). Two new
converters (IdleOpacityConverter, IdleDriftConverter).
Tier A4: Drawer slide-in / fade animations. Bio drawer slides from
-400px (off-screen left), Showlist drawer slides from +400px (off-screen
right), SyncToast slides up from +80px. All driven by VM-side timer
interpolation (BioDrawerOffsetX/Opacity, ShowlistDrawerOffsetX/Opacity)
with two new converters (SyncToastOpacityConverter, SyncToastSlideConverter)
providing the initial RenderTransform target values. NowPlayingViewModel
exposes UpdateDrawerTargets() invoked from ToggleBioDrawer/ToggleShowlist
that starts a 60fps interpolation timer until both drawers reach target.
Add full paired token sets for surfaces, text, borders, and inputs
(ZuneBackground / ZuneSurfaceElevated / ZuneCard / ZuneCardHover /
ZuneBorder / ZuneSubtleBorder / ZuneInputBackground / five text levels).
A Settings → Display "THEME" picker lets the user toggle dark/light;
the selection is persisted as SelectedThemeName.
ApplyTheme rewrites the brush colors in Application.Resources so every
view bound via DynamicResource updates without per-view restyling.
Verified visually under Xvfb at 1012x693: dark mode reproduces the
authentic #11090F, light mode reproduces the authentic #F3EFF1 with
the magenta accent family unchanged across both.
Zune 4.8's FirstConnect flow: welcome → device name → media-type sync
toggles → privacy → done. Triggered once per physical device serial
the first time it connects, mirroring the existing first-launch /
what's-new overlay pattern.
Persistence: FirstConnectCompletedSerials list in AppSettings tracks
which serials have completed setup. The chosen sync-rule defaults are
pushed into the existing SettingsVM sync-rule fields, and the device
name into a new FirstConnectDeviceName field, all saved via the
existing JSON settings pipeline.
File types page (FILETYPES.UIX parity): ingest-extensions editor with
Zune's default preset set; real OS file associations deferred.
Privacy page: usage-data opt-in (no telemetry subsystem ships with this
flag — stored for parity) + auto-check-for-updates toggle.
Photos page: photo folder picker + slideshow shuffle/repeat defaults
+ delete-after-reverse-sync toggle.
General page: startup view (Quickplay/Collection), sound effects,
compact-mode-always-on-top, show-ratings toggles.
FirstConnect completed-serials list also persisted here so the upcoming
FirstConnect wizard can run once per physical device.
- SystemDecorations=None for authentic Zune 4.8 chromeless window, with
invisible 8-zone edge/corner resize hits + resize cursors and
double-click-to-maximize on the title bar
- Widen default window (1360x780) and compact-exit floor (1100x560)
- pivot-header 32 -> 28; new mini-pivot style for SETTINGS/mode toggles;
CD + settings mode/sub-pivot rows moved to subpivot + Classes.active
- settings sub-pivot flags composed with top-level pivot to stop two
content panels rendering at once
- header search hidden on quickplay/now playing/settings (ShowSearch parity)
- background art, sync toast, first-launch/whats-new overlays span the full shell grid
- Create ViewLocator implementing IDataTemplate for ViewModel-to-View resolution
- Register ViewLocator in App.axaml and add explicit DataTemplates to MainShellView
- Expose PlayPauseIcon (▶ / ⏸) on MainShellViewModel and NowPlayingViewModel to replace raw boolean display
- Add SelectAccentCommand to SettingsViewModel and bind accent palette tiles
- Add NavigationAndPlaybackUiTests suite covering ViewLocator, glyph toggles, and pivot navigation (12/12 tests passing)
- Implement borderless custom window chrome with client area decorations and minimal controls
- Add two-column integrated artist discography view with inline album cards and tracklists
- Add interactive album cover grid and dense song data table with contextual queue management
- Implement Quickplay Hub with 3-deck panorama (Pins, History, New) and Smart DJ presets
- Implement cinematic Now Playing experience with dynamic Ken-Burns canvas, mosaic wall, and auto-hiding HUD
- Seed 6 complete iconic albums (Rush, Daft Punk, Pink Floyd, Fleetwood Mac, Miles Davis, New Order)
- Verify zero design invariant violations across all AXAML views