@dialtribe/react-sdk 0.1.0-alpha.10 → 0.1.0-alpha.12

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,25 +1,27 @@
1
1
  'use strict';
2
2
 
3
- var react = require('react');
3
+ var React2 = require('react');
4
4
  var jsxRuntime = require('react/jsx-runtime');
5
5
  var ReactPlayer = require('react-player');
6
+ var reactDom = require('react-dom');
6
7
 
7
8
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
8
9
 
10
+ var React2__default = /*#__PURE__*/_interopDefault(React2);
9
11
  var ReactPlayer__default = /*#__PURE__*/_interopDefault(ReactPlayer);
10
12
 
11
- // src/context/DialTribeProvider.tsx
12
- var DialTribeContext = react.createContext(null);
13
- function DialTribeProvider({
13
+ // src/context/DialtribeProvider.tsx
14
+ var DialtribeContext = React2.createContext(null);
15
+ function DialtribeProvider({
14
16
  sessionToken: initialToken,
15
17
  onTokenRefresh,
16
18
  onTokenExpired,
17
19
  apiBaseUrl,
18
20
  children
19
21
  }) {
20
- const [sessionToken, setSessionTokenState] = react.useState(initialToken);
21
- const [isExpired, setIsExpired] = react.useState(false);
22
- const setSessionToken = react.useCallback(
22
+ const [sessionToken, setSessionTokenState] = React2.useState(initialToken);
23
+ const [isExpired, setIsExpired] = React2.useState(false);
24
+ const setSessionToken = React2.useCallback(
23
25
  (newToken, expiresAt) => {
24
26
  setSessionTokenState(newToken);
25
27
  setIsExpired(false);
@@ -29,11 +31,11 @@ function DialTribeProvider({
29
31
  },
30
32
  [onTokenRefresh]
31
33
  );
32
- const markExpired = react.useCallback(() => {
34
+ const markExpired = React2.useCallback(() => {
33
35
  setIsExpired(true);
34
36
  onTokenExpired?.();
35
37
  }, [onTokenExpired]);
36
- react.useEffect(() => {
38
+ React2.useEffect(() => {
37
39
  if (initialToken !== sessionToken) {
38
40
  setSessionTokenState(initialToken);
39
41
  setIsExpired(false);
@@ -46,22 +48,22 @@ function DialTribeProvider({
46
48
  markExpired,
47
49
  apiBaseUrl
48
50
  };
49
- return /* @__PURE__ */ jsxRuntime.jsx(DialTribeContext.Provider, { value, children });
51
+ return /* @__PURE__ */ jsxRuntime.jsx(DialtribeContext.Provider, { value, children });
50
52
  }
51
- function useDialTribe() {
52
- const context = react.useContext(DialTribeContext);
53
+ function useDialtribe() {
54
+ const context = React2.useContext(DialtribeContext);
53
55
  if (!context) {
54
56
  throw new Error(
55
- 'useDialTribe must be used within a DialTribeProvider. Wrap your app with <DialTribeProvider sessionToken="sess_xxx">...</DialTribeProvider>'
57
+ 'useDialtribe must be used within a DialtribeProvider. Wrap your app with <DialtribeProvider sessionToken="sess_xxx">...</DialtribeProvider>'
56
58
  );
57
59
  }
58
60
  return context;
59
61
  }
60
- function useDialTribeOptional() {
61
- return react.useContext(DialTribeContext);
62
+ function useDialtribeOptional() {
63
+ return React2.useContext(DialtribeContext);
62
64
  }
63
65
 
64
- // src/client/DialTribeClient.ts
66
+ // src/client/DialtribeClient.ts
65
67
  function getDefaultApiBaseUrl() {
66
68
  if (typeof process !== "undefined" && process.env?.NEXT_PUBLIC_DIALTRIBE_API_URL) {
67
69
  return process.env.NEXT_PUBLIC_DIALTRIBE_API_URL;
@@ -75,18 +77,19 @@ function getEndpoints(baseUrl = DIALTRIBE_API_BASE) {
75
77
  broadcast: (id) => `${baseUrl}/broadcasts/${id}`,
76
78
  contentPlay: `${baseUrl}/content/play`,
77
79
  presignedUrl: `${baseUrl}/media/presigned-url`,
78
- sessionStart: `${baseUrl}/session/start`,
79
- sessionPing: `${baseUrl}/session/ping`
80
+ audienceStart: `${baseUrl}/audiences/start`,
81
+ audiencePing: `${baseUrl}/audiences/ping`,
82
+ sessionPing: `${baseUrl}/sessions/ping`
80
83
  };
81
84
  }
82
85
  var ENDPOINTS = getEndpoints();
83
- var DialTribeClient = class {
86
+ var DialtribeClient = class {
84
87
  constructor(config) {
85
88
  this.config = config;
86
89
  this.endpoints = config.apiBaseUrl ? getEndpoints(config.apiBaseUrl) : ENDPOINTS;
87
90
  }
88
91
  /**
89
- * Make an authenticated request to DialTribe API
92
+ * Make an authenticated request to Dialtribe API
90
93
  *
91
94
  * Automatically:
92
95
  * - Adds Authorization header with session token
@@ -200,7 +203,7 @@ var DialTribeClient = class {
200
203
  * @returns audienceId and optional resumePosition
201
204
  */
202
205
  async startSession(params) {
203
- const response = await this.fetch(this.endpoints.sessionStart, {
206
+ const response = await this.fetch(this.endpoints.audienceStart, {
204
207
  method: "POST",
205
208
  body: JSON.stringify(params)
206
209
  });
@@ -219,7 +222,7 @@ var DialTribeClient = class {
219
222
  * - 3: UNMOUNT
220
223
  */
221
224
  async sendSessionPing(params) {
222
- const response = await this.fetch(this.endpoints.sessionPing, {
225
+ const response = await this.fetch(this.endpoints.audiencePing, {
223
226
  method: "POST",
224
227
  body: JSON.stringify(params)
225
228
  });
@@ -530,18 +533,18 @@ function AudioWaveform({
530
533
  isPlaying = false,
531
534
  isLive = false
532
535
  }) {
533
- const canvasRef = react.useRef(null);
534
- const animationFrameRef = react.useRef(void 0);
535
- const [setupError, setSetupError] = react.useState(false);
536
- const isPlayingRef = react.useRef(isPlaying);
537
- const isLiveRef = react.useRef(isLive);
538
- react.useEffect(() => {
536
+ const canvasRef = React2.useRef(null);
537
+ const animationFrameRef = React2.useRef(void 0);
538
+ const [setupError, setSetupError] = React2.useState(false);
539
+ const isPlayingRef = React2.useRef(isPlaying);
540
+ const isLiveRef = React2.useRef(isLive);
541
+ React2.useEffect(() => {
539
542
  isPlayingRef.current = isPlaying;
540
543
  }, [isPlaying]);
541
- react.useEffect(() => {
544
+ React2.useEffect(() => {
542
545
  isLiveRef.current = isLive;
543
546
  }, [isLive]);
544
- react.useEffect(() => {
547
+ React2.useEffect(() => {
545
548
  const canvas = canvasRef.current;
546
549
  if (!canvas) return;
547
550
  const ctx = canvas.getContext("2d");
@@ -971,8 +974,8 @@ function StreamKeyDisplay({
971
974
  layout = "vertical",
972
975
  darkMode = false
973
976
  }) {
974
- const [isRevealed, setIsRevealed] = react.useState(false);
975
- const [copySuccess, setCopySuccess] = react.useState(false);
977
+ const [isRevealed, setIsRevealed] = React2.useState(false);
978
+ const [copySuccess, setCopySuccess] = React2.useState(false);
976
979
  const obscureStreamKey = (key) => {
977
980
  if (key.length <= 12) {
978
981
  return "\u2022".repeat(key.length);
@@ -1080,9 +1083,9 @@ function StreamingControls({
1080
1083
  onAudioDeviceChange,
1081
1084
  mediaStream
1082
1085
  }) {
1083
- const [duration, setDuration] = react.useState(0);
1084
- const [showSettings, setShowSettings] = react.useState(false);
1085
- react.useEffect(() => {
1086
+ const [duration, setDuration] = React2.useState(0);
1087
+ const [showSettings, setShowSettings] = React2.useState(false);
1088
+ React2.useEffect(() => {
1086
1089
  if (state !== "live" || !startTime) return;
1087
1090
  const interval = setInterval(() => {
1088
1091
  const elapsed = Math.floor((Date.now() - startTime.getTime()) / 1e3);
@@ -1415,8 +1418,8 @@ function StreamingControls({
1415
1418
  ] });
1416
1419
  }
1417
1420
  function StreamKeyInput({ onSubmit, inline = false }) {
1418
- const [streamKey, setStreamKey] = react.useState("");
1419
- const [error, setError] = react.useState("");
1421
+ const [streamKey, setStreamKey] = React2.useState("");
1422
+ const [error, setError] = React2.useState("");
1420
1423
  const containerClass = inline ? "dialtribe-stream-key-input flex items-center justify-center h-full w-full p-4 overflow-auto" : "dialtribe-stream-key-input flex items-center justify-center min-h-screen p-4";
1421
1424
  const validateStreamKey = (key) => {
1422
1425
  const pattern = /^[abvw][a-zA-Z0-9]+_.+$/;
@@ -1482,7 +1485,7 @@ function StreamKeyInput({ onSubmit, inline = false }) {
1482
1485
  ] })
1483
1486
  ] }) });
1484
1487
  }
1485
- function BroadcastStreamer({
1488
+ function DialtribeStreamer({
1486
1489
  sessionToken: propSessionToken,
1487
1490
  streamKey: initialStreamKey,
1488
1491
  onDone,
@@ -1491,35 +1494,35 @@ function BroadcastStreamer({
1491
1494
  apiBaseUrl = DIALTRIBE_API_BASE,
1492
1495
  inline = false
1493
1496
  }) {
1494
- const containerClass = inline ? "dialtribe-broadcast-streamer h-full w-full bg-black relative" : "dialtribe-broadcast-streamer min-h-screen bg-black";
1495
- const centeredContainerClass = inline ? "dialtribe-broadcast-streamer flex items-center justify-center h-full w-full p-4 bg-black relative" : "dialtribe-broadcast-streamer flex items-center justify-center min-h-screen p-4 bg-black";
1496
- const dialTribeContext = useDialTribeOptional();
1497
+ const containerClass = inline ? "dialtribe-dialtribe-streamer h-full w-full bg-black relative" : "dialtribe-dialtribe-streamer min-h-screen bg-black";
1498
+ const centeredContainerClass = inline ? "dialtribe-dialtribe-streamer flex items-center justify-center h-full w-full p-4 bg-black relative" : "dialtribe-dialtribe-streamer flex items-center justify-center min-h-screen p-4 bg-black";
1499
+ const dialTribeContext = useDialtribeOptional();
1497
1500
  const sessionToken = propSessionToken ?? dialTribeContext?.sessionToken ?? null;
1498
- const [streamKey, setStreamKey] = react.useState(initialStreamKey || null);
1499
- const [state, setState] = react.useState("idle");
1500
- react.useEffect(() => {
1501
+ const [streamKey, setStreamKey] = React2.useState(initialStreamKey || null);
1502
+ const [state, setState] = React2.useState("idle");
1503
+ React2.useEffect(() => {
1501
1504
  if (initialStreamKey && initialStreamKey !== streamKey) {
1502
1505
  setStreamKey(initialStreamKey);
1503
1506
  }
1504
1507
  }, [initialStreamKey]);
1505
- const [error, setError] = react.useState(null);
1506
- const [mediaStream, setMediaStream] = react.useState(null);
1507
- const [streamer, setStreamer] = react.useState(null);
1508
- const [bytesSent, setBytesSent] = react.useState(0);
1509
- const [startTime, setStartTime] = react.useState(null);
1510
- const [isMuted, setIsMuted] = react.useState(false);
1511
- const [isVideoEnabled, setIsVideoEnabled] = react.useState(true);
1512
- const [facingMode, setFacingMode] = react.useState("user");
1513
- const [showStopConfirm, setShowStopConfirm] = react.useState(false);
1514
- const [showCloseConfirm, setShowCloseConfirm] = react.useState(false);
1515
- const [hasMultipleCameras, setHasMultipleCameras] = react.useState(false);
1516
- const [videoDevices, setVideoDevices] = react.useState([]);
1517
- const [audioDevices, setAudioDevices] = react.useState([]);
1518
- const [selectedVideoDeviceId, setSelectedVideoDeviceId] = react.useState();
1519
- const [selectedAudioDeviceId, setSelectedAudioDeviceId] = react.useState();
1520
- const videoRef = react.useRef(null);
1521
- const streamerRef = react.useRef(null);
1522
- const mediaStreamRef = react.useRef(null);
1508
+ const [error, setError] = React2.useState(null);
1509
+ const [mediaStream, setMediaStream] = React2.useState(null);
1510
+ const [streamer, setStreamer] = React2.useState(null);
1511
+ const [bytesSent, setBytesSent] = React2.useState(0);
1512
+ const [startTime, setStartTime] = React2.useState(null);
1513
+ const [isMuted, setIsMuted] = React2.useState(false);
1514
+ const [isVideoEnabled, setIsVideoEnabled] = React2.useState(true);
1515
+ const [facingMode, setFacingMode] = React2.useState("user");
1516
+ const [showStopConfirm, setShowStopConfirm] = React2.useState(false);
1517
+ const [showCloseConfirm, setShowCloseConfirm] = React2.useState(false);
1518
+ const [hasMultipleCameras, setHasMultipleCameras] = React2.useState(false);
1519
+ const [videoDevices, setVideoDevices] = React2.useState([]);
1520
+ const [audioDevices, setAudioDevices] = React2.useState([]);
1521
+ const [selectedVideoDeviceId, setSelectedVideoDeviceId] = React2.useState();
1522
+ const [selectedAudioDeviceId, setSelectedAudioDeviceId] = React2.useState();
1523
+ const videoRef = React2.useRef(null);
1524
+ const streamerRef = React2.useRef(null);
1525
+ const mediaStreamRef = React2.useRef(null);
1523
1526
  const isVideoKey = streamKey ? streamKey.startsWith("v") || streamKey.startsWith("w") : false;
1524
1527
  const handleStreamKeySubmit = (key) => {
1525
1528
  setStreamKey(key);
@@ -1529,7 +1532,7 @@ function BroadcastStreamer({
1529
1532
  setStreamKey(key);
1530
1533
  onStreamKeyChange?.(key);
1531
1534
  };
1532
- react.useEffect(() => {
1535
+ React2.useEffect(() => {
1533
1536
  if (!streamKey) return;
1534
1537
  const compat = checkBrowserCompatibility();
1535
1538
  if (!compat.compatible) {
@@ -1567,13 +1570,13 @@ function BroadcastStreamer({
1567
1570
  setHasMultipleCameras(false);
1568
1571
  }
1569
1572
  };
1570
- react.useEffect(() => {
1573
+ React2.useEffect(() => {
1571
1574
  streamerRef.current = streamer;
1572
1575
  }, [streamer]);
1573
- react.useEffect(() => {
1576
+ React2.useEffect(() => {
1574
1577
  mediaStreamRef.current = mediaStream;
1575
1578
  }, [mediaStream]);
1576
- react.useEffect(() => {
1579
+ React2.useEffect(() => {
1577
1580
  return () => {
1578
1581
  if (streamerRef.current) {
1579
1582
  streamerRef.current.stop();
@@ -1583,7 +1586,7 @@ function BroadcastStreamer({
1583
1586
  }
1584
1587
  };
1585
1588
  }, []);
1586
- react.useEffect(() => {
1589
+ React2.useEffect(() => {
1587
1590
  if (state === "live") {
1588
1591
  const handleBeforeUnload = (e) => {
1589
1592
  e.preventDefault();
@@ -1594,7 +1597,7 @@ function BroadcastStreamer({
1594
1597
  return () => window.removeEventListener("beforeunload", handleBeforeUnload);
1595
1598
  }
1596
1599
  }, [state]);
1597
- react.useEffect(() => {
1600
+ React2.useEffect(() => {
1598
1601
  if (videoRef.current && mediaStream) {
1599
1602
  videoRef.current.srcObject = mediaStream;
1600
1603
  }
@@ -1877,36 +1880,9 @@ function BroadcastStreamer({
1877
1880
  }
1878
1881
  };
1879
1882
  if (!sessionToken) {
1880
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: centeredContainerClass, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-white dark:bg-zinc-900 rounded-lg border border-gray-200 dark:border-zinc-800 p-8 max-w-md w-full text-center", children: [
1881
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-16 h-16 bg-red-100 dark:bg-red-900/20 rounded-full flex items-center justify-center mx-auto mb-4", children: /* @__PURE__ */ jsxRuntime.jsx(
1882
- "svg",
1883
- {
1884
- className: "w-8 h-8 text-red-600 dark:text-red-400",
1885
- fill: "none",
1886
- stroke: "currentColor",
1887
- viewBox: "0 0 24 24",
1888
- children: /* @__PURE__ */ jsxRuntime.jsx(
1889
- "path",
1890
- {
1891
- strokeLinecap: "round",
1892
- strokeLinejoin: "round",
1893
- strokeWidth: 2,
1894
- d: "M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z"
1895
- }
1896
- )
1897
- }
1898
- ) }),
1899
- /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-xl font-bold text-black dark:text-white mb-2", children: "Authentication Required" }),
1900
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-gray-600 dark:text-gray-400 mb-4", children: "A session token is required to use the broadcast streamer." }),
1901
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-gray-500 dark:text-gray-500 mb-6", children: "Wrap your app with DialTribeProvider or pass a sessionToken prop." }),
1902
- /* @__PURE__ */ jsxRuntime.jsx(
1903
- "button",
1904
- {
1905
- onClick: handleDone,
1906
- className: "w-full px-6 py-2 bg-gray-100 dark:bg-zinc-800 hover:bg-gray-200 dark:hover:bg-zinc-700 text-black dark:text-white font-medium rounded-lg transition-colors",
1907
- children: "Close"
1908
- }
1909
- )
1883
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: centeredContainerClass, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-center", children: [
1884
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-16 h-16 border-4 border-gray-700 border-t-blue-600 rounded-full animate-spin mx-auto mb-4" }),
1885
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-white text-lg", children: "Connecting..." })
1910
1886
  ] }) });
1911
1887
  }
1912
1888
  if (!streamKey) {
@@ -2239,7 +2215,7 @@ function getErrorMessage(error) {
2239
2215
  }
2240
2216
  return "Unable to play media. Please try refreshing the page or contact support if the problem persists.";
2241
2217
  }
2242
- function BroadcastPlayer({
2218
+ function DialtribePlayer({
2243
2219
  broadcast,
2244
2220
  appId,
2245
2221
  contentId,
@@ -2250,18 +2226,18 @@ function BroadcastPlayer({
2250
2226
  className = "",
2251
2227
  enableKeyboardShortcuts = false
2252
2228
  }) {
2253
- const { sessionToken, setSessionToken, markExpired, apiBaseUrl } = useDialTribe();
2254
- const clientRef = react.useRef(null);
2229
+ const { sessionToken, setSessionToken, markExpired, apiBaseUrl } = useDialtribe();
2230
+ const clientRef = React2.useRef(null);
2255
2231
  if (!clientRef.current && sessionToken) {
2256
- clientRef.current = new DialTribeClient({
2232
+ clientRef.current = new DialtribeClient({
2257
2233
  sessionToken,
2258
2234
  apiBaseUrl,
2259
2235
  onTokenRefresh: (newToken, expiresAt) => {
2260
- debug.log(`[DialTribeClient] Token refreshed, expires at ${expiresAt}`);
2236
+ debug.log(`[DialtribeClient] Token refreshed, expires at ${expiresAt}`);
2261
2237
  setSessionToken(newToken, expiresAt);
2262
2238
  },
2263
2239
  onTokenExpired: () => {
2264
- debug.error("[DialTribeClient] Token expired");
2240
+ debug.error("[DialtribeClient] Token expired");
2265
2241
  markExpired();
2266
2242
  }
2267
2243
  });
@@ -2269,35 +2245,35 @@ function BroadcastPlayer({
2269
2245
  clientRef.current.setSessionToken(sessionToken);
2270
2246
  }
2271
2247
  const client = clientRef.current;
2272
- const playerRef = react.useRef(null);
2273
- const transcriptContainerRef = react.useRef(null);
2274
- const activeWordRef = react.useRef(null);
2275
- const [audioElement, setAudioElement] = react.useState(null);
2276
- const [playing, setPlaying] = react.useState(false);
2277
- const [played, setPlayed] = react.useState(0);
2278
- const [duration, setDuration] = react.useState(0);
2279
- const [volume, setVolume] = react.useState(1);
2280
- const [muted, setMuted] = react.useState(false);
2281
- const [seeking, setSeeking] = react.useState(false);
2282
- const [hasError, setHasError] = react.useState(false);
2283
- const [errorMessage, setErrorMessage] = react.useState("");
2284
- const [hasEnded, setHasEnded] = react.useState(false);
2285
- const [hasStreamEnded, setHasStreamEnded] = react.useState(false);
2286
- const [showTranscript, setShowTranscript] = react.useState(false);
2287
- const [transcriptData, setTranscriptData] = react.useState(null);
2288
- const [currentTime, setCurrentTime] = react.useState(0);
2289
- const [isLoadingTranscript, setIsLoadingTranscript] = react.useState(false);
2290
- const [isLoadingVideo, setIsLoadingVideo] = react.useState(true);
2291
- const [autoScrollEnabled, setAutoScrollEnabled] = react.useState(true);
2292
- const isScrollingProgrammatically = react.useRef(false);
2293
- const lastActiveWordIndex = react.useRef(-1);
2294
- const [showClipCreator, setShowClipCreator] = react.useState(false);
2295
- const initialPlaybackTypeRef = react.useRef(null);
2296
- const [currentPlaybackInfo, setCurrentPlaybackInfo] = react.useState(null);
2297
- const [urlExpiresAt, setUrlExpiresAt] = react.useState(null);
2298
- const isRefreshingUrl = react.useRef(false);
2299
- const [audienceId, setAudienceId] = react.useState(null);
2300
- const [sessionId] = react.useState(() => {
2248
+ const playerRef = React2.useRef(null);
2249
+ const transcriptContainerRef = React2.useRef(null);
2250
+ const activeWordRef = React2.useRef(null);
2251
+ const [audioElement, setAudioElement] = React2.useState(null);
2252
+ const [playing, setPlaying] = React2.useState(false);
2253
+ const [played, setPlayed] = React2.useState(0);
2254
+ const [duration, setDuration] = React2.useState(0);
2255
+ const [volume, setVolume] = React2.useState(1);
2256
+ const [muted, setMuted] = React2.useState(false);
2257
+ const [seeking, setSeeking] = React2.useState(false);
2258
+ const [hasError, setHasError] = React2.useState(false);
2259
+ const [errorMessage, setErrorMessage] = React2.useState("");
2260
+ const [hasEnded, setHasEnded] = React2.useState(false);
2261
+ const [hasStreamEnded, setHasStreamEnded] = React2.useState(false);
2262
+ const [showTranscript, setShowTranscript] = React2.useState(false);
2263
+ const [transcriptData, setTranscriptData] = React2.useState(null);
2264
+ const [currentTime, setCurrentTime] = React2.useState(0);
2265
+ const [isLoadingTranscript, setIsLoadingTranscript] = React2.useState(false);
2266
+ const [isLoadingVideo, setIsLoadingVideo] = React2.useState(true);
2267
+ const [autoScrollEnabled, setAutoScrollEnabled] = React2.useState(true);
2268
+ const isScrollingProgrammatically = React2.useRef(false);
2269
+ const lastActiveWordIndex = React2.useRef(-1);
2270
+ const [showClipCreator, setShowClipCreator] = React2.useState(false);
2271
+ const initialPlaybackTypeRef = React2.useRef(null);
2272
+ const [currentPlaybackInfo, setCurrentPlaybackInfo] = React2.useState(null);
2273
+ const [urlExpiresAt, setUrlExpiresAt] = React2.useState(null);
2274
+ const isRefreshingUrl = React2.useRef(false);
2275
+ const [audienceId, setAudienceId] = React2.useState(null);
2276
+ const [sessionId] = React2.useState(() => {
2301
2277
  if (typeof crypto !== "undefined" && crypto.randomUUID) {
2302
2278
  return crypto.randomUUID();
2303
2279
  }
@@ -2307,9 +2283,9 @@ function BroadcastPlayer({
2307
2283
  return v.toString(16);
2308
2284
  });
2309
2285
  });
2310
- const heartbeatIntervalRef = react.useRef(null);
2311
- const hasInitializedSession = react.useRef(false);
2312
- const refreshPresignedUrl = react.useCallback(
2286
+ const heartbeatIntervalRef = React2.useRef(null);
2287
+ const hasInitializedSession = React2.useRef(false);
2288
+ const refreshPresignedUrl = React2.useCallback(
2313
2289
  async (fileType) => {
2314
2290
  if (!broadcast.hash || isRefreshingUrl.current || !client) {
2315
2291
  debug.log("[URL Refresh] Skipping refresh - no hash, already refreshing, or no client");
@@ -2360,7 +2336,7 @@ function BroadcastPlayer({
2360
2336
  if (width < 1024) return "tablet";
2361
2337
  return "desktop";
2362
2338
  };
2363
- const initializeTrackingSession = react.useCallback(async () => {
2339
+ const initializeTrackingSession = React2.useCallback(async () => {
2364
2340
  if (!contentId || !appId || !client) return;
2365
2341
  if (currentPlaybackInfo?.type === "hls" && broadcast.broadcastStatus === 1) return;
2366
2342
  if (hasInitializedSession.current) return;
@@ -2395,7 +2371,7 @@ function BroadcastPlayer({
2395
2371
  }
2396
2372
  }
2397
2373
  }, [contentId, appId, broadcast.id, broadcast.broadcastStatus, foreignId, foreignTier, sessionId, currentPlaybackInfo?.type, audioElement, client, onError]);
2398
- const sendTrackingPing = react.useCallback(
2374
+ const sendTrackingPing = React2.useCallback(
2399
2375
  async (eventType) => {
2400
2376
  if (!audienceId || !sessionId || !client) return;
2401
2377
  try {
@@ -2433,7 +2409,7 @@ function BroadcastPlayer({
2433
2409
  }
2434
2410
  return null;
2435
2411
  };
2436
- react.useEffect(() => {
2412
+ React2.useEffect(() => {
2437
2413
  if (!currentPlaybackInfo) {
2438
2414
  const info = getPlaybackInfo();
2439
2415
  setCurrentPlaybackInfo(info);
@@ -2449,12 +2425,12 @@ function BroadcastPlayer({
2449
2425
  }
2450
2426
  }
2451
2427
  }, [currentPlaybackInfo]);
2452
- react.useEffect(() => {
2428
+ React2.useEffect(() => {
2453
2429
  if (currentPlaybackInfo?.url) {
2454
2430
  setIsLoadingVideo(true);
2455
2431
  }
2456
2432
  }, [currentPlaybackInfo?.url]);
2457
- react.useEffect(() => {
2433
+ React2.useEffect(() => {
2458
2434
  if (!urlExpiresAt || !currentPlaybackInfo?.type) return;
2459
2435
  const checkExpiration = () => {
2460
2436
  const now = /* @__PURE__ */ new Date();
@@ -2473,7 +2449,7 @@ function BroadcastPlayer({
2473
2449
  clearInterval(interval);
2474
2450
  };
2475
2451
  }, [urlExpiresAt, currentPlaybackInfo?.type, refreshPresignedUrl]);
2476
- react.useEffect(() => {
2452
+ React2.useEffect(() => {
2477
2453
  if (initialPlaybackTypeRef.current === "hls" && currentPlaybackInfo?.type === "hls" && broadcast.broadcastStatus !== 1 && broadcast.recordingMp3Url && broadcast.hash && parseInt(broadcast.mp3Size || "0") > 0) {
2478
2454
  const secureUrl = buildPlaybackUrl(broadcast.id, broadcast.hash);
2479
2455
  setCurrentPlaybackInfo({ url: secureUrl, type: "mp3" });
@@ -2509,22 +2485,22 @@ function BroadcastPlayer({
2509
2485
  setHasEnded(true);
2510
2486
  }
2511
2487
  };
2512
- react.useEffect(() => {
2488
+ React2.useEffect(() => {
2513
2489
  if (broadcast.durationSeconds && broadcast.durationSeconds > 0) {
2514
2490
  setDuration(broadcast.durationSeconds);
2515
2491
  }
2516
2492
  }, [broadcast.durationSeconds]);
2517
- react.useEffect(() => {
2493
+ React2.useEffect(() => {
2518
2494
  if (isLiveStream && !playing) {
2519
2495
  setPlaying(true);
2520
2496
  }
2521
2497
  }, [isLiveStream, playing]);
2522
- react.useEffect(() => {
2498
+ React2.useEffect(() => {
2523
2499
  if (currentPlaybackInfo && audioElement && !hasInitializedSession.current) {
2524
2500
  initializeTrackingSession();
2525
2501
  }
2526
2502
  }, [currentPlaybackInfo, audioElement, initializeTrackingSession]);
2527
- react.useEffect(() => {
2503
+ React2.useEffect(() => {
2528
2504
  if (playing && audienceId) {
2529
2505
  sendTrackingPing(1);
2530
2506
  heartbeatIntervalRef.current = setInterval(() => {
@@ -2544,7 +2520,7 @@ function BroadcastPlayer({
2544
2520
  }
2545
2521
  }
2546
2522
  }, [playing, audienceId, sendTrackingPing]);
2547
- react.useEffect(() => {
2523
+ React2.useEffect(() => {
2548
2524
  return () => {
2549
2525
  if (audienceId && sessionId && sessionToken) {
2550
2526
  const payload = {
@@ -2569,7 +2545,7 @@ function BroadcastPlayer({
2569
2545
  }
2570
2546
  };
2571
2547
  }, [audienceId, sessionId, sessionToken, audioElement, duration]);
2572
- react.useEffect(() => {
2548
+ React2.useEffect(() => {
2573
2549
  if (broadcast.transcriptUrl && broadcast.transcriptStatus === 2 && !transcriptData) {
2574
2550
  setIsLoadingTranscript(true);
2575
2551
  fetch(broadcast.transcriptUrl).then((res) => {
@@ -2600,7 +2576,7 @@ function BroadcastPlayer({
2600
2576
  });
2601
2577
  }
2602
2578
  }, [broadcast.transcriptUrl, broadcast.transcriptStatus, transcriptData]);
2603
- react.useEffect(() => {
2579
+ React2.useEffect(() => {
2604
2580
  if (!audioElement) return;
2605
2581
  const handleTimeUpdate2 = () => {
2606
2582
  setCurrentTime(audioElement.currentTime);
@@ -2608,7 +2584,7 @@ function BroadcastPlayer({
2608
2584
  audioElement.addEventListener("timeupdate", handleTimeUpdate2);
2609
2585
  return () => audioElement.removeEventListener("timeupdate", handleTimeUpdate2);
2610
2586
  }, [audioElement]);
2611
- react.useEffect(() => {
2587
+ React2.useEffect(() => {
2612
2588
  if (showTranscript && autoScrollEnabled && activeWordRef.current && transcriptContainerRef.current) {
2613
2589
  const container = transcriptContainerRef.current;
2614
2590
  const activeWord = activeWordRef.current;
@@ -2623,7 +2599,7 @@ function BroadcastPlayer({
2623
2599
  }
2624
2600
  }
2625
2601
  }, [currentTime, showTranscript, autoScrollEnabled]);
2626
- react.useEffect(() => {
2602
+ React2.useEffect(() => {
2627
2603
  if (!showTranscript || !transcriptContainerRef.current) return;
2628
2604
  const container = transcriptContainerRef.current;
2629
2605
  const handleScroll = () => {
@@ -2706,10 +2682,10 @@ function BroadcastPlayer({
2706
2682
  setAudioElement(internalPlayer);
2707
2683
  }
2708
2684
  } catch (error) {
2709
- debug.error("[BroadcastPlayer] Error getting internal player:", error);
2685
+ debug.error("[DialtribePlayer] Error getting internal player:", error);
2710
2686
  }
2711
2687
  };
2712
- react.useEffect(() => {
2688
+ React2.useEffect(() => {
2713
2689
  const findAudioElement = () => {
2714
2690
  const videoElements = document.querySelectorAll("video, audio");
2715
2691
  if (videoElements.length > 0) {
@@ -2729,7 +2705,7 @@ function BroadcastPlayer({
2729
2705
  return () => timeouts.forEach(clearTimeout);
2730
2706
  }
2731
2707
  }, [playbackUrl]);
2732
- react.useEffect(() => {
2708
+ React2.useEffect(() => {
2733
2709
  if (playing && !audioElement) {
2734
2710
  const videoElements = document.querySelectorAll("video, audio");
2735
2711
  if (videoElements.length > 0) {
@@ -2808,7 +2784,7 @@ function BroadcastPlayer({
2808
2784
  onError(error);
2809
2785
  }
2810
2786
  };
2811
- const handleRetry = react.useCallback(() => {
2787
+ const handleRetry = React2.useCallback(() => {
2812
2788
  setHasError(false);
2813
2789
  setErrorMessage("");
2814
2790
  setIsLoadingVideo(true);
@@ -2831,7 +2807,7 @@ function BroadcastPlayer({
2831
2807
  }
2832
2808
  }
2833
2809
  };
2834
- react.useEffect(() => {
2810
+ React2.useEffect(() => {
2835
2811
  if (!enableKeyboardShortcuts) return;
2836
2812
  const seekBy = (seconds) => {
2837
2813
  if (!audioElement || duration <= 0) return;
@@ -2914,7 +2890,7 @@ function BroadcastPlayer({
2914
2890
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-center p-8", children: /* @__PURE__ */ jsxRuntime.jsx(LoadingSpinner, { variant: "white", text: "Loading..." }) });
2915
2891
  }
2916
2892
  const hasTranscript = broadcast.transcriptStatus === 2 && transcriptData && (transcriptData.segments && transcriptData.segments.some((s) => s.words && s.words.length > 0) || transcriptData.words && transcriptData.words.length > 0);
2917
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `bg-black rounded-lg shadow-2xl w-full max-h-full flex flex-col overflow-hidden ${className}`, children: [
2893
+ const playerContent = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `bg-black rounded-lg shadow-2xl w-full max-h-full flex flex-col overflow-hidden ${className}`, children: [
2918
2894
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-zinc-900/50 backdrop-blur-sm border-b border-zinc-800 px-3 sm:px-4 md:px-6 py-2 sm:py-3 md:py-4 flex justify-between items-center rounded-t-lg shrink-0", children: [
2919
2895
  /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2920
2896
  /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-lg font-semibold text-white", children: broadcast.streamKeyRecord?.foreignName || "Broadcast" }),
@@ -3446,90 +3422,9 @@ function BroadcastPlayer({
3446
3422
  }
3447
3423
  ` })
3448
3424
  ] });
3425
+ return playerContent;
3449
3426
  }
3450
- function BroadcastPlayerModal({
3451
- broadcast,
3452
- isOpen,
3453
- onClose,
3454
- appId,
3455
- contentId,
3456
- foreignId,
3457
- foreignTier,
3458
- renderClipCreator,
3459
- className,
3460
- enableKeyboardShortcuts = false
3461
- }) {
3462
- const closeButtonRef = react.useRef(null);
3463
- const previousActiveElement = react.useRef(null);
3464
- react.useEffect(() => {
3465
- if (!isOpen) return;
3466
- previousActiveElement.current = document.activeElement;
3467
- setTimeout(() => {
3468
- closeButtonRef.current?.focus();
3469
- }, 100);
3470
- return () => {
3471
- if (previousActiveElement.current) {
3472
- previousActiveElement.current.focus();
3473
- }
3474
- };
3475
- }, [isOpen]);
3476
- react.useEffect(() => {
3477
- if (!isOpen) return;
3478
- const handleKeyDown = (e) => {
3479
- if (e.key === "Escape") {
3480
- onClose();
3481
- }
3482
- };
3483
- document.addEventListener("keydown", handleKeyDown);
3484
- return () => document.removeEventListener("keydown", handleKeyDown);
3485
- }, [isOpen, onClose]);
3486
- if (!isOpen) return null;
3487
- const handleBackdropClick = (e) => {
3488
- if (e.target === e.currentTarget) {
3489
- onClose();
3490
- }
3491
- };
3492
- return /* @__PURE__ */ jsxRuntime.jsx(
3493
- "div",
3494
- {
3495
- className: "fixed inset-0 bg-black/70 backdrop-blur-xl flex items-center justify-center z-50 p-2 sm:p-4",
3496
- onClick: handleBackdropClick,
3497
- role: "dialog",
3498
- "aria-modal": "true",
3499
- "aria-label": "Broadcast player",
3500
- children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative w-full max-w-7xl max-h-[95vh] sm:max-h-[90vh] overflow-hidden", children: [
3501
- /* @__PURE__ */ jsxRuntime.jsx(
3502
- "button",
3503
- {
3504
- ref: closeButtonRef,
3505
- onClick: onClose,
3506
- className: "absolute top-2 right-2 sm:top-4 sm:right-4 z-10 text-gray-400 hover:text-white text-2xl leading-none transition-colors w-8 h-8 flex items-center justify-center bg-black/50 rounded-full",
3507
- title: "Close (ESC)",
3508
- "aria-label": "Close player",
3509
- children: "\xD7"
3510
- }
3511
- ),
3512
- /* @__PURE__ */ jsxRuntime.jsx(
3513
- BroadcastPlayer,
3514
- {
3515
- broadcast,
3516
- appId,
3517
- contentId,
3518
- foreignId,
3519
- foreignTier,
3520
- renderClipCreator,
3521
- className,
3522
- enableKeyboardShortcuts,
3523
- onError: (error) => {
3524
- debug.error("[BroadcastPlayerModal] Player error:", error);
3525
- }
3526
- }
3527
- )
3528
- ] })
3529
- }
3530
- );
3531
- }
3532
- var BroadcastPlayerErrorBoundary = class extends react.Component {
3427
+ var DialtribePlayerErrorBoundary = class extends React2.Component {
3533
3428
  constructor(props) {
3534
3429
  super(props);
3535
3430
  this.handleReset = () => {
@@ -3655,8 +3550,86 @@ var BroadcastPlayerErrorBoundary = class extends react.Component {
3655
3550
  return this.props.children;
3656
3551
  }
3657
3552
  };
3553
+ var overlayStyles = {
3554
+ modal: {
3555
+ backdrop: "bg-black/70 backdrop-blur-xl p-2 sm:p-4",
3556
+ container: "max-w-7xl max-h-[95vh] sm:max-h-[90vh]"
3557
+ },
3558
+ fullscreen: {
3559
+ backdrop: "bg-black",
3560
+ container: "h-full"
3561
+ }
3562
+ };
3563
+ function DialtribeOverlay({
3564
+ isOpen,
3565
+ onClose,
3566
+ mode = "modal",
3567
+ children,
3568
+ ariaLabel = "Dialog",
3569
+ showCloseButton = true,
3570
+ closeOnBackdropClick = true,
3571
+ closeOnEsc = true
3572
+ }) {
3573
+ const closeButtonRef = React2.useRef(null);
3574
+ const previousActiveElement = React2.useRef(null);
3575
+ React2.useEffect(() => {
3576
+ if (!isOpen) return;
3577
+ previousActiveElement.current = document.activeElement;
3578
+ setTimeout(() => {
3579
+ closeButtonRef.current?.focus();
3580
+ }, 100);
3581
+ return () => {
3582
+ if (previousActiveElement.current) {
3583
+ previousActiveElement.current.focus();
3584
+ }
3585
+ };
3586
+ }, [isOpen]);
3587
+ React2.useEffect(() => {
3588
+ if (!isOpen || !closeOnEsc) return;
3589
+ const handleKeyDown = (e) => {
3590
+ if (e.key === "Escape") {
3591
+ onClose();
3592
+ }
3593
+ };
3594
+ document.addEventListener("keydown", handleKeyDown);
3595
+ return () => document.removeEventListener("keydown", handleKeyDown);
3596
+ }, [isOpen, onClose, closeOnEsc]);
3597
+ if (!isOpen) {
3598
+ return null;
3599
+ }
3600
+ const handleBackdropClick = (e) => {
3601
+ if (closeOnBackdropClick && e.target === e.currentTarget) {
3602
+ onClose();
3603
+ }
3604
+ };
3605
+ const styles = overlayStyles[mode];
3606
+ return /* @__PURE__ */ jsxRuntime.jsx(
3607
+ "div",
3608
+ {
3609
+ className: `fixed inset-0 flex items-center justify-center z-50 ${styles.backdrop}`,
3610
+ onClick: handleBackdropClick,
3611
+ role: "dialog",
3612
+ "aria-modal": "true",
3613
+ "aria-label": ariaLabel,
3614
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `relative w-full overflow-hidden ${styles.container}`, children: [
3615
+ showCloseButton && /* @__PURE__ */ jsxRuntime.jsx(
3616
+ "button",
3617
+ {
3618
+ ref: closeButtonRef,
3619
+ onClick: onClose,
3620
+ className: "absolute top-2 right-2 sm:top-4 sm:right-4 z-10 text-gray-400 hover:text-white text-2xl leading-none transition-colors w-8 h-8 flex items-center justify-center bg-black/50 rounded-full",
3621
+ title: "Close (ESC)",
3622
+ "aria-label": "Close",
3623
+ children: "\xD7"
3624
+ }
3625
+ ),
3626
+ children
3627
+ ] })
3628
+ }
3629
+ );
3630
+ }
3658
3631
 
3659
- // src/utils/broadcast-popup.ts
3632
+ // src/utils/dialtribe-popup.ts
3660
3633
  function calculatePopupDimensions() {
3661
3634
  const screenWidth = window.screen.width;
3662
3635
  const screenHeight = window.screen.height;
@@ -3674,26 +3647,22 @@ function calculatePopupDimensions() {
3674
3647
  const top = Math.floor((screenHeight - height) / 2);
3675
3648
  return { width, height, left, top };
3676
3649
  }
3677
- function openBroadcastStreamerPopup(options) {
3650
+ function openDialtribeStreamerPopup(options) {
3678
3651
  const {
3679
3652
  sessionToken,
3680
3653
  streamKey,
3654
+ streamerUrl,
3681
3655
  appId,
3682
- mode,
3683
- additionalParams,
3684
- baseUrl = "/broadcasts/new"
3656
+ additionalParams
3685
3657
  } = options;
3686
3658
  const { width, height, left, top } = calculatePopupDimensions();
3687
3659
  const params = new URLSearchParams();
3688
- if (mode) {
3689
- params.append("mode", mode);
3690
- }
3691
3660
  if (additionalParams) {
3692
3661
  Object.entries(additionalParams).forEach(([key, value]) => {
3693
3662
  params.append(key, value);
3694
3663
  });
3695
3664
  }
3696
- const url = `${baseUrl}${params.toString() ? `?${params.toString()}` : ""}`;
3665
+ const url = `${streamerUrl}${params.toString() ? `?${params.toString()}` : ""}`;
3697
3666
  const popup = window.open(
3698
3667
  url,
3699
3668
  "_blank",
@@ -3723,18 +3692,177 @@ function openBroadcastStreamerPopup(options) {
3723
3692
  setTimeout(sendMessage, 500);
3724
3693
  return popup;
3725
3694
  }
3726
- var openBroadcastPopup = openBroadcastStreamerPopup;
3695
+ var openBroadcastPopup = openDialtribeStreamerPopup;
3696
+ function useDialtribeStreamerPopup() {
3697
+ const [sessionToken, setSessionToken] = React2.useState(null);
3698
+ const [streamKey, setStreamKey] = React2.useState(null);
3699
+ const [apiBaseUrl, setApiBaseUrl] = React2.useState("");
3700
+ const receivedDataRef = React2.useRef(false);
3701
+ React2.useEffect(() => {
3702
+ const handleMessage = (event) => {
3703
+ if (event.data?.type !== "STREAM_KEY") return;
3704
+ const { sessionToken: token, streamKey: key, apiBaseUrl: url } = event.data;
3705
+ if (token && key) {
3706
+ receivedDataRef.current = true;
3707
+ setSessionToken(token);
3708
+ setStreamKey(key);
3709
+ if (url) {
3710
+ setApiBaseUrl(url);
3711
+ }
3712
+ } else if (key) {
3713
+ receivedDataRef.current = true;
3714
+ setStreamKey(key);
3715
+ }
3716
+ };
3717
+ window.addEventListener("message", handleMessage);
3718
+ const requestCredentials = () => {
3719
+ if (window.opener && !receivedDataRef.current) {
3720
+ window.opener.postMessage({ type: "POPUP_READY" }, "*");
3721
+ }
3722
+ };
3723
+ requestCredentials();
3724
+ const pollInterval = setInterval(() => {
3725
+ if (!receivedDataRef.current) {
3726
+ requestCredentials();
3727
+ } else {
3728
+ clearInterval(pollInterval);
3729
+ }
3730
+ }, 200);
3731
+ const timeout = setTimeout(() => {
3732
+ clearInterval(pollInterval);
3733
+ }, 1e4);
3734
+ return () => {
3735
+ window.removeEventListener("message", handleMessage);
3736
+ clearInterval(pollInterval);
3737
+ clearTimeout(timeout);
3738
+ };
3739
+ }, []);
3740
+ return {
3741
+ sessionToken,
3742
+ streamKey,
3743
+ apiBaseUrl,
3744
+ setStreamKey,
3745
+ isReady: receivedDataRef.current
3746
+ };
3747
+ }
3748
+ function useDialtribeStreamerLauncher(options) {
3749
+ const {
3750
+ sessionToken,
3751
+ streamKey,
3752
+ streamerUrl,
3753
+ apiBaseUrl,
3754
+ fallback = "fullscreen",
3755
+ onPopupBlocked,
3756
+ onDone,
3757
+ onStreamKeyChange
3758
+ } = options;
3759
+ const [showFallback, setShowFallback] = React2.useState(false);
3760
+ const [wasBlocked, setWasBlocked] = React2.useState(false);
3761
+ const popupRef = React2.useRef(null);
3762
+ const sessionTokenRef = React2.useRef(sessionToken);
3763
+ const streamKeyRef = React2.useRef(streamKey);
3764
+ const apiBaseUrlRef = React2.useRef(apiBaseUrl);
3765
+ React2.useEffect(() => {
3766
+ sessionTokenRef.current = sessionToken;
3767
+ }, [sessionToken]);
3768
+ React2.useEffect(() => {
3769
+ streamKeyRef.current = streamKey;
3770
+ }, [streamKey]);
3771
+ React2.useEffect(() => {
3772
+ apiBaseUrlRef.current = apiBaseUrl;
3773
+ }, [apiBaseUrl]);
3774
+ React2.useEffect(() => {
3775
+ const handleMessage = (event) => {
3776
+ if (event.data?.type === "POPUP_READY" && popupRef.current) {
3777
+ popupRef.current.postMessage(
3778
+ {
3779
+ type: "STREAM_KEY",
3780
+ sessionToken: sessionTokenRef.current,
3781
+ streamKey: streamKeyRef.current,
3782
+ apiBaseUrl: apiBaseUrlRef.current
3783
+ },
3784
+ "*"
3785
+ );
3786
+ }
3787
+ };
3788
+ window.addEventListener("message", handleMessage);
3789
+ return () => window.removeEventListener("message", handleMessage);
3790
+ }, []);
3791
+ const launch = React2.useCallback(() => {
3792
+ if (!sessionToken) {
3793
+ console.warn("Cannot launch streamer: no session token");
3794
+ return;
3795
+ }
3796
+ setWasBlocked(false);
3797
+ const popup = openDialtribeStreamerPopup({
3798
+ sessionToken,
3799
+ streamKey,
3800
+ streamerUrl
3801
+ });
3802
+ if (popup) {
3803
+ popupRef.current = popup;
3804
+ return;
3805
+ }
3806
+ setWasBlocked(true);
3807
+ onPopupBlocked?.();
3808
+ switch (fallback) {
3809
+ case "fullscreen":
3810
+ setShowFallback(true);
3811
+ break;
3812
+ case "newTab":
3813
+ window.open(streamerUrl, "_blank");
3814
+ break;
3815
+ }
3816
+ }, [sessionToken, streamKey, streamerUrl, fallback, onPopupBlocked]);
3817
+ const closeFallback = React2.useCallback(() => {
3818
+ setShowFallback(false);
3819
+ onDone?.();
3820
+ }, [onDone]);
3821
+ const Fallback = React2.useCallback(() => {
3822
+ if (fallback !== "fullscreen" || !showFallback) {
3823
+ return null;
3824
+ }
3825
+ if (typeof document === "undefined") {
3826
+ return null;
3827
+ }
3828
+ const streamerElement = React2__default.default.createElement(DialtribeStreamer, {
3829
+ sessionToken: sessionToken || void 0,
3830
+ streamKey: streamKey || void 0,
3831
+ apiBaseUrl,
3832
+ onDone: closeFallback,
3833
+ onStreamKeyChange
3834
+ });
3835
+ const overlayElement = React2__default.default.createElement(
3836
+ DialtribeOverlay,
3837
+ {
3838
+ mode: "fullscreen",
3839
+ isOpen: true,
3840
+ onClose: closeFallback,
3841
+ children: streamerElement
3842
+ }
3843
+ );
3844
+ return reactDom.createPortal(overlayElement, document.body);
3845
+ }, [fallback, showFallback, closeFallback, sessionToken, streamKey, apiBaseUrl, onStreamKeyChange]);
3846
+ return {
3847
+ launch,
3848
+ Fallback,
3849
+ showFallback,
3850
+ closeFallback,
3851
+ popupRef: popupRef.current,
3852
+ wasBlocked
3853
+ };
3854
+ }
3727
3855
 
3728
3856
  exports.AudioWaveform = AudioWaveform;
3729
- exports.BroadcastPlayer = BroadcastPlayer;
3730
- exports.BroadcastPlayerErrorBoundary = BroadcastPlayerErrorBoundary;
3731
- exports.BroadcastPlayerModal = BroadcastPlayerModal;
3732
- exports.BroadcastStreamer = BroadcastStreamer;
3733
3857
  exports.CDN_DOMAIN = CDN_DOMAIN;
3734
3858
  exports.DEFAULT_ENCODER_SERVER_URL = DEFAULT_ENCODER_SERVER_URL;
3735
3859
  exports.DIALTRIBE_API_BASE = DIALTRIBE_API_BASE;
3736
- exports.DialTribeClient = DialTribeClient;
3737
- exports.DialTribeProvider = DialTribeProvider;
3860
+ exports.DialtribeClient = DialtribeClient;
3861
+ exports.DialtribeOverlay = DialtribeOverlay;
3862
+ exports.DialtribePlayer = DialtribePlayer;
3863
+ exports.DialtribePlayerErrorBoundary = DialtribePlayerErrorBoundary;
3864
+ exports.DialtribeProvider = DialtribeProvider;
3865
+ exports.DialtribeStreamer = DialtribeStreamer;
3738
3866
  exports.ENDPOINTS = ENDPOINTS;
3739
3867
  exports.HTTP_STATUS = HTTP_STATUS;
3740
3868
  exports.LoadingSpinner = LoadingSpinner;
@@ -3751,8 +3879,10 @@ exports.formatTime = formatTime;
3751
3879
  exports.getMediaConstraints = getMediaConstraints;
3752
3880
  exports.getMediaRecorderOptions = getMediaRecorderOptions;
3753
3881
  exports.openBroadcastPopup = openBroadcastPopup;
3754
- exports.openBroadcastStreamerPopup = openBroadcastStreamerPopup;
3755
- exports.useDialTribe = useDialTribe;
3756
- exports.useDialTribeOptional = useDialTribeOptional;
3757
- //# sourceMappingURL=broadcast-streamer.js.map
3758
- //# sourceMappingURL=broadcast-streamer.js.map
3882
+ exports.openDialtribeStreamerPopup = openDialtribeStreamerPopup;
3883
+ exports.useDialtribe = useDialtribe;
3884
+ exports.useDialtribeOptional = useDialtribeOptional;
3885
+ exports.useDialtribeStreamerLauncher = useDialtribeStreamerLauncher;
3886
+ exports.useDialtribeStreamerPopup = useDialtribeStreamerPopup;
3887
+ //# sourceMappingURL=dialtribe-streamer.js.map
3888
+ //# sourceMappingURL=dialtribe-streamer.js.map