@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/index.cjs.js
CHANGED
|
@@ -7,7 +7,7 @@ var react = require('react');
|
|
|
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) => {
|
|
@@ -108,7 +108,7 @@ const useVerticalScrollPosition = (scrollElement, threshold = SCROLL_THRESHOLD)
|
|
|
108
108
|
};
|
|
109
109
|
const resizeObserver = new ResizeObserver(scrollHandler);
|
|
110
110
|
resizeObserver.observe(scrollElement);
|
|
111
|
-
scrollElement.addEventListener('scroll', scrollHandler);
|
|
111
|
+
scrollElement.addEventListener('scroll', scrollHandler, { passive: true });
|
|
112
112
|
return () => {
|
|
113
113
|
scrollElement.removeEventListener('scroll', scrollHandler);
|
|
114
114
|
resizeObserver.disconnect();
|
|
@@ -136,7 +136,7 @@ const useHorizontalScrollPosition = (scrollElement, threshold = SCROLL_THRESHOLD
|
|
|
136
136
|
};
|
|
137
137
|
const resizeObserver = new ResizeObserver(scrollHandler);
|
|
138
138
|
resizeObserver.observe(scrollElement);
|
|
139
|
-
scrollElement.addEventListener('scroll', scrollHandler);
|
|
139
|
+
scrollElement.addEventListener('scroll', scrollHandler, { passive: true });
|
|
140
140
|
return () => {
|
|
141
141
|
scrollElement.removeEventListener('scroll', scrollHandler);
|
|
142
142
|
resizeObserver.disconnect();
|
|
@@ -357,6 +357,7 @@ const useModeration = (options) => {
|
|
|
357
357
|
* @param options - Options for customizing the drag-to-scroll behavior.
|
|
358
358
|
*/
|
|
359
359
|
function useDragToScroll(element, options = {}) {
|
|
360
|
+
const { enabled, decay = 0.95, minVelocity = 0.5, dragThreshold = 5, } = options;
|
|
360
361
|
const stateRef = react.useRef({
|
|
361
362
|
isDragging: false,
|
|
362
363
|
isPointerActive: false,
|
|
@@ -369,9 +370,8 @@ function useDragToScroll(element, options = {}) {
|
|
|
369
370
|
startY: 0,
|
|
370
371
|
});
|
|
371
372
|
react.useEffect(() => {
|
|
372
|
-
if (!element || !
|
|
373
|
+
if (!element || !enabled)
|
|
373
374
|
return;
|
|
374
|
-
const { decay = 0.95, minVelocity = 0.5, dragThreshold = 5 } = options;
|
|
375
375
|
const state = stateRef.current;
|
|
376
376
|
const stopMomentum = () => {
|
|
377
377
|
if (state.rafId) {
|
|
@@ -455,7 +455,7 @@ function useDragToScroll(element, options = {}) {
|
|
|
455
455
|
window.removeEventListener('pointercancel', onPointerUpOrCancel);
|
|
456
456
|
stopMomentum();
|
|
457
457
|
};
|
|
458
|
-
}, [element,
|
|
458
|
+
}, [element, enabled, decay, minVelocity, dragThreshold]);
|
|
459
459
|
}
|
|
460
460
|
|
|
461
461
|
exports.MenuVisualType = void 0;
|
|
@@ -685,9 +685,10 @@ const BaseVideo = react.forwardRef(function BaseVideo({ stream, ...rest }, ref)
|
|
|
685
685
|
if (stream === videoElement.srcObject)
|
|
686
686
|
return;
|
|
687
687
|
videoElement.srcObject = stream;
|
|
688
|
+
let timeoutId;
|
|
688
689
|
if (videoClient.Browsers.isSafari() || videoClient.Browsers.isFirefox()) {
|
|
689
690
|
// Firefox and Safari have some timing issue
|
|
690
|
-
setTimeout(() => {
|
|
691
|
+
timeoutId = setTimeout(() => {
|
|
691
692
|
videoElement.srcObject = stream;
|
|
692
693
|
videoElement.play().catch((e) => {
|
|
693
694
|
console.error(`Failed to play stream`, e);
|
|
@@ -695,6 +696,7 @@ const BaseVideo = react.forwardRef(function BaseVideo({ stream, ...rest }, ref)
|
|
|
695
696
|
}, 0);
|
|
696
697
|
}
|
|
697
698
|
return () => {
|
|
699
|
+
clearTimeout(timeoutId);
|
|
698
700
|
videoElement.pause();
|
|
699
701
|
videoElement.srcObject = null;
|
|
700
702
|
};
|
|
@@ -731,6 +733,7 @@ const DefaultPictureInPicturePlaceholder = react.forwardRef(function DefaultPict
|
|
|
731
733
|
return (jsxRuntime.jsx(BaseVideoPlaceholder, { ref: ref, ...props, children: t('Video is playing in a popup') }));
|
|
732
734
|
});
|
|
733
735
|
|
|
736
|
+
const ABSOLUTE_POSITION_STYLE = { position: 'absolute' };
|
|
734
737
|
const Video$1 = ({ enabled = true, mirror, trackType, participant, className, VideoPlaceholder = DefaultVideoPlaceholder, PictureInPicturePlaceholder = DefaultPictureInPicturePlaceholder, refs, ...rest }) => {
|
|
735
738
|
const { sessionId, videoStream, screenShareStream, viewportVisibilityState, isLocalParticipant, userId, } = participant;
|
|
736
739
|
const call = videoReactBindings.useCall();
|
|
@@ -803,7 +806,7 @@ const Video$1 = ({ enabled = true, mirror, trackType, participant, className, Vi
|
|
|
803
806
|
}), "data-user-id": userId, "data-session-id": sessionId, ref: (element) => {
|
|
804
807
|
setVideoElement(element);
|
|
805
808
|
refs?.setVideoElement?.(element);
|
|
806
|
-
} })), isPiP && PictureInPicturePlaceholder && (jsxRuntime.jsx(PictureInPicturePlaceholder, { style:
|
|
809
|
+
} })), 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 }))] }));
|
|
807
810
|
};
|
|
808
811
|
Video$1.displayName = 'Video';
|
|
809
812
|
|
|
@@ -1216,16 +1219,20 @@ const ScreenShareButton = (props) => {
|
|
|
1216
1219
|
const AudioVolumeIndicator = () => {
|
|
1217
1220
|
const { useMicrophoneState } = videoReactBindings.useCallStateHooks();
|
|
1218
1221
|
const { isEnabled, mediaStream } = useMicrophoneState();
|
|
1219
|
-
const
|
|
1222
|
+
const barRef = react.useRef(null);
|
|
1220
1223
|
react.useEffect(() => {
|
|
1221
1224
|
if (!isEnabled || !mediaStream)
|
|
1222
1225
|
return;
|
|
1223
|
-
const disposeSoundDetector = videoClient.createSoundDetector(mediaStream, ({ audioLevel: al }) =>
|
|
1226
|
+
const disposeSoundDetector = videoClient.createSoundDetector(mediaStream, ({ audioLevel: al }) => {
|
|
1227
|
+
if (barRef.current) {
|
|
1228
|
+
barRef.current.style.transform = `scaleX(${al / 100})`;
|
|
1229
|
+
}
|
|
1230
|
+
}, { detectionFrequencyInMs: 80, destroyStreamOnStop: false });
|
|
1224
1231
|
return () => {
|
|
1225
1232
|
disposeSoundDetector().catch(console.error);
|
|
1226
1233
|
};
|
|
1227
1234
|
}, [isEnabled, mediaStream]);
|
|
1228
|
-
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"
|
|
1235
|
+
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" }) })] }));
|
|
1229
1236
|
};
|
|
1230
1237
|
|
|
1231
1238
|
const LEVEL_BARS = 5;
|
|
@@ -1399,7 +1406,7 @@ const SpeakerTest = (props) => {
|
|
|
1399
1406
|
const audioElementRef = react.useRef(null);
|
|
1400
1407
|
const [isPlaying, setIsPlaying] = react.useState(false);
|
|
1401
1408
|
const { t } = videoReactBindings.useI18n();
|
|
1402
|
-
const { audioUrl = `https://unpkg.com/${"@stream-io/video-react-sdk"}@${"1.
|
|
1409
|
+
const { audioUrl = `https://unpkg.com/${"@stream-io/video-react-sdk"}@${"1.39.0"}/assets/piano.mp3`, } = props;
|
|
1403
1410
|
// Update audio output device when selection changes
|
|
1404
1411
|
react.useEffect(() => {
|
|
1405
1412
|
const audio = audioElementRef.current;
|
|
@@ -1903,13 +1910,14 @@ const CallParticipantListHeader = ({ onClose, }) => {
|
|
|
1903
1910
|
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" })] }));
|
|
1904
1911
|
};
|
|
1905
1912
|
|
|
1906
|
-
const CallParticipantListingItem = ({ participant, DisplayName = DefaultDisplayName, })
|
|
1913
|
+
const CallParticipantListingItem = react.memo(function CallParticipantListingItem({ participant, DisplayName = DefaultDisplayName, }) {
|
|
1907
1914
|
const isAudioOn = videoClient.hasAudio(participant);
|
|
1908
1915
|
const isVideoOn = videoClient.hasVideo(participant);
|
|
1909
1916
|
const isPinnedOn = videoClient.isPinned(participant);
|
|
1910
1917
|
const { t } = videoReactBindings.useI18n();
|
|
1911
1918
|
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, {}) }) })] })] }));
|
|
1912
|
-
};
|
|
1919
|
+
});
|
|
1920
|
+
CallParticipantListingItem.displayName = 'CallParticipantListingItem';
|
|
1913
1921
|
const MediaIndicator = (props) => (jsxRuntime.jsx(WithTooltip, { ...props }));
|
|
1914
1922
|
const DefaultDisplayName = ({ participant }) => {
|
|
1915
1923
|
const connectedUser = videoReactBindings.useConnectedUser();
|
|
@@ -1941,18 +1949,19 @@ const EmptyParticipantSearchList = () => {
|
|
|
1941
1949
|
|
|
1942
1950
|
const SearchInput = ({ exitSearch, isActive, ...rest }) => {
|
|
1943
1951
|
const [inputElement, setInputElement] = react.useState(null);
|
|
1952
|
+
const onExitSearch = videoReactBindings.useEffectEvent(exitSearch);
|
|
1944
1953
|
react.useEffect(() => {
|
|
1945
1954
|
if (!inputElement)
|
|
1946
1955
|
return;
|
|
1947
1956
|
const handleKeyDown = (e) => {
|
|
1948
1957
|
if (e.key.toLowerCase() === 'escape')
|
|
1949
|
-
|
|
1958
|
+
onExitSearch();
|
|
1950
1959
|
};
|
|
1951
1960
|
inputElement.addEventListener('keydown', handleKeyDown);
|
|
1952
1961
|
return () => {
|
|
1953
1962
|
inputElement.removeEventListener('keydown', handleKeyDown);
|
|
1954
1963
|
};
|
|
1955
|
-
}, [
|
|
1964
|
+
}, [inputElement]);
|
|
1956
1965
|
return (jsxRuntime.jsxs("div", { className: clsx('str-video__search-input__container', {
|
|
1957
1966
|
'str-video__search-input__container--active': isActive,
|
|
1958
1967
|
}), 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" }))] }));
|
|
@@ -2023,10 +2032,19 @@ const CallParticipantListContentHeader = ({ userListType, setUserListType, }) =>
|
|
|
2023
2032
|
const ActiveUsersSearchResults = ({ searchQuery, activeUsersSearchFn: activeUsersSearchFnFromProps, debounceSearchInterval, }) => {
|
|
2024
2033
|
const { useParticipants } = videoReactBindings.useCallStateHooks();
|
|
2025
2034
|
const participants = useParticipants({ sortBy: videoClient.name });
|
|
2035
|
+
// cache: each distinct name is normalized once
|
|
2036
|
+
const normalizedNameCache = react.useRef(null);
|
|
2026
2037
|
const activeUsersSearchFn = react.useCallback(async (queryString) => {
|
|
2027
2038
|
const normalizedQuery = normalizeString(queryString);
|
|
2028
|
-
const
|
|
2029
|
-
return participants.filter((p) =>
|
|
2039
|
+
const cache = (normalizedNameCache.current ??= new Map());
|
|
2040
|
+
return participants.filter((p) => {
|
|
2041
|
+
let normalizedName = cache.get(p.name);
|
|
2042
|
+
if (normalizedName === undefined) {
|
|
2043
|
+
normalizedName = normalizeString(p.name);
|
|
2044
|
+
cache.set(p.name, normalizedName);
|
|
2045
|
+
}
|
|
2046
|
+
return normalizedName.includes(normalizedQuery);
|
|
2047
|
+
});
|
|
2030
2048
|
}, [participants]);
|
|
2031
2049
|
const { searchQueryInProgress, searchResults } = useSearch({
|
|
2032
2050
|
searchFn: activeUsersSearchFnFromProps ?? activeUsersSearchFn,
|
|
@@ -2039,8 +2057,8 @@ const BlockedUsersSearchResults = ({ blockedUsersSearchFn: blockedUsersSearchFnF
|
|
|
2039
2057
|
const { useCallBlockedUserIds } = videoReactBindings.useCallStateHooks();
|
|
2040
2058
|
const blockedUsers = useCallBlockedUserIds();
|
|
2041
2059
|
const blockedUsersSearchFn = react.useCallback(async (queryString) => {
|
|
2042
|
-
const
|
|
2043
|
-
return blockedUsers.filter((userId) => userId.
|
|
2060
|
+
const normalizedQuery = queryString.toLowerCase();
|
|
2061
|
+
return blockedUsers.filter((userId) => userId.toLowerCase().includes(normalizedQuery));
|
|
2044
2062
|
}, [blockedUsers]);
|
|
2045
2063
|
const { searchQueryInProgress, searchResults } = useSearch({
|
|
2046
2064
|
searchFn: blockedUsersSearchFnFromProps ?? blockedUsersSearchFn,
|
|
@@ -2396,7 +2414,8 @@ const ParticipantDetails = ({ indicatorsVisible = true, }) => {
|
|
|
2396
2414
|
const canUnpin = !!pin && pin.isLocalPin;
|
|
2397
2415
|
const isTrackPaused = trackType !== 'none' ? videoClient.hasPausedTrack(participant, trackType) : false;
|
|
2398
2416
|
const isAudioConnecting = videoReactBindings.useIsAudioConnecting(participant);
|
|
2399
|
-
|
|
2417
|
+
const isVideoConnecting = videoReactBindings.useIsVideoConnecting(participant);
|
|
2418
|
+
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 &&
|
|
2400
2419
|
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 })) }))] }));
|
|
2401
2420
|
};
|
|
2402
2421
|
const SpeechIndicator = () => {
|
|
@@ -2405,7 +2424,7 @@ const SpeechIndicator = () => {
|
|
|
2405
2424
|
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" })] }));
|
|
2406
2425
|
};
|
|
2407
2426
|
|
|
2408
|
-
const ParticipantView = react.forwardRef(function ParticipantView({ participant, trackType = 'videoTrack', mirror, muteAudio, refs: { setVideoElement, setVideoPlaceholderElement } = {}, className, VideoPlaceholder, PictureInPicturePlaceholder, ParticipantViewUI = DefaultParticipantViewUI, }, ref) {
|
|
2427
|
+
const ParticipantView = react.memo(react.forwardRef(function ParticipantView({ participant, trackType = 'videoTrack', mirror, muteAudio, refs: { setVideoElement, setVideoPlaceholderElement } = {}, className, VideoPlaceholder, PictureInPicturePlaceholder, ParticipantViewUI = DefaultParticipantViewUI, }, ref) {
|
|
2409
2428
|
const { isLocalParticipant, isSpeaking, isDominantSpeaker, sessionId } = participant;
|
|
2410
2429
|
const hasAudioTrack = videoClient.hasAudio(participant);
|
|
2411
2430
|
const hasVideoTrack = videoClient.hasVideo(participant);
|
|
@@ -2449,7 +2468,7 @@ const ParticipantView = react.forwardRef(function ParticipantView({ participant,
|
|
|
2449
2468
|
}, 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 ||
|
|
2450
2469
|
trackType !== 'videoTrack' ||
|
|
2451
2470
|
isParticipantVideoEnabled(participant.sessionId), mirror: mirror, autoPlay: true }), isComponentType(ParticipantViewUI) ? (jsxRuntime.jsx(ParticipantViewUI, {})) : (ParticipantViewUI)] }) }));
|
|
2452
|
-
});
|
|
2471
|
+
}));
|
|
2453
2472
|
ParticipantView.displayName = 'ParticipantView';
|
|
2454
2473
|
|
|
2455
2474
|
// re-exporting the StreamCallProvider as StreamCall
|
|
@@ -2576,6 +2595,7 @@ var en = {
|
|
|
2576
2595
|
"Poor connection quality": "Poor connection quality. Please check your internet connection.",
|
|
2577
2596
|
"Video paused due to insufficient bandwidth": "Video paused due to insufficient bandwidth",
|
|
2578
2597
|
"Audio is connecting...": "Audio is connecting...",
|
|
2598
|
+
"Video is connecting...": "Video is connecting...",
|
|
2579
2599
|
Participants: Participants,
|
|
2580
2600
|
Anonymous: Anonymous,
|
|
2581
2601
|
"No participants found": "No participants found",
|
|
@@ -2666,20 +2686,20 @@ function checkConditions(obj, conditions) {
|
|
|
2666
2686
|
const eqOperatorValue = isDateString(eqOperator.$eq)
|
|
2667
2687
|
? new Date(eqOperator.$eq).getTime()
|
|
2668
2688
|
: eqOperator.$eq;
|
|
2669
|
-
match
|
|
2689
|
+
match &&= eqOperatorValue === value;
|
|
2670
2690
|
}
|
|
2671
2691
|
else if (maybeOperator && '$neq' in operator) {
|
|
2672
2692
|
const neqOperator = operator;
|
|
2673
|
-
match
|
|
2693
|
+
match &&= neqOperator.$neq !== value;
|
|
2674
2694
|
}
|
|
2675
2695
|
else if (maybeOperator && '$in' in operator) {
|
|
2676
2696
|
const inOperator = operator;
|
|
2677
|
-
match
|
|
2697
|
+
match &&= inOperator.$in.includes(value);
|
|
2678
2698
|
}
|
|
2679
2699
|
else if (maybeOperator && '$contains' in operator) {
|
|
2680
2700
|
if (Array.isArray(value)) {
|
|
2681
2701
|
const containsOperator = operator;
|
|
2682
|
-
match
|
|
2702
|
+
match &&= value.includes(containsOperator.$contains);
|
|
2683
2703
|
}
|
|
2684
2704
|
else {
|
|
2685
2705
|
match = false;
|
|
@@ -2690,35 +2710,35 @@ function checkConditions(obj, conditions) {
|
|
|
2690
2710
|
const gtOperatorValue = isDateString(gtOperator.$gt)
|
|
2691
2711
|
? new Date(gtOperator.$gt).getTime()
|
|
2692
2712
|
: gtOperator.$gt;
|
|
2693
|
-
match
|
|
2713
|
+
match &&= value > gtOperatorValue;
|
|
2694
2714
|
}
|
|
2695
2715
|
else if (maybeOperator && '$gte' in operator) {
|
|
2696
2716
|
const gteOperator = operator;
|
|
2697
2717
|
const gteOperatorValue = isDateString(gteOperator.$gte)
|
|
2698
2718
|
? new Date(gteOperator.$gte).getTime()
|
|
2699
2719
|
: gteOperator.$gte;
|
|
2700
|
-
match
|
|
2720
|
+
match &&= value >= gteOperatorValue;
|
|
2701
2721
|
}
|
|
2702
2722
|
else if (maybeOperator && '$lt' in operator) {
|
|
2703
2723
|
const ltOperator = operator;
|
|
2704
2724
|
const ltOperatorValue = isDateString(ltOperator.$lt)
|
|
2705
2725
|
? new Date(ltOperator.$lt).getTime()
|
|
2706
2726
|
: ltOperator.$lt;
|
|
2707
|
-
match
|
|
2727
|
+
match &&= value < ltOperatorValue;
|
|
2708
2728
|
}
|
|
2709
2729
|
else if (maybeOperator && '$lte' in operator) {
|
|
2710
2730
|
const lteOperator = operator;
|
|
2711
2731
|
const lteOperatorValue = isDateString(lteOperator.$lte)
|
|
2712
2732
|
? new Date(lteOperator.$lte).getTime()
|
|
2713
2733
|
: lteOperator.$lte;
|
|
2714
|
-
match
|
|
2734
|
+
match &&= value <= lteOperatorValue;
|
|
2715
2735
|
// } else if (maybeOperator && '$autocomplete' in operator) {
|
|
2716
2736
|
// TODO: regexp solution maybe?
|
|
2717
2737
|
// match &&= false;
|
|
2718
2738
|
}
|
|
2719
2739
|
else {
|
|
2720
2740
|
const eqValue = operator;
|
|
2721
|
-
match
|
|
2741
|
+
match &&= eqValue === value;
|
|
2722
2742
|
}
|
|
2723
2743
|
if (!match) {
|
|
2724
2744
|
return false;
|
|
@@ -3248,12 +3268,12 @@ const useCanJoinEarly = () => {
|
|
|
3248
3268
|
const joinAheadTimeSeconds = settings?.backstage.join_ahead_time_seconds;
|
|
3249
3269
|
const [canJoinEarly, setCanJoinEarly] = react.useState(() => checkCanJoinEarly(startsAt, joinAheadTimeSeconds));
|
|
3250
3270
|
react.useEffect(() => {
|
|
3251
|
-
if (
|
|
3252
|
-
|
|
3253
|
-
|
|
3254
|
-
|
|
3255
|
-
|
|
3256
|
-
|
|
3271
|
+
if (canJoinEarly)
|
|
3272
|
+
return;
|
|
3273
|
+
const handle = setInterval(() => {
|
|
3274
|
+
setCanJoinEarly(checkCanJoinEarly(startsAt, joinAheadTimeSeconds));
|
|
3275
|
+
}, 1000);
|
|
3276
|
+
return () => clearInterval(handle);
|
|
3257
3277
|
}, [canJoinEarly, startsAt, joinAheadTimeSeconds]);
|
|
3258
3278
|
return canJoinEarly;
|
|
3259
3279
|
};
|
|
@@ -3264,7 +3284,7 @@ const checkCanJoinEarly = (startsAt, joinAheadTimeSeconds) => {
|
|
|
3264
3284
|
return Date.now() >= +startsAt - (joinAheadTimeSeconds ?? 0) * 1000;
|
|
3265
3285
|
};
|
|
3266
3286
|
|
|
3267
|
-
const [major, minor, patch] = ("1.
|
|
3287
|
+
const [major, minor, patch] = ("1.39.0").split('.');
|
|
3268
3288
|
videoClient.setSdkInfo({
|
|
3269
3289
|
type: videoClient.SfuModels.SdkType.REACT,
|
|
3270
3290
|
major,
|