🏗️ Build and Test JellyTau / Run Tests (push) Failing after 14m18s
🏗️ Build and Test JellyTau / Android Compile Check (push) Skipped
Publish Documentation / Build & publish docs to gitea-pages (push) Successful in 5m31s
Traceability Validation / Check Requirement Traces (push) Successful in 17s
Build & Release / Run Tests (push) Failing after 14m7s
Build & Release / Build Linux (push) Skipped
Build & Release / Build Windows (push) Skipped
Build & Release / Build Android (push) Skipped
Build & Release / Create Release (push) Skipped
The rotation interval was installed once when the banner mounted and never touched again, so a swipe, arrow or dot tap inherited whatever was left of the running countdown — swiping 5.5s into a 6s interval moved the banner on half a second later. The timer moves into heroRotation.ts as a small restartable object so it can be unit-tested, and every manual navigation path restarts it from that moment. Verified red-first: with restart() reverted to leave a running timer alone, the regression test fails. Release 0.9.1.
41 lines
1.2 KiB
TypeScript
41 lines
1.2 KiB
TypeScript
// Auto-rotation timer for the home-screen hero banner.
|
|
//
|
|
// Extracted from HeroBanner.svelte so it can be unit-tested: a manual swipe or
|
|
// dot/arrow click must restart the countdown from that moment. The old code
|
|
// installed one bare setInterval and left it running, so swiping late in an
|
|
// interval made the banner jump to the next item almost immediately.
|
|
//
|
|
// TRACES: UR-034 | DR-038 | UT-207
|
|
|
|
export interface RotationTimer {
|
|
/** (Re)start the countdown from now, replacing any pending tick. */
|
|
restart(): void;
|
|
/** Cancel the countdown. */
|
|
stop(): void;
|
|
isRunning(): boolean;
|
|
}
|
|
|
|
/**
|
|
* Create a repeating timer that calls `onElapse` every `interval` ms once
|
|
* started. Restarting is idempotent — there is never more than one live timer.
|
|
*/
|
|
export function createRotationTimer(interval: number, onElapse: () => void): RotationTimer {
|
|
let handle: ReturnType<typeof setInterval> | null = null;
|
|
|
|
function stop() {
|
|
if (handle !== null) {
|
|
clearInterval(handle);
|
|
handle = null;
|
|
}
|
|
}
|
|
|
|
return {
|
|
restart() {
|
|
stop();
|
|
handle = setInterval(onElapse, interval);
|
|
},
|
|
stop,
|
|
isRunning: () => handle !== null,
|
|
};
|
|
}
|