140 lines
9.1 KiB
Markdown
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?
|