@rxdrag/website-lib-core 0.0.109 → 0.0.111
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rxdrag/website-lib-core",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.111",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": "./index.ts"
|
|
@@ -34,8 +34,8 @@
|
|
|
34
34
|
"gsap": "^3.12.7",
|
|
35
35
|
"hls.js": "^1.6.13",
|
|
36
36
|
"lodash-es": "^4.17.21",
|
|
37
|
-
"@rxdrag/
|
|
38
|
-
"@rxdrag/
|
|
37
|
+
"@rxdrag/entify-lib": "0.0.23",
|
|
38
|
+
"@rxdrag/rxcms-models": "0.3.96"
|
|
39
39
|
},
|
|
40
40
|
"peerDependencies": {
|
|
41
41
|
"astro": "^4.0.0 || ^5.0.0",
|
|
@@ -19,6 +19,8 @@ export type VideoPlayerClassNames = {
|
|
|
19
19
|
playButtonOuter?: string;
|
|
20
20
|
playButtonInner?: string;
|
|
21
21
|
playIcon?: string;
|
|
22
|
+
loadingOverlay?: string;
|
|
23
|
+
loadingContent?: string;
|
|
22
24
|
overlay?: string;
|
|
23
25
|
overlayTitle?: string;
|
|
24
26
|
ctaButton?: string;
|
|
@@ -54,17 +56,22 @@ export const ReactVideoPlayer = forwardRef<
|
|
|
54
56
|
const [isPlaying, setIsPlaying] = useState(false);
|
|
55
57
|
const [isEnded, setIsEnded] = useState(false);
|
|
56
58
|
const [isSourceReady, setIsSourceReady] = useState(false);
|
|
59
|
+
const sourceReadyRef = useRef(false);
|
|
60
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
61
|
+
const isEndedRef = useRef(false);
|
|
62
|
+
const [hasStarted, setHasStarted] = useState(false);
|
|
57
63
|
|
|
58
64
|
const ensureSourceReady = useCallback(() => {
|
|
59
65
|
const video = videoRef.current;
|
|
60
66
|
const url = media.file?.original;
|
|
61
67
|
if (!video || !url) return false;
|
|
62
|
-
if (
|
|
68
|
+
if (sourceReadyRef.current) return true;
|
|
63
69
|
|
|
64
70
|
if (media.storageType === "cloudflare_stream") {
|
|
65
71
|
if (!Hls.isSupported()) {
|
|
66
72
|
if (video.canPlayType("application/vnd.apple.mpegurl")) {
|
|
67
73
|
video.src = url;
|
|
74
|
+
sourceReadyRef.current = true;
|
|
68
75
|
setIsSourceReady(true);
|
|
69
76
|
return true;
|
|
70
77
|
}
|
|
@@ -90,14 +97,16 @@ export const ReactVideoPlayer = forwardRef<
|
|
|
90
97
|
hls.loadSource(url);
|
|
91
98
|
hls.attachMedia(video);
|
|
92
99
|
hlsRef.current = hls;
|
|
100
|
+
sourceReadyRef.current = true;
|
|
93
101
|
setIsSourceReady(true);
|
|
94
102
|
return true;
|
|
95
103
|
}
|
|
96
104
|
|
|
97
105
|
video.src = url;
|
|
106
|
+
sourceReadyRef.current = true;
|
|
98
107
|
setIsSourceReady(true);
|
|
99
108
|
return true;
|
|
100
|
-
}, [
|
|
109
|
+
}, [media.file?.original, media.storageType]);
|
|
101
110
|
|
|
102
111
|
const handleContainerClick = useCallback(
|
|
103
112
|
(e: React.MouseEvent) => {
|
|
@@ -128,7 +137,12 @@ export const ReactVideoPlayer = forwardRef<
|
|
|
128
137
|
const ok = ensureSourceReady();
|
|
129
138
|
if (!ok) return;
|
|
130
139
|
|
|
131
|
-
|
|
140
|
+
setIsLoading(true);
|
|
141
|
+
|
|
142
|
+
v.play().catch((error) => {
|
|
143
|
+
console.log("ReactVideoPlayer play() failed:", error);
|
|
144
|
+
setIsLoading(false);
|
|
145
|
+
});
|
|
132
146
|
},
|
|
133
147
|
[isPlaying, designMode, ensureSourceReady]
|
|
134
148
|
);
|
|
@@ -137,6 +151,7 @@ export const ReactVideoPlayer = forwardRef<
|
|
|
137
151
|
const video = videoRef.current;
|
|
138
152
|
if (!video) return;
|
|
139
153
|
|
|
154
|
+
video.pause();
|
|
140
155
|
if (hlsRef.current) {
|
|
141
156
|
hlsRef.current.destroy();
|
|
142
157
|
hlsRef.current = null;
|
|
@@ -144,20 +159,35 @@ export const ReactVideoPlayer = forwardRef<
|
|
|
144
159
|
video.removeAttribute("src");
|
|
145
160
|
video.load();
|
|
146
161
|
setIsSourceReady(false);
|
|
162
|
+
sourceReadyRef.current = false;
|
|
147
163
|
|
|
148
164
|
const onPlay = () => {
|
|
149
165
|
setIsPlaying(true);
|
|
150
166
|
setIsEnded(false);
|
|
167
|
+
isEndedRef.current = false;
|
|
168
|
+
setIsLoading(false);
|
|
169
|
+
setHasStarted(true);
|
|
151
170
|
};
|
|
152
171
|
const onPause = () => setIsPlaying(false);
|
|
153
172
|
const onEnded = () => {
|
|
154
173
|
setIsPlaying(false);
|
|
155
174
|
setIsEnded(true);
|
|
175
|
+
isEndedRef.current = true;
|
|
176
|
+
setIsLoading(false);
|
|
177
|
+
};
|
|
178
|
+
const onWaiting = () => {
|
|
179
|
+
if (!isEndedRef.current) setIsLoading(true);
|
|
180
|
+
};
|
|
181
|
+
const onCanPlay = () => {
|
|
182
|
+
setIsLoading(false);
|
|
156
183
|
};
|
|
157
184
|
|
|
158
185
|
video.addEventListener("play", onPlay);
|
|
159
186
|
video.addEventListener("pause", onPause);
|
|
160
187
|
video.addEventListener("ended", onEnded);
|
|
188
|
+
video.addEventListener("waiting", onWaiting);
|
|
189
|
+
video.addEventListener("canplay", onCanPlay);
|
|
190
|
+
video.addEventListener("playing", onCanPlay);
|
|
161
191
|
|
|
162
192
|
if (eagerLoad) {
|
|
163
193
|
ensureSourceReady();
|
|
@@ -167,6 +197,9 @@ export const ReactVideoPlayer = forwardRef<
|
|
|
167
197
|
video.removeEventListener("play", onPlay);
|
|
168
198
|
video.removeEventListener("pause", onPause);
|
|
169
199
|
video.removeEventListener("ended", onEnded);
|
|
200
|
+
video.removeEventListener("waiting", onWaiting);
|
|
201
|
+
video.removeEventListener("canplay", onCanPlay);
|
|
202
|
+
video.removeEventListener("playing", onCanPlay);
|
|
170
203
|
|
|
171
204
|
if (hlsRef.current) {
|
|
172
205
|
hlsRef.current.destroy();
|
|
@@ -194,7 +227,8 @@ export const ReactVideoPlayer = forwardRef<
|
|
|
194
227
|
"w-full h-full rounded-lg object-cover",
|
|
195
228
|
classNames?.video
|
|
196
229
|
)}
|
|
197
|
-
|
|
230
|
+
playsInline
|
|
231
|
+
controls={!designMode && hasStarted}
|
|
198
232
|
>
|
|
199
233
|
{!media.storageType && media.file?.original && (eagerLoad || isSourceReady) ? (
|
|
200
234
|
<source src={media.file.original} />
|
|
@@ -202,7 +236,7 @@ export const ReactVideoPlayer = forwardRef<
|
|
|
202
236
|
Your browser does not support video playback.
|
|
203
237
|
</video>
|
|
204
238
|
|
|
205
|
-
{!isPlaying && !isEnded && (
|
|
239
|
+
{!isPlaying && !isEnded && !isLoading && (
|
|
206
240
|
<button
|
|
207
241
|
type="button"
|
|
208
242
|
onClick={handlePlayClick}
|
|
@@ -243,6 +277,26 @@ export const ReactVideoPlayer = forwardRef<
|
|
|
243
277
|
</button>
|
|
244
278
|
)}
|
|
245
279
|
|
|
280
|
+
{!isPlaying && !isEnded && isLoading && (
|
|
281
|
+
<div
|
|
282
|
+
className={clsx(
|
|
283
|
+
"absolute inset-0 flex items-center justify-center w-full h-full rounded-lg z-10 bg-black/20",
|
|
284
|
+
classNames?.loadingOverlay
|
|
285
|
+
)}
|
|
286
|
+
onClick={(e) => e.stopPropagation()}
|
|
287
|
+
>
|
|
288
|
+
<div
|
|
289
|
+
className={clsx(
|
|
290
|
+
"flex items-center gap-3 rounded-full bg-black/50 px-4 py-2 text-white",
|
|
291
|
+
classNames?.loadingContent
|
|
292
|
+
)}
|
|
293
|
+
>
|
|
294
|
+
<div className="h-4 w-4 animate-spin rounded-full border-2 border-white/30 border-t-white" />
|
|
295
|
+
<span className="text-sm">Loading...</span>
|
|
296
|
+
</div>
|
|
297
|
+
</div>
|
|
298
|
+
)}
|
|
299
|
+
|
|
246
300
|
<div
|
|
247
301
|
className={clsx(
|
|
248
302
|
"absolute inset-0 bg-black/50 flex-col gap-6 items-center justify-center text-center text-white hidden z-10 rounded-2xl",
|
|
@@ -277,9 +331,13 @@ export const ReactVideoPlayer = forwardRef<
|
|
|
277
331
|
if (!v) return;
|
|
278
332
|
const ok = ensureSourceReady();
|
|
279
333
|
if (!ok) return;
|
|
334
|
+
setIsLoading(true);
|
|
280
335
|
v.currentTime = 0;
|
|
281
336
|
setIsEnded(false);
|
|
282
|
-
v.play()
|
|
337
|
+
v.play().catch((error) => {
|
|
338
|
+
console.log("ReactVideoPlayer play() failed:", error);
|
|
339
|
+
setIsLoading(false);
|
|
340
|
+
});
|
|
283
341
|
}}
|
|
284
342
|
>
|
|
285
343
|
Replay
|