@thewhateverapp/tile-sdk 0.13.14 → 0.13.16

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.
@@ -38,7 +38,9 @@ export declare const TileContext: React.Context<TileContextValue | null>;
38
38
  interface TileProviderProps {
39
39
  children: React.ReactNode;
40
40
  router?: any;
41
+ /** Override tileId (for runtime injection, e.g., base workers) */
42
+ tileId?: string;
41
43
  }
42
- export declare function TileProvider({ children, router }: TileProviderProps): React.JSX.Element;
44
+ export declare function TileProvider({ children, router, tileId: propTileId }: TileProviderProps): React.JSX.Element;
43
45
  export {};
44
46
  //# sourceMappingURL=TileProvider.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"TileProvider.d.ts","sourceRoot":"","sources":["../../src/react/TileProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA0D,MAAM,OAAO,CAAC;AAC/E,OAAO,EAAiB,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACjE,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,KAAK,EACV,SAAS,EACT,mBAAmB,EACnB,iBAAiB,EAClB,MAAM,UAAU,CAAC;AAElB,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,MAAM,EAAE,UAAU,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,WAAW,GAAG,IAAI,CAAC;IAChC,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,QAAQ,GAAG,OAAO,KAAK,IAAI,CAAC;IAC5D,UAAU,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG,KAAK,IAAI,CAAC;IACpD,qBAAqB,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAClD,QAAQ,EAAE,MAAM,MAAM,GAAG,IAAI,CAAC;IAC9B,OAAO,EAAE;QACP,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;QACnC,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;KACjD,CAAC;IACF,SAAS,EAAE;QACT,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;KACxC,CAAC;IACF,IAAI,EAAE;QACJ,OAAO,EAAE,CAAC,OAAO,CAAC,EAAE;YAAE,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;YAAC,MAAM,CAAC,EAAE,MAAM,CAAA;SAAE,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;QAC5E,aAAa,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;QACtD,cAAc,EAAE,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC;KACpC,CAAC;IACF,KAAK,EAAE;QACL,YAAY,EAAE,CAAC,OAAO,CAAC,EAAE,mBAAmB,KAAK,OAAO,CAAC,SAAS,CAAC,CAAC;QACpE,UAAU,EAAE,CAAC,OAAO,CAAC,EAAE,iBAAiB,KAAK,OAAO,CAAC,SAAS,CAAC,CAAC;QAChE,WAAW,EAAE,CAAC,OAAO,CAAC,EAAE,iBAAiB,KAAK,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;KACpE,CAAC;CACH;AAED,eAAO,MAAM,WAAW,wCAA+C,CAAC;AAExE,UAAU,iBAAiB;IACzB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,MAAM,CAAC,EAAE,GAAG,CAAC;CACd;AAED,wBAAgB,YAAY,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,iBAAiB,qBAgEnE"}
