@thewhateverapp/tile-sdk 0.12.2 → 0.12.4

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.
@@ -59,28 +59,14 @@ export interface CuePoint {
59
59
  data?: unknown;
60
60
  }
61
61
  export interface VideoPlayerProps {
62
- /**
63
- * Video source URL (HLS playlist or direct video URL).
64
- * If not provided, VideoPlayer will auto-fetch from the tile's metadata
65
- * using the tileId from NEXT_PUBLIC_TILE_ID environment variable.
66
- */
67
- src?: string;
68
- /** Auto-start playback (default: true, or from tile metadata) */
69
- autoplay?: boolean;
70
- /** Loop video (default: false, but true in preview mode) */
71
- loop?: boolean;
72
- /** Start muted (default: true for autoplay compliance) */
73
- muted?: boolean;
74
- /** Poster image URL (auto-fetched from tile metadata if not provided) */
75
- poster?: string;
76
- /** Show native controls (default: false) */
77
- controls?: boolean;
78
62
  /** Children rendered as overlay */
79
63
  children?: ReactNode;
80
64
  /** Additional class names */
81
65
  className?: string;
82
66
  /** Video wrapper class names */
83
67
  videoClassName?: string;
68
+ /** Show native controls (default: false) */
69
+ controls?: boolean;
84
70
  /** Cue points for time-based triggers */
85
71
  cuePoints?: CuePoint[];
86
72
  /** Callback when a cue point is reached */
@@ -93,13 +79,20 @@ export interface VideoPlayerProps {
93
79
  * Provides video state and controls to child overlays via context.
94
80
  *
95
81
  * Features:
82
+ * - Auto-fetches video URL from tile metadata (no src prop needed!)
96
83
  * - HLS streaming with automatic quality adaptation
97
84
  * - Time-based cue points for triggering overlays
98
85
  * - Visibility-aware playback (plays when visible, pauses when hidden)
99
- * - Auto-loops in preview mode for testing
100
- * - Auto-fetches video URL from tile metadata when src is not provided
86
+ * - Auto-loops by default (can be disabled via tile metadata)
87
+ *
88
+ * Usage:
89
+ * ```tsx
90
+ * <VideoPlayer className="w-full h-full">
91
+ * <YourOverlay />
92
+ * </VideoPlayer>
93
+ * ```
101
94
  */
102
- export declare function VideoPlayer({ src: srcProp, autoplay: autoplayProp, loop: loopProp, muted: mutedProp, poster: posterProp, controls, children, className, videoClassName, cuePoints, onCuePoint, onTimeUpdate, }: VideoPlayerProps): React.JSX.Element;
95
+ export declare function VideoPlayer({ controls, children, className, videoClassName, cuePoints, onCuePoint, onTimeUpdate, }: VideoPlayerProps): React.JSX.Element;
103
96
  /**
104
97
  * Hook to access video state and controls from within VideoPlayer children.
105
98
  */
@@ -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;AA0Ef,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;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,WAAW,CAAC,EAC1B,QAAgB,EAChB,QAAQ,EACR,SAAc,EACd,cAAmB,EACnB,SAAc,EACd,UAAU,EACV,YAAY,GACb,EAAE,gBAAgB,qBAmWlB;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"}
@@ -38,24 +38,25 @@ async function fetchVideoMetadata(tileId) {
38
38
  }
39
39
  }
40
40
  const VideoContext = createContext(null);
41
- // Detect if we're in preview mode (tile-preview sets this global)
42
- function isPreviewMode() {
43
- if (typeof window === 'undefined')
44
- return false;
45
- return !!window.__PREVIEW_SESSION_ID__;
46
- }
47
41
  /**
48
42
  * VideoPlayer component with HLS streaming support.
49
43
  * Provides video state and controls to child overlays via context.
50
44
  *
51
45
  * Features:
46
+ * - Auto-fetches video URL from tile metadata (no src prop needed!)
52
47
  * - HLS streaming with automatic quality adaptation
53
48
  * - Time-based cue points for triggering overlays
54
49
  * - Visibility-aware playback (plays when visible, pauses when hidden)
55
- * - Auto-loops in preview mode for testing
56
- * - Auto-fetches video URL from tile metadata when src is not provided
50
+ * - Auto-loops by default (can be disabled via tile metadata)
51
+ *
52
+ * Usage:
53
+ * ```tsx
54
+ * <VideoPlayer className="w-full h-full">
55
+ * <YourOverlay />
56
+ * </VideoPlayer>
57
+ * ```
57
58
  */
58
- export function VideoPlayer({ src: srcProp, autoplay: autoplayProp, loop: loopProp, muted: mutedProp, poster: posterProp, controls = false, children, className = '', videoClassName = '', cuePoints = [], onCuePoint, onTimeUpdate, }) {
59
+ export function VideoPlayer({ controls = false, children, className = '', videoClassName = '', cuePoints = [], onCuePoint, onTimeUpdate, }) {
59
60
  const videoRef = useRef(null);
60
61
  const hlsRef = useRef(null);
61
62
  const triggeredCuePointsRef = useRef(new Set());
@@ -63,15 +64,11 @@ export function VideoPlayer({ src: srcProp, autoplay: autoplayProp, loop: loopPr
63
64
  // State for auto-fetched metadata
64
65
  const [metadata, setMetadata] = useState(null);
65
66
  const [metadataError, setMetadataError] = useState(null);
66
- // Auto-fetch video metadata if no src provided
67
+ // Auto-fetch video metadata from tile
67
68
  useEffect(() => {
68
- if (srcProp) {
69
- // src provided directly, no need to fetch
70
- return;
71
- }
72
69
  const tileId = getTileId();
73
70
  if (!tileId) {
74
- setMetadataError('No video source: src prop not provided and NEXT_PUBLIC_TILE_ID not set');
71
+ setMetadataError('NEXT_PUBLIC_TILE_ID not set');
75
72
  return;
76
73
  }
77
74
  fetchVideoMetadata(tileId).then((data) => {
@@ -87,14 +84,14 @@ export function VideoPlayer({ src: srcProp, autoplay: autoplayProp, loop: loopPr
87
84
  setMetadataError('Failed to fetch video metadata');
88
85
  }
89
86
  });
90
- }, [srcProp]);
91
- // Resolve actual values from props or metadata
92
- const src = srcProp || metadata?.videoUrl || null;
93
- const autoplay = autoplayProp ?? metadata?.autoplay ?? true;
94
- const muted = mutedProp ?? metadata?.muted ?? true;
95
- const poster = posterProp || metadata?.thumbnail || undefined;
96
- // Auto-enable loop in preview mode unless explicitly set to false
97
- const loop = loopProp ?? metadata?.loop ?? isPreviewMode();
87
+ }, []);
88
+ // Get values from metadata
89
+ const src = metadata?.videoUrl || null;
90
+ const autoplay = metadata?.autoplay ?? true;
91
+ const muted = metadata?.muted ?? false;
92
+ const poster = metadata?.thumbnail || undefined;
93
+ // Default to loop enabled (videos almost always loop)
94
+ const loop = metadata?.loop ?? true;
98
95
  const [state, setState] = useState({
99
96
  isPlaying: false,
100
97
  currentTime: 0,
@@ -277,9 +274,9 @@ export function VideoPlayer({ src: srcProp, autoplay: autoplayProp, loop: loopPr
277
274
  video.removeEventListener('loadeddata', handleLoadedData);
278
275
  };
279
276
  }, [onTimeUpdate, onCuePoint, cuePoints]);
280
- // Visibility handling - play/pause AND mute/unmute based on tile visibility
281
- // Enables TikTok-style preloaded video tiles that only play when visible
282
- // Audio is controlled here to ensure only the visible tile has sound
277
+ // Visibility handling - play/pause AND mute/unmute based on tile visibility.
278
+ // Enables TikTok-style preloaded video tiles that only play when visible.
279
+ // Audio is controlled here to ensure only the visible tile has sound.
283
280
  useEffect(() => {
284
281
  const video = videoRef.current;
285
282
  if (!video || !autoplay)
@@ -304,8 +301,18 @@ export function VideoPlayer({ src: srcProp, autoplay: autoplayProp, loop: loopPr
304
301
  video.pause();
305
302
  }
306
303
  });
307
- // Check initial visibility state
308
- if (!bridge.isVisible()) {
304
+ // Check initial visibility state and set audio accordingly
305
+ if (bridge.isVisible()) {
306
+ // If visible on mount, unmute so sound plays
307
+ // This handles the race condition where the first tile loads visible
308
+ video.muted = false;
309
+ // If unmuted autoplay fails, fall back to muted
310
+ video.play().catch(() => {
311
+ video.muted = true;
312
+ video.play().catch(() => { });
313
+ });
314
+ }
315
+ else {
309
316
  // If not visible on mount, ensure muted and paused
310
317
  video.muted = true;
311
318
  video.pause();
@@ -344,7 +351,7 @@ export function VideoPlayer({ src: srcProp, autoplay: autoplayProp, loop: loopPr
344
351
  display: none !important;
345
352
  }
346
353
  `),
347
- state.isLoading && (React.createElement("div", { className: "absolute inset-0 flex items-center justify-center" },
354
+ (state.isLoading || (!src && !metadataError)) && (React.createElement("div", { className: "absolute inset-0 flex items-center justify-center" },
348
355
  React.createElement("div", { className: "w-10 h-10 border-3 border-white/30 border-t-white rounded-full animate-spin" }))),
349
356
  (state.error || metadataError) && (React.createElement("div", { className: "absolute inset-0 flex items-center justify-center text-white/80" },
350
357
  React.createElement("p", null, state.error || metadataError))),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thewhateverapp/tile-sdk",
3
- "version": "0.12.2",
3
+ "version": "0.12.4",
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",