Merge remote-tracking branch 'origin/livekit' into dbkr/write_key_with_right_roomid

This commit is contained in:
David Baker
2023-10-11 12:53:54 +01:00
7 changed files with 98 additions and 41 deletions

View File

@@ -75,7 +75,7 @@ jobs:
uses: docker/setup-buildx-action@dedd61cf5d839122591f5027c89bf3ad27691d18
- name: Build and push Docker image
uses: docker/build-push-action@4c1b68d83ad20cc1a09620ca477d5bbbb5fa14d0
uses: docker/build-push-action@0f847266c302569530c95bfa228489494c43b002
with:
context: .
platforms: linux/amd64,linux/arm64

View File

@@ -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#6385c9c0dab8fe67bd3a8992a4777f243fdd1b68",
"matrix-js-sdk": "github:matrix-org/matrix-js-sdk#c8f8fb587d29dce22d314bfc16bf25a76b04e8bb",
"matrix-widget-api": "^1.3.1",
"normalize.css": "^8.0.1",
"pako": "^2.0.4",

View File

@@ -101,6 +101,17 @@ export function useLiveKit(
// 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);
const videoMuteUpdating = useRef(false);
// Store the current button mute state that gets passed to this hook via props.
// We need to store it for awaited code that relies on the current value.
const buttonEnabled = useRef({
audio: initialMuteStates.current.audio.enabled,
video: initialMuteStates.current.video.enabled,
});
// 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
@@ -137,20 +148,50 @@ export function useLiveKit(
// and setting tracks to be enabled during this time causes errors.
if (room !== undefined && connectionState === ConnectionState.Connected) {
const participant = room.localParticipant;
if (participant.isMicrophoneEnabled !== muteStates.audio.enabled) {
participant
.setMicrophoneEnabled(muteStates.audio.enabled)
.catch((e) =>
logger.error("Failed to sync audio mute state with LiveKit", e)
);
}
if (participant.isCameraEnabled !== muteStates.video.enabled) {
participant
.setCameraEnabled(muteStates.video.enabled)
.catch((e) =>
logger.error("Failed to sync video mute state with LiveKit", e)
);
}
// Always update the muteButtonState Ref so that we can read the current
// state in awaited blocks.
buttonEnabled.current = {
audio: muteStates.audio.enabled,
video: muteStates.video.enabled,
};
const syncMuteStateAudio = async () => {
if (
participant.isMicrophoneEnabled !== buttonEnabled.current.audio &&
!audioMuteUpdating.current
) {
audioMuteUpdating.current = true;
try {
await participant.setMicrophoneEnabled(buttonEnabled.current.audio);
} catch (e) {
logger.error("Failed to sync audio mute state with LiveKit", e);
}
audioMuteUpdating.current = false;
// Run the check again after the change is done. Because the user
// can update the state (presses mute button) while the device is enabling
// itself we need might need to update the mute state right away.
// This async recursion makes sure that setCamera/MicrophoneEnabled is
// called as little times as possible.
syncMuteStateAudio();
}
};
const syncMuteStateVideo = async () => {
if (
participant.isCameraEnabled !== buttonEnabled.current.video &&
!videoMuteUpdating.current
) {
videoMuteUpdating.current = true;
try {
await participant.setCameraEnabled(buttonEnabled.current.video);
} catch (e) {
logger.error("Failed to sync audio mute state with LiveKit", e);
}
videoMuteUpdating.current = false;
// see above
syncMuteStateVideo();
}
};
syncMuteStateAudio();
syncMuteStateVideo();
}
}, [room, muteStates, connectionState]);

View File

