@livepeer-frameworks/player-react 0.1.0 → 0.1.2

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.
Files changed (187) hide show
  1. package/README.md +7 -9
  2. package/dist/cjs/_virtual/_rollupPluginBabelHelpers.js +359 -0
  3. package/dist/cjs/_virtual/_rollupPluginBabelHelpers.js.map +1 -0
  4. package/dist/cjs/assets/logomark.svg.js +8 -0
  5. package/dist/cjs/assets/logomark.svg.js.map +1 -0
  6. package/dist/cjs/components/DevModePanel.js +826 -0
  7. package/dist/cjs/components/DevModePanel.js.map +1 -0
  8. package/dist/cjs/components/DvdLogo.js +200 -0
  9. package/dist/cjs/components/DvdLogo.js.map +1 -0
  10. package/dist/cjs/components/Icons.js +439 -0
  11. package/dist/cjs/components/Icons.js.map +1 -0
  12. package/dist/cjs/components/IdleScreen.js +587 -0
  13. package/dist/cjs/components/IdleScreen.js.map +1 -0
  14. package/dist/cjs/components/LoadingScreen.js +523 -0
  15. package/dist/cjs/components/LoadingScreen.js.map +1 -0
  16. package/dist/cjs/components/Player.js +420 -0
  17. package/dist/cjs/components/Player.js.map +1 -0
  18. package/dist/cjs/components/PlayerControls.js +798 -0
  19. package/dist/cjs/components/PlayerControls.js.map +1 -0
  20. package/dist/cjs/components/PlayerErrorBoundary.js +80 -0
  21. package/dist/cjs/components/PlayerErrorBoundary.js.map +1 -0
  22. package/dist/cjs/components/SeekBar.js +253 -0
  23. package/dist/cjs/components/SeekBar.js.map +1 -0
  24. package/dist/cjs/components/SkipIndicator.js +92 -0
  25. package/dist/cjs/components/SkipIndicator.js.map +1 -0
  26. package/dist/cjs/components/SpeedIndicator.js +43 -0
  27. package/dist/cjs/components/SpeedIndicator.js.map +1 -0
  28. package/dist/cjs/components/StatsPanel.js +202 -0
  29. package/dist/cjs/components/StatsPanel.js.map +1 -0
  30. package/dist/cjs/components/StreamStateOverlay.js +229 -0
  31. package/dist/cjs/components/StreamStateOverlay.js.map +1 -0
  32. package/dist/cjs/components/ThumbnailOverlay.js +86 -0
  33. package/dist/cjs/components/ThumbnailOverlay.js.map +1 -0
  34. package/dist/cjs/components/TitleOverlay.js +32 -0
  35. package/dist/cjs/components/TitleOverlay.js.map +1 -0
  36. package/dist/cjs/context/PlayerContext.js +46 -0
  37. package/dist/cjs/context/PlayerContext.js.map +1 -0
  38. package/dist/cjs/hooks/useMetaTrack.js +165 -0
  39. package/dist/cjs/hooks/useMetaTrack.js.map +1 -0
  40. package/dist/cjs/hooks/usePlaybackQuality.js +131 -0
  41. package/dist/cjs/hooks/usePlaybackQuality.js.map +1 -0
  42. package/dist/cjs/hooks/usePlayerController.js +518 -0
  43. package/dist/cjs/hooks/usePlayerController.js.map +1 -0
  44. package/dist/cjs/hooks/usePlayerSelection.js +90 -0
  45. package/dist/cjs/hooks/usePlayerSelection.js.map +1 -0
  46. package/dist/cjs/hooks/useStreamState.js +360 -0
  47. package/dist/cjs/hooks/useStreamState.js.map +1 -0
  48. package/dist/cjs/hooks/useTelemetry.js +120 -0
  49. package/dist/cjs/hooks/useTelemetry.js.map +1 -0
  50. package/dist/cjs/hooks/useViewerEndpoints.js +222 -0
  51. package/dist/cjs/hooks/useViewerEndpoints.js.map +1 -0
  52. package/dist/cjs/index.js +97 -1
  53. package/dist/cjs/index.js.map +1 -1
  54. package/dist/cjs/ui/badge.js +34 -0
  55. package/dist/cjs/ui/badge.js.map +1 -0
  56. package/dist/cjs/ui/button.js +74 -0
  57. package/dist/cjs/ui/button.js.map +1 -0
  58. package/dist/cjs/ui/context-menu.js +163 -0
  59. package/dist/cjs/ui/context-menu.js.map +1 -0
  60. package/dist/cjs/ui/slider.js +60 -0
  61. package/dist/cjs/ui/slider.js.map +1 -0
  62. package/dist/esm/_virtual/_rollupPluginBabelHelpers.js +329 -0
  63. package/dist/esm/_virtual/_rollupPluginBabelHelpers.js.map +1 -0
  64. package/dist/esm/assets/logomark.svg.js +4 -0
  65. package/dist/esm/assets/logomark.svg.js.map +1 -0
  66. package/dist/esm/components/DevModePanel.js +822 -0
  67. package/dist/esm/components/DevModePanel.js.map +1 -0
  68. package/dist/esm/components/DvdLogo.js +196 -0
  69. package/dist/esm/components/DvdLogo.js.map +1 -0
  70. package/dist/esm/components/Icons.js +421 -0
  71. package/dist/esm/components/Icons.js.map +1 -0
  72. package/dist/esm/components/IdleScreen.js +582 -0
  73. package/dist/esm/components/IdleScreen.js.map +1 -0
  74. package/dist/esm/components/LoadingScreen.js +519 -0
  75. package/dist/esm/components/LoadingScreen.js.map +1 -0
  76. package/dist/esm/components/Player.js +416 -0
  77. package/dist/esm/components/Player.js.map +1 -0
  78. package/dist/esm/components/PlayerControls.js +794 -0
  79. package/dist/esm/components/PlayerControls.js.map +1 -0
  80. package/dist/esm/components/PlayerErrorBoundary.js +76 -0
  81. package/dist/esm/components/PlayerErrorBoundary.js.map +1 -0
  82. package/dist/esm/components/SeekBar.js +249 -0
  83. package/dist/esm/components/SeekBar.js.map +1 -0
  84. package/dist/esm/components/SkipIndicator.js +88 -0
  85. package/dist/esm/components/SkipIndicator.js.map +1 -0
  86. package/dist/esm/components/SpeedIndicator.js +39 -0
  87. package/dist/esm/components/SpeedIndicator.js.map +1 -0
  88. package/dist/esm/components/StatsPanel.js +198 -0
  89. package/dist/esm/components/StatsPanel.js.map +1 -0
  90. package/dist/esm/components/StreamStateOverlay.js +224 -0
  91. package/dist/esm/components/StreamStateOverlay.js.map +1 -0
  92. package/dist/esm/components/ThumbnailOverlay.js +82 -0
  93. package/dist/esm/components/ThumbnailOverlay.js.map +1 -0
  94. package/dist/esm/components/TitleOverlay.js +28 -0
  95. package/dist/esm/components/TitleOverlay.js.map +1 -0
  96. package/dist/esm/context/PlayerContext.js +41 -0
  97. package/dist/esm/context/PlayerContext.js.map +1 -0
  98. package/dist/esm/hooks/useMetaTrack.js +163 -0
  99. package/dist/esm/hooks/useMetaTrack.js.map +1 -0
  100. package/dist/esm/hooks/usePlaybackQuality.js +129 -0
  101. package/dist/esm/hooks/usePlaybackQuality.js.map +1 -0
  102. package/dist/esm/hooks/usePlayerController.js +516 -0
  103. package/dist/esm/hooks/usePlayerController.js.map +1 -0
  104. package/dist/esm/hooks/usePlayerSelection.js +88 -0
  105. package/dist/esm/hooks/usePlayerSelection.js.map +1 -0
  106. package/dist/esm/hooks/useStreamState.js +358 -0
  107. package/dist/esm/hooks/useStreamState.js.map +1 -0
  108. package/dist/esm/hooks/useTelemetry.js +118 -0
  109. package/dist/esm/hooks/useTelemetry.js.map +1 -0
  110. package/dist/esm/hooks/useViewerEndpoints.js +220 -0
  111. package/dist/esm/hooks/useViewerEndpoints.js.map +1 -0
  112. package/dist/esm/index.js +23 -1
  113. package/dist/esm/index.js.map +1 -1
  114. package/dist/esm/ui/badge.js +31 -0
  115. package/dist/esm/ui/badge.js.map +1 -0
  116. package/dist/esm/ui/button.js +52 -0
  117. package/dist/esm/ui/button.js.map +1 -0
  118. package/dist/esm/ui/context-menu.js +132 -0
  119. package/dist/esm/ui/context-menu.js.map +1 -0
  120. package/dist/esm/ui/slider.js +38 -0
  121. package/dist/esm/ui/slider.js.map +1 -0
  122. package/dist/types/components/DvdLogo.d.ts +1 -1
  123. package/dist/types/components/Icons.d.ts +1 -1
  124. package/dist/types/components/Player.d.ts +1 -1
  125. package/dist/types/components/PlayerErrorBoundary.d.ts +2 -1
  126. package/dist/types/components/StreamStateOverlay.d.ts +2 -2
  127. package/dist/types/components/SubtitleRenderer.d.ts +2 -2
  128. package/dist/types/context/PlayerContext.d.ts +2 -2
  129. package/dist/types/context/index.d.ts +2 -2
  130. package/dist/types/hooks/useMetaTrack.d.ts +3 -3
  131. package/dist/types/hooks/usePlaybackQuality.d.ts +2 -2
  132. package/dist/types/hooks/usePlayerController.d.ts +26 -3
  133. package/dist/types/hooks/usePlayerSelection.d.ts +1 -1
  134. package/dist/types/hooks/useStreamState.d.ts +1 -1
  135. package/dist/types/hooks/useTelemetry.d.ts +1 -1
  136. package/dist/types/hooks/useViewerEndpoints.d.ts +3 -3
  137. package/dist/types/index.d.ts +28 -28
  138. package/dist/types/types.d.ts +3 -3
  139. package/dist/types/ui/select.d.ts +1 -1
  140. package/package.json +22 -14
  141. package/src/components/DevModePanel.tsx +244 -143
  142. package/src/components/DvdLogo.tsx +1 -1
  143. package/src/components/Icons.tsx +105 -25
  144. package/src/components/IdleScreen.tsx +262 -128
  145. package/src/components/LoadingScreen.tsx +169 -151
  146. package/src/components/LogoOverlay.tsx +3 -6
  147. package/src/components/Player.tsx +126 -59
  148. package/src/components/PlayerControls.tsx +384 -272
  149. package/src/components/PlayerErrorBoundary.tsx +7 -13
  150. package/src/components/SeekBar.tsx +96 -88
  151. package/src/components/SkipIndicator.tsx +2 -12
  152. package/src/components/SpeedIndicator.tsx +2 -11
  153. package/src/components/StatsPanel.tsx +31 -22
  154. package/src/components/StreamStateOverlay.tsx +105 -49
  155. package/src/components/SubtitleRenderer.tsx +29 -29
  156. package/src/components/ThumbnailOverlay.tsx +5 -6
  157. package/src/components/TitleOverlay.tsx +2 -8
  158. package/src/context/PlayerContext.tsx +4 -8
  159. package/src/context/index.ts +3 -3
  160. package/src/hooks/useMetaTrack.ts +27 -27
  161. package/src/hooks/usePlaybackQuality.ts +3 -3
  162. package/src/hooks/usePlayerController.ts +246 -138
  163. package/src/hooks/usePlayerSelection.ts +6 -6
  164. package/src/hooks/useStreamState.ts +51 -56
  165. package/src/hooks/useTelemetry.ts +18 -3
  166. package/src/hooks/useViewerEndpoints.ts +34 -23
  167. package/src/index.tsx +36 -28
  168. package/src/types.ts +8 -8
  169. package/src/ui/badge.tsx +6 -5
  170. package/src/ui/button.tsx +9 -8
  171. package/src/ui/context-menu.tsx +42 -61
  172. package/src/ui/select.tsx +13 -7
  173. package/src/ui/slider.tsx +18 -29
  174. package/dist/types/components/players/DashJsPlayer.d.ts +0 -18
  175. package/dist/types/components/players/HlsJsPlayer.d.ts +0 -18
  176. package/dist/types/components/players/MewsWsPlayer/index.d.ts +0 -18
  177. package/dist/types/components/players/MistPlayer.d.ts +0 -20
  178. package/dist/types/components/players/MistWebRTCPlayer/index.d.ts +0 -20
  179. package/dist/types/components/players/NativePlayer.d.ts +0 -19
  180. package/dist/types/components/players/VideoJsPlayer.d.ts +0 -18
  181. package/src/components/players/DashJsPlayer.tsx +0 -56
  182. package/src/components/players/HlsJsPlayer.tsx +0 -56
  183. package/src/components/players/MewsWsPlayer/index.tsx +0 -56
  184. package/src/components/players/MistPlayer.tsx +0 -60
  185. package/src/components/players/MistWebRTCPlayer/index.tsx +0 -59
  186. package/src/components/players/NativePlayer.tsx +0 -58
  187. package/src/components/players/VideoJsPlayer.tsx +0 -56