1
+ {"version":3,"file":"TileProvider.d.ts","sourceRoot":"","sources":["../../src/react/TileProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA0D,MAAM,OAAO,CAAC;AAC/E,OAAO,EAAiB,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACjE,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,KAAK,EACV,SAAS,EACT,mBAAmB,EACnB,iBAAiB,EAClB,MAAM,UAAU,CAAC;AAElB,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,MAAM,EAAE,UAAU,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,WAAW,GAAG,IAAI,CAAC;IAChC,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,QAAQ,GAAG,OAAO,KAAK,IAAI,CAAC;IAC5D,UAAU,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG,KAAK,IAAI,CAAC;IACpD,qBAAqB,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAClD,QAAQ,EAAE,MAAM,MAAM,GAAG,IAAI,CAAC;IAC9B,OAAO,EAAE;QACP,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;QACnC,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;KACjD,CAAC;IACF,SAAS,EAAE;QACT,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;KACxC,CAAC;IACF,IAAI,EAAE;QACJ,OAAO,EAAE,CAAC,OAAO,CAAC,EAAE;YAAE,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;YAAC,MAAM,CAAC,EAAE,MAAM,CAAA;SAAE,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;QAC5E,aAAa,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;QACtD,cAAc,EAAE,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC;KACpC,CAAC;IACF,KAAK,EAAE;QACL,YAAY,EAAE,CAAC,OAAO,CAAC,EAAE,mBAAmB,KAAK,OAAO,CAAC,SAAS,CAAC,CAAC;QACpE,UAAU,EAAE,CAAC,OAAO,CAAC,EAAE,iBAAiB,KAAK,OAAO,CAAC,SAAS,CAAC,CAAC;QAChE,WAAW,EAAE,CAAC,OAAO,CAAC,EAAE,iBAAiB,KAAK,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;KACpE,CAAC;CACH;AAED,eAAO,MAAM,WAAW,wCAA+C,CAAC;AAExE,UAAU,iBAAiB;IACzB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,MAAM,CAAC,EAAE,GAAG,CAAC;IACb,kEAAkE;IAClE,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,YAAY,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,EAAE,iBAAiB,qBAkEvF"}
@@ -2,14 +2,14 @@ import React, { createContext, useEffect, useState } from 'react';
2
2
  import { getTileBridge } from '../bridge/TileBridge';
3
3
  import { StateClient } from '../state/StateClient';
4
4
  export const TileContext = createContext(null);
5
- export function TileProvider({ children, router }) {
5
+ export function TileProvider({ children, router, tileId: propTileId }) {
6
6
  const [isReady, setIsReady] = useState(false);
7
7
  const [stateClient, setStateClient] = useState(null);
8
8
  const bridge = getTileBridge(router);
9
- // Get tileId from environment variable
10
- const tileId = typeof process !== 'undefined' && process.env?.NEXT_PUBLIC_TILE_ID
9
+ // Get tileId from prop (runtime injection) or environment variable (build-time)
10
+ const tileId = propTileId || (typeof process !== 'undefined' && process.env?.NEXT_PUBLIC_TILE_ID
11
11
  ? process.env.NEXT_PUBLIC_TILE_ID
12
- : null;
12
+ : null);
13
13
  useEffect(() => {
14
14
  // Create state client if tileId exists
15
15
  if (tileId) {
@@ -1 +1 @@
1
- {"version":3,"file":"Slideshow.d.ts","sourceRoot":"","sources":["../../../src/react/overlay/Slideshow.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Slideshow.d.ts","sourceRoot":"","sources":["../../../src/react/overlay/Slideshow.tsx"],"names":[],"mappings":"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"}
@@ -75,12 +75,21 @@ class SlideshowSingletonClass {
75
75
  }
76
76
  // Navigation controls
77
77
  next() {
78
- if (this.currentState.isTransitioning || this.currentState.totalSlides <= 1)
78
+ console.log('[SlideshowSingleton] next() called:', {
79
+ isTransitioning: this.currentState.isTransitioning,
80
+ totalSlides: this.currentState.totalSlides,
81
+ currentIndex: this.currentState.currentIndex,
82
+ });
83
+ if (this.currentState.isTransitioning || this.currentState.totalSlides <= 1) {
84
+ console.log('[SlideshowSingleton] next() blocked:', this.currentState.isTransitioning ? 'transitioning' : 'single slide');
79
85
  return;
86
+ }
87
+ const newIndex = (this.currentState.currentIndex + 1) % this.currentState.totalSlides;
88
+ console.log('[SlideshowSingleton] next() advancing to index:', newIndex);
80
89
  this.currentState = {
81
90
  ...this.currentState,
82
91
  isTransitioning: true,
83
- currentIndex: (this.currentState.currentIndex + 1) % this.currentState.totalSlides,
92
+ currentIndex: newIndex,
84
93
  };
85
94
  this.notifyListeners();
86
95
  setTimeout(() => {
@@ -89,12 +98,21 @@ class SlideshowSingletonClass {
89
98
  }, this.transitionDuration);
90
99
  }
91
100
  prev() {
92
- if (this.currentState.isTransitioning || this.currentState.totalSlides <= 1)
101
+ console.log('[SlideshowSingleton] prev() called:', {
102
+ isTransitioning: this.currentState.isTransitioning,
103
+ totalSlides: this.currentState.totalSlides,
104
+ currentIndex: this.currentState.currentIndex,
105
+ });
106
+ if (this.currentState.isTransitioning || this.currentState.totalSlides <= 1) {
107
+ console.log('[SlideshowSingleton] prev() blocked:', this.currentState.isTransitioning ? 'transitioning' : 'single slide');
93
108
  return;
109
+ }
110
+ const newIndex = (this.currentState.currentIndex - 1 + this.currentState.totalSlides) % this.currentState.totalSlides;
111
+ console.log('[SlideshowSingleton] prev() going back to index:', newIndex);
94
112
  this.currentState = {
95
113
  ...this.currentState,
96
114
  isTransitioning: true,
97
- currentIndex: (this.currentState.currentIndex - 1 + this.currentState.totalSlides) % this.currentState.totalSlides,
115
+ currentIndex: newIndex,
98
116
  };
99
117
  this.notifyListeners();
100
118
  setTimeout(() => {
@@ -217,10 +235,34 @@ export function Slideshow({ images, intervalMs = 5000, autoAdvance = true, trans
217
235
  const touchCurrentRef = useRef(null);
218
236
  useEffect(() => {
219
237
  const container = containerRef.current;
220
- if (!container || !swipeable || state.totalSlides <= 1)
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');
221
250
  return;
251
+ }
252
+ if (state.totalSlides <= 1) {
253
+ console.log('[Slideshow Swipe] ❌ Only', state.totalSlides, 'slide(s)');
254
+ return;
255
+ }
256
+ console.log('[Slideshow Swipe] ✅ Attaching touch listeners to container');
222
257
  const handleTouchStart = (e) => {
223
258
  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
+ });
224
266
  if (!touch)
225
267
  return;
226
268
  touchStartRef.current = {
@@ -231,28 +273,40 @@ export function Slideshow({ images, intervalMs = 5000, autoAdvance = true, trans
231
273
  touchCurrentRef.current = { x: touch.clientX, y: touch.clientY };
232
274
  };
233
275
  const handleTouchMove = (e) => {
234
- if (!touchStartRef.current)
276
+ if (!touchStartRef.current) {
277
+ console.log('[Slideshow Swipe] touchmove: no touchStart ref');
235
278
  return;
279
+ }
236
280
  const touch = e.touches[0];
237
- if (!touch)
281
+ if (!touch) {
282
+ console.log('[Slideshow Swipe] touchmove: no touch');
238
283
  return;
284
+ }
239
285
  touchCurrentRef.current = { x: touch.clientX, y: touch.clientY };
240
286
  // Prevent default and stop propagation for horizontal swipes
241
287
  const deltaX = touch.clientX - touchStartRef.current.x;
242
288
  const deltaY = touch.clientY - touchStartRef.current.y;
243
289
  if (Math.abs(deltaX) > Math.abs(deltaY) && Math.abs(deltaX) > 10) {
290
+ console.log('[Slideshow Swipe] touchmove: horizontal swipe detected, preventing default', { deltaX, deltaY });
244
291
  e.preventDefault();
245
292
  e.stopPropagation();
246
293
  }
247
294
  };
248
295
  const handleTouchEnd = (e) => {
296
+ console.log('[Slideshow Swipe] touchend:', {
297
+ hasTouchStart: !!touchStartRef.current,
298
+ hasTouchCurrent: !!touchCurrentRef.current,
299
+ isTransitioning: state.isTransitioning,
300
+ });
249
301
  if (!touchStartRef.current || !touchCurrentRef.current) {
302
+ console.log('[Slideshow Swipe] touchend: missing refs, aborting');
250
303
  touchStartRef.current = null;
251
304
  touchCurrentRef.current = null;
252
305
  return;
253
306
  }
254
307
  // Don't process if transitioning
255
308
  if (state.isTransitioning) {
309
+ console.log('[Slideshow Swipe] touchend: transitioning, aborting');
256
310
  touchStartRef.current = null;
257
311
  touchCurrentRef.current = null;
258
312
  return;
@@ -265,16 +319,34 @@ export function Slideshow({ images, intervalMs = 5000, autoAdvance = true, trans
265
319
  const isHorizontalSwipe = Math.abs(deltaX) > Math.abs(deltaY);
266
320
  const isValidSwipe = Math.abs(deltaX) > minSwipeDistance && isHorizontalSwipe;
267
321
  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
+ });
268
333
  if (isValidSwipe && isQuickSwipe) {
269
334
  e.preventDefault();
270
335
  e.stopPropagation();
271
336
  if (deltaX > 0) {
337
+ console.log('[Slideshow Swipe] 🎯 Triggering PREV');
272
338
  singleton.prev();
273
339
  }
274
340
  else {
341
+ console.log('[Slideshow Swipe] 🎯 Triggering NEXT');
275
342
  singleton.next();
276
343
  }
277
344
  }
345
+ else {
346
+ console.log('[Slideshow Swipe] ❌ Swipe not valid:', {
347
+ reason: !isHorizontalSwipe ? 'not horizontal' : !isValidSwipe ? 'too short' : 'too slow',
348
+ });
349
+ }
278
350
  touchStartRef.current = null;
279
351
  touchCurrentRef.current = null;
280
352
  };
@@ -282,7 +354,9 @@ export function Slideshow({ images, intervalMs = 5000, autoAdvance = true, trans
282
354
  container.addEventListener('touchstart', handleTouchStart, { passive: false });
283
355
  container.addEventListener('touchmove', handleTouchMove, { passive: false });
284
356
  container.addEventListener('touchend', handleTouchEnd, { passive: false });
357
+ console.log('[Slideshow Swipe] ✅ Listeners attached successfully');
285
358
  return () => {
359
+ console.log('[Slideshow Swipe] Cleaning up listeners');
286
360
  container.removeEventListener('touchstart', handleTouchStart);
287
361
  container.removeEventListener('touchmove', handleTouchMove);
288
362
  container.removeEventListener('touchend', handleTouchEnd);
@@ -112,6 +112,16 @@ export interface CuePoint {
112
112
  data?: unknown;
113
113
  }
114
114
  export interface VideoPlayerProps {
115
+ /** Video source URL (overrides env var NEXT_PUBLIC_VIDEO_*) */
116
+ src?: string;
117
+ /** Poster/thumbnail URL (overrides env var) */
118
+ poster?: string;
119
+ /** Loop video (overrides env var, default: true) */
120
+ loop?: boolean;
121
+ /** Muted (overrides env var, default: true) */
122
+ muted?: boolean;
123
+ /** Autoplay (overrides env var, default: false) */
124
+ autoplay?: boolean;
115
125
  children?: ReactNode;
116
126
  className?: string;
117
127
  videoClassName?: string;
@@ -133,7 +143,7 @@ export interface VideoPlayerProps {
133
143
  * </VideoPlayer>
134
144
  * ```
135
145
  */
136
- export declare function VideoPlayer({ controls, children, className, videoClassName, cuePoints, onCuePoint, onTimeUpdate, }: VideoPlayerProps): React.JSX.Element;
146
+ export declare function VideoPlayer({ src: propSrc, poster: propPoster, loop: propLoop, muted: propMuted, autoplay: propAutoplay, controls, children, className, videoClassName, cuePoints, onCuePoint, onTimeUpdate, }: VideoPlayerProps): React.JSX.Element;
137
147
  /**
138
148
  * Hook to access video state and controls from within VideoPlayer children.
139
149
  * Also aliased as useVideo for compatibility.
@@ -1 +1 @@
1
- {"version":3,"file":"VideoPlayer.d.ts","sourceRoot":"","sources":["../../../src/react/overlay/VideoPlayer.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,EAOZ,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAOf,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM;QACd,cAAc,CAAC,EAAE,gBAAgB,CAAC;QAClC,UAAU,CAAC,EAAE,WAAW,CAAC;QACzB,gBAAgB,CAAC,EAAE,mBAAmB,CAAC;KACxC;CACF;AASD,UAAU,WAAW;IACnB,UAAU,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,WAAW,EAAE,CAAC,KAAK,EAAE,gBAAgB,KAAK,IAAI,CAAC;IAC/C,EAAE,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,KAAK,IAAI,CAAC;IACpE,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,iBAAiB,EAAE,MAAM,IAAI,CAAC;IAC9B,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,UAAU,SAAS;IACjB,WAAW,EAAE,MAAM,OAAO,CAAC;IAC3B,MAAM,EAAE;QACN,eAAe,EAAE,MAAM,CAAC;QACxB,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;IACF,UAAU,EAAE;QACV,aAAa,EAAE,MAAM,CAAC;QACtB,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;IACF,KAAK,MAAM,CAAC,EAAE;QAAE,YAAY,CAAC,EAAE,OAAO,CAAC;QAAC,cAAc,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,WAAW,CAAC;CAClF;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM;QACd,GAAG,EAAE,SAAS,CAAC;KAChB;CACF;AAED,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,OAAO,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,OAAO,CAAC;IACf,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAED,KAAK,aAAa,GAAG,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;AAEjD;;;;;;GAMG;AACH,cAAM,mBAAmB;IACvB,OAAO,CAAC,cAAc,CAAiC;IACvD,OAAO,CAAC,YAAY,CASlB;IACF,OAAO,CAAC,UAAU,CAAuB;IACzC,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,eAAe,CAAS;IAEhC;;OAEG;IACH,QAAQ,IAAI,gBAAgB;IAwD5B;;OAEG;IACG,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA6B7D;;OAEG;YACW,OAAO;IA2DrB;;OAEG;IACH,uBAAuB,IAAI,IAAI;IA0C/B;;OAEG;IACH,QAAQ,CAAC,SAAS,EAAE,WAAW,GAAG,IAAI;IAOtC;;OAEG;IACH,WAAW,IAAI,gBAAgB;IAK/B,IAAI,IAAI,IAAI;IAIZ,KAAK,IAAI,IAAI;IAIb,MAAM,IAAI,IAAI;IASd,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAIxB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI;IAI9B,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAI/B,OAAO,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI;IAK5B,QAAQ,IAAI,UAAU;IAItB,aAAa,CAAC,QAAQ,EAAE,aAAa,GAAG,MAAM,IAAI;IAOlD,OAAO,CAAC,WAAW;CAIpB;AA8HD,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7B,SAAS,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,QAAQ,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;CACpC;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,UAAU,CAAC;IAClB,QAAQ,EAAE,aAAa,CAAC;IACxB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;CAC7C;AAID,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,QAAQ,EAAE,CAAC;IACvB,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,KAAK,IAAI,CAAC;IAC1C,YAAY,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;CAChE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,WAAW,CAAC,EAC1B,QAAgB,EAChB,QAAQ,EACR,SAAc,EACd,cAAmB,EACnB,SAAc,EACd,UAAU,EACV,YAAY,GACb,EAAE,gBAAgB,qBAkKlB;AAED;;;GAGG;AACH,wBAAgB,aAAa,IAAI,iBAAiB,CAMjD;AAGD,eAAO,MAAM,QAAQ,sBAAgB,CAAC;AAEtC;;GAEG;AACH,wBAAgB,WAAW,CACzB,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE;IACP,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,GAAG,YAAY,CAAC;CACzB,GACL,OAAO,CAuBT;AAED;;GAEG;AACH,wBAAgB,YAAY,CAC1B,SAAS,EAAE,KAAK,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,EAAE,CAAC,EAAE,MAAM,CAAC;CACb,CAAC,EACF,OAAO,GAAE;IACP,WAAW,CAAC,EAAE,OAAO,CAAC;CAClB,GACL,IAAI,CA8BN;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,CAMzC"}
1
+ {"version":3,"file":"VideoPlayer.d.ts","sourceRoot":"","sources":["../../../src/react/overlay/VideoPlayer.tsx"],"names":[],"mappings":"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"}
@@ -370,17 +370,20 @@ const VideoContext = createContext(null);
370
370
  * </VideoPlayer>
371
371
  * ```
372
372
  */
373
- export function VideoPlayer({ controls = false, children, className = '', videoClassName = '', cuePoints = [], onCuePoint, onTimeUpdate, }) {
373
+ export function VideoPlayer({ src: propSrc, poster: propPoster, loop: propLoop, muted: propMuted, autoplay: propAutoplay, controls = false, children, className = '', videoClassName = '', cuePoints = [], onCuePoint, onTimeUpdate, }) {
374
374
  const containerRef = useRef(null);
375
375
  const videoRefProxy = useRef(null);
376
376
  const triggeredCuePointsRef = useRef(new Set());
377
377
  const lastTimeRef = useRef(0);
378
378
  const [state, setState] = useState(() => getVideoSingleton().getState());
379
379
  const [metadataError, setMetadataError] = useState(null);
380
- // Get video metadata from env vars
380
+ // Get video metadata from env vars (as fallback)
381
381
  const metadata = getVideoMetadataFromEnv();
382
- const src = metadata?.videoUrl || null;
383
- const poster = metadata?.thumbnail || undefined;
382
+ // Props override env vars
383
+ const src = propSrc || metadata?.videoUrl || null;
384
+ const poster = propPoster || metadata?.thumbnail || undefined;
385
+ const loop = propLoop ?? metadata?.loop ?? true;
386
+ const muted = propMuted ?? metadata?.muted ?? true;
384
387
  // Subscribe to singleton state changes
385
388
  useEffect(() => {
386
389
  const singleton = getVideoSingleton();
@@ -410,21 +413,21 @@ export function VideoPlayer({ controls = false, children, className = '', videoC
410
413
  singleton.attachTo(containerRef.current);
411
414
  // Update video ref proxy
412
415
  videoRefProxy.current = singleton.getVideoRef();
413
- // Set loop preference
414
- if (metadata?.loop !== undefined) {
415
- singleton.setLoop(metadata.loop);
416
- }
416
+ // Set loop preference (use resolved loop value)
417
+ singleton.setLoop(loop);
418
+ // Set muted preference
419
+ singleton.setMuted(muted);
417
420
  // Load source if available
418
421
  if (src) {
419
422
  singleton.loadSource(src, poster);
420
423
  }
421
- else if (!metadata) {
422
- setMetadataError('No video metadata found in environment variables');
424
+ else if (!metadata && !propSrc) {
425
+ setMetadataError('No video source provided');
423
426
  }
424
427
  // Set up visibility handling
425
428
  singleton.setupVisibilityHandling();
426
429
  // Note: We don't detach on unmount - that's the whole point of persistence!
427
- }, [src, poster, metadata]);
430
+ }, [src, poster, loop, muted, metadata, propSrc]);
428
431
  // Handle cue points and time updates
429
432
  useEffect(() => {
430
433
  const { currentTime, duration } = state;
@@ -4,5 +4,5 @@
4
4
  * React component that attaches to the SlideshowManager singleton.
5
5
  * The slideshow state persists across route changes.
6
6
  */
7
- export declare const persistentSlideshowTemplate = "'use client';\n\nimport { useEffect, useState, useRef, useCallback, createContext, useContext, ReactNode } from 'react';\nimport { SlideshowManager, SlideshowState, SlideImage } from '../lib/SlideshowManager';\n\n// Context to share slideshow state with overlays\ninterface SlideshowContextValue {\n state: SlideshowState;\n controls: {\n next: () => void;\n prev: () => void;\n goTo: (index: number) => void;\n pause: () => void;\n resume: () => void;\n toggle: () => void;\n };\n}\n\nconst SlideshowContext = createContext<SlideshowContextValue | null>(null);\n\nexport function useSlideshow(): SlideshowContextValue {\n const context = useContext(SlideshowContext);\n if (!context) {\n throw new Error('useSlideshow must be used within PersistentSlideshow');\n }\n return context;\n}\n\ninterface PersistentSlideshowProps {\n images: SlideImage[];\n /** Auto-advance interval in milliseconds (default: 5000) */\n intervalMs?: number;\n /** Auto-advance slides (default: true) */\n autoAdvance?: boolean;\n /** Transition type (default: 'fade') */\n transition?: 'fade' | 'slide' | 'none';\n /** Transition duration in ms (default: 500) */\n transitionDuration?: number;\n /** Show navigation dots (default: true) */\n showDots?: boolean;\n /** Show navigation arrows (default: true) */\n showArrows?: boolean;\n /** Enable swipe gestures on touch devices (default: true) */\n swipeable?: boolean;\n /** Additional class names */\n className?: string;\n /** Image container class names */\n imageClassName?: string;\n /** Children rendered as overlay */\n children?: ReactNode;\n}\n\nexport function PersistentSlideshow({\n images,\n intervalMs = 5000,\n autoAdvance = true,\n transition = 'fade',\n transitionDuration = 500,\n showDots = true,\n showArrows = true,\n swipeable = true,\n className = '',\n imageClassName = '',\n children\n}: PersistentSlideshowProps) {\n const [state, setState] = useState<SlideshowState>(SlideshowManager.getState());\n const containerRef = useRef<HTMLDivElement>(null);\n const touchStartRef = useRef<{ x: number; y: number; time: number } | null>(null);\n const touchCurrentRef = useRef<{ x: number; y: number } | null>(null);\n\n // Touch/swipe handlers using native events (React touch events are passive)\n useEffect(() => {\n const container = containerRef.current;\n if (!container || !swipeable || state.totalSlides <= 1) return;\n\n const handleTouchStart = (e: TouchEvent) => {\n const touch = e.touches[0];\n if (!touch) return;\n\n touchStartRef.current = {\n x: touch.clientX,\n y: touch.clientY,\n time: Date.now(),\n };\n touchCurrentRef.current = { x: touch.clientX, y: touch.clientY };\n };\n\n const handleTouchMove = (e: TouchEvent) => {\n if (!touchStartRef.current) return;\n const touch = e.touches[0];\n if (!touch) return;\n\n touchCurrentRef.current = { x: touch.clientX, y: touch.clientY };\n\n // Prevent default and stop propagation for horizontal swipes\n const deltaX = touch.clientX - touchStartRef.current.x;\n const deltaY = touch.clientY - touchStartRef.current.y;\n if (Math.abs(deltaX) > Math.abs(deltaY) && Math.abs(deltaX) > 10) {\n e.preventDefault();\n e.stopPropagation();\n }\n };\n\n const handleTouchEnd = (e: TouchEvent) => {\n if (!touchStartRef.current || !touchCurrentRef.current) {\n touchStartRef.current = null;\n touchCurrentRef.current = null;\n return;\n }\n\n // Don't process if transitioning\n if (state.isTransitioning) {\n touchStartRef.current = null;\n touchCurrentRef.current = null;\n return;\n }\n\n const deltaX = touchCurrentRef.current.x - touchStartRef.current.x;\n const deltaY = touchCurrentRef.current.y - touchStartRef.current.y;\n const deltaTime = Date.now() - touchStartRef.current.time;\n\n // Lower threshold for smaller tiles - 30px minimum swipe distance\n const minSwipeDistance = 30;\n const isHorizontalSwipe = Math.abs(deltaX) > Math.abs(deltaY);\n const isValidSwipe = Math.abs(deltaX) > minSwipeDistance && isHorizontalSwipe;\n const isQuickSwipe = deltaTime < 500 || Math.abs(deltaX) > 60;\n\n if (isValidSwipe && isQuickSwipe) {\n e.preventDefault();\n e.stopPropagation();\n\n if (deltaX > 0) {\n SlideshowManager.prev();\n } else {\n SlideshowManager.next();\n }\n }\n\n touchStartRef.current = null;\n touchCurrentRef.current = null;\n };\n\n // Use passive: false on all to allow preventDefault()\n container.addEventListener('touchstart', handleTouchStart, { passive: false });\n container.addEventListener('touchmove', handleTouchMove, { passive: false });\n container.addEventListener('touchend', handleTouchEnd, { passive: false });\n\n return () => {\n container.removeEventListener('touchstart', handleTouchStart);\n container.removeEventListener('touchmove', handleTouchMove);\n container.removeEventListener('touchend', handleTouchEnd);\n };\n }, [swipeable, state.totalSlides, state.isTransitioning]);\n\n useEffect(() => {\n // Initialize slideshow with images\n SlideshowManager.initialize(images, {\n intervalMs,\n transitionDuration,\n autoAdvance,\n });\n\n // Subscribe to state changes\n const unsubscribe = SlideshowManager.onStateChange(setState);\n\n return () => {\n unsubscribe();\n // Don't destroy - let slideshow persist for route changes\n };\n }, [images, intervalMs, transitionDuration, autoAdvance]);\n\n const contextValue: SlideshowContextValue = {\n state,\n controls: {\n next: () => SlideshowManager.next(),\n prev: () => SlideshowManager.prev(),\n goTo: (index) => SlideshowManager.goTo(index),\n pause: () => SlideshowManager.pause(),\n resume: () => SlideshowManager.resume(),\n toggle: () => SlideshowManager.toggle(),\n },\n };\n\n // Get transition styles\n const getTransitionStyles = (index: number): React.CSSProperties => {\n const isActive = index === state.currentIndex;\n\n switch (transition) {\n case 'fade':\n return {\n opacity: isActive ? 1 : 0,\n transition: `opacity ${transitionDuration}ms ease-in-out`,\n position: 'absolute',\n inset: 0,\n };\n case 'slide':\n const offset = (index - state.currentIndex) * 100;\n return {\n transform: `translateX(${offset}%)`,\n transition: `transform ${transitionDuration}ms ease-in-out`,\n position: 'absolute',\n inset: 0,\n };\n case 'none':\n default:\n return {\n opacity: isActive ? 1 : 0,\n position: 'absolute',\n inset: 0,\n };\n }\n };\n\n if (images.length === 0) {\n return (\n <div className={`relative w-full h-full bg-black flex items-center justify-center ${className}`}>\n <p className=\"text-white/60\">No images</p>\n </div>\n );\n }\n\n return (\n <SlideshowContext.Provider value={contextValue}>\n <div\n ref={containerRef}\n className={`relative w-full h-full bg-black overflow-hidden ${className}`}\n style={{ touchAction: swipeable && state.totalSlides > 1 ? 'none' : 'auto' }}\n >\n {/* Image container */}\n <div className=\"relative w-full h-full\">\n {state.images.map((image, index) => (\n <div\n key={`${image.url}-${index}`}\n style={getTransitionStyles(index)}\n className={imageClassName}\n >\n <img\n src={image.url}\n alt={image.alt || `Slide ${index + 1}`}\n className=\"w-full h-full object-contain\"\n loading={index === 0 ? 'eager' : 'lazy'}\n />\n </div>\n ))}\n </div>\n\n {/* Navigation arrows */}\n {showArrows && state.totalSlides > 1 && (\n <>\n <button\n onClick={() => SlideshowManager.prev()}\n disabled={state.isTransitioning}\n className=\"absolute left-2 top-1/2 -translate-y-1/2 p-2 bg-black/40 hover:bg-black/60 rounded-full text-white transition-colors disabled:opacity-50\"\n aria-label=\"Previous slide\"\n >\n <svg className=\"w-5 h-5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M15 19l-7-7 7-7\" />\n </svg>\n </button>\n <button\n onClick={() => SlideshowManager.next()}\n disabled={state.isTransitioning}\n className=\"absolute right-2 top-1/2 -translate-y-1/2 p-2 bg-black/40 hover:bg-black/60 rounded-full text-white transition-colors disabled:opacity-50\"\n aria-label=\"Next slide\"\n >\n <svg className=\"w-5 h-5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M9 5l7 7-7 7\" />\n </svg>\n </button>\n </>\n )}\n\n {/* Navigation dots */}\n {showDots && state.totalSlides > 1 && (\n <div className=\"absolute bottom-3 left-1/2 -translate-x-1/2 flex gap-1.5\">\n {state.images.map((_, index) => (\n <button\n key={index}\n onClick={() => SlideshowManager.goTo(index)}\n disabled={state.isTransitioning}\n className={`w-2 h-2 rounded-full transition-colors ${\n index === state.currentIndex\n ? 'bg-white'\n : 'bg-white/40 hover:bg-white/60'\n }`}\n aria-label={`Go to slide ${index + 1}`}\n />\n ))}\n </div>\n )}\n\n {/* Overlay children - pointer-events managed by individual OverlaySlot components */}\n <div className=\"absolute inset-0 z-10 pointer-events-none\">\n {children}\n </div>\n </div>\n </SlideshowContext.Provider>\n );\n}\n";
7
+ export declare const persistentSlideshowTemplate = "'use client';\n\nimport { useEffect, useState, useRef, useCallback, createContext, useContext, ReactNode } from 'react';\nimport { SlideshowManager, SlideshowState, SlideImage } from '../lib/SlideshowManager';\n\n// Context to share slideshow state with overlays\ninterface SlideshowContextValue {\n state: SlideshowState;\n controls: {\n next: () => void;\n prev: () => void;\n goTo: (index: number) => void;\n pause: () => void;\n resume: () => void;\n toggle: () => void;\n };\n}\n\nconst SlideshowContext = createContext<SlideshowContextValue | null>(null);\n\nexport function useSlideshow(): SlideshowContextValue {\n const context = useContext(SlideshowContext);\n if (!context) {\n throw new Error('useSlideshow must be used within PersistentSlideshow');\n }\n return context;\n}\n\ninterface PersistentSlideshowProps {\n images: SlideImage[];\n /** Auto-advance interval in milliseconds (default: 5000) */\n intervalMs?: number;\n /** Auto-advance slides (default: true) */\n autoAdvance?: boolean;\n /** Transition type (default: 'fade') */\n transition?: 'fade' | 'slide' | 'none';\n /** Transition duration in ms (default: 500) */\n transitionDuration?: number;\n /** Show navigation dots (default: true) */\n showDots?: boolean;\n /** Show navigation arrows (default: true) */\n showArrows?: boolean;\n /** Enable swipe gestures on touch devices (default: true) */\n swipeable?: boolean;\n /** Additional class names */\n className?: string;\n /** Image container class names */\n imageClassName?: string;\n /** Children rendered as overlay */\n children?: ReactNode;\n}\n\nexport function PersistentSlideshow({\n images,\n intervalMs = 5000,\n autoAdvance = true,\n transition = 'fade',\n transitionDuration = 500,\n showDots = true,\n showArrows = true,\n swipeable = true,\n className = '',\n imageClassName = '',\n children\n}: PersistentSlideshowProps) {\n const [state, setState] = useState<SlideshowState>(SlideshowManager.getState());\n const containerRef = useRef<HTMLDivElement>(null);\n const touchStartRef = useRef<{ x: number; y: number; time: number } | null>(null);\n const touchCurrentRef = useRef<{ x: number; y: number } | null>(null);\n\n // Touch/swipe handlers using native events (React touch events are passive)\n useEffect(() => {\n const container = containerRef.current;\n\n console.log('[PersistentSlideshow] Touch effect running:', {\n hasContainer: !!container,\n swipeable,\n totalSlides: state.totalSlides,\n });\n\n if (!container) {\n console.log('[PersistentSlideshow] No container ref');\n return;\n }\n if (!swipeable) {\n console.log('[PersistentSlideshow] Swipeable disabled');\n return;\n }\n if (state.totalSlides <= 1) {\n console.log('[PersistentSlideshow] Only', state.totalSlides, 'slide(s)');\n return;\n }\n\n console.log('[PersistentSlideshow] Attaching touch listeners');\n\n const handleTouchStart = (e: TouchEvent) => {\n const touch = e.touches[0];\n console.log('[PersistentSlideshow] touchstart', { hasTouch: !!touch, x: touch?.clientX, y: touch?.clientY });\n if (!touch) return;\n\n touchStartRef.current = {\n x: touch.clientX,\n y: touch.clientY,\n time: Date.now(),\n };\n touchCurrentRef.current = { x: touch.clientX, y: touch.clientY };\n };\n\n const handleTouchMove = (e: TouchEvent) => {\n if (!touchStartRef.current) return;\n const touch = e.touches[0];\n if (!touch) return;\n\n touchCurrentRef.current = { x: touch.clientX, y: touch.clientY };\n\n // Prevent default and stop propagation for horizontal swipes\n const deltaX = touch.clientX - touchStartRef.current.x;\n const deltaY = touch.clientY - touchStartRef.current.y;\n if (Math.abs(deltaX) > Math.abs(deltaY) && Math.abs(deltaX) > 10) {\n console.log('[PersistentSlideshow] touchmove horizontal', { deltaX, deltaY });\n e.preventDefault();\n e.stopPropagation();\n }\n };\n\n const handleTouchEnd = (e: TouchEvent) => {\n console.log('[PersistentSlideshow] touchend', {\n hasStart: !!touchStartRef.current,\n hasCurrent: !!touchCurrentRef.current,\n isTransitioning: state.isTransitioning,\n });\n\n if (!touchStartRef.current || !touchCurrentRef.current) {\n touchStartRef.current = null;\n touchCurrentRef.current = null;\n return;\n }\n\n // Don't process if transitioning\n if (state.isTransitioning) {\n touchStartRef.current = null;\n touchCurrentRef.current = null;\n return;\n }\n\n const deltaX = touchCurrentRef.current.x - touchStartRef.current.x;\n const deltaY = touchCurrentRef.current.y - touchStartRef.current.y;\n const deltaTime = Date.now() - touchStartRef.current.time;\n\n // Lower threshold for smaller tiles - 30px minimum swipe distance\n const minSwipeDistance = 30;\n const isHorizontalSwipe = Math.abs(deltaX) > Math.abs(deltaY);\n const isValidSwipe = Math.abs(deltaX) > minSwipeDistance && isHorizontalSwipe;\n const isQuickSwipe = deltaTime < 500 || Math.abs(deltaX) > 60;\n\n console.log('[PersistentSlideshow] touchend analysis', {\n deltaX,\n deltaY,\n deltaTime,\n isHorizontalSwipe,\n isValidSwipe,\n isQuickSwipe,\n willTrigger: isValidSwipe && isQuickSwipe,\n });\n\n if (isValidSwipe && isQuickSwipe) {\n e.preventDefault();\n e.stopPropagation();\n\n if (deltaX > 0) {\n console.log('[PersistentSlideshow] PREV');\n SlideshowManager.prev();\n } else {\n console.log('[PersistentSlideshow] NEXT');\n SlideshowManager.next();\n }\n }\n\n touchStartRef.current = null;\n touchCurrentRef.current = null;\n };\n\n // Use passive: false on all to allow preventDefault()\n container.addEventListener('touchstart', handleTouchStart, { passive: false });\n container.addEventListener('touchmove', handleTouchMove, { passive: false });\n container.addEventListener('touchend', handleTouchEnd, { passive: false });\n\n console.log('[PersistentSlideshow] Listeners attached');\n\n return () => {\n console.log('[PersistentSlideshow] Removing listeners');\n container.removeEventListener('touchstart', handleTouchStart);\n container.removeEventListener('touchmove', handleTouchMove);\n container.removeEventListener('touchend', handleTouchEnd);\n };\n }, [swipeable, state.totalSlides, state.isTransitioning]);\n\n useEffect(() => {\n // Initialize slideshow with images\n SlideshowManager.initialize(images, {\n intervalMs,\n transitionDuration,\n autoAdvance,\n });\n\n // Subscribe to state changes\n const unsubscribe = SlideshowManager.onStateChange(setState);\n\n return () => {\n unsubscribe();\n // Don't destroy - let slideshow persist for route changes\n };\n }, [images, intervalMs, transitionDuration, autoAdvance]);\n\n const contextValue: SlideshowContextValue = {\n state,\n controls: {\n next: () => SlideshowManager.next(),\n prev: () => SlideshowManager.prev(),\n goTo: (index) => SlideshowManager.goTo(index),\n pause: () => SlideshowManager.pause(),\n resume: () => SlideshowManager.resume(),\n toggle: () => SlideshowManager.toggle(),\n },\n };\n\n // Get transition styles\n const getTransitionStyles = (index: number): React.CSSProperties => {\n const isActive = index === state.currentIndex;\n\n switch (transition) {\n case 'fade':\n return {\n opacity: isActive ? 1 : 0,\n transition: `opacity ${transitionDuration}ms ease-in-out`,\n position: 'absolute',\n inset: 0,\n };\n case 'slide':\n const offset = (index - state.currentIndex) * 100;\n return {\n transform: `translateX(${offset}%)`,\n transition: `transform ${transitionDuration}ms ease-in-out`,\n position: 'absolute',\n inset: 0,\n };\n case 'none':\n default:\n return {\n opacity: isActive ? 1 : 0,\n position: 'absolute',\n inset: 0,\n };\n }\n };\n\n if (images.length === 0) {\n return (\n <div className={`relative w-full h-full bg-black flex items-center justify-center ${className}`}>\n <p className=\"text-white/60\">No images</p>\n </div>\n );\n }\n\n return (\n <SlideshowContext.Provider value={contextValue}>\n <div\n ref={containerRef}\n className={`relative w-full h-full bg-black overflow-hidden ${className}`}\n style={{ touchAction: swipeable && state.totalSlides > 1 ? 'none' : 'auto' }}\n >\n {/* Image container */}\n <div className=\"relative w-full h-full\">\n {state.images.map((image, index) => (\n <div\n key={`${image.url}-${index}`}\n style={getTransitionStyles(index)}\n className={imageClassName}\n >\n <img\n src={image.url}\n alt={image.alt || `Slide ${index + 1}`}\n className=\"w-full h-full object-contain\"\n loading={index === 0 ? 'eager' : 'lazy'}\n />\n </div>\n ))}\n </div>\n\n {/* Navigation arrows */}\n {showArrows && state.totalSlides > 1 && (\n <>\n <button\n onClick={() => SlideshowManager.prev()}\n disabled={state.isTransitioning}\n className=\"absolute left-2 top-1/2 -translate-y-1/2 p-2 bg-black/40 hover:bg-black/60 rounded-full text-white transition-colors disabled:opacity-50\"\n aria-label=\"Previous slide\"\n >\n <svg className=\"w-5 h-5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M15 19l-7-7 7-7\" />\n </svg>\n </button>\n <button\n onClick={() => SlideshowManager.next()}\n disabled={state.isTransitioning}\n className=\"absolute right-2 top-1/2 -translate-y-1/2 p-2 bg-black/40 hover:bg-black/60 rounded-full text-white transition-colors disabled:opacity-50\"\n aria-label=\"Next slide\"\n >\n <svg className=\"w-5 h-5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M9 5l7 7-7 7\" />\n </svg>\n </button>\n </>\n )}\n\n {/* Navigation dots */}\n {showDots && state.totalSlides > 1 && (\n <div className=\"absolute bottom-3 left-1/2 -translate-x-1/2 flex gap-1.5\">\n {state.images.map((_, index) => (\n <button\n key={index}\n onClick={() => SlideshowManager.goTo(index)}\n disabled={state.isTransitioning}\n className={`w-2 h-2 rounded-full transition-colors ${\n index === state.currentIndex\n ? 'bg-white'\n : 'bg-white/40 hover:bg-white/60'\n }`}\n aria-label={`Go to slide ${index + 1}`}\n />\n ))}\n </div>\n )}\n\n {/* Overlay children - pointer-events managed by individual OverlaySlot components */}\n <div className=\"absolute inset-0 z-10 pointer-events-none\">\n {children}\n </div>\n </div>\n </SlideshowContext.Provider>\n );\n}\n";
8
8
  //# sourceMappingURL=PersistentSlideshow.tsx.template.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"PersistentSlideshow.tsx.template.d.ts","sourceRoot":"","sources":["../../../src/templates/slideshow/PersistentSlideshow.tsx.template.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,eAAO,MAAM,2BAA2B,8qUA2SvC,CAAC"}
1
+ {"version":3,"file":"PersistentSlideshow.tsx.template.d.ts","sourceRoot":"","sources":["../../../src/templates/slideshow/PersistentSlideshow.tsx.template.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,eAAO,MAAM,2BAA2B,ukXAsVvC,CAAC"}
@@ -77,10 +77,31 @@ export function PersistentSlideshow({
77
77
  // Touch/swipe handlers using native events (React touch events are passive)
78
78
  useEffect(() => {
79
79
  const container = containerRef.current;
80
- if (!container || !swipeable || state.totalSlides <= 1) return;
80
+
81
+ console.log('[PersistentSlideshow] Touch effect running:', {
82
+ hasContainer: !!container,
83
+ swipeable,
84
+ totalSlides: state.totalSlides,
85
+ });
86
+
87
+ if (!container) {
88
+ console.log('[PersistentSlideshow] No container ref');
89
+ return;
90
+ }
91
+ if (!swipeable) {
92
+ console.log('[PersistentSlideshow] Swipeable disabled');
93
+ return;
94
+ }
95
+ if (state.totalSlides <= 1) {
96
+ console.log('[PersistentSlideshow] Only', state.totalSlides, 'slide(s)');
97
+ return;
98
+ }
99
+
100
+ console.log('[PersistentSlideshow] Attaching touch listeners');
81
101
 
82
102
  const handleTouchStart = (e: TouchEvent) => {
83
103
  const touch = e.touches[0];
104
+ console.log('[PersistentSlideshow] touchstart', { hasTouch: !!touch, x: touch?.clientX, y: touch?.clientY });
84
105
  if (!touch) return;
85
106
 
86
107
  touchStartRef.current = {
@@ -102,12 +123,19 @@ export function PersistentSlideshow({
102
123
  const deltaX = touch.clientX - touchStartRef.current.x;
103
124
  const deltaY = touch.clientY - touchStartRef.current.y;
104
125
  if (Math.abs(deltaX) > Math.abs(deltaY) && Math.abs(deltaX) > 10) {
126
+ console.log('[PersistentSlideshow] touchmove horizontal', { deltaX, deltaY });
105
127
  e.preventDefault();
106
128
  e.stopPropagation();
107
129
  }
108
130
  };
109
131
 
110
132
  const handleTouchEnd = (e: TouchEvent) => {
133
+ console.log('[PersistentSlideshow] touchend', {
134
+ hasStart: !!touchStartRef.current,
135
+ hasCurrent: !!touchCurrentRef.current,
136
+ isTransitioning: state.isTransitioning,
137
+ });
138
+
111
139
  if (!touchStartRef.current || !touchCurrentRef.current) {
112
140
  touchStartRef.current = null;
113
141
  touchCurrentRef.current = null;
@@ -131,13 +159,25 @@ export function PersistentSlideshow({
131
159
  const isValidSwipe = Math.abs(deltaX) > minSwipeDistance && isHorizontalSwipe;
132
160
  const isQuickSwipe = deltaTime < 500 || Math.abs(deltaX) > 60;
133
161
 
162
+ console.log('[PersistentSlideshow] touchend analysis', {
163
+ deltaX,
164
+ deltaY,
165
+ deltaTime,
166
+ isHorizontalSwipe,
167
+ isValidSwipe,
168
+ isQuickSwipe,
169
+ willTrigger: isValidSwipe && isQuickSwipe,
170
+ });
171
+
134
172
  if (isValidSwipe && isQuickSwipe) {
135
173
  e.preventDefault();
136
174
  e.stopPropagation();
137
175
 
138
176
  if (deltaX > 0) {
177
+ console.log('[PersistentSlideshow] PREV');
139
178
  SlideshowManager.prev();
140
179
  } else {
180
+ console.log('[PersistentSlideshow] NEXT');
141
181
  SlideshowManager.next();
142
182
  }
143
183
  }
@@ -151,7 +191,10 @@ export function PersistentSlideshow({
151
191
  container.addEventListener('touchmove', handleTouchMove, { passive: false });
152
192
  container.addEventListener('touchend', handleTouchEnd, { passive: false });
153
193
 
194
+ console.log('[PersistentSlideshow] Listeners attached');
195
+
154
196
  return () => {
197
+ console.log('[PersistentSlideshow] Removing listeners');
155
198
  container.removeEventListener('touchstart', handleTouchStart);
156
199
  container.removeEventListener('touchmove', handleTouchMove);
157
200
  container.removeEventListener('touchend', handleTouchEnd);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thewhateverapp/tile-sdk",
3
- "version": "0.13.14",
3
+ "version": "0.13.16",
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",