@mottosports/motto-video-player 1.0.0 → 1.0.1-rc.1
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 +64 -0
- package/dist/index.js +38 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +38 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -20,6 +20,70 @@ React video player component for the Motto platform, powered by Shaka Player wit
|
|
|
20
20
|
npm install @motto-ui-components/motto-video-player @tanstack/react-query
|
|
21
21
|
```
|
|
22
22
|
|
|
23
|
+
## Next.js SSR Compatibility
|
|
24
|
+
|
|
25
|
+
This component is now fully compatible with Next.js Server-Side Rendering (SSR). The component automatically detects when it's running in a server environment and gracefully handles browser-only APIs.
|
|
26
|
+
|
|
27
|
+
### Basic Usage in Next.js
|
|
28
|
+
|
|
29
|
+
```tsx
|
|
30
|
+
import { Event } from '@mottosports/motto-video-player';
|
|
31
|
+
|
|
32
|
+
export default function MyPage() {
|
|
33
|
+
return (
|
|
34
|
+
<Event
|
|
35
|
+
publicKey="your-public-key"
|
|
36
|
+
eventId="your-event-id"
|
|
37
|
+
locale="en"
|
|
38
|
+
/>
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Dynamic Imports (Optional)
|
|
44
|
+
|
|
45
|
+
For optimal performance and to ensure the component only loads on the client side, you can use Next.js dynamic imports:
|
|
46
|
+
|
|
47
|
+
```tsx
|
|
48
|
+
import dynamic from 'next/dynamic';
|
|
49
|
+
|
|
50
|
+
const Event = dynamic(
|
|
51
|
+
() => import('@mottosports/motto-video-player').then(mod => ({ default: mod.Event })),
|
|
52
|
+
{
|
|
53
|
+
ssr: false,
|
|
54
|
+
loading: () => <div>Loading video player...</div>
|
|
55
|
+
}
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
export default function MyPage() {
|
|
59
|
+
return (
|
|
60
|
+
<Event
|
|
61
|
+
publicKey="your-public-key"
|
|
62
|
+
eventId="your-event-id"
|
|
63
|
+
locale="en"
|
|
64
|
+
/>
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### App Router Usage (Next.js 13+)
|
|
70
|
+
|
|
71
|
+
```tsx
|
|
72
|
+
'use client';
|
|
73
|
+
|
|
74
|
+
import { Event } from '@mottosports/motto-video-player';
|
|
75
|
+
|
|
76
|
+
export default function VideoPlayer() {
|
|
77
|
+
return (
|
|
78
|
+
<Event
|
|
79
|
+
publicKey="your-public-key"
|
|
80
|
+
eventId="your-event-id"
|
|
81
|
+
locale="en"
|
|
82
|
+
/>
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
23
87
|
## Quick Start
|
|
24
88
|
|
|
25
89
|
### Setup QueryClient (Required for Video wrapper)
|
package/dist/index.js
CHANGED
|
@@ -309,6 +309,10 @@ var SkipBackButton = class {
|
|
|
309
309
|
this.eventManager = { listen: (element, event, handler) => {
|
|
310
310
|
element.addEventListener(event, handler);
|
|
311
311
|
} };
|
|
312
|
+
if (typeof document === "undefined") {
|
|
313
|
+
console.warn("SkipBackButton: document is not available (SSR environment)");
|
|
314
|
+
return;
|
|
315
|
+
}
|
|
312
316
|
this.button_ = document.createElement("button");
|
|
313
317
|
this.button_.className = "shaka-button motto-native-skip-button";
|
|
314
318
|
this.button_.innerHTML = `
|
|
@@ -339,6 +343,10 @@ var SkipForwardButton = class {
|
|
|
339
343
|
this.eventManager = { listen: (element, event, handler) => {
|
|
340
344
|
element.addEventListener(event, handler);
|
|
341
345
|
} };
|
|
346
|
+
if (typeof document === "undefined") {
|
|
347
|
+
console.warn("SkipForwardButton: document is not available (SSR environment)");
|
|
348
|
+
return;
|
|
349
|
+
}
|
|
342
350
|
this.button_ = document.createElement("button");
|
|
343
351
|
this.button_.className = "shaka-button motto-native-skip-button";
|
|
344
352
|
this.button_.innerHTML = `
|
|
@@ -382,6 +390,10 @@ var MobilePlayButton = class {
|
|
|
382
390
|
constructor(parent, controls) {
|
|
383
391
|
this.parent = parent;
|
|
384
392
|
this.controls = controls;
|
|
393
|
+
if (typeof document === "undefined") {
|
|
394
|
+
console.warn("MobilePlayButton: document is not available (SSR environment)");
|
|
395
|
+
return;
|
|
396
|
+
}
|
|
385
397
|
this.video = controls?.getVideo?.() || parent.querySelector("video") || document.querySelector("video");
|
|
386
398
|
if (!this.video) {
|
|
387
399
|
console.error("MobilePlayButton: No video element found");
|
|
@@ -426,6 +438,10 @@ var MobileSkipBackButton = class {
|
|
|
426
438
|
constructor(parent, controls, onSkipBack) {
|
|
427
439
|
this.parent = parent;
|
|
428
440
|
this.controls = controls;
|
|
441
|
+
if (typeof document === "undefined") {
|
|
442
|
+
console.warn("MobileSkipBackButton: document is not available (SSR environment)");
|
|
443
|
+
return;
|
|
444
|
+
}
|
|
429
445
|
this.video = controls?.getVideo?.() || parent.querySelector("video") || document.querySelector("video");
|
|
430
446
|
if (!this.video) {
|
|
431
447
|
console.error("MobileSkipBackButton: No video element found");
|
|
@@ -457,6 +473,10 @@ var MobileSkipForwardButton = class {
|
|
|
457
473
|
constructor(parent, controls, onSkipForward) {
|
|
458
474
|
this.parent = parent;
|
|
459
475
|
this.controls = controls;
|
|
476
|
+
if (typeof document === "undefined") {
|
|
477
|
+
console.warn("MobileSkipForwardButton: document is not available (SSR environment)");
|
|
478
|
+
return;
|
|
479
|
+
}
|
|
460
480
|
this.video = controls?.getVideo?.() || parent.querySelector("video") || document.querySelector("video");
|
|
461
481
|
if (!this.video) {
|
|
462
482
|
console.error("MobileSkipForwardButton: No video element found");
|
|
@@ -488,6 +508,10 @@ var MobileControlsContainer = class {
|
|
|
488
508
|
constructor(parent, controls, onSkipBack, onSkipForward) {
|
|
489
509
|
this.parent = parent;
|
|
490
510
|
this.controls = controls;
|
|
511
|
+
if (typeof document === "undefined") {
|
|
512
|
+
console.warn("MobileControlsContainer: document is not available (SSR environment)");
|
|
513
|
+
return;
|
|
514
|
+
}
|
|
491
515
|
if (!parent) {
|
|
492
516
|
console.error("MobileControlsContainer: No parent element provided");
|
|
493
517
|
return;
|
|
@@ -545,6 +569,9 @@ var MobileControlsContainer = class {
|
|
|
545
569
|
}
|
|
546
570
|
}
|
|
547
571
|
isElementVisible(element) {
|
|
572
|
+
if (typeof window === "undefined") {
|
|
573
|
+
return false;
|
|
574
|
+
}
|
|
548
575
|
const style = window.getComputedStyle(element);
|
|
549
576
|
const hasHiddenClass = element.classList.contains("shaka-hidden") || element.classList.contains("hidden") || element.classList.contains("shaka-fade-out");
|
|
550
577
|
return style.display !== "none" && style.visibility !== "hidden" && style.opacity !== "0" && !element.hidden && !hasHiddenClass;
|
|
@@ -563,10 +590,14 @@ var useShakaUI = (playerRef, containerRef, videoRef, controls, chromecastConfig,
|
|
|
563
590
|
const uiRef = (0, import_react5.useRef)(null);
|
|
564
591
|
const registeredElements = (0, import_react5.useRef)(/* @__PURE__ */ new Set());
|
|
565
592
|
const initializeUI = (0, import_react5.useCallback)(async () => {
|
|
593
|
+
if (typeof window === "undefined" || typeof document === "undefined") {
|
|
594
|
+
console.warn("useShakaUI: Cannot initialize UI in SSR environment");
|
|
595
|
+
return null;
|
|
596
|
+
}
|
|
566
597
|
if (!controls || !containerRef.current || !playerRef.current || !videoRef.current) {
|
|
567
598
|
return null;
|
|
568
599
|
}
|
|
569
|
-
const isMobile = window.innerWidth <= 767 || /Android|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
|
|
600
|
+
const isMobile = typeof window !== "undefined" && typeof navigator !== "undefined" && (window.innerWidth <= 767 || /Android|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent));
|
|
570
601
|
if (!registeredElements.current.has("skip_back_button")) {
|
|
571
602
|
import_shaka_player3.ui.Controls.registerElement("skip_back_button", new SkipBackButtonFactory(onSkipBack));
|
|
572
603
|
registeredElements.current.add("skip_back_button");
|
|
@@ -760,6 +791,9 @@ var useLiveIndicator = (containerRef, options = {}) => {
|
|
|
760
791
|
showPulseAnimation = true
|
|
761
792
|
} = options;
|
|
762
793
|
(0, import_react9.useEffect)(() => {
|
|
794
|
+
if (typeof window === "undefined" || typeof document === "undefined") {
|
|
795
|
+
return;
|
|
796
|
+
}
|
|
763
797
|
if (!containerRef.current || !enabled) {
|
|
764
798
|
return;
|
|
765
799
|
}
|
|
@@ -1822,6 +1856,9 @@ var availableLanguages = {
|
|
|
1822
1856
|
fa: fa_default
|
|
1823
1857
|
};
|
|
1824
1858
|
var getBrowserLanguage = () => {
|
|
1859
|
+
if (typeof window === "undefined" || typeof navigator === "undefined") {
|
|
1860
|
+
return "en";
|
|
1861
|
+
}
|
|
1825
1862
|
const language = navigator.language.split("-")[0];
|
|
1826
1863
|
return availableLanguages[language] ? language : "en";
|
|
1827
1864
|
};
|