fix: homepage overlay blocker and carousel auto-advance
Some checks failed
Release / Test backend (push) Successful in 41s
Release / Check ui (push) Successful in 1m43s
Release / Docker / caddy (push) Successful in 42s
Release / Docker / backend (push) Successful in 2m31s
Release / Docker / runner (push) Successful in 2m36s
Release / Docker / ui (push) Has been cancelled
Release / Gitea Release (push) Has been cancelled
Release / Upload source maps (push) Has been cancelled
CI / Backend (push) Successful in 43s
CI / UI (push) Successful in 49s
Some checks failed
Release / Test backend (push) Successful in 41s
Release / Check ui (push) Successful in 1m43s
Release / Docker / caddy (push) Successful in 42s
Release / Docker / backend (push) Successful in 2m31s
Release / Docker / runner (push) Successful in 2m36s
Release / Docker / ui (push) Has been cancelled
Release / Gitea Release (push) Has been cancelled
Release / Upload source maps (push) Has been cancelled
CI / Backend (push) Successful in 43s
CI / UI (push) Successful in 49s
- Add pointer-events:none to ListeningMode fly-transition wrapper div in +layout.svelte so the exiting animation div never blocks page interaction - Add pointer-events:auto to ListeningMode root div so it still captures all touch/click events correctly despite the parent being pointer-events:none - Rewrite carousel auto-advance using $effect + autoAdvanceSeed pattern: replaces the stale-closure setInterval in resetAutoAdvance() with a reactive $effect that owns the interval and re-starts cleanly on manual navigation by bumping a seed counter
This commit is contained in:
@@ -256,6 +256,7 @@
|
|||||||
transition: {isDragging ? 'none' : 'transform 0.32s cubic-bezier(0.32,0.72,0,1), opacity 0.32s ease'};
|
transition: {isDragging ? 'none' : 'transform 0.32s cubic-bezier(0.32,0.72,0,1), opacity 0.32s ease'};
|
||||||
will-change: transform;
|
will-change: transform;
|
||||||
touch-action: pan-x;
|
touch-action: pan-x;
|
||||||
|
pointer-events: auto;
|
||||||
"
|
"
|
||||||
ontouchstart={onTouchStart}
|
ontouchstart={onTouchStart}
|
||||||
ontouchend={onTouchEnd}
|
ontouchend={onTouchEnd}
|
||||||
|
|||||||
@@ -954,7 +954,7 @@
|
|||||||
<!-- Listening mode — mounted at root level, independent of audioStore.active,
|
<!-- Listening mode — mounted at root level, independent of audioStore.active,
|
||||||
so closing/pausing audio never tears it down and loses context. -->
|
so closing/pausing audio never tears it down and loses context. -->
|
||||||
{#if listeningModeOpen}
|
{#if listeningModeOpen}
|
||||||
<div transition:fly={{ y: '100%', duration: 320, opacity: 1 }}>
|
<div transition:fly={{ y: '100%', duration: 320, opacity: 1 }} style="pointer-events: none;">
|
||||||
<ListeningMode
|
<ListeningMode
|
||||||
onclose={() => { listeningModeOpen = false; listeningModeChapters = false; }}
|
onclose={() => { listeningModeOpen = false; listeningModeChapters = false; }}
|
||||||
openChapters={listeningModeChapters}
|
openChapters={listeningModeChapters}
|
||||||
|
|||||||
@@ -95,22 +95,28 @@
|
|||||||
resetAutoAdvance();
|
resetAutoAdvance();
|
||||||
}
|
}
|
||||||
|
|
||||||
let autoAdvanceTimer = $state<ReturnType<typeof setInterval> | null>(null);
|
// Auto-advance carousel every 6 s when there are multiple books.
|
||||||
|
// We use a $state counter as a "restart token" so the $effect can be
|
||||||
function resetAutoAdvance() {
|
// re-triggered by manual navigation without reading heroIndex (which would
|
||||||
if (autoAdvanceTimer) clearInterval(autoAdvanceTimer);
|
// cause an infinite loop when the interval itself mutates heroIndex).
|
||||||
if (heroBooks.length > 1) {
|
let autoAdvanceSeed = $state(0);
|
||||||
autoAdvanceTimer = setInterval(() => {
|
|
||||||
heroIndex = (heroIndex + 1) % heroBooks.length;
|
|
||||||
}, 6000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$effect(() => {
|
$effect(() => {
|
||||||
resetAutoAdvance();
|
if (heroBooks.length <= 1) return;
|
||||||
return () => { if (autoAdvanceTimer) clearInterval(autoAdvanceTimer); };
|
// Subscribe to heroBooks.length and autoAdvanceSeed only — not heroIndex.
|
||||||
|
const len = heroBooks.length;
|
||||||
|
void autoAdvanceSeed; // track the seed
|
||||||
|
const id = setInterval(() => {
|
||||||
|
heroIndex = (heroIndex + 1) % len;
|
||||||
|
}, 6000);
|
||||||
|
return () => clearInterval(id);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function resetAutoAdvance() {
|
||||||
|
// Bump the seed to restart the interval after manual navigation.
|
||||||
|
autoAdvanceSeed++;
|
||||||
|
}
|
||||||
|
|
||||||
function playChapter(slug: string, chapter: number) {
|
function playChapter(slug: string, chapter: number) {
|
||||||
audioStore.autoStartChapter = chapter;
|
audioStore.autoStartChapter = chapter;
|
||||||
goto(`/books/${slug}/chapters/${chapter}`);
|
goto(`/books/${slug}/chapters/${chapter}`);
|
||||||
|
|||||||
Reference in New Issue
Block a user