WIP: global player pt. 3 monstrosity

This commit is contained in:
2026-02-09 23:55:19 -08:00
parent f9fe6a2d11
commit a4cf9356a8
2 changed files with 117 additions and 108 deletions

View File

@@ -17,119 +17,117 @@
} }
</script> </script>
{#if player.currentTrack} <div
<div class="fixed bottom-0 left-0 right-0 z-50 border-t bg-background/95 backdrop-blur shadow-2xl safe-area-pb"
class="fixed bottom-0 left-0 right-0 z-50 border-t bg-background/95 backdrop-blur shadow-2xl safe-area-pb" >
> <div class="px-4 py-2 flex items-center justify-between gap-4 h-16">
<div class="px-4 py-2 flex items-center justify-between gap-4 h-16"> <!-- Mini Player Info -->
<!-- Mini Player Info --> <button
<button type="button"
type="button" class="flex items-center gap-3 overflow-hidden flex-1 text-left bg-transparent border-none p-0 cursor-pointer"
class="flex items-center gap-3 overflow-hidden flex-1 text-left bg-transparent border-none p-0 cursor-pointer" onclick={() => (open = true)}
onclick={() => (open = true)} >
> <!-- Placeholder Art -->
<!-- Placeholder Art -->
<div
class="h-10 w-10 rounded bg-muted flex items-center justify-center shrink-0"
>
<Disc class="h-6 w-6 text-muted-foreground" />
</div>
<div class="flex flex-col overflow-hidden">
<div class="text-sm font-medium truncate leading-tight">
{player.currentTrack.title || "Unknown Title"}
</div>
<div
class="text-xs text-muted-foreground truncate leading-tight"
>
{player.currentTrack.artist || "Unknown Artist"}
</div>
</div>
</button>
<!-- Mini Controls -->
<div class="flex items-center gap-1">
<Controls />
<!-- Actually Controls has too many buttons for mini player. Just Play/Next? -->
<!-- We'll reimplement mini controls or pass props to Controls to show fewer buttons -->
<!-- Let's just use simplified controls here for now, or just Play/Pause -->
</div>
</div>
<!-- Progress Bar (thin line at top of bar) -->
<div class="absolute top-0 left-0 right-0 h-1 bg-muted">
<div <div
class="h-full bg-primary transition-all duration-100 ease-linear" class="h-10 w-10 rounded bg-muted flex items-center justify-center shrink-0"
style="width: {(audio.currentTime / audio.duration) * 100}%" >
></div> <Disc class="h-6 w-6 text-muted-foreground" />
</div>
<div class="flex flex-col overflow-hidden">
<div class="text-sm font-medium truncate leading-tight">
{player.currentTrack?.title || "Unknown Title"}
</div>
<div
class="text-xs text-muted-foreground truncate leading-tight"
>
{player.currentTrack?.artist || "Unknown Artist"}
</div>
</div>
</button>
<!-- Mini Controls -->
<div class="flex items-center gap-1">
<Controls />
<!-- Actually Controls has too many buttons for mini player. Just Play/Next? -->
<!-- We'll reimplement mini controls or pass props to Controls to show fewer buttons -->
<!-- Let's just use simplified controls here for now, or just Play/Pause -->
</div> </div>
</div> </div>
<Drawer.Root bind:open> <!-- Progress Bar (thin line at top of bar) -->
<Drawer.Content class="h-[96dvh] flex flex-col rounded-t-[10px]"> <div class="absolute top-0 left-0 right-0 h-1 bg-muted">
<div class="mx-auto w-Full max-w-sm flex-1 flex flex-col p-4 gap-6"> <div
<!-- Header --> class="h-full bg-primary transition-all duration-100 ease-linear"
<div class="flex justify-center pt-2"> style="width: {(audio.currentTime / audio.duration) * 100}%"
<div ></div>
class="h-1.5 w-12 rounded-full bg-muted-foreground/20" </div>
></div> </div>
</div>
<!-- Expanded Art --> <Drawer.Root bind:open>
<Drawer.Content class="h-[96dvh] flex flex-col rounded-t-[10px]">
<div class="mx-auto w-Full max-w-sm flex-1 flex flex-col p-4 gap-6">
<!-- Header -->
<div class="flex justify-center pt-2">
<div <div
class="aspect-square w-full relative rounded-xl overflow-hidden bg-muted flex items-center justify-center shadow-lg" class="h-1.5 w-12 rounded-full bg-muted-foreground/20"
></div>
</div>
<!-- Expanded Art -->
<div
class="aspect-square w-full relative rounded-xl overflow-hidden bg-muted flex items-center justify-center shadow-lg"
>
<Disc class="h-24 w-24 text-muted-foreground" />
<!-- If we had art, we'd show it here -->
</div>
<!-- Track Info -->
<div class="text-center space-y-1">
<h2 class="text-xl font-bold leading-tight line-clamp-2">
{player.currentTrack?.title}
</h2>
<p
class="text-muted-foreground font-medium text-lg line-clamp-1"
> >
<Disc class="h-24 w-24 text-muted-foreground" /> {player.currentTrack?.artist}
<!-- If we had art, we'd show it here --> </p>
</div> <p class="text-xs text-muted-foreground/80 mt-1">
{player.currentTrack?.album ||
player.currentTrack?.animeName}
</p>
</div>
<!-- Track Info --> <!-- Progress -->
<div class="text-center space-y-1"> <div class="space-y-2">
<h2 class="text-xl font-bold leading-tight line-clamp-2"> <Slider
{player.currentTrack.title} value={[audio.currentTime]}
</h2> max={audio.duration || 100}
<p step={1}
class="text-muted-foreground font-medium text-lg line-clamp-1" onValueChange={onSeek}
> type="multiple"
{player.currentTrack.artist} class="w-full"
</p> />
<p class="text-xs text-muted-foreground/80 mt-1"> <div
{player.currentTrack.album || class="flex justify-between text-xs text-muted-foreground font-variant-numeric tabular-nums"
player.currentTrack.animeName} >
</p> <span>{formatTime(audio.currentTime)}</span>
</div> <span>{formatTime(audio.duration)}</span>
<!-- Progress -->
<div class="space-y-2">
<Slider
value={[audio.currentTime]}
max={audio.duration || 100}
step={1}
onValueChange={onSeek}
type="multiple"
class="w-full"
/>
<div
class="flex justify-between text-xs text-muted-foreground font-variant-numeric tabular-nums"
>
<span>{formatTime(audio.currentTime)}</span>
<span>{formatTime(audio.duration)}</span>
</div>
</div>
<!-- Main Controls -->
<div class="flex justify-center py-4">
<Controls />
</div>
<!-- Volume? Or Queue toggle? -->
<!-- Queue -->
<div class="flex-1 overflow-hidden relative mt-auto">
<div class="absolute inset-0">
<Queue />
</div>
</div> </div>
</div> </div>
</Drawer.Content>
</Drawer.Root> <!-- Main Controls -->
{/if} <div class="flex justify-center py-4">
<Controls />
</div>
<!-- Volume? Or Queue toggle? -->
<!-- Queue -->
<div class="flex-1 overflow-hidden relative mt-auto">
<div class="absolute inset-0">
<Queue />
</div>
</div>
</div>
</Drawer.Content>
</Drawer.Root>

View File

@@ -75,8 +75,19 @@
// ... existing effect for playback ... // ... existing effect for playback ...
$effect(() => { $effect(() => {
const track = player.currentTrack; const track = player.currentTrack;
if (track && audioEl) { if (audioEl) {
// ... if (track) {
const newSrc = track.src;
if (audioEl.src !== newSrc) {
audioEl.src = newSrc;
audioEl.play().catch((e) => {
console.warn("Autoplay blocked or failed", e);
});
}
} else {
audioEl.removeAttribute("src");
}
// Update MediaSession playback state // Update MediaSession playback state
if ("mediaSession" in navigator) { if ("mediaSession" in navigator) {
navigator.mediaSession.playbackState = audioEl.paused navigator.mediaSession.playbackState = audioEl.paused