feat(queue): add scroll to currently playing button

Adds a scrollToIndex method to VirtualList and a locate button in the
Queue header that scrolls to center the currently playing track.
This commit is contained in:
2026-02-12 22:00:03 -08:00
parent c0ff938bf3
commit 63145c128e
2 changed files with 36 additions and 7 deletions

View File

@@ -1,5 +1,5 @@
<script lang="ts">
import { GripVertical, Play, X } from "@lucide/svelte";
import { GripVertical, LocateFixed, Play, X } from "@lucide/svelte";
import * as AlertDialog from "$lib/components/ui/alert-dialog";
import { Button } from "$lib/components/ui/button";
import VirtualList from "$lib/components/ui/VirtualList.svelte";
@@ -7,6 +7,16 @@
import type { Track } from "$lib/player/types";
import { songTypeNumberLabel } from "$lib/utils/amq";
let virtualList: ReturnType<typeof VirtualList>;
function scrollToCurrentlyPlaying() {
if (player.currentId == null) return;
const index = player.displayQueue.findIndex(
(t) => t.id === player.currentId,
);
if (index !== -1) virtualList?.scrollToIndex(index);
}
const ITEM_HEIGHT = 64;
function onRemove(id: number) {
@@ -45,21 +55,31 @@
<div
class="flex flex-col h-full w-full bg-background/50 backdrop-blur rounded-lg border overflow-hidden"
>
<div class="px-4 py-3 border-b flex justify-between items-center bg-muted/20">
<h3 class="font-semibold text-sm">
Up Next
<div
class="px-4 py-3 border-b flex text-sm items-center justify-between bg-muted/20"
>
<div class="flex items-center gap-1">
<h3 class="font-semibold">Up Next</h3>
{#if player.displayQueue.length > 0}
<span class="text-muted-foreground font-normal ml-1"
>({player.displayQueue.length})</span
>
<Button
variant="ghost"
size="sm"
class="h-6 w-6 p-0"
aria-label="Scroll to currently playing"
onclick={scrollToCurrentlyPlaying}
>
<LocateFixed class="h-3 w-3" />
</Button>
{/if}
</h3>
</div>
<AlertDialog.Root>
<AlertDialog.Trigger>
{#snippet child({ props })}
<Button variant="ghost" size="sm" class="h-6 w-6 p-0" {...props}>
<span class="sr-only">Clear</span>
<X class="h-3 w-3" />
<X class="h-3 w-3" aria-label="Clear" />
</Button>
{/snippet}
</AlertDialog.Trigger>
@@ -81,6 +101,7 @@
</div>
<VirtualList
bind:this={virtualList}
items={player.displayQueue}
itemHeight={ITEM_HEIGHT}
overscan={5}