player use icons

This commit is contained in:
2026-02-06 03:44:14 -08:00
parent 455699415f
commit c0d4f47d9c
2 changed files with 115 additions and 38 deletions

View File

@@ -35,6 +35,21 @@
} from "$lib/player/player.svelte";
import { createMediaSessionBindings } from "$lib/player/media-session";
import {
ChevronsUpDown,
ListX,
Pause as PauseIcon,
PanelRightClose,
PanelRightOpen,
Play as PlayIcon,
Repeat,
Shuffle,
SkipBack,
SkipForward,
Volume2,
X,
} from "@lucide/svelte";
let audioEl: HTMLAudioElement | null = null;
// Best-effort preload of the upcoming track's URL
@@ -439,12 +454,17 @@
>
<div class="mx-auto flex max-w-4xl items-center gap-2 px-3 py-2">
<button
class="rounded border px-2 py-1 text-sm"
class="inline-flex h-8 w-8 items-center justify-center rounded border"
type="button"
onclick={() => toggleUiOpen()}
aria-label={snap.uiOpen ? "Close player" : "Open player"}
title={snap.uiOpen ? "Close player" : "Open player"}
>
{snap.uiOpen ? "Close" : "Player"}
{#if snap.uiOpen}
<X class="h-4 w-4" />
{:else}
<ChevronsUpDown class="h-4 w-4" />
{/if}
</button>
<div
@@ -502,20 +522,24 @@
</div>
<button
class="rounded border px-2 py-1 text-sm"
class="inline-flex h-8 w-8 items-center justify-center rounded border"
type="button"
disabled={!canPrev}
aria-label="Previous"
title="Previous"
onclick={() => {
prev(currentTime);
void syncAndAutoplay();
}}
>
Prev
<SkipBack class="h-4 w-4" />
</button>
<button
class="rounded border px-2 py-1 text-sm"
class="inline-flex h-8 w-8 items-center justify-center rounded border"
type="button"
aria-label={isPlaying ? "Pause" : "Play"}
title={isPlaying ? "Pause" : "Play"}
onclick={() => {
if (!audioEl) return;
if (audioEl.paused) void audioEl.play();
@@ -523,19 +547,25 @@
}}
disabled={!snap.currentTrack}
>
{isPlaying ? "Pause" : "Play"}
{#if isPlaying}
<PauseIcon class="h-4 w-4" />
{:else}
<PlayIcon class="h-4 w-4" />
{/if}
</button>
<button
class="rounded border px-2 py-1 text-sm"
class="inline-flex h-8 w-8 items-center justify-center rounded border"
type="button"
disabled={!canNext}
aria-label="Next"
title="Next"
onclick={() => {
next();
void syncAndAutoplay();
}}
>
Next
<SkipForward class="h-4 w-4" />
</button>
</div>
@@ -544,22 +574,29 @@
<div class="mx-auto max-w-4xl space-y-3">
<div class="flex flex-wrap items-center gap-2">
<button
class="rounded border px-2 py-1 text-sm"
class="inline-flex h-8 w-8 items-center justify-center rounded border"
type="button"
onclick={() => toggleShuffle()}
aria-label={snap.shuffleEnabled ? "Shuffle on" : "Shuffle off"}
title={snap.shuffleEnabled ? "Shuffle on" : "Shuffle off"}
>
Shuffle: {snap.shuffleEnabled ? "On" : "Off"}
<Shuffle class="h-4 w-4" />
</button>
<button
class="rounded border px-2 py-1 text-sm"
class="inline-flex h-8 w-8 items-center justify-center rounded border"
type="button"
onclick={() => toggleWrap()}
aria-label={snap.wrapEnabled ? "Wrap on" : "Wrap off"}
title={snap.wrapEnabled ? "Wrap on" : "Wrap off"}
>
Wrap: {snap.wrapEnabled ? "On" : "Off"}
<Repeat class="h-4 w-4" />
</button>
<label class="ml-auto flex items-center gap-2 text-sm">
<span class="text-muted-foreground">Vol</span>
<span class="text-muted-foreground" aria-hidden="true">
<Volume2 class="h-4 w-4" />
</span>
<span class="sr-only">Volume</span>
<input
type="range"
min="0"
@@ -623,11 +660,13 @@
</button>
<button
class="rounded border px-2 py-1 text-xs"
class="inline-flex h-8 w-8 items-center justify-center rounded border"
type="button"
onclick={() => removeTrack(item.track.id)}
aria-label="Remove from queue"
title="Remove from queue"
>
Remove
<ListX class="h-4 w-4" />
</button>
</li>
{/each}
@@ -679,12 +718,17 @@
</div>
<button
class="rounded border px-2 py-1 text-sm"
class="inline-flex h-8 w-8 items-center justify-center rounded border"
type="button"
onclick={() => toggleUiOpen()}
aria-label={snap.uiOpen ? "Hide player sidebar" : "Show player sidebar"}
title={snap.uiOpen ? "Hide player sidebar" : "Show player sidebar"}
>
{snap.uiOpen ? "Hide" : "Show"}
{#if snap.uiOpen}
<PanelRightClose class="h-4 w-4" />
{:else}
<PanelRightOpen class="h-4 w-4" />
{/if}
</button>
</div>
@@ -697,38 +741,46 @@
</div>
<div class="flex items-center gap-2">
<button
class="rounded border px-2 py-1 text-sm"
class="inline-flex h-8 w-8 items-center justify-center rounded border"
type="button"
onclick={() => toggleShuffle()}
aria-label={snap.shuffleEnabled ? "Shuffle on" : "Shuffle off"}
title={snap.shuffleEnabled ? "Shuffle on" : "Shuffle off"}
>
Shuffle: {snap.shuffleEnabled ? "On" : "Off"}
<Shuffle class="h-4 w-4" />
</button>
<button
class="rounded border px-2 py-1 text-sm"
class="inline-flex h-8 w-8 items-center justify-center rounded border"
type="button"
onclick={() => toggleWrap()}
aria-label={snap.wrapEnabled ? "Wrap on" : "Wrap off"}
title={snap.wrapEnabled ? "Wrap on" : "Wrap off"}
>
Wrap: {snap.wrapEnabled ? "On" : "Off"}
<Repeat class="h-4 w-4" />
</button>
</div>
</div>
<div class="flex items-center gap-2">
<button
class="rounded border px-2 py-1 text-sm"
class="inline-flex h-8 w-8 items-center justify-center rounded border"
type="button"
disabled={!canPrev}
aria-label="Previous"
title="Previous"
onclick={() => {
prev(currentTime);
void syncAndAutoplay();
}}
>
Prev
<SkipBack class="h-4 w-4" />
</button>
<button
class="rounded border px-2 py-1 text-sm"
class="inline-flex h-8 w-8 items-center justify-center rounded border"
type="button"
aria-label={isPlaying ? "Pause" : "Play"}
title={isPlaying ? "Pause" : "Play"}
onclick={() => {
if (!audioEl) return;
if (audioEl.paused) void audioEl.play();
@@ -736,23 +788,32 @@
}}
disabled={!snap.currentTrack}
>
{isPlaying ? "Pause" : "Play"}
{#if isPlaying}
<PauseIcon class="h-4 w-4" />
{:else}
<PlayIcon class="h-4 w-4" />
{/if}
</button>
<button
class="rounded border px-2 py-1 text-sm"
class="inline-flex h-8 w-8 items-center justify-center rounded border"
type="button"
disabled={!canNext}
aria-label="Next"
title="Next"
onclick={() => {
next();
void syncAndAutoplay();
}}
>
Next
<SkipForward class="h-4 w-4" />
</button>
<label class="ml-auto flex items-center gap-2 text-sm">
<span class="text-muted-foreground">Vol</span>
<span class="text-muted-foreground" aria-hidden="true">
<Volume2 class="h-4 w-4" />
</span>
<span class="sr-only">Volume</span>
<input
type="range"
min="0"
@@ -819,11 +880,13 @@
</button>
<button
class="rounded border px-2 py-1 text-xs"
class="inline-flex h-8 w-8 items-center justify-center rounded border"
type="button"
onclick={() => removeTrack(item.track.id)}
aria-label="Remove from queue"
title="Remove from queue"
>
Remove
<ListX class="h-4 w-4" />
</button>
</li>
{/each}