feat(mini): queue-style meta block, action toolbar, vertical volume slider

Restructure the MiniPlayer to mirror the main window's queue panel layout:

UI changes:
- Meta block: cover + title/artist/album/year (year added to MiniTrackInfo)
- Action toolbar styled like .queue-round-btn (30px round, accent fill when
  active), in order: volume, shuffle | gapless, crossfade, infinite | queue
- Volume button opens a thin 5px vertical strip slider that drops down (click
  / drag / wheel to adjust). Right-click on the volume button mutes.
- Controls + progress moved to the bottom as a true footer (margin-top: auto),
  so they stay anchored even with the queue expanded
- Queue toggle moved out of the titlebar into the action bar (logically lives
  with the other queue/playback toggles)
- Window size bumped to 340x260 collapsed / 340x500 expanded for the new layout

Bridge changes (miniPlayerBridge.ts):
- MiniSyncPayload extended with volume, gaplessEnabled, crossfadeEnabled,
  infiniteQueueEnabled
- Bridge now subscribes to authStore in addition to playerStore so toolbar
  toggle states propagate cross-window
- New events: mini:set-volume, mini:shuffle, mini:set-gapless, mini:set-crossfade,
  mini:set-infinite-queue
- Bridge enforces gapless ↔ crossfade mutual exclusion (per CLAUDE.md gotcha)
  so the mini doesn't need to know about both states to act

Misc:
- Belt-and-suspenders user-select: none on .mini-player-shell * to kill
  Ctrl+A / mouse-drag selection that WebKit/WebView2 occasionally let through
This commit is contained in:
Psychotoxical
2026-04-20 18:51:31 +02:00
parent a7eb0eda72
commit 9f21edee80
4 changed files with 415 additions and 90 deletions
+3 -3
View File
@@ -2838,7 +2838,7 @@ fn default_mini_position(app: &tauri::AppHandle) -> Option<tauri::PhysicalPositi
let m_size = monitor.size();
let win_w = (340.0 * scale).round() as i32;
let win_h = (180.0 * scale).round() as i32;
let win_h = (260.0 * scale).round() as i32;
let margin_x = (24.0 * scale).round() as i32;
let margin_y = (56.0 * scale).round() as i32;
@@ -2886,8 +2886,8 @@ fn build_mini_player_window(
tauri::WebviewUrl::App("index.html".into()),
)
.title("Psysonic Mini")
.inner_size(340.0, 180.0)
.min_inner_size(320.0, 180.0)
.inner_size(340.0, 260.0)
.min_inner_size(320.0, 240.0)
.resizable(true)
.decorations(use_decorations)
.always_on_top(use_always_on_top)