WIP: global player pt. 3 monstrosity
This commit is contained in:
@@ -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>
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user