library roots get cover art in the music grid

they are indexed like any other folder — all six carry cover:true and serve a
jpeg — so the root view uses the same card as the folder grid instead of flat
gradient tiles. a root that holds tracks directly gets the hover play button
for free.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-04 16:39:23 +00:00
co-authored by Claude Opus 5
parent 1712a8b4d5
commit 1be43df75b
@@ -205,11 +205,11 @@ export const MusicDetail = () => {
const crumbs = rel ? rel.split('/') : [];
const Card = ({ r, name, playable }: { r: string; name: string; playable: boolean }) => (
const Card = ({ r, name, playable, onOpen }: { r: string; name: string; playable: boolean; onOpen?: () => void }) => (
<div className="group relative">
<button
type="button"
onClick={() => enter(name)}
onClick={onOpen ?? (() => enter(name))}
className="flex w-full flex-col gap-2 rounded-lg bg-card/60 p-3 text-left transition-colors hover:bg-card"
>
<div className="aspect-square w-full overflow-hidden rounded-md bg-muted">
@@ -263,18 +263,18 @@ export const MusicDetail = () => {
{loading && <p className="text-sm text-muted-foreground">Loading</p>}
{/* Home */}
{/* Home — the library roots carry their own folder art (the manifest indexes them like any other
folder), so they get the same cards as everything else rather than a wall of flat tiles. */}
{!cwd && (
<div className="grid grid-cols-2 gap-3 sm:grid-cols-3 lg:grid-cols-5">
{libraries.map((lib) => (
<button
<Card
key={lib}
type="button"
onClick={() => setCwd(`${MUSIC_ROOT}/${lib}`)}
className="flex aspect-video items-end rounded-lg bg-gradient-to-br from-primary/30 to-primary/5 p-3 text-left text-lg font-semibold text-foreground transition-transform hover:scale-[1.02]"
>
{lib}
</button>
r={lib}
name={lib}
playable={(manifest[lib]?.tracks ?? 0) > 0}
onOpen={() => setCwd(`${MUSIC_ROOT}/${lib}`)}
/>
))}
</div>
)}