@stream-io/video-react-sdk 1.37.7 → 1.39.0
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/CHANGELOG.md +4409 -0
- package/dist/css/embedded.css +1 -0
- package/dist/css/embedded.css.map +1 -1
- package/dist/css/styles.css +1 -0
- package/dist/css/styles.css.map +1 -1
- package/dist/embedded.cjs.js +60 -39
- package/dist/embedded.cjs.js.map +1 -1
- package/dist/embedded.es.js +62 -41
- package/dist/embedded.es.js.map +1 -1
- package/dist/index.cjs.js +60 -40
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.es.js +62 -42
- package/dist/index.es.js.map +1 -1
- package/dist/src/components/CallParticipantsList/CallParticipantListingItem.d.ts +1 -1
- package/dist/src/core/components/Audio/Audio.d.ts +1 -4
- package/dist/src/core/components/ParticipantView/ParticipantView.d.ts +1 -1
- package/dist/src/translations/index.d.ts +1 -0
- package/package.json +9 -7
- package/src/components/CallParticipantsList/CallParticipantListingItem.tsx +50 -46
- package/src/components/CallParticipantsList/CallParticipantsList.tsx +17 -6
- package/src/components/DeviceSettings/AudioVolumeIndicator.tsx +8 -4
- package/src/components/Search/SearchInput.tsx +4 -2
- package/src/core/components/Audio/Audio.tsx +4 -4
- package/src/core/components/ParticipantView/DefaultParticipantViewUI.tsx +8 -0
- package/src/core/components/ParticipantView/ParticipantView.tsx +4 -3
- package/src/core/components/Video/BaseVideo.tsx +3 -1
- package/src/core/components/Video/Video.tsx +5 -2
- package/src/embedded/hooks/useWakeLock.ts +1 -0
- package/src/embedded/livestream/viewer/ViewerLobby.tsx +5 -6
- package/src/hooks/useDragToScroll.ts +9 -4
- package/src/hooks/useScrollPosition.ts +2 -2
- package/src/translations/en.json +1 -0
- package/src/wrappers/LivestreamPlayer/LivestreamPlayer.tsx +5 -6
package/dist/embedded.cjs.js
CHANGED
|
@@ -7,7 +7,7 @@ var videoClient = require('@stream-io/video-client');
|
|
|
7
7
|
var react$1 = require('@floating-ui/react');
|
|
8
8
|
var clsx = require('clsx');
|
|
9
9
|
|
|
10
|
-
const Audio = ({ participant, trackType = 'audioTrack', ...rest })
|
|
10
|
+
const Audio = react.memo(function Audio({ participant, trackType = 'audioTrack', ...rest }) {
|
|
11
11
|
const call = videoReactBindings.useCall();
|
|
12
12
|
const [audioElement, setAudioElement] = react.useState(null);
|
|
13
13
|
const { userId, sessionId } = participant;
|
|
@@ -20,7 +20,7 @@ const Audio = ({ participant, trackType = 'audioTrack', ...rest }) => {
|
|
|
20
20
|
};
|
|
21
21
|
}, [call, sessionId, audioElement, trackType]);
|
|
22
22
|
return (jsxRuntime.jsx("audio", { autoPlay: true, ...rest, ref: setAudioElement, "data-user-id": userId, "data-session-id": sessionId, "data-track-type": trackType }));
|
|
23
|
-
};
|
|
23
|
+
});
|
|
24
24
|
Audio.displayName = 'Audio';
|
|
25
25
|
|
|
26
26
|
const ParticipantsAudio = (props) => {
|
|
@@ -96,7 +96,7 @@ const useVerticalScrollPosition = (scrollElement, threshold = SCROLL_THRESHOLD)
|
|
|
96
96
|
};
|
|
97
97
|
const resizeObserver = new ResizeObserver(scrollHandler);
|
|
98
98
|
resizeObserver.observe(scrollElement);
|
|
99
|
-
scrollElement.addEventListener('scroll', scrollHandler);
|
|
99
|
+
scrollElement.addEventListener('scroll', scrollHandler, { passive: true });
|
|
100
100
|
return () => {
|
|
101
101
|
scrollElement.removeEventListener('scroll', scrollHandler);
|
|
102
102
|
resizeObserver.disconnect();
|
|
@@ -124,7 +124,7 @@ const useHorizontalScrollPosition = (scrollElement, threshold = SCROLL_THRESHOLD
|
|
|
124
124
|
};
|
|
125
125
|
const resizeObserver = new ResizeObserver(scrollHandler);
|
|
126
126
|
resizeObserver.observe(scrollElement);
|
|
127
|
-
scrollElement.addEventListener('scroll', scrollHandler);
|
|
127
|
+
scrollElement.addEventListener('scroll', scrollHandler, { passive: true });
|
|
128
128
|
return () => {
|
|
129
129
|
scrollElement.removeEventListener('scroll', scrollHandler);
|
|
130
130
|
resizeObserver.disconnect();
|
|
@@ -215,6 +215,7 @@ function useDeviceList(devices, selectedDeviceId) {
|
|
|
215
215
|
* @param options - Options for customizing the drag-to-scroll behavior.
|
|
216
216
|
*/
|
|
217
217
|
function useDragToScroll(element, options = {}) {
|
|
218
|
+
const { enabled, decay = 0.95, minVelocity = 0.5, dragThreshold = 5, } = options;
|
|
218
219
|
const stateRef = react.useRef({
|
|
219
220
|
isDragging: false,
|
|
220
221
|
isPointerActive: false,
|
|
@@ -227,9 +228,8 @@ function useDragToScroll(element, options = {}) {
|
|
|
227
228
|
startY: 0,
|
|
228
229
|
});
|
|
229
230
|
react.useEffect(() => {
|
|
230
|
-
if (!element || !
|
|
231
|
+
if (!element || !enabled)
|
|
231
232
|
return;
|
|
232
|
-
const { decay = 0.95, minVelocity = 0.5, dragThreshold = 5 } = options;
|
|
233
233
|
const state = stateRef.current;
|
|
234
234
|
const stopMomentum = () => {
|
|
235
235
|
if (state.rafId) {
|
|
@@ -313,7 +313,7 @@ function useDragToScroll(element, options = {}) {
|
|
|
313
313
|
window.removeEventListener('pointercancel', onPointerUpOrCancel);
|
|
314
314
|
stopMomentum();
|
|
315
315
|
};
|
|
316
|
-
}, [element,
|
|
316
|
+
}, [element, enabled, decay, minVelocity, dragThreshold]);
|
|
317
317
|
}
|
|
318
318
|
|
|
319
319
|
var MenuVisualType;
|
|
@@ -543,9 +543,10 @@ const BaseVideo = react.forwardRef(function BaseVideo({ stream, ...rest }, ref)
|
|
|
543
543
|
if (stream === videoElement.srcObject)
|
|
544
544
|
return;
|
|
545
545
|
videoElement.srcObject = stream;
|
|
546
|
+
let timeoutId;
|
|
546
547
|
if (videoClient.Browsers.isSafari() || videoClient.Browsers.isFirefox()) {
|
|
547
548
|
// Firefox and Safari have some timing issue
|
|
548
|
-
setTimeout(() => {
|
|
549
|
+
timeoutId = setTimeout(() => {
|
|
549
550
|
videoElement.srcObject = stream;
|
|
550
551
|
videoElement.play().catch((e) => {
|
|
551
552
|
console.error(`Failed to play stream`, e);
|
|
@@ -553,6 +554,7 @@ const BaseVideo = react.forwardRef(function BaseVideo({ stream, ...rest }, ref)
|
|
|
553
554
|
}, 0);
|
|
554
555
|
}
|
|
555
556
|
return () => {
|
|
557
|
+
clearTimeout(timeoutId);
|
|
556
558
|
videoElement.pause();
|
|
557
559
|
videoElement.srcObject = null;
|
|
558
560
|
};
|
|
@@ -589,6 +591,7 @@ const DefaultPictureInPicturePlaceholder = react.forwardRef(function DefaultPict
|
|
|
589
591
|
return (jsxRuntime.jsx(BaseVideoPlaceholder, { ref: ref, ...props, children: t('Video is playing in a popup') }));
|
|
590
592
|
});
|
|
591
593
|
|
|
594
|
+
const ABSOLUTE_POSITION_STYLE = { position: 'absolute' };
|
|
592
595
|
const Video$1 = ({ enabled = true, mirror, trackType, participant, className, VideoPlaceholder = DefaultVideoPlaceholder, PictureInPicturePlaceholder = DefaultPictureInPicturePlaceholder, refs, ...rest }) => {
|
|
593
596
|
const { sessionId, videoStream, screenShareStream, viewportVisibilityState, isLocalParticipant, userId, } = participant;
|
|
594
597
|
const call = videoReactBindings.useCall();
|
|
@@ -661,7 +664,7 @@ const Video$1 = ({ enabled = true, mirror, trackType, participant, className, Vi
|
|
|
661
664
|
}), "data-user-id": userId, "data-session-id": sessionId, ref: (element) => {
|
|
662
665
|
setVideoElement(element);
|
|
663
666
|
refs?.setVideoElement?.(element);
|
|
664
|
-
} })), isPiP && PictureInPicturePlaceholder && (jsxRuntime.jsx(PictureInPicturePlaceholder, { style:
|
|
667
|
+
} })), isPiP && PictureInPicturePlaceholder && (jsxRuntime.jsx(PictureInPicturePlaceholder, { style: ABSOLUTE_POSITION_STYLE, participant: participant })), (hasNoVideoOrInvisible || isVideoPaused) && VideoPlaceholder && (jsxRuntime.jsx(VideoPlaceholder, { style: ABSOLUTE_POSITION_STYLE, participant: participant, ref: refs?.setVideoPlaceholderElement }))] }));
|
|
665
668
|
};
|
|
666
669
|
Video$1.displayName = 'Video';
|
|
667
670
|
|
|
@@ -1020,16 +1023,20 @@ const ScreenShareButton = (props) => {
|
|
|
1020
1023
|
const AudioVolumeIndicator = () => {
|
|
1021
1024
|
const { useMicrophoneState } = videoReactBindings.useCallStateHooks();
|
|
1022
1025
|
const { isEnabled, mediaStream } = useMicrophoneState();
|
|
1023
|
-
const
|
|
1026
|
+
const barRef = react.useRef(null);
|
|
1024
1027
|
react.useEffect(() => {
|
|
1025
1028
|
if (!isEnabled || !mediaStream)
|
|
1026
1029
|
return;
|
|
1027
|
-
const disposeSoundDetector = videoClient.createSoundDetector(mediaStream, ({ audioLevel: al }) =>
|
|
1030
|
+
const disposeSoundDetector = videoClient.createSoundDetector(mediaStream, ({ audioLevel: al }) => {
|
|
1031
|
+
if (barRef.current) {
|
|
1032
|
+
barRef.current.style.transform = `scaleX(${al / 100})`;
|
|
1033
|
+
}
|
|
1034
|
+
}, { detectionFrequencyInMs: 80, destroyStreamOnStop: false });
|
|
1028
1035
|
return () => {
|
|
1029
1036
|
disposeSoundDetector().catch(console.error);
|
|
1030
1037
|
};
|
|
1031
1038
|
}, [isEnabled, mediaStream]);
|
|
1032
|
-
return (jsxRuntime.jsxs("div", { className: "str-video__audio-volume-indicator", children: [jsxRuntime.jsx(Icon, { icon: isEnabled ? 'mic' : 'mic-off' }), jsxRuntime.jsx("div", { className: "str-video__audio-volume-indicator__bar", children: jsxRuntime.jsx("div", { className: "str-video__audio-volume-indicator__bar-value"
|
|
1039
|
+
return (jsxRuntime.jsxs("div", { className: "str-video__audio-volume-indicator", children: [jsxRuntime.jsx(Icon, { icon: isEnabled ? 'mic' : 'mic-off' }), jsxRuntime.jsx("div", { className: "str-video__audio-volume-indicator__bar", children: jsxRuntime.jsx("div", { ref: barRef, className: "str-video__audio-volume-indicator__bar-value" }) })] }));
|
|
1033
1040
|
};
|
|
1034
1041
|
|
|
1035
1042
|
const LEVEL_BARS = 5;
|
|
@@ -1203,7 +1210,7 @@ const SpeakerTest = (props) => {
|
|
|
1203
1210
|
const audioElementRef = react.useRef(null);
|
|
1204
1211
|
const [isPlaying, setIsPlaying] = react.useState(false);
|
|
1205
1212
|
const { t } = videoReactBindings.useI18n();
|
|
1206
|
-
const { audioUrl = `https://unpkg.com/${"@stream-io/video-react-sdk"}@${"1.
|
|
1213
|
+
const { audioUrl = `https://unpkg.com/${"@stream-io/video-react-sdk"}@${"1.39.0"}/assets/piano.mp3`, } = props;
|
|
1207
1214
|
// Update audio output device when selection changes
|
|
1208
1215
|
react.useEffect(() => {
|
|
1209
1216
|
const audio = audioElementRef.current;
|
|
@@ -1502,13 +1509,14 @@ const CallParticipantListHeader = ({ onClose, }) => {
|
|
|
1502
1509
|
return (jsxRuntime.jsxs("div", { className: "str-video__participant-list-header", children: [jsxRuntime.jsxs("div", { className: "str-video__participant-list-header__title", children: [t('Participants'), ' ', jsxRuntime.jsxs("span", { className: "str-video__participant-list-header__title-count", children: ["[", participants.length, "]"] }), anonymousParticipantCount > 0 && (jsxRuntime.jsx("span", { className: "str-video__participant-list-header__title-anonymous", children: t('Anonymous', { count: anonymousParticipantCount }) }))] }), jsxRuntime.jsx(IconButton, { onClick: onClose, className: "str-video__participant-list-header__close-button", icon: "close" })] }));
|
|
1503
1510
|
};
|
|
1504
1511
|
|
|
1505
|
-
const CallParticipantListingItem = ({ participant, DisplayName = DefaultDisplayName, })
|
|
1512
|
+
const CallParticipantListingItem = react.memo(function CallParticipantListingItem({ participant, DisplayName = DefaultDisplayName, }) {
|
|
1506
1513
|
const isAudioOn = videoClient.hasAudio(participant);
|
|
1507
1514
|
const isVideoOn = videoClient.hasVideo(participant);
|
|
1508
1515
|
const isPinnedOn = videoClient.isPinned(participant);
|
|
1509
1516
|
const { t } = videoReactBindings.useI18n();
|
|
1510
1517
|
return (jsxRuntime.jsxs("div", { className: "str-video__participant-listing-item", children: [jsxRuntime.jsx(Avatar, { name: participant.name, imageSrc: participant.image }), jsxRuntime.jsx(DisplayName, { participant: participant }), jsxRuntime.jsxs("div", { className: "str-video__participant-listing-item__media-indicator-group", children: [jsxRuntime.jsx(MediaIndicator, { title: isAudioOn ? t('Microphone on') : t('Microphone off'), className: clsx('str-video__participant-listing-item__icon', `str-video__participant-listing-item__icon-${isAudioOn ? 'mic' : 'mic-off'}`) }), jsxRuntime.jsx(MediaIndicator, { title: isVideoOn ? t('Camera on') : t('Camera off'), className: clsx('str-video__participant-listing-item__icon', `str-video__participant-listing-item__icon-${isVideoOn ? 'camera' : 'camera-off'}`) }), isPinnedOn && (jsxRuntime.jsx(MediaIndicator, { title: t('Pinned'), className: clsx('str-video__participant-listing-item__icon', 'str-video__participant-listing-item__icon-pinned') })), jsxRuntime.jsx(MenuToggle, { placement: "bottom-end", ToggleButton: ToggleButton$2, children: jsxRuntime.jsx(ParticipantViewContext.Provider, { value: { participant, trackType: 'none' }, children: jsxRuntime.jsx(ParticipantActionsContextMenu, {}) }) })] })] }));
|
|
1511
|
-
};
|
|
1518
|
+
});
|
|
1519
|
+
CallParticipantListingItem.displayName = 'CallParticipantListingItem';
|
|
1512
1520
|
const MediaIndicator = (props) => (jsxRuntime.jsx(WithTooltip, { ...props }));
|
|
1513
1521
|
const DefaultDisplayName = ({ participant }) => {
|
|
1514
1522
|
const connectedUser = videoReactBindings.useConnectedUser();
|
|
@@ -1540,18 +1548,19 @@ const EmptyParticipantSearchList = () => {
|
|
|
1540
1548
|
|
|
1541
1549
|
const SearchInput = ({ exitSearch, isActive, ...rest }) => {
|
|
1542
1550
|
const [inputElement, setInputElement] = react.useState(null);
|
|
1551
|
+
const onExitSearch = videoReactBindings.useEffectEvent(exitSearch);
|
|
1543
1552
|
react.useEffect(() => {
|
|
1544
1553
|
if (!inputElement)
|
|
1545
1554
|
return;
|
|
1546
1555
|
const handleKeyDown = (e) => {
|
|
1547
1556
|
if (e.key.toLowerCase() === 'escape')
|
|
1548
|
-
|
|
1557
|
+
onExitSearch();
|
|
1549
1558
|
};
|
|
1550
1559
|
inputElement.addEventListener('keydown', handleKeyDown);
|
|
1551
1560
|
return () => {
|
|
1552
1561
|
inputElement.removeEventListener('keydown', handleKeyDown);
|
|
1553
1562
|
};
|
|
1554
|
-
}, [
|
|
1563
|
+
}, [inputElement]);
|
|
1555
1564
|
return (jsxRuntime.jsxs("div", { className: clsx('str-video__search-input__container', {
|
|
1556
1565
|
'str-video__search-input__container--active': isActive,
|
|
1557
1566
|
}), children: [jsxRuntime.jsx("input", { placeholder: "Search", ...rest, ref: setInputElement }), isActive ? (jsxRuntime.jsx("button", { className: "str-video__search-input__clear-btn", onClick: exitSearch, children: jsxRuntime.jsx("span", { className: "str-video__search-input__icon--active" }) })) : (jsxRuntime.jsx("span", { className: "str-video__search-input__icon" }))] }));
|
|
@@ -1622,10 +1631,19 @@ const CallParticipantListContentHeader = ({ userListType, setUserListType, }) =>
|
|
|
1622
1631
|
const ActiveUsersSearchResults = ({ searchQuery, activeUsersSearchFn: activeUsersSearchFnFromProps, debounceSearchInterval, }) => {
|
|
1623
1632
|
const { useParticipants } = videoReactBindings.useCallStateHooks();
|
|
1624
1633
|
const participants = useParticipants({ sortBy: videoClient.name });
|
|
1634
|
+
// cache: each distinct name is normalized once
|
|
1635
|
+
const normalizedNameCache = react.useRef(null);
|
|
1625
1636
|
const activeUsersSearchFn = react.useCallback(async (queryString) => {
|
|
1626
1637
|
const normalizedQuery = normalizeString(queryString);
|
|
1627
|
-
const
|
|
1628
|
-
return participants.filter((p) =>
|
|
1638
|
+
const cache = (normalizedNameCache.current ??= new Map());
|
|
1639
|
+
return participants.filter((p) => {
|
|
1640
|
+
let normalizedName = cache.get(p.name);
|
|
1641
|
+
if (normalizedName === undefined) {
|
|
1642
|
+
normalizedName = normalizeString(p.name);
|
|
1643
|
+
cache.set(p.name, normalizedName);
|
|
1644
|
+
}
|
|
1645
|
+
return normalizedName.includes(normalizedQuery);
|
|
1646
|
+
});
|
|
1629
1647
|
}, [participants]);
|
|
1630
1648
|
const { searchQueryInProgress, searchResults } = useSearch({
|
|
1631
1649
|
searchFn: activeUsersSearchFnFromProps ?? activeUsersSearchFn,
|
|
@@ -1638,8 +1656,8 @@ const BlockedUsersSearchResults = ({ blockedUsersSearchFn: blockedUsersSearchFnF
|
|
|
1638
1656
|
const { useCallBlockedUserIds } = videoReactBindings.useCallStateHooks();
|
|
1639
1657
|
const blockedUsers = useCallBlockedUserIds();
|
|
1640
1658
|
const blockedUsersSearchFn = react.useCallback(async (queryString) => {
|
|
1641
|
-
const
|
|
1642
|
-
return blockedUsers.filter((userId) => userId.
|
|
1659
|
+
const normalizedQuery = queryString.toLowerCase();
|
|
1660
|
+
return blockedUsers.filter((userId) => userId.toLowerCase().includes(normalizedQuery));
|
|
1643
1661
|
}, [blockedUsers]);
|
|
1644
1662
|
const { searchQueryInProgress, searchResults } = useSearch({
|
|
1645
1663
|
searchFn: blockedUsersSearchFnFromProps ?? blockedUsersSearchFn,
|
|
@@ -1900,7 +1918,8 @@ const ParticipantDetails = ({ indicatorsVisible = true, }) => {
|
|
|
1900
1918
|
const canUnpin = !!pin && pin.isLocalPin;
|
|
1901
1919
|
const isTrackPaused = trackType !== 'none' ? videoClient.hasPausedTrack(participant, trackType) : false;
|
|
1902
1920
|
const isAudioConnecting = videoReactBindings.useIsAudioConnecting(participant);
|
|
1903
|
-
|
|
1921
|
+
const isVideoConnecting = videoReactBindings.useIsVideoConnecting(participant);
|
|
1922
|
+
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("div", { className: "str-video__participant-details", children: jsxRuntime.jsxs("div", { className: "str-video__participant-details__name", children: [name || userId, indicatorsVisible && isAudioConnecting && (jsxRuntime.jsx(LoadingIndicator, { className: "str-video__participant-details__name--audio-connecting", tooltip: t('Audio is connecting...') })), indicatorsVisible && !hasAudioTrack && (jsxRuntime.jsx("span", { className: "str-video__participant-details__name--audio-muted" })), indicatorsVisible && isVideoConnecting && (jsxRuntime.jsx(LoadingIndicator, { className: "str-video__participant-details__name--video-connecting", tooltip: t('Video is connecting...') })), indicatorsVisible && !hasVideoTrack && (jsxRuntime.jsx("span", { className: "str-video__participant-details__name--video-muted" })), indicatorsVisible && isTrackPaused && (jsxRuntime.jsx("span", { title: t('Video paused due to insufficient bandwidth'), className: "str-video__participant-details__name--track-paused" })), indicatorsVisible && pin && (jsxRuntime.jsx("span", { title: canUnpin ? t('Unpin') : t('Pinned'), onClick: canUnpin ? () => call?.unpin(sessionId) : undefined, className: "str-video__participant-details__name--pinned" })), indicatorsVisible && jsxRuntime.jsx(SpeechIndicator, {})] }) }), indicatorsVisible && (jsxRuntime.jsx(Notification, { isVisible: isLocalParticipant &&
|
|
1904
1923
|
connectionQuality === videoClient.SfuModels.ConnectionQuality.POOR, message: t('Poor connection quality'), children: connectionQualityAsString && (jsxRuntime.jsx("span", { className: clsx('str-video__participant-details__connection-quality', `str-video__participant-details__connection-quality--${connectionQualityAsString}`), title: connectionQualityAsString })) }))] }));
|
|
1905
1924
|
};
|
|
1906
1925
|
const SpeechIndicator = () => {
|
|
@@ -1909,7 +1928,7 @@ const SpeechIndicator = () => {
|
|
|
1909
1928
|
return (jsxRuntime.jsxs("span", { className: clsx('str-video__speech-indicator', isSpeaking && 'str-video__speech-indicator--speaking', isDominantSpeaker && 'str-video__speech-indicator--dominant'), children: [jsxRuntime.jsx("span", { className: "str-video__speech-indicator__bar" }), jsxRuntime.jsx("span", { className: "str-video__speech-indicator__bar" }), jsxRuntime.jsx("span", { className: "str-video__speech-indicator__bar" })] }));
|
|
1910
1929
|
};
|
|
1911
1930
|
|
|
1912
|
-
const ParticipantView = react.forwardRef(function ParticipantView({ participant, trackType = 'videoTrack', mirror, muteAudio, refs: { setVideoElement, setVideoPlaceholderElement } = {}, className, VideoPlaceholder, PictureInPicturePlaceholder, ParticipantViewUI = DefaultParticipantViewUI, }, ref) {
|
|
1931
|
+
const ParticipantView = react.memo(react.forwardRef(function ParticipantView({ participant, trackType = 'videoTrack', mirror, muteAudio, refs: { setVideoElement, setVideoPlaceholderElement } = {}, className, VideoPlaceholder, PictureInPicturePlaceholder, ParticipantViewUI = DefaultParticipantViewUI, }, ref) {
|
|
1913
1932
|
const { isLocalParticipant, isSpeaking, isDominantSpeaker, sessionId } = participant;
|
|
1914
1933
|
const hasAudioTrack = videoClient.hasAudio(participant);
|
|
1915
1934
|
const hasVideoTrack = videoClient.hasVideo(participant);
|
|
@@ -1953,7 +1972,7 @@ const ParticipantView = react.forwardRef(function ParticipantView({ participant,
|
|
|
1953
1972
|
}, className: clsx('str-video__participant-view', isDominantSpeaker && 'str-video__participant-view--dominant-speaker', isSpeaking && 'str-video__participant-view--speaking', !hasVideoTrack && 'str-video__participant-view--no-video', !hasAudioTrack && 'str-video__participant-view--no-audio', className), children: jsxRuntime.jsxs(ParticipantViewContext.Provider, { value: participantViewContextValue, children: [!isLocalParticipant && !muteAudio && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [hasAudioTrack && (jsxRuntime.jsx(Audio, { participant: participant, trackType: "audioTrack" })), hasScreenShareAudioTrack && (jsxRuntime.jsx(Audio, { participant: participant, trackType: "screenShareAudioTrack" }))] })), jsxRuntime.jsx(Video$1, { VideoPlaceholder: VideoPlaceholder, PictureInPicturePlaceholder: PictureInPicturePlaceholder, participant: participant, trackType: trackType, refs: videoRefs, enabled: isLocalParticipant ||
|
|
1954
1973
|
trackType !== 'videoTrack' ||
|
|
1955
1974
|
isParticipantVideoEnabled(participant.sessionId), mirror: mirror, autoPlay: true }), isComponentType(ParticipantViewUI) ? (jsxRuntime.jsx(ParticipantViewUI, {})) : (ParticipantViewUI)] }) }));
|
|
1956
|
-
});
|
|
1975
|
+
}));
|
|
1957
1976
|
ParticipantView.displayName = 'ParticipantView';
|
|
1958
1977
|
|
|
1959
1978
|
// re-exporting the StreamCallProvider as StreamCall
|
|
@@ -2080,6 +2099,7 @@ var en = {
|
|
|
2080
2099
|
"Poor connection quality": "Poor connection quality. Please check your internet connection.",
|
|
2081
2100
|
"Video paused due to insufficient bandwidth": "Video paused due to insufficient bandwidth",
|
|
2082
2101
|
"Audio is connecting...": "Audio is connecting...",
|
|
2102
|
+
"Video is connecting...": "Video is connecting...",
|
|
2083
2103
|
Participants: Participants,
|
|
2084
2104
|
Anonymous: Anonymous,
|
|
2085
2105
|
"No participants found": "No participants found",
|
|
@@ -2170,20 +2190,20 @@ function checkConditions(obj, conditions) {
|
|
|
2170
2190
|
const eqOperatorValue = isDateString(eqOperator.$eq)
|
|
2171
2191
|
? new Date(eqOperator.$eq).getTime()
|
|
2172
2192
|
: eqOperator.$eq;
|
|
2173
|
-
match
|
|
2193
|
+
match &&= eqOperatorValue === value;
|
|
2174
2194
|
}
|
|
2175
2195
|
else if (maybeOperator && '$neq' in operator) {
|
|
2176
2196
|
const neqOperator = operator;
|
|
2177
|
-
match
|
|
2197
|
+
match &&= neqOperator.$neq !== value;
|
|
2178
2198
|
}
|
|
2179
2199
|
else if (maybeOperator && '$in' in operator) {
|
|
2180
2200
|
const inOperator = operator;
|
|
2181
|
-
match
|
|
2201
|
+
match &&= inOperator.$in.includes(value);
|
|
2182
2202
|
}
|
|
2183
2203
|
else if (maybeOperator && '$contains' in operator) {
|
|
2184
2204
|
if (Array.isArray(value)) {
|
|
2185
2205
|
const containsOperator = operator;
|
|
2186
|
-
match
|
|
2206
|
+
match &&= value.includes(containsOperator.$contains);
|
|
2187
2207
|
}
|
|
2188
2208
|
else {
|
|
2189
2209
|
match = false;
|
|
@@ -2194,35 +2214,35 @@ function checkConditions(obj, conditions) {
|
|
|
2194
2214
|
const gtOperatorValue = isDateString(gtOperator.$gt)
|
|
2195
2215
|
? new Date(gtOperator.$gt).getTime()
|
|
2196
2216
|
: gtOperator.$gt;
|
|
2197
|
-
match
|
|
2217
|
+
match &&= value > gtOperatorValue;
|
|
2198
2218
|
}
|
|
2199
2219
|
else if (maybeOperator && '$gte' in operator) {
|
|
2200
2220
|
const gteOperator = operator;
|
|
2201
2221
|
const gteOperatorValue = isDateString(gteOperator.$gte)
|
|
2202
2222
|
? new Date(gteOperator.$gte).getTime()
|
|
2203
2223
|
: gteOperator.$gte;
|
|
2204
|
-
match
|
|
2224
|
+
match &&= value >= gteOperatorValue;
|
|
2205
2225
|
}
|
|
2206
2226
|
else if (maybeOperator && '$lt' in operator) {
|
|
2207
2227
|
const ltOperator = operator;
|
|
2208
2228
|
const ltOperatorValue = isDateString(ltOperator.$lt)
|
|
2209
2229
|
? new Date(ltOperator.$lt).getTime()
|
|
2210
2230
|
: ltOperator.$lt;
|
|
2211
|
-
match
|
|
2231
|
+
match &&= value < ltOperatorValue;
|
|
2212
2232
|
}
|
|
2213
2233
|
else if (maybeOperator && '$lte' in operator) {
|
|
2214
2234
|
const lteOperator = operator;
|
|
2215
2235
|
const lteOperatorValue = isDateString(lteOperator.$lte)
|
|
2216
2236
|
? new Date(lteOperator.$lte).getTime()
|
|
2217
2237
|
: lteOperator.$lte;
|
|
2218
|
-
match
|
|
2238
|
+
match &&= value <= lteOperatorValue;
|
|
2219
2239
|
// } else if (maybeOperator && '$autocomplete' in operator) {
|
|
2220
2240
|
// TODO: regexp solution maybe?
|
|
2221
2241
|
// match &&= false;
|
|
2222
2242
|
}
|
|
2223
2243
|
else {
|
|
2224
2244
|
const eqValue = operator;
|
|
2225
|
-
match
|
|
2245
|
+
match &&= eqValue === value;
|
|
2226
2246
|
}
|
|
2227
2247
|
if (!match) {
|
|
2228
2248
|
return false;
|
|
@@ -3061,6 +3081,7 @@ const useWakeLock = () => {
|
|
|
3061
3081
|
if (interrupted)
|
|
3062
3082
|
return wls.release();
|
|
3063
3083
|
wakeLockSentinel = wls;
|
|
3084
|
+
return undefined;
|
|
3064
3085
|
})
|
|
3065
3086
|
.catch((error) => console.debug(`Couldn't setup WakeLock due to: ${error}`));
|
|
3066
3087
|
return () => {
|
|
@@ -3395,12 +3416,12 @@ const ViewerLobby = ({ onJoin }) => {
|
|
|
3395
3416
|
}
|
|
3396
3417
|
}, [canJoin, autoJoin, onJoin]);
|
|
3397
3418
|
react.useEffect(() => {
|
|
3398
|
-
if (
|
|
3399
|
-
|
|
3400
|
-
|
|
3401
|
-
|
|
3402
|
-
|
|
3403
|
-
|
|
3419
|
+
if (canJoinEarly)
|
|
3420
|
+
return;
|
|
3421
|
+
const handle = setInterval(() => {
|
|
3422
|
+
setCanJoinEarly(checkCanJoinEarly(startsAt, joinAheadTimeSeconds));
|
|
3423
|
+
}, 1000);
|
|
3424
|
+
return () => clearInterval(handle);
|
|
3404
3425
|
}, [canJoinEarly, startsAt, joinAheadTimeSeconds]);
|
|
3405
3426
|
react.useEffect(() => {
|
|
3406
3427
|
if (!startsAt || startsAtPassed)
|