playlists + lyrics: setlists with pages of their own, and the words timed to the voice

This commit is contained in:
KeelrLeek committed 2026-08-17 18:05:31 -05:00
1 parent c4ff6269a3
commit df3d15553a
49 files changed
+14419 -599

No files matched your search

+35 -3
View File
@@ -28,6 +28,8 @@
} from "../lib/state.svelte.js";
import Icon from "./Icon.svelte";
import SaveMenu from "./SaveMenu.svelte";
import LyricsPane from "./LyricsPane.svelte";
import PlaylistMenu from "./PlaylistMenu.svelte";
import * as api from "../lib/api.js";
import { floatScroll } from "../lib/scrollbar.js";
import { splitDescription } from "../lib/editions.js";
@@ -1087,6 +1089,27 @@
{metaParts[1] || player.track?.title || "Nothing playing"}
</span>
</div>
{#if currentItem}
<PlaylistMenu
compact
align="right"
iconSize={15}
title="Add this track to a playlist"
tracks={() => [
{
title: currentItem.title,
artist: currentItem.artist ?? metaParts[0] ?? null,
album: currentItem.album ?? metaParts[1] ?? null,
duration_secs: currentItem.duration ?? null,
// A stream item's path names a file on the PEER's
// machine — the row goes in as a placeholder that
// streams on click, not as a fake local file.
path: currentItem.stream ? null : currentItem.path,
art_path: currentItem.stream ? null : (currentItem.art ?? null),
},
]}
/>
{/if}
<!-- Saving what you are streaming lived in the popover. It is the
only ACTION that did, so it comes up here rather than being
lost with it. -->
@@ -1272,9 +1295,7 @@
{/if}
{:else if pane === "lyrics"}
<p class="pane-empty">
Lyrics aren't wired up yet — this pane is a placeholder.
</p>
<LyricsPane />
{:else if pane === "artist"}
{@render artistChip()}
@@ -1825,6 +1846,17 @@
color: var(--text-secondary);
}
.np-icon:hover { background: var(--bg-highlight); color: var(--text-primary); }
/* The add-to-playlist trigger wears the header-icon look exactly. */
.np-head :global(.plm-trigger) {
width: 28px;
height: 28px;
border-radius: 6px;
color: var(--text-secondary);
}
.np-head :global(.plm-trigger:hover) {
background: var(--bg-highlight);
color: var(--text-primary);
}
.np-scroll {
/* Fills the absolutely-positioned .full-view rather than sizing to its