@@ -76,9 +76,18 @@ function waitForSync(client: MatrixClient) {
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("/", "_")
.replace(/=*$/, "");
}
/**
@@ -395,9 +404,16 @@ export function getRelativeRoomUrl(
roomName?: string,
password?: string
): string {
// The password shouldn't need URL encoding here (we generate URL-safe ones) but encode
// it in case it came from another client that generated a non url-safe one
const encodedPassword = password ? encodeURIComponent(password) : undefined;
if (password && encodedPassword !== password) {
logger.info("Encoded call password used non URL-safe chars: buggy client?");
}
return `/room/#${
roomName ? "/" + roomAliasLocalpartFromRoomName(roomName) : ""
}?roomId=${roomId}${password ? "&" + PASSWORD_STRING + password : ""}`;
}?roomId=${roomId}${password ? "&" + PASSWORD_STRING + encodedPassword : ""}`;
}
export function getAvatarUrl(

View File

@@ -110,7 +110,7 @@ export function GroupCallView({
// Count each member only once, regardless of how many devices they use
const participantCount = useMemo(
() => new Set<string>(memberships.map((m) => m.member.userId)).size,
() => new Set<string>(memberships.map((m) => m.sender!)).size,
[memberships]
);

View File

@@ -41,7 +41,7 @@ export function enterRTCSession(rtcSession: MatrixRTCSession) {
// have started tracking by the time calls start getting created.
//groupCallOTelMembership?.onJoinCall();
// right now we asume everything is a room-scoped call
// right now we assume everything is a room-scoped call
const livekitAlias = rtcSession.room.roomId;
rtcSession.joinRoomSession([makeFocus(livekitAlias)]);

View File

@@ -3552,9 +3552,9 @@
integrity sha512-zI22/pJW2wUZOVyguFaUL1HABdmSVxpXrzIqkjsHmyUjNhPoWM1CKfvVuXfetHhIok4RY573cqS0mZ1SJEnoTg==
"@types/node@^18.13.0":
version "18.18.3"
resolved "https://registry.yarnpkg.com/@types/node/-/node-18.18.3.tgz#e5188135fc2909b46530c798ef49be65083be3fd"
integrity sha512-0OVfGupTl3NBFr8+iXpfZ8NR7jfFO+P1Q+IO/q0wbo02wYkP5gy36phojeYWpLQ6WAMjl+VfmqUk2YbUfp0irA==
version "18.18.4"
resolved "https://registry.yarnpkg.com/@types/node/-/node-18.18.4.tgz#519fef47a13cf869be290c20fc6ae9b7fe887aa7"
integrity sha512-t3rNFBgJRugIhackit2mVcLfF6IRc0JE4oeizPQL8Zrm8n2WY/0wOdpOPhdtG0V9Q2TlW/axbF1MJ6z+Yj/kKQ==
"@types/prop-types@*":
version "15.7.8"
@@ -3567,9 +3567,9 @@
integrity sha512-IKjZ8RjTSwD4/YG+2gtj7BPFRB/lNbWKTiSj3M7U/TD2B7HfYCxvp2Zz6xA2WIY7pAuL1QOUPw8gQRbUrrq4fQ==
"@types/react-dom@^18.0.0":
version "18.2.8"
resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.2.8.tgz#338f1b0a646c9f10e0a97208c1d26b9f473dffd6"
integrity sha512-bAIvO5lN/U8sPGvs1Xm61rlRHHaq5rp5N3kp9C+NJ/Q41P8iqjkXSu0+/qu8POsjH9pNWb0OYabFez7taP7omw==
version "18.2.11"
resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.2.11.tgz#4332c315544698a0875dfdb6e320dda59e1b3d58"
integrity sha512-zq6Dy0EiCuF9pWFW6I6k6W2LdpUixLE4P6XjXU1QHLfak3GPACQfLwEuHzY5pOYa4hzj1d0GxX/P141aFjZsyg==
dependencies:
"@types/react" "*"
@@ -3655,19 +3655,19 @@
integrity sha512-IDaobHimLQhjwsQ/NMwRVfa/yL7L/wriQPMhw1ZJall0KX6E1oxk29XMDeilW5qTIg5aoiqf5Udy8U/51aNoQQ==
"@types/uuid@9":
version "9.0.4"
resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-9.0.4.tgz#e884a59338da907bda8d2ed03e01c5c49d036f1c"
integrity sha512-zAuJWQflfx6dYJM62vna+Sn5aeSWhh3OB+wfUEACNcqUSc0AGc5JKl+ycL1vrH7frGTXhJchYjE1Hak8L819dA==
version "9.0.5"
resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-9.0.5.tgz#25a71eb73eba95ac0e559ff3dd018fc08294acf6"
integrity sha512-xfHdwa1FMJ082prjSJpoEI57GZITiQz10r3vEJCHa2khEFQjKy91aWKz6+zybzssCvXUwE1LQWgWVwZ4nYUvHQ==
"@types/yargs-parser@*":
version "21.0.0"
resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.0.tgz#0c60e537fa790f5f9472ed2776c2b71ec117351b"
integrity sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==
version "21.0.1"
resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.1.tgz#07773d7160494d56aa882d7531aac7319ea67c3b"
integrity sha512-axdPBuLuEJt0c4yI5OZssC19K2Mq1uKdrfZBzuxLvaztgqUtFYZUNw7lETExPYJR9jdEoIg4mb7RQKRQzOkeGQ==
"@types/yargs@^17.0.8":
version "17.0.24"
resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.24.tgz#b3ef8d50ad4aa6aecf6ddc97c580a00f5aa11902"
integrity sha512-6i0aC7jV6QzQB8ne1joVZ0eSFIstHsCrobmOtghM11yGlH0j43FKL2UhWdELkyps0zuf7qVTUVCCR+tgSlyLLw==
version "17.0.28"
resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.28.tgz#d106e4301fbacde3d1796ab27374dd16588ec851"
integrity sha512-N3e3fkS86hNhtk6BEnc0rj3zcehaxx8QWhCROJkqpl5Zaoi7nAic3jH8q94jVD3zu5LGk+PUB6KAiDmimYOEQw==
dependencies:
"@types/yargs-parser" "*"
@@ -7286,9 +7286,9 @@ 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#6385c9c0dab8fe67bd3a8992a4777f243fdd1b68":
version "28.1.0"
resolved "https://codeload.github.com/matrix-org/matrix-js-sdk/tar.gz/6385c9c0dab8fe67bd3a8992a4777f243fdd1b68"
"matrix-js-sdk@github:matrix-org/matrix-js-sdk#c8f8fb587d29dce22d314bfc16bf25a76b04e8bb":
version "29.0.0"
resolved "https://codeload.github.com/matrix-org/matrix-js-sdk/tar.gz/c8f8fb587d29dce22d314bfc16bf25a76b04e8bb"
dependencies:
"@babel/runtime" "^7.12.5"
"@matrix-org/matrix-sdk-crypto-wasm" "^1.2.3-alpha.0"
@@ -8078,9 +8078,9 @@ postcss@^8.4.27:
source-map-js "^1.0.2"
posthog-js@^1.29.0:
version "1.81.3"
resolved "https://registry.yarnpkg.com/posthog-js/-/posthog-js-1.81.3.tgz#64f7fe50f31a13ad7290a3020328989045cee3c7"
integrity sha512-Aqqcj1n1KqZlxMaYYfd5OJC2BMIAP927+f7XqEbEplYJKigGTbQ6ygt2UeSJZe3xcDMxyDK4jxOWy68kD3YIlw==
version "1.83.0"
resolved "https://registry.yarnpkg.com/posthog-js/-/posthog-js-1.83.0.tgz#e13d114922f863f4bfbf7c7cc4e11dc194139a91"
integrity sha512-3dp/yNbRCYsOgvJovFUMCLv9/KxnwmGBy5Ft27Q7/rbW++iJXVR64liX7i0NrXkudjoL9j1GW1LGh84rV7kv8Q==
dependencies:
fflate "^0.4.1"