@thewhateverapp/tile-sdk 0.12.14 → 0.12.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.
@@ -1 +1 @@
1
- {"version":3,"file":"VideoPlayer.d.ts","sourceRoot":"","sources":["../../../src/react/overlay/VideoPlayer.tsx"],"names":[],"mappings":"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"}
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;AA6Ff,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;AAGD,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,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,kDAAkD;IAClD,IAAI,EAAE,MAAM,CAAC;IACb,0CAA0C;IAC1C,EAAE,EAAE,MAAM,CAAC;IACX,4CAA4C;IAC5C,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,gBAAgB;IAC/B,mCAAmC;IACnC,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,6BAA6B;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gCAAgC;IAChC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,4CAA4C;IAC5C,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,yCAAyC;IACzC,SAAS,CAAC,EAAE,QAAQ,EAAE,CAAC;IACvB,2CAA2C;IAC3C,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,KAAK,IAAI,CAAC;IAC1C,0DAA0D;IAC1D,YAAY,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;CAChE;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,WAAW,CAAC,EAC1B,QAAgB,EAChB,QAAQ,EACR,SAAc,EACd,cAAmB,EACnB,SAAc,EACd,UAAU,EACV,YAAY,GACb,EAAE,gBAAgB,qBAialB;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,iBAAiB,CAMjD;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,WAAW,CACzB,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE;IACP,qDAAqD;IACrD,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,uEAAuE;IACvE,IAAI,CAAC,EAAE,MAAM,GAAG,YAAY,CAAC;CACzB,GACL,OAAO,CAyBT;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,YAAY,CAC1B,SAAS,EAAE,KAAK,CAAC;IACf,sCAAsC;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,+CAA+C;IAC/C,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,6CAA6C;IAC7C,EAAE,CAAC,EAAE,MAAM,CAAC;CACb,CAAC,EACF,OAAO,GAAE;IACP,sDAAsD;IACtD,WAAW,CAAC,EAAE,OAAO,CAAC;CAClB,GACL,IAAI,CAgCN;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,CAMzC"}
@@ -46,10 +46,12 @@ function getVideoMetadataFromEnv() {
46
46
  ? parseFloat(process.env.NEXT_PUBLIC_VIDEO_DURATION)
47
47
  : null,
48
48
  title: process.env.NEXT_PUBLIC_VIDEO_TITLE || null,
49
- // Default to true for autoplay and muted (better for mobile autoplay policies)
50
- autoplay: process.env.NEXT_PUBLIC_VIDEO_AUTOPLAY !== 'false',
49
+ // Default to false for autoplay - wait for visibility message from parent
50
+ // This prevents offscreen tiles from playing in TikTok-style feeds
51
+ autoplay: process.env.NEXT_PUBLIC_VIDEO_AUTOPLAY === 'true',
51
52
  // Default to true for loop (most video tiles loop)
52
53
  loop: process.env.NEXT_PUBLIC_VIDEO_LOOP !== 'false',
54
+ // Default to true for muted - start muted, unmute on visibility
53
55
  muted: process.env.NEXT_PUBLIC_VIDEO_MUTED !== 'false',
54
56
  };
55
57
  }
@@ -109,8 +111,10 @@ export function VideoPlayer({ controls = false, children, className = '', videoC
109
111
  }, []);
110
112
  // Get values from metadata
111
113
  const src = metadata?.videoUrl || null;
112
- const autoplay = metadata?.autoplay ?? true;
113
- // Default to true for muted - browsers require muted for autoplay to work without user interaction
114
+ // Default to false for autoplay - videos wait for visibility message from parent
115
+ // This prevents offscreen tiles from playing in TikTok-style feeds
116
+ const autoplay = metadata?.autoplay ?? false;
117
+ // Default to true for muted - videos start muted until visibility says otherwise
114
118
  const muted = metadata?.muted ?? true;
115
119
  const poster = metadata?.thumbnail || undefined;
116
120
  // Default to loop enabled (videos almost always loop)
@@ -343,72 +347,64 @@ export function VideoPlayer({ controls = false, children, className = '', videoC
343
347
  };
344
348
  }, [onTimeUpdate, onCuePoint, cuePoints]);
