@thewhateverapp/tile-sdk 0.13.16 → 0.13.18
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.
|
@@ -43,6 +43,10 @@ declare class SlideshowSingletonClass {
|
|
|
43
43
|
private transitionDuration;
|
|
44
44
|
/**
|
|
45
45
|
* Initialize slideshow with images
|
|
46
|
+
*
|
|
47
|
+
* Auto-advance state is ALWAYS updated based on the autoAdvance option,
|
|
48
|
+
* allowing tile mode (no auto-advance) and page mode (auto-advance) to
|
|
49
|
+
* work correctly when navigating between routes with the same images.
|
|
46
50
|
*/
|
|
47
51
|
initialize(images: SlideImage[], options?: {
|
|
48
52
|
intervalMs?: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Slideshow.d.ts","sourceRoot":"","sources":["../../../src/react/overlay/Slideshow.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,EAOZ,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAMf,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM;QACd,oBAAoB,CAAC,EAAE,uBAAuB,CAAC;KAChD;CACF;AAED,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,OAAO,CAAC;IACzB,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,UAAU,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,IAAI,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9B,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,MAAM,EAAE,MAAM,IAAI,CAAC;CACpB;AAED,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,cAAc,CAAC;IACtB,QAAQ,EAAE,iBAAiB,CAAC;CAC7B;AAED,KAAK,aAAa,GAAG,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,CAAC;AAErD;;;;;GAKG;AACH,cAAM,uBAAuB;IAC3B,OAAO,CAAC,cAAc,CAAiC;IACvD,OAAO,CAAC,YAAY,CAMlB;IACF,OAAO,CAAC,WAAW,CAA+B;IAClD,OAAO,CAAC,UAAU,CAAgB;IAClC,OAAO,CAAC,kBAAkB,CAAe;IAEzC
|
|
1
|
+
{"version":3,"file":"Slideshow.d.ts","sourceRoot":"","sources":["../../../src/react/overlay/Slideshow.tsx"],"names":[],"mappings":"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"}
|
|
@@ -22,25 +22,33 @@ class SlideshowSingletonClass {
|
|
|
22
22
|
}
|
|
23
23
|
/**
|
|
24
24
|
* Initialize slideshow with images
|
|
25
|
+
*
|
|
26
|
+
* Auto-advance state is ALWAYS updated based on the autoAdvance option,
|
|
27
|
+
* allowing tile mode (no auto-advance) and page mode (auto-advance) to
|
|
28
|
+
* work correctly when navigating between routes with the same images.
|
|
25
29
|
*/
|
|
26
30
|
initialize(images, options) {
|
|
27
31
|
const imagesChanged = JSON.stringify(images) !== JSON.stringify(this.currentState.images);
|
|
28
|
-
//
|
|
32
|
+
// Determine pause state from autoAdvance option (default: true = not paused)
|
|
33
|
+
const shouldBePaused = options?.autoAdvance === false;
|
|
29
34
|
if (imagesChanged) {
|
|
35
|
+
// Images changed - reset to first slide
|
|
30
36
|
this.currentState = {
|
|
31
37
|
...this.currentState,
|
|
32
38
|
currentIndex: 0,
|
|
33
39
|
totalSlides: images.length,
|
|
34
40
|
images,
|
|
35
|
-
isPaused:
|
|
41
|
+
isPaused: shouldBePaused,
|
|
36
42
|
};
|
|
37
43
|
}
|
|
38
44
|
else {
|
|
39
|
-
//
|
|
45
|
+
// Same images - preserve current slide but update auto-advance state
|
|
46
|
+
// This allows tile→page navigation to start auto-advancing
|
|
40
47
|
this.currentState = {
|
|
41
48
|
...this.currentState,
|
|
42
49
|
totalSlides: images.length,
|
|
43
50
|
images,
|
|
51
|
+
isPaused: shouldBePaused,
|
|
44
52
|
};
|
|
45
53
|
}
|
|
46
54
|
if (options?.intervalMs) {
|
|
@@ -232,37 +240,21 @@ export function Slideshow({ images, intervalMs = 5000, autoAdvance = true, trans
|
|
|
232
240
|
toggle: useCallback(() => singleton.toggle(), []),
|
|
233
241
|
};
|
|
234
242
|
// Touch/swipe handlers using native events (React touch events are passive)
|
|
243
|
+
// NOTE: We attach listeners once and check singleton state directly to avoid
|
|
244
|
+
// stale closure issues and listener teardown during swipe sequences.
|
|
235
245
|
const touchCurrentRef = useRef(null);
|
|
236
246
|
useEffect(() => {
|
|
237
247
|
const container = containerRef.current;
|
|
238
|
-
|
|
239
|
-
hasContainer: !!container,
|
|
240
|
-
swipeable,
|
|
241
|
-
totalSlides: state.totalSlides,
|
|
242
|
-
isTransitioning: state.isTransitioning,
|
|
243
|
-
});
|
|
244
|
-
if (!container) {
|
|
245
|
-
console.log('[Slideshow Swipe] ❌ No container ref');
|
|
246
|
-
return;
|
|
247
|
-
}
|
|
248
|
-
if (!swipeable) {
|
|
249
|
-
console.log('[Slideshow Swipe] ❌ Swipeable is false');
|
|
250
|
-
return;
|
|
251
|
-
}
|
|
252
|
-
if (state.totalSlides <= 1) {
|
|
253
|
-
console.log('[Slideshow Swipe] ❌ Only', state.totalSlides, 'slide(s)');
|
|
248
|
+
if (!container || !swipeable) {
|
|
254
249
|
return;
|
|
255
250
|
}
|
|
256
|
-
|
|
251
|
+
// Get singleton reference once - we'll check its state directly in handlers
|
|
252
|
+
const swipeSingleton = getSlideshowSingleton();
|
|
257
253
|
const handleTouchStart = (e) => {
|
|
254
|
+
// Check totalSlides from singleton (not stale closure)
|
|
255
|
+
if (swipeSingleton.getState().totalSlides <= 1)
|
|
256
|
+
return;
|
|
258
257
|
const touch = e.touches[0];
|
|
259
|
-
console.log('[Slideshow Swipe] touchstart:', {
|
|
260
|
-
hasTouch: !!touch,
|
|
261
|
-
clientX: touch?.clientX,
|
|
262
|
-
clientY: touch?.clientY,
|
|
263
|
-
target: e.target?.tagName,
|
|
264
|
-
currentTarget: e.currentTarget?.tagName,
|
|
265
|
-
});
|
|
266
258
|
if (!touch)
|
|
267
259
|
return;
|
|
268
260
|
touchStartRef.current = {
|
|
@@ -273,40 +265,28 @@ export function Slideshow({ images, intervalMs = 5000, autoAdvance = true, trans
|
|
|
273
265
|
touchCurrentRef.current = { x: touch.clientX, y: touch.clientY };
|
|
274
266
|
};
|
|
275
267
|
const handleTouchMove = (e) => {
|
|
276
|
-
if (!touchStartRef.current)
|
|
277
|
-
console.log('[Slideshow Swipe] touchmove: no touchStart ref');
|
|
268
|
+
if (!touchStartRef.current)
|
|
278
269
|
return;
|
|
279
|
-
}
|
|
280
270
|
const touch = e.touches[0];
|
|
281
|
-
if (!touch)
|
|
282
|
-
console.log('[Slideshow Swipe] touchmove: no touch');
|
|
271
|
+
if (!touch)
|
|
283
272
|
return;
|
|
284
|
-
}
|
|
285
273
|
touchCurrentRef.current = { x: touch.clientX, y: touch.clientY };
|
|
286
|
-
// Prevent default
|
|
274
|
+
// Prevent default for horizontal swipes to avoid scroll interference
|
|
287
275
|
const deltaX = touch.clientX - touchStartRef.current.x;
|
|
288
276
|
const deltaY = touch.clientY - touchStartRef.current.y;
|
|
289
277
|
if (Math.abs(deltaX) > Math.abs(deltaY) && Math.abs(deltaX) > 10) {
|
|
290
|
-
console.log('[Slideshow Swipe] touchmove: horizontal swipe detected, preventing default', { deltaX, deltaY });
|
|
291
278
|
e.preventDefault();
|
|
292
279
|
e.stopPropagation();
|
|
293
280
|
}
|
|
294
281
|
};
|
|
295
282
|
const handleTouchEnd = (e) => {
|
|
296
|
-
console.log('[Slideshow Swipe] touchend:', {
|
|
297
|
-
hasTouchStart: !!touchStartRef.current,
|
|
298
|
-
hasTouchCurrent: !!touchCurrentRef.current,
|
|
299
|
-
isTransitioning: state.isTransitioning,
|
|
300
|
-
});
|
|
301
283
|
if (!touchStartRef.current || !touchCurrentRef.current) {
|
|
302
|
-
console.log('[Slideshow Swipe] touchend: missing refs, aborting');
|
|
303
284
|
touchStartRef.current = null;
|
|
304
285
|
touchCurrentRef.current = null;
|
|
305
286
|
return;
|
|
306
287
|
}
|
|
307
|
-
//
|
|
308
|
-
if (
|
|
309
|
-
console.log('[Slideshow Swipe] touchend: transitioning, aborting');
|
|
288
|
+
// Check transitioning from singleton directly (not stale closure)
|
|
289
|
+
if (swipeSingleton.getState().isTransitioning) {
|
|
310
290
|
touchStartRef.current = null;
|
|
311
291
|
touchCurrentRef.current = null;
|
|
312
292
|
return;
|
|
@@ -314,54 +294,34 @@ export function Slideshow({ images, intervalMs = 5000, autoAdvance = true, trans
|
|
|
314
294
|
const deltaX = touchCurrentRef.current.x - touchStartRef.current.x;
|
|
315
295
|
const deltaY = touchCurrentRef.current.y - touchStartRef.current.y;
|
|
316
296
|
const deltaTime = Date.now() - touchStartRef.current.time;
|
|
317
|
-
//
|
|
297
|
+
// 30px minimum swipe distance, must be horizontal
|
|
318
298
|
const minSwipeDistance = 30;
|
|
319
299
|
const isHorizontalSwipe = Math.abs(deltaX) > Math.abs(deltaY);
|
|
320
300
|
const isValidSwipe = Math.abs(deltaX) > minSwipeDistance && isHorizontalSwipe;
|
|
321
301
|
const isQuickSwipe = deltaTime < 500 || Math.abs(deltaX) > 60;
|
|
322
|
-
console.log('[Slideshow Swipe] touchend analysis:', {
|
|
323
|
-
deltaX,
|
|
324
|
-
deltaY,
|
|
325
|
-
deltaTime,
|
|
326
|
-
minSwipeDistance,
|
|
327
|
-
isHorizontalSwipe,
|
|
328
|
-
isValidSwipe,
|
|
329
|
-
isQuickSwipe,
|
|
330
|
-
willTrigger: isValidSwipe && isQuickSwipe,
|
|
331
|
-
direction: deltaX > 0 ? 'prev' : 'next',
|
|
332
|
-
});
|
|
333
302
|
if (isValidSwipe && isQuickSwipe) {
|
|
334
303
|
e.preventDefault();
|
|
335
304
|
e.stopPropagation();
|
|
336
305
|
if (deltaX > 0) {
|
|
337
|
-
|
|
338
|
-
singleton.prev();
|
|
306
|
+
swipeSingleton.prev();
|
|
339
307
|
}
|
|
340
308
|
else {
|
|
341
|
-
|
|
342
|
-
singleton.next();
|
|
309
|
+
swipeSingleton.next();
|
|
343
310
|
}
|
|
344
311
|
}
|
|
345
|
-
else {
|
|
346
|
-
console.log('[Slideshow Swipe] ❌ Swipe not valid:', {
|
|
347
|
-
reason: !isHorizontalSwipe ? 'not horizontal' : !isValidSwipe ? 'too short' : 'too slow',
|
|
348
|
-
});
|
|
349
|
-
}
|
|
350
312
|
touchStartRef.current = null;
|
|
351
313
|
touchCurrentRef.current = null;
|
|
352
314
|
};
|
|
353
|
-
// Use passive: false
|
|
315
|
+
// Use passive: false to allow preventDefault()
|
|
354
316
|
container.addEventListener('touchstart', handleTouchStart, { passive: false });
|
|
355
317
|
container.addEventListener('touchmove', handleTouchMove, { passive: false });
|
|
356
318
|
container.addEventListener('touchend', handleTouchEnd, { passive: false });
|
|
357
|
-
console.log('[Slideshow Swipe] ✅ Listeners attached successfully');
|
|
358
319
|
return () => {
|
|
359
|
-
console.log('[Slideshow Swipe] Cleaning up listeners');
|
|
360
320
|
container.removeEventListener('touchstart', handleTouchStart);
|
|
361
321
|
container.removeEventListener('touchmove', handleTouchMove);
|
|
362
322
|
container.removeEventListener('touchend', handleTouchEnd);
|
|
363
323
|
};
|
|
364
|
-
}, [swipeable
|
|
324
|
+
}, [swipeable]); // Only re-attach if swipeable changes - check singleton for dynamic state
|
|
365
325
|
// Get transition styles
|
|
366
326
|
const getTransitionStyles = (index) => {
|
|
367
327
|
const isActive = index === state.currentIndex;
|