animot-presenter 0.5.14 → 0.5.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/AnimotPresenter.svelte +36 -5
- package/dist/cdn/animot-presenter.esm.js +3724 -3715
- package/dist/cdn/animot-presenter.min.js +8 -8
- package/package.json +1 -1
|
@@ -191,6 +191,11 @@
|
|
|
191
191
|
// when `project.settings.narrationEnabled` is true. Lazy-allocated so
|
|
192
192
|
// decks without narration don't pay for it.
|
|
193
193
|
let narrationAudio: HTMLAudioElement | null = null;
|
|
194
|
+
// Set when the most recent play() was rejected by the browser autoplay
|
|
195
|
+
// policy. The first user gesture clears it and replays the current
|
|
196
|
+
// slide's clip — without this a single-slide deck would never play
|
|
197
|
+
// narration, since there's no navigation event to retry on.
|
|
198
|
+
let narrationPendingGesture = false;
|
|
194
199
|
function playNarrationForSlide(index: number) {
|
|
195
200
|
if (!project?.settings?.narrationEnabled) return;
|
|
196
201
|
const slide = project?.slides?.[index];
|
|
@@ -202,13 +207,22 @@
|
|
|
202
207
|
if (!src) return;
|
|
203
208
|
if (!narrationAudio) narrationAudio = new Audio();
|
|
204
209
|
narrationAudio.src = src;
|
|
205
|
-
// First play() may reject under autoplay policy
|
|
206
|
-
//
|
|
207
|
-
//
|
|
208
|
-
narrationAudio.play().
|
|
210
|
+
// First play() may reject under autoplay policy. We track the
|
|
211
|
+
// rejection so a subsequent user gesture (handled below) retries
|
|
212
|
+
// once instead of silently giving up.
|
|
213
|
+
narrationAudio.play().then(
|
|
214
|
+
() => { narrationPendingGesture = false; },
|
|
215
|
+
() => { narrationPendingGesture = true; }
|
|
216
|
+
);
|
|
217
|
+
}
|
|
218
|
+
function tryUnlockNarrationOnGesture() {
|
|
219
|
+
if (narrationPendingGesture) {
|
|
220
|
+
playNarrationForSlide(currentSlideIndex);
|
|
221
|
+
}
|
|
209
222
|
}
|
|
210
223
|
function stopNarration() {
|
|
211
224
|
if (narrationAudio) { narrationAudio.pause(); narrationAudio = null; }
|
|
225
|
+
narrationPendingGesture = false;
|
|
212
226
|
}
|
|
213
227
|
|
|
214
228
|
const slides = $derived(project?.slides ?? []);
|
|
@@ -1158,7 +1172,24 @@
|
|
|
1158
1172
|
});
|
|
1159
1173
|
if (containerEl) resizeObserver.observe(containerEl);
|
|
1160
1174
|
resetMouseIdleTimer();
|
|
1161
|
-
|
|
1175
|
+
|
|
1176
|
+
// First-gesture retry for narration playback. Browsers block
|
|
1177
|
+
// audio.play() until the user has interacted; without this hook
|
|
1178
|
+
// a single-slide deck would never play its narration since there's
|
|
1179
|
+
// no slide change to retry on. Attached on document so any click
|
|
1180
|
+
// or key press in the page acts as the unlocking gesture.
|
|
1181
|
+
document.addEventListener('pointerdown', tryUnlockNarrationOnGesture, { capture: true });
|
|
1182
|
+
document.addEventListener('keydown', tryUnlockNarrationOnGesture, { capture: true });
|
|
1183
|
+
|
|
1184
|
+
return () => {
|
|
1185
|
+
resizeObserver?.disconnect();
|
|
1186
|
+
clearAutoplayTimer();
|
|
1187
|
+
clearAllTypewriterAnimations();
|
|
1188
|
+
if (mouseIdleTimer) clearTimeout(mouseIdleTimer);
|
|
1189
|
+
stopNarration();
|
|
1190
|
+
document.removeEventListener('pointerdown', tryUnlockNarrationOnGesture, { capture: true });
|
|
1191
|
+
document.removeEventListener('keydown', tryUnlockNarrationOnGesture, { capture: true });
|
|
1192
|
+
};
|
|
1162
1193
|
});
|
|
1163
1194
|
|
|
1164
1195
|
// Watch for prop changes
|