345
349
  // Visibility handling - play/pause AND mute/unmute based on tile visibility.
346
- // Enables TikTok-style preloaded video tiles that only play when visible.
347
- // Audio is controlled here to ensure only the visible tile has sound.
348
- // IMPORTANT: muted state is now sent atomically with visibility from the parent
349
- // to prevent race conditions between visibility and mute messages.
350
+ // Videos start paused and only play when parent sends visible: true.
351
+ // This enables TikTok-style feeds where only the active tile plays.
352
+ // IMPORTANT: Videos default to autoplay=false, muted=true.
353
+ // Parent controls playback via visibility messages.
350
354
  useEffect(() => {
351
355
  const video = videoRef.current;
352
- if (!video || !autoplay)
356
+ if (!video)
353
357
  return;
354
358
  try {
355
359
  const bridge = getTileBridge();
356
360
  // Handle visibility changes from parent (mobile app)
357
- // Now includes muted state for atomic updates (no race conditions)
358
361
  const unsubscribe = bridge.onVisibilityChange((visibilityState) => {
359
- // Use the muted field from the visibility state (sent atomically by parent)
360
- // This prevents race conditions where visibility arrives before mute state
361
- const shouldMute = visibilityState.muted ?? !visibilityState.visible;
362
- if (visibilityState.visible && !shouldMute) {
363
- // Tile became visible and should be unmuted - unmute and play
364
- // Unmute first so audio starts with the video
362
+ if (visibilityState.visible) {
363
+ // Tile is visible - play video, unmute audio
365
364
  video.muted = false;
366
365
  video.play().catch(() => {
367
- // If play fails (e.g., autoplay policy), keep muted and retry
366
+ // If unmuted play fails (browser policy), retry muted
368
367
  video.muted = true;
369
368
  video.play().catch(() => { });
370
369
  });
371
370
  }
372
- else if (visibilityState.visible && shouldMute) {
373
- // Tile is visible but should be muted (e.g., transitioning)
374
- video.muted = true;
375
- video.play().catch(() => { });
376
- }
377
371
  else {
378
- // Tile became hidden - mute first (immediate audio stop), then pause
372
+ // Tile is hidden - pause video, mute audio
379
373
  video.muted = true;
380
374
  video.pause();
381
375
  }
382
376
  });
383
- // Check initial visibility state and set audio accordingly
377
+ // Check initial visibility state
384
378
  const initialState = bridge.getVisibilityState();
385
- const initialMuted = initialState.muted ?? !initialState.visible;
386
- if (initialState.visible && !initialMuted) {
387
- // If visible and unmuted on mount, unmute so sound plays
388
- // This handles the race condition where the first tile loads visible
379
+ if (initialState.visible) {
380
+ // Visible on mount - start playing
389
381
  video.muted = false;
390
- // If unmuted autoplay fails, fall back to muted
391
382
  video.play().catch(() => {
392
383
  video.muted = true;
393
384
  video.play().catch(() => { });
394
385
  });
395
386
  }
396
387
  else {
397
- // If not visible or muted on mount, ensure muted and paused
388
+ // Not visible on mount - ensure paused and muted
398
389
  video.muted = true;
399
- if (!initialState.visible) {
400
- video.pause();
401
- }
390
+ video.pause();
402
391
  }
403
392
  return () => {
404
393
  unsubscribe();
405
394
  };
406
395
  }
407
396
  catch {
408
- // Bridge not available (e.g., in SSR or outside TileProvider)
409
- // Video will just use autoplay behavior (muted)
397
+ // Bridge not available (standalone tile, not in feed)
398
+ // For standalone tiles, play with audio if visible
399
+ if (!document.hidden) {
400
+ video.muted = false;
401
+ video.play().catch(() => {
402
+ video.muted = true;
403
+ video.play().catch(() => { });
404
+ });
405
+ }
410
406
  }
411
- }, [autoplay]);
407
+ }, []);
412
408
  const contextValue = {
413
409
  state,
414
410
  controls: { play, pause, toggle, seek, setVolume, setMuted },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thewhateverapp/tile-sdk",
3
- "version": "0.12.14",
3
+ "version": "0.12.15",
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",