@thewhateverapp/tile-sdk 0.13.18 → 0.13.19

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.
@@ -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;;;;;;OAMG;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;IAqCR;;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,qBA8PhB;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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"}
@@ -239,10 +239,13 @@ export function Slideshow({ images, intervalMs = 5000, autoAdvance = true, trans
239
239
  resume: useCallback(() => singleton.resume(), []),
240
240
  toggle: useCallback(() => singleton.toggle(), []),
241
241
  };
242
- // Touch/swipe handlers using native events (React touch events are passive)
242
+ // Touch/swipe handlers with visual drag feedback
243
243
  // NOTE: We attach listeners once and check singleton state directly to avoid
244
244
  // stale closure issues and listener teardown during swipe sequences.
245
245
  const touchCurrentRef = useRef(null);
246
+ const [dragOffset, setDragOffset] = useState(0); // Pixels dragged horizontally
247
+ const [isDragging, setIsDragging] = useState(false);
248
+ const containerWidthRef = useRef(0);
246
249
  useEffect(() => {
247
250
  const container = containerRef.current;
248
251
  if (!container || !swipeable) {
@@ -257,12 +260,16 @@ export function Slideshow({ images, intervalMs = 5000, autoAdvance = true, trans
257
260
  const touch = e.touches[0];
258
261
  if (!touch)
259
262
  return;
263
+ // Store container width for percentage calculations
264
+ containerWidthRef.current = container.offsetWidth;
260
265
  touchStartRef.current = {
261
266
  x: touch.clientX,
262
267
  y: touch.clientY,
263
268
  time: Date.now(),
264
269
  };
265
270
  touchCurrentRef.current = { x: touch.clientX, y: touch.clientY };
271
+ setIsDragging(true);
272
+ setDragOffset(0);
266
273
  };
267
274
  const handleTouchMove = (e) => {
268
275
  if (!touchStartRef.current)
@@ -271,24 +278,41 @@ export function Slideshow({ images, intervalMs = 5000, autoAdvance = true, trans
271
278
  if (!touch)
272
279
  return;
273
280
  touchCurrentRef.current = { x: touch.clientX, y: touch.clientY };
274
- // Prevent default for horizontal swipes to avoid scroll interference
275
281
  const deltaX = touch.clientX - touchStartRef.current.x;
276
282
  const deltaY = touch.clientY - touchStartRef.current.y;
277
- if (Math.abs(deltaX) > Math.abs(deltaY) && Math.abs(deltaX) > 10) {
283
+ // Only start visual drag if horizontal movement dominates
284
+ if (Math.abs(deltaX) > Math.abs(deltaY) && Math.abs(deltaX) > 5) {
278
285
  e.preventDefault();
279
286
  e.stopPropagation();
287
+ // Apply resistance at edges (can't drag past first/last)
288
+ const currentIndex = swipeSingleton.getState().currentIndex;
289
+ const totalSlides = swipeSingleton.getState().totalSlides;
290
+ const isAtStart = currentIndex === 0 && deltaX > 0;
291
+ const isAtEnd = currentIndex === totalSlides - 1 && deltaX < 0;
292
+ if (isAtStart || isAtEnd) {
293
+ // Rubber band effect - reduced movement at edges
294
+ setDragOffset(deltaX * 0.3);
295
+ }
296
+ else {
297
+ setDragOffset(deltaX);
298
+ }
280
299
  }
281
300
  };
282
301
  const handleTouchEnd = (e) => {
302
+ const wasDragging = !!touchStartRef.current;
283
303
  if (!touchStartRef.current || !touchCurrentRef.current) {
284
304
  touchStartRef.current = null;
285
305
  touchCurrentRef.current = null;
306
+ setIsDragging(false);
307
+ setDragOffset(0);
286
308
  return;
287
309
  }
288
310
  // Check transitioning from singleton directly (not stale closure)
289
311
  if (swipeSingleton.getState().isTransitioning) {
290
312
  touchStartRef.current = null;
291
313
  touchCurrentRef.current = null;
314
+ setIsDragging(false);
315
+ setDragOffset(0);
292
316
  return;
293
317
  }
294
318
  const deltaX = touchCurrentRef.current.x - touchStartRef.current.x;
@@ -299,6 +323,9 @@ export function Slideshow({ images, intervalMs = 5000, autoAdvance = true, trans
299
323
  const isHorizontalSwipe = Math.abs(deltaX) > Math.abs(deltaY);
300
324
  const isValidSwipe = Math.abs(deltaX) > minSwipeDistance && isHorizontalSwipe;
301
325
  const isQuickSwipe = deltaTime < 500 || Math.abs(deltaX) > 60;
326
+ // Reset drag state before triggering transition
327
+ setIsDragging(false);
328
+ setDragOffset(0);
302
329
  if (isValidSwipe && isQuickSwipe) {
303
330
  e.preventDefault();
304
331
  e.stopPropagation();
@@ -312,19 +339,77 @@ export function Slideshow({ images, intervalMs = 5000, autoAdvance = true, trans
312
339
  touchStartRef.current = null;
313
340
  touchCurrentRef.current = null;
314
341
  };
342
+ // Also handle touch cancel (e.g., incoming call)
343
+ const handleTouchCancel = () => {
344
+ touchStartRef.current = null;
345
+ touchCurrentRef.current = null;
346
+ setIsDragging(false);
347
+ setDragOffset(0);
348
+ };
315
349
  // Use passive: false to allow preventDefault()
316
350
  container.addEventListener('touchstart', handleTouchStart, { passive: false });
317
351
  container.addEventListener('touchmove', handleTouchMove, { passive: false });
318
352
  container.addEventListener('touchend', handleTouchEnd, { passive: false });
353
+ container.addEventListener('touchcancel', handleTouchCancel, { passive: false });
319
354
  return () => {
320
355
  container.removeEventListener('touchstart', handleTouchStart);
321
356
  container.removeEventListener('touchmove', handleTouchMove);
322
357
  container.removeEventListener('touchend', handleTouchEnd);
358
+ container.removeEventListener('touchcancel', handleTouchCancel);
323
359
  };
324
360
  }, [swipeable]); // Only re-attach if swipeable changes - check singleton for dynamic state
325
- // Get transition styles
361
+ // Get transition styles with drag offset support
326
362
  const getTransitionStyles = (index) => {
327
363
  const isActive = index === state.currentIndex;
364
+ const isPrev = index === state.currentIndex - 1 ||
365
+ (state.currentIndex === 0 && index === state.totalSlides - 1); // Wrap around
366
+ const isNext = index === state.currentIndex + 1 ||
367
+ (state.currentIndex === state.totalSlides - 1 && index === 0); // Wrap around
368
+ // During drag, use slide-style movement for visual feedback
369
+ if (isDragging && swipeable && state.totalSlides > 1) {
370
+ const containerWidth = containerWidthRef.current || 256;
371
+ const dragPercent = (dragOffset / containerWidth) * 100;
372
+ // Show current, prev, and next slides during drag
373
+ if (isActive) {
374
+ return {
375
+ transform: `translateX(${dragPercent}%)`,
376
+ transition: 'none', // Immediate response during drag
377
+ position: 'absolute',
378
+ inset: 0,
379
+ zIndex: 2,
380
+ };
381
+ }
382
+ else if (isPrev && dragOffset > 0) {
383
+ // Dragging right - show previous slide coming in from left
384
+ return {
385
+ transform: `translateX(${-100 + dragPercent}%)`,
386
+ transition: 'none',
387
+ position: 'absolute',
388
+ inset: 0,
389
+ zIndex: 1,
390
+ };
391
+ }
392
+ else if (isNext && dragOffset < 0) {
393
+ // Dragging left - show next slide coming in from right
394
+ return {
395
+ transform: `translateX(${100 + dragPercent}%)`,
396
+ transition: 'none',
397
+ position: 'absolute',
398
+ inset: 0,
399
+ zIndex: 1,
400
+ };
401
+ }
402
+ else {
403
+ // Hide other slides during drag
404
+ return {
405
+ opacity: 0,
406
+ position: 'absolute',
407
+ inset: 0,
408
+ zIndex: 0,
409
+ };
410
+ }
411
+ }
412
+ // Normal transition styles (when not dragging)
328
413
  switch (transition) {
329
414
  case 'fade':
330
415
  return {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thewhateverapp/tile-sdk",
3
- "version": "0.13.18",
3
+ "version": "0.13.19",
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",