Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9ecab1d61c | ||
|
|
930cb49589 |
@@ -46,7 +46,7 @@
|
||||
"@sentry/tracing": "^7.0.0",
|
||||
"@types/lodash": "^4.14.199",
|
||||
"@use-gesture/react": "^10.2.11",
|
||||
"@vector-im/compound-design-tokens": "^0.1.0",
|
||||
"@vector-im/compound-design-tokens": "^0.0.7",
|
||||
"@vector-im/compound-web": "^0.6.0",
|
||||
"@vitejs/plugin-basic-ssl": "^1.0.1",
|
||||
"@vitejs/plugin-react": "^4.0.1",
|
||||
@@ -58,7 +58,7 @@
|
||||
"i18next-http-backend": "^2.0.0",
|
||||
"livekit-client": "^1.12.3",
|
||||
"lodash": "^4.17.21",
|
||||
"matrix-js-sdk": "github:matrix-org/matrix-js-sdk#107e28e1145c8b2667701e1f75b9f09b5d2ac3d6",
|
||||
"matrix-js-sdk": "github:matrix-org/matrix-js-sdk#4ce837b20e638a185f9002b2388fbaf48975ee6e",
|
||||
"matrix-widget-api": "^1.3.1",
|
||||
"normalize.css": "^8.0.1",
|
||||
"pako": "^2.0.4",
|
||||
|
||||
@@ -115,10 +115,6 @@ interface UrlParams {
|
||||
* E2EE password
|
||||
*/
|
||||
password: string | null;
|
||||
/**
|
||||
* Whether we the app should use per participant keys for E2EE.
|
||||
*/
|
||||
perParticipantE2EE: boolean;
|
||||
/**
|
||||
* Setting this flag skips the lobby and brings you in the call directly.
|
||||
* In the widget this can be combined with preload to pass the device settings
|
||||
@@ -221,7 +217,6 @@ export const getUrlParams = (
|
||||
fontScale: Number.isNaN(fontScale) ? null : fontScale,
|
||||
analyticsID: parser.getParam("analyticsID"),
|
||||
allowIceFallback: parser.getFlagParam("allowIceFallback"),
|
||||
perParticipantE2EE: parser.getFlagParam("perParticipantE2EE"),
|
||||
skipLobby: parser.getFlagParam("skipLobby"),
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
/*
|
||||
Copyright 2023 New Vector Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
export enum E2eeType {
|
||||
NONE = 0,
|
||||
PER_PARTICIPANT = 1,
|
||||
SHARED_KEY = 2,
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
/*
|
||||
Copyright 2023 New Vector Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import { BaseKeyProvider, createKeyMaterialFromBuffer } from "livekit-client";
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
import {
|
||||
MatrixRTCSession,
|
||||
MatrixRTCSessionEvent,
|
||||
} from "matrix-js-sdk/src/matrixrtc/MatrixRTCSession";
|
||||
|
||||
export class MatrixKeyProvider extends BaseKeyProvider {
|
||||
private rtcSession?: MatrixRTCSession;
|
||||
|
||||
public constructor() {
|
||||
super({ ratchetWindowSize: 0 });
|
||||
}
|
||||
|
||||
public setRTCSession(rtcSession: MatrixRTCSession): void {
|
||||
if (this.rtcSession) {
|
||||
this.rtcSession.off(
|
||||
MatrixRTCSessionEvent.EncryptionKeyChanged,
|
||||
this.onEncryptionKeyChanged,
|
||||
);
|
||||
}
|
||||
|
||||
this.rtcSession = rtcSession;
|
||||
|
||||
this.rtcSession.on(
|
||||
MatrixRTCSessionEvent.EncryptionKeyChanged,
|
||||
this.onEncryptionKeyChanged,
|
||||
);
|
||||
|
||||
// The new session could be aware of keys of which the old session wasn't,
|
||||
// so emit a key changed event.
|
||||
for (const [
|
||||
participant,
|
||||
encryptionKeys,
|
||||
] of this.rtcSession.getEncryptionKeys()) {
|
||||
for (const [index, encryptionKey] of encryptionKeys.entries()) {
|
||||
this.onEncryptionKeyChanged(encryptionKey, index, participant);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private onEncryptionKeyChanged = async (
|
||||
encryptionKey: Uint8Array,
|
||||
encryptionKeyIndex: number,
|
||||
participantId: string,
|
||||
): Promise<void> => {
|
||||
this.onSetEncryptionKey(
|
||||
await createKeyMaterialFromBuffer(encryptionKey),
|
||||
participantId,
|
||||
encryptionKeyIndex,
|
||||
);
|
||||
|
||||
logger.debug(
|
||||
`Sent new key to livekit room=${this.rtcSession?.room.roomId} participantId=${participantId} encryptionKeyIndex=${encryptionKeyIndex}`,
|
||||
);
|
||||
};
|
||||
}
|
||||
@@ -40,7 +40,6 @@ import { Caption } from "../typography/Typography";
|
||||
import { Form } from "../form/Form";
|
||||
import { useOptInAnalytics } from "../settings/useSetting";
|
||||
import { AnalyticsNotice } from "../analytics/AnalyticsNotice";
|
||||
import { E2eeType } from "../e2ee/e2eeType";
|
||||
|
||||
interface Props {
|
||||
client: MatrixClient;
|
||||
@@ -73,11 +72,7 @@ export const RegisteredView: FC<Props> = ({ client }) => {
|
||||
setError(undefined);
|
||||
setLoading(true);
|
||||
|
||||
const createRoomResult = await createRoom(
|
||||
client,
|
||||
roomName,
|
||||
E2eeType.SHARED_KEY,
|
||||
);
|
||||
const createRoomResult = await createRoom(client, roomName, true);
|
||||
|
||||
history.push(
|
||||
getRelativeRoomUrl(
|
||||
|
||||
@@ -43,7 +43,6 @@ import { generateRandomName } from "../auth/generateRandomName";
|
||||
import { AnalyticsNotice } from "../analytics/AnalyticsNotice";
|
||||
import { useOptInAnalytics } from "../settings/useSetting";
|
||||
import { Config } from "../config/Config";
|
||||
import { E2eeType } from "../e2ee/e2eeType";
|
||||
|
||||
export const UnauthenticatedView: FC = () => {
|
||||
const { setClient } = useClient();
|
||||
@@ -85,11 +84,7 @@ export const UnauthenticatedView: FC = () => {
|
||||
|
||||
let createRoomResult;
|
||||
try {
|
||||
createRoomResult = await createRoom(
|
||||
client,
|
||||
roomName,
|
||||
E2eeType.SHARED_KEY,
|
||||
);
|
||||
createRoomResult = await createRoom(client, roomName, true);
|
||||
} catch (error) {
|
||||
if (!setClient) {
|
||||
throw error;
|
||||
|
||||
@@ -17,7 +17,6 @@ limitations under the License.
|
||||
import {
|
||||
AudioCaptureOptions,
|
||||
ConnectionState,
|
||||
LocalTrack,
|
||||
Room,
|
||||
RoomEvent,
|
||||
Track,
|
||||
@@ -56,6 +55,8 @@ async function doConnect(
|
||||
audioEnabled: boolean,
|
||||
audioOptions: AudioCaptureOptions,
|
||||
): Promise<void> {
|
||||
await livekitRoom!.connect(sfuConfig!.url, sfuConfig!.jwt);
|
||||
|
||||
// Always create an audio track manually.
|
||||
// livekit (by default) keeps the mic track open when you mute, but if you start muted,
|
||||
// doesn't publish it until you unmute. We want to publish it from the start so we're
|
||||
@@ -81,60 +82,15 @@ async function doConnect(
|
||||
}
|
||||
if (!audioEnabled) await audioTracks[0].mute();
|
||||
|
||||
logger.info("Pre-created microphone track");
|
||||
|
||||
// check again having awaited for the track to create
|
||||
if (livekitRoom!.localParticipant.getTrack(Track.Source.Microphone)) {
|
||||
logger.warn(
|
||||
"Publishing pre-created audio track but participant already appears to have an microphone track: this shouldn't happen!",
|
||||
);
|
||||
for (const t of audioTracks) {
|
||||
t.stop();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
logger.info("Connecting & publishing");
|
||||
try {
|
||||
await connectAndPublish(livekitRoom, sfuConfig, audioTracks[0], []);
|
||||
} catch (e) {
|
||||
for (const t of audioTracks) {
|
||||
t.stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect to the SFU and publish specific tracks, if provided.
|
||||
* This is very specific to what we need to do: for instance, we don't
|
||||
* currently have a need to prepublish video tracks. We just prepublish
|
||||
* a mic track at the start of a call and copy any srceenshare tracks over
|
||||
* when switching focus (because we can't re-acquire them without the user
|
||||
* going through the dialog to choose them again).
|
||||
*/
|
||||
async function connectAndPublish(
|
||||
livekitRoom: Room,
|
||||
sfuConfig: SFUConfig,
|
||||
micTrack: LocalTrack | undefined,
|
||||
screenshareTracks: MediaStreamTrack[],
|
||||
): Promise<void> {
|
||||
await livekitRoom!.connect(sfuConfig!.url, sfuConfig!.jwt);
|
||||
|
||||
if (micTrack) {
|
||||
logger.info(`Publishing precreated mic track`);
|
||||
await livekitRoom.localParticipant.publishTrack(micTrack, {
|
||||
source: Track.Source.Microphone,
|
||||
});
|
||||
}
|
||||
|
||||
logger.info(
|
||||
`Publishing ${screenshareTracks.length} precreated screenshare tracks`,
|
||||
);
|
||||
for (const st of screenshareTracks) {
|
||||
livekitRoom.localParticipant.publishTrack(st, {
|
||||
source: Track.Source.ScreenShare,
|
||||
});
|
||||
}
|
||||
logger.info("Publishing pre-created mic track");
|
||||
await livekitRoom?.localParticipant.publishTrack(audioTracks[0]);
|
||||
}
|
||||
|
||||
export function useECConnectionState(
|
||||
@@ -170,33 +126,6 @@ export function useECConnectionState(
|
||||
};
|
||||
}, [livekitRoom, onConnStateChanged]);
|
||||
|
||||
const doFocusSwitch = useCallback(async (): Promise<void> => {
|
||||
const screenshareTracks: MediaStreamTrack[] = [];
|
||||
for (const t of livekitRoom!.localParticipant.videoTracks.values()) {
|
||||
if (t.track && t.source == Track.Source.ScreenShare) {
|
||||
const newTrack = t.track.mediaStreamTrack.clone();
|
||||
newTrack.enabled = true;
|
||||
screenshareTracks.push(newTrack);
|
||||
}
|
||||
}
|
||||
|
||||
// Flag that we're currently switching focus. This will get reset when the
|
||||
// connection state changes back to connected in onConnStateChanged above.
|
||||
setSwitchingFocus(true);
|
||||
await livekitRoom?.disconnect();
|
||||
setIsInDoConnect(true);
|
||||
try {
|
||||
await connectAndPublish(
|
||||
livekitRoom!,
|
||||
sfuConfig!,
|
||||
undefined,
|
||||
screenshareTracks,
|
||||
);
|
||||
} finally {
|
||||
setIsInDoConnect(false);
|
||||
}
|
||||
}, [livekitRoom, sfuConfig]);
|
||||
|
||||
const currentSFUConfig = useRef(Object.assign({}, sfuConfig));
|
||||
|
||||
// Id we are transitioning from a valid config to another valid one, we need
|
||||
@@ -211,7 +140,21 @@ export function useECConnectionState(
|
||||
`SFU config changed! URL was ${currentSFUConfig.current?.url} now ${sfuConfig?.url}`,
|
||||
);
|
||||
|
||||
doFocusSwitch();
|
||||
(async (): Promise<void> => {
|
||||
setSwitchingFocus(true);
|
||||
await livekitRoom?.disconnect();
|
||||
setIsInDoConnect(true);
|
||||
try {
|
||||
await doConnect(
|
||||
livekitRoom!,
|
||||
sfuConfig!,
|
||||
initialAudioEnabled,
|
||||
initialAudioOptions,
|
||||
);
|
||||
} finally {
|
||||
setIsInDoConnect(false);
|
||||
}
|
||||
})();
|
||||
} else if (
|
||||
!sfuConfigValid(currentSFUConfig.current) &&
|
||||
sfuConfigValid(sfuConfig)
|
||||
@@ -232,13 +175,7 @@ export function useECConnectionState(
|
||||
}
|
||||
|
||||
currentSFUConfig.current = Object.assign({}, sfuConfig);
|
||||
}, [
|
||||
sfuConfig,
|
||||
livekitRoom,
|
||||
initialAudioOptions,
|
||||
initialAudioEnabled,
|
||||
doFocusSwitch,
|
||||
]);
|
||||
}, [sfuConfig, livekitRoom, initialAudioOptions, initialAudioEnabled]);
|
||||
|
||||
// Because we create audio tracks by hand, there's more to connecting than
|
||||
// just what LiveKit does in room.connect, and we should continue to return
|
||||
|
||||
@@ -22,10 +22,10 @@ import {
|
||||
RoomOptions,
|
||||
Track,
|
||||
} from "livekit-client";
|
||||
import { useEffect, useMemo, useRef } from "react";
|
||||
import { useLiveKitRoom } from "@livekit/components-react";
|
||||
import { useEffect, useMemo, useRef, useState } from "react";
|
||||
import E2EEWorker from "livekit-client/e2ee-worker?worker";
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
import { MatrixRTCSession } from "matrix-js-sdk/src/matrixrtc/MatrixRTCSession";
|
||||
|
||||
import { defaultLiveKitOptions } from "./options";
|
||||
import { SFUConfig } from "./openIDSFU";
|
||||
@@ -39,12 +39,9 @@ import {
|
||||
ECConnectionState,
|
||||
useECConnectionState,
|
||||
} from "./useECConnectionState";
|
||||
import { MatrixKeyProvider } from "../e2ee/matrixKeyProvider";
|
||||
import { E2eeType } from "../e2ee/e2eeType";
|
||||
|
||||
export type E2EEConfig = {
|
||||
mode: E2eeType;
|
||||
sharedKey?: string;
|
||||
sharedKey: string;
|
||||
};
|
||||
|
||||
interface UseLivekitResult {
|
||||
@@ -53,44 +50,26 @@ interface UseLivekitResult {
|
||||
}
|
||||
|
||||
export function useLiveKit(
|
||||
rtcSession: MatrixRTCSession,
|
||||
muteStates: MuteStates,
|
||||
sfuConfig: SFUConfig | undefined,
|
||||
e2eeConfig: E2EEConfig,
|
||||
sfuConfig?: SFUConfig,
|
||||
e2eeConfig?: E2EEConfig,
|
||||
): UseLivekitResult {
|
||||
const e2eeOptions = useMemo((): E2EEOptions | undefined => {
|
||||
if (e2eeConfig.mode === E2eeType.NONE) return undefined;
|
||||
const e2eeOptions = useMemo(() => {
|
||||
if (!e2eeConfig?.sharedKey) return undefined;
|
||||
|
||||
if (e2eeConfig.mode === E2eeType.PER_PARTICIPANT) {
|
||||
return {
|
||||
keyProvider: new MatrixKeyProvider(),
|
||||
worker: new E2EEWorker(),
|
||||
};
|
||||
} else if (
|
||||
e2eeConfig.mode === E2eeType.SHARED_KEY &&
|
||||
e2eeConfig.sharedKey
|
||||
) {
|
||||
return {
|
||||
keyProvider: new ExternalE2EEKeyProvider(),
|
||||
worker: new E2EEWorker(),
|
||||
};
|
||||
}
|
||||
return {
|
||||
keyProvider: new ExternalE2EEKeyProvider(),
|
||||
worker: new E2EEWorker(),
|
||||
} as E2EEOptions;
|
||||
}, [e2eeConfig]);
|
||||
|
||||
useEffect(() => {
|
||||
if (e2eeConfig.mode === E2eeType.NONE || !e2eeOptions) return;
|
||||
if (!e2eeConfig?.sharedKey || !e2eeOptions) return;
|
||||
|
||||
if (e2eeConfig.mode === E2eeType.PER_PARTICIPANT) {
|
||||
(e2eeOptions.keyProvider as MatrixKeyProvider).setRTCSession(rtcSession);
|
||||
} else if (
|
||||
e2eeConfig.mode === E2eeType.SHARED_KEY &&
|
||||
e2eeConfig.sharedKey
|
||||
) {
|
||||
(e2eeOptions.keyProvider as ExternalE2EEKeyProvider).setKey(
|
||||
e2eeConfig.sharedKey,
|
||||
);
|
||||
}
|
||||
}, [e2eeOptions, e2eeConfig, rtcSession]);
|
||||
(e2eeOptions.keyProvider as ExternalE2EEKeyProvider).setKey(
|
||||
e2eeConfig?.sharedKey,
|
||||
);
|
||||
}, [e2eeOptions, e2eeConfig?.sharedKey]);
|
||||
|
||||
const initialMuteStates = useRef<MuteStates>(muteStates);
|
||||
const devices = useMediaDevices();
|
||||
@@ -117,6 +96,11 @@ export function useLiveKit(
|
||||
[e2eeOptions],
|
||||
);
|
||||
|
||||
// useECConnectionState creates and publishes an audio track by hand. To keep
|
||||
// this from racing with LiveKit's automatic creation of the audio track, we
|
||||
// block audio from being enabled until the connection is finished.
|
||||
const [blockAudio, setBlockAudio] = useState(true);
|
||||
|
||||
// Store if audio/video are currently updating. If to prohibit unnecessary calls
|
||||
// to setMicrophoneEnabled/setCameraEnabled
|
||||
const audioMuteUpdating = useRef(false);
|
||||
@@ -131,11 +115,15 @@ export function useLiveKit(
|
||||
// We have to create the room manually here due to a bug inside
|
||||
// @livekit/components-react. JSON.stringify() is used in deps of a
|
||||
// useEffect() with an argument that references itself, if E2EE is enabled
|
||||
const room = useMemo(() => {
|
||||
const r = new Room(roomOptions);
|
||||
r.setE2EEEnabled(e2eeConfig.mode !== E2eeType.NONE);
|
||||
return r;
|
||||
}, [roomOptions, e2eeConfig]);
|
||||
const roomWithoutProps = useMemo(() => new Room(roomOptions), [roomOptions]);
|
||||
const { room } = useLiveKitRoom({
|
||||
token: sfuConfig?.jwt,
|
||||
serverUrl: sfuConfig?.url,
|
||||
audio: initialMuteStates.current.audio.enabled && !blockAudio,
|
||||
video: initialMuteStates.current.video.enabled,
|
||||
room: roomWithoutProps,
|
||||
connect: false,
|
||||
});
|
||||
|
||||
const connectionState = useECConnectionState(
|
||||
{
|
||||
@@ -146,6 +134,11 @@ export function useLiveKit(
|
||||
sfuConfig,
|
||||
);
|
||||
|
||||
// Unblock audio once the connection is finished
|
||||
useEffect(() => {
|
||||
if (connectionState === ConnectionState.Connected) setBlockAudio(false);
|
||||
}, [connectionState, setBlockAudio]);
|
||||
|
||||
useEffect(() => {
|
||||
// Sync the requested mute states with LiveKit's mute states. We do it this
|
||||
// way around rather than using LiveKit as the source of truth, so that the
|
||||
|
||||
@@ -28,7 +28,6 @@ import {
|
||||
GroupCallIntent,
|
||||
GroupCallType,
|
||||
} from "matrix-js-sdk/src/webrtc/groupCall";
|
||||
import { secureRandomBase64Url } from "matrix-js-sdk/src/randomstring";
|
||||
|
||||
import type { MatrixClient } from "matrix-js-sdk/src/client";
|
||||
import type { Room } from "matrix-js-sdk/src/models/room";
|
||||
@@ -38,7 +37,6 @@ import { loadOlm } from "./olm";
|
||||
import { Config } from "./config/Config";
|
||||
import { setLocalStorageItem } from "./useLocalStorage";
|
||||
import { getRoomSharedKeyLocalStorageKey } from "./e2ee/sharedKeyManagement";
|
||||
import { E2eeType } from "./e2ee/e2eeType";
|
||||
|
||||
export const fallbackICEServerAllowed =
|
||||
import.meta.env.VITE_FALLBACK_STUN_ALLOWED === "true";
|
||||
@@ -75,6 +73,23 @@ function waitForSync(client: MatrixClient): Promise<void> {
|
||||
});
|
||||
}
|
||||
|
||||
function secureRandomString(entropyBytes: number): string {
|
||||
const key = new Uint8Array(entropyBytes);
|
||||
crypto.getRandomValues(key);
|
||||
// encode to base64url as this value goes into URLs
|
||||
// base64url is just base64 with thw two non-alphanum characters swapped out for
|
||||
// ones that can be put in a URL without encoding. Browser JS has a native impl
|
||||
// for base64 encoding but only a string (there isn't one that takes a UInt8Array
|
||||
// yet) so just use the built-in one and convert, replace the chars and strip the
|
||||
// padding from the end (otherwise we'd need to pull in another dependency).
|
||||
return btoa(
|
||||
key.reduce((acc, current) => acc + String.fromCharCode(current), ""),
|
||||
)
|
||||
.replace("+", "-")
|
||||
.replace("/", "_")
|
||||
.replace(/=*$/, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialises and returns a new standalone Matrix Client.
|
||||
* If true is passed for the 'restore' parameter, a check will be made
|
||||
@@ -279,20 +294,10 @@ interface CreateRoomResult {
|
||||
password?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new room ready for calls
|
||||
*
|
||||
* @param client Matrix client to use
|
||||
* @param name The name of the room
|
||||
* @param e2ee The type of e2ee call to create. Note that we would currently never
|
||||
* create a room for per-participant e2ee calls: since it's used in
|
||||
* embedded mode, we use the existing room.
|
||||
* @returns Object holding information about the new room
|
||||
*/
|
||||
export async function createRoom(
|
||||
client: MatrixClient,
|
||||
name: string,
|
||||
e2ee: E2eeType,
|
||||
e2ee: boolean,
|
||||
): Promise<CreateRoomResult> {
|
||||
logger.log(`Creating room for group call`);
|
||||
const createPromise = client.createRoom({
|
||||
@@ -357,8 +362,8 @@ export async function createRoom(
|
||||
);
|
||||
|
||||
let password;
|
||||
if (e2ee == E2eeType.SHARED_KEY) {
|
||||
password = secureRandomBase64Url(16);
|
||||
if (e2ee) {
|
||||
password = secureRandomString(16);
|
||||
setLocalStorageItem(
|
||||
getRoomSharedKeyLocalStorageKey(result.room_id),
|
||||
password,
|
||||
|
||||
@@ -44,9 +44,6 @@ import { useRoomAvatar } from "./useRoomAvatar";
|
||||
import { useRoomName } from "./useRoomName";
|
||||
import { useJoinRule } from "./useJoinRule";
|
||||
import { InviteModal } from "./InviteModal";
|
||||
import { E2EEConfig } from "../livekit/useLiveKit";
|
||||
import { useUrlParams } from "../UrlParams";
|
||||
import { E2eeType } from "../e2ee/e2eeType";
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
@@ -90,7 +87,6 @@ export const GroupCallView: FC<Props> = ({
|
||||
const roomName = useRoomName(rtcSession.room);
|
||||
const roomAvatar = useRoomAvatar(rtcSession.room);
|
||||
const roomEncrypted = useIsRoomE2EE(rtcSession.room.roomId)!;
|
||||
const { perParticipantE2EE } = useUrlParams();
|
||||
|
||||
const matrixInfo = useMemo((): MatrixInfo => {
|
||||
return {
|
||||
@@ -186,7 +182,7 @@ export const GroupCallView: FC<Props> = ({
|
||||
ev: CustomEvent<IWidgetApiRequest>,
|
||||
): Promise<void> => {
|
||||
defaultDeviceSetup(ev.detail.data as unknown as JoinCallData);
|
||||
enterRTCSession(rtcSession, perParticipantE2EE);
|
||||
enterRTCSession(rtcSession);
|
||||
await Promise.all([
|
||||
widget!.api.setAlwaysOnScreen(true),
|
||||
widget!.api.transport.reply(ev.detail, {}),
|
||||
@@ -199,9 +195,9 @@ export const GroupCallView: FC<Props> = ({
|
||||
} else {
|
||||
// if we don't use preload and only skipLobby we enter the rtc session right away
|
||||
defaultDeviceSetup({ audioInput: null, videoInput: null });
|
||||
enterRTCSession(rtcSession, perParticipantE2EE);
|
||||
enterRTCSession(rtcSession);
|
||||
}
|
||||
}, [rtcSession, preload, skipLobby, perParticipantE2EE]);
|
||||
}, [rtcSession, preload, skipLobby]);
|
||||
|
||||
const [left, setLeft] = useState(false);
|
||||
const [leaveError, setLeaveError] = useState<Error | undefined>(undefined);
|
||||
@@ -249,21 +245,16 @@ export const GroupCallView: FC<Props> = ({
|
||||
}
|
||||
}, [isJoined, rtcSession]);
|
||||
|
||||
const e2eeConfig = useMemo((): E2EEConfig => {
|
||||
if (perParticipantE2EE) {
|
||||
return { mode: E2eeType.PER_PARTICIPANT };
|
||||
} else if (e2eeSharedKey) {
|
||||
return { mode: E2eeType.SHARED_KEY, sharedKey: e2eeSharedKey };
|
||||
} else {
|
||||
return { mode: E2eeType.NONE };
|
||||
}
|
||||
}, [perParticipantE2EE, e2eeSharedKey]);
|
||||
const e2eeConfig = useMemo(
|
||||
() => (e2eeSharedKey ? { sharedKey: e2eeSharedKey } : undefined),
|
||||
[e2eeSharedKey],
|
||||
);
|
||||
|
||||
const onReconnect = useCallback(() => {
|
||||
setLeft(false);
|
||||
setLeaveError(undefined);
|
||||
enterRTCSession(rtcSession, perParticipantE2EE);
|
||||
}, [rtcSession, perParticipantE2EE]);
|
||||
enterRTCSession(rtcSession);
|
||||
}, [rtcSession]);
|
||||
|
||||
const joinRule = useJoinRule(rtcSession.room);
|
||||
|
||||
@@ -289,7 +280,7 @@ export const GroupCallView: FC<Props> = ({
|
||||
|
||||
const { t } = useTranslation();
|
||||
|
||||
if (isRoomE2EE && !perParticipantE2EE && !e2eeSharedKey) {
|
||||
if (isRoomE2EE && !e2eeSharedKey) {
|
||||
return (
|
||||
<ErrorView
|
||||
error={
|
||||
@@ -379,7 +370,7 @@ export const GroupCallView: FC<Props> = ({
|
||||
client={client}
|
||||
matrixInfo={matrixInfo}
|
||||
muteStates={muteStates}
|
||||
onEnter={(): void => enterRTCSession(rtcSession, perParticipantE2EE)}
|
||||
onEnter={(): void => enterRTCSession(rtcSession)}
|
||||
confineToRoom={confineToRoom}
|
||||
hideHeader={hideHeader}
|
||||
participantCount={participantCount}
|
||||
|
||||
@@ -95,13 +95,12 @@ const POST_FOCUS_PARTICIPANT_UPDATE_DELAY_MS = 3000;
|
||||
|
||||
export interface ActiveCallProps
|
||||
extends Omit<InCallViewProps, "livekitRoom" | "connState"> {
|
||||
e2eeConfig: E2EEConfig;
|
||||
e2eeConfig?: E2EEConfig;
|
||||
}
|
||||
|
||||
export const ActiveCall: FC<ActiveCallProps> = (props) => {
|
||||
const sfuConfig = useOpenIDSFU(props.client, props.rtcSession);
|
||||
const { livekitRoom, connState } = useLiveKit(
|
||||
props.rtcSession,
|
||||
props.muteStates,
|
||||
sfuConfig,
|
||||
props.e2eeConfig,
|
||||
@@ -111,6 +110,10 @@ export const ActiveCall: FC<ActiveCallProps> = (props) => {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (props.e2eeConfig && !livekitRoom.isE2EEEnabled) {
|
||||
livekitRoom.setE2EEEnabled(!!props.e2eeConfig);
|
||||
}
|
||||
|
||||
return (
|
||||
<RoomContext.Provider value={livekitRoom}>
|
||||
<InCallView {...props} livekitRoom={livekitRoom} connState={connState} />
|
||||
@@ -200,12 +203,8 @@ export const InCallView: FC<InCallViewProps> = ({
|
||||
);
|
||||
|
||||
const onLeavePress = useCallback(() => {
|
||||
// Disconnect from the room. We don't do this in onLeave because that's
|
||||
// also called on an unintentional disconnect. Plus we don't have the
|
||||
// livekit room in onLeave anyway.
|
||||
livekitRoom.disconnect();
|
||||
onLeave();
|
||||
}, [livekitRoom, onLeave]);
|
||||
}, [onLeave]);
|
||||
|
||||
useEffect(() => {
|
||||
widget?.api.transport.send(
|
||||
|
||||
@@ -34,10 +34,7 @@ function makeFocus(livekitAlias: string): LivekitFocus {
|
||||
};
|
||||
}
|
||||
|
||||
export function enterRTCSession(
|
||||
rtcSession: MatrixRTCSession,
|
||||
encryptMedia: boolean,
|
||||
): void {
|
||||
export function enterRTCSession(rtcSession: MatrixRTCSession): void {
|
||||
PosthogAnalytics.instance.eventCallEnded.cacheStartCall(new Date());
|
||||
PosthogAnalytics.instance.eventCallStarted.track(rtcSession.room.roomId);
|
||||
|
||||
@@ -48,7 +45,7 @@ export function enterRTCSession(
|
||||
// right now we assume everything is a room-scoped call
|
||||
const livekitAlias = rtcSession.room.roomId;
|
||||
|
||||
rtcSession.joinRoomSession([makeFocus(livekitAlias)], encryptMedia);
|
||||
rtcSession.joinRoomSession([makeFocus(livekitAlias)]);
|
||||
}
|
||||
|
||||
const widgetPostHangupProcedure = async (
|
||||
|
||||
@@ -77,8 +77,6 @@ export const widget = ((): WidgetHelpers | null => {
|
||||
logger.info("Widget API is available");
|
||||
const api = new WidgetApi(widgetId, parentOrigin);
|
||||
api.requestCapability(MatrixCapabilities.AlwaysOnScreen);
|
||||
api.requestCapabilityToSendEvent(EventType.CallEncryptionKeysPrefix);
|
||||
api.requestCapabilityToReceiveEvent(EventType.CallEncryptionKeysPrefix);
|
||||
|
||||
// Set up the lazy action emitter, but only for select actions that we
|
||||
// intend for the app to handle
|
||||
|
||||
223
yarn.lock
223
yarn.lock
@@ -2010,10 +2010,10 @@
|
||||
clsx "^2.0.0"
|
||||
usehooks-ts "^2.9.1"
|
||||
|
||||
"@matrix-org/matrix-sdk-crypto-wasm@^2.2.0":
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/@matrix-org/matrix-sdk-crypto-wasm/-/matrix-sdk-crypto-wasm-2.2.0.tgz#7c60afe01915281a6b71502821bc8e01afbfa70d"
|
||||
integrity sha512-txmvaTiZpVV0/kWCRcE7tZvRESCEc1ynLJDVh9OUsFlaXfl13c7qdD3E6IJEJ8YiPMIn+PHogdfBZsO84reaMg==
|
||||
"@matrix-org/matrix-sdk-crypto-wasm@^1.2.3-alpha.0":
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/@matrix-org/matrix-sdk-crypto-wasm/-/matrix-sdk-crypto-wasm-1.3.0.tgz#f098c72701801334eeb7049ca7074fe6eb3686d6"
|
||||
integrity sha512-vQ5PVppKu1PY7xy7QDw+RJLYLGFKhJyxLqjXHr0uEUJwfvz2IH2njTLXzrz77dOo9qacxJ9/YNOTe0Hl+98N0A==
|
||||
|
||||
"@matrix-org/olm@https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.14.tgz":
|
||||
version "3.2.14"
|
||||
@@ -3304,19 +3304,19 @@
|
||||
"@babel/types" "^7.20.7"
|
||||
|
||||
"@types/caseless@*":
|
||||
version "0.12.5"
|
||||
resolved "https://registry.yarnpkg.com/@types/caseless/-/caseless-0.12.5.tgz#db9468cb1b1b5a925b8f34822f1669df0c5472f5"
|
||||
integrity sha512-hWtVTC2q7hc7xZ/RLbxapMvDMgUnDvKvMOpKal4DrMyfGBUfB1oKaZlIRr6mJL+If3bAP6sV/QneGzF6tJjZDg==
|
||||
version "0.12.4"
|
||||
resolved "https://registry.yarnpkg.com/@types/caseless/-/caseless-0.12.4.tgz#1326429a519cc077028150343fd502b04686bd6f"
|
||||
integrity sha512-2in/lrHRNmDvHPgyormtEralhPcN3An1gLjJzj2Bw145VBxkQ75JEXW6CTdMAwShiHQcYsl2d10IjQSdJSJz4g==
|
||||
|
||||
"@types/content-type@^1.1.5":
|
||||
version "1.1.8"
|
||||
resolved "https://registry.yarnpkg.com/@types/content-type/-/content-type-1.1.8.tgz#319644d07ee6b4bfc734483008393b89b99f0219"
|
||||
integrity sha512-1tBhmVUeso3+ahfyaKluXe38p+94lovUZdoVfQ3OnJo9uJC42JT7CBoN3k9HYhAae+GwiBYmHu+N9FZhOG+2Pg==
|
||||
version "1.1.7"
|
||||
resolved "https://registry.yarnpkg.com/@types/content-type/-/content-type-1.1.7.tgz#1e74d573f0d0bd5a6076ff44c6080212fca55a5b"
|
||||
integrity sha512-dSM/IQ1fgM1aSQ2PlHR4uWQGDjs9SY+/ilm228CIs9hwlyIfW+q5asThulBforWR6ktt/o8L8m6GPW/Fz1dk2A==
|
||||
|
||||
"@types/dom-screen-wake-lock@^1.0.1":
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/dom-screen-wake-lock/-/dom-screen-wake-lock-1.0.3.tgz#c3588a5f6f40fae957f9ce5be9bc4927a61bb9a0"
|
||||
integrity sha512-3Iten7X3Zgwvk6kh6/NRdwN7WbZ760YgFCsF5AxDifltUQzW1RaW+WRmcVtgwFzLjaNu64H+0MPJ13yRa8g3Dw==
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/@types/dom-screen-wake-lock/-/dom-screen-wake-lock-1.0.2.tgz#df0f77b1a653f66fba7ab38e962ff8440682fb61"
|
||||
integrity sha512-fgOIOXxoa3bHb4dPWrRA8xMCccrxRpqIOXBA0KAFR+/j11fYRGgJUh7qoyF38UAwn8//xwgUHKMvNKDfVGydAQ==
|
||||
|
||||
"@types/dompurify@^3.0.2":
|
||||
version "3.0.5"
|
||||
@@ -3352,34 +3352,29 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/history/-/history-4.7.11.tgz#56588b17ae8f50c53983a524fc3cc47437969d64"
|
||||
integrity sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA==
|
||||
|
||||
"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0":
|
||||
version "2.0.6"
|
||||
resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz#7739c232a1fee9b4d3ce8985f314c0c6d33549d7"
|
||||
integrity sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==
|
||||
|
||||
"@types/istanbul-lib-coverage@^2.0.1":
|
||||
"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1":
|
||||
version "2.0.5"
|
||||
resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz#fdfdd69fa16d530047d9963635bd77c71a08c068"
|
||||
integrity sha512-zONci81DZYCZjiLe0r6equvZut0b+dBRPBN5kBDjsONnutYNtJMoWQ9uR2RkL1gLG9NMTzvf+29e5RFfPbeKhQ==
|
||||
|
||||
"@types/istanbul-lib-report@*":
|
||||
version "3.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz#53047614ae72e19fc0401d872de3ae2b4ce350bf"
|
||||
integrity sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.2.tgz#394798d5f727402eb5ec99eb9618ffcd2b7645a1"
|
||||
integrity sha512-8toY6FgdltSdONav1XtUHl4LN1yTmLza+EuDazb/fEmRNCwjyqNVIQWs2IfC74IqjHkREs/nQ2FWq5kZU9IC0w==
|
||||
dependencies:
|
||||
"@types/istanbul-lib-coverage" "*"
|
||||
|
||||
"@types/istanbul-reports@^3.0.0":
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz#0f03e3d2f670fbdac586e34b433783070cc16f54"
|
||||
integrity sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==
|
||||
version "3.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.3.tgz#0313e2608e6d6955d195f55361ddeebd4b74c6e7"
|
||||
integrity sha512-1nESsePMBlf0RPRffLZi5ujYh7IH1BWL4y9pr+Bn3cJBdxz+RTP8bUFljLz9HvzhhOSWKdyBZ4DIivdL6rvgZg==
|
||||
dependencies:
|
||||
"@types/istanbul-lib-report" "*"
|
||||
|
||||
"@types/jest@^29.5.5":
|
||||
version "29.5.8"
|
||||
resolved "https://registry.yarnpkg.com/@types/jest/-/jest-29.5.8.tgz#ed5c256fe2bc7c38b1915ee5ef1ff24a3427e120"
|
||||
integrity sha512-fXEFTxMV2Co8ZF5aYFJv+YeA08RTYJfhtN5c9JSv/mFEMe+xxjufCb+PHL+bJcMs/ebPUsBu+UNTEz+ydXrR6g==
|
||||
version "29.5.7"
|
||||
resolved "https://registry.yarnpkg.com/@types/jest/-/jest-29.5.7.tgz#2c0dafe2715dd958a455bc10e2ec3e1ec47b5036"
|
||||
integrity sha512-HLyetab6KVPSiF+7pFcUyMeLsx25LDNDemw9mGsJBkai/oouwrjTycocSDYopMEwFhN2Y4s9oPyOCZNofgSt2g==
|
||||
dependencies:
|
||||
expect "^29.0.0"
|
||||
pretty-format "^29.0.0"
|
||||
@@ -3409,9 +3404,9 @@
|
||||
integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==
|
||||
|
||||
"@types/lodash@^4.14.199":
|
||||
version "4.14.201"
|
||||
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.201.tgz#76f47cb63124e806824b6c18463daf3e1d480239"
|
||||
integrity sha512-y9euML0cim1JrykNxADLfaG0FgD1g/yTHwUs/Jg9ZIU7WKj2/4IW9Lbb1WZbvck78W/lfGXFfe+u2EGfIJXdLQ==
|
||||
version "4.14.200"
|
||||
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.200.tgz#435b6035c7eba9cdf1e039af8212c9e9281e7149"
|
||||
integrity sha512-YI/M/4HRImtNf3pJgbF+W6FrXovqj+T+/HpENLTooK9PnkacBsDpeP3IpHab40CClUfhNmdM2WTNP2sa2dni5Q==
|
||||
|
||||
"@types/minimatch@^3.0.3":
|
||||
version "3.0.5"
|
||||
@@ -3419,9 +3414,9 @@
|
||||
integrity sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==
|
||||
|
||||
"@types/node@*", "@types/node@^20.0.0":
|
||||
version "20.9.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-20.9.0.tgz#bfcdc230583aeb891cf51e73cfdaacdd8deae298"
|
||||
integrity sha512-nekiGu2NDb1BcVofVcEKMIwzlx4NjHlcjhoxxKBNLtz15Y1z7MYf549DFvkHSId02Ax6kGwWntIBPC3l/JZcmw==
|
||||
version "20.8.10"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-20.8.10.tgz#a5448b895c753ae929c26ce85cab557c6d4a365e"
|
||||
integrity sha512-TlgT8JntpcbmKUFzjhsyhGfP2fsiz1Mv56im6enJ905xG1DAYesxJaeSbGqQmAw8OWPdhyJGhGSQGKRNJ45u9w==
|
||||
dependencies:
|
||||
undici-types "~5.26.4"
|
||||
|
||||
@@ -3474,9 +3469,9 @@
|
||||
csstype "^3.0.2"
|
||||
|
||||
"@types/request@^2.48.8":
|
||||
version "2.48.12"
|
||||
resolved "https://registry.yarnpkg.com/@types/request/-/request-2.48.12.tgz#0f590f615a10f87da18e9790ac94c29ec4c5ef30"
|
||||
integrity sha512-G3sY+NpsA9jnwm0ixhAFQSJ3Q9JkpLZpJbI3GMv0mIAT0y3mRabYeINzal5WOChIiaTEGQYlHOKgkaM9EisWHw==
|
||||
version "2.48.11"
|
||||
resolved "https://registry.yarnpkg.com/@types/request/-/request-2.48.11.tgz#04b597ea308418422f7901c9a52b24967a2c4ed2"
|
||||
integrity sha512-HuihY1+Vss5RS9ZHzRyTGIzwPTdrJBkCm/mAeLRYrOQu/MGqyezKXWOK1VhCnR+SDbp9G2mRUP+OVEqCrzpcfA==
|
||||
dependencies:
|
||||
"@types/caseless" "*"
|
||||
"@types/node" "*"
|
||||
@@ -3509,9 +3504,9 @@
|
||||
integrity sha512-hsughtxFsdJ9+Gxd/qH8zHE+KT6YEAxx9hJLoSXhxTBKHMQ2NMhN23fRJ75M9RRn2hDMNn13H3gS1EktA9VgDA==
|
||||
|
||||
"@types/stack-utils@^2.0.0":
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.3.tgz#6209321eb2c1712a7e7466422b8cb1fc0d9dd5d8"
|
||||
integrity sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.2.tgz#01284dde9ef4e6d8cef6422798d9a3ad18a66f8b"
|
||||
integrity sha512-g7CK9nHdwjK2n0ymT2CW698FuWJRIx+RP6embAzZ2Qi8/ilIrA1Imt2LVSeHUzKvpoi7BhmmQcXz95eS0f2JXw==
|
||||
|
||||
"@types/symlink-or-copy@^1.2.0":
|
||||
version "1.2.1"
|
||||
@@ -3519,9 +3514,9 @@
|
||||
integrity sha512-8LQKxlJ8zXQ5U0wFXTSBXLHg8+oBbLMJXEC6vOqhL+iz8EfVvSxfdwtvq8ufkT9pumab0ntnvYXQBF/+cxzl9w==
|
||||
|
||||
"@types/tough-cookie@*":
|
||||
version "4.0.4"
|
||||
resolved "https://registry.yarnpkg.com/@types/tough-cookie/-/tough-cookie-4.0.4.tgz#cf2f0c7c51b985b6afecea73eb2cd65421ecb717"
|
||||
integrity sha512-95Sfz4nvMAb0Nl9DTxN3j64adfwfbBPEYq14VN7zT5J5O2M9V6iZMIIQU1U+pJyl9agHYHNCqhCXgyEtIRRa5A==
|
||||
version "4.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/tough-cookie/-/tough-cookie-4.0.3.tgz#3d06b6769518450871fbc40770b7586334bdfd90"
|
||||
integrity sha512-THo502dA5PzG/sfQH+42Lw3fvmYkceefOspdCwpHRul8ik2Jv1K8I5OZz1AT3/rs46kwgMCe9bSBmDLYkkOMGg==
|
||||
|
||||
"@types/trusted-types@*":
|
||||
version "2.0.5"
|
||||
@@ -3529,32 +3524,32 @@
|
||||
integrity sha512-I3pkr8j/6tmQtKV/ZzHtuaqYSQvyjGRKH4go60Rr0IDLlFxuRT5V32uvB1mecM5G1EVAUyF/4r4QZ1GHgz+mxA==
|
||||
|
||||
"@types/uuid@9":
|
||||
version "9.0.7"
|
||||
resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-9.0.7.tgz#b14cebc75455eeeb160d5fe23c2fcc0c64f724d8"
|
||||
integrity sha512-WUtIVRUZ9i5dYXefDEAI7sh9/O7jGvHg7Df/5O/gtH3Yabe5odI3UWopVR1qbPXQtvOxWu3mM4XxlYeZtMWF4g==
|
||||
version "9.0.6"
|
||||
resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-9.0.6.tgz#c91ae743d8344a54b2b0c691195f5ff5265f6dfb"
|
||||
integrity sha512-BT2Krtx4xaO6iwzwMFUYvWBWkV2pr37zD68Vmp1CDV196MzczBRxuEpD6Pr395HAgebC/co7hOphs53r8V7jew==
|
||||
|
||||
"@types/yargs-parser@*":
|
||||
version "21.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.3.tgz#815e30b786d2e8f0dcd85fd5bcf5e1a04d008f15"
|
||||
integrity sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==
|
||||
version "21.0.2"
|
||||
resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.2.tgz#7bd04c5da378496ef1695a1008bf8f71847a8b8b"
|
||||
integrity sha512-5qcvofLPbfjmBfKaLfj/+f+Sbd6pN4zl7w7VSVI5uz7m9QZTuB2aZAa2uo1wHFBNN2x6g/SoTkXmd8mQnQF2Cw==
|
||||
|
||||
"@types/yargs@^17.0.8":
|
||||
version "17.0.31"
|
||||
resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.31.tgz#8fd0089803fd55d8a285895a18b88cb71a99683c"
|
||||
integrity sha512-bocYSx4DI8TmdlvxqGpVNXOgCNR1Jj0gNPhhAY+iz1rgKDAaYrAYdFYnhDV1IFuiuVc9HkOwyDcFxaTElF3/wg==
|
||||
version "17.0.29"
|
||||
resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.29.tgz#06aabc72497b798c643c812a8b561537fea760cf"
|
||||
integrity sha512-nacjqA3ee9zRF/++a3FUY1suHTFKZeHba2n8WeDw9cCVdmzmHpIxyzOJBcpHvvEmS8E9KqWlSnWHUkOrkhWcvA==
|
||||
dependencies:
|
||||
"@types/yargs-parser" "*"
|
||||
|
||||
"@typescript-eslint/eslint-plugin@^6.1.0":
|
||||
version "6.10.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.10.0.tgz#cfe2bd34e26d2289212946b96ab19dcad64b661a"
|
||||
integrity sha512-uoLj4g2OTL8rfUQVx2AFO1hp/zja1wABJq77P6IclQs6I/m9GLrm7jCdgzZkvWdDCQf1uEvoa8s8CupsgWQgVg==
|
||||
version "6.9.1"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.9.1.tgz#d8ce497dc0ed42066e195c8ecc40d45c7b1254f4"
|
||||
integrity sha512-w0tiiRc9I4S5XSXXrMHOWgHgxbrBn1Ro+PmiYhSg2ZVdxrAJtQgzU5o2m1BfP6UOn7Vxcc6152vFjQfmZR4xEg==
|
||||
dependencies:
|
||||
"@eslint-community/regexpp" "^4.5.1"
|
||||
"@typescript-eslint/scope-manager" "6.10.0"
|
||||
"@typescript-eslint/type-utils" "6.10.0"
|
||||
"@typescript-eslint/utils" "6.10.0"
|
||||
"@typescript-eslint/visitor-keys" "6.10.0"
|
||||
"@typescript-eslint/scope-manager" "6.9.1"
|
||||
"@typescript-eslint/type-utils" "6.9.1"
|
||||
"@typescript-eslint/utils" "6.9.1"
|
||||
"@typescript-eslint/visitor-keys" "6.9.1"
|
||||
debug "^4.3.4"
|
||||
graphemer "^1.4.0"
|
||||
ignore "^5.2.4"
|
||||
@@ -3563,71 +3558,71 @@
|
||||
ts-api-utils "^1.0.1"
|
||||
|
||||
"@typescript-eslint/parser@^6.1.0":
|
||||
version "6.10.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-6.10.0.tgz#578af79ae7273193b0b6b61a742a2bc8e02f875a"
|
||||
integrity sha512-+sZwIj+s+io9ozSxIWbNB5873OSdfeBEH/FR0re14WLI6BaKuSOnnwCJ2foUiu8uXf4dRp1UqHP0vrZ1zXGrog==
|
||||
version "6.9.1"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-6.9.1.tgz#4f685f672f8b9580beb38d5fb99d52fc3e34f7a3"
|
||||
integrity sha512-C7AK2wn43GSaCUZ9do6Ksgi2g3mwFkMO3Cis96kzmgudoVaKyt62yNzJOktP0HDLb/iO2O0n2lBOzJgr6Q/cyg==
|
||||
dependencies:
|
||||
"@typescript-eslint/scope-manager" "6.10.0"
|
||||
"@typescript-eslint/types" "6.10.0"
|
||||
"@typescript-eslint/typescript-estree" "6.10.0"
|
||||
"@typescript-eslint/visitor-keys" "6.10.0"
|
||||
"@typescript-eslint/scope-manager" "6.9.1"
|
||||
"@typescript-eslint/types" "6.9.1"
|
||||
"@typescript-eslint/typescript-estree" "6.9.1"
|
||||
"@typescript-eslint/visitor-keys" "6.9.1"
|
||||
debug "^4.3.4"
|
||||
|
||||
"@typescript-eslint/scope-manager@6.10.0":
|
||||
version "6.10.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-6.10.0.tgz#b0276118b13d16f72809e3cecc86a72c93708540"
|
||||
integrity sha512-TN/plV7dzqqC2iPNf1KrxozDgZs53Gfgg5ZHyw8erd6jd5Ta/JIEcdCheXFt9b1NYb93a1wmIIVW/2gLkombDg==
|
||||
"@typescript-eslint/scope-manager@6.9.1":
|
||||
version "6.9.1"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-6.9.1.tgz#e96afeb9a68ad1cd816dba233351f61e13956b75"
|
||||
integrity sha512-38IxvKB6NAne3g/+MyXMs2Cda/Sz+CEpmm+KLGEM8hx/CvnSRuw51i8ukfwB/B/sESdeTGet1NH1Wj7I0YXswg==
|
||||
dependencies:
|
||||
"@typescript-eslint/types" "6.10.0"
|
||||
"@typescript-eslint/visitor-keys" "6.10.0"
|
||||
"@typescript-eslint/types" "6.9.1"
|
||||
"@typescript-eslint/visitor-keys" "6.9.1"
|
||||
|
||||
"@typescript-eslint/type-utils@6.10.0":
|
||||
version "6.10.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-6.10.0.tgz#1007faede067c78bdbcef2e8abb31437e163e2e1"
|
||||
integrity sha512-wYpPs3hgTFblMYwbYWPT3eZtaDOjbLyIYuqpwuLBBqhLiuvJ+9sEp2gNRJEtR5N/c9G1uTtQQL5AhV0fEPJYcg==
|
||||
"@typescript-eslint/type-utils@6.9.1":
|
||||
version "6.9.1"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-6.9.1.tgz#efd5db20ed35a74d3c7d8fba51b830ecba09ce32"
|
||||
integrity sha512-eh2oHaUKCK58qIeYp19F5V5TbpM52680sB4zNSz29VBQPTWIlE/hCj5P5B1AChxECe/fmZlspAWFuRniep1Skg==
|
||||
dependencies:
|
||||
"@typescript-eslint/typescript-estree" "6.10.0"
|
||||
"@typescript-eslint/utils" "6.10.0"
|
||||
"@typescript-eslint/typescript-estree" "6.9.1"
|
||||
"@typescript-eslint/utils" "6.9.1"
|
||||
debug "^4.3.4"
|
||||
ts-api-utils "^1.0.1"
|
||||
|
||||
"@typescript-eslint/types@6.10.0":
|
||||
version "6.10.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-6.10.0.tgz#f4f0a84aeb2ac546f21a66c6e0da92420e921367"
|
||||
integrity sha512-36Fq1PWh9dusgo3vH7qmQAj5/AZqARky1Wi6WpINxB6SkQdY5vQoT2/7rW7uBIsPDcvvGCLi4r10p0OJ7ITAeg==
|
||||
"@typescript-eslint/types@6.9.1":
|
||||
version "6.9.1"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-6.9.1.tgz#a6cfc20db0fcedcb2f397ea728ef583e0ee72459"
|
||||
integrity sha512-BUGslGOb14zUHOUmDB2FfT6SI1CcZEJYfF3qFwBeUrU6srJfzANonwRYHDpLBuzbq3HaoF2XL2hcr01c8f8OaQ==
|
||||
|
||||
"@typescript-eslint/typescript-estree@6.10.0":
|
||||
version "6.10.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-6.10.0.tgz#667381eed6f723a1a8ad7590a31f312e31e07697"
|
||||
integrity sha512-ek0Eyuy6P15LJVeghbWhSrBCj/vJpPXXR+EpaRZqou7achUWL8IdYnMSC5WHAeTWswYQuP2hAZgij/bC9fanBg==
|
||||
"@typescript-eslint/typescript-estree@6.9.1":
|
||||
version "6.9.1"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-6.9.1.tgz#8c77910a49a04f0607ba94d78772da07dab275ad"
|
||||
integrity sha512-U+mUylTHfcqeO7mLWVQ5W/tMLXqVpRv61wm9ZtfE5egz7gtnmqVIw9ryh0mgIlkKk9rZLY3UHygsBSdB9/ftyw==
|
||||
dependencies:
|
||||
"@typescript-eslint/types" "6.10.0"
|
||||
"@typescript-eslint/visitor-keys" "6.10.0"
|
||||
"@typescript-eslint/types" "6.9.1"
|
||||
"@typescript-eslint/visitor-keys" "6.9.1"
|
||||
debug "^4.3.4"
|
||||
globby "^11.1.0"
|
||||
is-glob "^4.0.3"
|
||||
semver "^7.5.4"
|
||||
ts-api-utils "^1.0.1"
|
||||
|
||||
"@typescript-eslint/utils@6.10.0":
|
||||
version "6.10.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-6.10.0.tgz#4d76062d94413c30e402c9b0df8c14aef8d77336"
|
||||
integrity sha512-v+pJ1/RcVyRc0o4wAGux9x42RHmAjIGzPRo538Z8M1tVx6HOnoQBCX/NoadHQlZeC+QO2yr4nNSFWOoraZCAyg==
|
||||
"@typescript-eslint/utils@6.9.1":
|
||||
version "6.9.1"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-6.9.1.tgz#763da41281ef0d16974517b5f0d02d85897a1c1e"
|
||||
integrity sha512-L1T0A5nFdQrMVunpZgzqPL6y2wVreSyHhKGZryS6jrEN7bD9NplVAyMryUhXsQ4TWLnZmxc2ekar/lSGIlprCA==
|
||||
dependencies:
|
||||
"@eslint-community/eslint-utils" "^4.4.0"
|
||||
"@types/json-schema" "^7.0.12"
|
||||
"@types/semver" "^7.5.0"
|
||||
"@typescript-eslint/scope-manager" "6.10.0"
|
||||
"@typescript-eslint/types" "6.10.0"
|
||||
"@typescript-eslint/typescript-estree" "6.10.0"
|
||||
"@typescript-eslint/scope-manager" "6.9.1"
|
||||
"@typescript-eslint/types" "6.9.1"
|
||||
"@typescript-eslint/typescript-estree" "6.9.1"
|
||||
semver "^7.5.4"
|
||||
|
||||
"@typescript-eslint/visitor-keys@6.10.0":
|
||||
version "6.10.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-6.10.0.tgz#b9eaf855a1ac7e95633ae1073af43d451e8f84e3"
|
||||
integrity sha512-xMGluxQIEtOM7bqFCo+rCMh5fqI+ZxV5RUUOa29iVPz1OgCZrtc7rFnz5cLUazlkPKYqX+75iuDq7m0HQ48nCg==
|
||||
"@typescript-eslint/visitor-keys@6.9.1":
|
||||
version "6.9.1"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-6.9.1.tgz#6753a9225a0ba00459b15d6456b9c2780b66707d"
|
||||
integrity sha512-MUaPUe/QRLEffARsmNfmpghuQkW436DvESW+h+M52w0coICHRfD6Np9/K6PdACwnrq1HmuLl+cSPZaJmeVPkSw==
|
||||
dependencies:
|
||||
"@typescript-eslint/types" "6.10.0"
|
||||
"@typescript-eslint/types" "6.9.1"
|
||||
eslint-visitor-keys "^3.4.1"
|
||||
|
||||
"@ungap/structured-clone@^1.2.0":
|
||||
@@ -3647,10 +3642,10 @@
|
||||
dependencies:
|
||||
"@use-gesture/core" "10.3.0"
|
||||
|
||||
"@vector-im/compound-design-tokens@^0.1.0":
|
||||
version "0.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@vector-im/compound-design-tokens/-/compound-design-tokens-0.1.0.tgz#1a574fba872ff93b1de8490f475e30b922cd02a2"
|
||||
integrity sha512-vnDrd1CPPR7CwQLss/JnIE1ga6QwmCkhgBvXm1huMhCs7nIiqf90Sbgc0WugbHNaRXGEEhMVGrE69DaQIUcqOA==
|
||||
"@vector-im/compound-design-tokens@^0.0.7":
|
||||
version "0.0.7"
|
||||
resolved "https://registry.yarnpkg.com/@vector-im/compound-design-tokens/-/compound-design-tokens-0.0.7.tgz#b0716dd4782dd95900491e45b003b58f93748024"
|
||||
integrity sha512-RCQc6qr+s8cp4xKbNi/I3OL43uPCH+N4L9vYf0r+qwRy4WCKdI4QL0TBTV4bOo8hF49z8e+BgU5ZIu5TVQXNMQ==
|
||||
dependencies:
|
||||
svg2vectordrawable "^2.9.1"
|
||||
|
||||
@@ -5400,9 +5395,9 @@ fast-fifo@^1.1.0:
|
||||
integrity sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==
|
||||
|
||||
fast-glob@^3.2.9:
|
||||
version "3.3.2"
|
||||
resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.2.tgz#a904501e57cfdd2ffcded45e99a54fef55e46129"
|
||||
integrity sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==
|
||||
version "3.3.1"
|
||||
resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.1.tgz#784b4e897340f3dbbef17413b3f11acf03c874c4"
|
||||
integrity sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==
|
||||
dependencies:
|
||||
"@nodelib/fs.stat" "^2.0.2"
|
||||
"@nodelib/fs.walk" "^1.2.3"
|
||||
@@ -7106,12 +7101,12 @@ matrix-events-sdk@0.0.1:
|
||||
resolved "https://registry.yarnpkg.com/matrix-events-sdk/-/matrix-events-sdk-0.0.1.tgz#c8c38911e2cb29023b0bbac8d6f32e0de2c957dd"
|
||||
integrity sha512-1QEOsXO+bhyCroIe2/A5OwaxHvBm7EsSQ46DEDn8RBIfQwN5HWBpFvyWWR4QY0KHPPnnJdI99wgRiAl7Ad5qaA==
|
||||
|
||||
"matrix-js-sdk@github:matrix-org/matrix-js-sdk#107e28e1145c8b2667701e1f75b9f09b5d2ac3d6":
|
||||
version "30.0.0"
|
||||
resolved "https://codeload.github.com/matrix-org/matrix-js-sdk/tar.gz/107e28e1145c8b2667701e1f75b9f09b5d2ac3d6"
|
||||
"matrix-js-sdk@github:matrix-org/matrix-js-sdk#4ce837b20e638a185f9002b2388fbaf48975ee6e":
|
||||
version "29.0.0"
|
||||
resolved "https://codeload.github.com/matrix-org/matrix-js-sdk/tar.gz/4ce837b20e638a185f9002b2388fbaf48975ee6e"
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.12.5"
|
||||
"@matrix-org/matrix-sdk-crypto-wasm" "^2.2.0"
|
||||
"@matrix-org/matrix-sdk-crypto-wasm" "^1.2.3-alpha.0"
|
||||
another-json "^0.2.0"
|
||||
bs58 "^5.0.0"
|
||||
content-type "^1.0.4"
|
||||
@@ -7897,9 +7892,9 @@ postcss@^8.4.27:
|
||||
source-map-js "^1.0.2"
|
||||
|
||||
posthog-js@^1.29.0:
|
||||
version "1.88.3"
|
||||
resolved "https://registry.yarnpkg.com/posthog-js/-/posthog-js-1.88.3.tgz#5d4a6432eb10d60377073ee7ff52030df44dd021"
|
||||
integrity sha512-6BLFTSWK8GrWfl5j9Ib+2w8YZKZfz2GqLMS7q4I93hbkknEMH5f1KaKDqPsGmGOM3SLQV0Cwd6nuCdFdqANS1w==
|
||||
version "1.88.1"
|
||||
resolved "https://registry.yarnpkg.com/posthog-js/-/posthog-js-1.88.1.tgz#ab81f21ec158a9c57be0e696744a9c9f6967ba3b"
|
||||
integrity sha512-+8kFFU5KIcFSm8zB3tX8l0GSPyq/OtMtdrS9dYpMJk6nsEwXvOjkwFEpSrYzL5eGEpTPdbM65M52HvMqqsjpXw==
|
||||
dependencies:
|
||||
fflate "^0.4.1"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user