Merge remote-tracking branch 'origin/livekit' into dbkr/remove_e2ee_setting
This commit is contained in:
@@ -36,7 +36,6 @@ module.exports = {
|
|||||||
rules: {
|
rules: {
|
||||||
"matrix-org/require-copyright-header": ["error", COPYRIGHT_HEADER],
|
"matrix-org/require-copyright-header": ["error", COPYRIGHT_HEADER],
|
||||||
"jsx-a11y/media-has-caption": "off",
|
"jsx-a11y/media-has-caption": "off",
|
||||||
"deprecate/import": "off", // Disabled because it crashes the linter
|
|
||||||
// We should use the js-sdk logger, never console directly.
|
// We should use the js-sdk logger, never console directly.
|
||||||
"no-console": ["error"],
|
"no-console": ["error"],
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ limitations under the License.
|
|||||||
|
|
||||||
import { useEffect, useMemo } from "react";
|
import { useEffect, useMemo } from "react";
|
||||||
|
|
||||||
import { useLocalStorage } from "../useLocalStorage";
|
import { setLocalStorageItem, useLocalStorage } from "../useLocalStorage";
|
||||||
import { useClient } from "../ClientContext";
|
import { useClient } from "../ClientContext";
|
||||||
import { useUrlParams } from "../UrlParams";
|
import { useUrlParams } from "../UrlParams";
|
||||||
import { widget } from "../widget";
|
import { widget } from "../widget";
|
||||||
@@ -24,38 +24,52 @@ import { widget } from "../widget";
|
|||||||
export const getRoomSharedKeyLocalStorageKey = (roomId: string): string =>
|
export const getRoomSharedKeyLocalStorageKey = (roomId: string): string =>
|
||||||
`room-shared-key-${roomId}`;
|
`room-shared-key-${roomId}`;
|
||||||
|
|
||||||
const useInternalRoomSharedKey = (
|
const useInternalRoomSharedKey = (roomId: string): string | null => {
|
||||||
roomId: string,
|
const key = getRoomSharedKeyLocalStorageKey(roomId);
|
||||||
): [string | null, (value: string) => void] => {
|
const roomSharedKey = useLocalStorage(key)[0];
|
||||||
const key = useMemo(() => getRoomSharedKeyLocalStorageKey(roomId), [roomId]);
|
|
||||||
const [roomSharedKey, setRoomSharedKey] = useLocalStorage(key);
|
|
||||||
|
|
||||||
return [roomSharedKey, setRoomSharedKey];
|
return roomSharedKey;
|
||||||
};
|
};
|
||||||
|
|
||||||
const useKeyFromUrl = (roomId: string): string | null => {
|
/**
|
||||||
|
* Extracts the room password from the URL if one is present, saving it in localstorage
|
||||||
|
* and returning it in a tuple with the corresponding room ID from the URL.
|
||||||
|
* @returns A tuple of the roomId and password from the URL if the URL has both,
|
||||||
|
* otherwise [undefined, undefined]
|
||||||
|
*/
|
||||||
|
const useKeyFromUrl = (): [string, string] | [undefined, undefined] => {
|
||||||
const urlParams = useUrlParams();
|
const urlParams = useUrlParams();
|
||||||
const [e2eeSharedKey, setE2EESharedKey] = useInternalRoomSharedKey(roomId);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!urlParams.password) return;
|
if (!urlParams.password || !urlParams.roomId) return;
|
||||||
if (urlParams.password === "") return;
|
if (!urlParams.roomId) return;
|
||||||
if (urlParams.password === e2eeSharedKey) return;
|
|
||||||
|
|
||||||
setE2EESharedKey(urlParams.password);
|
setLocalStorageItem(
|
||||||
}, [urlParams, e2eeSharedKey, setE2EESharedKey]);
|
// We set the Item by only using data from the url. This way we
|
||||||
|
// make sure, we always have matching pairs in the LocalStorage,
|
||||||
|
// as they occur in the call links.
|
||||||
|
getRoomSharedKeyLocalStorageKey(urlParams.roomId),
|
||||||
|
urlParams.password,
|
||||||
|
);
|
||||||
|
}, [urlParams]);
|
||||||
|
|
||||||
return urlParams.password ?? null;
|
return urlParams.roomId && urlParams.password
|
||||||
|
? [urlParams.roomId, urlParams.password]
|
||||||
|
: [undefined, undefined];
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useRoomSharedKey = (roomId: string): string | null => {
|
export const useRoomSharedKey = (roomId: string): string | undefined => {
|
||||||
// make sure we've extracted the key from the URL first
|
// make sure we've extracted the key from the URL first
|
||||||
// (and we still need to take the value it returns because
|
// (and we still need to take the value it returns because
|
||||||
// the effect won't run in time for it to save to localstorage in
|
// the effect won't run in time for it to save to localstorage in
|
||||||
// time for us to read it out again).
|
// time for us to read it out again).
|
||||||
const passwordFormUrl = useKeyFromUrl(roomId);
|
const [urlRoomId, passwordFormUrl] = useKeyFromUrl();
|
||||||
|
|
||||||
return useInternalRoomSharedKey(roomId)[0] ?? passwordFormUrl;
|
const storedPassword = useInternalRoomSharedKey(roomId);
|
||||||
|
|
||||||
|
if (storedPassword) return storedPassword;
|
||||||
|
if (urlRoomId === roomId) return passwordFormUrl;
|
||||||
|
return undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useIsRoomE2EE = (roomId: string): boolean | null => {
|
export const useIsRoomE2EE = (roomId: string): boolean | null => {
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import {
|
|||||||
ConnectionState,
|
ConnectionState,
|
||||||
Room,
|
Room,
|
||||||
RoomEvent,
|
RoomEvent,
|
||||||
|
Track,
|
||||||
} from "livekit-client";
|
} from "livekit-client";
|
||||||
import { useCallback, useEffect, useRef, useState } from "react";
|
import { useCallback, useEffect, useRef, useState } from "react";
|
||||||
import { logger } from "matrix-js-sdk/src/logger";
|
import { logger } from "matrix-js-sdk/src/logger";
|
||||||
@@ -60,6 +61,14 @@ async function doConnect(
|
|||||||
// doesn't publish it until you unmute. We want to publish it from the start so we're
|
// doesn't publish it until you unmute. We want to publish it from the start so we're
|
||||||
// always capturing audio: it helps keep bluetooth headsets in the right mode and
|
// always capturing audio: it helps keep bluetooth headsets in the right mode and
|
||||||
// mobile browsers to know we're doing a call.
|
// mobile browsers to know we're doing a call.
|
||||||
|
if (livekitRoom!.localParticipant.getTrack(Track.Source.Microphone)) {
|
||||||
|
logger.warn(
|
||||||
|
"Pre-creating audio track but participant already appears to have an microphone track: this shouldn't happen!",
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.info("Pre-creating microphone track");
|
||||||
const audioTracks = await livekitRoom!.localParticipant.createTracks({
|
const audioTracks = await livekitRoom!.localParticipant.createTracks({
|
||||||
audio: audioOptions,
|
audio: audioOptions,
|
||||||
});
|
});
|
||||||
@@ -69,6 +78,14 @@ async function doConnect(
|
|||||||
}
|
}
|
||||||
if (!audioEnabled) await audioTracks[0].mute();
|
if (!audioEnabled) await audioTracks[0].mute();
|
||||||
|
|
||||||
|
// 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!",
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
logger.info("Publishing pre-created mic track");
|
||||||
await livekitRoom?.localParticipant.publishTrack(audioTracks[0]);
|
await livekitRoom?.localParticipant.publishTrack(audioTracks[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -127,7 +127,7 @@ export function useLiveKit(
|
|||||||
|
|
||||||
const connectionState = useECConnectionState(
|
const connectionState = useECConnectionState(
|
||||||
{
|
{
|
||||||
deviceId: initialDevices.current.audioOutput.selectedId,
|
deviceId: initialDevices.current.audioInput.selectedId,
|
||||||
},
|
},
|
||||||
initialMuteStates.current.audio.enabled,
|
initialMuteStates.current.audio.enabled,
|
||||||
room,
|
room,
|
||||||
|
|||||||
@@ -87,9 +87,6 @@ import {
|
|||||||
import { useOpenIDSFU } from "../livekit/openIDSFU";
|
import { useOpenIDSFU } from "../livekit/openIDSFU";
|
||||||
|
|
||||||
const canScreenshare = "getDisplayMedia" in (navigator.mediaDevices ?? {});
|
const canScreenshare = "getDisplayMedia" in (navigator.mediaDevices ?? {});
|
||||||
// There is currently a bug in Safari our our code with cloning and sending MediaStreams
|
|
||||||
// or with getUsermedia and getDisplaymedia being used within the same session.
|
|
||||||
// For now we can disable screensharing in Safari.
|
|
||||||
const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
|
const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
|
||||||
|
|
||||||
// How long we wait after a focus switch before showing the real participant list again
|
// How long we wait after a focus switch before showing the real participant list again
|
||||||
@@ -369,7 +366,7 @@ export const InCallView: FC<InCallViewProps> = ({
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (!reducedControls) {
|
if (!reducedControls) {
|
||||||
if (canScreenshare && !hideScreensharing && !isSafari) {
|
if (canScreenshare && !hideScreensharing) {
|
||||||
buttons.push(
|
buttons.push(
|
||||||
<ScreenshareButton
|
<ScreenshareButton
|
||||||
key="3"
|
key="3"
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import {
|
|||||||
} from "matrix-js-sdk/src/matrixrtc/MatrixRTCSession";
|
} from "matrix-js-sdk/src/matrixrtc/MatrixRTCSession";
|
||||||
import { useCallback, useEffect, useState } from "react";
|
import { useCallback, useEffect, useState } from "react";
|
||||||
import { deepCompare } from "matrix-js-sdk/src/utils";
|
import { deepCompare } from "matrix-js-sdk/src/utils";
|
||||||
|
import { logger } from "matrix-js-sdk/src/logger";
|
||||||
|
|
||||||
import { LivekitFocus } from "../livekit/LivekitFocus";
|
import { LivekitFocus } from "../livekit/LivekitFocus";
|
||||||
|
|
||||||
@@ -27,7 +28,16 @@ function getActiveFocus(
|
|||||||
rtcSession: MatrixRTCSession,
|
rtcSession: MatrixRTCSession,
|
||||||
): LivekitFocus | undefined {
|
): LivekitFocus | undefined {
|
||||||
const oldestMembership = rtcSession.getOldestMembership();
|
const oldestMembership = rtcSession.getOldestMembership();
|
||||||
return oldestMembership?.getActiveFoci()[0] as LivekitFocus;
|
const focus = oldestMembership?.getActiveFoci()[0] as LivekitFocus;
|
||||||
|
|
||||||
|
if (focus) {
|
||||||
|
logger.info(
|
||||||
|
`Got active focus for call from ${oldestMembership?.sender}/${oldestMembership?.deviceId}`,
|
||||||
|
focus,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return focus;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
40
yarn.lock
40
yarn.lock
@@ -1026,7 +1026,7 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
regenerator-runtime "^0.14.0"
|
regenerator-runtime "^0.14.0"
|
||||||
|
|
||||||
"@babel/runtime@^7.13.10", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2":
|
"@babel/runtime@^7.13.10", "@babel/runtime@^7.22.5", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2":
|
||||||
version "7.23.2"
|
version "7.23.2"
|
||||||
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.2.tgz#062b0ac103261d68a966c4c7baf2ae3e62ec3885"
|
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.2.tgz#062b0ac103261d68a966c4c7baf2ae3e62ec3885"
|
||||||
integrity sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg==
|
integrity sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg==
|
||||||
@@ -1047,7 +1047,7 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
regenerator-runtime "^0.14.0"
|
regenerator-runtime "^0.14.0"
|
||||||
|
|
||||||
"@babel/runtime@^7.20.6", "@babel/runtime@^7.22.5":
|
"@babel/runtime@^7.20.6":
|
||||||
version "7.23.1"
|
version "7.23.1"
|
||||||
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.1.tgz#72741dc4d413338a91dcb044a86f3c0bc402646d"
|
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.1.tgz#72741dc4d413338a91dcb044a86f3c0bc402646d"
|
||||||
integrity sha512-hC2v6p8ZSI/W0HUzh3V8C5g+NwSKzKPtJwSpTjwl0o297GP9+ZLQSkdvHz46CM3LqyoXxq+5G9komY+eSqSO0g==
|
integrity sha512-hC2v6p8ZSI/W0HUzh3V8C5g+NwSKzKPtJwSpTjwl0o297GP9+ZLQSkdvHz46CM3LqyoXxq+5G9komY+eSqSO0g==
|
||||||
@@ -1110,9 +1110,9 @@
|
|||||||
integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==
|
integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==
|
||||||
|
|
||||||
"@bufbuild/protobuf@^1.3.0":
|
"@bufbuild/protobuf@^1.3.0":
|
||||||
version "1.3.1"
|
version "1.3.3"
|
||||||
resolved "https://registry.yarnpkg.com/@bufbuild/protobuf/-/protobuf-1.3.1.tgz#c4de66bacbe7ac97fe054e68314aeba6f45177f9"
|
resolved "https://registry.yarnpkg.com/@bufbuild/protobuf/-/protobuf-1.3.3.tgz#814562a5db0233a1ececda97b930c2dde5897de8"
|
||||||
integrity sha512-BUyJWutgP2S8K/1NphOJokuwDckXS4qI2T1pGZAlkFdZchWae3jm6fCdkcGbLlM1QLOcNFFePd+7Feo4BYGrJQ==
|
integrity sha512-AoHSiIpTFF97SQgmQni4c+Tyr0CDhkaRaR2qGEJTEbauqQwLRpLrd9yVv//wVHOSxr/b4FJcL54VchhY6710xA==
|
||||||
|
|
||||||
"@csstools/cascade-layer-name-parser@^1.0.5":
|
"@csstools/cascade-layer-name-parser@^1.0.5":
|
||||||
version "1.0.5"
|
version "1.0.5"
|
||||||
@@ -3565,9 +3565,9 @@
|
|||||||
undici-types "~5.25.1"
|
undici-types "~5.25.1"
|
||||||
|
|
||||||
"@types/node@^18.13.0":
|
"@types/node@^18.13.0":
|
||||||
version "18.18.4"
|
version "18.18.5"
|
||||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-18.18.4.tgz#519fef47a13cf869be290c20fc6ae9b7fe887aa7"
|
resolved "https://registry.yarnpkg.com/@types/node/-/node-18.18.5.tgz#afc0fd975df946d6e1add5bbf98264225b212244"
|
||||||
integrity sha512-t3rNFBgJRugIhackit2mVcLfF6IRc0JE4oeizPQL8Zrm8n2WY/0wOdpOPhdtG0V9Q2TlW/axbF1MJ6z+Yj/kKQ==
|
integrity sha512-4slmbtwV59ZxitY4ixUZdy1uRLf9eSIvBWPQxNjhHYWEtn0FryfKpyS2cvADYXTayWdKEIsJengncrVvkI4I6A==
|
||||||
|
|
||||||
"@types/normalize-package-data@^2.4.0":
|
"@types/normalize-package-data@^2.4.0":
|
||||||
version "2.4.2"
|
version "2.4.2"
|
||||||
@@ -3585,9 +3585,9 @@
|
|||||||
integrity sha512-IKjZ8RjTSwD4/YG+2gtj7BPFRB/lNbWKTiSj3M7U/TD2B7HfYCxvp2Zz6xA2WIY7pAuL1QOUPw8gQRbUrrq4fQ==
|
integrity sha512-IKjZ8RjTSwD4/YG+2gtj7BPFRB/lNbWKTiSj3M7U/TD2B7HfYCxvp2Zz6xA2WIY7pAuL1QOUPw8gQRbUrrq4fQ==
|
||||||
|
|
||||||
"@types/react-dom@^18.0.0":
|
"@types/react-dom@^18.0.0":
|
||||||
version "18.2.11"
|
version "18.2.13"
|
||||||
resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.2.11.tgz#4332c315544698a0875dfdb6e320dda59e1b3d58"
|
resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.2.13.tgz#89cd7f9ec8b28c8b6f0392b9591671fb4a9e96b7"
|
||||||
integrity sha512-zq6Dy0EiCuF9pWFW6I6k6W2LdpUixLE4P6XjXU1QHLfak3GPACQfLwEuHzY5pOYa4hzj1d0GxX/P141aFjZsyg==
|
integrity sha512-eJIUv7rPP+EC45uNYp/ThhSpE16k22VJUknt5OLoH9tbXoi8bMhwLf5xRuWMywamNbWzhrSmU7IBJfPup1+3fw==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@types/react" "*"
|
"@types/react" "*"
|
||||||
|
|
||||||
@@ -5318,9 +5318,9 @@ eslint-module-utils@^2.8.0:
|
|||||||
debug "^3.2.7"
|
debug "^3.2.7"
|
||||||
|
|
||||||
eslint-plugin-deprecate@^0.8.2:
|
eslint-plugin-deprecate@^0.8.2:
|
||||||
version "0.8.3"
|
version "0.8.4"
|
||||||
resolved "https://registry.yarnpkg.com/eslint-plugin-deprecate/-/eslint-plugin-deprecate-0.8.3.tgz#99e583c1facc99e99d97a9f795bdfd400232af0f"
|
resolved "https://registry.yarnpkg.com/eslint-plugin-deprecate/-/eslint-plugin-deprecate-0.8.4.tgz#1bbedca80f763cadf228c66a4cf639eb16aeca68"
|
||||||
integrity sha512-OCbDN5xNIdGt/Y1T5u44SJXbo/dmYebiMcBgxda7w8CDRNjat4cyBSbPQC3y9BYbJjM9JWkYgX5xlfMA+H95TA==
|
integrity sha512-bzpQTyXNWXbMWRH77XiuzfAthOhQhizEZrTf7krRiMYrq6ENUsWfbCe8A3SeRNa4eW8T2QrHsg/lXmxLq9xXXA==
|
||||||
|
|
||||||
eslint-plugin-import@^2.26.0:
|
eslint-plugin-import@^2.26.0:
|
||||||
version "2.28.1"
|
version "2.28.1"
|
||||||
@@ -7202,9 +7202,9 @@ lines-and-columns@^1.1.6:
|
|||||||
integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==
|
integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==
|
||||||
|
|
||||||
livekit-client@^1.12.3:
|
livekit-client@^1.12.3:
|
||||||
version "1.13.4"
|
version "1.14.0"
|
||||||
resolved "https://registry.yarnpkg.com/livekit-client/-/livekit-client-1.13.4.tgz#af20a338334d6c9e3c81e7c9641222d95a532b75"
|
resolved "https://registry.yarnpkg.com/livekit-client/-/livekit-client-1.14.0.tgz#3852138e01022227b24201f2625881c4e4c9d3a4"
|
||||||
integrity sha512-7Ef80q7aWkgkFWfWBd+gv2AcUrubpt+oXYk+tXSWVkTXoPpm6xqrMPu3TNYKIzXQWt8IEbyPQLLVsCZpR7RBTg==
|
integrity sha512-jQmIaPze4hTJCDLskMHDnvvz9RpHvWURgf/ZL8/m3DBUY3ERE2KkwcEX0cGom3FZgiiywolJFM3uKMC28Ad+nw==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@bufbuild/protobuf" "^1.3.0"
|
"@bufbuild/protobuf" "^1.3.0"
|
||||||
events "^3.3.0"
|
events "^3.3.0"
|
||||||
@@ -8291,9 +8291,9 @@ react-dom@18:
|
|||||||
scheduler "^0.23.0"
|
scheduler "^0.23.0"
|
||||||
|
|
||||||
react-i18next@^13.0.0:
|
react-i18next@^13.0.0:
|
||||||
version "13.2.2"
|
version "13.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/react-i18next/-/react-i18next-13.2.2.tgz#b1e78ed66a54f4bc819616f68b98221e1b1a1936"
|
resolved "https://registry.yarnpkg.com/react-i18next/-/react-i18next-13.3.0.tgz#8e39c0101f654db7eb971f159bb55067a78925c3"
|
||||||
integrity sha512-+nFUkbRByFwnrfDcYqvzBuaeZb+nACHx+fAWN/pZMddWOCJH5hoc21+Sa/N/Lqi6ne6/9wC/qRGOoQhJa6IkEQ==
|
integrity sha512-FlR9xjYHSPIJfQspEmkN0yOlxgRyNuiJKJ8gCaZH08UJ7SZHG+VrptEPcpEMEchjNoCOZdKcvJ3PnmHEZhkeXg==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@babel/runtime" "^7.22.5"
|
"@babel/runtime" "^7.22.5"
|
||||||
html-parse-stringify "^3.0.1"
|
html-parse-stringify "^3.0.1"
|
||||||
|
|||||||
Reference in New Issue
Block a user