analytica-frontend-lib 1.1.77 → 1.1.78
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/NotificationCard/index.js +23 -0
- package/dist/NotificationCard/index.js.map +1 -1
- package/dist/NotificationCard/index.mjs +23 -0
- package/dist/NotificationCard/index.mjs.map +1 -1
- package/dist/VideoPlayer/index.js +262 -118
- package/dist/VideoPlayer/index.js.map +1 -1
- package/dist/VideoPlayer/index.mjs +233 -89
- package/dist/VideoPlayer/index.mjs.map +1 -1
- package/dist/hooks/useMobile/index.d.mts +5 -0
- package/dist/hooks/useMobile/index.d.ts +5 -0
- package/dist/hooks/useMobile/index.js +23 -0
- package/dist/hooks/useMobile/index.js.map +1 -1
- package/dist/hooks/useMobile/index.mjs +23 -0
- package/dist/hooks/useMobile/index.mjs.map +1 -1
- package/dist/index.css +38 -0
- package/dist/index.css.map +1 -1
- package/dist/index.js +153 -66
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +153 -66
- package/dist/index.mjs.map +1 -1
- package/dist/styles.css +38 -0
- package/dist/styles.css.map +1 -1
- package/package.json +1 -1
|
@@ -23,7 +23,7 @@ __export(VideoPlayer_exports, {
|
|
|
23
23
|
default: () => VideoPlayer_default
|
|
24
24
|
});
|
|
25
25
|
module.exports = __toCommonJS(VideoPlayer_exports);
|
|
26
|
-
var
|
|
26
|
+
var import_react3 = require("react");
|
|
27
27
|
var import_react_dom = require("react-dom");
|
|
28
28
|
var import_phosphor_react = require("phosphor-react");
|
|
29
29
|
|
|
@@ -138,6 +138,86 @@ var Text = ({
|
|
|
138
138
|
};
|
|
139
139
|
var Text_default = Text;
|
|
140
140
|
|
|
141
|
+
// src/hooks/useMobile.ts
|
|
142
|
+
var import_react2 = require("react");
|
|
143
|
+
var MOBILE_WIDTH = 500;
|
|
144
|
+
var TABLET_WIDTH = 931;
|
|
145
|
+
var SMALL_MOBILE_WIDTH = 425;
|
|
146
|
+
var EXTRA_SMALL_MOBILE_WIDTH = 375;
|
|
147
|
+
var ULTRA_SMALL_MOBILE_WIDTH = 375;
|
|
148
|
+
var TINY_MOBILE_WIDTH = 320;
|
|
149
|
+
var DEFAULT_WIDTH = 1200;
|
|
150
|
+
var getWindowWidth = () => {
|
|
151
|
+
if (typeof window === "undefined") {
|
|
152
|
+
return DEFAULT_WIDTH;
|
|
153
|
+
}
|
|
154
|
+
return window.innerWidth;
|
|
155
|
+
};
|
|
156
|
+
var getDeviceType = () => {
|
|
157
|
+
const width = getWindowWidth();
|
|
158
|
+
return width < TABLET_WIDTH ? "responsive" : "desktop";
|
|
159
|
+
};
|
|
160
|
+
var useMobile = () => {
|
|
161
|
+
const [isMobile, setIsMobile] = (0, import_react2.useState)(false);
|
|
162
|
+
const [isTablet, setIsTablet] = (0, import_react2.useState)(false);
|
|
163
|
+
const [isSmallMobile, setIsSmallMobile] = (0, import_react2.useState)(false);
|
|
164
|
+
const [isExtraSmallMobile, setIsExtraSmallMobile] = (0, import_react2.useState)(false);
|
|
165
|
+
const [isUltraSmallMobile, setIsUltraSmallMobile] = (0, import_react2.useState)(false);
|
|
166
|
+
const [isTinyMobile, setIsTinyMobile] = (0, import_react2.useState)(false);
|
|
167
|
+
(0, import_react2.useEffect)(() => {
|
|
168
|
+
const checkScreenSize = () => {
|
|
169
|
+
const width = getWindowWidth();
|
|
170
|
+
setIsMobile(width < MOBILE_WIDTH);
|
|
171
|
+
setIsTablet(width < TABLET_WIDTH);
|
|
172
|
+
setIsSmallMobile(width < SMALL_MOBILE_WIDTH);
|
|
173
|
+
setIsExtraSmallMobile(width < EXTRA_SMALL_MOBILE_WIDTH);
|
|
174
|
+
setIsUltraSmallMobile(width < ULTRA_SMALL_MOBILE_WIDTH);
|
|
175
|
+
setIsTinyMobile(width < TINY_MOBILE_WIDTH);
|
|
176
|
+
};
|
|
177
|
+
checkScreenSize();
|
|
178
|
+
window.addEventListener("resize", checkScreenSize);
|
|
179
|
+
return () => window.removeEventListener("resize", checkScreenSize);
|
|
180
|
+
}, []);
|
|
181
|
+
const getFormContainerClasses = () => {
|
|
182
|
+
if (isMobile) {
|
|
183
|
+
return "w-full px-4";
|
|
184
|
+
}
|
|
185
|
+
if (isTablet) {
|
|
186
|
+
return "w-full px-6";
|
|
187
|
+
}
|
|
188
|
+
return "w-full max-w-[992px] mx-auto px-0";
|
|
189
|
+
};
|
|
190
|
+
const getMobileHeaderClasses = () => {
|
|
191
|
+
return "flex flex-col items-start gap-4 mb-6";
|
|
192
|
+
};
|
|
193
|
+
const getDesktopHeaderClasses = () => {
|
|
194
|
+
return "flex flex-row justify-between items-center gap-6 mb-8";
|
|
195
|
+
};
|
|
196
|
+
const getHeaderClasses = () => {
|
|
197
|
+
return isMobile ? getMobileHeaderClasses() : getDesktopHeaderClasses();
|
|
198
|
+
};
|
|
199
|
+
const getVideoContainerClasses = () => {
|
|
200
|
+
if (isTinyMobile) return "aspect-square";
|
|
201
|
+
if (isExtraSmallMobile) return "aspect-[4/3]";
|
|
202
|
+
if (isSmallMobile) return "aspect-[16/12]";
|
|
203
|
+
return "aspect-video";
|
|
204
|
+
};
|
|
205
|
+
return {
|
|
206
|
+
isMobile,
|
|
207
|
+
isTablet,
|
|
208
|
+
isSmallMobile,
|
|
209
|
+
isExtraSmallMobile,
|
|
210
|
+
isUltraSmallMobile,
|
|
211
|
+
isTinyMobile,
|
|
212
|
+
getFormContainerClasses,
|
|
213
|
+
getHeaderClasses,
|
|
214
|
+
getMobileHeaderClasses,
|
|
215
|
+
getDesktopHeaderClasses,
|
|
216
|
+
getVideoContainerClasses,
|
|
217
|
+
getDeviceType
|
|
218
|
+
};
|
|
219
|
+
};
|
|
220
|
+
|
|
141
221
|
// src/components/VideoPlayer/VideoPlayer.tsx
|
|
142
222
|
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
143
223
|
var CONTROLS_HIDE_TIMEOUT = 3e3;
|
|
@@ -153,8 +233,9 @@ var ProgressBar = ({
|
|
|
153
233
|
currentTime,
|
|
154
234
|
duration,
|
|
155
235
|
progressPercentage,
|
|
156
|
-
onSeek
|
|
157
|
-
|
|
236
|
+
onSeek,
|
|
237
|
+
className = "px-4 pb-2"
|
|
238
|
+
}) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
158
239
|
"input",
|
|
159
240
|
{
|
|
160
241
|
type: "range",
|
|
@@ -173,18 +254,20 @@ var VolumeControls = ({
|
|
|
173
254
|
volume,
|
|
174
255
|
isMuted,
|
|
175
256
|
onVolumeChange,
|
|
176
|
-
onToggleMute
|
|
257
|
+
onToggleMute,
|
|
258
|
+
iconSize = 24,
|
|
259
|
+
showSlider = true
|
|
177
260
|
}) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
178
261
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
179
262
|
IconButton_default,
|
|
180
263
|
{
|
|
181
|
-
icon: isMuted ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_phosphor_react.SpeakerSlash, { size:
|
|
264
|
+
icon: isMuted ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_phosphor_react.SpeakerSlash, { size: iconSize }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_phosphor_react.SpeakerHigh, { size: iconSize }),
|
|
182
265
|
onClick: onToggleMute,
|
|
183
266
|
"aria-label": isMuted ? "Unmute" : "Mute",
|
|
184
267
|
className: "!bg-transparent !text-white hover:!bg-white/20"
|
|
185
268
|
}
|
|
186
269
|
),
|
|
187
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
270
|
+
showSlider && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
188
271
|
"input",
|
|
189
272
|
{
|
|
190
273
|
type: "range",
|
|
@@ -205,22 +288,27 @@ var SpeedMenu = ({
|
|
|
205
288
|
playbackRate,
|
|
206
289
|
onToggleMenu,
|
|
207
290
|
onSpeedChange,
|
|
208
|
-
isFullscreen
|
|
291
|
+
isFullscreen,
|
|
292
|
+
iconSize = 24,
|
|
293
|
+
isTinyMobile = false
|
|
209
294
|
}) => {
|
|
210
|
-
const buttonRef = (0,
|
|
211
|
-
const speedMenuContainerRef = (0,
|
|
212
|
-
const speedMenuRef = (0,
|
|
295
|
+
const buttonRef = (0, import_react3.useRef)(null);
|
|
296
|
+
const speedMenuContainerRef = (0, import_react3.useRef)(null);
|
|
297
|
+
const speedMenuRef = (0, import_react3.useRef)(null);
|
|
213
298
|
const getMenuPosition = () => {
|
|
214
299
|
if (!buttonRef.current) return { top: 0, left: 0 };
|
|
215
300
|
const rect = buttonRef.current.getBoundingClientRect();
|
|
301
|
+
const menuHeight = isTinyMobile ? 150 : 180;
|
|
302
|
+
const menuWidth = isTinyMobile ? 60 : 80;
|
|
303
|
+
const padding = isTinyMobile ? 4 : 8;
|
|
216
304
|
return {
|
|
217
305
|
// Fixed coords are viewport-based — no scroll offsets.
|
|
218
|
-
top: Math.max(
|
|
219
|
-
left: Math.max(
|
|
306
|
+
top: Math.max(padding, rect.top - menuHeight),
|
|
307
|
+
left: Math.max(padding, rect.right - menuWidth)
|
|
220
308
|
};
|
|
221
309
|
};
|
|
222
310
|
const position = getMenuPosition();
|
|
223
|
-
(0,
|
|
311
|
+
(0, import_react3.useEffect)(() => {
|
|
224
312
|
const handleClickOutside = (event) => {
|
|
225
313
|
const target = event.target;
|
|
226
314
|
const isOutsideContainer = speedMenuContainerRef.current && !speedMenuContainerRef.current.contains(target);
|
|
@@ -269,7 +357,7 @@ var SpeedMenu = ({
|
|
|
269
357
|
IconButton_default,
|
|
270
358
|
{
|
|
271
359
|
ref: buttonRef,
|
|
272
|
-
icon: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_phosphor_react.DotsThreeVertical, { size:
|
|
360
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_phosphor_react.DotsThreeVertical, { size: iconSize }),
|
|
273
361
|
onClick: onToggleMenu,
|
|
274
362
|
"aria-label": "Playback speed",
|
|
275
363
|
"aria-haspopup": "menu",
|
|
@@ -294,26 +382,27 @@ var VideoPlayer = ({
|
|
|
294
382
|
autoSave = true,
|
|
295
383
|
storageKey = "video-progress"
|
|
296
384
|
}) => {
|
|
297
|
-
const videoRef = (0,
|
|
298
|
-
const
|
|
299
|
-
const [
|
|
300
|
-
const [
|
|
301
|
-
const [
|
|
302
|
-
const [
|
|
303
|
-
const [
|
|
304
|
-
const [
|
|
305
|
-
const [
|
|
306
|
-
const [
|
|
307
|
-
(0,
|
|
385
|
+
const videoRef = (0, import_react3.useRef)(null);
|
|
386
|
+
const { isUltraSmallMobile, isTinyMobile } = useMobile();
|
|
387
|
+
const [isPlaying, setIsPlaying] = (0, import_react3.useState)(false);
|
|
388
|
+
const [currentTime, setCurrentTime] = (0, import_react3.useState)(0);
|
|
389
|
+
const [duration, setDuration] = (0, import_react3.useState)(0);
|
|
390
|
+
const [isMuted, setIsMuted] = (0, import_react3.useState)(false);
|
|
391
|
+
const [volume, setVolume] = (0, import_react3.useState)(1);
|
|
392
|
+
const [isFullscreen, setIsFullscreen] = (0, import_react3.useState)(false);
|
|
393
|
+
const [showControls, setShowControls] = (0, import_react3.useState)(true);
|
|
394
|
+
const [hasCompleted, setHasCompleted] = (0, import_react3.useState)(false);
|
|
395
|
+
const [showCaptions, setShowCaptions] = (0, import_react3.useState)(false);
|
|
396
|
+
(0, import_react3.useEffect)(() => {
|
|
308
397
|
setHasCompleted(false);
|
|
309
398
|
}, [src]);
|
|
310
|
-
const [playbackRate, setPlaybackRate] = (0,
|
|
311
|
-
const [showSpeedMenu, setShowSpeedMenu] = (0,
|
|
312
|
-
const lastSaveTimeRef = (0,
|
|
313
|
-
const trackRef = (0,
|
|
314
|
-
const controlsTimeoutRef = (0,
|
|
315
|
-
const lastMousePositionRef = (0,
|
|
316
|
-
const isUserInteracting = (0,
|
|
399
|
+
const [playbackRate, setPlaybackRate] = (0, import_react3.useState)(1);
|
|
400
|
+
const [showSpeedMenu, setShowSpeedMenu] = (0, import_react3.useState)(false);
|
|
401
|
+
const lastSaveTimeRef = (0, import_react3.useRef)(0);
|
|
402
|
+
const trackRef = (0, import_react3.useRef)(null);
|
|
403
|
+
const controlsTimeoutRef = (0, import_react3.useRef)(null);
|
|
404
|
+
const lastMousePositionRef = (0, import_react3.useRef)({ x: 0, y: 0 });
|
|
405
|
+
const isUserInteracting = (0, import_react3.useCallback)(() => {
|
|
317
406
|
if (showSpeedMenu) {
|
|
318
407
|
return true;
|
|
319
408
|
}
|
|
@@ -330,13 +419,13 @@ var VideoPlayer = ({
|
|
|
330
419
|
}
|
|
331
420
|
return false;
|
|
332
421
|
}, [showSpeedMenu]);
|
|
333
|
-
const clearControlsTimeout = (0,
|
|
422
|
+
const clearControlsTimeout = (0, import_react3.useCallback)(() => {
|
|
334
423
|
if (controlsTimeoutRef.current) {
|
|
335
424
|
clearTimeout(controlsTimeoutRef.current);
|
|
336
425
|
controlsTimeoutRef.current = null;
|
|
337
426
|
}
|
|
338
427
|
}, []);
|
|
339
|
-
const showControlsWithTimer = (0,
|
|
428
|
+
const showControlsWithTimer = (0, import_react3.useCallback)(() => {
|
|
340
429
|
setShowControls(true);
|
|
341
430
|
clearControlsTimeout();
|
|
342
431
|
if (isFullscreen) {
|
|
@@ -351,7 +440,7 @@ var VideoPlayer = ({
|
|
|
351
440
|
}, CONTROLS_HIDE_TIMEOUT);
|
|
352
441
|
}
|
|
353
442
|
}, [isFullscreen, isPlaying, clearControlsTimeout]);
|
|
354
|
-
const handleMouseMove = (0,
|
|
443
|
+
const handleMouseMove = (0, import_react3.useCallback)(
|
|
355
444
|
(event) => {
|
|
356
445
|
const currentX = event.clientX;
|
|
357
446
|
const currentY = event.clientY;
|
|
@@ -364,10 +453,10 @@ var VideoPlayer = ({
|
|
|
364
453
|
},
|
|
365
454
|
[showControlsWithTimer]
|
|
366
455
|
);
|
|
367
|
-
const handleMouseEnter = (0,
|
|
456
|
+
const handleMouseEnter = (0, import_react3.useCallback)(() => {
|
|
368
457
|
showControlsWithTimer();
|
|
369
458
|
}, [showControlsWithTimer]);
|
|
370
|
-
const handleMouseLeave = (0,
|
|
459
|
+
const handleMouseLeave = (0, import_react3.useCallback)(() => {
|
|
371
460
|
const userInteracting = isUserInteracting();
|
|
372
461
|
clearControlsTimeout();
|
|
373
462
|
if (!isFullscreen && !userInteracting) {
|
|
@@ -376,13 +465,13 @@ var VideoPlayer = ({
|
|
|
376
465
|
}, LEAVE_HIDE_TIMEOUT);
|
|
377
466
|
}
|
|
378
467
|
}, [isFullscreen, clearControlsTimeout, isUserInteracting]);
|
|
379
|
-
(0,
|
|
468
|
+
(0, import_react3.useEffect)(() => {
|
|
380
469
|
if (videoRef.current) {
|
|
381
470
|
videoRef.current.volume = volume;
|
|
382
471
|
videoRef.current.muted = isMuted;
|
|
383
472
|
}
|
|
384
473
|
}, [volume, isMuted]);
|
|
385
|
-
(0,
|
|
474
|
+
(0, import_react3.useEffect)(() => {
|
|
386
475
|
const video = videoRef.current;
|
|
387
476
|
if (!video) return;
|
|
388
477
|
const onPlay = () => setIsPlaying(true);
|
|
@@ -397,7 +486,13 @@ var VideoPlayer = ({
|
|
|
397
486
|
video.removeEventListener("ended", onEnded);
|
|
398
487
|
};
|
|
399
488
|
}, []);
|
|
400
|
-
(0,
|
|
489
|
+
(0, import_react3.useEffect)(() => {
|
|
490
|
+
const video = videoRef.current;
|
|
491
|
+
if (!video) return;
|
|
492
|
+
video.setAttribute("playsinline", "");
|
|
493
|
+
video.setAttribute("webkit-playsinline", "");
|
|
494
|
+
}, []);
|
|
495
|
+
(0, import_react3.useEffect)(() => {
|
|
401
496
|
if (isPlaying) {
|
|
402
497
|
showControlsWithTimer();
|
|
403
498
|
} else {
|
|
@@ -409,7 +504,7 @@ var VideoPlayer = ({
|
|
|
409
504
|
}
|
|
410
505
|
}
|
|
411
506
|
}, [isPlaying, isFullscreen, showControlsWithTimer, clearControlsTimeout]);
|
|
412
|
-
(0,
|
|
507
|
+
(0, import_react3.useEffect)(() => {
|
|
413
508
|
const handleFullscreenChange = () => {
|
|
414
509
|
const isCurrentlyFullscreen = !!document.fullscreenElement;
|
|
415
510
|
setIsFullscreen(isCurrentlyFullscreen);
|
|
@@ -422,7 +517,7 @@ var VideoPlayer = ({
|
|
|
422
517
|
document.removeEventListener("fullscreenchange", handleFullscreenChange);
|
|
423
518
|
};
|
|
424
519
|
}, [showControlsWithTimer]);
|
|
425
|
-
(0,
|
|
520
|
+
(0, import_react3.useEffect)(() => {
|
|
426
521
|
const init = () => {
|
|
427
522
|
if (!isFullscreen) {
|
|
428
523
|
showControlsWithTimer();
|
|
@@ -444,7 +539,7 @@ var VideoPlayer = ({
|
|
|
444
539
|
};
|
|
445
540
|
}
|
|
446
541
|
}, []);
|
|
447
|
-
const getInitialTime = (0,
|
|
542
|
+
const getInitialTime = (0, import_react3.useCallback)(() => {
|
|
448
543
|
if (!autoSave || !storageKey) {
|
|
449
544
|
return Number.isFinite(initialTime) && initialTime >= 0 ? initialTime : void 0;
|
|
450
545
|
}
|
|
@@ -455,14 +550,14 @@ var VideoPlayer = ({
|
|
|
455
550
|
if (hasValidSaved) return saved;
|
|
456
551
|
return void 0;
|
|
457
552
|
}, [autoSave, storageKey, src, initialTime]);
|
|
458
|
-
(0,
|
|
553
|
+
(0, import_react3.useEffect)(() => {
|
|
459
554
|
const start = getInitialTime();
|
|
460
555
|
if (start !== void 0 && videoRef.current) {
|
|
461
556
|
videoRef.current.currentTime = start;
|
|
462
557
|
setCurrentTime(start);
|
|
463
558
|
}
|
|
464
559
|
}, [getInitialTime]);
|
|
465
|
-
const saveProgress = (0,
|
|
560
|
+
const saveProgress = (0, import_react3.useCallback)(
|
|
466
561
|
(time) => {
|
|
467
562
|
if (!autoSave || !storageKey) return;
|
|
468
563
|
const now = Date.now();
|
|
@@ -473,7 +568,7 @@ var VideoPlayer = ({
|
|
|
473
568
|
},
|
|
474
569
|
[autoSave, storageKey, src]
|
|
475
570
|
);
|
|
476
|
-
const togglePlayPause = (0,
|
|
571
|
+
const togglePlayPause = (0, import_react3.useCallback)(async () => {
|
|
477
572
|
const video = videoRef.current;
|
|
478
573
|
if (!video) return;
|
|
479
574
|
if (!video.paused) {
|
|
@@ -485,7 +580,7 @@ var VideoPlayer = ({
|
|
|
485
580
|
} catch {
|
|
486
581
|
}
|
|
487
582
|
}, []);
|
|
488
|
-
const handleVolumeChange = (0,
|
|
583
|
+
const handleVolumeChange = (0, import_react3.useCallback)(
|
|
489
584
|
(newVolume) => {
|
|
490
585
|
const video = videoRef.current;
|
|
491
586
|
if (!video) return;
|
|
@@ -504,7 +599,7 @@ var VideoPlayer = ({
|
|
|
504
599
|
},
|
|
505
600
|
[isMuted]
|
|
506
601
|
);
|
|
507
|
-
const toggleMute = (0,
|
|
602
|
+
const toggleMute = (0, import_react3.useCallback)(() => {
|
|
508
603
|
const video = videoRef.current;
|
|
509
604
|
if (!video) return;
|
|
510
605
|
if (isMuted) {
|
|
@@ -518,13 +613,13 @@ var VideoPlayer = ({
|
|
|
518
613
|
setIsMuted(true);
|
|
519
614
|
}
|
|
520
615
|
}, [isMuted, volume]);
|
|
521
|
-
const handleSeek = (0,
|
|
616
|
+
const handleSeek = (0, import_react3.useCallback)((newTime) => {
|
|
522
617
|
const video = videoRef.current;
|
|
523
618
|
if (video) {
|
|
524
619
|
video.currentTime = newTime;
|
|
525
620
|
}
|
|
526
621
|
}, []);
|
|
527
|
-
const toggleFullscreen = (0,
|
|
622
|
+
const toggleFullscreen = (0, import_react3.useCallback)(() => {
|
|
528
623
|
const container = videoRef.current?.parentElement;
|
|
529
624
|
if (!container) return;
|
|
530
625
|
if (!isFullscreen && container.requestFullscreen) {
|
|
@@ -533,23 +628,23 @@ var VideoPlayer = ({
|
|
|
533
628
|
document.exitFullscreen();
|
|
534
629
|
}
|
|
535
630
|
}, [isFullscreen]);
|
|
536
|
-
const handleSpeedChange = (0,
|
|
631
|
+
const handleSpeedChange = (0, import_react3.useCallback)((speed) => {
|
|
537
632
|
if (videoRef.current) {
|
|
538
633
|
videoRef.current.playbackRate = speed;
|
|
539
634
|
setPlaybackRate(speed);
|
|
540
635
|
setShowSpeedMenu(false);
|
|
541
636
|
}
|
|
542
637
|
}, []);
|
|
543
|
-
const toggleSpeedMenu = (0,
|
|
638
|
+
const toggleSpeedMenu = (0, import_react3.useCallback)(() => {
|
|
544
639
|
setShowSpeedMenu(!showSpeedMenu);
|
|
545
640
|
}, [showSpeedMenu]);
|
|
546
|
-
const toggleCaptions = (0,
|
|
641
|
+
const toggleCaptions = (0, import_react3.useCallback)(() => {
|
|
547
642
|
if (!trackRef.current?.track || !subtitles) return;
|
|
548
643
|
const newShowCaptions = !showCaptions;
|
|
549
644
|
setShowCaptions(newShowCaptions);
|
|
550
645
|
trackRef.current.track.mode = newShowCaptions && subtitles ? "showing" : "hidden";
|
|
551
646
|
}, [showCaptions, subtitles]);
|
|
552
|
-
const checkVideoCompletion = (0,
|
|
647
|
+
const checkVideoCompletion = (0, import_react3.useCallback)(
|
|
553
648
|
(progressPercent) => {
|
|
554
649
|
if (progressPercent >= 95 && !hasCompleted) {
|
|
555
650
|
setHasCompleted(true);
|
|
@@ -558,7 +653,7 @@ var VideoPlayer = ({
|
|
|
558
653
|
},
|
|
559
654
|
[hasCompleted, onVideoComplete]
|
|
560
655
|
);
|
|
561
|
-
const handleTimeUpdate = (0,
|
|
656
|
+
const handleTimeUpdate = (0, import_react3.useCallback)(() => {
|
|
562
657
|
const video = videoRef.current;
|
|
563
658
|
if (!video) return;
|
|
564
659
|
const current = video.currentTime;
|
|
@@ -571,17 +666,17 @@ var VideoPlayer = ({
|
|
|
571
666
|
checkVideoCompletion(progressPercent);
|
|
572
667
|
}
|
|
573
668
|
}, [duration, saveProgress, onTimeUpdate, onProgress, checkVideoCompletion]);
|
|
574
|
-
const handleLoadedMetadata = (0,
|
|
669
|
+
const handleLoadedMetadata = (0, import_react3.useCallback)(() => {
|
|
575
670
|
if (videoRef.current) {
|
|
576
671
|
setDuration(videoRef.current.duration);
|
|
577
672
|
}
|
|
578
673
|
}, []);
|
|
579
|
-
(0,
|
|
674
|
+
(0, import_react3.useEffect)(() => {
|
|
580
675
|
if (trackRef.current?.track) {
|
|
581
676
|
trackRef.current.track.mode = showCaptions && subtitles ? "showing" : "hidden";
|
|
582
677
|
}
|
|
583
678
|
}, [subtitles, showCaptions]);
|
|
584
|
-
(0,
|
|
679
|
+
(0, import_react3.useEffect)(() => {
|
|
585
680
|
const handleVisibilityChange = () => {
|
|
586
681
|
if (document.hidden && isPlaying && videoRef.current) {
|
|
587
682
|
videoRef.current.pause();
|
|
@@ -603,13 +698,38 @@ var VideoPlayer = ({
|
|
|
603
698
|
};
|
|
604
699
|
}, [isPlaying, clearControlsTimeout]);
|
|
605
700
|
const progressPercentage = duration > 0 ? currentTime / duration * 100 : 0;
|
|
606
|
-
const
|
|
701
|
+
const getIconSize = (0, import_react3.useCallback)(() => {
|
|
702
|
+
if (isTinyMobile) return 18;
|
|
703
|
+
if (isUltraSmallMobile) return 20;
|
|
704
|
+
return 24;
|
|
705
|
+
}, [isTinyMobile, isUltraSmallMobile]);
|
|
706
|
+
const getControlsPadding = (0, import_react3.useCallback)(() => {
|
|
707
|
+
if (isTinyMobile) return "px-2 pb-2 pt-1";
|
|
708
|
+
if (isUltraSmallMobile) return "px-3 pb-3 pt-1";
|
|
709
|
+
return "px-4 pb-4";
|
|
710
|
+
}, [isTinyMobile, isUltraSmallMobile]);
|
|
711
|
+
const getControlsGap = (0, import_react3.useCallback)(() => {
|
|
712
|
+
if (isTinyMobile) return "gap-1";
|
|
713
|
+
if (isUltraSmallMobile) return "gap-2";
|
|
714
|
+
return "gap-4";
|
|
715
|
+
}, [isTinyMobile, isUltraSmallMobile]);
|
|
716
|
+
const getProgressBarPadding = (0, import_react3.useCallback)(() => {
|
|
717
|
+
if (isTinyMobile) return "px-2 pb-1";
|
|
718
|
+
if (isUltraSmallMobile) return "px-3 pb-1";
|
|
719
|
+
return "px-4 pb-2";
|
|
720
|
+
}, [isTinyMobile, isUltraSmallMobile]);
|
|
721
|
+
const getCenterPlayButtonPosition = (0, import_react3.useCallback)(() => {
|
|
722
|
+
if (isTinyMobile) return "items-center justify-center -translate-y-12";
|
|
723
|
+
if (isUltraSmallMobile) return "items-center justify-center -translate-y-8";
|
|
724
|
+
return "items-center justify-center";
|
|
725
|
+
}, [isTinyMobile, isUltraSmallMobile]);
|
|
726
|
+
const getTopControlsOpacity = (0, import_react3.useCallback)(() => {
|
|
607
727
|
return showControls ? "opacity-100" : "opacity-0";
|
|
608
728
|
}, [showControls]);
|
|
609
|
-
const getBottomControlsOpacity = (0,
|
|
729
|
+
const getBottomControlsOpacity = (0, import_react3.useCallback)(() => {
|
|
610
730
|
return showControls ? "opacity-100" : "opacity-0";
|
|
611
731
|
}, [showControls]);
|
|
612
|
-
const handleVideoKeyDown = (0,
|
|
732
|
+
const handleVideoKeyDown = (0, import_react3.useCallback)(
|
|
613
733
|
(e) => {
|
|
614
734
|
if (e.key) {
|
|
615
735
|
e.stopPropagation();
|
|
@@ -710,8 +830,9 @@ var VideoPlayer = ({
|
|
|
710
830
|
ref: videoRef,
|
|
711
831
|
src,
|
|
712
832
|
poster,
|
|
713
|
-
className: "w-full h-full object-contain",
|
|
833
|
+
className: "w-full h-full object-contain analytica-video",
|
|
714
834
|
controlsList: "nodownload",
|
|
835
|
+
playsInline: true,
|
|
715
836
|
onTimeUpdate: handleTimeUpdate,
|
|
716
837
|
onLoadedMetadata: handleLoadedMetadata,
|
|
717
838
|
onClick: togglePlayPause,
|
|
@@ -731,15 +852,24 @@ var VideoPlayer = ({
|
|
|
731
852
|
)
|
|
732
853
|
}
|
|
733
854
|
),
|
|
734
|
-
!isPlaying && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
735
|
-
|
|
855
|
+
!isPlaying && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
856
|
+
"div",
|
|
736
857
|
{
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
858
|
+
className: cn(
|
|
859
|
+
"absolute inset-0 flex bg-black/30 transition-opacity",
|
|
860
|
+
getCenterPlayButtonPosition()
|
|
861
|
+
),
|
|
862
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
863
|
+
IconButton_default,
|
|
864
|
+
{
|
|
865
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_phosphor_react.Play, { size: 32, weight: "regular", className: "ml-1" }),
|
|
866
|
+
onClick: togglePlayPause,
|
|
867
|
+
"aria-label": "Play video",
|
|
868
|
+
className: "!bg-transparent !text-white !w-auto !h-auto hover:!bg-transparent hover:!text-gray-200"
|
|
869
|
+
}
|
|
870
|
+
)
|
|
741
871
|
}
|
|
742
|
-
)
|
|
872
|
+
),
|
|
743
873
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
744
874
|
"div",
|
|
745
875
|
{
|
|
@@ -772,58 +902,72 @@ var VideoPlayer = ({
|
|
|
772
902
|
currentTime,
|
|
773
903
|
duration,
|
|
774
904
|
progressPercentage,
|
|
775
|
-
onSeek: handleSeek
|
|
905
|
+
onSeek: handleSeek,
|
|
906
|
+
className: getProgressBarPadding()
|
|
776
907
|
}
|
|
777
908
|
),
|
|
778
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
onClick: togglePlayPause,
|
|
785
|
-
"aria-label": isPlaying ? "Pause" : "Play",
|
|
786
|
-
className: "!bg-transparent !text-white hover:!bg-white/20"
|
|
787
|
-
}
|
|
788
|
-
),
|
|
789
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
790
|
-
VolumeControls,
|
|
791
|
-
{
|
|
792
|
-
volume,
|
|
793
|
-
isMuted,
|
|
794
|
-
onVolumeChange: handleVolumeChange,
|
|
795
|
-
onToggleMute: toggleMute
|
|
796
|
-
}
|
|
797
|
-
),
|
|
798
|
-
subtitles && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
799
|
-
IconButton_default,
|
|
800
|
-
{
|
|
801
|
-
icon: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_phosphor_react.ClosedCaptioning, { size: 24 }),
|
|
802
|
-
onClick: toggleCaptions,
|
|
803
|
-
"aria-label": showCaptions ? "Hide captions" : "Show captions",
|
|
804
|
-
className: cn(
|
|
805
|
-
"!bg-transparent hover:!bg-white/20",
|
|
806
|
-
showCaptions ? "!text-primary-400" : "!text-white"
|
|
807
|
-
)
|
|
808
|
-
}
|
|
909
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
910
|
+
"div",
|
|
911
|
+
{
|
|
912
|
+
className: cn(
|
|
913
|
+
"flex items-center justify-between",
|
|
914
|
+
getControlsPadding()
|
|
809
915
|
),
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
916
|
+
children: [
|
|
917
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: cn("flex items-center", getControlsGap()), children: [
|
|
918
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
919
|
+
IconButton_default,
|
|
920
|
+
{
|
|
921
|
+
icon: isPlaying ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_phosphor_react.Pause, { size: getIconSize() }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_phosphor_react.Play, { size: getIconSize() }),
|
|
922
|
+
onClick: togglePlayPause,
|
|
923
|
+
"aria-label": isPlaying ? "Pause" : "Play",
|
|
924
|
+
className: "!bg-transparent !text-white hover:!bg-white/20"
|
|
925
|
+
}
|
|
926
|
+
),
|
|
927
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
928
|
+
VolumeControls,
|
|
929
|
+
{
|
|
930
|
+
volume,
|
|
931
|
+
isMuted,
|
|
932
|
+
onVolumeChange: handleVolumeChange,
|
|
933
|
+
onToggleMute: toggleMute,
|
|
934
|
+
iconSize: getIconSize(),
|
|
935
|
+
showSlider: !isUltraSmallMobile
|
|
936
|
+
}
|
|
937
|
+
),
|
|
938
|
+
subtitles && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
939
|
+
IconButton_default,
|
|
940
|
+
{
|
|
941
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_phosphor_react.ClosedCaptioning, { size: getIconSize() }),
|
|
942
|
+
onClick: toggleCaptions,
|
|
943
|
+
"aria-label": showCaptions ? "Hide captions" : "Show captions",
|
|
944
|
+
className: cn(
|
|
945
|
+
"!bg-transparent hover:!bg-white/20",
|
|
946
|
+
showCaptions ? "!text-primary-400" : "!text-white"
|
|
947
|
+
)
|
|
948
|
+
}
|
|
949
|
+
),
|
|
950
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Text_default, { size: "sm", weight: "medium", color: "text-white", children: [
|
|
951
|
+
formatTime(currentTime),
|
|
952
|
+
" / ",
|
|
953
|
+
formatTime(duration)
|
|
954
|
+
] })
|
|
955
|
+
] }),
|
|
956
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "flex items-center gap-4", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
957
|
+
SpeedMenu,
|
|
958
|
+
{
|
|
959
|
+
showSpeedMenu,
|
|
960
|
+
playbackRate,
|
|
961
|
+
onToggleMenu: toggleSpeedMenu,
|
|
962
|
+
onSpeedChange: handleSpeedChange,
|
|
963
|
+
iconSize: getIconSize(),
|
|
964
|
+
isTinyMobile,
|
|
965
|
+
isFullscreen
|
|
966
|
+
}
|
|
967
|
+
) })
|
|
968
|
+
]
|
|
969
|
+
}
|
|
970
|
+
)
|
|
827
971
|
]
|
|
828
972
|
}
|
|
829
973
|
)
|