@homecode/ui 5.20.8 → 5.20.10
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/esm/src/components/Gallery/Gallery.js +7 -9
- package/dist/esm/src/components/Popup/Popup.js +3 -3
- package/dist/esm/src/components/VideoPlayer/VideoPlayer.js +22 -7
- package/dist/esm/types/src/components/VideoPlayer/VideoPlayer.d.ts +1 -1
- package/dist/esm/types/src/components/VideoPlayer/VideoPlayer.types.d.ts +1 -0
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
2
|
-
import { Component, createRef, useState, useRef, useLayoutEffect
|
|
2
|
+
import { Component, createRef, useState, useRef, useLayoutEffect } from 'react';
|
|
3
3
|
import { createStore } from 'justorm/react';
|
|
4
4
|
import Time from 'timen';
|
|
5
5
|
import compare from 'compareq';
|
|
@@ -39,13 +39,7 @@ function Arr({ className, size, icon, ...rest }) {
|
|
|
39
39
|
return (jsx(Button, { className: cn(S.arr, className), size: size, variant: "clear", ...rest, children: jsx(Icon, { type: icon, size: size }) }));
|
|
40
40
|
}
|
|
41
41
|
function VideoItem({ src, size, isActive, }) {
|
|
42
|
-
|
|
43
|
-
useEffect(() => {
|
|
44
|
-
if (isActive)
|
|
45
|
-
return;
|
|
46
|
-
wrapRef.current?.querySelector('video')?.pause();
|
|
47
|
-
}, [isActive, src]);
|
|
48
|
-
return (jsx("div", { ref: wrapRef, className: cn(S.item, S.videoItem), children: jsx(VideoPlayer, { src: src, size: size, storageKey: `Gallery:${src}`, className: S.video }) }));
|
|
42
|
+
return (jsx("div", { className: cn(S.item, S.videoItem), children: jsx(VideoPlayer, { src: src, size: size, storageKey: `Gallery:${src}`, isActive: isActive, className: S.video }) }));
|
|
49
43
|
}
|
|
50
44
|
function Item({ src, kind, size, isActive, }) {
|
|
51
45
|
const [loaded, setLoaded] = useState(false);
|
|
@@ -167,6 +161,9 @@ class Gallery extends Component {
|
|
|
167
161
|
}
|
|
168
162
|
};
|
|
169
163
|
onPointerDown = e => {
|
|
164
|
+
// Pointer on a video belongs to the player (seek, play, volume), not swipe.
|
|
165
|
+
if (e.target.closest?.(`.${S.video}`))
|
|
166
|
+
return;
|
|
170
167
|
this.startX = e.pageX;
|
|
171
168
|
};
|
|
172
169
|
onPointerMove = e => {
|
|
@@ -225,6 +222,7 @@ class Gallery extends Component {
|
|
|
225
222
|
const { items, movingDirection, isDragging } = this.store;
|
|
226
223
|
const dirName = DIR_NAME[movingDirection];
|
|
227
224
|
const isSingle = this.isSingle();
|
|
225
|
+
const isVideoActive = items[isSingle ? 0 : 1]?.kind === 'video';
|
|
228
226
|
const props = omit(rest, ['items', 'onChange', 'animation', 'startIndex']);
|
|
229
227
|
const classes = cn(S.root, isSingle && S.single, cover && S.cover, className);
|
|
230
228
|
const innerClasses = cn(S.inner, initialBounce && S.initialBounce, S[dirName]);
|
|
@@ -236,7 +234,7 @@ class Gallery extends Component {
|
|
|
236
234
|
props.onPointerLeave = this.onPointerUp;
|
|
237
235
|
}
|
|
238
236
|
}
|
|
239
|
-
return (jsxs("div", { className: classes, ...props, children: [jsx("div", { className: innerClasses, ref: this.innerRef, children: items.map((item, i) => (jsx(Item, { src: item.src, kind: item.kind, size: size, isActive: isSingle ? i === 0 : i === 1 }, `${i}_${item.src}_${item.kind}`))) }), !isSingle && showArrows && !isDragging && (jsxs(Fragment, { children: [jsx(Arr, { className: S.left, size: size, icon: "chevronLeft", onClick: () => this.move(1) }), jsx(Arr, { className: S.right, size: size, icon: "chevronRight", onClick: () => this.move(-1) })] })), showDots && (jsx(Lazy, { hideSpinner: true, loader: () => import('./Dots/Dots.js'),
|
|
237
|
+
return (jsxs("div", { className: classes, ...props, children: [jsx("div", { className: innerClasses, ref: this.innerRef, children: items.map((item, i) => (jsx(Item, { src: item.src, kind: item.kind, size: size, isActive: isSingle ? i === 0 : i === 1 }, `${i}_${item.src}_${item.kind}`))) }), !isSingle && showArrows && !isDragging && !isVideoActive && (jsxs(Fragment, { children: [jsx(Arr, { className: S.left, size: size, icon: "chevronLeft", onClick: () => this.move(1) }), jsx(Arr, { className: S.right, size: size, icon: "chevronRight", onClick: () => this.move(-1) })] })), showDots && (jsx(Lazy, { hideSpinner: true, loader: () => import('./Dots/Dots.js'),
|
|
240
238
|
// @ts-ignore
|
|
241
239
|
index: this.index % this.props.items.length, count: this.props.items.length }))] }));
|
|
242
240
|
}
|
|
@@ -343,9 +343,9 @@ class Popup extends Component {
|
|
|
343
343
|
}
|
|
344
344
|
return;
|
|
345
345
|
}
|
|
346
|
-
// if scrolling outside this popup - close it
|
|
347
|
-
|
|
348
|
-
|
|
346
|
+
// if scrolling outside this popup - close it. A scroll inside the trigger
|
|
347
|
+
// (a search input scrolling its text while the user types) doesn't move it.
|
|
348
|
+
if (!this.isHoverInside(e.target) && !childs[this.id]?.length) {
|
|
349
349
|
this.close();
|
|
350
350
|
}
|
|
351
351
|
}, 200);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
2
|
-
import { useRef,
|
|
2
|
+
import { useRef, useId, useState, useMemo, useCallback, useEffect } from 'react';
|
|
3
3
|
import cn from 'classnames';
|
|
4
4
|
import { Button } from '../Button/Button.js';
|
|
5
5
|
import { Icon } from '../Icon/Icon.js';
|
|
@@ -12,7 +12,7 @@ import S from './VideoPlayer.styl.js';
|
|
|
12
12
|
import { TIME_PERSIST_DEBOUNCE_MS, saveStorage, formatTime, VOLUME_POPUP_HIDE_MS, clamp, leadingDebounce, isEditableTarget, loadStorage, getBufferedPercent, DOUBLE_TAP_MS, getStorageKey, timeToProgressPct, KEYBOARD_DEBOUNCE_MS, getSeekDelta, VOLUME_STEP } from './VideoPlayer.helpers.js';
|
|
13
13
|
|
|
14
14
|
let activePlayerId = null;
|
|
15
|
-
function VideoPlayer({ src, poster, storageKey, size = 'm', autoPlay = false, muted = false, loop = false, className, onPlayChange, onTimeUpdate, }) {
|
|
15
|
+
function VideoPlayer({ src, poster, storageKey, size = 'm', autoPlay = false, muted = false, loop = false, isActive = true, className, onPlayChange, onTimeUpdate, }) {
|
|
16
16
|
const rootRef = useRef(null);
|
|
17
17
|
const videoRef = useRef(null);
|
|
18
18
|
const barRef = useRef(null);
|
|
@@ -25,7 +25,10 @@ function VideoPlayer({ src, poster, storageKey, size = 'm', autoPlay = false, mu
|
|
|
25
25
|
const volumeHideTimerRef = useRef(0);
|
|
26
26
|
const lastTapRef = useRef(0);
|
|
27
27
|
const singleClickTimerRef = useRef(0);
|
|
28
|
-
const
|
|
28
|
+
const isActiveRef = useRef(isActive);
|
|
29
|
+
isActiveRef.current = isActive;
|
|
30
|
+
// Per-instance id: two players may share a src/storageKey (e.g. Gallery slots).
|
|
31
|
+
const playerId = useId();
|
|
29
32
|
const lsKey = getStorageKey(src, storageKey);
|
|
30
33
|
const [isReady, setIsReady] = useState(false);
|
|
31
34
|
const [isPlaying, setIsPlaying] = useState(false);
|
|
@@ -56,8 +59,9 @@ function VideoPlayer({ src, poster, storageKey, size = 'm', autoPlay = false, mu
|
|
|
56
59
|
label.textContent = formatTime(time);
|
|
57
60
|
}, []);
|
|
58
61
|
const claimKeyboard = useCallback(() => {
|
|
59
|
-
|
|
60
|
-
|
|
62
|
+
if (isActive)
|
|
63
|
+
activePlayerId = playerId;
|
|
64
|
+
}, [playerId, isActive]);
|
|
61
65
|
const clearVolumeHideTimer = useCallback(() => {
|
|
62
66
|
window.clearTimeout(volumeHideTimerRef.current);
|
|
63
67
|
}, []);
|
|
@@ -157,7 +161,7 @@ function VideoPlayer({ src, poster, storageKey, size = 'm', autoPlay = false, mu
|
|
|
157
161
|
const debouncedVolumeUp = useMemo(() => leadingDebounce(() => applyVolume(volumeRef.current + VOLUME_STEP, { flashPopup: true }), KEYBOARD_DEBOUNCE_MS), [applyVolume]);
|
|
158
162
|
const debouncedVolumeDown = useMemo(() => leadingDebounce(() => applyVolume(volumeRef.current - VOLUME_STEP, { flashPopup: true }), KEYBOARD_DEBOUNCE_MS), [applyVolume]);
|
|
159
163
|
const onKeyDown = useCallback((e) => {
|
|
160
|
-
if (activePlayerId !== playerId)
|
|
164
|
+
if (!isActive || activePlayerId !== playerId)
|
|
161
165
|
return;
|
|
162
166
|
if (isEditableTarget(e.target))
|
|
163
167
|
return;
|
|
@@ -184,6 +188,7 @@ function VideoPlayer({ src, poster, storageKey, size = 'm', autoPlay = false, mu
|
|
|
184
188
|
break;
|
|
185
189
|
}
|
|
186
190
|
}, [
|
|
191
|
+
isActive,
|
|
187
192
|
playerId,
|
|
188
193
|
togglePlay,
|
|
189
194
|
debouncedSeekLeft,
|
|
@@ -196,6 +201,15 @@ function VideoPlayer({ src, poster, storageKey, size = 'm', autoPlay = false, mu
|
|
|
196
201
|
callback: onKeyDown,
|
|
197
202
|
isActive: true,
|
|
198
203
|
});
|
|
204
|
+
useEffect(() => {
|
|
205
|
+
if (isActive) {
|
|
206
|
+
activePlayerId = playerId;
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
if (activePlayerId === playerId)
|
|
210
|
+
activePlayerId = null;
|
|
211
|
+
videoRef.current?.pause();
|
|
212
|
+
}, [isActive, playerId]);
|
|
199
213
|
useEffect(() => {
|
|
200
214
|
const onFullscreenChange = () => {
|
|
201
215
|
setIsFullscreen(document.fullscreenElement === rootRef.current);
|
|
@@ -242,7 +256,8 @@ function VideoPlayer({ src, poster, storageKey, size = 'm', autoPlay = false, mu
|
|
|
242
256
|
setLoadProgress(0);
|
|
243
257
|
setDuration(0);
|
|
244
258
|
durationRef.current = 0;
|
|
245
|
-
|
|
259
|
+
if (isActiveRef.current)
|
|
260
|
+
activePlayerId = playerId;
|
|
246
261
|
syncProgressDom(0);
|
|
247
262
|
const stored = loadStorage(lsKey);
|
|
248
263
|
if (typeof stored.volume === 'number') {
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import * as T from './VideoPlayer.types';
|
|
2
2
|
export type VideoPlayerProps = T.Props;
|
|
3
|
-
export declare function VideoPlayer({ src, poster, storageKey, size, autoPlay, muted, loop, className, onPlayChange, onTimeUpdate, }: T.Props): import("react").JSX.Element;
|
|
3
|
+
export declare function VideoPlayer({ src, poster, storageKey, size, autoPlay, muted, loop, isActive, className, onPlayChange, onTimeUpdate, }: T.Props): import("react").JSX.Element;
|