fix stupid slider

This commit is contained in:
2026-02-10 00:58:40 -08:00
parent bfae55afa3
commit 892f43381b
6 changed files with 15 additions and 103 deletions

View File

@@ -1,6 +1,6 @@
<script lang="ts">
import { Disc, Volume1, Volume2, VolumeX } from "@lucide/svelte";
import { Slider } from "$lib/components/ui/slider";
import { player } from "$lib/player/store.svelte";
import Controls from "./Controls.svelte";
import { getAudioContext } from "./ctx.svelte";
@@ -8,21 +8,13 @@
import { formatTime } from "./utils";
const audio = getAudioContext();
function onVolume(v: number[]) {
player.setVolume(v[0]);
}
function toggleMute() {
player.toggleMute();
}
</script>
<div
class="h-full flex flex-col border-l bg-background/50 backdrop-blur w-full"
>
{#if player.currentTrack}
<div class="p-6 space-y-6 flex-shrink-0">
<div class="p-6 space-y-6 shrink-0">
<!-- Artwork -->
<div
class="aspect-square w-full relative rounded-xl overflow-hidden bg-muted flex items-center justify-center shadow-lg border"
@@ -72,7 +64,7 @@
<!-- Volume -->
<div class="flex items-center gap-3 px-4">
<button
onclick={toggleMute}
onclick={() => player.toggleMute()}
class="text-muted-foreground hover:text-foreground transition-colors"
title={player.isMuted ? "Unmute" : "Mute"}
>
@@ -84,12 +76,11 @@
<Volume2 class="h-4 w-4" />
{/if}
</button>
<Slider
value={[player.isMuted ? 0 : player.volume]}
<input
type="range"
bind:value={player.volume}
max={1}
step={0.01}
onValueChange={onVolume}
type="multiple"
step={0.05}
class="flex-1"
/>
</div>

View File

@@ -1,8 +1,6 @@
<script lang="ts">
import { ChevronUp, Disc, X } from "@lucide/svelte";
import { Button } from "$lib/components/ui/button";
import { Disc } from "@lucide/svelte";
import * as Drawer from "$lib/components/ui/drawer";
import { Slider } from "$lib/components/ui/slider";
import { player } from "$lib/player/store.svelte";
import Controls from "./Controls.svelte";
import { getAudioContext } from "./ctx.svelte";
@@ -11,19 +9,6 @@
const audio = getAudioContext();
let open = $state(false);
let sliderValue = $state([0]);
// Sync Audio -> Slider
$effect(() => {
if (Math.abs(sliderValue[0] - audio.currentTime) > 0.1) {
sliderValue = [audio.currentTime];
}
});
function onSeek(v: number[]) {
if (Math.abs(v[0] - audio.currentTime) < 0.1) return;
audio.seek(v[0]);
}
</script>
<div
@@ -109,12 +94,10 @@
<!-- Progress -->
<div class="space-y-2">
<Slider
bind:value={sliderValue}
<input
type="range"
bind:value={audio.currentTime}
max={audio.duration || 100}
step={0.01}
onValueChange={onSeek}
type="multiple"
class="w-full"
/>
<div

View File

@@ -40,13 +40,8 @@
if (track) {
const newSrc = track.src;
const currentSrc = audioEl.currentSrc;
// Create absolute URL for comparison if needed, or rely on currentSrc
// audioEl.src sets the attribute, currentSrc is the resolved URL
const newSrcAbsolute = new URL(newSrc, document.baseURI).href;
// audioEl.src sets the attribute, currentSrc is the resolved URL
if (currentSrc !== newSrcAbsolute) {
if (currentSrc !== newSrc) {
audioEl.src = newSrc;
audioEl.play().catch((e) => {
console.warn("Autoplay blocked or failed", e);
@@ -87,6 +82,8 @@
bind:currentTime={audioCtx.currentTime}
bind:duration={audioCtx.duration}
bind:paused={audioCtx.paused}
bind:volume={player.volume}
bind:muted={player.isMuted}
onended={onEnded}
class="hidden"
></audio>

View File

@@ -51,7 +51,7 @@
class:active={player.currentId === track.id}
>
<div
class="w-8 flex-shrink-0 text-center text-xs text-muted-foreground/60 font-mono"
class="w-8 shrink-0 text-center text-xs text-muted-foreground/60 font-mono"
>
{#if player.currentId === track.id}
<div

View File

@@ -1,7 +0,0 @@
import Root from "./slider.svelte";
export {
Root,
//
Root as Slider,
};

View File

@@ -1,52 +0,0 @@
<script lang="ts">
import { Slider as SliderPrimitive } from "bits-ui";
import { cn, type WithoutChildrenOrChild } from "$lib/utils.js";
let {
ref = $bindable(null),
value = $bindable(),
orientation = "horizontal",
class: className,
...restProps
}: WithoutChildrenOrChild<SliderPrimitive.RootProps> = $props();
</script>
<!--
Discriminated Unions + Destructing (required for bindable) do not
get along, so we shut typescript up by casting `value` to `never`.
-->
<SliderPrimitive.Root
bind:ref
bind:value={value as never}
data-slot="slider"
{orientation}
class={cn(
"relative flex w-full touch-none items-center select-none data-[disabled]:opacity-50 data-[orientation=vertical]:h-full data-[orientation=vertical]:min-h-44 data-[orientation=vertical]:w-auto data-[orientation=vertical]:flex-col",
className
)}
{...restProps}
>
{#snippet children({ thumbs })}
<span
data-orientation={orientation}
data-slot="slider-track"
class={cn(
"bg-muted relative grow overflow-hidden rounded-full data-[orientation=horizontal]:h-1.5 data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-1.5"
)}
>
<SliderPrimitive.Range
data-slot="slider-range"
class={cn(
"bg-primary absolute data-[orientation=horizontal]:h-full data-[orientation=vertical]:w-full"
)}
/>
</span>
{#each thumbs as thumb (thumb)}
<SliderPrimitive.Thumb
data-slot="slider-thumb"
index={thumb}
class="border-primary ring-ring/50 block size-4 shrink-0 rounded-full border bg-white shadow-sm transition-[color,box-shadow] hover:ring-4 focus-visible:ring-4 focus-visible:outline-hidden disabled:pointer-events-none disabled:opacity-50"
/>
{/each}
{/snippet}
</SliderPrimitive.Root>