Combined permission request with newer livekit sdk version (#1200)
--------- Signed-off-by: Timo K <toger5@hotmail.de>
This commit is contained in:
parent
cc95ed7c30
commit
9be9250124
6 changed files with 137 additions and 107 deletions
|
@ -19,7 +19,7 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@juggle/resize-observer": "^3.3.1",
|
||||
"@livekit/components-react": "^1.0.3",
|
||||
"@livekit/components-react": "^1.0.7",
|
||||
"@matrix-org/olm": "https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.14.tgz",
|
||||
"@opentelemetry/api": "^1.4.0",
|
||||
"@opentelemetry/context-zone": "^1.9.1",
|
||||
|
@ -55,7 +55,7 @@
|
|||
"i18next": "^21.10.0",
|
||||
"i18next-browser-languagedetector": "^6.1.8",
|
||||
"i18next-http-backend": "^1.4.4",
|
||||
"livekit-client": "^1.9.7",
|
||||
"livekit-client": "^1.11.4",
|
||||
"lodash": "^4.17.21",
|
||||
"matrix-js-sdk": "github:matrix-org/matrix-js-sdk#4b3406daa95c8f969f386341b8b632ba4a60501a",
|
||||
"matrix-widget-api": "^1.3.1",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { useMediaDeviceSelect } from "@livekit/components-react";
|
||||
import { Room } from "livekit-client";
|
||||
import { LocalAudioTrack, LocalVideoTrack, Room } from "livekit-client";
|
||||
import { useEffect } from "react";
|
||||
|
||||
import { useDefaultDevices } from "../settings/useSetting";
|
||||
|
@ -17,12 +17,21 @@ export type MediaDevicesState = {
|
|||
};
|
||||
|
||||
// if a room is passed this only affects the device selection inside a call. Without room it changes what we see in the lobby
|
||||
export function useMediaDevices(room?: Room): MediaDevicesState {
|
||||
export function useMediaDevicesSwitcher(
|
||||
room?: Room,
|
||||
tracks?: { videoTrack?: LocalVideoTrack; audioTrack?: LocalAudioTrack },
|
||||
requestPermissions = true
|
||||
): MediaDevicesState {
|
||||
const {
|
||||
devices: videoDevices,
|
||||
activeDeviceId: activeVideoDevice,
|
||||
setActiveMediaDevice: setActiveVideoDevice,
|
||||
} = useMediaDeviceSelect({ kind: "videoinput", room });
|
||||
} = useMediaDeviceSelect({
|
||||
kind: "videoinput",
|
||||
room,
|
||||
track: tracks?.videoTrack,
|
||||
requestPermissions,
|
||||
});
|
||||
|
||||
const {
|
||||
devices: audioDevices,
|
||||
|
@ -31,6 +40,8 @@ export function useMediaDevices(room?: Room): MediaDevicesState {
|
|||
} = useMediaDeviceSelect({
|
||||
kind: "audioinput",
|
||||
room,
|
||||
track: tracks?.audioTrack,
|
||||
requestPermissions,
|
||||
});
|
||||
|
||||
const {
|
|
@ -80,7 +80,7 @@ import { useRageshakeRequestModal } from "../settings/submit-rageshake";
|
|||
import { RageshakeRequestModal } from "./RageshakeRequestModal";
|
||||
import { VideoTile } from "../video-grid/VideoTile";
|
||||
import { UserChoices, useLiveKit } from "../livekit/useLiveKit";
|
||||
import { useMediaDevices } from "../livekit/useMediaDevices";
|
||||
import { useMediaDevicesSwitcher } from "../livekit/useMediaDevicesSwitcher";
|
||||
import { useFullscreen } from "./useFullscreen";
|
||||
import { useLayoutStates } from "../video-grid/Layout";
|
||||
import { useSFUConfig } from "../livekit/OpenIDLoader";
|
||||
|
@ -148,7 +148,7 @@ export function InCallView({
|
|||
);
|
||||
|
||||
// Managed media devices state coupled with an active room.
|
||||
const roomMediaDevices = useMediaDevices(livekitRoom);
|
||||
const roomMediaSwitcher = useMediaDevicesSwitcher(livekitRoom);
|
||||
|
||||
const screenSharingTracks = useTracks(
|
||||
[{ source: Track.Source.ScreenShare, withPlaceholder: false }],
|
||||
|
@ -427,7 +427,7 @@ export function InCallView({
|
|||
<SettingsModal
|
||||
client={client}
|
||||
roomId={groupCall.room.roomId}
|
||||
mediaDevices={roomMediaDevices}
|
||||
mediaDevicesSwitcher={roomMediaSwitcher}
|
||||
{...settingsModalProps}
|
||||
/>
|
||||
)}
|
||||
|
|
|
@ -14,11 +14,12 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
import { useState, useEffect, useRef, useCallback } from "react";
|
||||
import React, { useState, useEffect, useCallback, useRef } from "react";
|
||||
import useMeasure from "react-use-measure";
|
||||
import { ResizeObserver } from "@juggle/resize-observer";
|
||||
import { OverlayTriggerState } from "@react-stately/overlays";
|
||||
import { usePreviewDevice } from "@livekit/components-react";
|
||||
import { usePreviewTracks } from "@livekit/components-react";
|
||||
import { LocalAudioTrack, LocalVideoTrack, Track } from "livekit-client";
|
||||
|
||||
import { MicButton, SettingsButton, VideoButton } from "../button";
|
||||
import { Avatar } from "../Avatar";
|
||||
|
@ -26,7 +27,7 @@ import styles from "./VideoPreview.module.css";
|
|||
import { useModalTriggerState } from "../Modal";
|
||||
import { SettingsModal } from "../settings/SettingsModal";
|
||||
import { useClient } from "../ClientContext";
|
||||
import { useMediaDevices } from "../livekit/useMediaDevices";
|
||||
import { useMediaDevicesSwitcher } from "../livekit/useMediaDevicesSwitcher";
|
||||
import { DeviceChoices, UserChoices } from "../livekit/useLiveKit";
|
||||
import { useDefaultDevices } from "../settings/useSetting";
|
||||
|
||||
|
@ -61,85 +62,107 @@ export function VideoPreview({ matrixInfo, onUserChoicesChanged }: Props) {
|
|||
settingsModalState.open();
|
||||
}, [settingsModalState]);
|
||||
|
||||
// Fetch user media devices.
|
||||
const mediaDevices = useMediaDevices();
|
||||
|
||||
// Create local media tracks.
|
||||
const [videoEnabled, setVideoEnabled] = useState<boolean>(true);
|
||||
const [audioEnabled, setAudioEnabled] = useState<boolean>(true);
|
||||
const [videoId, audioId] = [
|
||||
mediaDevices.videoIn.selectedId,
|
||||
mediaDevices.audioIn.selectedId,
|
||||
];
|
||||
const [defaultDevices] = useDefaultDevices();
|
||||
const video = usePreviewDevice(
|
||||
videoEnabled,
|
||||
videoId != "" ? videoId : defaultDevices.videoinput,
|
||||
"videoinput"
|
||||
);
|
||||
const audio = usePreviewDevice(
|
||||
audioEnabled,
|
||||
audioId != "" ? audioId : defaultDevices.audioinput,
|
||||
"audioinput"
|
||||
);
|
||||
|
||||
const activeVideoId = video?.selectedDevice?.deviceId;
|
||||
const activeAudioId = audio?.selectedDevice?.deviceId;
|
||||
// The settings are updated as soon as the device changes. We wrap the settings value in a ref to store their initial value.
|
||||
// Not changing the device options prohibits the usePreviewTracks hook to recreate the tracks.
|
||||
const initialDefaultDevices = useRef(useDefaultDevices()[0]);
|
||||
|
||||
const tracks = usePreviewTracks(
|
||||
{
|
||||
audio: { deviceId: initialDefaultDevices.current.audioinput },
|
||||
video: { deviceId: initialDefaultDevices.current.videoinput },
|
||||
},
|
||||
(error) => {
|
||||
console.error("Error while creating preview Tracks:", error);
|
||||
}
|
||||
);
|
||||
const videoTrack = React.useMemo(
|
||||
() =>
|
||||
tracks?.filter((t) => t.kind === Track.Kind.Video)[0] as LocalVideoTrack,
|
||||
[tracks]
|
||||
);
|
||||
const audioTrack = React.useMemo(
|
||||
() =>
|
||||
tracks?.filter((t) => t.kind === Track.Kind.Audio)[0] as LocalAudioTrack,
|
||||
[tracks]
|
||||
);
|
||||
// Only let the MediaDeviceSwitcher request permissions if a video track is already available.
|
||||
// Otherwise we would end up asking for permissions in usePreviewTracks and in useMediaDevicesSwitcher.
|
||||
const requestPermissions = !!videoTrack;
|
||||
const mediaSwitcher = useMediaDevicesSwitcher(
|
||||
undefined,
|
||||
{
|
||||
videoTrack,
|
||||
audioTrack,
|
||||
},
|
||||
requestPermissions
|
||||
);
|
||||
const { videoIn, audioIn } = mediaSwitcher;
|
||||
|
||||
const videoEl = React.useRef(null);
|
||||
|
||||
useEffect(() => {
|
||||
// Effect to update the settings
|
||||
const createChoices = (
|
||||
enabled: boolean,
|
||||
deviceId?: string
|
||||
): DeviceChoices | undefined => {
|
||||
if (deviceId === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return {
|
||||
selectedId: deviceId,
|
||||
enabled,
|
||||
};
|
||||
return deviceId
|
||||
? {
|
||||
selectedId: deviceId,
|
||||
enabled,
|
||||
}
|
||||
: undefined;
|
||||
};
|
||||
|
||||
onUserChoicesChanged({
|
||||
video: createChoices(videoEnabled, activeVideoId),
|
||||
audio: createChoices(audioEnabled, activeAudioId),
|
||||
video: createChoices(videoEnabled, videoIn.selectedId),
|
||||
audio: createChoices(audioEnabled, audioIn.selectedId),
|
||||
});
|
||||
}, [
|
||||
onUserChoicesChanged,
|
||||
activeVideoId,
|
||||
videoIn.selectedId,
|
||||
videoEnabled,
|
||||
activeAudioId,
|
||||
audioIn.selectedId,
|
||||
audioEnabled,
|
||||
]);
|
||||
|
||||
const [selectVideo, selectAudio] = [
|
||||
mediaDevices.videoIn.setSelected,
|
||||
mediaDevices.audioIn.setSelected,
|
||||
];
|
||||
useEffect(() => {
|
||||
if (activeVideoId && activeVideoId !== "") {
|
||||
selectVideo(activeVideoId);
|
||||
// Effect to update the initial device selection for the ui elements based on the current preview track.
|
||||
if (!videoIn.selectedId || videoIn.selectedId == "") {
|
||||
videoTrack?.getDeviceId().then((videoId) => {
|
||||
if (videoId) {
|
||||
videoIn.setSelected(videoId);
|
||||
}
|
||||
});
|
||||
}
|
||||
if (activeAudioId && activeAudioId !== "") {
|
||||
selectAudio(activeAudioId);
|
||||
if (!audioIn.selectedId || audioIn.selectedId == "") {
|
||||
audioTrack?.getDeviceId().then((audioId) => {
|
||||
if (audioId) {
|
||||
audioIn.setSelected(audioId);
|
||||
}
|
||||
});
|
||||
}
|
||||
}, [selectVideo, selectAudio, activeVideoId, activeAudioId]);
|
||||
}, [videoIn, audioIn, videoTrack, audioTrack]);
|
||||
|
||||
const mediaElement = useRef(null);
|
||||
useEffect(() => {
|
||||
if (mediaElement.current) {
|
||||
video?.localTrack?.attach(mediaElement.current);
|
||||
// Effect to connect the videoTrack with the video element.
|
||||
if (videoEl.current) {
|
||||
videoTrack?.unmute();
|
||||
videoTrack?.attach(videoEl.current);
|
||||
}
|
||||
return () => {
|
||||
video?.localTrack?.detach();
|
||||
videoTrack?.detach();
|
||||
};
|
||||
}, [video?.localTrack, mediaElement]);
|
||||
}, [videoTrack]);
|
||||
|
||||
return (
|
||||
<div className={styles.preview} ref={previewRef}>
|
||||
<video ref={mediaElement} muted playsInline disablePictureInPicture />
|
||||
<video ref={videoEl} muted playsInline disablePictureInPicture />
|
||||
<>
|
||||
{(video ? !videoEnabled : true) && (
|
||||
{(videoTrack ? !videoEnabled : true) && (
|
||||
<div className={styles.avatarContainer}>
|
||||
<Avatar
|
||||
size={(previewBounds.height - 66) / 2}
|
||||
|
@ -149,25 +172,21 @@ export function VideoPreview({ matrixInfo, onUserChoicesChanged }: Props) {
|
|||
</div>
|
||||
)}
|
||||
<div className={styles.previewButtons}>
|
||||
{audio.localTrack && (
|
||||
<MicButton
|
||||
muted={!audioEnabled}
|
||||
onPress={() => setAudioEnabled(!audioEnabled)}
|
||||
/>
|
||||
)}
|
||||
{video.localTrack && (
|
||||
<VideoButton
|
||||
muted={!videoEnabled}
|
||||
onPress={() => setVideoEnabled(!videoEnabled)}
|
||||
/>
|
||||
)}
|
||||
<MicButton
|
||||
muted={!audioEnabled}
|
||||
onPress={() => setAudioEnabled(!audioEnabled)}
|
||||
/>
|
||||
<VideoButton
|
||||
muted={!videoEnabled}
|
||||
onPress={() => setVideoEnabled(!videoEnabled)}
|
||||
/>
|
||||
<SettingsButton onPress={openSettings} />
|
||||
</div>
|
||||
</>
|
||||
{settingsModalState.isOpen && (
|
||||
<SettingsModal
|
||||
client={client}
|
||||
mediaDevices={mediaDevices}
|
||||
mediaDevicesSwitcher={mediaSwitcher}
|
||||
{...settingsModalProps}
|
||||
/>
|
||||
)}
|
||||
|
|
|
@ -42,10 +42,13 @@ import { Body, Caption } from "../typography/Typography";
|
|||
import { AnalyticsNotice } from "../analytics/AnalyticsNotice";
|
||||
import { ProfileSettingsTab } from "./ProfileSettingsTab";
|
||||
import { FeedbackSettingsTab } from "./FeedbackSettingsTab";
|
||||
import { MediaDevices, MediaDevicesState } from "../livekit/useMediaDevices";
|
||||
import {
|
||||
MediaDevices,
|
||||
MediaDevicesState,
|
||||
} from "../livekit/useMediaDevicesSwitcher";
|
||||
|
||||
interface Props {
|
||||
mediaDevices?: MediaDevicesState;
|
||||
mediaDevicesSwitcher?: MediaDevicesState;
|
||||
isOpen: boolean;
|
||||
client: MatrixClient;
|
||||
roomId?: string;
|
||||
|
@ -106,7 +109,7 @@ export const SettingsModal = (props: Props) => {
|
|||
</Caption>
|
||||
);
|
||||
|
||||
const devices = props.mediaDevices;
|
||||
const devices = props.mediaDevicesSwitcher;
|
||||
|
||||
return (
|
||||
<Modal
|
||||
|
|
59
yarn.lock
59
yarn.lock
|
@ -2166,23 +2166,23 @@
|
|||
resolved "https://registry.yarnpkg.com/@juggle/resize-observer/-/resize-observer-3.3.1.tgz#b50a781709c81e10701004214340f25475a171a0"
|
||||
integrity sha512-zMM9Ds+SawiUkakS7y94Ymqx+S0ORzpG3frZirN3l+UlXUmSUR7hF4wxCVqW+ei94JzV5kt0uXBcoOEAuiydrw==
|
||||
|
||||
"@livekit/components-core@0.6.7":
|
||||
version "0.6.7"
|
||||
resolved "https://registry.yarnpkg.com/@livekit/components-core/-/components-core-0.6.7.tgz#e6fdbdf0feade66f6c187dc8b7f1b54e2fbe4b85"
|
||||
integrity sha512-Nc+HMvIhMRuZUYkUWxHobVH+ZpQNSwzdeVZpWOVea0hUGh7A3WeOY5rS0LY3zrvCAseRooOK+pQHna9KSFf2RQ==
|
||||
"@livekit/components-core@0.6.10":
|
||||
version "0.6.10"
|
||||
resolved "https://registry.yarnpkg.com/@livekit/components-core/-/components-core-0.6.10.tgz#5d05cc096e43b9caff6e363d03ecd388febc9108"
|
||||
integrity sha512-UG96mKcdHWSAqFT9J9j5D4R2d78Q7O4RGK7GYLBLqwvnmGJc1rbCYWezte2GZwZNa4RtbLfDKTD9M6Z78xGDLg==
|
||||
dependencies:
|
||||
"@floating-ui/dom" "^1.1.0"
|
||||
email-regex "^5.0.0"
|
||||
global-tld-list "^0.0.1093"
|
||||
global-tld-list "^0.0.1139"
|
||||
loglevel "^1.8.1"
|
||||
rxjs "^7.8.0"
|
||||
|
||||
"@livekit/components-react@^1.0.3":
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@livekit/components-react/-/components-react-1.0.3.tgz#03a32c200fae6a386cdcaaab77226abab00c8673"
|
||||
integrity sha512-HJxsEdApjQa5fa/qXXkixw2V6MRziWHKow7oRi1ZPsmxt/Xls9vbbsMFaUYPh6bXiBm8Fz4RznmdvMOPk1YIPg==
|
||||
"@livekit/components-react@^1.0.7":
|
||||
version "1.0.7"
|
||||
resolved "https://registry.yarnpkg.com/@livekit/components-react/-/components-react-1.0.7.tgz#bce1d32be155eb5c02465de846c8fbb0e7c5f481"
|
||||
integrity sha512-xPgOwEFp4M4oH8QGlHYHiU75Q8lrcMiH1CVC0yAVJhmqDcn8ihj5S5iziP0CMhXSv1zYJNjkGaBK+P11NtNLjQ==
|
||||
dependencies:
|
||||
"@livekit/components-core" "0.6.7"
|
||||
"@livekit/components-core" "0.6.10"
|
||||
"@react-hook/latest" "^1.0.3"
|
||||
clsx "^1.2.1"
|
||||
|
||||
|
@ -4112,9 +4112,9 @@
|
|||
"@types/react" "*"
|
||||
|
||||
"@types/react@*":
|
||||
version "18.0.15"
|
||||
resolved "https://registry.yarnpkg.com/@types/react/-/react-18.0.15.tgz#d355644c26832dc27f3e6cbf0c4f4603fc4ab7fe"
|
||||
integrity sha512-iz3BtLuIYH1uWdsv6wXYdhozhqj20oD4/Hk2DNXIn1kFsmp9x8d9QB6FnPhfkbhd2PgEONt9Q1x/ebkwjfFLow==
|
||||
version "18.2.14"
|
||||
resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.14.tgz#fa7a6fecf1ce35ca94e74874f70c56ce88f7a127"
|
||||
integrity sha512-A0zjq+QN/O0Kpe30hA1GidzyFjatVvrpIvWLxD+xv67Vt91TWWgco9IvrJBkeyHm1trGaFS/FSGqPlhyeZRm0g==
|
||||
dependencies:
|
||||
"@types/prop-types" "*"
|
||||
"@types/scheduler" "*"
|
||||
|
@ -8066,6 +8066,11 @@ etag@~1.8.1:
|
|||
resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
|
||||
integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==
|
||||
|
||||
eventemitter3@^5.0.1:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-5.0.1.tgz#53f5ffd0a492ac800721bb42c66b841de96423c4"
|
||||
integrity sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==
|
||||
|
||||
events@^3.0.0, events@^3.2.0, events@^3.3.0:
|
||||
version "3.3.0"
|
||||
resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400"
|
||||
|
@ -8850,10 +8855,10 @@ glob@^7.0.0, glob@^7.1.1, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6, glob@^7.2.0:
|
|||
once "^1.3.0"
|
||||
path-is-absolute "^1.0.0"
|
||||
|
||||
global-tld-list@^0.0.1093:
|
||||
version "0.0.1093"
|
||||
resolved "https://registry.yarnpkg.com/global-tld-list/-/global-tld-list-0.0.1093.tgz#223c3e82e1673f36f8d874d42a30f3b8463508de"
|
||||
integrity sha512-V6ZI9rzpsiVQdEZyMgt4ujKPkR82a+IxmPdMGO7oHc+iBfhdxTTO3nk8+pNUyGCXOHeOCrk7icOKcBMxBMEKkg==
|
||||
global-tld-list@^0.0.1139:
|
||||
version "0.0.1139"
|
||||
resolved "https://registry.yarnpkg.com/global-tld-list/-/global-tld-list-0.0.1139.tgz#70400a3f3ccac1a19a8184274a1b117bc8a27969"
|
||||
integrity sha512-TCWjAwHPzFV6zbQ5jnJvJTctesHGJr9BppxivRuIxTiIFUzaxy1F0674cxjoJecW5s8V32Q5i35dBFqvAy7eGQ==
|
||||
|
||||
global@^4.4.0:
|
||||
version "4.4.0"
|
||||
|
@ -10710,17 +10715,16 @@ lines-and-columns@^1.1.6:
|
|||
resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632"
|
||||
integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==
|
||||
|
||||
livekit-client@^1.9.7:
|
||||
version "1.9.7"
|
||||
resolved "https://registry.yarnpkg.com/livekit-client/-/livekit-client-1.9.7.tgz#51e7d8975ce7dcbfd51e91a8f9221f5868a1e606"
|
||||
integrity sha512-w0WjLat0qF76l71esjTXam5JE+7vCpBF6WW+oloHFNBIVtEzEnBZa2JUo/e2oWN2YypEO5MjCIDPo7Tuvo9clA==
|
||||
livekit-client@^1.11.4:
|
||||
version "1.11.4"
|
||||
resolved "https://registry.yarnpkg.com/livekit-client/-/livekit-client-1.11.4.tgz#e222afc111f36a28a7171755cdcfe6b8fa2ca2dc"
|
||||
integrity sha512-TX53HRrtz7ZPWLasnrUOkrGN8EL22/IDwg39uLT7aJcSBWtgKlCueQkwjW4nn7KVWRF8mv00g8WiPDE9jyS8fQ==
|
||||
dependencies:
|
||||
events "^3.3.0"
|
||||
eventemitter3 "^5.0.1"
|
||||
loglevel "^1.8.0"
|
||||
protobufjs "^7.0.0"
|
||||
sdp-transform "^2.14.1"
|
||||
ts-debounce "^4.0.0"
|
||||
typed-emitter "^2.1.0"
|
||||
webrtc-adapter "^8.1.1"
|
||||
|
||||
load-json-file@^1.0.0:
|
||||
|
@ -13496,7 +13500,7 @@ rw@1:
|
|||
resolved "https://registry.yarnpkg.com/rw/-/rw-1.3.3.tgz#3f862dfa91ab766b14885ef4d01124bfda074fb4"
|
||||
integrity sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==
|
||||
|
||||
rxjs@^7.5.2, rxjs@^7.8.0:
|
||||
rxjs@^7.8.0:
|
||||
version "7.8.1"
|
||||
resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.8.1.tgz#6f6f3d99ea8044291efd92e7c7fcf562c4057543"
|
||||
integrity sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==
|
||||
|
@ -14639,13 +14643,6 @@ type-is@~1.6.18:
|
|||
media-typer "0.3.0"
|
||||
mime-types "~2.1.24"
|
||||
|
||||
typed-emitter@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/typed-emitter/-/typed-emitter-2.1.0.tgz#ca78e3d8ef1476f228f548d62e04e3d4d3fd77fb"
|
||||
integrity sha512-g/KzbYKbH5C2vPkaXGu8DJlHrGKHLsM25Zg9WuC9pMGfuvT+X25tZQWo5fK1BjBm8+UrVE9LDCvaY0CQk+fXDA==
|
||||
optionalDependencies:
|
||||
rxjs "^7.5.2"
|
||||
|
||||
typedarray@^0.0.6:
|
||||
version "0.0.6"
|
||||
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
|
||||
|
|
Loading…
Add table
Reference in a new issue