Files
muzick/docs/ui-rework.md
T

140 lines
9.1 KiB
Markdown

# UI Rework Plan
> Status: **planned, not started.** This document captures the target direction for a
> richer player UI (reference: the "LocalTunes" three-pane mockup) and what it implies for
> both the frontend and the backend. It is a plan to execute later, not a description of the
> current app.
## 1. Vision
Move from the current functional-but-plain single-content-column layout to a polished,
artwork-forward **three-pane music player** in the spirit of modern desktop players
(Spotify / Apple Music / the LocalTunes reference):
- **Left:** persistent navigation rail (library sections + a personal/"your music" group).
- **Center:** scrollable content (Home, Library, Vibe, etc.) — artwork-rich cards, horizontal
carousels, hover-to-play.
- **Right:** persistent **Now Playing** panel — large artwork, track info, transport, and an
**Up Next / queue** list.
- **Bottom:** full-width global **playback bar** (shuffle / prev / play / next / repeat,
scrubber, volume, queue toggle) that's always visible regardless of route.
- **Top:** global search field + (future) user/account menu.
Accent-driven, rounded, soft-gradient cards; dark by default but fully themeable via tokens.
## 2. Layout structure
```
┌────────────────────────────────────────────────────────────────────────────┐
│ Top bar: [logo] [ global search ⌘K ] [bell] [avatar ▾] │
├───────────────┬────────────────────────────────────────────┬───────────────┤
│ Nav rail │ Content (router Outlet) │ Now Playing │
│ - Home │ Good evening 👋 │ [ artwork ] │
│ - Songs │ Quick Access cards │ Title/Artist │
│ - Albums │ Recently Played (carousel, View all) │ scrubber │
│ - Artists │ Made for you (mixes carousel) │ transport │
│ - Genres │ ... │ Up Next list │
│ - Playlists │ │ │
│ - Folder │ │ (collapsible)│
│ ────────── │ │ │
│ Now Playing │ │ │
│ Recently … │ │ │
│ Most Played │ │ │
│ Favorites │ │ │
│ ────────── │ │ │
│ Settings │ │ │
│ Theme │ │ │
│ About │ │ │
├───────────────┴────────────────────────────────────────────┴───────────────┤
│ Bottom bar: [art] Title/Artist ♥ ⇄ ◀ ▶▶ ⏯ ▶▶ ↻ 🔊────── queue ▤ │
└──────────────────────────────────────────────────────────────────────────────┘
```
The right Now-Playing panel and the bottom bar are partly redundant by design (desktop
players do this): the bottom bar is the always-on minimal transport; the right panel is the
expanded view with queue and large art, and is collapsible.
## 3. Design tokens / theming
This rework is the right moment to finish theming. Today only the shell consumes tokens
(`--bg`, `--surface`, `--text`, `--accent` from `src/lib/theme.ts`). Target:
- **Expand the token set:** `--bg`, `--bg-elevated`, `--surface`, `--surface-hover`,
`--border`, `--text`, `--text-muted`, `--accent`, `--accent-hover`, `--on-accent`,
plus gradient stops for cards (`--card-grad-a/b`).
- **Drive Tailwind from the tokens:** extend `tailwind.config.js` `theme.colors` to reference
the CSS variables (e.g. `bg: 'var(--bg)'`, `surface: 'var(--surface)'`, `accent:
'var(--accent)'`) so components use semantic classes (`bg-surface`, `text-muted`,
`bg-accent`) instead of hard-coded `bg-zinc-900` etc. This makes every component themeable
without per-component edits.
- Keep the existing presets (Dark / Midnight / Forest / Plum), add a light option, and keep
`initTheme()` applying the persisted choice before first paint.
- The reference's purple accent → add a "Default (Purple)" preset.
## 4. Component inventory (new / reworked)
| Component | Purpose |
| :--- | :--- |
| `AppShell` | 3-pane grid (rail / content / now-playing) + top bar + bottom bar. Replaces `Layout`. |
| `NavRail` | Sections + personal group + settings group; active state via `--accent`. |
| `TopBar` | Global search (debounced, ⌘K focus), account menu (stub until auth). |
| `NowPlayingPanel` | Right rail: large art, info, scrubber, transport, Up Next queue (reorder/remove). Collapsible. |
| `PlaybackBar` | Bottom global transport (always visible). Reworks `NowPlayingBar`. |
| `MediaCard` | Square artwork card with hover play overlay (used by carousels + grids). |
| `Carousel` / `ShelfRow` | Horizontal scroll row with title + "View all". |
| `QuickAccessCard` | Wide gradient card (Favorites / Recently Added / Most Played / Folder). |
| `TrackRow` | Reusable list row (replaces the per-page `LibraryTrackRow`) with art, actions, now-playing highlight. |
| `Artwork` | Resolves album/track artwork URL with a graceful gradient placeholder fallback. |
State: keep Zustand `usePlaybackStore` (current/queue/isPlaying/position/volume) and
`useVibeStore`; add a small `useUiStore` for panel collapse + theme if useful. The Up Next
list is just the playback `queue`.
## 5. Backend work this UI implies (gaps)
The mockup assumes data we don't serve yet. Each is a discrete backend task:
1. **Artwork serving**`albums.artwork_id` / Cover-Art URLs are stored but never served.
Need `GET /api/albums/:id/artwork` (and/or per-track) that streams/redirects to the cached
cover, plus a placeholder when absent. Without this every card is a gradient placeholder.
2. **Playlists** — the rail shows "Playlists"; there are no playlist tables/endpoints. Needs
`playlists` + `playlist_track` schema and CRUD + reorder endpoints. (Net-new feature.)
3. **"Most Played"** — derivable now via `GET /api/tracks?sort_by=play_count&order=DESC`.
Wire a dedicated view/shelf.
4. **"Recently Added"** — needs reliable `mtime`/`created_at` sorting (currently sorted
client-side). Consider a `created_at` column + a sorted endpoint.
5. **"Made for you" mixes** — map to the Vibe engine: per-genre/seed mixes via
`/api/vibe/from-genre` and saved seeds. No new engine work, just presentation + maybe a
"mixes" endpoint that returns a handful of seed suggestions.
6. **Folder browse** — the rail shows "Folder"; there's no filesystem-browse endpoint. Needs
a sandboxed `GET /api/library/browse?path=` under `MUSIC_DIR` (reuse the stream route's
traversal guard). Optional / later.
7. **Typesense search** — the redesigned top-bar search wants fast fuzzy results; finish the
Typesense indexing pipeline (collection + reindex job + index-on-enrich) so search graduates
from the Postgres ILIKE fallback. (Already tracked in `progress.md`.)
## 6. Suggested phasing
1. **Tokenise theming** — extend tokens + wire Tailwind to CSS vars; migrate existing
components to semantic colour classes. (Unblocks real theming; low risk, high leverage.)
2. **AppShell + PlaybackBar + NowPlayingPanel** — the structural 3-pane shell with the
always-on transport and queue, reusing the current playback store/audio engine.
3. **MediaCard / Carousel / Artwork** + **artwork backend endpoint** — make the content
artwork-forward; redesign Home around Quick Access + shelves.
4. **Library/Discover/Vibe pages** restyled onto the new components.
5. **New features as desired:** Playlists, Folder browse, Most Played/Recently Added shelves,
Typesense search.
## 7. Non-goals (for the first rework pass)
- Auth / multi-user (still single-user).
- Mobile/responsive layout (target desktop first; the 3-pane collapses later).
- Real-time collaborative features.
## 8. Open questions
- Keep both the right Now-Playing panel **and** the bottom bar, or collapse to one? (Plan
assumes both, panel collapsible.)
- Artwork storage: serve via a backend proxy/cache, or store files locally and serve static?
- Playlists: is this in scope for the rework, or a separate feature track?