@dialtribe/react-sdk 0.1.0-alpha.11 → 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.
@@ -2,10 +2,10 @@ import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import React$1, { Component, ReactNode, ErrorInfo } from 'react';
3
3
 
4
4
  /**
5
- * DialTribe SDK Context
5
+ * Dialtribe SDK Context
6
6
  * Manages session token and auto-refresh across all SDK components
7
7
  */
8
- interface DialTribeContextValue {
8
+ interface DialtribeContextValue {
9
9
  /** Current session token */
10
10
  sessionToken: string | null;
11
11
  /** Update the session token (called automatically on refresh) */
@@ -17,7 +17,7 @@ interface DialTribeContextValue {
17
17
  /** Optional API base URL override */
18
18
  apiBaseUrl?: string;
19
19
  }
20
- interface DialTribeProviderProps {
20
+ interface DialtribeProviderProps {
21
21
  /** Session token from your backend (required) */
22
22
  sessionToken: string;
23
23
  /** Called when the API returns a refreshed token via X-Session-Token header */
@@ -34,70 +34,70 @@ interface DialTribeProviderProps {
34
34
  children: React$1.ReactNode;
35
35
  }
36
36
  /**
37
- * DialTribe Provider
37
+ * Dialtribe Provider
38
38
  *
39
39
  * Wraps your app to provide session token authentication to all SDK components.
40
40
  *
41
41
  * @example
42
42
  * ```tsx
43
43
  * // Production (default)
44
- * <DialTribeProvider
44
+ * <DialtribeProvider
45
45
  * sessionToken="sess_xxx..."
46
46
  * onTokenRefresh={(newToken) => setToken(newToken)}
47
47
  * onTokenExpired={() => router.push('/login')}
48
48
  * >
49
49
  * <App />
50
- * </DialTribeProvider>
50
+ * </DialtribeProvider>
51
51
  *
52
52
  * // Local development (explicit)
53
- * <DialTribeProvider
53
+ * <DialtribeProvider
54
54
  * sessionToken="sess_xxx..."
55
55
  * apiBaseUrl="http://localhost:3001/api/public/v1"
56
56
  * onTokenRefresh={(newToken) => setToken(newToken)}
57
57
  * >
58
58
  * <App />
59
- * </DialTribeProvider>
59
+ * </DialtribeProvider>
60
60
  *
61
61
  * // Local development (via env var - recommended)
62
62
  * // Set NEXT_PUBLIC_DIALTRIBE_API_URL=http://localhost:3001/api/public/v1 in .env
63
- * <DialTribeProvider sessionToken="sess_xxx...">
63
+ * <DialtribeProvider sessionToken="sess_xxx...">
64
64
  * <App />
65
- * </DialTribeProvider>
65
+ * </DialtribeProvider>
66
66
  * ```
67
67
  */
68
- declare function DialTribeProvider({ sessionToken: initialToken, onTokenRefresh, onTokenExpired, apiBaseUrl, children, }: DialTribeProviderProps): react_jsx_runtime.JSX.Element;
68
+ declare function DialtribeProvider({ sessionToken: initialToken, onTokenRefresh, onTokenExpired, apiBaseUrl, children, }: DialtribeProviderProps): react_jsx_runtime.JSX.Element;
69
69
  /**
70
- * Hook to access DialTribe context
70
+ * Hook to access Dialtribe context
71
71
  *
72
- * @throws Error if used outside DialTribeProvider
72
+ * @throws Error if used outside DialtribeProvider
73
73
  *
74
74
  * @example
75
75
  * ```tsx
76
- * const { sessionToken, setSessionToken } = useDialTribe();
76
+ * const { sessionToken, setSessionToken } = useDialtribe();
77
77
  * ```
78
78
  */
79
- declare function useDialTribe(): DialTribeContextValue;
79
+ declare function useDialtribe(): DialtribeContextValue;
80
80
  /**
81
- * Hook to optionally access DialTribe context
82
- * Returns null if not within a DialTribeProvider (doesn't throw)
81
+ * Hook to optionally access Dialtribe context
82
+ * Returns null if not within a DialtribeProvider (doesn't throw)
83
83
  *
84
84
  * @example
85
85
  * ```tsx
86
- * const context = useDialTribeOptional();
86
+ * const context = useDialtribeOptional();
87
87
  * const sessionToken = context?.sessionToken ?? propSessionToken;
88
88
  * ```
89
89
  */
90
- declare function useDialTribeOptional(): DialTribeContextValue | null;
90
+ declare function useDialtribeOptional(): DialtribeContextValue | null;
91
91
 
92
92
  /**
93
- * DialTribe API Client
93
+ * Dialtribe API Client
94
94
  *
95
- * Handles all API communication with DialTribe endpoints.
95
+ * Handles all API communication with Dialtribe endpoints.
96
96
  * Automatically manages session token refresh via X-Session-Token headers.
97
97
  *
98
98
  * Supports configurable API base URL for development:
99
99
  * 1. Via environment variable: NEXT_PUBLIC_DIALTRIBE_API_URL
100
- * 2. Via apiBaseUrl prop on DialTribeProvider (takes precedence)
100
+ * 2. Via apiBaseUrl prop on DialtribeProvider (takes precedence)
101
101
  *
102
102
  * Defaults to production URL if neither is specified.
103
103
  */
@@ -128,17 +128,17 @@ interface ApiClientConfig {
128
128
  apiBaseUrl?: string;
129
129
  }
130
130
  /**
131
- * DialTribe API Client
131
+ * Dialtribe API Client
132
132
  *
133
- * Low-level client for making authenticated requests to DialTribe API.
133
+ * Low-level client for making authenticated requests to Dialtribe API.
134
134
  * Handles session token auto-refresh automatically.
135
135
  */
136
- declare class DialTribeClient {
136
+ declare class DialtribeClient {
137
137
  private config;
138
138
  private endpoints;
139
139
  constructor(config: ApiClientConfig);
140
140
  /**
141
- * Make an authenticated request to DialTribe API
141
+ * Make an authenticated request to Dialtribe API
142
142
  *
143
143
  * Automatically:
144
144
  * - Adds Authorization header with session token
@@ -304,8 +304,8 @@ interface TranscriptData {
304
304
  words?: TranscriptWord[];
305
305
  }
306
306
 
307
- interface BroadcastPlayerProps {
308
- /** Broadcast data from DialTribe API */
307
+ interface DialtribePlayerProps {
308
+ /** Broadcast data from Dialtribe API */
309
309
  broadcast: Broadcast;
310
310
  /** Optional: App ID for tracking */
311
311
  appId?: string;
@@ -335,72 +335,28 @@ interface BroadcastPlayerProps {
335
335
  enableKeyboardShortcuts?: boolean;
336
336
  }
337
337
  /**
338
- * BroadcastPlayer - Core media player component (no modal wrapper)
338
+ * DialtribePlayer - Media player component for Dialtribe broadcasts
339
339
  *
340
340
  * Plays video/audio broadcasts with transcript, waveform visualization, and clip creation.
341
- * Uses DialTribeClient for authenticated API calls.
341
+ * For modal or fullscreen display, wrap with the Overlay component.
342
342
  *
343
343
  * @example
344
344
  * ```tsx
345
- * <BroadcastPlayer
346
- * broadcast={broadcast}
347
- * appId="app_123"
348
- * contentId={456}
349
- * />
350
- * ```
351
- */
352
- declare function BroadcastPlayer({ broadcast, appId, contentId, foreignId, foreignTier, renderClipCreator, onError, className, enableKeyboardShortcuts, }: BroadcastPlayerProps): react_jsx_runtime.JSX.Element;
353
-
354
- interface BroadcastPlayerModalProps {
355
- /** Broadcast data from DialTribe API */
356
- broadcast: Broadcast;
357
- /** Whether modal is open */
358
- isOpen: boolean;
359
- /** Called when modal should close */
360
- onClose: () => void;
361
- /** Optional: App ID for tracking */
362
- appId?: string;
363
- /** Optional: Content ID for tracking */
364
- contentId?: number;
365
- /** Foreign user ID from partner system (any tier) */
366
- foreignId?: string;
367
- /** Tier name from partner system (e.g., 'guest', 'member', 'subscriber_gold') */
368
- foreignTier?: string;
369
- /**
370
- * Optional render prop for clip creator
371
- * If provided, the "Create Clip" button will be shown and this will be called when clicked
372
- */
373
- renderClipCreator?: (props: {
374
- isOpen: boolean;
375
- onClose: () => void;
376
- sourceVideoUrl?: string;
377
- sourceAudioUrl?: string;
378
- sourceDuration: number;
379
- onPauseParent: () => void;
380
- }) => React.ReactNode;
381
- /** Optional: Custom CSS classes for the player */
382
- className?: string;
383
- /** Optional: Enable keyboard shortcuts (Space, arrows, M, F, etc.). Default: false */
384
- enableKeyboardShortcuts?: boolean;
385
- }
386
- /**
387
- * BroadcastPlayerModal - Modal wrapper for BroadcastPlayer
345
+ * // Inline (embedded in page)
346
+ * <DialtribePlayer broadcast={broadcast} />
388
347
  *
389
- * Provides a modal overlay with ESC key handling and backdrop click to close.
390
- * Uses the new BroadcastPlayer component for all player functionality.
348
+ * // Modal (wrap with Overlay)
349
+ * <Overlay mode="modal" isOpen={show} onClose={() => setShow(false)}>
350
+ * <DialtribePlayer broadcast={broadcast} />
351
+ * </Overlay>
391
352
  *
392
- * @example
393
- * ```tsx
394
- * <BroadcastPlayerModal
395
- * broadcast={broadcast}
396
- * isOpen={showModal}
397
- * onClose={() => setShowModal(false)}
398
- * appId="app_123"
399
- * contentId={456}
400
- * />
353
+ * // Fullscreen (wrap with Overlay)
354
+ * <Overlay mode="fullscreen" isOpen={show} onClose={() => setShow(false)}>
355
+ * <DialtribePlayer broadcast={broadcast} />
356
+ * </Overlay>
401
357
  * ```
402
358
  */
403
- declare function BroadcastPlayerModal({ broadcast, isOpen, onClose, appId, contentId, foreignId, foreignTier, renderClipCreator, className, enableKeyboardShortcuts, }: BroadcastPlayerModalProps): react_jsx_runtime.JSX.Element | null;
359
+ declare function DialtribePlayer({ broadcast, appId, contentId, foreignId, foreignTier, renderClipCreator, onError, className, enableKeyboardShortcuts, }: DialtribePlayerProps): react_jsx_runtime.JSX.Element;
404
360
 
405
361
  interface Props {
406
362
  children: ReactNode;
@@ -434,7 +390,7 @@ interface State {
434
390
  * - Logs errors for debugging
435
391
  * - Allows graceful recovery
436
392
  */
437
- declare class BroadcastPlayerErrorBoundary extends Component<Props, State> {
393
+ declare class DialtribePlayerErrorBoundary extends Component<Props, State> {
438
394
  constructor(props: Props);
439
395
  static getDerivedStateFromError(error: Error): Partial<State>;
440
396
  componentDidCatch(error: Error, errorInfo: ErrorInfo): void;
@@ -488,6 +444,50 @@ interface LoadingSpinnerProps {
488
444
  */
489
445
  declare function LoadingSpinner({ text, size, variant, }: LoadingSpinnerProps): react_jsx_runtime.JSX.Element;
490
446
 
447
+ /** Display mode for the overlay */
448
+ type DialtribeOverlayMode = "modal" | "fullscreen";
449
+ interface DialtribeOverlayProps {
450
+ /** Whether the overlay is open */
451
+ isOpen: boolean;
452
+ /** Called when the overlay should close */
453
+ onClose: () => void;
454
+ /** Display mode: "modal" (centered with backdrop) or "fullscreen" (fills viewport) */
455
+ mode?: DialtribeOverlayMode;
456
+ /** Content to display inside the overlay */
457
+ children: React.ReactNode;
458
+ /** Optional: aria-label for accessibility */
459
+ ariaLabel?: string;
460
+ /** Optional: Show close button. Default: true */
461
+ showCloseButton?: boolean;
462
+ /** Optional: Close on backdrop click. Default: true */
463
+ closeOnBackdropClick?: boolean;
464
+ /** Optional: Close on ESC key. Default: true */
465
+ closeOnEsc?: boolean;
466
+ }
467
+ /**
468
+ * DialtribeOverlay - Reusable modal/fullscreen overlay component
469
+ *
470
+ * Provides a consistent overlay experience with:
471
+ * - Focus management (traps focus, restores on close)
472
+ * - ESC key to close
473
+ * - Backdrop click to close
474
+ * - Accessible with proper ARIA attributes
475
+ *
476
+ * @example
477
+ * ```tsx
478
+ * // Modal mode (centered with backdrop blur)
479
+ * <DialtribeOverlay isOpen={show} onClose={() => setShow(false)} mode="modal">
480
+ * <MyContent />
481
+ * </DialtribeOverlay>
482
+ *
483
+ * // Fullscreen mode (fills entire viewport)
484
+ * <DialtribeOverlay isOpen={show} onClose={() => setShow(false)} mode="fullscreen">
485
+ * <MyContent />
486
+ * </DialtribeOverlay>
487
+ * ```
488
+ */
489
+ declare function DialtribeOverlay({ isOpen, onClose, mode, children, ariaLabel, showCloseButton, closeOnBackdropClick, closeOnEsc, }: DialtribeOverlayProps): react_jsx_runtime.JSX.Element | null;
490
+
491
491
  /**
492
492
  * Format seconds to time string (HH:MM:SS or MM:SS)
493
493
  *
@@ -557,4 +557,4 @@ declare const HTTP_STATUS: {
557
557
  };
558
558
  type HttpStatusCode = typeof HTTP_STATUS[keyof typeof HTTP_STATUS];
559
559
 
560
- export { type ApiClientConfig as A, BroadcastPlayer as B, CDN_DOMAIN as C, DialTribeProvider as D, ENDPOINTS as E, HTTP_STATUS as H, LoadingSpinner as L, type TranscriptWord as T, type DialTribeContextValue as a, type DialTribeProviderProps as b, DialTribeClient as c, DIALTRIBE_API_BASE as d, type BroadcastPlayerProps as e, BroadcastPlayerModal as f, type BroadcastPlayerModalProps as g, BroadcastPlayerErrorBoundary as h, AudioWaveform as i, type Broadcast as j, type TranscriptSegment as k, type TranscriptData as l, formatTime as m, buildBroadcastCdnUrl as n, buildBroadcastS3KeyPrefix as o, type HttpStatusCode as p, useDialTribeOptional as q, useDialTribe as u };
560
+ export { type ApiClientConfig as A, type Broadcast as B, CDN_DOMAIN as C, DialtribeProvider as D, ENDPOINTS as E, HTTP_STATUS as H, LoadingSpinner as L, type TranscriptWord as T, type DialtribeContextValue as a, type DialtribeProviderProps as b, DialtribeClient as c, DIALTRIBE_API_BASE as d, DialtribePlayer as e, type DialtribePlayerProps as f, DialtribePlayerErrorBoundary as g, AudioWaveform as h, DialtribeOverlay as i, type DialtribeOverlayProps as j, type DialtribeOverlayMode as k, type TranscriptSegment as l, type TranscriptData as m, formatTime as n, buildBroadcastCdnUrl as o, buildBroadcastS3KeyPrefix as p, type HttpStatusCode as q, useDialtribeOptional as r, useDialtribe as u };
@@ -0,0 +1,3 @@
1
+ export { A as ApiClientConfig, h as AudioWaveform, B as Broadcast, C as CDN_DOMAIN, d as DIALTRIBE_API_BASE, c as DialtribeClient, a as DialtribeContextValue, i as DialtribeOverlay, k as DialtribeOverlayMode, j as DialtribeOverlayProps, e as DialtribePlayer, g as DialtribePlayerErrorBoundary, f as DialtribePlayerProps, D as DialtribeProvider, b as DialtribeProviderProps, E as ENDPOINTS, H as HTTP_STATUS, q as HttpStatusCode, L as LoadingSpinner, m as TranscriptData, l as TranscriptSegment, T as TranscriptWord, o as buildBroadcastCdnUrl, p as buildBroadcastS3KeyPrefix, n as formatTime, u as useDialtribe } from './dialtribe-player-Rc9kfQiX.mjs';
2
+ import 'react/jsx-runtime';
3
+ import 'react';
@@ -0,0 +1,3 @@
1
+ export { A as ApiClientConfig, h as AudioWaveform, B as Broadcast, C as CDN_DOMAIN, d as DIALTRIBE_API_BASE, c as DialtribeClient, a as DialtribeContextValue, i as DialtribeOverlay, k as DialtribeOverlayMode, j as DialtribeOverlayProps, e as DialtribePlayer, g as DialtribePlayerErrorBoundary, f as DialtribePlayerProps, D as DialtribeProvider, b as DialtribeProviderProps, E as ENDPOINTS, H as HTTP_STATUS, q as HttpStatusCode, L as LoadingSpinner, m as TranscriptData, l as TranscriptSegment, T as TranscriptWord, o as buildBroadcastCdnUrl, p as buildBroadcastS3KeyPrefix, n as formatTime, u as useDialtribe } from './dialtribe-player-Rc9kfQiX.js';
2
+ import 'react/jsx-runtime';
3
+ import 'react';
@@ -8,9 +8,9 @@ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
8
8
 
9
9
  var ReactPlayer__default = /*#__PURE__*/_interopDefault(ReactPlayer);
10
10
 
11
- // src/context/DialTribeProvider.tsx
12
- var DialTribeContext = react.createContext(null);
13
- function DialTribeProvider({
11
+ // src/context/DialtribeProvider.tsx
12
+ var DialtribeContext = react.createContext(null);
13
+ function DialtribeProvider({
14
14
  sessionToken: initialToken,
15
15
  onTokenRefresh,
16
16
  onTokenExpired,
@@ -46,19 +46,19 @@ function DialTribeProvider({
46
46
  markExpired,
47
47
  apiBaseUrl
48
48
  };
49
- return /* @__PURE__ */ jsxRuntime.jsx(DialTribeContext.Provider, { value, children });
49
+ return /* @__PURE__ */ jsxRuntime.jsx(DialtribeContext.Provider, { value, children });
50
50
  }
51
- function useDialTribe() {
52
- const context = react.useContext(DialTribeContext);
51
+ function useDialtribe() {
52
+ const context = react.useContext(DialtribeContext);
53
53
  if (!context) {
54
54
  throw new Error(
55
- 'useDialTribe must be used within a DialTribeProvider. Wrap your app with <DialTribeProvider sessionToken="sess_xxx">...</DialTribeProvider>'
55
+ 'useDialtribe must be used within a DialtribeProvider. Wrap your app with <DialtribeProvider sessionToken="sess_xxx">...</DialtribeProvider>'
56
56
  );
57
57
  }
58
58
  return context;
59
59
  }
60
60
 
61
- // src/client/DialTribeClient.ts
61
+ // src/client/DialtribeClient.ts
62
62
  function getDefaultApiBaseUrl() {
63
63
  if (typeof process !== "undefined" && process.env?.NEXT_PUBLIC_DIALTRIBE_API_URL) {
64
64
  return process.env.NEXT_PUBLIC_DIALTRIBE_API_URL;
@@ -78,13 +78,13 @@ function getEndpoints(baseUrl = DIALTRIBE_API_BASE) {
78
78
  };
79
79
  }
80
80
  var ENDPOINTS = getEndpoints();
81
- var DialTribeClient = class {
81
+ var DialtribeClient = class {
82
82
  constructor(config) {
83
83
  this.config = config;
84
84
  this.endpoints = config.apiBaseUrl ? getEndpoints(config.apiBaseUrl) : ENDPOINTS;
85
85
  }
86
86
  /**
87
- * Make an authenticated request to DialTribe API
87
+ * Make an authenticated request to Dialtribe API
88
88
  *
89
89
  * Automatically:
90
90
  * - Adds Authorization header with session token
@@ -749,7 +749,7 @@ function getErrorMessage(error) {
749
749
  }
750
750
  return "Unable to play media. Please try refreshing the page or contact support if the problem persists.";
751
751
  }
752
- function BroadcastPlayer({
752
+ function DialtribePlayer({
753
753
  broadcast,
754
754
  appId,
755
755
  contentId,
@@ -760,18 +760,18 @@ function BroadcastPlayer({
760
760
  className = "",
761
761
  enableKeyboardShortcuts = false
762
762
  }) {
763
- const { sessionToken, setSessionToken, markExpired, apiBaseUrl } = useDialTribe();
763
+ const { sessionToken, setSessionToken, markExpired, apiBaseUrl } = useDialtribe();
764
764
  const clientRef = react.useRef(null);
765
765
  if (!clientRef.current && sessionToken) {
766
- clientRef.current = new DialTribeClient({
766
+ clientRef.current = new DialtribeClient({
767
767
  sessionToken,
768
768
  apiBaseUrl,
769
769
  onTokenRefresh: (newToken, expiresAt) => {
770
- debug.log(`[DialTribeClient] Token refreshed, expires at ${expiresAt}`);
770
+ debug.log(`[DialtribeClient] Token refreshed, expires at ${expiresAt}`);
771
771
  setSessionToken(newToken, expiresAt);
772
772
  },
773
773
  onTokenExpired: () => {
774
- debug.error("[DialTribeClient] Token expired");
774
+ debug.error("[DialtribeClient] Token expired");
775
775
  markExpired();
776
776
  }
777
777
  });
@@ -1216,7 +1216,7 @@ function BroadcastPlayer({
1216
1216
  setAudioElement(internalPlayer);
1217
1217
  }
1218
1218
  } catch (error) {
1219
- debug.error("[BroadcastPlayer] Error getting internal player:", error);
1219
+ debug.error("[DialtribePlayer] Error getting internal player:", error);
1220
1220
  }
1221
1221
  };
1222
1222
  react.useEffect(() => {
@@ -1424,7 +1424,7 @@ function BroadcastPlayer({
1424
1424
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-center p-8", children: /* @__PURE__ */ jsxRuntime.jsx(LoadingSpinner, { variant: "white", text: "Loading..." }) });
1425
1425
  }
1426
1426
  const hasTranscript = broadcast.transcriptStatus === 2 && transcriptData && (transcriptData.segments && transcriptData.segments.some((s) => s.words && s.words.length > 0) || transcriptData.words && transcriptData.words.length > 0);
1427
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `bg-black rounded-lg shadow-2xl w-full max-h-full flex flex-col overflow-hidden ${className}`, children: [
1427
+ 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: [
1428
1428
  /* @__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: [
1429
1429
  /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
1430
1430
  /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-lg font-semibold text-white", children: broadcast.streamKeyRecord?.foreignName || "Broadcast" }),
@@ -1956,90 +1956,9 @@ function BroadcastPlayer({
1956
1956
  }
1957
1957
  ` })
1958
1958
  ] });
1959
+ return playerContent;
1959
1960
  }
1960
- function BroadcastPlayerModal({
1961
- broadcast,
1962
- isOpen,
1963
- onClose,
1964
- appId,
1965
- contentId,
1966
- foreignId,
1967
- foreignTier,
1968
- renderClipCreator,
1969
- className,
1970
- enableKeyboardShortcuts = false
1971
- }) {
1972
- const closeButtonRef = react.useRef(null);
1973
- const previousActiveElement = react.useRef(null);
1974
- react.useEffect(() => {
1975
- if (!isOpen) return;
1976
- previousActiveElement.current = document.activeElement;
1977
- setTimeout(() => {
1978
- closeButtonRef.current?.focus();
1979
- }, 100);
1980
- return () => {
1981
- if (previousActiveElement.current) {
1982
- previousActiveElement.current.focus();
1983
- }
1984
- };
1985
- }, [isOpen]);
1986
- react.useEffect(() => {
1987
- if (!isOpen) return;
1988
- const handleKeyDown = (e) => {
1989
- if (e.key === "Escape") {
1990
- onClose();
1991
- }
1992
- };
1993
- document.addEventListener("keydown", handleKeyDown);
1994
- return () => document.removeEventListener("keydown", handleKeyDown);
1995
- }, [isOpen, onClose]);
1996
- if (!isOpen) return null;
1997
- const handleBackdropClick = (e) => {
1998
- if (e.target === e.currentTarget) {
1999
- onClose();
2000
- }
2001
- };
2002
- return /* @__PURE__ */ jsxRuntime.jsx(
2003
- "div",
2004
- {
2005
- className: "fixed inset-0 bg-black/70 backdrop-blur-xl flex items-center justify-center z-50 p-2 sm:p-4",
2006
- onClick: handleBackdropClick,
2007
- role: "dialog",
2008
- "aria-modal": "true",
2009
- "aria-label": "Broadcast player",
2010
- children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative w-full max-w-7xl max-h-[95vh] sm:max-h-[90vh] overflow-hidden", children: [
2011
- /* @__PURE__ */ jsxRuntime.jsx(
2012
- "button",
2013
- {
2014
- ref: closeButtonRef,
2015
- onClick: onClose,
2016
- 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",
2017
- title: "Close (ESC)",
2018
- "aria-label": "Close player",
2019
- children: "\xD7"
2020
- }
2021
- ),
2022
- /* @__PURE__ */ jsxRuntime.jsx(
2023
- BroadcastPlayer,
2024
- {
2025
- broadcast,
2026
- appId,
2027
- contentId,
2028
- foreignId,
2029
- foreignTier,
2030
- renderClipCreator,
2031
- className,
2032
- enableKeyboardShortcuts,
2033
- onError: (error) => {
2034
- debug.error("[BroadcastPlayerModal] Player error:", error);
2035
- }
2036
- }
2037
- )
2038
- ] })
2039
- }
2040
- );
2041
- }
2042
- var BroadcastPlayerErrorBoundary = class extends react.Component {
1961
+ var DialtribePlayerErrorBoundary = class extends react.Component {
2043
1962
  constructor(props) {
2044
1963
  super(props);
2045
1964
  this.handleReset = () => {
@@ -2165,21 +2084,99 @@ var BroadcastPlayerErrorBoundary = class extends react.Component {
2165
2084
  return this.props.children;
2166
2085
  }
2167
2086
  };
2087
+ var overlayStyles = {
2088
+ modal: {
2089
+ backdrop: "bg-black/70 backdrop-blur-xl p-2 sm:p-4",
2090
+ container: "max-w-7xl max-h-[95vh] sm:max-h-[90vh]"
2091
+ },
2092
+ fullscreen: {
2093
+ backdrop: "bg-black",
2094
+ container: "h-full"
2095
+ }
2096
+ };
2097
+ function DialtribeOverlay({
2098
+ isOpen,
2099
+ onClose,
2100
+ mode = "modal",
2101
+ children,
2102
+ ariaLabel = "Dialog",
2103
+ showCloseButton = true,
2104
+ closeOnBackdropClick = true,
2105
+ closeOnEsc = true
2106
+ }) {
2107
+ const closeButtonRef = react.useRef(null);
2108
+ const previousActiveElement = react.useRef(null);
2109
+ react.useEffect(() => {
2110
+ if (!isOpen) return;
2111
+ previousActiveElement.current = document.activeElement;
2112
+ setTimeout(() => {
2113
+ closeButtonRef.current?.focus();
2114
+ }, 100);
2115
+ return () => {
2116
+ if (previousActiveElement.current) {
2117
+ previousActiveElement.current.focus();
2118
+ }
2119
+ };
2120
+ }, [isOpen]);
2121
+ react.useEffect(() => {
2122
+ if (!isOpen || !closeOnEsc) return;
2123
+ const handleKeyDown = (e) => {
2124
+ if (e.key === "Escape") {
2125
+ onClose();
2126
+ }
2127
+ };
2128
+ document.addEventListener("keydown", handleKeyDown);
2129
+ return () => document.removeEventListener("keydown", handleKeyDown);
2130
+ }, [isOpen, onClose, closeOnEsc]);
2131
+ if (!isOpen) {
2132
+ return null;
2133
+ }
2134
+ const handleBackdropClick = (e) => {
2135
+ if (closeOnBackdropClick && e.target === e.currentTarget) {
2136
+ onClose();
2137
+ }
2138
+ };
2139
+ const styles = overlayStyles[mode];
2140
+ return /* @__PURE__ */ jsxRuntime.jsx(
2141
+ "div",
2142
+ {
2143
+ className: `fixed inset-0 flex items-center justify-center z-50 ${styles.backdrop}`,
2144
+ onClick: handleBackdropClick,
2145
+ role: "dialog",
2146
+ "aria-modal": "true",
2147
+ "aria-label": ariaLabel,
2148
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `relative w-full overflow-hidden ${styles.container}`, children: [
2149
+ showCloseButton && /* @__PURE__ */ jsxRuntime.jsx(
2150
+ "button",
2151
+ {
2152
+ ref: closeButtonRef,
2153
+ onClick: onClose,
2154
+ 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",
2155
+ title: "Close (ESC)",
2156
+ "aria-label": "Close",
2157
+ children: "\xD7"
2158
+ }
2159
+ ),
2160
+ children
2161
+ ] })
2162
+ }
2163
+ );
2164
+ }
2168
2165
 
2169
2166
  exports.AudioWaveform = AudioWaveform;
2170
- exports.BroadcastPlayer = BroadcastPlayer;
2171
- exports.BroadcastPlayerErrorBoundary = BroadcastPlayerErrorBoundary;
2172
- exports.BroadcastPlayerModal = BroadcastPlayerModal;
2173
2167
  exports.CDN_DOMAIN = CDN_DOMAIN;
2174
2168
  exports.DIALTRIBE_API_BASE = DIALTRIBE_API_BASE;
2175
- exports.DialTribeClient = DialTribeClient;
2176
- exports.DialTribeProvider = DialTribeProvider;
2169
+ exports.DialtribeClient = DialtribeClient;
2170
+ exports.DialtribeOverlay = DialtribeOverlay;
2171
+ exports.DialtribePlayer = DialtribePlayer;
2172
+ exports.DialtribePlayerErrorBoundary = DialtribePlayerErrorBoundary;
2173
+ exports.DialtribeProvider = DialtribeProvider;
2177
2174
  exports.ENDPOINTS = ENDPOINTS;
2178
2175
  exports.HTTP_STATUS = HTTP_STATUS;
2179
2176
  exports.LoadingSpinner = LoadingSpinner;
2180
2177
  exports.buildBroadcastCdnUrl = buildBroadcastCdnUrl;
2181
2178
  exports.buildBroadcastS3KeyPrefix = buildBroadcastS3KeyPrefix;
2182
2179
  exports.formatTime = formatTime;
2183
- exports.useDialTribe = useDialTribe;
2184
- //# sourceMappingURL=broadcast-player.js.map
2185
- //# sourceMappingURL=broadcast-player.js.map
2180
+ exports.useDialtribe = useDialtribe;
2181
+ //# sourceMappingURL=dialtribe-player.js.map
2182
+ //# sourceMappingURL=dialtribe-player.js.map