@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/README.md +11 -11
- package/dist/{broadcast-player-CEAnuf6t.d.mts → dialtribe-player-Rc9kfQiX.d.mts} +90 -89
- package/dist/{broadcast-player-CEAnuf6t.d.ts → dialtribe-player-Rc9kfQiX.d.ts} +90 -89
- package/dist/dialtribe-player.d.mts +3 -0
- package/dist/dialtribe-player.d.ts +3 -0
- package/dist/{broadcast-player.js → dialtribe-player.js} +110 -112
- package/dist/dialtribe-player.js.map +1 -0
- package/dist/{broadcast-player.mjs → dialtribe-player.mjs} +105 -107
- package/dist/dialtribe-player.mjs.map +1 -0
- package/dist/{broadcast-streamer.d.ts → dialtribe-streamer.d.mts} +203 -32
- package/dist/{broadcast-streamer.d.mts → dialtribe-streamer.d.ts} +203 -32
- package/dist/{broadcast-streamer.js → dialtribe-streamer.js} +391 -261
- package/dist/dialtribe-streamer.js.map +1 -0
- package/dist/{broadcast-streamer.mjs → dialtribe-streamer.mjs} +281 -154
- package/dist/dialtribe-streamer.mjs.map +1 -0
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +387 -257
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +278 -151
- package/dist/index.mjs.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +9 -9
- package/dist/broadcast-player.d.mts +0 -3
- package/dist/broadcast-player.d.ts +0 -3
- package/dist/broadcast-player.js.map +0 -1
- package/dist/broadcast-player.mjs.map +0 -1
- package/dist/broadcast-streamer.js.map +0 -1
- package/dist/broadcast-streamer.mjs.map +0 -1
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { createContext, useState, useCallback, useEffect, useContext, useRef, Component } from 'react';
|
|
1
|
+
import React2, { createContext, useState, useCallback, useEffect, useContext, useRef, Component } from 'react';
|
|
2
2
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
3
3
|
import ReactPlayer from 'react-player';
|
|
4
|
+
import { createPortal } from 'react-dom';
|
|
4
5
|
|
|
5
|
-
// src/context/
|
|
6
|
-
var
|
|
7
|
-
function
|
|
6
|
+
// src/context/DialtribeProvider.tsx
|
|
7
|
+
var DialtribeContext = createContext(null);
|
|
8
|
+
function DialtribeProvider({
|
|
8
9
|
sessionToken: initialToken,
|
|
9
10
|
onTokenRefresh,
|
|
10
11
|
onTokenExpired,
|
|
@@ -40,22 +41,22 @@ function DialTribeProvider({
|
|
|
40
41
|
markExpired,
|
|
41
42
|
apiBaseUrl
|
|
42
43
|
};
|
|
43
|
-
return /* @__PURE__ */ jsx(
|
|
44
|
+
return /* @__PURE__ */ jsx(DialtribeContext.Provider, { value, children });
|
|
44
45
|
}
|
|
45
|
-
function
|
|
46
|
-
const context = useContext(
|
|
46
|
+
function useDialtribe() {
|
|
47
|
+
const context = useContext(DialtribeContext);
|
|
47
48
|
if (!context) {
|
|
48
49
|
throw new Error(
|
|
49
|
-
'
|
|
50
|
+
'useDialtribe must be used within a DialtribeProvider. Wrap your app with <DialtribeProvider sessionToken="sess_xxx">...</DialtribeProvider>'
|
|
50
51
|
);
|
|
51
52
|
}
|
|
52
53
|
return context;
|
|
53
54
|
}
|
|
54
|
-
function
|
|
55
|
-
return useContext(
|
|
55
|
+
function useDialtribeOptional() {
|
|
56
|
+
return useContext(DialtribeContext);
|
|
56
57
|
}
|
|
57
58
|
|
|
58
|
-
// src/client/
|
|
59
|
+
// src/client/DialtribeClient.ts
|
|
59
60
|
function getDefaultApiBaseUrl() {
|
|
60
61
|
if (typeof process !== "undefined" && process.env?.NEXT_PUBLIC_DIALTRIBE_API_URL) {
|
|
61
62
|
return process.env.NEXT_PUBLIC_DIALTRIBE_API_URL;
|
|
@@ -69,18 +70,19 @@ function getEndpoints(baseUrl = DIALTRIBE_API_BASE) {
|
|
|
69
70
|
broadcast: (id) => `${baseUrl}/broadcasts/${id}`,
|
|
70
71
|
contentPlay: `${baseUrl}/content/play`,
|
|
71
72
|
presignedUrl: `${baseUrl}/media/presigned-url`,
|
|
72
|
-
|
|
73
|
-
|
|
73
|
+
audienceStart: `${baseUrl}/audiences/start`,
|
|
74
|
+
audiencePing: `${baseUrl}/audiences/ping`,
|
|
75
|
+
sessionPing: `${baseUrl}/sessions/ping`
|
|
74
76
|
};
|
|
75
77
|
}
|
|
76
78
|
var ENDPOINTS = getEndpoints();
|
|
77
|
-
var
|
|
79
|
+
var DialtribeClient = class {
|
|
78
80
|
constructor(config) {
|
|
79
81
|
this.config = config;
|
|
80
82
|
this.endpoints = config.apiBaseUrl ? getEndpoints(config.apiBaseUrl) : ENDPOINTS;
|
|
81
83
|
}
|
|
82
84
|
/**
|
|
83
|
-
* Make an authenticated request to
|
|
85
|
+
* Make an authenticated request to Dialtribe API
|
|
84
86
|
*
|
|
85
87
|
* Automatically:
|
|
86
88
|
* - Adds Authorization header with session token
|
|
@@ -194,7 +196,7 @@ var DialTribeClient = class {
|
|
|
194
196
|
* @returns audienceId and optional resumePosition
|
|
195
197
|
*/
|
|
196
198
|
async startSession(params) {
|
|
197
|
-
const response = await this.fetch(this.endpoints.
|
|
199
|
+
const response = await this.fetch(this.endpoints.audienceStart, {
|
|
198
200
|
method: "POST",
|
|
199
201
|
body: JSON.stringify(params)
|
|
200
202
|
});
|
|
@@ -213,7 +215,7 @@ var DialTribeClient = class {
|
|
|
213
215
|
* - 3: UNMOUNT
|
|
214
216
|
*/
|
|
215
217
|
async sendSessionPing(params) {
|
|
216
|
-
const response = await this.fetch(this.endpoints.
|
|
218
|
+
const response = await this.fetch(this.endpoints.audiencePing, {
|
|
217
219
|
method: "POST",
|
|
218
220
|
body: JSON.stringify(params)
|
|
219
221
|
});
|
|
@@ -1476,7 +1478,7 @@ function StreamKeyInput({ onSubmit, inline = false }) {
|
|
|
1476
1478
|
] })
|
|
1477
1479
|
] }) });
|
|
1478
1480
|
}
|
|
1479
|
-
function
|
|
1481
|
+
function DialtribeStreamer({
|
|
1480
1482
|
sessionToken: propSessionToken,
|
|
1481
1483
|
streamKey: initialStreamKey,
|
|
1482
1484
|
onDone,
|
|
@@ -1485,9 +1487,9 @@ function BroadcastStreamer({
|
|
|
1485
1487
|
apiBaseUrl = DIALTRIBE_API_BASE,
|
|
1486
1488
|
inline = false
|
|
1487
1489
|
}) {
|
|
1488
|
-
const containerClass = inline ? "dialtribe-
|
|
1489
|
-
const centeredContainerClass = inline ? "dialtribe-
|
|
1490
|
-
const dialTribeContext =
|
|
1490
|
+
const containerClass = inline ? "dialtribe-dialtribe-streamer h-full w-full bg-black relative" : "dialtribe-dialtribe-streamer min-h-screen bg-black";
|
|
1491
|
+
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";
|
|
1492
|
+
const dialTribeContext = useDialtribeOptional();
|
|
1491
1493
|
const sessionToken = propSessionToken ?? dialTribeContext?.sessionToken ?? null;
|
|
1492
1494
|
const [streamKey, setStreamKey] = useState(initialStreamKey || null);
|
|
1493
1495
|
const [state, setState] = useState("idle");
|
|
@@ -1871,36 +1873,9 @@ function BroadcastStreamer({
|
|
|
1871
1873
|
}
|
|
1872
1874
|
};
|
|
1873
1875
|
if (!sessionToken) {
|
|
1874
|
-
return /* @__PURE__ */ jsx("div", { className: centeredContainerClass, children: /* @__PURE__ */ jsxs("div", { className: "
|
|
1875
|
-
/* @__PURE__ */ jsx("div", { className: "w-16 h-16
|
|
1876
|
-
|
|
1877
|
-
{
|
|
1878
|
-
className: "w-8 h-8 text-red-600 dark:text-red-400",
|
|
1879
|
-
fill: "none",
|
|
1880
|
-
stroke: "currentColor",
|
|
1881
|
-
viewBox: "0 0 24 24",
|
|
1882
|
-
children: /* @__PURE__ */ jsx(
|
|
1883
|
-
"path",
|
|
1884
|
-
{
|
|
1885
|
-
strokeLinecap: "round",
|
|
1886
|
-
strokeLinejoin: "round",
|
|
1887
|
-
strokeWidth: 2,
|
|
1888
|
-
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"
|
|
1889
|
-
}
|
|
1890
|
-
)
|
|
1891
|
-
}
|
|
1892
|
-
) }),
|
|
1893
|
-
/* @__PURE__ */ jsx("h2", { className: "text-xl font-bold text-black dark:text-white mb-2", children: "Authentication Required" }),
|
|
1894
|
-
/* @__PURE__ */ jsx("p", { className: "text-gray-600 dark:text-gray-400 mb-4", children: "A session token is required to use the broadcast streamer." }),
|
|
1895
|
-
/* @__PURE__ */ 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." }),
|
|
1896
|
-
/* @__PURE__ */ jsx(
|
|
1897
|
-
"button",
|
|
1898
|
-
{
|
|
1899
|
-
onClick: handleDone,
|
|
1900
|
-
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",
|
|
1901
|
-
children: "Close"
|
|
1902
|
-
}
|
|
1903
|
-
)
|
|
1876
|
+
return /* @__PURE__ */ jsx("div", { className: centeredContainerClass, children: /* @__PURE__ */ jsxs("div", { className: "text-center", children: [
|
|
1877
|
+
/* @__PURE__ */ jsx("div", { className: "w-16 h-16 border-4 border-gray-700 border-t-blue-600 rounded-full animate-spin mx-auto mb-4" }),
|
|
1878
|
+
/* @__PURE__ */ jsx("p", { className: "text-white text-lg", children: "Connecting..." })
|
|
1904
1879
|
] }) });
|
|
1905
1880
|
}
|
|
1906
1881
|
if (!streamKey) {
|
|
@@ -2233,7 +2208,7 @@ function getErrorMessage(error) {
|
|
|
2233
2208
|
}
|
|
2234
2209
|
return "Unable to play media. Please try refreshing the page or contact support if the problem persists.";
|
|
2235
2210
|
}
|
|
2236
|
-
function
|
|
2211
|
+
function DialtribePlayer({
|
|
2237
2212
|
broadcast,
|
|
2238
2213
|
appId,
|
|
2239
2214
|
contentId,
|
|
@@ -2244,18 +2219,18 @@ function BroadcastPlayer({
|
|
|
2244
2219
|
className = "",
|
|
2245
2220
|
enableKeyboardShortcuts = false
|
|
2246
2221
|
}) {
|
|
2247
|
-
const { sessionToken, setSessionToken, markExpired, apiBaseUrl } =
|
|
2222
|
+
const { sessionToken, setSessionToken, markExpired, apiBaseUrl } = useDialtribe();
|
|
2248
2223
|
const clientRef = useRef(null);
|
|
2249
2224
|
if (!clientRef.current && sessionToken) {
|
|
2250
|
-
clientRef.current = new
|
|
2225
|
+
clientRef.current = new DialtribeClient({
|
|
2251
2226
|
sessionToken,
|
|
2252
2227
|
apiBaseUrl,
|
|
2253
2228
|
onTokenRefresh: (newToken, expiresAt) => {
|
|
2254
|
-
debug.log(`[
|
|
2229
|
+
debug.log(`[DialtribeClient] Token refreshed, expires at ${expiresAt}`);
|
|
2255
2230
|
setSessionToken(newToken, expiresAt);
|
|
2256
2231
|
},
|
|
2257
2232
|
onTokenExpired: () => {
|
|
2258
|
-
debug.error("[
|
|
2233
|
+
debug.error("[DialtribeClient] Token expired");
|
|
2259
2234
|
markExpired();
|
|
2260
2235
|
}
|
|
2261
2236
|
});
|
|
@@ -2700,7 +2675,7 @@ function BroadcastPlayer({
|
|
|
2700
2675
|
setAudioElement(internalPlayer);
|
|
2701
2676
|
}
|
|
2702
2677
|
} catch (error) {
|
|
2703
|
-
debug.error("[
|
|
2678
|
+
debug.error("[DialtribePlayer] Error getting internal player:", error);
|
|
2704
2679
|
}
|
|
2705
2680
|
};
|
|
2706
2681
|
useEffect(() => {
|
|
@@ -2908,7 +2883,7 @@ function BroadcastPlayer({
|
|
|
2908
2883
|
return /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center p-8", children: /* @__PURE__ */ jsx(LoadingSpinner, { variant: "white", text: "Loading..." }) });
|
|
2909
2884
|
}
|
|
2910
2885
|
const hasTranscript = broadcast.transcriptStatus === 2 && transcriptData && (transcriptData.segments && transcriptData.segments.some((s) => s.words && s.words.length > 0) || transcriptData.words && transcriptData.words.length > 0);
|
|
2911
|
-
|
|
2886
|
+
const playerContent = /* @__PURE__ */ jsxs("div", { className: `bg-black rounded-lg shadow-2xl w-full max-h-full flex flex-col overflow-hidden ${className}`, children: [
|
|
2912
2887
|
/* @__PURE__ */ 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: [
|
|
2913
2888
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
2914
2889
|
/* @__PURE__ */ jsx("h3", { className: "text-lg font-semibold text-white", children: broadcast.streamKeyRecord?.foreignName || "Broadcast" }),
|
|
@@ -3440,90 +3415,9 @@ function BroadcastPlayer({
|
|
|
3440
3415
|
}
|
|
3441
3416
|
` })
|
|
3442
3417
|
] });
|
|
3418
|
+
return playerContent;
|
|
3443
3419
|
}
|
|
3444
|
-
|
|
3445
|
-
broadcast,
|
|
3446
|
-
isOpen,
|
|
3447
|
-
onClose,
|
|
3448
|
-
appId,
|
|
3449
|
-
contentId,
|
|
3450
|
-
foreignId,
|
|
3451
|
-
foreignTier,
|
|
3452
|
-
renderClipCreator,
|
|
3453
|
-
className,
|
|
3454
|
-
enableKeyboardShortcuts = false
|
|
3455
|
-
}) {
|
|
3456
|
-
const closeButtonRef = useRef(null);
|
|
3457
|
-
const previousActiveElement = useRef(null);
|
|
3458
|
-
useEffect(() => {
|
|
3459
|
-
if (!isOpen) return;
|
|
3460
|
-
previousActiveElement.current = document.activeElement;
|
|
3461
|
-
setTimeout(() => {
|
|
3462
|
-
closeButtonRef.current?.focus();
|
|
3463
|
-
}, 100);
|
|
3464
|
-
return () => {
|
|
3465
|
-
if (previousActiveElement.current) {
|
|
3466
|
-
previousActiveElement.current.focus();
|
|
3467
|
-
}
|
|
3468
|
-
};
|
|
3469
|
-
}, [isOpen]);
|
|
3470
|
-
useEffect(() => {
|
|
3471
|
-
if (!isOpen) return;
|
|
3472
|
-
const handleKeyDown = (e) => {
|
|
3473
|
-
if (e.key === "Escape") {
|
|
3474
|
-
onClose();
|
|
3475
|
-
}
|
|
3476
|
-
};
|
|
3477
|
-
document.addEventListener("keydown", handleKeyDown);
|
|
3478
|
-
return () => document.removeEventListener("keydown", handleKeyDown);
|
|
3479
|
-
}, [isOpen, onClose]);
|
|
3480
|
-
if (!isOpen) return null;
|
|
3481
|
-
const handleBackdropClick = (e) => {
|
|
3482
|
-
if (e.target === e.currentTarget) {
|
|
3483
|
-
onClose();
|
|
3484
|
-
}
|
|
3485
|
-
};
|
|
3486
|
-
return /* @__PURE__ */ jsx(
|
|
3487
|
-
"div",
|
|
3488
|
-
{
|
|
3489
|
-
className: "fixed inset-0 bg-black/70 backdrop-blur-xl flex items-center justify-center z-50 p-2 sm:p-4",
|
|
3490
|
-
onClick: handleBackdropClick,
|
|
3491
|
-
role: "dialog",
|
|
3492
|
-
"aria-modal": "true",
|
|
3493
|
-
"aria-label": "Broadcast player",
|
|
3494
|
-
children: /* @__PURE__ */ jsxs("div", { className: "relative w-full max-w-7xl max-h-[95vh] sm:max-h-[90vh] overflow-hidden", children: [
|
|
3495
|
-
/* @__PURE__ */ jsx(
|
|
3496
|
-
"button",
|
|
3497
|
-
{
|
|
3498
|
-
ref: closeButtonRef,
|
|
3499
|
-
onClick: onClose,
|
|
3500
|
-
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",
|
|
3501
|
-
title: "Close (ESC)",
|
|
3502
|
-
"aria-label": "Close player",
|
|
3503
|
-
children: "\xD7"
|
|
3504
|
-
}
|
|
3505
|
-
),
|
|
3506
|
-
/* @__PURE__ */ jsx(
|
|
3507
|
-
BroadcastPlayer,
|
|
3508
|
-
{
|
|
3509
|
-
broadcast,
|
|
3510
|
-
appId,
|
|
3511
|
-
contentId,
|
|
3512
|
-
foreignId,
|
|
3513
|
-
foreignTier,
|
|
3514
|
-
renderClipCreator,
|
|
3515
|
-
className,
|
|
3516
|
-
enableKeyboardShortcuts,
|
|
3517
|
-
onError: (error) => {
|
|
3518
|
-
debug.error("[BroadcastPlayerModal] Player error:", error);
|
|
3519
|
-
}
|
|
3520
|
-
}
|
|
3521
|
-
)
|
|
3522
|
-
] })
|
|
3523
|
-
}
|
|
3524
|
-
);
|
|
3525
|
-
}
|
|
3526
|
-
var BroadcastPlayerErrorBoundary = class extends Component {
|
|
3420
|
+
var DialtribePlayerErrorBoundary = class extends Component {
|
|
3527
3421
|
constructor(props) {
|
|
3528
3422
|
super(props);
|
|
3529
3423
|
this.handleReset = () => {
|
|
@@ -3649,8 +3543,86 @@ var BroadcastPlayerErrorBoundary = class extends Component {
|
|
|
3649
3543
|
return this.props.children;
|
|
3650
3544
|
}
|
|
3651
3545
|
};
|
|
3546
|
+
var overlayStyles = {
|
|
3547
|
+
modal: {
|
|
3548
|
+
backdrop: "bg-black/70 backdrop-blur-xl p-2 sm:p-4",
|
|
3549
|
+
container: "max-w-7xl max-h-[95vh] sm:max-h-[90vh]"
|
|
3550
|
+
},
|
|
3551
|
+
fullscreen: {
|
|
3552
|
+
backdrop: "bg-black",
|
|
3553
|
+
container: "h-full"
|
|
3554
|
+
}
|
|
3555
|
+
};
|
|
3556
|
+
function DialtribeOverlay({
|
|
3557
|
+
isOpen,
|
|
3558
|
+
onClose,
|
|
3559
|
+
mode = "modal",
|
|
3560
|
+
children,
|
|
3561
|
+
ariaLabel = "Dialog",
|
|
3562
|
+
showCloseButton = true,
|
|
3563
|
+
closeOnBackdropClick = true,
|
|
3564
|
+
closeOnEsc = true
|
|
3565
|
+
}) {
|
|
3566
|
+
const closeButtonRef = useRef(null);
|
|
3567
|
+
const previousActiveElement = useRef(null);
|
|
3568
|
+
useEffect(() => {
|
|
3569
|
+
if (!isOpen) return;
|
|
3570
|
+
previousActiveElement.current = document.activeElement;
|
|
3571
|
+
setTimeout(() => {
|
|
3572
|
+
closeButtonRef.current?.focus();
|
|
3573
|
+
}, 100);
|
|
3574
|
+
return () => {
|
|
3575
|
+
if (previousActiveElement.current) {
|
|
3576
|
+
previousActiveElement.current.focus();
|
|
3577
|
+
}
|
|
3578
|
+
};
|
|
3579
|
+
}, [isOpen]);
|
|
3580
|
+
useEffect(() => {
|
|
3581
|
+
if (!isOpen || !closeOnEsc) return;
|
|
3582
|
+
const handleKeyDown = (e) => {
|
|
3583
|
+
if (e.key === "Escape") {
|
|
3584
|
+
onClose();
|
|
3585
|
+
}
|
|
3586
|
+
};
|
|
3587
|
+
document.addEventListener("keydown", handleKeyDown);
|
|
3588
|
+
return () => document.removeEventListener("keydown", handleKeyDown);
|
|
3589
|
+
}, [isOpen, onClose, closeOnEsc]);
|
|
3590
|
+
if (!isOpen) {
|
|
3591
|
+
return null;
|
|
3592
|
+
}
|
|
3593
|
+
const handleBackdropClick = (e) => {
|
|
3594
|
+
if (closeOnBackdropClick && e.target === e.currentTarget) {
|
|
3595
|
+
onClose();
|
|
3596
|
+
}
|
|
3597
|
+
};
|
|
3598
|
+
const styles = overlayStyles[mode];
|
|
3599
|
+
return /* @__PURE__ */ jsx(
|
|
3600
|
+
"div",
|
|
3601
|
+
{
|
|
3602
|
+
className: `fixed inset-0 flex items-center justify-center z-50 ${styles.backdrop}`,
|
|
3603
|
+
onClick: handleBackdropClick,
|
|
3604
|
+
role: "dialog",
|
|
3605
|
+
"aria-modal": "true",
|
|
3606
|
+
"aria-label": ariaLabel,
|
|
3607
|
+
children: /* @__PURE__ */ jsxs("div", { className: `relative w-full overflow-hidden ${styles.container}`, children: [
|
|
3608
|
+
showCloseButton && /* @__PURE__ */ jsx(
|
|
3609
|
+
"button",
|
|
3610
|
+
{
|
|
3611
|
+
ref: closeButtonRef,
|
|
3612
|
+
onClick: onClose,
|
|
3613
|
+
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",
|
|
3614
|
+
title: "Close (ESC)",
|
|
3615
|
+
"aria-label": "Close",
|
|
3616
|
+
children: "\xD7"
|
|
3617
|
+
}
|
|
3618
|
+
),
|
|
3619
|
+
children
|
|
3620
|
+
] })
|
|
3621
|
+
}
|
|
3622
|
+
);
|
|
3623
|
+
}
|
|
3652
3624
|
|
|
3653
|
-
// src/utils/
|
|
3625
|
+
// src/utils/dialtribe-popup.ts
|
|
3654
3626
|
function calculatePopupDimensions() {
|
|
3655
3627
|
const screenWidth = window.screen.width;
|
|
3656
3628
|
const screenHeight = window.screen.height;
|
|
@@ -3668,26 +3640,22 @@ function calculatePopupDimensions() {
|
|
|
3668
3640
|
const top = Math.floor((screenHeight - height) / 2);
|
|
3669
3641
|
return { width, height, left, top };
|
|
3670
3642
|
}
|
|
3671
|
-
function
|
|
3643
|
+
function openDialtribeStreamerPopup(options) {
|
|
3672
3644
|
const {
|
|
3673
3645
|
sessionToken,
|
|
3674
3646
|
streamKey,
|
|
3647
|
+
streamerUrl,
|
|
3675
3648
|
appId,
|
|
3676
|
-
|
|
3677
|
-
additionalParams,
|
|
3678
|
-
baseUrl = "/broadcasts/new"
|
|
3649
|
+
additionalParams
|
|
3679
3650
|
} = options;
|
|
3680
3651
|
const { width, height, left, top } = calculatePopupDimensions();
|
|
3681
3652
|
const params = new URLSearchParams();
|
|
3682
|
-
if (mode) {
|
|
3683
|
-
params.append("mode", mode);
|
|
3684
|
-
}
|
|
3685
3653
|
if (additionalParams) {
|
|
3686
3654
|
Object.entries(additionalParams).forEach(([key, value]) => {
|
|
3687
3655
|
params.append(key, value);
|
|
3688
3656
|
});
|
|
3689
3657
|
}
|
|
3690
|
-
const url = `${
|
|
3658
|
+
const url = `${streamerUrl}${params.toString() ? `?${params.toString()}` : ""}`;
|
|
3691
3659
|
const popup = window.open(
|
|
3692
3660
|
url,
|
|
3693
3661
|
"_blank",
|
|
@@ -3717,8 +3685,167 @@ function openBroadcastStreamerPopup(options) {
|
|
|
3717
3685
|
setTimeout(sendMessage, 500);
|
|
3718
3686
|
return popup;
|
|
3719
3687
|
}
|
|
3720
|
-
var openBroadcastPopup =
|
|
3688
|
+
var openBroadcastPopup = openDialtribeStreamerPopup;
|
|
3689
|
+
function useDialtribeStreamerPopup() {
|
|
3690
|
+
const [sessionToken, setSessionToken] = useState(null);
|
|
3691
|
+
const [streamKey, setStreamKey] = useState(null);
|
|
3692
|
+
const [apiBaseUrl, setApiBaseUrl] = useState("");
|
|
3693
|
+
const receivedDataRef = useRef(false);
|
|
3694
|
+
useEffect(() => {
|
|
3695
|
+
const handleMessage = (event) => {
|
|
3696
|
+
if (event.data?.type !== "STREAM_KEY") return;
|
|
3697
|
+
const { sessionToken: token, streamKey: key, apiBaseUrl: url } = event.data;
|
|
3698
|
+
if (token && key) {
|
|
3699
|
+
receivedDataRef.current = true;
|
|
3700
|
+
setSessionToken(token);
|
|
3701
|
+
setStreamKey(key);
|
|
3702
|
+
if (url) {
|
|
3703
|
+
setApiBaseUrl(url);
|
|
3704
|
+
}
|
|
3705
|
+
} else if (key) {
|
|
3706
|
+
receivedDataRef.current = true;
|
|
3707
|
+
setStreamKey(key);
|
|
3708
|
+
}
|
|
3709
|
+
};
|
|
3710
|
+
window.addEventListener("message", handleMessage);
|
|
3711
|
+
const requestCredentials = () => {
|
|
3712
|
+
if (window.opener && !receivedDataRef.current) {
|
|
3713
|
+
window.opener.postMessage({ type: "POPUP_READY" }, "*");
|
|
3714
|
+
}
|
|
3715
|
+
};
|
|
3716
|
+
requestCredentials();
|
|
3717
|
+
const pollInterval = setInterval(() => {
|
|
3718
|
+
if (!receivedDataRef.current) {
|
|
3719
|
+
requestCredentials();
|
|
3720
|
+
} else {
|
|
3721
|
+
clearInterval(pollInterval);
|
|
3722
|
+
}
|
|
3723
|
+
}, 200);
|
|
3724
|
+
const timeout = setTimeout(() => {
|
|
3725
|
+
clearInterval(pollInterval);
|
|
3726
|
+
}, 1e4);
|
|
3727
|
+
return () => {
|
|
3728
|
+
window.removeEventListener("message", handleMessage);
|
|
3729
|
+
clearInterval(pollInterval);
|
|
3730
|
+
clearTimeout(timeout);
|
|
3731
|
+
};
|
|
3732
|
+
}, []);
|
|
3733
|
+
return {
|
|
3734
|
+
sessionToken,
|
|
3735
|
+
streamKey,
|
|
3736
|
+
apiBaseUrl,
|
|
3737
|
+
setStreamKey,
|
|
3738
|
+
isReady: receivedDataRef.current
|
|
3739
|
+
};
|
|
3740
|
+
}
|
|
3741
|
+
function useDialtribeStreamerLauncher(options) {
|
|
3742
|
+
const {
|
|
3743
|
+
sessionToken,
|
|
3744
|
+
streamKey,
|
|
3745
|
+
streamerUrl,
|
|
3746
|
+
apiBaseUrl,
|
|
3747
|
+
fallback = "fullscreen",
|
|
3748
|
+
onPopupBlocked,
|
|
3749
|
+
onDone,
|
|
3750
|
+
onStreamKeyChange
|
|
3751
|
+
} = options;
|
|
3752
|
+
const [showFallback, setShowFallback] = useState(false);
|
|
3753
|
+
const [wasBlocked, setWasBlocked] = useState(false);
|
|
3754
|
+
const popupRef = useRef(null);
|
|
3755
|
+
const sessionTokenRef = useRef(sessionToken);
|
|
3756
|
+
const streamKeyRef = useRef(streamKey);
|
|
3757
|
+
const apiBaseUrlRef = useRef(apiBaseUrl);
|
|
3758
|
+
useEffect(() => {
|
|
3759
|
+
sessionTokenRef.current = sessionToken;
|
|
3760
|
+
}, [sessionToken]);
|
|
3761
|
+
useEffect(() => {
|
|
3762
|
+
streamKeyRef.current = streamKey;
|
|
3763
|
+
}, [streamKey]);
|
|
3764
|
+
useEffect(() => {
|
|
3765
|
+
apiBaseUrlRef.current = apiBaseUrl;
|
|
3766
|
+
}, [apiBaseUrl]);
|
|
3767
|
+
useEffect(() => {
|
|
3768
|
+
const handleMessage = (event) => {
|
|
3769
|
+
if (event.data?.type === "POPUP_READY" && popupRef.current) {
|
|
3770
|
+
popupRef.current.postMessage(
|
|
3771
|
+
{
|
|
3772
|
+
type: "STREAM_KEY",
|
|
3773
|
+
sessionToken: sessionTokenRef.current,
|
|
3774
|
+
streamKey: streamKeyRef.current,
|
|
3775
|
+
apiBaseUrl: apiBaseUrlRef.current
|
|
3776
|
+
},
|
|
3777
|
+
"*"
|
|
3778
|
+
);
|
|
3779
|
+
}
|
|
3780
|
+
};
|
|
3781
|
+
window.addEventListener("message", handleMessage);
|
|
3782
|
+
return () => window.removeEventListener("message", handleMessage);
|
|
3783
|
+
}, []);
|
|
3784
|
+
const launch = useCallback(() => {
|
|
3785
|
+
if (!sessionToken) {
|
|
3786
|
+
console.warn("Cannot launch streamer: no session token");
|
|
3787
|
+
return;
|
|
3788
|
+
}
|
|
3789
|
+
setWasBlocked(false);
|
|
3790
|
+
const popup = openDialtribeStreamerPopup({
|
|
3791
|
+
sessionToken,
|
|
3792
|
+
streamKey,
|
|
3793
|
+
streamerUrl
|
|
3794
|
+
});
|
|
3795
|
+
if (popup) {
|
|
3796
|
+
popupRef.current = popup;
|
|
3797
|
+
return;
|
|
3798
|
+
}
|
|
3799
|
+
setWasBlocked(true);
|
|
3800
|
+
onPopupBlocked?.();
|
|
3801
|
+
switch (fallback) {
|
|
3802
|
+
case "fullscreen":
|
|
3803
|
+
setShowFallback(true);
|
|
3804
|
+
break;
|
|
3805
|
+
case "newTab":
|
|
3806
|
+
window.open(streamerUrl, "_blank");
|
|
3807
|
+
break;
|
|
3808
|
+
}
|
|
3809
|
+
}, [sessionToken, streamKey, streamerUrl, fallback, onPopupBlocked]);
|
|
3810
|
+
const closeFallback = useCallback(() => {
|
|
3811
|
+
setShowFallback(false);
|
|
3812
|
+
onDone?.();
|
|
3813
|
+
}, [onDone]);
|
|
3814
|
+
const Fallback = useCallback(() => {
|
|
3815
|
+
if (fallback !== "fullscreen" || !showFallback) {
|
|
3816
|
+
return null;
|
|
3817
|
+
}
|
|
3818
|
+
if (typeof document === "undefined") {
|
|
3819
|
+
return null;
|
|
3820
|
+
}
|
|
3821
|
+
const streamerElement = React2.createElement(DialtribeStreamer, {
|
|
3822
|
+
sessionToken: sessionToken || void 0,
|
|
3823
|
+
streamKey: streamKey || void 0,
|
|
3824
|
+
apiBaseUrl,
|
|
3825
|
+
onDone: closeFallback,
|
|
3826
|
+
onStreamKeyChange
|
|
3827
|
+
});
|
|
3828
|
+
const overlayElement = React2.createElement(
|
|
3829
|
+
DialtribeOverlay,
|
|
3830
|
+
{
|
|
3831
|
+
mode: "fullscreen",
|
|
3832
|
+
isOpen: true,
|
|
3833
|
+
onClose: closeFallback,
|
|
3834
|
+
children: streamerElement
|
|
3835
|
+
}
|
|
3836
|
+
);
|
|
3837
|
+
return createPortal(overlayElement, document.body);
|
|
3838
|
+
}, [fallback, showFallback, closeFallback, sessionToken, streamKey, apiBaseUrl, onStreamKeyChange]);
|
|
3839
|
+
return {
|
|
3840
|
+
launch,
|
|
3841
|
+
Fallback,
|
|
3842
|
+
showFallback,
|
|
3843
|
+
closeFallback,
|
|
3844
|
+
popupRef: popupRef.current,
|
|
3845
|
+
wasBlocked
|
|
3846
|
+
};
|
|
3847
|
+
}
|
|
3721
3848
|
|
|
3722
|
-
export { AudioWaveform,
|
|
3723
|
-
//# sourceMappingURL=
|
|
3724
|
-
//# sourceMappingURL=
|
|
3849
|
+
export { AudioWaveform, CDN_DOMAIN, DEFAULT_ENCODER_SERVER_URL, DIALTRIBE_API_BASE, DialtribeClient, DialtribeOverlay, DialtribePlayer, DialtribePlayerErrorBoundary, DialtribeProvider, DialtribeStreamer, ENDPOINTS, HTTP_STATUS, LoadingSpinner, StreamKeyDisplay, StreamKeyInput, StreamingControls, StreamingPreview, WebSocketStreamer, buildBroadcastCdnUrl, buildBroadcastS3KeyPrefix, calculatePopupDimensions, checkBrowserCompatibility, formatTime, getMediaConstraints, getMediaRecorderOptions, openBroadcastPopup, openDialtribeStreamerPopup, useDialtribe, useDialtribeOptional, useDialtribeStreamerLauncher, useDialtribeStreamerPopup };
|
|
3850
|
+
//# sourceMappingURL=dialtribe-streamer.mjs.map
|
|
3851
|
+
//# sourceMappingURL=dialtribe-streamer.mjs.map
|