@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;;OAEG;IACH,UAAU,CAAC,MAAM,EAAE,UAAU,EAAE,EAAE,OAAO,CAAC,EAAE;QACzC,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,WAAW,CAAC,EAAE,OAAO,CAAC;QACtB,kBAAkB,CAAC,EAAE,MAAM,CAAC;KAC7B,GAAG,IAAI;IAgCR;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAYxB;;OAEG;IACH,OAAO,CAAC,eAAe;IAQvB,IAAI,IAAI,IAAI;IA4BZ,IAAI,IAAI,IAAI;IA4BZ,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAqBzB,KAAK,IAAI,IAAI;IAMb,MAAM,IAAI,IAAI;IAMd,MAAM,IAAI,IAAI;IASd,QAAQ,IAAI,cAAc;IAI1B,aAAa,CAAC,QAAQ,EAAE,aAAa,GAAG,MAAM,IAAI;IAMlD,OAAO,CAAC,eAAe;IAIvB;;OAEG;IACH,OAAO,IAAI,IAAI;CAIhB;AAqBD,MAAM,WAAW,cAAc;IAC7B,iCAAiC;IACjC,MAAM,EAAE,UAAU,EAAE,CAAC;IACrB,4DAA4D;IAC5D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,0CAA0C;IAC1C,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,wCAAwC;IACxC,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;IACvC,+CAA+C;IAC/C,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,2CAA2C;IAC3C,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,6CAA6C;IAC7C,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,6DAA6D;IAC7D,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,qGAAqG;IACrG,SAAS,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAChC,mCAAmC;IACnC,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,6BAA6B;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kCAAkC;IAClC,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,SAAS,CAAC,EACxB,MAAM,EACN,UAAiB,EACjB,WAAkB,EAClB,UAAmB,EACnB,kBAAwB,EACxB,QAAe,EACf,UAAiB,EACjB,SAAgB,EAChB,SAAmB,EACnB,QAAQ,EACR,SAAc,EACd,cAAmB,GACpB,EAAE,cAAc,qBAmThB;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI,qBAAqB,CAMzD;AAGD,eAAO,MAAM,YAAY,0BAAoB,CAAC"}
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
- // Only reset if images changed
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: options?.autoAdvance === false,
41
+ isPaused: shouldBePaused,
36
42
  };
37
43
  }
38
44
  else {
39
- // Just update totalSlides in case it changed
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
- console.log('[Slideshow Swipe] Effect running:', {
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
- console.log('[Slideshow Swipe] Attaching touch listeners to container');
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 and stop propagation for horizontal swipes
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
- // Don't process if transitioning
308
- if (state.isTransitioning) {
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
- // Lower threshold for smaller tiles - 30px minimum swipe distance
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
- console.log('[Slideshow Swipe] 🎯 Triggering PREV');
338
- singleton.prev();
306
+ swipeSingleton.prev();
339
307
  }
340
308
  else {
341
- console.log('[Slideshow Swipe] 🎯 Triggering NEXT');
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 on all to allow preventDefault()
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, state.totalSlides, state.isTransitioning, singleton]);
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;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thewhateverapp/tile-sdk",
3
- "version": "0.13.16",
3
+ "version": "0.13.18",
4
4
  "description": "SDK for building interactive tiles on The Whatever App platform",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",