@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.
package/dist/index.js CHANGED
@@ -1,11 +1,13 @@
1
1
  'use strict';
2
2
 
3
3
  var jsxRuntime = require('react/jsx-runtime');
4
- var react = require('react');
4
+ var React2 = require('react');
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
13
  // src/components/HelloWorld.tsx
@@ -27,17 +29,17 @@ function HelloWorld({ name = "World" }) {
27
29
  /* @__PURE__ */ jsxRuntime.jsx("p", { style: { margin: 0, fontSize: "14px" }, children: "@dialtribe/react-sdk is working correctly" })
28
30
  ] });
29
31
  }
30
- var DialTribeContext = react.createContext(null);
31
- function DialTribeProvider({
32
+ var DialtribeContext = React2.createContext(null);
33
+ function DialtribeProvider({
32
34
  sessionToken: initialToken,
33
35
  onTokenRefresh,
34
36
  onTokenExpired,
35
37
  apiBaseUrl,
36
38
  children
37
39
  }) {
38
- const [sessionToken, setSessionTokenState] = react.useState(initialToken);
39
- const [isExpired, setIsExpired] = react.useState(false);
40
- const setSessionToken = react.useCallback(
40
+ const [sessionToken, setSessionTokenState] = React2.useState(initialToken);
41
+ const [isExpired, setIsExpired] = React2.useState(false);
42
+ const setSessionToken = React2.useCallback(
41
43
  (newToken, expiresAt) => {
42
44
  setSessionTokenState(newToken);
43
45
  setIsExpired(false);
@@ -47,11 +49,11 @@ function DialTribeProvider({
47
49
  },
48
50
  [onTokenRefresh]
49
51
  );
50
- const markExpired = react.useCallback(() => {
52
+ const markExpired = React2.useCallback(() => {
51
53
  setIsExpired(true);
52
54
  onTokenExpired?.();
53
55
  }, [onTokenExpired]);
54
- react.useEffect(() => {
56
+ React2.useEffect(() => {
55
57
  if (initialToken !== sessionToken) {
56
58
  setSessionTokenState(initialToken);
57
59
  setIsExpired(false);
@@ -64,22 +66,22 @@ function DialTribeProvider({
64
66
  markExpired,
65
67
  apiBaseUrl
66
68
  };
67
- return /* @__PURE__ */ jsxRuntime.jsx(DialTribeContext.Provider, { value, children });
69
+ return /* @__PURE__ */ jsxRuntime.jsx(DialtribeContext.Provider, { value, children });
68
70
  }
69
- function useDialTribe() {
70
- const context = react.useContext(DialTribeContext);
71
+ function useDialtribe() {
72
+ const context = React2.useContext(DialtribeContext);
71
73
  if (!context) {
72
74
  throw new Error(
73
- 'useDialTribe must be used within a DialTribeProvider. Wrap your app with <DialTribeProvider sessionToken="sess_xxx">...</DialTribeProvider>'
75
+ 'useDialtribe must be used within a DialtribeProvider. Wrap your app with <DialtribeProvider sessionToken="sess_xxx">...</DialtribeProvider>'
74
76
  );
75
77
  }
76
78
  return context;
77
79
  }
78
- function useDialTribeOptional() {
79
- return react.useContext(DialTribeContext);
80
+ function useDialtribeOptional() {
81
+ return React2.useContext(DialtribeContext);
80
82
  }
81
83
 
82
- // src/client/DialTribeClient.ts
84
+ // src/client/DialtribeClient.ts
83
85
  function getDefaultApiBaseUrl() {
84
86
  if (typeof process !== "undefined" && process.env?.NEXT_PUBLIC_DIALTRIBE_API_URL) {
85
87
  return process.env.NEXT_PUBLIC_DIALTRIBE_API_URL;
@@ -93,18 +95,19 @@ function getEndpoints(baseUrl = DIALTRIBE_API_BASE) {
93
95
  broadcast: (id) => `${baseUrl}/broadcasts/${id}`,
94
96
  contentPlay: `${baseUrl}/content/play`,
95
97
  presignedUrl: `${baseUrl}/media/presigned-url`,
96
- sessionStart: `${baseUrl}/session/start`,
97
- sessionPing: `${baseUrl}/session/ping`
98
+ audienceStart: `${baseUrl}/audiences/start`,
99
+ audiencePing: `${baseUrl}/audiences/ping`,
100
+ sessionPing: `${baseUrl}/sessions/ping`
98
101
  };
99
102
  }
100
103
  var ENDPOINTS = getEndpoints();
101
- var DialTribeClient = class {
104
+ var DialtribeClient = class {
102
105
  constructor(config) {
103
106
  this.config = config;
104
107
  this.endpoints = config.apiBaseUrl ? getEndpoints(config.apiBaseUrl) : ENDPOINTS;
105
108
  }
106
109
  /**
107
- * Make an authenticated request to DialTribe API
110
+ * Make an authenticated request to Dialtribe API
108
111
  *
109
112
  * Automatically:
110
113
  * - Adds Authorization header with session token
@@ -218,7 +221,7 @@ var DialTribeClient = class {
218
221
  * @returns audienceId and optional resumePosition
219
222
  */
220
223
  async startSession(params) {
221
- const response = await this.fetch(this.endpoints.sessionStart, {
224
+ const response = await this.fetch(this.endpoints.audienceStart, {
222
225
  method: "POST",
223
226
  body: JSON.stringify(params)
224
227
  });
@@ -237,7 +240,7 @@ var DialTribeClient = class {
237
240
  * - 3: UNMOUNT
238
241
  */
239
242
  async sendSessionPing(params) {
240
- const response = await this.fetch(this.endpoints.sessionPing, {
243
+ const response = await this.fetch(this.endpoints.audiencePing, {
241
244
  method: "POST",
242
245
  body: JSON.stringify(params)
243
246
  });
@@ -256,18 +259,18 @@ function AudioWaveform({
256
259
  isPlaying = false,
257
260
  isLive = false
258
261
  }) {
259
- const canvasRef = react.useRef(null);
260
- const animationFrameRef = react.useRef(void 0);
261
- const [setupError, setSetupError] = react.useState(false);
262
- const isPlayingRef = react.useRef(isPlaying);
263
- const isLiveRef = react.useRef(isLive);
264
- react.useEffect(() => {
262
+ const canvasRef = React2.useRef(null);
263
+ const animationFrameRef = React2.useRef(void 0);
264
+ const [setupError, setSetupError] = React2.useState(false);
265
+ const isPlayingRef = React2.useRef(isPlaying);
266
+ const isLiveRef = React2.useRef(isLive);
267
+ React2.useEffect(() => {
265
268
  isPlayingRef.current = isPlaying;
266
269
  }, [isPlaying]);
267
- react.useEffect(() => {
270
+ React2.useEffect(() => {
268
271
  isLiveRef.current = isLive;
269
272
  }, [isLive]);
270
- react.useEffect(() => {
273
+ React2.useEffect(() => {
271
274
  const canvas = canvasRef.current;
272
275
  if (!canvas) return;
273
276
  const ctx = canvas.getContext("2d");
@@ -769,7 +772,7 @@ function getErrorMessage(error) {
769
772
  }
770
773
  return "Unable to play media. Please try refreshing the page or contact support if the problem persists.";
771
774
  }
772
- function BroadcastPlayer({
775
+ function DialtribePlayer({
773
776
  broadcast,
774
777
  appId,
775
778
  contentId,
@@ -780,18 +783,18 @@ function BroadcastPlayer({
780
783
  className = "",
781
784
  enableKeyboardShortcuts = false
782
785
  }) {
783
- const { sessionToken, setSessionToken, markExpired, apiBaseUrl } = useDialTribe();
784
- const clientRef = react.useRef(null);
786
+ const { sessionToken, setSessionToken, markExpired, apiBaseUrl } = useDialtribe();
787
+ const clientRef = React2.useRef(null);
785
788
  if (!clientRef.current && sessionToken) {
786
- clientRef.current = new DialTribeClient({
789
+ clientRef.current = new DialtribeClient({
787
790
  sessionToken,
788
791
  apiBaseUrl,
789
792
  onTokenRefresh: (newToken, expiresAt) => {
790
- debug.log(`[DialTribeClient] Token refreshed, expires at ${expiresAt}`);
793
+ debug.log(`[DialtribeClient] Token refreshed, expires at ${expiresAt}`);
791
794
  setSessionToken(newToken, expiresAt);
792
795
  },
793
796
  onTokenExpired: () => {
794
- debug.error("[DialTribeClient] Token expired");
797
+ debug.error("[DialtribeClient] Token expired");
795
798
  markExpired();
796
799
  }
797
800
  });
@@ -799,35 +802,35 @@ function BroadcastPlayer({
799
802
  clientRef.current.setSessionToken(sessionToken);
800
803
  }
801
804
  const client = clientRef.current;
802
- const playerRef = react.useRef(null);
803
- const transcriptContainerRef = react.useRef(null);
804
- const activeWordRef = react.useRef(null);
805
- const [audioElement, setAudioElement] = react.useState(null);
806
- const [playing, setPlaying] = react.useState(false);
807
- const [played, setPlayed] = react.useState(0);
808
- const [duration, setDuration] = react.useState(0);
809
- const [volume, setVolume] = react.useState(1);
810
- const [muted, setMuted] = react.useState(false);
811
- const [seeking, setSeeking] = react.useState(false);
812
- const [hasError, setHasError] = react.useState(false);
813
- const [errorMessage, setErrorMessage] = react.useState("");
814
- const [hasEnded, setHasEnded] = react.useState(false);
815
- const [hasStreamEnded, setHasStreamEnded] = react.useState(false);
816
- const [showTranscript, setShowTranscript] = react.useState(false);
817
- const [transcriptData, setTranscriptData] = react.useState(null);
818
- const [currentTime, setCurrentTime] = react.useState(0);
819
- const [isLoadingTranscript, setIsLoadingTranscript] = react.useState(false);
820
- const [isLoadingVideo, setIsLoadingVideo] = react.useState(true);
821
- const [autoScrollEnabled, setAutoScrollEnabled] = react.useState(true);
822
- const isScrollingProgrammatically = react.useRef(false);
823
- const lastActiveWordIndex = react.useRef(-1);
824
- const [showClipCreator, setShowClipCreator] = react.useState(false);
825
- const initialPlaybackTypeRef = react.useRef(null);
826
- const [currentPlaybackInfo, setCurrentPlaybackInfo] = react.useState(null);
827
- const [urlExpiresAt, setUrlExpiresAt] = react.useState(null);
828
- const isRefreshingUrl = react.useRef(false);
829
- const [audienceId, setAudienceId] = react.useState(null);
830
- const [sessionId] = react.useState(() => {
805
+ const playerRef = React2.useRef(null);
806
+ const transcriptContainerRef = React2.useRef(null);
807
+ const activeWordRef = React2.useRef(null);
808
+ const [audioElement, setAudioElement] = React2.useState(null);
809
+ const [playing, setPlaying] = React2.useState(false);
810
+ const [played, setPlayed] = React2.useState(0);
811
+ const [duration, setDuration] = React2.useState(0);
812
+ const [volume, setVolume] = React2.useState(1);
813
+ const [muted, setMuted] = React2.useState(false);
814
+ const [seeking, setSeeking] = React2.useState(false);
815
+ const [hasError, setHasError] = React2.useState(false);
816
+ const [errorMessage, setErrorMessage] = React2.useState("");
817
+ const [hasEnded, setHasEnded] = React2.useState(false);
818
+ const [hasStreamEnded, setHasStreamEnded] = React2.useState(false);
819
+ const [showTranscript, setShowTranscript] = React2.useState(false);
820
+ const [transcriptData, setTranscriptData] = React2.useState(null);
821
+ const [currentTime, setCurrentTime] = React2.useState(0);
822
+ const [isLoadingTranscript, setIsLoadingTranscript] = React2.useState(false);
823
+ const [isLoadingVideo, setIsLoadingVideo] = React2.useState(true);
824
+ const [autoScrollEnabled, setAutoScrollEnabled] = React2.useState(true);
825
+ const isScrollingProgrammatically = React2.useRef(false);
826
+ const lastActiveWordIndex = React2.useRef(-1);
827
+ const [showClipCreator, setShowClipCreator] = React2.useState(false);
828
+ const initialPlaybackTypeRef = React2.useRef(null);
829
+ const [currentPlaybackInfo, setCurrentPlaybackInfo] = React2.useState(null);
830
+ const [urlExpiresAt, setUrlExpiresAt] = React2.useState(null);
831
+ const isRefreshingUrl = React2.useRef(false);
832
+ const [audienceId, setAudienceId] = React2.useState(null);
833
+ const [sessionId] = React2.useState(() => {
831
834
  if (typeof crypto !== "undefined" && crypto.randomUUID) {
832
835
  return crypto.randomUUID();
833
836
  }
@@ -837,9 +840,9 @@ function BroadcastPlayer({
837
840
  return v.toString(16);
838
841
  });
839
842
  });
840
- const heartbeatIntervalRef = react.useRef(null);
841
- const hasInitializedSession = react.useRef(false);
842
- const refreshPresignedUrl = react.useCallback(
843
+ const heartbeatIntervalRef = React2.useRef(null);
844
+ const hasInitializedSession = React2.useRef(false);
845
+ const refreshPresignedUrl = React2.useCallback(
843
846
  async (fileType) => {
844
847
  if (!broadcast.hash || isRefreshingUrl.current || !client) {
845
848
  debug.log("[URL Refresh] Skipping refresh - no hash, already refreshing, or no client");
@@ -890,7 +893,7 @@ function BroadcastPlayer({
890
893
  if (width < 1024) return "tablet";
891
894
  return "desktop";
892
895
  };
893
- const initializeTrackingSession = react.useCallback(async () => {
896
+ const initializeTrackingSession = React2.useCallback(async () => {
894
897
  if (!contentId || !appId || !client) return;
895
898
  if (currentPlaybackInfo?.type === "hls" && broadcast.broadcastStatus === 1) return;
896
899
  if (hasInitializedSession.current) return;
@@ -925,7 +928,7 @@ function BroadcastPlayer({
925
928
  }
926
929
  }
927
930
  }, [contentId, appId, broadcast.id, broadcast.broadcastStatus, foreignId, foreignTier, sessionId, currentPlaybackInfo?.type, audioElement, client, onError]);
928
- const sendTrackingPing = react.useCallback(
931
+ const sendTrackingPing = React2.useCallback(
929
932
  async (eventType) => {
930
933
  if (!audienceId || !sessionId || !client) return;
931
934
  try {
@@ -963,7 +966,7 @@ function BroadcastPlayer({
963
966
  }
964
967
  return null;
965
968
  };
966
- react.useEffect(() => {
969
+ React2.useEffect(() => {
967
970
  if (!currentPlaybackInfo) {
968
971
  const info = getPlaybackInfo();
969
972
  setCurrentPlaybackInfo(info);
@@ -979,12 +982,12 @@ function BroadcastPlayer({
979
982
  }
980
983
  }
981
984
  }, [currentPlaybackInfo]);
982
- react.useEffect(() => {
985
+ React2.useEffect(() => {
983
986
  if (currentPlaybackInfo?.url) {
984
987
  setIsLoadingVideo(true);
985
988
  }
986
989
  }, [currentPlaybackInfo?.url]);
987
- react.useEffect(() => {
990
+ React2.useEffect(() => {
988
991
  if (!urlExpiresAt || !currentPlaybackInfo?.type) return;
989
992
  const checkExpiration = () => {
990
993
  const now = /* @__PURE__ */ new Date();
@@ -1003,7 +1006,7 @@ function BroadcastPlayer({
1003
1006
  clearInterval(interval);
1004
1007
  };
1005
1008
  }, [urlExpiresAt, currentPlaybackInfo?.type, refreshPresignedUrl]);
1006
- react.useEffect(() => {
1009
+ React2.useEffect(() => {
1007
1010
  if (initialPlaybackTypeRef.current === "hls" && currentPlaybackInfo?.type === "hls" && broadcast.broadcastStatus !== 1 && broadcast.recordingMp3Url && broadcast.hash && parseInt(broadcast.mp3Size || "0") > 0) {
1008
1011
  const secureUrl = buildPlaybackUrl(broadcast.id, broadcast.hash);
1009
1012
  setCurrentPlaybackInfo({ url: secureUrl, type: "mp3" });
@@ -1039,22 +1042,22 @@ function BroadcastPlayer({
1039
1042
  setHasEnded(true);
1040
1043
  }
1041
1044
  };
1042
- react.useEffect(() => {
1045
+ React2.useEffect(() => {
1043
1046
  if (broadcast.durationSeconds && broadcast.durationSeconds > 0) {
1044
1047
  setDuration(broadcast.durationSeconds);
1045
1048
  }
1046
1049
  }, [broadcast.durationSeconds]);
1047
- react.useEffect(() => {
1050
+ React2.useEffect(() => {
1048
1051
  if (isLiveStream && !playing) {
1049
1052
  setPlaying(true);
1050
1053
  }
1051
1054
  }, [isLiveStream, playing]);
1052
- react.useEffect(() => {
1055
+ React2.useEffect(() => {
1053
1056
  if (currentPlaybackInfo && audioElement && !hasInitializedSession.current) {
1054
1057
  initializeTrackingSession();
1055
1058
  }
1056
1059
  }, [currentPlaybackInfo, audioElement, initializeTrackingSession]);
1057
- react.useEffect(() => {
1060
+ React2.useEffect(() => {
1058
1061
  if (playing && audienceId) {
1059
1062
  sendTrackingPing(1);
1060
1063
  heartbeatIntervalRef.current = setInterval(() => {
@@ -1074,7 +1077,7 @@ function BroadcastPlayer({
1074
1077
  }
1075
1078
  }
1076
1079
  }, [playing, audienceId, sendTrackingPing]);
1077
- react.useEffect(() => {
1080
+ React2.useEffect(() => {
1078
1081
  return () => {
1079
1082
  if (audienceId && sessionId && sessionToken) {
1080
1083
  const payload = {
@@ -1099,7 +1102,7 @@ function BroadcastPlayer({
1099
1102
  }
1100
1103
  };
1101
1104
  }, [audienceId, sessionId, sessionToken, audioElement, duration]);
1102
- react.useEffect(() => {
1105
+ React2.useEffect(() => {
1103
1106
  if (broadcast.transcriptUrl && broadcast.transcriptStatus === 2 && !transcriptData) {
1104
1107
  setIsLoadingTranscript(true);
1105
1108
  fetch(broadcast.transcriptUrl).then((res) => {
@@ -1130,7 +1133,7 @@ function BroadcastPlayer({
1130
1133
  });
1131
1134
  }
1132
1135
  }, [broadcast.transcriptUrl, broadcast.transcriptStatus, transcriptData]);
1133
- react.useEffect(() => {
1136
+ React2.useEffect(() => {
1134
1137
  if (!audioElement) return;
1135
1138
  const handleTimeUpdate2 = () => {
1136
1139
  setCurrentTime(audioElement.currentTime);
@@ -1138,7 +1141,7 @@ function BroadcastPlayer({
1138
1141
  audioElement.addEventListener("timeupdate", handleTimeUpdate2);
1139
1142
  return () => audioElement.removeEventListener("timeupdate", handleTimeUpdate2);
1140
1143
  }, [audioElement]);
1141
- react.useEffect(() => {
1144
+ React2.useEffect(() => {
1142
1145
  if (showTranscript && autoScrollEnabled && activeWordRef.current && transcriptContainerRef.current) {
1143
1146
  const container = transcriptContainerRef.current;
1144
1147
  const activeWord = activeWordRef.current;
@@ -1153,7 +1156,7 @@ function BroadcastPlayer({
1153
1156
  }
1154
1157
  }
1155
1158
  }, [currentTime, showTranscript, autoScrollEnabled]);
1156
- react.useEffect(() => {
1159
+ React2.useEffect(() => {
1157
1160
  if (!showTranscript || !transcriptContainerRef.current) return;
1158
1161
  const container = transcriptContainerRef.current;
1159
1162
  const handleScroll = () => {
@@ -1236,10 +1239,10 @@ function BroadcastPlayer({
1236
1239
  setAudioElement(internalPlayer);
1237
1240
  }
1238
1241
  } catch (error) {
1239
- debug.error("[BroadcastPlayer] Error getting internal player:", error);
1242
+ debug.error("[DialtribePlayer] Error getting internal player:", error);
1240
1243
  }
1241
1244
  };
1242
- react.useEffect(() => {
1245
+ React2.useEffect(() => {
1243
1246
  const findAudioElement = () => {
1244
1247
  const videoElements = document.querySelectorAll("video, audio");
1245
1248
  if (videoElements.length > 0) {
@@ -1259,7 +1262,7 @@ function BroadcastPlayer({
1259
1262
  return () => timeouts.forEach(clearTimeout);
1260
1263
  }
1261
1264
  }, [playbackUrl]);
1262
- react.useEffect(() => {
1265
+ React2.useEffect(() => {
1263
1266
  if (playing && !audioElement) {
1264
1267
  const videoElements = document.querySelectorAll("video, audio");
1265
1268
  if (videoElements.length > 0) {
@@ -1338,7 +1341,7 @@ function BroadcastPlayer({
1338
1341
  onError(error);
1339
1342
  }
1340
1343
  };
1341
- const handleRetry = react.useCallback(() => {
1344
+ const handleRetry = React2.useCallback(() => {
1342
1345
  setHasError(false);
1343
1346
  setErrorMessage("");
1344
1347
  setIsLoadingVideo(true);
@@ -1361,7 +1364,7 @@ function BroadcastPlayer({
1361
1364
  }
1362
1365
  }
1363
1366
  };
1364
- react.useEffect(() => {
1367
+ React2.useEffect(() => {
1365
1368
  if (!enableKeyboardShortcuts) return;
1366
1369
  const seekBy = (seconds) => {
1367
1370
  if (!audioElement || duration <= 0) return;
@@ -1444,7 +1447,7 @@ function BroadcastPlayer({
1444
1447
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-center p-8", children: /* @__PURE__ */ jsxRuntime.jsx(LoadingSpinner, { variant: "white", text: "Loading..." }) });
1445
1448
  }
1446
1449
  const hasTranscript = broadcast.transcriptStatus === 2 && transcriptData && (transcriptData.segments && transcriptData.segments.some((s) => s.words && s.words.length > 0) || transcriptData.words && transcriptData.words.length > 0);
1447
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `bg-black rounded-lg shadow-2xl w-full max-h-full flex flex-col overflow-hidden ${className}`, children: [
1450
+ 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: [
1448
1451
  /* @__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: [
1449
1452
  /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
1450
1453
  /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-lg font-semibold text-white", children: broadcast.streamKeyRecord?.foreignName || "Broadcast" }),
@@ -1976,90 +1979,9 @@ function BroadcastPlayer({
1976
1979
  }
1977
1980
  ` })
1978
1981
  ] });
1982
+ return playerContent;
1979
1983
  }
1980
- function BroadcastPlayerModal({
1981
- broadcast,
1982
- isOpen,
1983
- onClose,
1984
- appId,
1985
- contentId,
1986
- foreignId,
1987
- foreignTier,
1988
- renderClipCreator,
1989
- className,
1990
- enableKeyboardShortcuts = false
1991
- }) {
1992
- const closeButtonRef = react.useRef(null);
1993
- const previousActiveElement = react.useRef(null);
1994
- react.useEffect(() => {
1995
- if (!isOpen) return;
1996
- previousActiveElement.current = document.activeElement;
1997
- setTimeout(() => {
1998
- closeButtonRef.current?.focus();
1999
- }, 100);
2000
- return () => {
2001
- if (previousActiveElement.current) {
2002
- previousActiveElement.current.focus();
2003
- }
2004
- };
2005
- }, [isOpen]);
2006
- react.useEffect(() => {
2007
- if (!isOpen) return;
2008
- const handleKeyDown = (e) => {
2009
- if (e.key === "Escape") {
2010
- onClose();
2011
- }
2012
- };
2013
- document.addEventListener("keydown", handleKeyDown);
2014
- return () => document.removeEventListener("keydown", handleKeyDown);
2015
- }, [isOpen, onClose]);
2016
- if (!isOpen) return null;
2017
- const handleBackdropClick = (e) => {
2018
- if (e.target === e.currentTarget) {
2019
- onClose();
2020
- }
2021
- };
2022
- return /* @__PURE__ */ jsxRuntime.jsx(
2023
- "div",
2024
- {
2025
- className: "fixed inset-0 bg-black/70 backdrop-blur-xl flex items-center justify-center z-50 p-2 sm:p-4",
2026
- onClick: handleBackdropClick,
2027
- role: "dialog",
2028
- "aria-modal": "true",
2029
- "aria-label": "Broadcast player",
2030
- children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative w-full max-w-7xl max-h-[95vh] sm:max-h-[90vh] overflow-hidden", children: [
2031
- /* @__PURE__ */ jsxRuntime.jsx(
2032
- "button",
2033
- {
2034
- ref: closeButtonRef,
2035
- onClick: onClose,
2036
- 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",
2037
- title: "Close (ESC)",
2038
- "aria-label": "Close player",
2039
- children: "\xD7"
2040
- }
2041
- ),
2042
- /* @__PURE__ */ jsxRuntime.jsx(
2043
- BroadcastPlayer,
2044
- {
2045
- broadcast,
2046
- appId,
2047
- contentId,
2048
- foreignId,
2049
- foreignTier,
2050
- renderClipCreator,
2051
- className,
2052
- enableKeyboardShortcuts,
2053
- onError: (error) => {
2054
- debug.error("[BroadcastPlayerModal] Player error:", error);
2055
- }
2056
- }
2057
- )
2058
- ] })
2059
- }
2060
- );
2061
- }
2062
- var BroadcastPlayerErrorBoundary = class extends react.Component {
1984
+ var DialtribePlayerErrorBoundary = class extends React2.Component {
2063
1985
  constructor(props) {
2064
1986
  super(props);
2065
1987
  this.handleReset = () => {
@@ -2185,6 +2107,84 @@ var BroadcastPlayerErrorBoundary = class extends react.Component {
2185
2107
  return this.props.children;
2186
2108
  }
2187
2109
  };
2110
+ var overlayStyles = {
2111
+ modal: {
2112
+ backdrop: "bg-black/70 backdrop-blur-xl p-2 sm:p-4",
2113
+ container: "max-w-7xl max-h-[95vh] sm:max-h-[90vh]"
2114
+ },
2115
+ fullscreen: {
2116
+ backdrop: "bg-black",
2117
+ container: "h-full"
2118
+ }
2119
+ };
2120
+ function DialtribeOverlay({
2121
+ isOpen,
2122
+ onClose,
2123
+ mode = "modal",
2124
+ children,
2125
+ ariaLabel = "Dialog",
2126
+ showCloseButton = true,
2127
+ closeOnBackdropClick = true,
2128
+ closeOnEsc = true
2129
+ }) {
2130
+ const closeButtonRef = React2.useRef(null);
2131
+ const previousActiveElement = React2.useRef(null);
2132
+ React2.useEffect(() => {
2133
+ if (!isOpen) return;
2134
+ previousActiveElement.current = document.activeElement;
2135
+ setTimeout(() => {
2136
+ closeButtonRef.current?.focus();
2137
+ }, 100);
2138
+ return () => {
2139
+ if (previousActiveElement.current) {
2140
+ previousActiveElement.current.focus();
2141
+ }
2142
+ };
2143
+ }, [isOpen]);
2144
+ React2.useEffect(() => {
2145
+ if (!isOpen || !closeOnEsc) return;
2146
+ const handleKeyDown = (e) => {
2147
+ if (e.key === "Escape") {
2148
+ onClose();
2149
+ }
2150
+ };
2151
+ document.addEventListener("keydown", handleKeyDown);
2152
+ return () => document.removeEventListener("keydown", handleKeyDown);
2153
+ }, [isOpen, onClose, closeOnEsc]);
2154
+ if (!isOpen) {
2155
+ return null;
2156
+ }
2157
+ const handleBackdropClick = (e) => {
2158
+ if (closeOnBackdropClick && e.target === e.currentTarget) {
2159
+ onClose();
2160
+ }
2161
+ };
2162
+ const styles = overlayStyles[mode];
2163
+ return /* @__PURE__ */ jsxRuntime.jsx(
2164
+ "div",
2165
+ {
2166
+ className: `fixed inset-0 flex items-center justify-center z-50 ${styles.backdrop}`,
2167
+ onClick: handleBackdropClick,
2168
+ role: "dialog",
2169
+ "aria-modal": "true",
2170
+ "aria-label": ariaLabel,
2171
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `relative w-full overflow-hidden ${styles.container}`, children: [
2172
+ showCloseButton && /* @__PURE__ */ jsxRuntime.jsx(
2173
+ "button",
2174
+ {
2175
+ ref: closeButtonRef,
2176
+ onClick: onClose,
2177
+ 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",
2178
+ title: "Close (ESC)",
2179
+ "aria-label": "Close",
2180
+ children: "\xD7"
2181
+ }
2182
+ ),
2183
+ children
2184
+ ] })
2185
+ }
2186
+ );
2187
+ }
2188
2188
 
2189
2189
  // src/utils/media-constraints.ts
2190
2190
  function getMediaConstraints(options) {
@@ -2560,8 +2560,8 @@ function StreamKeyDisplay({
2560
2560
  layout = "vertical",
2561
2561
  darkMode = false
2562
2562
  }) {
2563
- const [isRevealed, setIsRevealed] = react.useState(false);
2564
- const [copySuccess, setCopySuccess] = react.useState(false);
2563
+ const [isRevealed, setIsRevealed] = React2.useState(false);
2564
+ const [copySuccess, setCopySuccess] = React2.useState(false);
2565
2565
  const obscureStreamKey = (key) => {
2566
2566
  if (key.length <= 12) {
2567
2567
  return "\u2022".repeat(key.length);
@@ -2669,9 +2669,9 @@ function StreamingControls({
2669
2669
  onAudioDeviceChange,
2670
2670
  mediaStream
2671
2671
  }) {
2672
- const [duration, setDuration] = react.useState(0);
2673
- const [showSettings, setShowSettings] = react.useState(false);
2674
- react.useEffect(() => {
2672
+ const [duration, setDuration] = React2.useState(0);
2673
+ const [showSettings, setShowSettings] = React2.useState(false);
2674
+ React2.useEffect(() => {
2675
2675
  if (state !== "live" || !startTime) return;
2676
2676
  const interval = setInterval(() => {
2677
2677
  const elapsed = Math.floor((Date.now() - startTime.getTime()) / 1e3);
@@ -3004,8 +3004,8 @@ function StreamingControls({
3004
3004
  ] });
3005
3005
  }
3006
3006
  function StreamKeyInput({ onSubmit, inline = false }) {
3007
- const [streamKey, setStreamKey] = react.useState("");
3008
- const [error, setError] = react.useState("");
3007
+ const [streamKey, setStreamKey] = React2.useState("");
3008
+ const [error, setError] = React2.useState("");
3009
3009
  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";
3010
3010
  const validateStreamKey = (key) => {
3011
3011
  const pattern = /^[abvw][a-zA-Z0-9]+_.+$/;
@@ -3071,7 +3071,7 @@ function StreamKeyInput({ onSubmit, inline = false }) {
3071
3071
  ] })
3072
3072
  ] }) });
3073
3073
  }
3074
- function BroadcastStreamer({
3074
+ function DialtribeStreamer({
3075
3075
  sessionToken: propSessionToken,
3076
3076
  streamKey: initialStreamKey,
3077
3077
  onDone,
@@ -3080,35 +3080,35 @@ function BroadcastStreamer({
3080
3080
  apiBaseUrl = DIALTRIBE_API_BASE,
3081
3081
  inline = false
3082
3082
  }) {
3083
- const containerClass = inline ? "dialtribe-broadcast-streamer h-full w-full bg-black relative" : "dialtribe-broadcast-streamer min-h-screen bg-black";
3084
- 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";
3085
- const dialTribeContext = useDialTribeOptional();
3083
+ const containerClass = inline ? "dialtribe-dialtribe-streamer h-full w-full bg-black relative" : "dialtribe-dialtribe-streamer min-h-screen bg-black";
3084
+ 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";
3085
+ const dialTribeContext = useDialtribeOptional();
3086
3086
  const sessionToken = propSessionToken ?? dialTribeContext?.sessionToken ?? null;
3087
- const [streamKey, setStreamKey] = react.useState(initialStreamKey || null);
3088
- const [state, setState] = react.useState("idle");
3089
- react.useEffect(() => {
3087
+ const [streamKey, setStreamKey] = React2.useState(initialStreamKey || null);
3088
+ const [state, setState] = React2.useState("idle");
3089
+ React2.useEffect(() => {
3090
3090
  if (initialStreamKey && initialStreamKey !== streamKey) {
3091
3091
  setStreamKey(initialStreamKey);
3092
3092
  }
3093
3093
  }, [initialStreamKey]);
3094
- const [error, setError] = react.useState(null);
3095
- const [mediaStream, setMediaStream] = react.useState(null);
3096
- const [streamer, setStreamer] = react.useState(null);
3097
- const [bytesSent, setBytesSent] = react.useState(0);
3098
- const [startTime, setStartTime] = react.useState(null);
3099
- const [isMuted, setIsMuted] = react.useState(false);
3100
- const [isVideoEnabled, setIsVideoEnabled] = react.useState(true);
3101
- const [facingMode, setFacingMode] = react.useState("user");
3102
- const [showStopConfirm, setShowStopConfirm] = react.useState(false);
3103
- const [showCloseConfirm, setShowCloseConfirm] = react.useState(false);
3104
- const [hasMultipleCameras, setHasMultipleCameras] = react.useState(false);
3105
- const [videoDevices, setVideoDevices] = react.useState([]);
3106
- const [audioDevices, setAudioDevices] = react.useState([]);
3107
- const [selectedVideoDeviceId, setSelectedVideoDeviceId] = react.useState();
3108
- const [selectedAudioDeviceId, setSelectedAudioDeviceId] = react.useState();
3109
- const videoRef = react.useRef(null);
3110
- const streamerRef = react.useRef(null);
3111
- const mediaStreamRef = react.useRef(null);
3094
+ const [error, setError] = React2.useState(null);
3095
+ const [mediaStream, setMediaStream] = React2.useState(null);
3096
+ const [streamer, setStreamer] = React2.useState(null);
3097
+ const [bytesSent, setBytesSent] = React2.useState(0);
3098
+ const [startTime, setStartTime] = React2.useState(null);
3099
+ const [isMuted, setIsMuted] = React2.useState(false);
3100
+ const [isVideoEnabled, setIsVideoEnabled] = React2.useState(true);
3101
+ const [facingMode, setFacingMode] = React2.useState("user");
3102
+ const [showStopConfirm, setShowStopConfirm] = React2.useState(false);
3103
+ const [showCloseConfirm, setShowCloseConfirm] = React2.useState(false);
3104
+ const [hasMultipleCameras, setHasMultipleCameras] = React2.useState(false);
3105
+ const [videoDevices, setVideoDevices] = React2.useState([]);
3106
+ const [audioDevices, setAudioDevices] = React2.useState([]);
3107
+ const [selectedVideoDeviceId, setSelectedVideoDeviceId] = React2.useState();
3108
+ const [selectedAudioDeviceId, setSelectedAudioDeviceId] = React2.useState();
3109
+ const videoRef = React2.useRef(null);
3110
+ const streamerRef = React2.useRef(null);
3111
+ const mediaStreamRef = React2.useRef(null);
3112
3112
  const isVideoKey = streamKey ? streamKey.startsWith("v") || streamKey.startsWith("w") : false;
3113
3113
  const handleStreamKeySubmit = (key) => {
3114
3114
  setStreamKey(key);
@@ -3118,7 +3118,7 @@ function BroadcastStreamer({
3118
3118
  setStreamKey(key);
3119
3119
  onStreamKeyChange?.(key);
3120
3120
  };
3121
- react.useEffect(() => {
3121
+ React2.useEffect(() => {
3122
3122
  if (!streamKey) return;
3123
3123
  const compat = checkBrowserCompatibility();
3124
3124
  if (!compat.compatible) {
@@ -3156,13 +3156,13 @@ function BroadcastStreamer({
3156
3156
  setHasMultipleCameras(false);
3157
3157
  }
3158
3158
  };
3159
- react.useEffect(() => {
3159
+ React2.useEffect(() => {
3160
3160
  streamerRef.current = streamer;
3161
3161
  }, [streamer]);
3162
- react.useEffect(() => {
3162
+ React2.useEffect(() => {
3163
3163
  mediaStreamRef.current = mediaStream;
3164
3164
  }, [mediaStream]);
3165
- react.useEffect(() => {
3165
+ React2.useEffect(() => {
3166
3166
  return () => {
3167
3167
  if (streamerRef.current) {
3168
3168
  streamerRef.current.stop();
@@ -3172,7 +3172,7 @@ function BroadcastStreamer({
3172
3172
  }
3173
3173
  };
3174
3174
  }, []);
3175
- react.useEffect(() => {
3175
+ React2.useEffect(() => {
3176
3176
  if (state === "live") {
3177
3177
  const handleBeforeUnload = (e) => {
3178
3178
  e.preventDefault();
@@ -3183,7 +3183,7 @@ function BroadcastStreamer({
3183
3183
  return () => window.removeEventListener("beforeunload", handleBeforeUnload);
3184
3184
  }
3185
3185
  }, [state]);
3186
- react.useEffect(() => {
3186
+ React2.useEffect(() => {
3187
3187
  if (videoRef.current && mediaStream) {
3188
3188
  videoRef.current.srcObject = mediaStream;
3189
3189
  }
@@ -3466,36 +3466,9 @@ function BroadcastStreamer({
3466
3466
  }
3467
3467
  };
3468
3468
  if (!sessionToken) {
3469
- 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: [
3470
- /* @__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(
3471
- "svg",
3472
- {
3473
- className: "w-8 h-8 text-red-600 dark:text-red-400",
3474
- fill: "none",
3475
- stroke: "currentColor",
3476
- viewBox: "0 0 24 24",
3477
- children: /* @__PURE__ */ jsxRuntime.jsx(
3478
- "path",
3479
- {
3480
- strokeLinecap: "round",
3481
- strokeLinejoin: "round",
3482
- strokeWidth: 2,
3483
- 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"
3484
- }
3485
- )
3486
- }
3487
- ) }),
3488
- /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-xl font-bold text-black dark:text-white mb-2", children: "Authentication Required" }),
3489
- /* @__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." }),
3490
- /* @__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." }),
3491
- /* @__PURE__ */ jsxRuntime.jsx(
3492
- "button",
3493
- {
3494
- onClick: handleDone,
3495
- 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",
3496
- children: "Close"
3497
- }
3498
- )
3469
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: centeredContainerClass, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-center", children: [
3470
+ /* @__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" }),
3471
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-white text-lg", children: "Connecting..." })
3499
3472
  ] }) });
3500
3473
  }
3501
3474
  if (!streamKey) {
@@ -3674,7 +3647,7 @@ function BroadcastStreamer({
3674
3647
  ] });
3675
3648
  }
3676
3649
 
3677
- // src/utils/broadcast-popup.ts
3650
+ // src/utils/dialtribe-popup.ts
3678
3651
  function calculatePopupDimensions() {
3679
3652
  const screenWidth = window.screen.width;
3680
3653
  const screenHeight = window.screen.height;
@@ -3692,26 +3665,22 @@ function calculatePopupDimensions() {
3692
3665
  const top = Math.floor((screenHeight - height) / 2);
3693
3666
  return { width, height, left, top };
3694
3667
  }
3695
- function openBroadcastStreamerPopup(options) {
3668
+ function openDialtribeStreamerPopup(options) {
3696
3669
  const {
3697
3670
  sessionToken,
3698
3671
  streamKey,
3672
+ streamerUrl,
3699
3673
  appId,
3700
- mode,
3701
- additionalParams,
3702
- baseUrl = "/broadcasts/new"
3674
+ additionalParams
3703
3675
  } = options;
3704
3676
  const { width, height, left, top } = calculatePopupDimensions();
3705
3677
  const params = new URLSearchParams();
3706
- if (mode) {
3707
- params.append("mode", mode);
3708
- }
3709
3678
  if (additionalParams) {
3710
3679
  Object.entries(additionalParams).forEach(([key, value]) => {
3711
3680
  params.append(key, value);
3712
3681
  });
3713
3682
  }
3714
- const url = `${baseUrl}${params.toString() ? `?${params.toString()}` : ""}`;
3683
+ const url = `${streamerUrl}${params.toString() ? `?${params.toString()}` : ""}`;
3715
3684
  const popup = window.open(
3716
3685
  url,
3717
3686
  "_blank",
@@ -3741,18 +3710,177 @@ function openBroadcastStreamerPopup(options) {
3741
3710
  setTimeout(sendMessage, 500);
3742
3711
  return popup;
3743
3712
  }
3744
- var openBroadcastPopup = openBroadcastStreamerPopup;
3713
+ var openBroadcastPopup = openDialtribeStreamerPopup;
3714
+ function useDialtribeStreamerPopup() {
3715
+ const [sessionToken, setSessionToken] = React2.useState(null);
3716
+ const [streamKey, setStreamKey] = React2.useState(null);
3717
+ const [apiBaseUrl, setApiBaseUrl] = React2.useState("");
3718
+ const receivedDataRef = React2.useRef(false);
3719
+ React2.useEffect(() => {
3720
+ const handleMessage = (event) => {
3721
+ if (event.data?.type !== "STREAM_KEY") return;
3722
+ const { sessionToken: token, streamKey: key, apiBaseUrl: url } = event.data;
3723
+ if (token && key) {
3724
+ receivedDataRef.current = true;
3725
+ setSessionToken(token);
3726
+ setStreamKey(key);
3727
+ if (url) {
3728
+ setApiBaseUrl(url);
3729
+ }
3730
+ } else if (key) {
3731
+ receivedDataRef.current = true;
3732
+ setStreamKey(key);
3733
+ }
3734
+ };
3735
+ window.addEventListener("message", handleMessage);
3736
+ const requestCredentials = () => {
3737
+ if (window.opener && !receivedDataRef.current) {
3738
+ window.opener.postMessage({ type: "POPUP_READY" }, "*");
3739
+ }
3740
+ };
3741
+ requestCredentials();
3742
+ const pollInterval = setInterval(() => {
3743
+ if (!receivedDataRef.current) {
3744
+ requestCredentials();
3745
+ } else {
3746
+ clearInterval(pollInterval);
3747
+ }
3748
+ }, 200);
3749
+ const timeout = setTimeout(() => {
3750
+ clearInterval(pollInterval);
3751
+ }, 1e4);
3752
+ return () => {
3753
+ window.removeEventListener("message", handleMessage);
3754
+ clearInterval(pollInterval);
3755
+ clearTimeout(timeout);
3756
+ };
3757
+ }, []);
3758
+ return {
3759
+ sessionToken,
3760
+ streamKey,
3761
+ apiBaseUrl,
3762
+ setStreamKey,
3763
+ isReady: receivedDataRef.current
3764
+ };
3765
+ }
3766
+ function useDialtribeStreamerLauncher(options) {
3767
+ const {
3768
+ sessionToken,
3769
+ streamKey,
3770
+ streamerUrl,
3771
+ apiBaseUrl,
3772
+ fallback = "fullscreen",
3773
+ onPopupBlocked,
3774
+ onDone,
3775
+ onStreamKeyChange
3776
+ } = options;
3777
+ const [showFallback, setShowFallback] = React2.useState(false);
3778
+ const [wasBlocked, setWasBlocked] = React2.useState(false);
3779
+ const popupRef = React2.useRef(null);
3780
+ const sessionTokenRef = React2.useRef(sessionToken);
3781
+ const streamKeyRef = React2.useRef(streamKey);
3782
+ const apiBaseUrlRef = React2.useRef(apiBaseUrl);
3783
+ React2.useEffect(() => {
3784
+ sessionTokenRef.current = sessionToken;
3785
+ }, [sessionToken]);
3786
+ React2.useEffect(() => {
3787
+ streamKeyRef.current = streamKey;
3788
+ }, [streamKey]);
3789
+ React2.useEffect(() => {
3790
+ apiBaseUrlRef.current = apiBaseUrl;
3791
+ }, [apiBaseUrl]);
3792
+ React2.useEffect(() => {
3793
+ const handleMessage = (event) => {
3794
+ if (event.data?.type === "POPUP_READY" && popupRef.current) {
3795
+ popupRef.current.postMessage(
3796
+ {
3797
+ type: "STREAM_KEY",
3798
+ sessionToken: sessionTokenRef.current,
3799
+ streamKey: streamKeyRef.current,
3800
+ apiBaseUrl: apiBaseUrlRef.current
3801
+ },
3802
+ "*"
3803
+ );
3804
+ }
3805
+ };
3806
+ window.addEventListener("message", handleMessage);
3807
+ return () => window.removeEventListener("message", handleMessage);
3808
+ }, []);
3809
+ const launch = React2.useCallback(() => {
3810
+ if (!sessionToken) {
3811
+ console.warn("Cannot launch streamer: no session token");
3812
+ return;
3813
+ }
3814
+ setWasBlocked(false);
3815
+ const popup = openDialtribeStreamerPopup({
3816
+ sessionToken,
3817
+ streamKey,
3818
+ streamerUrl
3819
+ });
3820
+ if (popup) {
3821
+ popupRef.current = popup;
3822
+ return;
3823
+ }
3824
+ setWasBlocked(true);
3825
+ onPopupBlocked?.();
3826
+ switch (fallback) {
3827
+ case "fullscreen":
3828
+ setShowFallback(true);
3829
+ break;
3830
+ case "newTab":
3831
+ window.open(streamerUrl, "_blank");
3832
+ break;
3833
+ }
3834
+ }, [sessionToken, streamKey, streamerUrl, fallback, onPopupBlocked]);
3835
+ const closeFallback = React2.useCallback(() => {
3836
+ setShowFallback(false);
3837
+ onDone?.();
3838
+ }, [onDone]);
3839
+ const Fallback = React2.useCallback(() => {
3840
+ if (fallback !== "fullscreen" || !showFallback) {
3841
+ return null;
3842
+ }
3843
+ if (typeof document === "undefined") {
3844
+ return null;
3845
+ }
3846
+ const streamerElement = React2__default.default.createElement(DialtribeStreamer, {
3847
+ sessionToken: sessionToken || void 0,
3848
+ streamKey: streamKey || void 0,
3849
+ apiBaseUrl,
3850
+ onDone: closeFallback,
3851
+ onStreamKeyChange
3852
+ });
3853
+ const overlayElement = React2__default.default.createElement(
3854
+ DialtribeOverlay,
3855
+ {
3856
+ mode: "fullscreen",
3857
+ isOpen: true,
3858
+ onClose: closeFallback,
3859
+ children: streamerElement
3860
+ }
3861
+ );
3862
+ return reactDom.createPortal(overlayElement, document.body);
3863
+ }, [fallback, showFallback, closeFallback, sessionToken, streamKey, apiBaseUrl, onStreamKeyChange]);
3864
+ return {
3865
+ launch,
3866
+ Fallback,
3867
+ showFallback,
3868
+ closeFallback,
3869
+ popupRef: popupRef.current,
3870
+ wasBlocked
3871
+ };
3872
+ }
3745
3873
 
3746
3874
  exports.AudioWaveform = AudioWaveform;
3747
- exports.BroadcastPlayer = BroadcastPlayer;
3748
- exports.BroadcastPlayerErrorBoundary = BroadcastPlayerErrorBoundary;
3749
- exports.BroadcastPlayerModal = BroadcastPlayerModal;
3750
- exports.BroadcastStreamer = BroadcastStreamer;
3751
3875
  exports.CDN_DOMAIN = CDN_DOMAIN;
3752
3876
  exports.DEFAULT_ENCODER_SERVER_URL = DEFAULT_ENCODER_SERVER_URL;
3753
3877
  exports.DIALTRIBE_API_BASE = DIALTRIBE_API_BASE;
3754
- exports.DialTribeClient = DialTribeClient;
3755
- exports.DialTribeProvider = DialTribeProvider;
3878
+ exports.DialtribeClient = DialtribeClient;
3879
+ exports.DialtribeOverlay = DialtribeOverlay;
3880
+ exports.DialtribePlayer = DialtribePlayer;
3881
+ exports.DialtribePlayerErrorBoundary = DialtribePlayerErrorBoundary;
3882
+ exports.DialtribeProvider = DialtribeProvider;
3883
+ exports.DialtribeStreamer = DialtribeStreamer;
3756
3884
  exports.ENDPOINTS = ENDPOINTS;
3757
3885
  exports.HTTP_STATUS = HTTP_STATUS;
3758
3886
  exports.HelloWorld = HelloWorld;
@@ -3770,7 +3898,9 @@ exports.formatTime = formatTime;
3770
3898
  exports.getMediaConstraints = getMediaConstraints;
3771
3899
  exports.getMediaRecorderOptions = getMediaRecorderOptions;
3772
3900
  exports.openBroadcastPopup = openBroadcastPopup;
3773
- exports.openBroadcastStreamerPopup = openBroadcastStreamerPopup;
3774
- exports.useDialTribe = useDialTribe;
3901
+ exports.openDialtribeStreamerPopup = openDialtribeStreamerPopup;
3902
+ exports.useDialtribe = useDialtribe;
3903
+ exports.useDialtribeStreamerLauncher = useDialtribeStreamerLauncher;
3904
+ exports.useDialtribeStreamerPopup = useDialtribeStreamerPopup;
3775
3905
  //# sourceMappingURL=index.js.map
3776
3906
  //# sourceMappingURL=index.js.map