Compare commits

...

1 Commits

Author SHA1 Message Date
root
5177320418 feat(player): scroll chapter list to current chapter on open
Some checks failed
Release / Test backend (push) Successful in 39s
Release / Check ui (push) Successful in 1m41s
Release / Docker / caddy (push) Successful in 52s
Release / Docker / backend (push) Successful in 2m42s
Release / Docker / runner (push) Successful in 2m35s
Release / Upload source maps (push) Successful in 1m31s
Release / Docker / ui (push) Has been cancelled
Release / Gitea Release (push) Has been cancelled
Use a Svelte action on each chapter button that calls scrollIntoView with
behavior:'instant' so the list opens centred on the active chapter with
no visible scroll animation.
2026-04-06 15:31:24 +05:00

View File

@@ -34,6 +34,14 @@
// ── Chapter search ────────────────────────────────────────────────────────
let chapterSearch = $state('');
// Scroll the current chapter into view instantly (no animation) when the
// chapter modal opens. Applied to every chapter button; only scrolls when
// the chapter number matches the currently playing one. Runs once on mount
// before the browser paints so no scroll animation is ever visible.
function scrollIfActive(node: HTMLElement, isActive: boolean) {
if (isActive) node.scrollIntoView({ block: 'center', behavior: 'instant' });
}
const filteredChapters = $derived(
chapterSearch.trim() === ''
? audioStore.chapters
@@ -386,11 +394,12 @@
</div>
<!-- Chapter list -->
<div class="flex-1 overflow-y-auto">
{#each filteredChapters as ch (ch.number)}
<button
type="button"
onclick={() => playChapter(ch.number)}
class={cn(
{#each filteredChapters as ch (ch.number)}
<button
type="button"
onclick={() => playChapter(ch.number)}
use:scrollIfActive={ch.number === audioStore.chapter}
class={cn(
'w-full flex items-center gap-3 px-4 py-3 border-b border-(--color-border)/40 transition-colors text-left',
ch.number === audioStore.chapter ? 'bg-(--color-brand)/8' : 'hover:bg-(--color-surface-2)'
)}