@folklore/hooks 0.0.31 → 0.0.33
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/cjs.js +388 -527
- package/dist/es.js +389 -528
- package/package.json +4 -3
package/dist/es.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import raf from 'raf';
|
|
2
2
|
import { useState, useEffect, useRef, useMemo, useCallback } from 'react';
|
|
3
|
-
import { loadDailymotion,
|
|
3
|
+
import { loadDailymotion, loadVimeo, loadYouTube } from '@folklore/services';
|
|
4
4
|
import createDebug from 'debug';
|
|
5
5
|
import EventsManager from '@folklore/events';
|
|
6
6
|
import { cancelable } from 'cancelable-promise';
|
|
@@ -19,32 +19,26 @@ function useCounter(desiredValue, _ref) {
|
|
|
19
19
|
let canceled = false;
|
|
20
20
|
const startValue = currentValue;
|
|
21
21
|
const delta = desiredValue - startValue;
|
|
22
|
-
|
|
23
22
|
function loop() {
|
|
24
23
|
if (canceled) {
|
|
25
24
|
return;
|
|
26
25
|
}
|
|
27
|
-
|
|
28
26
|
const currentTime = Date.now();
|
|
29
27
|
const elapsedTime = currentTime - startTime;
|
|
30
28
|
const progress = Math.min(elapsedTime / duration, 1);
|
|
31
29
|
const newValue = Math.round(startValue + progress * delta);
|
|
32
30
|
setCurrentValue(newValue);
|
|
33
|
-
|
|
34
31
|
if (newValue !== desiredValue) {
|
|
35
32
|
animationFrame = raf(loop);
|
|
36
33
|
}
|
|
37
34
|
}
|
|
38
|
-
|
|
39
35
|
if (delta !== 0) {
|
|
40
36
|
duration = Math.min(maxDuration, Math.abs(delta) * speed * 1000);
|
|
41
37
|
startTime = Date.now();
|
|
42
38
|
animationFrame = raf(loop);
|
|
43
39
|
}
|
|
44
|
-
|
|
45
40
|
return () => {
|
|
46
41
|
canceled = true;
|
|
47
|
-
|
|
48
42
|
if (animationFrame !== null) {
|
|
49
43
|
raf.cancel(animationFrame);
|
|
50
44
|
}
|
|
@@ -65,36 +59,29 @@ function usePlayerCurrentTime(player) {
|
|
|
65
59
|
const realCurrentTime = useRef(currentTime);
|
|
66
60
|
const lastIdRef = useRef(id);
|
|
67
61
|
const idChanged = lastIdRef.current !== id;
|
|
68
|
-
|
|
69
62
|
if (idChanged) {
|
|
70
63
|
realCurrentTime.current = 0;
|
|
71
64
|
lastIdRef.current = id;
|
|
72
|
-
}
|
|
73
|
-
|
|
65
|
+
}
|
|
74
66
|
|
|
67
|
+
// Check time update
|
|
75
68
|
useEffect(() => {
|
|
76
69
|
if (disabled || player === null) {
|
|
77
70
|
return () => {};
|
|
78
71
|
}
|
|
79
|
-
|
|
80
72
|
let canceled = false;
|
|
81
|
-
|
|
82
73
|
const updateTime = time => {
|
|
83
74
|
if (canceled) {
|
|
84
75
|
return;
|
|
85
76
|
}
|
|
86
|
-
|
|
87
77
|
realCurrentTime.current = time;
|
|
88
78
|
setCurrentTime(time);
|
|
89
|
-
|
|
90
79
|
if (customOnUpdate !== null) {
|
|
91
80
|
customOnUpdate(time);
|
|
92
81
|
}
|
|
93
82
|
};
|
|
94
|
-
|
|
95
83
|
const interval = setInterval(() => {
|
|
96
84
|
const time = getCurrentTime(player);
|
|
97
|
-
|
|
98
85
|
if (typeof time.then !== 'undefined') {
|
|
99
86
|
time.then(updateTime);
|
|
100
87
|
} else {
|
|
@@ -109,10 +96,8 @@ function usePlayerCurrentTime(player) {
|
|
|
109
96
|
return realCurrentTime.current;
|
|
110
97
|
}
|
|
111
98
|
|
|
112
|
-
const
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
const useDailymotionPlayer = function () {
|
|
99
|
+
const NO_PLAYER_ERROR$3 = new Error('No player');
|
|
100
|
+
function useDailymotionPlayer() {
|
|
116
101
|
let id = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
|
|
117
102
|
let params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
118
103
|
const {
|
|
@@ -134,15 +119,15 @@ const useDailymotionPlayer = function () {
|
|
|
134
119
|
if (url === null || url.match(/^https?:/) === null) {
|
|
135
120
|
return url;
|
|
136
121
|
}
|
|
137
|
-
|
|
138
122
|
const match = url.match(/\/video\/([^/?]+)/);
|
|
139
123
|
return match !== null ? match[1] : null;
|
|
140
124
|
}
|
|
141
125
|
} = params;
|
|
142
|
-
const
|
|
126
|
+
const debug = useMemo(() => createDebug('folklore:video:dailymotion'), []);
|
|
127
|
+
const [apiLoaded, setApiLoaded] = useState(typeof window !== 'undefined' && typeof window.DM !== 'undefined');
|
|
143
128
|
const [playerReady, setPlayerReady] = useState(false);
|
|
144
129
|
const [loaded, setLoaded] = useState(false);
|
|
145
|
-
const apiRef = useRef(typeof window.DM !== 'undefined' ? window.DM : null);
|
|
130
|
+
const apiRef = useRef(typeof window !== 'undefined' && typeof window.DM !== 'undefined' ? window.DM : null);
|
|
146
131
|
const ready = apiLoaded && playerReady;
|
|
147
132
|
const videoId = useMemo(() => getVideoId(id), [id]);
|
|
148
133
|
const elementRef = useRef(null);
|
|
@@ -162,27 +147,27 @@ const useDailymotionPlayer = function () {
|
|
|
162
147
|
width,
|
|
163
148
|
height,
|
|
164
149
|
duration
|
|
165
|
-
});
|
|
150
|
+
});
|
|
166
151
|
|
|
152
|
+
// Load SDK
|
|
167
153
|
useEffect(() => {
|
|
168
154
|
let canceled = false;
|
|
169
|
-
|
|
170
155
|
if (!apiLoaded && videoId !== null) {
|
|
171
|
-
debug
|
|
156
|
+
debug('Load API');
|
|
172
157
|
loadDailymotion().then(api => {
|
|
173
158
|
if (!canceled) {
|
|
174
159
|
apiRef.current = api;
|
|
175
160
|
setApiLoaded(true);
|
|
176
|
-
debug
|
|
161
|
+
debug('API Loaded');
|
|
177
162
|
}
|
|
178
163
|
});
|
|
179
164
|
}
|
|
180
|
-
|
|
181
165
|
return () => {
|
|
182
166
|
canceled = true;
|
|
183
167
|
};
|
|
184
|
-
}, [videoId, apiLoaded, setApiLoaded]);
|
|
168
|
+
}, [videoId, apiLoaded, setApiLoaded]);
|
|
185
169
|
|
|
170
|
+
// Create or update player
|
|
186
171
|
useEffect(() => {
|
|
187
172
|
const {
|
|
188
173
|
current: DM = null
|
|
@@ -193,11 +178,9 @@ const useDailymotionPlayer = function () {
|
|
|
193
178
|
const {
|
|
194
179
|
current: element = null
|
|
195
180
|
} = elementRef;
|
|
196
|
-
|
|
197
181
|
if (!apiLoaded || videoId === null || element === null) {
|
|
198
182
|
return;
|
|
199
183
|
}
|
|
200
|
-
|
|
201
184
|
const playerParams = {
|
|
202
185
|
'autoplay-d': autoplay,
|
|
203
186
|
// muted,
|
|
@@ -210,12 +193,11 @@ const useDailymotionPlayer = function () {
|
|
|
210
193
|
'ui-start-screen-info': uiStartScreenInfo
|
|
211
194
|
};
|
|
212
195
|
let player = currentPlayer;
|
|
213
|
-
|
|
214
196
|
if (player !== null) {
|
|
215
197
|
player.load(videoId, {
|
|
216
198
|
params: playerParams
|
|
217
199
|
});
|
|
218
|
-
debug
|
|
200
|
+
debug('Load video [ID: %s]', videoId);
|
|
219
201
|
} else {
|
|
220
202
|
player = DM.player(element, {
|
|
221
203
|
video: videoId,
|
|
@@ -223,13 +205,11 @@ const useDailymotionPlayer = function () {
|
|
|
223
205
|
height,
|
|
224
206
|
params: playerParams
|
|
225
207
|
});
|
|
226
|
-
debug
|
|
208
|
+
debug('Create player [ID: %s]', videoId);
|
|
227
209
|
}
|
|
228
|
-
|
|
229
210
|
if (!playerReady) {
|
|
230
211
|
setPlayerReady(true);
|
|
231
212
|
}
|
|
232
|
-
|
|
233
213
|
playerRef.current = player;
|
|
234
214
|
playerElementRef.current = element;
|
|
235
215
|
}, [apiLoaded, elementHasChanged, videoId, width, height, autoplay, muted, start, controls, queueAutoplayNext, queueEnable, sharingEnable, uiLogo, uiStartScreenInfo]);
|
|
@@ -237,103 +217,98 @@ const useDailymotionPlayer = function () {
|
|
|
237
217
|
const {
|
|
238
218
|
current: player = null
|
|
239
219
|
} = playerRef;
|
|
240
|
-
|
|
241
220
|
if (player === null) {
|
|
242
221
|
return () => {};
|
|
243
222
|
}
|
|
244
|
-
|
|
245
223
|
let currentPlayState = playState;
|
|
246
224
|
let currentMetadata = metadata;
|
|
247
|
-
|
|
248
225
|
function onPlaybackReady() {
|
|
249
226
|
setLoaded(true);
|
|
250
|
-
debug
|
|
227
|
+
debug('onPlaybackReady [ID: %s]', videoId);
|
|
251
228
|
}
|
|
252
|
-
|
|
253
229
|
function onLoadedMetadata() {
|
|
254
|
-
currentMetadata = {
|
|
230
|
+
currentMetadata = {
|
|
231
|
+
...currentMetadata,
|
|
255
232
|
duration: player.duration
|
|
256
233
|
};
|
|
257
234
|
setMetadata(currentMetadata);
|
|
258
|
-
debug
|
|
235
|
+
debug('onLoadedMetadata [ID: %s]', videoId);
|
|
259
236
|
}
|
|
260
|
-
|
|
261
237
|
function onDurationChange() {
|
|
262
|
-
currentMetadata = {
|
|
238
|
+
currentMetadata = {
|
|
239
|
+
...currentMetadata,
|
|
263
240
|
duration: player.duration
|
|
264
241
|
};
|
|
265
242
|
setMetadata(currentMetadata);
|
|
266
|
-
debug
|
|
243
|
+
debug('onDurationChange [ID: %s]', videoId);
|
|
267
244
|
}
|
|
268
|
-
|
|
269
245
|
function onVolumeChange() {
|
|
270
246
|
setMuted(player.muted);
|
|
271
247
|
setVolumeState(player.volume);
|
|
272
|
-
debug
|
|
248
|
+
debug('onVolumeChange [ID: %s]', videoId);
|
|
273
249
|
}
|
|
274
|
-
|
|
275
250
|
function onPlay() {
|
|
276
|
-
currentPlayState = {
|
|
251
|
+
currentPlayState = {
|
|
252
|
+
...currentPlayState,
|
|
277
253
|
playing: true,
|
|
278
254
|
paused: false,
|
|
279
255
|
ended: false
|
|
280
256
|
};
|
|
281
257
|
setPlayState(currentPlayState);
|
|
282
|
-
debug
|
|
258
|
+
debug('onPlay [ID: %s]', videoId);
|
|
283
259
|
}
|
|
284
|
-
|
|
285
260
|
function onPause() {
|
|
286
|
-
currentPlayState = {
|
|
261
|
+
currentPlayState = {
|
|
262
|
+
...currentPlayState,
|
|
287
263
|
playing: false,
|
|
288
264
|
paused: true,
|
|
289
265
|
ended: false
|
|
290
266
|
};
|
|
291
267
|
setPlayState(currentPlayState);
|
|
292
|
-
debug
|
|
268
|
+
debug('onPause [ID: %s]', videoId);
|
|
293
269
|
}
|
|
294
|
-
|
|
295
270
|
function onEnd() {
|
|
296
|
-
currentPlayState = {
|
|
271
|
+
currentPlayState = {
|
|
272
|
+
...currentPlayState,
|
|
297
273
|
playing: false,
|
|
298
274
|
paused: false,
|
|
299
275
|
ended: true
|
|
300
276
|
};
|
|
301
277
|
setPlayState(currentPlayState);
|
|
302
|
-
debug
|
|
278
|
+
debug('onEnd [ID: %s]', videoId);
|
|
303
279
|
}
|
|
304
|
-
|
|
305
280
|
function onPlaying() {
|
|
306
|
-
currentPlayState = {
|
|
281
|
+
currentPlayState = {
|
|
282
|
+
...currentPlayState,
|
|
307
283
|
buffering: false
|
|
308
284
|
};
|
|
309
285
|
setPlayState(currentPlayState);
|
|
310
|
-
debug
|
|
286
|
+
debug('onPlaying [ID: %s]', videoId);
|
|
311
287
|
}
|
|
312
|
-
|
|
313
288
|
function onWaiting() {
|
|
314
|
-
currentPlayState = {
|
|
289
|
+
currentPlayState = {
|
|
290
|
+
...currentPlayState,
|
|
315
291
|
buffering: true
|
|
316
292
|
};
|
|
317
293
|
setPlayState(currentPlayState);
|
|
318
|
-
debug
|
|
294
|
+
debug('onWaiting [ID: %s]', videoId);
|
|
319
295
|
}
|
|
320
|
-
|
|
321
296
|
function onAdStart() {
|
|
322
|
-
currentPlayState = {
|
|
297
|
+
currentPlayState = {
|
|
298
|
+
...currentPlayState,
|
|
323
299
|
adPlaying: true
|
|
324
300
|
};
|
|
325
301
|
setPlayState(currentPlayState);
|
|
326
|
-
debug
|
|
302
|
+
debug('onAdStart [ID: %s]', videoId);
|
|
327
303
|
}
|
|
328
|
-
|
|
329
304
|
function onAdEnd() {
|
|
330
|
-
currentPlayState = {
|
|
305
|
+
currentPlayState = {
|
|
306
|
+
...currentPlayState,
|
|
331
307
|
adPlaying: false
|
|
332
308
|
};
|
|
333
309
|
setPlayState(currentPlayState);
|
|
334
|
-
debug
|
|
310
|
+
debug('onAdEnd [ID: %s]', videoId);
|
|
335
311
|
}
|
|
336
|
-
|
|
337
312
|
player.addEventListener('playback_ready', onPlaybackReady);
|
|
338
313
|
player.addEventListener('loadedmetadata', onLoadedMetadata);
|
|
339
314
|
player.addEventListener('durationchange', onDurationChange);
|
|
@@ -363,37 +338,37 @@ const useDailymotionPlayer = function () {
|
|
|
363
338
|
const {
|
|
364
339
|
current: player
|
|
365
340
|
} = playerRef;
|
|
366
|
-
return player !== null ? player.play() : Promise.reject(
|
|
341
|
+
return player !== null ? player.play() : Promise.reject(NO_PLAYER_ERROR$3);
|
|
367
342
|
}, []);
|
|
368
343
|
const pause = useCallback(() => {
|
|
369
344
|
const {
|
|
370
345
|
current: player
|
|
371
346
|
} = playerRef;
|
|
372
|
-
return player !== null ? player.pause() : Promise.reject(
|
|
347
|
+
return player !== null ? player.pause() : Promise.reject(NO_PLAYER_ERROR$3);
|
|
373
348
|
}, []);
|
|
374
349
|
const setVolume = useCallback(newVolume => {
|
|
375
350
|
const {
|
|
376
351
|
current: player
|
|
377
352
|
} = playerRef;
|
|
378
|
-
return player !== null ? player.setVolume(newVolume) : Promise.reject(
|
|
353
|
+
return player !== null ? player.setVolume(newVolume) : Promise.reject(NO_PLAYER_ERROR$3);
|
|
379
354
|
}, []);
|
|
380
355
|
const mute = useCallback(() => {
|
|
381
356
|
const {
|
|
382
357
|
current: player
|
|
383
358
|
} = playerRef;
|
|
384
|
-
return player !== null ? player.setMute(true) : Promise.reject(
|
|
359
|
+
return player !== null ? player.setMute(true) : Promise.reject(NO_PLAYER_ERROR$3);
|
|
385
360
|
}, []);
|
|
386
361
|
const unmute = useCallback(() => {
|
|
387
362
|
const {
|
|
388
363
|
current: player
|
|
389
364
|
} = playerRef;
|
|
390
|
-
return player !== null ? player.setMute(false) : Promise.reject(
|
|
365
|
+
return player !== null ? player.setMute(false) : Promise.reject(NO_PLAYER_ERROR$3);
|
|
391
366
|
}, []);
|
|
392
367
|
const seek = useCallback(time => {
|
|
393
368
|
const {
|
|
394
369
|
current: player
|
|
395
370
|
} = playerRef;
|
|
396
|
-
return player !== null ? player.seek(time) : Promise.reject(
|
|
371
|
+
return player !== null ? player.seek(time) : Promise.reject(NO_PLAYER_ERROR$3);
|
|
397
372
|
}, []);
|
|
398
373
|
const {
|
|
399
374
|
playing
|
|
@@ -421,39 +396,35 @@ const useDailymotionPlayer = function () {
|
|
|
421
396
|
...metadata,
|
|
422
397
|
...playState
|
|
423
398
|
};
|
|
424
|
-
}
|
|
399
|
+
}
|
|
425
400
|
|
|
426
401
|
const eventsManager$1 = typeof document !== 'undefined' ? new EventsManager(document) : null;
|
|
427
|
-
|
|
428
|
-
const useDocumentEvent = (event, callback) => {
|
|
402
|
+
function useDocumentEvent(event, callback) {
|
|
429
403
|
useEffect(() => {
|
|
430
404
|
if (eventsManager$1 !== null && callback !== null) {
|
|
431
405
|
eventsManager$1.subscribe(event, callback);
|
|
432
406
|
}
|
|
433
|
-
|
|
434
407
|
return () => {
|
|
435
408
|
if (eventsManager$1 !== null && callback !== null) {
|
|
436
409
|
eventsManager$1.unsubscribe(event, callback);
|
|
437
410
|
}
|
|
438
411
|
};
|
|
439
412
|
}, [event, callback]);
|
|
440
|
-
}
|
|
413
|
+
}
|
|
441
414
|
|
|
442
415
|
const eventsManager = typeof window !== 'undefined' ? new EventsManager(window) : null;
|
|
443
|
-
|
|
444
|
-
const useWindowEvent = (event, callback) => {
|
|
416
|
+
function useWindowEvent(event, callback) {
|
|
445
417
|
useEffect(() => {
|
|
446
418
|
if (eventsManager !== null && callback !== null) {
|
|
447
419
|
eventsManager.subscribe(event, callback);
|
|
448
420
|
}
|
|
449
|
-
|
|
450
421
|
return () => {
|
|
451
422
|
if (eventsManager !== null && callback !== null) {
|
|
452
423
|
eventsManager.unsubscribe(event, callback);
|
|
453
424
|
}
|
|
454
425
|
};
|
|
455
426
|
}, [event, callback]);
|
|
456
|
-
}
|
|
427
|
+
}
|
|
457
428
|
|
|
458
429
|
function useKeyboard() {
|
|
459
430
|
let keyMap = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
|
|
@@ -462,13 +433,11 @@ function useKeyboard() {
|
|
|
462
433
|
key
|
|
463
434
|
} = event;
|
|
464
435
|
let callback = null;
|
|
465
|
-
|
|
466
436
|
if (typeof keyMap === 'function') {
|
|
467
437
|
callback = keyMap;
|
|
468
438
|
} else if (typeof keyMap[key] !== 'undefined') {
|
|
469
439
|
callback = typeof keyMap[key] === 'function' ? keyMap[key] : (keyMap[key] || {}).down || null;
|
|
470
440
|
}
|
|
471
|
-
|
|
472
441
|
if (callback !== null) {
|
|
473
442
|
callback(event);
|
|
474
443
|
}
|
|
@@ -478,13 +447,11 @@ function useKeyboard() {
|
|
|
478
447
|
key
|
|
479
448
|
} = event;
|
|
480
449
|
let callback = null;
|
|
481
|
-
|
|
482
450
|
if (typeof keyMap === 'function') {
|
|
483
451
|
callback = keyMap;
|
|
484
452
|
} else if (typeof keyMap[key] !== 'undefined') {
|
|
485
453
|
callback = typeof keyMap[key] === 'function' ? keyMap[key] : (keyMap[key] || {}).up || null;
|
|
486
454
|
}
|
|
487
|
-
|
|
488
455
|
if (callback !== null) {
|
|
489
456
|
callback(event);
|
|
490
457
|
}
|
|
@@ -550,15 +517,13 @@ const useItemsPaginated = function (loader) {
|
|
|
550
517
|
} = _ref4;
|
|
551
518
|
return pagesItems.concat(pageItems);
|
|
552
519
|
}, []) : null;
|
|
553
|
-
|
|
554
|
-
|
|
520
|
+
const updateState = update => setState({
|
|
521
|
+
...state,
|
|
555
522
|
...update
|
|
556
523
|
});
|
|
557
|
-
|
|
558
524
|
const updateFromResponse = function (response) {
|
|
559
525
|
let error = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
|
|
560
526
|
let reset = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|
561
|
-
|
|
562
527
|
if (error !== null) {
|
|
563
528
|
updateState({
|
|
564
529
|
loaded: false,
|
|
@@ -566,7 +531,6 @@ const useItemsPaginated = function (loader) {
|
|
|
566
531
|
});
|
|
567
532
|
throw error;
|
|
568
533
|
}
|
|
569
|
-
|
|
570
534
|
const newPage = getPageFromResponse(response);
|
|
571
535
|
const currentPages = currentPagesRef.current || [];
|
|
572
536
|
const newPages = (reset ? [newPage] : [...currentPages.filter(it => it.page !== newPage.page), newPage]).sort((a, b) => {
|
|
@@ -577,23 +541,18 @@ const useItemsPaginated = function (loader) {
|
|
|
577
541
|
page: bPage = null
|
|
578
542
|
} = b;
|
|
579
543
|
const hasObject = aPage !== null && bPage !== null;
|
|
580
|
-
|
|
581
544
|
if (hasObject) {
|
|
582
545
|
if (aPage === bPage) {
|
|
583
546
|
return 0;
|
|
584
547
|
}
|
|
585
|
-
|
|
586
548
|
return aPage > bPage ? 1 : -1;
|
|
587
549
|
}
|
|
588
|
-
|
|
589
550
|
if (isNumber(a) && isNumber(b)) {
|
|
590
551
|
if (a === b) {
|
|
591
552
|
return 0;
|
|
592
553
|
}
|
|
593
|
-
|
|
594
554
|
return a > b ? 1 : -1;
|
|
595
555
|
}
|
|
596
|
-
|
|
597
556
|
return 0;
|
|
598
557
|
});
|
|
599
558
|
currentPagesRef.current = newPages;
|
|
@@ -606,7 +565,6 @@ const useItemsPaginated = function (loader) {
|
|
|
606
565
|
});
|
|
607
566
|
return newPage;
|
|
608
567
|
};
|
|
609
|
-
|
|
610
568
|
const getNextPage = () => {
|
|
611
569
|
const allPages = lastPage !== -1 ? Array.call(null, ...Array(lastPage)).map((it, index) => index + 1) : [];
|
|
612
570
|
const currentPages = currentPagesRef.current || [];
|
|
@@ -614,7 +572,6 @@ const useItemsPaginated = function (loader) {
|
|
|
614
572
|
const firstItem = remainingPages.length > 0 ? remainingPages.shift() : null;
|
|
615
573
|
return firstItem !== null ? firstItem : null;
|
|
616
574
|
};
|
|
617
|
-
|
|
618
575
|
const loadItems = requestPage => {
|
|
619
576
|
updateState({
|
|
620
577
|
loading: true
|
|
@@ -623,7 +580,6 @@ const useItemsPaginated = function (loader) {
|
|
|
623
580
|
if (onLoaded !== null) {
|
|
624
581
|
onLoaded(response);
|
|
625
582
|
}
|
|
626
|
-
|
|
627
583
|
return response;
|
|
628
584
|
}).catch(error => {
|
|
629
585
|
if (onError !== null) {
|
|
@@ -631,35 +587,28 @@ const useItemsPaginated = function (loader) {
|
|
|
631
587
|
}
|
|
632
588
|
});
|
|
633
589
|
};
|
|
634
|
-
|
|
635
590
|
const loadPage = pageToLoad => {
|
|
636
591
|
if (loading) {
|
|
637
592
|
return Promise.reject();
|
|
638
593
|
}
|
|
639
|
-
|
|
640
594
|
const currentPages = currentPagesRef.current || [];
|
|
641
595
|
const foundPage = currentPages.find(it => it.page === pageToLoad) || null;
|
|
642
|
-
|
|
643
596
|
if (foundPage !== null) {
|
|
644
597
|
return Promise.resolve(foundPage);
|
|
645
598
|
}
|
|
646
|
-
|
|
647
599
|
return loadItems(pageToLoad);
|
|
648
600
|
};
|
|
649
|
-
|
|
650
601
|
const loadNextPage = () => {
|
|
651
602
|
if (loading) {
|
|
652
603
|
return Promise.reject();
|
|
653
604
|
}
|
|
654
|
-
|
|
655
605
|
const nextPage = getNextPage();
|
|
656
606
|
return nextPage !== null ? loadItems(nextPage) : Promise.resolve();
|
|
657
|
-
};
|
|
658
|
-
|
|
607
|
+
};
|
|
659
608
|
|
|
609
|
+
// Reset all on query change
|
|
660
610
|
useEffect(() => {
|
|
661
611
|
const hadState = lastState.current !== null;
|
|
662
|
-
|
|
663
612
|
if (hadState) {
|
|
664
613
|
currentPagesRef.current = null;
|
|
665
614
|
updateState({
|
|
@@ -674,7 +623,6 @@ const useItemsPaginated = function (loader) {
|
|
|
674
623
|
useEffect(() => {
|
|
675
624
|
const hadState = lastState.current !== null;
|
|
676
625
|
lastState.current = initialState;
|
|
677
|
-
|
|
678
626
|
if (hadState) {
|
|
679
627
|
currentPagesRef.current = initialState.pages;
|
|
680
628
|
setState(initialState);
|
|
@@ -684,14 +632,11 @@ const useItemsPaginated = function (loader) {
|
|
|
684
632
|
if (loader === null) {
|
|
685
633
|
return () => {};
|
|
686
634
|
}
|
|
687
|
-
|
|
688
635
|
let loadPromise = null;
|
|
689
636
|
const pageToLoad = initialPages === null && page === null ? 1 : page;
|
|
690
|
-
|
|
691
637
|
if (pageToLoad !== null) {
|
|
692
638
|
loadPromise = loadItems(pageToLoad);
|
|
693
639
|
}
|
|
694
|
-
|
|
695
640
|
return () => {
|
|
696
641
|
if (loadPromise !== null) {
|
|
697
642
|
loadPromise.cancel();
|
|
@@ -719,10 +664,8 @@ const useItemsPaginated = function (loader) {
|
|
|
719
664
|
};
|
|
720
665
|
};
|
|
721
666
|
|
|
722
|
-
const
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
const useNativeVideoPlayer = function (url) {
|
|
667
|
+
const NO_PLAYER_ERROR$2 = new Error('No player');
|
|
668
|
+
function useNativeVideoPlayer(url) {
|
|
726
669
|
let {
|
|
727
670
|
width = 0,
|
|
728
671
|
height = 0,
|
|
@@ -731,6 +674,7 @@ const useNativeVideoPlayer = function (url) {
|
|
|
731
674
|
timeUpdateInterval = 1000,
|
|
732
675
|
onTimeUpdate: customOnTimeUpdate = null
|
|
733
676
|
} = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
677
|
+
const debug = useMemo(() => createDebug('folklore:video:native'), []);
|
|
734
678
|
const elementRef = useRef(null);
|
|
735
679
|
const [loaded, setLoaded] = useState(false);
|
|
736
680
|
const [volume, setVolumeState] = useState(initialMuted ? 0 : 1);
|
|
@@ -749,89 +693,77 @@ const useNativeVideoPlayer = function (url) {
|
|
|
749
693
|
const {
|
|
750
694
|
current: player
|
|
751
695
|
} = elementRef;
|
|
752
|
-
return player !== null ? player.play() : Promise.reject(
|
|
696
|
+
return player !== null ? player.play() : Promise.reject(NO_PLAYER_ERROR$2);
|
|
753
697
|
}, []);
|
|
754
698
|
const pause = useCallback(() => {
|
|
755
699
|
const {
|
|
756
700
|
current: player
|
|
757
701
|
} = elementRef;
|
|
758
|
-
return player !== null ? player.pause() : Promise.reject(
|
|
702
|
+
return player !== null ? player.pause() : Promise.reject(NO_PLAYER_ERROR$2);
|
|
759
703
|
}, []);
|
|
760
704
|
const setVolume = useCallback(newVolume => {
|
|
761
705
|
const {
|
|
762
706
|
current: player
|
|
763
707
|
} = elementRef;
|
|
764
|
-
|
|
765
708
|
if (player !== null) {
|
|
766
709
|
player.volume = newVolume;
|
|
767
710
|
return Promise.resolve(newVolume);
|
|
768
711
|
}
|
|
769
|
-
|
|
770
|
-
return Promise.reject(noPlayerError);
|
|
712
|
+
return Promise.reject(NO_PLAYER_ERROR$2);
|
|
771
713
|
}, []);
|
|
772
714
|
const mute = useCallback(() => {
|
|
773
715
|
const {
|
|
774
716
|
current: player
|
|
775
717
|
} = elementRef;
|
|
776
|
-
|
|
777
718
|
if (player !== null) {
|
|
778
719
|
player.muted = true;
|
|
779
720
|
return Promise.resolve(true);
|
|
780
721
|
}
|
|
781
|
-
|
|
782
|
-
return Promise.reject(noPlayerError);
|
|
722
|
+
return Promise.reject(NO_PLAYER_ERROR$2);
|
|
783
723
|
}, []);
|
|
784
724
|
const unmute = useCallback(() => {
|
|
785
725
|
const {
|
|
786
726
|
current: player
|
|
787
727
|
} = elementRef;
|
|
788
|
-
|
|
789
728
|
if (player !== null) {
|
|
790
729
|
player.muted = false;
|
|
791
730
|
return Promise.resolve(false);
|
|
792
731
|
}
|
|
793
|
-
|
|
794
|
-
return Promise.reject(noPlayerError);
|
|
732
|
+
return Promise.reject(NO_PLAYER_ERROR$2);
|
|
795
733
|
}, []);
|
|
796
734
|
const seek = useCallback(newTime => {
|
|
797
735
|
const {
|
|
798
736
|
current: player
|
|
799
737
|
} = elementRef;
|
|
800
|
-
|
|
801
738
|
if (player !== null) {
|
|
802
739
|
player.currentTime = newTime;
|
|
803
740
|
return Promise.resolve(newTime);
|
|
804
741
|
}
|
|
805
|
-
|
|
806
|
-
return Promise.reject(noPlayerError);
|
|
742
|
+
return Promise.reject(NO_PLAYER_ERROR$2);
|
|
807
743
|
}, []);
|
|
808
744
|
const setLoop = useCallback(newLoop => {
|
|
809
745
|
const {
|
|
810
746
|
current: player
|
|
811
747
|
} = elementRef;
|
|
812
|
-
|
|
813
748
|
if (player !== null) {
|
|
814
749
|
player.loop = newLoop;
|
|
815
750
|
return Promise.resolve(newLoop);
|
|
816
751
|
}
|
|
752
|
+
return Promise.reject(NO_PLAYER_ERROR$2);
|
|
753
|
+
}, []);
|
|
817
754
|
|
|
818
|
-
|
|
819
|
-
}, []); // Bind player events
|
|
820
|
-
|
|
755
|
+
// Bind player events
|
|
821
756
|
useEffect(() => {
|
|
822
757
|
const {
|
|
823
758
|
current: player
|
|
824
759
|
} = elementRef;
|
|
825
|
-
|
|
826
760
|
if (player === null) {
|
|
827
761
|
return () => {};
|
|
828
762
|
}
|
|
829
|
-
|
|
830
763
|
const onCanPlay = () => {
|
|
831
764
|
setLoaded(true);
|
|
832
|
-
debug
|
|
765
|
+
debug('onCanPlay [URL: %s]', url);
|
|
833
766
|
};
|
|
834
|
-
|
|
835
767
|
const onMetadataLoaded = () => {
|
|
836
768
|
const newMetadata = {
|
|
837
769
|
duration: player.duration,
|
|
@@ -839,9 +771,8 @@ const useNativeVideoPlayer = function (url) {
|
|
|
839
771
|
height: player.videoHeight
|
|
840
772
|
};
|
|
841
773
|
setMetadata(newMetadata);
|
|
842
|
-
debug
|
|
774
|
+
debug('onMetadataLoaded [URL: %s]', url);
|
|
843
775
|
};
|
|
844
|
-
|
|
845
776
|
const onPlay = () => {
|
|
846
777
|
setPlayState({
|
|
847
778
|
playing: true,
|
|
@@ -849,9 +780,8 @@ const useNativeVideoPlayer = function (url) {
|
|
|
849
780
|
ended: false,
|
|
850
781
|
buffering: false
|
|
851
782
|
});
|
|
852
|
-
debug
|
|
783
|
+
debug('onPlay [URL: %s]', url);
|
|
853
784
|
};
|
|
854
|
-
|
|
855
785
|
const onPause = () => {
|
|
856
786
|
setPlayState({
|
|
857
787
|
playing: false,
|
|
@@ -859,9 +789,8 @@ const useNativeVideoPlayer = function (url) {
|
|
|
859
789
|
ended: false,
|
|
860
790
|
buffering: false
|
|
861
791
|
});
|
|
862
|
-
debug
|
|
792
|
+
debug('onPause [URL: %s]', url);
|
|
863
793
|
};
|
|
864
|
-
|
|
865
794
|
const onEnded = () => {
|
|
866
795
|
setPlayState({
|
|
867
796
|
playing: false,
|
|
@@ -869,17 +798,16 @@ const useNativeVideoPlayer = function (url) {
|
|
|
869
798
|
ended: true,
|
|
870
799
|
buffering: false
|
|
871
800
|
});
|
|
872
|
-
debug
|
|
801
|
+
debug('onEnded [URL: %s]', url);
|
|
873
802
|
};
|
|
874
|
-
|
|
875
|
-
debug$2('Bind events [URL: %s]', url);
|
|
803
|
+
debug('Bind events [URL: %s]', url);
|
|
876
804
|
player.addEventListener('canplay', onCanPlay);
|
|
877
805
|
player.addEventListener('metadataloaded', onMetadataLoaded);
|
|
878
806
|
player.addEventListener('play', onPlay);
|
|
879
807
|
player.addEventListener('pause', onPause);
|
|
880
808
|
player.addEventListener('ended', onEnded);
|
|
881
809
|
return () => {
|
|
882
|
-
debug
|
|
810
|
+
debug('Unbind events [URL: %s]', url);
|
|
883
811
|
player.removeEventListener('canplay', onCanPlay);
|
|
884
812
|
player.removeEventListener('metadataloaded', onMetadataLoaded);
|
|
885
813
|
player.removeEventListener('play', onPlay);
|
|
@@ -914,42 +842,37 @@ const useNativeVideoPlayer = function (url) {
|
|
|
914
842
|
...metadata,
|
|
915
843
|
...playState
|
|
916
844
|
};
|
|
917
|
-
}
|
|
845
|
+
}
|
|
918
846
|
|
|
919
847
|
const observersCache = new Map();
|
|
920
|
-
|
|
921
|
-
const getOptionsKey = _ref => {
|
|
848
|
+
function getOptionsKey(_ref) {
|
|
922
849
|
let {
|
|
923
850
|
root = null,
|
|
924
851
|
rootMargin,
|
|
925
852
|
threshold = null
|
|
926
853
|
} = _ref;
|
|
927
|
-
return
|
|
928
|
-
}
|
|
929
|
-
|
|
930
|
-
const createObserver = function (Observer) {
|
|
854
|
+
return `root_${root}_rootMargin_${rootMargin || null}_threshold_${threshold}`;
|
|
855
|
+
}
|
|
856
|
+
function createObserver(Observer) {
|
|
931
857
|
let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
932
858
|
let subscribers = [];
|
|
933
|
-
|
|
934
859
|
const addSubscriber = (element, callback) => {
|
|
935
860
|
const currentSubscriber = subscribers.find(it => it.element === element) || null;
|
|
936
|
-
|
|
937
861
|
if (currentSubscriber !== null) {
|
|
938
|
-
return subscribers.map(it => it.element === element && it.callbacks.indexOf(callback) === -1 ? {
|
|
862
|
+
return subscribers.map(it => it.element === element && it.callbacks.indexOf(callback) === -1 ? {
|
|
863
|
+
...it,
|
|
939
864
|
callbacks: [...it.callbacks, callback]
|
|
940
865
|
} : it).filter(it => it.callbacks.length > 0);
|
|
941
866
|
}
|
|
942
|
-
|
|
943
867
|
return [...subscribers, {
|
|
944
868
|
element,
|
|
945
869
|
callbacks: [callback]
|
|
946
870
|
}];
|
|
947
871
|
};
|
|
948
|
-
|
|
949
|
-
|
|
872
|
+
const removeSubscriber = (element, callback) => subscribers.map(it => it.element === element ? {
|
|
873
|
+
...it,
|
|
950
874
|
callbacks: it.callbacks.filter(subCallback => subCallback !== callback)
|
|
951
875
|
} : it).filter(it => it.callbacks.length > 0);
|
|
952
|
-
|
|
953
876
|
const onUpdate = entries => {
|
|
954
877
|
entries.forEach(entry => {
|
|
955
878
|
subscribers.forEach(_ref2 => {
|
|
@@ -957,7 +880,6 @@ const createObserver = function (Observer) {
|
|
|
957
880
|
element,
|
|
958
881
|
callbacks
|
|
959
882
|
} = _ref2;
|
|
960
|
-
|
|
961
883
|
if (element === entry.target) {
|
|
962
884
|
callbacks.forEach(callback => {
|
|
963
885
|
callback(entry);
|
|
@@ -966,13 +888,10 @@ const createObserver = function (Observer) {
|
|
|
966
888
|
});
|
|
967
889
|
});
|
|
968
890
|
};
|
|
969
|
-
|
|
970
891
|
const observer = new Observer(onUpdate, options);
|
|
971
|
-
|
|
972
892
|
const unsubscribe = function (element) {
|
|
973
893
|
let callback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
|
|
974
894
|
subscribers = removeSubscriber(element, callback);
|
|
975
|
-
|
|
976
895
|
if (typeof observer.unobserve === 'undefined') {
|
|
977
896
|
observer.disconnect();
|
|
978
897
|
subscribers.forEach(subscriber => {
|
|
@@ -980,48 +899,46 @@ const createObserver = function (Observer) {
|
|
|
980
899
|
});
|
|
981
900
|
return;
|
|
982
901
|
}
|
|
983
|
-
|
|
984
902
|
const currentSubscriber = subscribers.find(it => it.element === element) || null;
|
|
985
|
-
|
|
986
903
|
if (currentSubscriber === null) {
|
|
987
904
|
observer.unobserve(element);
|
|
988
905
|
}
|
|
989
906
|
};
|
|
990
|
-
|
|
991
907
|
const subscribe = (element, callback) => {
|
|
992
908
|
const currentSubscriber = subscribers.find(it => it.element === element) || null;
|
|
993
909
|
subscribers = addSubscriber(element, callback);
|
|
994
|
-
|
|
995
910
|
if (currentSubscriber === null) {
|
|
996
911
|
observer.observe(element);
|
|
997
912
|
}
|
|
998
913
|
};
|
|
999
|
-
|
|
1000
914
|
return {
|
|
1001
915
|
subscribe,
|
|
1002
916
|
unsubscribe,
|
|
1003
917
|
observer
|
|
1004
918
|
};
|
|
1005
|
-
}
|
|
1006
|
-
|
|
1007
|
-
|
|
919
|
+
}
|
|
920
|
+
function getObserver() {
|
|
921
|
+
let Observer = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
|
|
1008
922
|
let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
923
|
+
if (Observer === null) {
|
|
924
|
+
return {
|
|
925
|
+
observer: null,
|
|
926
|
+
subscribe: () => {},
|
|
927
|
+
unsubscribe: () => {}
|
|
928
|
+
};
|
|
929
|
+
}
|
|
1009
930
|
const observerKey = getOptionsKey(options);
|
|
1010
|
-
|
|
1011
931
|
if (!observersCache.has(Observer)) {
|
|
1012
932
|
observersCache.set(Observer, {});
|
|
1013
933
|
}
|
|
1014
|
-
|
|
1015
934
|
const observers = observersCache.get(Observer);
|
|
1016
|
-
|
|
1017
935
|
if (typeof observers[observerKey] === 'undefined') {
|
|
1018
936
|
observers[observerKey] = createObserver(Observer, options);
|
|
1019
937
|
observersCache.set(Observer, observers);
|
|
1020
938
|
}
|
|
1021
|
-
|
|
1022
939
|
return observers[observerKey];
|
|
1023
|
-
}
|
|
1024
|
-
|
|
940
|
+
}
|
|
941
|
+
function useObserver(Observer) {
|
|
1025
942
|
let opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
1026
943
|
let initialEntry = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
1027
944
|
const {
|
|
@@ -1039,26 +956,19 @@ const useObserver = function (Observer) {
|
|
|
1039
956
|
const {
|
|
1040
957
|
current: nodeElement
|
|
1041
958
|
} = nodeRef;
|
|
1042
|
-
|
|
1043
959
|
const callback = newEntry => setEntry(newEntry);
|
|
1044
|
-
|
|
1045
960
|
let unsubscribe = null;
|
|
1046
|
-
|
|
1047
961
|
if (nodeElement !== null) {
|
|
1048
962
|
const newOpts = {};
|
|
1049
|
-
|
|
1050
963
|
if (root !== null) {
|
|
1051
964
|
newOpts.root = root;
|
|
1052
965
|
}
|
|
1053
|
-
|
|
1054
966
|
if (rootMargin !== null) {
|
|
1055
967
|
newOpts.rootMargin = rootMargin;
|
|
1056
968
|
}
|
|
1057
|
-
|
|
1058
969
|
if (threshold !== null) {
|
|
1059
970
|
newOpts.threshold = threshold;
|
|
1060
971
|
}
|
|
1061
|
-
|
|
1062
972
|
const {
|
|
1063
973
|
subscribe,
|
|
1064
974
|
unsubscribe: localUnsubscribe
|
|
@@ -1066,7 +976,6 @@ const useObserver = function (Observer) {
|
|
|
1066
976
|
unsubscribe = localUnsubscribe;
|
|
1067
977
|
subscribe(nodeElement, callback);
|
|
1068
978
|
}
|
|
1069
|
-
|
|
1070
979
|
currentElement.current = nodeElement;
|
|
1071
980
|
return () => {
|
|
1072
981
|
if (unsubscribe !== null) {
|
|
@@ -1078,11 +987,11 @@ const useObserver = function (Observer) {
|
|
|
1078
987
|
ref: nodeRef,
|
|
1079
988
|
entry
|
|
1080
989
|
};
|
|
1081
|
-
}
|
|
990
|
+
}
|
|
991
|
+
|
|
1082
992
|
/**
|
|
1083
993
|
* Intersection Observer
|
|
1084
994
|
*/
|
|
1085
|
-
|
|
1086
995
|
const defaultThreshold = [0, 1.0];
|
|
1087
996
|
const intersectionObserverInitialEntry = {
|
|
1088
997
|
target: null,
|
|
@@ -1094,72 +1003,71 @@ const intersectionObserverInitialEntry = {
|
|
|
1094
1003
|
boundingClientRect: null,
|
|
1095
1004
|
rootBounds: null
|
|
1096
1005
|
};
|
|
1097
|
-
|
|
1006
|
+
function useIntersectionObserver() {
|
|
1098
1007
|
let {
|
|
1099
1008
|
root = null,
|
|
1100
1009
|
rootMargin = '0px',
|
|
1101
1010
|
threshold = defaultThreshold,
|
|
1102
1011
|
disabled = false
|
|
1103
1012
|
} = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
1104
|
-
return useObserver(IntersectionObserver, {
|
|
1013
|
+
return useObserver(typeof IntersectionObserver !== 'undefined' ? IntersectionObserver : null, {
|
|
1105
1014
|
root,
|
|
1106
1015
|
rootMargin,
|
|
1107
1016
|
threshold,
|
|
1108
1017
|
disabled
|
|
1109
1018
|
}, intersectionObserverInitialEntry);
|
|
1110
|
-
}
|
|
1019
|
+
}
|
|
1020
|
+
|
|
1111
1021
|
/**
|
|
1112
1022
|
* Resize Observer
|
|
1113
1023
|
*/
|
|
1114
|
-
|
|
1115
1024
|
const resizeObserverInitialEntry = {
|
|
1116
1025
|
target: null,
|
|
1117
1026
|
contentRect: null,
|
|
1118
1027
|
contentBoxSize: null,
|
|
1119
1028
|
borderBoxSize: null
|
|
1120
1029
|
};
|
|
1121
|
-
|
|
1030
|
+
function useResizeObserver() {
|
|
1122
1031
|
let {
|
|
1123
1032
|
disabled = false
|
|
1124
1033
|
} = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
1125
|
-
return useObserver(ResizeObserver, {
|
|
1034
|
+
return useObserver(typeof ResizeObserver !== 'undefined' ? ResizeObserver : null, {
|
|
1126
1035
|
disabled
|
|
1127
1036
|
}, resizeObserverInitialEntry);
|
|
1128
|
-
}
|
|
1037
|
+
}
|
|
1129
1038
|
|
|
1130
1039
|
const NO_PLAYER_ERROR$1 = new Error('No player');
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
function useYouTubePlayer(id) {
|
|
1040
|
+
function useVimeoPlayer(id) {
|
|
1134
1041
|
let {
|
|
1135
1042
|
width = 0,
|
|
1136
1043
|
height = 0,
|
|
1137
1044
|
duration = 0,
|
|
1138
1045
|
autoplay = false,
|
|
1139
|
-
|
|
1046
|
+
autopause = true,
|
|
1047
|
+
byline = false,
|
|
1048
|
+
controls = false,
|
|
1049
|
+
initialMuted = false,
|
|
1140
1050
|
timeUpdateInterval = 1000,
|
|
1141
|
-
muted: initialMuted = false,
|
|
1142
|
-
onVolumeChange: customOnVolumeChange = null,
|
|
1143
1051
|
onTimeUpdate: customOnTimeUpdate = null,
|
|
1144
1052
|
getVideoId = url => {
|
|
1145
|
-
if (url === null || url.match(/^
|
|
1053
|
+
if (url === null || url.match(/^[0-9]+$/) !== null) {
|
|
1146
1054
|
return url;
|
|
1147
1055
|
}
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
const match = url.match(regExp);
|
|
1151
|
-
return match && match[7].length === 11 ? match[7] : null;
|
|
1056
|
+
const match = url.match(/\/[0-9]+/);
|
|
1057
|
+
return match !== null ? match[1] : null;
|
|
1152
1058
|
}
|
|
1153
1059
|
} = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
1154
|
-
const
|
|
1155
|
-
const
|
|
1060
|
+
const debug = useMemo(() => createDebug('folklore:video:vimeo'), []);
|
|
1061
|
+
const [apiLoaded, setApiLoaded] = useState(false);
|
|
1062
|
+
const apiRef = useRef(null);
|
|
1156
1063
|
const elementRef = useRef(null);
|
|
1157
1064
|
const playerRef = useRef(null);
|
|
1158
1065
|
const playerElementRef = useRef(elementRef.current);
|
|
1159
1066
|
const elementHasChanged = elementRef.current !== playerElementRef.current;
|
|
1160
1067
|
const videoId = useMemo(() => getVideoId(id), [id]);
|
|
1161
1068
|
const [ready, setReady] = useState(false);
|
|
1162
|
-
const [
|
|
1069
|
+
const [loaded, setLoaded] = useState(false);
|
|
1070
|
+
const [volume, setVolumeState] = useState(initialMuted ? 0 : 1);
|
|
1163
1071
|
const [playState, setPlayState] = useState({
|
|
1164
1072
|
playing: false,
|
|
1165
1073
|
paused: false,
|
|
@@ -1171,93 +1079,93 @@ function useYouTubePlayer(id) {
|
|
|
1171
1079
|
height,
|
|
1172
1080
|
duration
|
|
1173
1081
|
});
|
|
1082
|
+
|
|
1083
|
+
// Load SDK
|
|
1174
1084
|
useEffect(() => {
|
|
1175
1085
|
let canceled = false;
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
loadYouTube().then(api => {
|
|
1086
|
+
if (!apiLoaded && id !== null) {
|
|
1087
|
+
debug('Load API');
|
|
1088
|
+
loadVimeo().then(api => {
|
|
1180
1089
|
if (!canceled) {
|
|
1181
1090
|
apiRef.current = api;
|
|
1182
1091
|
setApiLoaded(true);
|
|
1183
|
-
debug
|
|
1092
|
+
debug('API Loaded');
|
|
1184
1093
|
}
|
|
1185
1094
|
});
|
|
1186
1095
|
}
|
|
1187
|
-
|
|
1188
1096
|
return () => {
|
|
1189
1097
|
canceled = true;
|
|
1190
1098
|
};
|
|
1191
|
-
}, [
|
|
1099
|
+
}, [id]);
|
|
1192
1100
|
const play = useCallback(() => {
|
|
1193
1101
|
const {
|
|
1194
1102
|
current: player
|
|
1195
1103
|
} = playerRef;
|
|
1196
|
-
return player !== null
|
|
1104
|
+
return player !== null ? player.play() : Promise.reject(NO_PLAYER_ERROR$1);
|
|
1197
1105
|
}, []);
|
|
1198
1106
|
const pause = useCallback(() => {
|
|
1199
1107
|
const {
|
|
1200
1108
|
current: player
|
|
1201
1109
|
} = playerRef;
|
|
1202
|
-
return player !== null
|
|
1110
|
+
return player !== null ? player.pause() : Promise.reject(NO_PLAYER_ERROR$1);
|
|
1203
1111
|
}, []);
|
|
1204
|
-
const setVolume = useCallback(
|
|
1112
|
+
const setVolume = useCallback(newVolume => {
|
|
1205
1113
|
const {
|
|
1206
1114
|
current: player
|
|
1207
1115
|
} = playerRef;
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
if (customOnVolumeChange) {
|
|
1211
|
-
customOnVolumeChange(volume);
|
|
1212
|
-
}
|
|
1213
|
-
|
|
1214
|
-
return promise;
|
|
1215
|
-
}, [customOnVolumeChange]);
|
|
1116
|
+
return player !== null ? player.setVolume(newVolume) : Promise.reject(NO_PLAYER_ERROR$1);
|
|
1117
|
+
}, []);
|
|
1216
1118
|
const mute = useCallback(() => {
|
|
1217
1119
|
const {
|
|
1218
1120
|
current: player
|
|
1219
1121
|
} = playerRef;
|
|
1220
|
-
return
|
|
1221
|
-
}, [
|
|
1122
|
+
return player !== null ? player.setVolume(0) : Promise.reject(NO_PLAYER_ERROR$1);
|
|
1123
|
+
}, []);
|
|
1222
1124
|
const unmute = useCallback(() => {
|
|
1223
1125
|
const {
|
|
1224
1126
|
current: player
|
|
1225
1127
|
} = playerRef;
|
|
1226
|
-
return
|
|
1128
|
+
return player !== null ? player.setVolume(1) : Promise.reject(NO_PLAYER_ERROR$1);
|
|
1227
1129
|
}, []);
|
|
1228
1130
|
const seek = useCallback(time => {
|
|
1229
1131
|
const {
|
|
1230
1132
|
current: player
|
|
1231
1133
|
} = playerRef;
|
|
1232
|
-
return player !== null
|
|
1134
|
+
return player !== null ? player.setCurrentTime(time) : Promise.reject(NO_PLAYER_ERROR$1);
|
|
1233
1135
|
}, []);
|
|
1234
1136
|
const setLoop = useCallback(loop => {
|
|
1235
1137
|
const {
|
|
1236
1138
|
current: player
|
|
1237
1139
|
} = playerRef;
|
|
1238
|
-
return player !== null
|
|
1140
|
+
return player !== null ? player.setLoop(loop) : Promise.reject(NO_PLAYER_ERROR$1);
|
|
1239
1141
|
}, []);
|
|
1240
|
-
const
|
|
1241
|
-
|
|
1242
|
-
|
|
1142
|
+
const destroyVideo = useCallback(() => {
|
|
1143
|
+
const {
|
|
1144
|
+
current: player
|
|
1145
|
+
} = playerRef;
|
|
1146
|
+
if (player !== null) {
|
|
1147
|
+
debug('Unload video');
|
|
1148
|
+
player.unload();
|
|
1149
|
+
}
|
|
1150
|
+
if (player !== null) {
|
|
1151
|
+
debug('Unset video');
|
|
1243
1152
|
playerRef.current = null;
|
|
1244
1153
|
}
|
|
1245
|
-
}, []);
|
|
1246
|
-
|
|
1154
|
+
}, []);
|
|
1247
1155
|
useEffect(() => {
|
|
1248
1156
|
const {
|
|
1249
1157
|
current: currentPlayer
|
|
1250
1158
|
} = playerRef;
|
|
1251
|
-
|
|
1252
1159
|
if (playerElementRef.current !== elementRef.current && currentPlayer !== null) {
|
|
1253
|
-
debug
|
|
1254
|
-
|
|
1160
|
+
debug('iFrame switched');
|
|
1161
|
+
destroyVideo();
|
|
1255
1162
|
}
|
|
1256
|
-
}, [elementHasChanged]);
|
|
1163
|
+
}, [elementHasChanged]);
|
|
1257
1164
|
|
|
1165
|
+
// Create player
|
|
1258
1166
|
useEffect(() => {
|
|
1259
1167
|
const {
|
|
1260
|
-
current:
|
|
1168
|
+
current: Player = null
|
|
1261
1169
|
} = apiRef;
|
|
1262
1170
|
const {
|
|
1263
1171
|
current: currentPlayer = null
|
|
@@ -1265,89 +1173,140 @@ function useYouTubePlayer(id) {
|
|
|
1265
1173
|
const {
|
|
1266
1174
|
current: element = null
|
|
1267
1175
|
} = elementRef;
|
|
1268
|
-
|
|
1269
1176
|
if (!apiLoaded || videoId === null || element === null) {
|
|
1270
|
-
|
|
1177
|
+
destroyVideo();
|
|
1271
1178
|
return;
|
|
1272
1179
|
}
|
|
1273
|
-
|
|
1274
1180
|
let player = currentPlayer;
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1181
|
+
if (player === null) {
|
|
1182
|
+
debug('Create player [ID: %s]', videoId);
|
|
1183
|
+
player = new Player(element, {
|
|
1184
|
+
id: videoId,
|
|
1185
|
+
autoplay,
|
|
1186
|
+
autopause,
|
|
1187
|
+
byline,
|
|
1188
|
+
controls,
|
|
1189
|
+
muted: initialMuted,
|
|
1190
|
+
background: !controls
|
|
1191
|
+
});
|
|
1192
|
+
player.ready().then(() => setReady(true)).catch(e => {
|
|
1193
|
+
debug('ERROR: %o', e);
|
|
1194
|
+
});
|
|
1279
1195
|
} else {
|
|
1280
|
-
debug
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
setReady(true);
|
|
1289
|
-
const newDuration = target.getDuration();
|
|
1196
|
+
debug('Load video [ID: %s]', videoId);
|
|
1197
|
+
player.loadVideo(videoId).catch(e => {
|
|
1198
|
+
debug('ERROR: %o', e);
|
|
1199
|
+
});
|
|
1200
|
+
}
|
|
1201
|
+
playerRef.current = player;
|
|
1202
|
+
playerElementRef.current = element;
|
|
1203
|
+
}, [apiLoaded, videoId, elementHasChanged, setReady, destroyVideo, setLoaded]);
|
|
1290
1204
|
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1205
|
+
// Bind player events
|
|
1206
|
+
useEffect(() => {
|
|
1207
|
+
const {
|
|
1208
|
+
current: player
|
|
1209
|
+
} = playerRef;
|
|
1210
|
+
if (player === null) {
|
|
1211
|
+
return () => {};
|
|
1212
|
+
}
|
|
1213
|
+
let canceled = false;
|
|
1214
|
+
const onLoaded = () => {
|
|
1215
|
+
Promise.all([player.getDuration(), player.getVideoWidth(), player.getVideoHeight(), player.getMuted()]).then(_ref => {
|
|
1216
|
+
let [newDuration, newWidth, newHeight, newMuted] = _ref;
|
|
1217
|
+
if (canceled) {
|
|
1218
|
+
return;
|
|
1295
1219
|
}
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
const onStateChange = _ref2 => {
|
|
1301
|
-
let {
|
|
1302
|
-
data: state
|
|
1303
|
-
} = _ref2;
|
|
1304
|
-
const newState = {
|
|
1305
|
-
playing: state === YT.PlayerState.PLAYING,
|
|
1306
|
-
paused: state === YT.PlayerState.PAUSED,
|
|
1307
|
-
ended: state === YT.PlayerState.ENDED,
|
|
1308
|
-
buffering: state === YT.PlayerState.BUFFERING
|
|
1220
|
+
const newMetadata = {
|
|
1221
|
+
duration: newDuration,
|
|
1222
|
+
width: newWidth,
|
|
1223
|
+
height: newHeight
|
|
1309
1224
|
};
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
if (newState.playing) {
|
|
1314
|
-
stateLabel = 'playing';
|
|
1315
|
-
} else if (newState.paused) {
|
|
1316
|
-
stateLabel = 'paused';
|
|
1317
|
-
} else if (newState.ended) {
|
|
1318
|
-
stateLabel = 'ended';
|
|
1319
|
-
} else if (newState.buffering) {
|
|
1320
|
-
stateLabel = 'buffering';
|
|
1321
|
-
} else if (state === -1) {
|
|
1322
|
-
stateLabel = 'not started';
|
|
1323
|
-
} else if (state === 0) {
|
|
1324
|
-
stateLabel = 'stopped';
|
|
1225
|
+
setMetadata(newMetadata);
|
|
1226
|
+
if (newMuted) {
|
|
1227
|
+
setVolumeState(0);
|
|
1325
1228
|
}
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
events: {
|
|
1342
|
-
onReady,
|
|
1343
|
-
onStateChange
|
|
1229
|
+
setLoaded(true);
|
|
1230
|
+
});
|
|
1231
|
+
debug('onLoaded [ID: %s]', videoId);
|
|
1232
|
+
};
|
|
1233
|
+
const onPlay = () => {
|
|
1234
|
+
setPlayState({
|
|
1235
|
+
playing: true,
|
|
1236
|
+
paused: false,
|
|
1237
|
+
ended: false,
|
|
1238
|
+
buffering: false
|
|
1239
|
+
});
|
|
1240
|
+
debug('onPlay [ID: %s]', videoId);
|
|
1241
|
+
player.getMuted().then(newMuted => {
|
|
1242
|
+
if (!canceled && newMuted) {
|
|
1243
|
+
setVolumeState(0);
|
|
1344
1244
|
}
|
|
1245
|
+
}).catch(() => {});
|
|
1246
|
+
};
|
|
1247
|
+
const onPause = () => {
|
|
1248
|
+
setPlayState({
|
|
1249
|
+
playing: false,
|
|
1250
|
+
paused: true,
|
|
1251
|
+
ended: false,
|
|
1252
|
+
buffering: false
|
|
1345
1253
|
});
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1254
|
+
debug('onPause [ID: %s]', videoId);
|
|
1255
|
+
};
|
|
1256
|
+
const onVolumeChange = _ref2 => {
|
|
1257
|
+
let {
|
|
1258
|
+
volume: newVolume
|
|
1259
|
+
} = _ref2;
|
|
1260
|
+
setVolumeState(newVolume);
|
|
1261
|
+
debug('onVolumeChange [ID: %s]', videoId);
|
|
1262
|
+
};
|
|
1263
|
+
const onEnded = () => {
|
|
1264
|
+
setPlayState({
|
|
1265
|
+
playing: false,
|
|
1266
|
+
paused: false,
|
|
1267
|
+
ended: true,
|
|
1268
|
+
buffering: false
|
|
1269
|
+
});
|
|
1270
|
+
debug('onEnded [ID: %s]', videoId);
|
|
1271
|
+
};
|
|
1272
|
+
const onBufferStart = () => {
|
|
1273
|
+
setPlayState({
|
|
1274
|
+
playing: true,
|
|
1275
|
+
paused: false,
|
|
1276
|
+
ended: false,
|
|
1277
|
+
buffering: true
|
|
1278
|
+
});
|
|
1279
|
+
debug('onBufferStart [ID: %s]', videoId);
|
|
1280
|
+
};
|
|
1281
|
+
const onBufferEnded = () => {
|
|
1282
|
+
setPlayState({
|
|
1283
|
+
playing: true,
|
|
1284
|
+
paused: false,
|
|
1285
|
+
ended: false,
|
|
1286
|
+
buffering: false
|
|
1287
|
+
});
|
|
1288
|
+
debug('onBufferStart [ID: %s]', videoId);
|
|
1289
|
+
};
|
|
1290
|
+
debug('Bind events [ID: %s]', videoId);
|
|
1291
|
+
player.on('loaded', onLoaded);
|
|
1292
|
+
player.on('play', onPlay);
|
|
1293
|
+
player.on('pause', onPause);
|
|
1294
|
+
player.on('volumechange', onVolumeChange);
|
|
1295
|
+
player.on('ended', onEnded);
|
|
1296
|
+
player.on('bufferstart', onBufferStart);
|
|
1297
|
+
player.on('bufferend', onBufferEnded);
|
|
1298
|
+
return () => {
|
|
1299
|
+
canceled = true;
|
|
1300
|
+
debug('Unbind events [ID: %s]', videoId);
|
|
1301
|
+
player.off('loaded', onLoaded);
|
|
1302
|
+
player.off('play', onPlay);
|
|
1303
|
+
player.off('pause', onPause);
|
|
1304
|
+
player.off('volumechange', onVolumeChange);
|
|
1305
|
+
player.off('ended', onEnded);
|
|
1306
|
+
player.off('bufferstart', onBufferStart);
|
|
1307
|
+
player.off('bufferend', onBufferEnded);
|
|
1308
|
+
};
|
|
1309
|
+
}, [videoId, playerRef.current, setPlayState, setMetadata, setVolumeState, setLoaded]);
|
|
1351
1310
|
const {
|
|
1352
1311
|
playing
|
|
1353
1312
|
} = playState;
|
|
@@ -1371,47 +1330,45 @@ function useYouTubePlayer(id) {
|
|
|
1371
1330
|
setLoop,
|
|
1372
1331
|
ready,
|
|
1373
1332
|
currentTime,
|
|
1374
|
-
|
|
1375
|
-
|
|
1333
|
+
loaded,
|
|
1334
|
+
muted: volume === 0,
|
|
1335
|
+
volume,
|
|
1376
1336
|
...metadata,
|
|
1377
1337
|
...playState
|
|
1378
1338
|
};
|
|
1379
1339
|
}
|
|
1380
1340
|
|
|
1381
|
-
const debug = createDebug('folklore:video:vimeo');
|
|
1382
1341
|
const NO_PLAYER_ERROR = new Error('No player');
|
|
1383
|
-
|
|
1384
|
-
const useVimeoPlayer = function (id) {
|
|
1342
|
+
function useYouTubePlayer(id) {
|
|
1385
1343
|
let {
|
|
1386
1344
|
width = 0,
|
|
1387
1345
|
height = 0,
|
|
1388
1346
|
duration = 0,
|
|
1389
1347
|
autoplay = false,
|
|
1390
|
-
|
|
1391
|
-
byline = false,
|
|
1392
|
-
controls = false,
|
|
1393
|
-
initialMuted = false,
|
|
1348
|
+
controls = true,
|
|
1394
1349
|
timeUpdateInterval = 1000,
|
|
1350
|
+
muted: initialMuted = false,
|
|
1351
|
+
onVolumeChange: customOnVolumeChange = null,
|
|
1395
1352
|
onTimeUpdate: customOnTimeUpdate = null,
|
|
1396
1353
|
getVideoId = url => {
|
|
1397
|
-
if (url === null || url.match(/^
|
|
1354
|
+
if (url === null || url.match(/^https?:/) === null) {
|
|
1398
1355
|
return url;
|
|
1399
1356
|
}
|
|
1400
|
-
|
|
1401
|
-
const match = url.match(
|
|
1402
|
-
return match
|
|
1357
|
+
const regExp = /^.*((youtu.be\/)|(v\/)|(\/u\/\w\/)|(embed\/)|(watch\?))\??v?=?([^#&?]*).*/;
|
|
1358
|
+
const match = url.match(regExp);
|
|
1359
|
+
return match && match[7].length === 11 ? match[7] : null;
|
|
1403
1360
|
}
|
|
1404
1361
|
} = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
1405
|
-
const
|
|
1406
|
-
const
|
|
1362
|
+
const debug = useMemo(() => createDebug('folklore:video:youtube'), []);
|
|
1363
|
+
const [apiLoaded, setApiLoaded] = useState(typeof window !== 'undefined' && typeof window.YT !== 'undefined');
|
|
1364
|
+
const apiRef = useRef(typeof window !== 'undefined' && typeof window.YT !== 'undefined' ? window.YT : null);
|
|
1407
1365
|
const elementRef = useRef(null);
|
|
1408
1366
|
const playerRef = useRef(null);
|
|
1409
1367
|
const playerElementRef = useRef(elementRef.current);
|
|
1410
1368
|
const elementHasChanged = elementRef.current !== playerElementRef.current;
|
|
1411
1369
|
const videoId = useMemo(() => getVideoId(id), [id]);
|
|
1412
1370
|
const [ready, setReady] = useState(false);
|
|
1413
|
-
const [
|
|
1414
|
-
const [volume, setVolumeState] = useState(initialMuted ? 0 : 1);
|
|
1371
|
+
const [muted, setMuted] = useState(initialMuted);
|
|
1415
1372
|
const [playState, setPlayState] = useState({
|
|
1416
1373
|
playing: false,
|
|
1417
1374
|
paused: false,
|
|
@@ -1422,14 +1379,12 @@ const useVimeoPlayer = function (id) {
|
|
|
1422
1379
|
width,
|
|
1423
1380
|
height,
|
|
1424
1381
|
duration
|
|
1425
|
-
});
|
|
1426
|
-
|
|
1382
|
+
});
|
|
1427
1383
|
useEffect(() => {
|
|
1428
1384
|
let canceled = false;
|
|
1429
|
-
|
|
1430
|
-
if (!apiLoaded && id !== null) {
|
|
1385
|
+
if (!apiLoaded && videoId !== null) {
|
|
1431
1386
|
debug('Load API');
|
|
1432
|
-
|
|
1387
|
+
loadYouTube().then(api => {
|
|
1433
1388
|
if (!canceled) {
|
|
1434
1389
|
apiRef.current = api;
|
|
1435
1390
|
setApiLoaded(true);
|
|
@@ -1437,82 +1392,79 @@ const useVimeoPlayer = function (id) {
|
|
|
1437
1392
|
}
|
|
1438
1393
|
});
|
|
1439
1394
|
}
|
|
1440
|
-
|
|
1441
1395
|
return () => {
|
|
1442
1396
|
canceled = true;
|
|
1443
1397
|
};
|
|
1444
|
-
}, [
|
|
1398
|
+
}, [apiLoaded, videoId, setApiLoaded]);
|
|
1445
1399
|
const play = useCallback(() => {
|
|
1446
1400
|
const {
|
|
1447
1401
|
current: player
|
|
1448
1402
|
} = playerRef;
|
|
1449
|
-
return player !== null ? player.
|
|
1403
|
+
return player !== null && typeof player.playVideo !== 'undefined' ? Promise.resolve(player.playVideo()) : Promise.reject(NO_PLAYER_ERROR);
|
|
1450
1404
|
}, []);
|
|
1451
1405
|
const pause = useCallback(() => {
|
|
1452
1406
|
const {
|
|
1453
1407
|
current: player
|
|
1454
1408
|
} = playerRef;
|
|
1455
|
-
return player !== null ? player.
|
|
1409
|
+
return player !== null && typeof player.pauseVideo !== 'undefined' ? Promise.resolve(player.pauseVideo()) : Promise.reject(NO_PLAYER_ERROR);
|
|
1456
1410
|
}, []);
|
|
1457
|
-
const setVolume = useCallback(
|
|
1411
|
+
const setVolume = useCallback(volume => {
|
|
1458
1412
|
const {
|
|
1459
1413
|
current: player
|
|
1460
1414
|
} = playerRef;
|
|
1461
|
-
|
|
1462
|
-
|
|
1415
|
+
const promise = player !== null && typeof player.setVolume !== 'undefined' ? Promise.resolve(player.setVolume(volume * 100)) : Promise.reject(NO_PLAYER_ERROR);
|
|
1416
|
+
if (customOnVolumeChange) {
|
|
1417
|
+
customOnVolumeChange(volume);
|
|
1418
|
+
}
|
|
1419
|
+
return promise;
|
|
1420
|
+
}, [customOnVolumeChange]);
|
|
1463
1421
|
const mute = useCallback(() => {
|
|
1464
1422
|
const {
|
|
1465
1423
|
current: player
|
|
1466
1424
|
} = playerRef;
|
|
1467
|
-
return player !== null ? player.
|
|
1468
|
-
}, []);
|
|
1425
|
+
return (player !== null && typeof player.mute !== 'undefined' ? Promise.resolve(player.mute()) : Promise.reject(NO_PLAYER_ERROR)).then(() => setMuted(true));
|
|
1426
|
+
}, [setMuted]);
|
|
1469
1427
|
const unmute = useCallback(() => {
|
|
1470
1428
|
const {
|
|
1471
1429
|
current: player
|
|
1472
1430
|
} = playerRef;
|
|
1473
|
-
return player !== null ? player.
|
|
1431
|
+
return (player !== null && typeof player.unMute !== 'undefined' ? Promise.resolve(player.unMute()) : Promise.reject(NO_PLAYER_ERROR)).then(() => setMuted(false));
|
|
1474
1432
|
}, []);
|
|
1475
1433
|
const seek = useCallback(time => {
|
|
1476
1434
|
const {
|
|
1477
1435
|
current: player
|
|
1478
1436
|
} = playerRef;
|
|
1479
|
-
return player !== null ? player.
|
|
1437
|
+
return player !== null && typeof player.seekTo !== 'undefined' ? Promise.resolve(player.seekTo(time)) : Promise.reject(NO_PLAYER_ERROR);
|
|
1480
1438
|
}, []);
|
|
1481
1439
|
const setLoop = useCallback(loop => {
|
|
1482
1440
|
const {
|
|
1483
1441
|
current: player
|
|
1484
1442
|
} = playerRef;
|
|
1485
|
-
return player !== null ? player.setLoop(loop) : Promise.reject(NO_PLAYER_ERROR);
|
|
1443
|
+
return player !== null && typeof player.setLoop !== 'undefined' ? Promise.resolve(player.setLoop(loop)) : Promise.reject(NO_PLAYER_ERROR);
|
|
1486
1444
|
}, []);
|
|
1487
|
-
const
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
} = playerRef;
|
|
1491
|
-
|
|
1492
|
-
if (player !== null) {
|
|
1493
|
-
debug('Unload video');
|
|
1494
|
-
player.unload();
|
|
1495
|
-
}
|
|
1496
|
-
|
|
1497
|
-
if (player !== null) {
|
|
1498
|
-
debug('Unset video');
|
|
1445
|
+
const destroyPlayer = useCallback(() => {
|
|
1446
|
+
if (playerRef.current !== null) {
|
|
1447
|
+
debug('Unset player');
|
|
1499
1448
|
playerRef.current = null;
|
|
1500
1449
|
}
|
|
1501
1450
|
}, []);
|
|
1451
|
+
|
|
1452
|
+
// Detect iframe switch and destroy player
|
|
1453
|
+
|
|
1502
1454
|
useEffect(() => {
|
|
1503
1455
|
const {
|
|
1504
1456
|
current: currentPlayer
|
|
1505
1457
|
} = playerRef;
|
|
1506
|
-
|
|
1507
1458
|
if (playerElementRef.current !== elementRef.current && currentPlayer !== null) {
|
|
1508
1459
|
debug('iFrame switched');
|
|
1509
|
-
|
|
1460
|
+
destroyPlayer();
|
|
1510
1461
|
}
|
|
1511
|
-
}, [elementHasChanged]);
|
|
1462
|
+
}, [elementHasChanged]);
|
|
1512
1463
|
|
|
1464
|
+
// Create player
|
|
1513
1465
|
useEffect(() => {
|
|
1514
1466
|
const {
|
|
1515
|
-
current:
|
|
1467
|
+
current: YT = null
|
|
1516
1468
|
} = apiRef;
|
|
1517
1469
|
const {
|
|
1518
1470
|
current: currentPlayer = null
|
|
@@ -1520,157 +1472,79 @@ const useVimeoPlayer = function (id) {
|
|
|
1520
1472
|
const {
|
|
1521
1473
|
current: element = null
|
|
1522
1474
|
} = elementRef;
|
|
1523
|
-
|
|
1524
1475
|
if (!apiLoaded || videoId === null || element === null) {
|
|
1525
|
-
|
|
1476
|
+
destroyPlayer();
|
|
1526
1477
|
return;
|
|
1527
1478
|
}
|
|
1528
|
-
|
|
1529
1479
|
let player = currentPlayer;
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
player = new Player(element, {
|
|
1534
|
-
id: videoId,
|
|
1535
|
-
autoplay,
|
|
1536
|
-
autopause,
|
|
1537
|
-
byline,
|
|
1538
|
-
controls,
|
|
1539
|
-
muted: initialMuted,
|
|
1540
|
-
background: !controls
|
|
1541
|
-
});
|
|
1542
|
-
player.ready().then(() => setReady(true)).catch(e => {
|
|
1543
|
-
debug('ERROR: %o', e);
|
|
1544
|
-
});
|
|
1480
|
+
if (player !== null && typeof player.loadVideoById !== 'undefined') {
|
|
1481
|
+
debug('Switch video [ID: %s]', videoId);
|
|
1482
|
+
player.loadVideoById(videoId);
|
|
1545
1483
|
} else {
|
|
1546
|
-
debug('
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
if (player === null) {
|
|
1562
|
-
return () => {};
|
|
1563
|
-
}
|
|
1564
|
-
|
|
1565
|
-
let canceled = false;
|
|
1566
|
-
|
|
1567
|
-
const onLoaded = () => {
|
|
1568
|
-
Promise.all([player.getDuration(), player.getVideoWidth(), player.getVideoHeight(), player.getMuted()]).then(_ref => {
|
|
1569
|
-
let [newDuration, newWidth, newHeight, newMuted] = _ref;
|
|
1570
|
-
|
|
1571
|
-
if (canceled) {
|
|
1572
|
-
return;
|
|
1484
|
+
debug('Create player [ID: %s]', videoId);
|
|
1485
|
+
const onReady = _ref => {
|
|
1486
|
+
let {
|
|
1487
|
+
target
|
|
1488
|
+
} = _ref;
|
|
1489
|
+
player = target;
|
|
1490
|
+
playerRef.current = target;
|
|
1491
|
+
setReady(true);
|
|
1492
|
+
const newDuration = target.getDuration();
|
|
1493
|
+
if (newDuration !== metadata.duration) {
|
|
1494
|
+
setMetadata({
|
|
1495
|
+
...metadata,
|
|
1496
|
+
duration: newDuration
|
|
1497
|
+
});
|
|
1573
1498
|
}
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1499
|
+
debug('onReady [ID: %s]', videoId);
|
|
1500
|
+
};
|
|
1501
|
+
const onStateChange = _ref2 => {
|
|
1502
|
+
let {
|
|
1503
|
+
data: state
|
|
1504
|
+
} = _ref2;
|
|
1505
|
+
const newState = {
|
|
1506
|
+
playing: state === YT.PlayerState.PLAYING,
|
|
1507
|
+
paused: state === YT.PlayerState.PAUSED,
|
|
1508
|
+
ended: state === YT.PlayerState.ENDED,
|
|
1509
|
+
buffering: state === YT.PlayerState.BUFFERING
|
|
1579
1510
|
};
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
if (
|
|
1583
|
-
|
|
1511
|
+
setPlayState(newState);
|
|
1512
|
+
let stateLabel = null;
|
|
1513
|
+
if (newState.playing) {
|
|
1514
|
+
stateLabel = 'playing';
|
|
1515
|
+
} else if (newState.paused) {
|
|
1516
|
+
stateLabel = 'paused';
|
|
1517
|
+
} else if (newState.ended) {
|
|
1518
|
+
stateLabel = 'ended';
|
|
1519
|
+
} else if (newState.buffering) {
|
|
1520
|
+
stateLabel = 'buffering';
|
|
1521
|
+
} else if (state === -1) {
|
|
1522
|
+
stateLabel = 'not started';
|
|
1523
|
+
} else if (state === 0) {
|
|
1524
|
+
stateLabel = 'stopped';
|
|
1584
1525
|
}
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
setVolumeState(0);
|
|
1526
|
+
debug('onStateChange %s [ID: %s]', stateLabel, videoId);
|
|
1527
|
+
};
|
|
1528
|
+
player = new YT.Player(element, {
|
|
1529
|
+
videoId,
|
|
1530
|
+
playerVars: {
|
|
1531
|
+
controls,
|
|
1532
|
+
autoplay: autoplay ? 1 : 0,
|
|
1533
|
+
mute: initialMuted,
|
|
1534
|
+
playsinline: true,
|
|
1535
|
+
rel: 0,
|
|
1536
|
+
showinfo: 0,
|
|
1537
|
+
modestbranding: 1
|
|
1538
|
+
},
|
|
1539
|
+
events: {
|
|
1540
|
+
onReady,
|
|
1541
|
+
onStateChange
|
|
1602
1542
|
}
|
|
1603
|
-
}).catch(() => {});
|
|
1604
|
-
};
|
|
1605
|
-
|
|
1606
|
-
const onPause = () => {
|
|
1607
|
-
setPlayState({
|
|
1608
|
-
playing: false,
|
|
1609
|
-
paused: true,
|
|
1610
|
-
ended: false,
|
|
1611
|
-
buffering: false
|
|
1612
1543
|
});
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
let {
|
|
1618
|
-
volume: newVolume
|
|
1619
|
-
} = _ref2;
|
|
1620
|
-
setVolumeState(newVolume);
|
|
1621
|
-
debug('onVolumeChange [ID: %s]', videoId);
|
|
1622
|
-
};
|
|
1623
|
-
|
|
1624
|
-
const onEnded = () => {
|
|
1625
|
-
setPlayState({
|
|
1626
|
-
playing: false,
|
|
1627
|
-
paused: false,
|
|
1628
|
-
ended: true,
|
|
1629
|
-
buffering: false
|
|
1630
|
-
});
|
|
1631
|
-
debug('onEnded [ID: %s]', videoId);
|
|
1632
|
-
};
|
|
1633
|
-
|
|
1634
|
-
const onBufferStart = () => {
|
|
1635
|
-
setPlayState({
|
|
1636
|
-
playing: true,
|
|
1637
|
-
paused: false,
|
|
1638
|
-
ended: false,
|
|
1639
|
-
buffering: true
|
|
1640
|
-
});
|
|
1641
|
-
debug('onBufferStart [ID: %s]', videoId);
|
|
1642
|
-
};
|
|
1643
|
-
|
|
1644
|
-
const onBufferEnded = () => {
|
|
1645
|
-
setPlayState({
|
|
1646
|
-
playing: true,
|
|
1647
|
-
paused: false,
|
|
1648
|
-
ended: false,
|
|
1649
|
-
buffering: false
|
|
1650
|
-
});
|
|
1651
|
-
debug('onBufferStart [ID: %s]', videoId);
|
|
1652
|
-
};
|
|
1653
|
-
|
|
1654
|
-
debug('Bind events [ID: %s]', videoId);
|
|
1655
|
-
player.on('loaded', onLoaded);
|
|
1656
|
-
player.on('play', onPlay);
|
|
1657
|
-
player.on('pause', onPause);
|
|
1658
|
-
player.on('volumechange', onVolumeChange);
|
|
1659
|
-
player.on('ended', onEnded);
|
|
1660
|
-
player.on('bufferstart', onBufferStart);
|
|
1661
|
-
player.on('bufferend', onBufferEnded);
|
|
1662
|
-
return () => {
|
|
1663
|
-
canceled = true;
|
|
1664
|
-
debug('Unbind events [ID: %s]', videoId);
|
|
1665
|
-
player.off('loaded', onLoaded);
|
|
1666
|
-
player.off('play', onPlay);
|
|
1667
|
-
player.off('pause', onPause);
|
|
1668
|
-
player.off('volumechange', onVolumeChange);
|
|
1669
|
-
player.off('ended', onEnded);
|
|
1670
|
-
player.off('bufferstart', onBufferStart);
|
|
1671
|
-
player.off('bufferend', onBufferEnded);
|
|
1672
|
-
};
|
|
1673
|
-
}, [videoId, playerRef.current, setPlayState, setMetadata, setVolumeState, setLoaded]);
|
|
1544
|
+
}
|
|
1545
|
+
playerRef.current = player;
|
|
1546
|
+
playerElementRef.current = element;
|
|
1547
|
+
}, [apiLoaded, videoId, elementHasChanged, setPlayState, setReady, setMetadata, destroyPlayer]);
|
|
1674
1548
|
const {
|
|
1675
1549
|
playing
|
|
1676
1550
|
} = playState;
|
|
@@ -1694,13 +1568,12 @@ const useVimeoPlayer = function (id) {
|
|
|
1694
1568
|
setLoop,
|
|
1695
1569
|
ready,
|
|
1696
1570
|
currentTime,
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
volume,
|
|
1571
|
+
muted,
|
|
1572
|
+
loaded: ready,
|
|
1700
1573
|
...metadata,
|
|
1701
1574
|
...playState
|
|
1702
1575
|
};
|
|
1703
|
-
}
|
|
1576
|
+
}
|
|
1704
1577
|
|
|
1705
1578
|
function useVideoPlayer(params) {
|
|
1706
1579
|
const {
|
|
@@ -1720,7 +1593,6 @@ function useVideoPlayer(params) {
|
|
|
1720
1593
|
const vimeoPlayer = useVimeoPlayer(service === 'vimeo' ? videoId || url : null, params);
|
|
1721
1594
|
const nativePlayer = useNativeVideoPlayer(url, params);
|
|
1722
1595
|
let player = null;
|
|
1723
|
-
|
|
1724
1596
|
if (service === 'dailymotion') {
|
|
1725
1597
|
player = dailymotionPlayer;
|
|
1726
1598
|
} else if (service === 'youtube') {
|
|
@@ -1730,7 +1602,6 @@ function useVideoPlayer(params) {
|
|
|
1730
1602
|
} else {
|
|
1731
1603
|
player = nativePlayer;
|
|
1732
1604
|
}
|
|
1733
|
-
|
|
1734
1605
|
const {
|
|
1735
1606
|
playing = false,
|
|
1736
1607
|
paused = false,
|
|
@@ -1770,7 +1641,6 @@ function useVideoPlayer(params) {
|
|
|
1770
1641
|
}, [ended, customOnEnd]);
|
|
1771
1642
|
useEffect(() => {
|
|
1772
1643
|
const hasMetadata = metaWidth !== null || metaHeight !== null || metaDuration !== null;
|
|
1773
|
-
|
|
1774
1644
|
if (hasMetadata && customOnMetadataChange !== null) {
|
|
1775
1645
|
customOnMetadataChange({
|
|
1776
1646
|
width: metaWidth,
|
|
@@ -1786,10 +1656,8 @@ const getWindowScroll = () => ({
|
|
|
1786
1656
|
x: typeof window !== 'undefined' ? window.scrollX || 0 : 0,
|
|
1787
1657
|
y: typeof window !== 'undefined' ? window.scrollY || 0 : 0
|
|
1788
1658
|
});
|
|
1789
|
-
|
|
1790
1659
|
const currentScroll = getWindowScroll();
|
|
1791
|
-
|
|
1792
|
-
const useWindowScroll = function () {
|
|
1660
|
+
function useWindowScroll() {
|
|
1793
1661
|
let opts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
1794
1662
|
const {
|
|
1795
1663
|
onChange = null
|
|
@@ -1797,19 +1665,16 @@ const useWindowScroll = function () {
|
|
|
1797
1665
|
const [scroll, setScroll] = useState(currentScroll);
|
|
1798
1666
|
const updateScroll = useCallback(() => {
|
|
1799
1667
|
const newScroll = getWindowScroll();
|
|
1800
|
-
|
|
1801
1668
|
if (currentScroll.x !== newScroll.x || currentScroll.y !== newScroll.y) {
|
|
1802
1669
|
currentScroll.x = newScroll.x;
|
|
1803
1670
|
currentScroll.y = newScroll.y;
|
|
1804
1671
|
setScroll(newScroll);
|
|
1805
1672
|
return newScroll;
|
|
1806
1673
|
}
|
|
1807
|
-
|
|
1808
1674
|
return null;
|
|
1809
1675
|
}, [setScroll]);
|
|
1810
1676
|
const onScroll = useCallback(() => {
|
|
1811
1677
|
const newScroll = updateScroll();
|
|
1812
|
-
|
|
1813
1678
|
if (newScroll !== null && onChange !== null) {
|
|
1814
1679
|
onChange(newScroll);
|
|
1815
1680
|
}
|
|
@@ -1819,14 +1684,13 @@ const useWindowScroll = function () {
|
|
|
1819
1684
|
onScroll();
|
|
1820
1685
|
}, []);
|
|
1821
1686
|
return scroll;
|
|
1822
|
-
}
|
|
1687
|
+
}
|
|
1823
1688
|
|
|
1824
1689
|
const getWindowSize = () => ({
|
|
1825
1690
|
width: typeof window !== 'undefined' ? window.innerWidth || 0 : 0,
|
|
1826
1691
|
height: typeof window !== 'undefined' ? window.innerHeight || 0 : 0
|
|
1827
1692
|
});
|
|
1828
1693
|
let currentSize = getWindowSize();
|
|
1829
|
-
|
|
1830
1694
|
function useWindowSize() {
|
|
1831
1695
|
let {
|
|
1832
1696
|
onChange = null
|
|
@@ -1834,18 +1698,15 @@ function useWindowSize() {
|
|
|
1834
1698
|
const [size, setSize] = useState(currentSize);
|
|
1835
1699
|
const updateSize = useCallback(() => {
|
|
1836
1700
|
const newSize = getWindowSize();
|
|
1837
|
-
|
|
1838
1701
|
if (currentSize.width !== newSize.width || currentSize.height !== newSize.height) {
|
|
1839
1702
|
currentSize = newSize;
|
|
1840
1703
|
setSize(newSize);
|
|
1841
1704
|
return newSize;
|
|
1842
1705
|
}
|
|
1843
|
-
|
|
1844
1706
|
return null;
|
|
1845
1707
|
}, [setSize]);
|
|
1846
1708
|
const onResize = useCallback(() => {
|
|
1847
1709
|
const newSize = updateSize();
|
|
1848
|
-
|
|
1849
1710
|
if (newSize !== null && onChange !== null) {
|
|
1850
1711
|
onChange(newSize);
|
|
1851
1712
|
}
|