fix(ads): banner truly continuous across navigation + re-measure on resize
CI / changes (pull_request) Successful in 3s
CI / unit (pull_request) Successful in 8s
CI / integration (pull_request) Successful in 14s
CI / ui (pull_request) Successful in 48s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m6s
CI / changes (pull_request) Successful in 3s
CI / unit (pull_request) Successful in 8s
CI / integration (pull_request) Successful in 14s
CI / ui (pull_request) Successful in 48s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m6s
The previous engine kept the scheduler running but the view re-`show()`-ed the
current message on every (re)mount, replaying the fade on each navigation — which
looked like the cycle restarting (especially for a single message). Now:
- A mounted AdBanner reads the engine's live message (bannerCurrent) and renders
it immediately, with no fade; attach no longer re-shows. Only a real advance
fades. Verified: opacity stays 1.0 across a navigation, message preserved.
- The fade is manual opacity on a .fadewrap layer (not transition:fade), kept
independent of the scroll (inner track transform), so a long message still
fades at both ends and a {#key} remount cannot force an intro fade.
- A viewport size change (portrait↔landscape) re-measures the current message
(remeasureBanner on resize/orientationchange, debounced) so the scroll
re-evaluates for the new width — the owner accepts the restart on resize.
Rotator gains restart(); engine gains bannerCurrent()/remeasureBanner().
Engine continuity + remeasure unit-tested.
This commit is contained in:
@@ -73,6 +73,9 @@ export interface BannerHost {
|
||||
export interface Rotator {
|
||||
start(): void;
|
||||
stop(): void;
|
||||
/** Re-present the current message (re-measure overflow + restart its scroll), e.g. after the
|
||||
* viewport size changed. A no-op before start(). */
|
||||
restart(): void;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -91,6 +94,7 @@ export function createBannerRotator(
|
||||
const sched = createScheduler(campaigns);
|
||||
let running = false;
|
||||
let cycleStart = 0;
|
||||
let lastShown = ''; // the message currently presented, for restart() (re-measure)
|
||||
const timers: ReturnType<typeof setTimeout>[] = [];
|
||||
|
||||
const at = (ms: number, fn: () => void) => {
|
||||
@@ -104,6 +108,7 @@ export function createBannerRotator(
|
||||
function present(md: string) {
|
||||
if (!running) return;
|
||||
clear();
|
||||
lastShown = md;
|
||||
host.show(md);
|
||||
at(config.fadeInMs, measure);
|
||||
}
|
||||
@@ -151,6 +156,9 @@ export function createBannerRotator(
|
||||
running = false;
|
||||
clear();
|
||||
},
|
||||
restart() {
|
||||
if (running && lastShown) present(lastShown);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user