@@ -0,0 +1,582 @@
1
+ import { slicedToArray as _slicedToArray, toConsumableArray as _toConsumableArray } from '../_virtual/_rollupPluginBabelHelpers.js';
2
+ import { jsxs, jsx } from 'react/jsx-runtime';
3
+ import { useRef, useState, useEffect } from 'react';
4
+ import DvdLogo from './DvdLogo.js';
5
+ import logomarkAsset from '../assets/logomark.svg.js';
6
+
7
+ var AnimatedBubble = function AnimatedBubble(_ref) {
8
+ var index = _ref.index;
9
+ var _useState = useState({
10
+ top: 0,
11
+ left: 0
12
+ }),
13
+ _useState2 = _slicedToArray(_useState, 2),
14
+ position = _useState2[0],
15
+ setPosition = _useState2[1];
16
+ var _useState3 = useState(40),
17
+ _useState4 = _slicedToArray(_useState3, 2),
18
+ size = _useState4[0],
19
+ setSize = _useState4[1];
20
+ var _useState5 = useState(0),
21
+ _useState6 = _slicedToArray(_useState5, 2),
22
+ opacity = _useState6[0],
23
+ setOpacity = _useState6[1];
24
+ var getRandomPosition = function getRandomPosition() {
25
+ return {
26
+ top: Math.random() * 80 + 10,
27
+ left: Math.random() * 80 + 10
28
+ };
29
+ };
30
+ var getRandomSize = function getRandomSize() {
31
+ return Math.random() * 60 + 30;
32
+ };
33
+ useEffect(function () {
34
+ setPosition(getRandomPosition());
35
+ setSize(getRandomSize());
36
+ var _animationCycle = function animationCycle() {
37
+ setOpacity(0.15);
38
+ setTimeout(function () {
39
+ setOpacity(0);
40
+ setTimeout(function () {
41
+ setPosition(getRandomPosition());
42
+ setSize(getRandomSize());
43
+ setTimeout(function () {
44
+ _animationCycle();
45
+ }, 200);
46
+ }, 1500);
47
+ }, 4000 + Math.random() * 3000);
48
+ };
49
+ var timeout = setTimeout(_animationCycle, index * 500);
50
+ return function () {
51
+ return clearTimeout(timeout);
52
+ };
53
+ }, [index]);
54
+ var bubbleColors = ["rgba(122, 162, 247, 0.2)", "rgba(187, 154, 247, 0.2)", "rgba(158, 206, 106, 0.2)", "rgba(115, 218, 202, 0.2)", "rgba(125, 207, 255, 0.2)", "rgba(247, 118, 142, 0.2)", "rgba(224, 175, 104, 0.2)", "rgba(42, 195, 222, 0.2)"];
55
+ return jsx("div", {
56
+ style: {
57
+ position: "absolute",
58
+ top: "".concat(position.top, "%"),
59
+ left: "".concat(position.left, "%"),
60
+ width: "".concat(size, "px"),
61
+ height: "".concat(size, "px"),
62
+ borderRadius: "50%",
63
+ background: bubbleColors[index % bubbleColors.length],
64
+ opacity: opacity,
65
+ transition: "opacity 1s ease-in-out",
66
+ pointerEvents: "none",
67
+ userSelect: "none"
68
+ }
69
+ });
70
+ };
71
+ var CenterLogo = function CenterLogo(_ref2) {
72
+ var containerRef = _ref2.containerRef,
73
+ _ref2$scale = _ref2.scale,
74
+ scale = _ref2$scale === void 0 ? 0.2 : _ref2$scale,
75
+ onHitmarker = _ref2.onHitmarker;
76
+ var _useState7 = useState(100),
77
+ _useState8 = _slicedToArray(_useState7, 2),
78
+ logoSize = _useState8[0],
79
+ setLogoSize = _useState8[1];
80
+ var _useState9 = useState({
81
+ x: 0,
82
+ y: 0
83
+ }),
84
+ _useState0 = _slicedToArray(_useState9, 2),
85
+ offset = _useState0[0],
86
+ setOffset = _useState0[1];
87
+ var _useState1 = useState(false),
88
+ _useState10 = _slicedToArray(_useState1, 2),
89
+ isHovered = _useState10[0],
90
+ setIsHovered = _useState10[1];
91
+ useEffect(function () {
92
+ if (containerRef.current) {
93
+ var containerWidth = containerRef.current.clientWidth;
94
+ var containerHeight = containerRef.current.clientHeight;
95
+ var minDimension = Math.min(containerWidth, containerHeight);
96
+ setLogoSize(minDimension * scale);
97
+ }
98
+ }, [containerRef, scale]);
99
+ var handleLogoClick = function handleLogoClick(e) {
100
+ e.stopPropagation();
101
+ if (onHitmarker) {
102
+ onHitmarker({
103
+ clientX: e.clientX,
104
+ clientY: e.clientY
105
+ });
106
+ }
107
+ };
108
+ var handleMouseMove = function handleMouseMove(e) {
109
+ if (!containerRef.current) return;
110
+ var rect = containerRef.current.getBoundingClientRect();
111
+ var centerX = rect.left + rect.width / 2;
112
+ var centerY = rect.top + rect.height / 2;
113
+ var deltaX = e.clientX - centerX;
114
+ var deltaY = e.clientY - centerY;
115
+ var distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
116
+ var maxDistance = logoSize * 1.5;
117
+ if (distance < maxDistance && distance > 0) {
118
+ var pushStrength = (maxDistance - distance) / maxDistance;
119
+ var pushDistance = 50 * pushStrength;
120
+ var pushX = -(deltaX / distance) * pushDistance;
121
+ var pushY = -(deltaY / distance) * pushDistance;
122
+ setOffset({
123
+ x: pushX,
124
+ y: pushY
125
+ });
126
+ setIsHovered(true);
127
+ } else {
128
+ setOffset({
129
+ x: 0,
130
+ y: 0
131
+ });
132
+ setIsHovered(false);
133
+ }
134
+ };
135
+ var handleMouseLeave = function handleMouseLeave() {
136
+ setOffset({
137
+ x: 0,
138
+ y: 0
139
+ });
140
+ setIsHovered(false);
141
+ };
142
+ useEffect(function () {
143
+ if (containerRef.current) {
144
+ var container = containerRef.current;
145
+ container.addEventListener("mousemove", handleMouseMove);
146
+ container.addEventListener("mouseleave", handleMouseLeave);
147
+ return function () {
148
+ container.removeEventListener("mousemove", handleMouseMove);
149
+ container.removeEventListener("mouseleave", handleMouseLeave);
150
+ };
151
+ }
152
+ }, [logoSize, containerRef]);
153
+ return jsxs("div", {
154
+ style: {
155
+ position: "absolute",
156
+ top: "50%",
157
+ left: "50%",
158
+ transform: "translate(-50%, -50%) translate(".concat(offset.x, "px, ").concat(offset.y, "px)"),
159
+ display: "flex",
160
+ alignItems: "center",
161
+ justifyContent: "center",
162
+ zIndex: 10,
163
+ transition: "transform 0.3s ease-out",
164
+ userSelect: "none"
165
+ },
166
+ children: [jsx("div", {
167
+ style: {
168
+ position: "absolute",
169
+ width: "".concat(logoSize * 1.4, "px"),
170
+ height: "".concat(logoSize * 1.4, "px"),
171
+ borderRadius: "50%",
172
+ background: "rgba(122, 162, 247, 0.15)",
173
+ animation: isHovered ? "logoPulse 1s ease-in-out infinite" : "logoPulse 3s ease-in-out infinite",
174
+ transform: isHovered ? "scale(1.2)" : "scale(1)",
175
+ transition: "transform 0.3s ease-out",
176
+ pointerEvents: "none"
177
+ }
178
+ }), jsx("img", {
179
+ src: logomarkAsset,
180
+ alt: "FrameWorks Logo",
181
+ onClick: handleLogoClick,
182
+ style: {
183
+ width: "".concat(logoSize, "px"),
184
+ height: "".concat(logoSize, "px"),
185
+ position: "relative",
186
+ zIndex: 1,
187
+ filter: isHovered ? "drop-shadow(0 6px 12px rgba(36, 40, 59, 0.4)) brightness(1.1)" : "drop-shadow(0 4px 8px rgba(36, 40, 59, 0.3))",
188
+ transform: isHovered ? "scale(1.1)" : "scale(1)",
189
+ transition: "all 0.3s ease-out",
190
+ cursor: isHovered ? "pointer" : "default",
191
+ userSelect: "none",
192
+ WebkitUserDrag: "none"
193
+ }
194
+ })]
195
+ });
196
+ };
197
+ function StatusIcon(_ref3) {
198
+ var status = _ref3.status;
199
+ var iconClass = "w-5 h-5";
200
+ // Spinner for loading states
201
+ if (status === "INITIALIZING" || status === "BOOTING" || status === "WAITING_FOR_DATA" || !status) {
202
+ return jsxs("svg", {
203
+ className: "".concat(iconClass, " animate-spin"),
204
+ fill: "none",
205
+ viewBox: "0 0 24 24",
206
+ style: {
207
+ color: "hsl(var(--tn-yellow, 40 95% 64%))"
208
+ },
209
+ children: [jsx("circle", {
210
+ className: "opacity-25",
211
+ cx: "12",
212
+ cy: "12",
213
+ r: "10",
214
+ stroke: "currentColor",
215
+ strokeWidth: "4"
216
+ }), jsx("path", {
217
+ className: "opacity-75",
218
+ fill: "currentColor",
219
+ d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
220
+ })]
221
+ });
222
+ }
223
+ // Offline icon
224
+ if (status === "OFFLINE") {
225
+ return jsx("svg", {
226
+ className: iconClass,
227
+ fill: "none",
228
+ viewBox: "0 0 24 24",
229
+ stroke: "currentColor",
230
+ style: {
231
+ color: "hsl(var(--tn-red, 348 100% 72%))"
232
+ },
233
+ children: jsx("path", {
234
+ strokeLinecap: "round",
235
+ strokeLinejoin: "round",
236
+ strokeWidth: 2,
237
+ d: "M18.364 5.636a9 9 0 010 12.728m0 0l-2.829-2.829m2.829 2.829L21 21M15.536 8.464a5 5 0 010 7.072m0 0l-2.829-2.829m-4.243 2.829a4.978 4.978 0 01-1.414-2.83m-1.414 5.658a9 9 0 01-2.167-9.238m7.824 2.167a1 1 0 111.414 1.414m-1.414-1.414L3 3m8.293 8.293l1.414 1.414"
238
+ })
239
+ });
240
+ }
241
+ // Error icon
242
+ if (status === "ERROR" || status === "INVALID") {
243
+ return jsx("svg", {
244
+ className: iconClass,
245
+ fill: "none",
246
+ viewBox: "0 0 24 24",
247
+ stroke: "currentColor",
248
+ style: {
249
+ color: "hsl(var(--tn-red, 348 100% 72%))"
250
+ },
251
+ children: jsx("path", {
252
+ strokeLinecap: "round",
253
+ strokeLinejoin: "round",
254
+ strokeWidth: 2,
255
+ d: "M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"
256
+ })
257
+ });
258
+ }
259
+ // Default spinner
260
+ return jsxs("svg", {
261
+ className: "".concat(iconClass, " animate-spin"),
262
+ fill: "none",
263
+ viewBox: "0 0 24 24",
264
+ style: {
265
+ color: "hsl(var(--tn-cyan, 193 100% 75%))"
266
+ },
267
+ children: [jsx("circle", {
268
+ className: "opacity-25",
269
+ cx: "12",
270
+ cy: "12",
271
+ r: "10",
272
+ stroke: "currentColor",
273
+ strokeWidth: "4"
274
+ }), jsx("path", {
275
+ className: "opacity-75",
276
+ fill: "currentColor",
277
+ d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
278
+ })]
279
+ });
280
+ }
281
+ var StatusOverlay = function StatusOverlay(_ref4) {
282
+ var status = _ref4.status,
283
+ message = _ref4.message,
284
+ percentage = _ref4.percentage,
285
+ error = _ref4.error,
286
+ onRetry = _ref4.onRetry;
287
+ var showRetry = (status === "ERROR" || status === "INVALID") && onRetry;
288
+ var showProgress = status === "INITIALIZING" && percentage !== undefined;
289
+ var displayMessage = error || message;
290
+ return jsxs("div", {
291
+ style: {
292
+ position: "absolute",
293
+ bottom: "16px",
294
+ left: "50%",
295
+ transform: "translateX(-50%)",
296
+ zIndex: 20,
297
+ display: "flex",
298
+ flexDirection: "column",
299
+ alignItems: "center",
300
+ gap: "8px",
301
+ maxWidth: "280px",
302
+ textAlign: "center"
303
+ },
304
+ children: [jsxs("div", {
305
+ style: {
306
+ display: "flex",
307
+ alignItems: "center",
308
+ gap: "8px",
309
+ color: "#787c99",
310
+ fontSize: "13px",
311
+ fontFamily: "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif"
312
+ },
313
+ children: [jsx(StatusIcon, {
314
+ status: status
315
+ }), jsx("span", {
316
+ children: displayMessage
317
+ })]
318
+ }), showProgress && jsx("div", {
319
+ style: {
320
+ width: "160px",
321
+ height: "4px",
322
+ background: "rgba(65, 72, 104, 0.4)",
323
+ borderRadius: "2px",
324
+ overflow: "hidden"
325
+ },
326
+ children: jsx("div", {
327
+ style: {
328
+ width: "".concat(Math.min(100, percentage), "%"),
329
+ height: "100%",
330
+ background: "hsl(var(--tn-cyan, 193 100% 75%))",
331
+ transition: "width 0.3s ease-out"
332
+ }
333
+ })
334
+ }), showRetry && jsx("button", {
335
+ type: "button",
336
+ onClick: onRetry,
337
+ style: {
338
+ padding: "6px 16px",
339
+ background: "transparent",
340
+ border: "1px solid rgba(122, 162, 247, 0.4)",
341
+ borderRadius: "4px",
342
+ color: "#7aa2f7",
343
+ fontSize: "11px",
344
+ fontWeight: 500,
345
+ cursor: "pointer",
346
+ transition: "all 0.2s ease",
347
+ fontFamily: "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif"
348
+ },
349
+ onMouseEnter: function onMouseEnter(e) {
350
+ e.currentTarget.style.background = "rgba(122, 162, 247, 0.1)";
351
+ },
352
+ onMouseLeave: function onMouseLeave(e) {
353
+ e.currentTarget.style.background = "transparent";
354
+ },
355
+ children: "Retry"
356
+ })]
357
+ });
358
+ };
359
+ var playHitmarkerSound = function playHitmarkerSound() {
360
+ try {
361
+ // Embedded hitmarker sound as base64 data URL
362
+ var hitmarkerDataUrl = "data:audio/mpeg;base64,SUQzBAAAAAAANFRDT04AAAAHAAADT3RoZXIAVFNTRQAAAA8AAANMYXZmNTcuODMuMTAwAAAAAAAAAAAA" + "AAD/+1QAAAAAAAAAAAAAAAAAAAAA" + "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" + "qqqqqqqqqqqqqqqqqqqqqqqqqqo=";
363
+ var audio = new Audio(hitmarkerDataUrl);
364
+ audio.volume = 0.3;
365
+ audio.play()["catch"](function () {
366
+ return createSyntheticHitmarkerSound();
367
+ });
368
+ } catch (_unused) {
369
+ createSyntheticHitmarkerSound();
370
+ }
371
+ };
372
+ var createSyntheticHitmarkerSound = function createSyntheticHitmarkerSound() {
373
+ try {
374
+ var audioContext = new (window.AudioContext || window.webkitAudioContext)();
375
+ var oscillator1 = audioContext.createOscillator();
376
+ var oscillator2 = audioContext.createOscillator();
377
+ var gainNode1 = audioContext.createGain();
378
+ var gainNode2 = audioContext.createGain();
379
+ var masterGain = audioContext.createGain();
380
+ oscillator1.connect(gainNode1);
381
+ oscillator2.connect(gainNode2);
382
+ gainNode1.connect(masterGain);
383
+ gainNode2.connect(masterGain);
384
+ masterGain.connect(audioContext.destination);
385
+ oscillator1.frequency.setValueAtTime(1800, audioContext.currentTime);
386
+ oscillator1.frequency.exponentialRampToValueAtTime(900, audioContext.currentTime + 0.08);
387
+ oscillator2.frequency.setValueAtTime(3600, audioContext.currentTime);
388
+ oscillator2.frequency.exponentialRampToValueAtTime(1800, audioContext.currentTime + 0.04);
389
+ oscillator1.type = "triangle";
390
+ oscillator2.type = "sine";
391
+ gainNode1.gain.setValueAtTime(0, audioContext.currentTime);
392
+ gainNode1.gain.linearRampToValueAtTime(0.4, audioContext.currentTime + 0.002);
393
+ gainNode1.gain.exponentialRampToValueAtTime(0.001, audioContext.currentTime + 0.12);
394
+ gainNode2.gain.setValueAtTime(0, audioContext.currentTime);
395
+ gainNode2.gain.linearRampToValueAtTime(0.3, audioContext.currentTime + 0.001);
396
+ gainNode2.gain.exponentialRampToValueAtTime(0.001, audioContext.currentTime + 0.06);
397
+ masterGain.gain.setValueAtTime(0.5, audioContext.currentTime);
398
+ var startTime = audioContext.currentTime;
399
+ var stopTime = startTime + 0.15;
400
+ oscillator1.start(startTime);
401
+ oscillator2.start(startTime);
402
+ oscillator1.stop(stopTime);
403
+ oscillator2.stop(stopTime);
404
+ } catch (_unused2) {
405
+ // Audio context not available
406
+ }
407
+ };
408
+ var IdleScreen = function IdleScreen(_ref5) {
409
+ var status = _ref5.status,
410
+ _ref5$message = _ref5.message,
411
+ message = _ref5$message === void 0 ? "Waiting for stream..." : _ref5$message,
412
+ percentage = _ref5.percentage,
413
+ error = _ref5.error,
414
+ onRetry = _ref5.onRetry;
415
+ var containerRef = useRef(null);
416
+ var _useState11 = useState([]),
417
+ _useState12 = _slicedToArray(_useState11, 2),
418
+ hitmarkers = _useState12[0],
419
+ setHitmarkers = _useState12[1];
420
+ var createHitmarker = function createHitmarker(e) {
421
+ if (!containerRef.current) return;
422
+ var rect = containerRef.current.getBoundingClientRect();
423
+ var x = e.clientX - rect.left;
424
+ var y = e.clientY - rect.top;
425
+ var newHitmarker = {
426
+ id: Date.now() + Math.random(),
427
+ x: x,
428
+ y: y
429
+ };
430
+ setHitmarkers(function (prev) {
431
+ return [].concat(_toConsumableArray(prev), [newHitmarker]);
432
+ });
433
+ playHitmarkerSound();
434
+ setTimeout(function () {
435
+ setHitmarkers(function (prev) {
436
+ return prev.filter(function (h) {
437
+ return h.id !== newHitmarker.id;
438
+ });
439
+ });
440
+ }, 600);
441
+ };
442
+ // Inject CSS animations
443
+ useEffect(function () {
444
+ var styleId = "idle-screen-animations";
445
+ if (!document.getElementById(styleId)) {
446
+ var style = document.createElement("style");
447
+ style.id = styleId;
448
+ style.textContent = "\n @keyframes fadeInOut {\n 0%, 100% { opacity: 0.6; }\n 50% { opacity: 0.9; }\n }\n @keyframes logoPulse {\n 0%, 100% { opacity: 0.15; transform: scale(1); }\n 50% { opacity: 0.25; transform: scale(1.05); }\n }\n @keyframes floatUp {\n 0% { transform: translateY(100vh) rotate(0deg); opacity: 0; }\n 10% { opacity: 0.6; }\n 90% { opacity: 0.6; }\n 100% { transform: translateY(-100px) rotate(360deg); opacity: 0; }\n }\n @keyframes gradientShift {\n 0%, 100% { background-position: 0% 50%; }\n 50% { background-position: 100% 50%; }\n }\n @keyframes hitmarkerFade45 {\n 0% { opacity: 1; transform: translate(-50%, -50%) rotate(45deg) scale(0.5); }\n 20% { opacity: 1; transform: translate(-50%, -50%) rotate(45deg) scale(1.2); }\n 100% { opacity: 0; transform: translate(-50%, -50%) rotate(45deg) scale(1); }\n }\n @keyframes hitmarkerFadeNeg45 {\n 0% { opacity: 1; transform: translate(-50%, -50%) rotate(-45deg) scale(0.5); }\n 20% { opacity: 1; transform: translate(-50%, -50%) rotate(-45deg) scale(1.2); }\n 100% { opacity: 0; transform: translate(-50%, -50%) rotate(-45deg) scale(1); }\n }\n ";
449
+ document.head.appendChild(style);
450
+ }
451
+ }, []);
452
+ return jsxs("div", {
453
+ ref: containerRef,
454
+ className: "fw-player-root",
455
+ style: {
456
+ position: "absolute",
457
+ inset: 0,
458
+ zIndex: 5,
459
+ background: "\n linear-gradient(135deg,\n hsl(var(--tn-bg-dark, 235 21% 11%)) 0%,\n hsl(var(--tn-bg, 233 23% 17%)) 25%,\n hsl(var(--tn-bg-dark, 235 21% 11%)) 50%,\n hsl(var(--tn-bg, 233 23% 17%)) 75%,\n hsl(var(--tn-bg-dark, 235 21% 11%)) 100%\n )\n ",
460
+ backgroundSize: "400% 400%",
461
+ animation: "gradientShift 16s ease-in-out infinite",
462
+ display: "flex",
463
+ flexDirection: "column",
464
+ alignItems: "center",
465
+ justifyContent: "center",
466
+ overflow: "hidden",
467
+ borderRadius: "0",
468
+ userSelect: "none"
469
+ },
470
+ children: [hitmarkers.map(function (hitmarker) {
471
+ return jsxs("div", {
472
+ style: {
473
+ position: "absolute",
474
+ left: "".concat(hitmarker.x, "px"),
475
+ top: "".concat(hitmarker.y, "px"),
476
+ transform: "translate(-50%, -50%)",
477
+ pointerEvents: "none",
478
+ zIndex: 100,
479
+ width: "40px",
480
+ height: "40px"
481
+ },
482
+ children: [jsx("div", {
483
+ style: {
484
+ position: "absolute",
485
+ top: "25%",
486
+ left: "25%",
487
+ width: "12px",
488
+ height: "3px",
489
+ backgroundColor: "#ffffff",
490
+ transform: "translate(-50%, -50%) rotate(45deg)",
491
+ animation: "hitmarkerFade45 0.6s ease-out forwards",
492
+ boxShadow: "0 0 8px rgba(255, 255, 255, 0.8)",
493
+ borderRadius: "1px"
494
+ }
495
+ }), jsx("div", {
496
+ style: {
497
+ position: "absolute",
498
+ top: "25%",
499
+ left: "75%",
500
+ width: "12px",
501
+ height: "3px",
502
+ backgroundColor: "#ffffff",
503
+ transform: "translate(-50%, -50%) rotate(-45deg)",
504
+ animation: "hitmarkerFadeNeg45 0.6s ease-out forwards",
505
+ boxShadow: "0 0 8px rgba(255, 255, 255, 0.8)",
506
+ borderRadius: "1px"
507
+ }
508
+ }), jsx("div", {
509
+ style: {
510
+ position: "absolute",
511
+ top: "75%",
512
+ left: "25%",
513
+ width: "12px",
514
+ height: "3px",
515
+ backgroundColor: "#ffffff",
516
+ transform: "translate(-50%, -50%) rotate(-45deg)",
517
+ animation: "hitmarkerFadeNeg45 0.6s ease-out forwards",
518
+ boxShadow: "0 0 8px rgba(255, 255, 255, 0.8)",
519
+ borderRadius: "1px"
520
+ }
521
+ }), jsx("div", {
522
+ style: {
523
+ position: "absolute",
524
+ top: "75%",
525
+ left: "75%",
526
+ width: "12px",
527
+ height: "3px",
528
+ backgroundColor: "#ffffff",
529
+ transform: "translate(-50%, -50%) rotate(45deg)",
530
+ animation: "hitmarkerFade45 0.6s ease-out forwards",
531
+ boxShadow: "0 0 8px rgba(255, 255, 255, 0.8)",
532
+ borderRadius: "1px"
533
+ }
534
+ })]
535
+ }, hitmarker.id);
536
+ }), _toConsumableArray(Array(12)).map(function (_, index) {
537
+ return jsx("div", {
538
+ style: {
539
+ position: "absolute",
540
+ left: "".concat(Math.random() * 100, "%"),
541
+ width: "".concat(Math.random() * 4 + 2, "px"),
542
+ height: "".concat(Math.random() * 4 + 2, "px"),
543
+ borderRadius: "50%",
544
+ background: ["#7aa2f7", "#bb9af7", "#9ece6a", "#73daca", "#7dcfff", "#f7768e", "#e0af68", "#2ac3de"][index % 8],
545
+ opacity: 0,
546
+ animation: "floatUp ".concat(8 + Math.random() * 4, "s linear infinite"),
547
+ animationDelay: "".concat(Math.random() * 8, "s"),
548
+ pointerEvents: "none"
549
+ }
550
+ }, "particle-".concat(index));
551
+ }), _toConsumableArray(Array(8)).map(function (_, index) {
552
+ return jsx(AnimatedBubble, {
553
+ index: index
554
+ }, index);
555
+ }), jsx(CenterLogo, {
556
+ containerRef: containerRef,
557
+ onHitmarker: createHitmarker
558
+ }), jsx(DvdLogo, {
559
+ parentRef: containerRef,
560
+ scale: 0.08
561
+ }), jsx(StatusOverlay, {
562
+ status: status,
563
+ message: message,
564
+ percentage: percentage,
565
+ error: error,
566
+ onRetry: onRetry
567
+ }), jsx("div", {
568
+ style: {
569
+ position: "absolute",
570
+ top: 0,
571
+ left: 0,
572
+ right: 0,
573
+ bottom: 0,
574
+ background: "\n radial-gradient(circle at 20% 80%, rgba(122, 162, 247, 0.03) 0%, transparent 50%),\n radial-gradient(circle at 80% 20%, rgba(187, 154, 247, 0.03) 0%, transparent 50%),\n radial-gradient(circle at 40% 40%, rgba(158, 206, 106, 0.02) 0%, transparent 50%)\n ",
575
+ pointerEvents: "none"
576
+ }
577
+ })]
578
+ });
579
+ };
580
+
581
+ export { IdleScreen, IdleScreen as default };
582
+ //# sourceMappingURL=IdleScreen.js.map