Merge branch 'livekit' into mobile-gradient

This commit is contained in:
Robin
2026-07-09 12:56:28 +02:00
33 changed files with 444 additions and 319 deletions

View File

@@ -15,9 +15,9 @@ jobs:
security-events: write # Required for upload-sarif (used by zizmor-action) to upload SARIF files. security-events: write # Required for upload-sarif (used by zizmor-action) to upload SARIF files.
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with: with:
persist-credentials: false persist-credentials: false
- name: Run zizmor 🌈 - name: Run zizmor 🌈
uses: zizmorcore/zizmor-action@b1d7e1fb5de872772f31590499237e7cce841e8e # v0.5.3 uses: zizmorcore/zizmor-action@192e21d79ab29983730a13d1382995c2307fbcaa # v0.5.7

View File

@@ -34,6 +34,7 @@
"/*\nCopyright %%CURRENT_YEAR%% Element Creations Ltd.\n\nSPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial\nPlease see LICENSE in the repository root for full details.\n*/\n\n" "/*\nCopyright %%CURRENT_YEAR%% Element Creations Ltd.\n\nSPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial\nPlease see LICENSE in the repository root for full details.\n*/\n\n"
], ],
"element-call/no-observablescope-leak": "error", "element-call/no-observablescope-leak": "error",
"element-call/no-top-level-logger-get-child": "error",
"jsdoc/empty-tags": "error", "jsdoc/empty-tags": "error",
"jsdoc/check-property-names": "error", "jsdoc/check-property-names": "error",
"jsdoc/require-param-description": "warn", "jsdoc/require-param-description": "warn",

View File

@@ -0,0 +1,92 @@
/*
Copyright 2026 Element Creations Ltd.
SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
Please see LICENSE in the repository root for full details.
*/
import { ESLintUtils } from "@typescript-eslint/utils";
/**
* Node types that introduce a new non-module scope. A getChild() call nested
* inside any of these is considered "not at the top level".
*/
const FUNCTION_OR_CLASS_TYPES = new Set([
"FunctionDeclaration",
"FunctionExpression",
"ArrowFunctionExpression",
"ClassBody",
]);
const rule = ESLintUtils.RuleCreator(
() => "https://github.com/element-hq/element-call",
)({
name: "no-top-level-logger-get-child",
meta: {
type: "problem",
docs: {
description:
"Disallow calling logger.getChild() at the top level of a module." +
"`getChild` has to be called after the rageshake logger `init()`." +
"If it is called at the top level the child logger will never be setup for rageshakes.",
},
messages: {
noTopLevelGetChild:
"Do not call logger.getChild() at the top level of a module; move it inside a function or class instead that gets called after rageshake logger `init()` is called.",
},
schema: [],
},
create(context) {
// Tracks the local binding names that refer to the logger imported from
// 'matrix-js-sdk/lib/logger', e.g. both `logger` and `rootLogger` in:
// import { logger } from "matrix-js-sdk/lib/logger";
// import { logger as rootLogger } from "matrix-js-sdk/lib/logger";
const loggerNames = new Set();
return {
ImportDeclaration(node) {
if (node.source.value !== "matrix-js-sdk/lib/logger") return;
for (const specifier of node.specifiers) {
if (
specifier.type === "ImportSpecifier" &&
specifier.imported.name === "logger"
) {
loggerNames.add(specifier.local.name);
}
}
},
CallExpression(node) {
// Must be a non-computed member expression call: something.getChild(...)
if (
node.callee.type !== "MemberExpression" ||
node.callee.computed ||
node.callee.property.type !== "Identifier" ||
node.callee.property.name !== "getChild"
)
return;
// The receiver must be one of the tracked logger names.
const object = node.callee.object;
if (object.type !== "Identifier" || !loggerNames.has(object.name))
return;
// Flag the call only when it is at module top level — i.e. there is no
// enclosing function or class body anywhere in the ancestor chain.
const ancestors = context.sourceCode.getAncestors(node);
const isTopLevel = !ancestors.some((a) =>
FUNCTION_OR_CLASS_TYPES.has(a.type),
);
if (isTopLevel) {
context.report({
messageId: "noTopLevelGetChild",
node,
});
}
},
};
},
});
export default rule;

View File

@@ -2,5 +2,7 @@ module.exports = {
rules: { rules: {
"copyright-header": require("./CopyrightHeader").default, "copyright-header": require("./CopyrightHeader").default,
"no-observablescope-leak": require("./NoObservableScopeLeak").default, "no-observablescope-leak": require("./NoObservableScopeLeak").default,
"no-top-level-logger-get-child": require("./NoTopLevelLoggerGetChild")
.default,
}, },
}; };

View File

@@ -205,6 +205,7 @@
"blur_not_supported_by_browser": "(Background blur is not supported by this device.)", "blur_not_supported_by_browser": "(Background blur is not supported by this device.)",
"developer_tab_title": "Developer", "developer_tab_title": "Developer",
"devices": { "devices": {
"activating": "Activating…",
"camera": "Camera", "camera": "Camera",
"camera_numbered": "Camera {{n}}", "camera_numbered": "Camera {{n}}",
"change_device_button": "Change audio device", "change_device_button": "Change audio device",

View File

@@ -15,9 +15,8 @@ import { scan } from "rxjs";
import { type WidgetHelpers } from "../src/widget"; import { type WidgetHelpers } from "../src/widget";
import { type LivekitRoomItem } from "../src/state/CallViewModel/CallViewModel"; import { type LivekitRoomItem } from "../src/state/CallViewModel/CallViewModel";
export const logger = rootLogger.getChild("[MatrixRTCSdk]");
export const tryMakeSticky = (widget: WidgetHelpers): void => { export const tryMakeSticky = (widget: WidgetHelpers): void => {
const logger = rootLogger.getChild("[MatrixRTCSdk]");
logger.info("try making sticky MatrixRTCSdk"); logger.info("try making sticky MatrixRTCSdk");
void widget.api void widget.api
.setAlwaysOnScreen(true) .setAlwaysOnScreen(true)

View File

@@ -52,7 +52,8 @@ import { getUrlParams } from "../src/UrlParams";
import { MuteStates } from "../src/state/MuteStates"; import { MuteStates } from "../src/state/MuteStates";
import { MediaDevices } from "../src/state/MediaDevices"; import { MediaDevices } from "../src/state/MediaDevices";
import { E2eeType } from "../src/e2ee/e2eeType"; import { E2eeType } from "../src/e2ee/e2eeType";
import { currentAndPrev, logger, TEXT_LK_TOPIC, tryMakeSticky } from "./helper"; import { currentAndPrev, TEXT_LK_TOPIC, tryMakeSticky } from "./helper";
import { logger as rootLogger } from "matrix-js-sdk/lib/logger";
import { import {
ElementWidgetActions, ElementWidgetActions,
widget as _widget, widget as _widget,
@@ -104,6 +105,7 @@ export async function createMatrixRTCSdk(
id: string = "", id: string = "",
sticky: boolean = false, sticky: boolean = false,
): Promise<MatrixRTCSdk> { ): Promise<MatrixRTCSdk> {
const logger = rootLogger.getChild("[MatrixRTCSdk]");
const scope = new ObservableScope(); const scope = new ObservableScope();
// widget client // widget client

View File

@@ -3,12 +3,12 @@
exports[`AppBar > renders 1`] = ` exports[`AppBar > renders 1`] = `
<div> <div>
<div <div
class="bar" class="_bar_221541"
> >
<header> <header>
<button <button
aria-labelledby="_r_0_" aria-labelledby="_r_0_"
class="_icon-button_1215g_8 primaryButton" class="_icon-button_1215g_8 _primaryButton_221541"
data-kind="primary" data-kind="primary"
role="button" role="button"
style="--cpd-icon-button-size: 24px;" style="--cpd-icon-button-size: 24px;"
@@ -33,7 +33,7 @@ exports[`AppBar > renders 1`] = `
</div> </div>
</button> </button>
<div <div
class="secondaryButton" class="_secondaryButton_221541"
/> />
</header> </header>
</div> </div>
@@ -46,12 +46,12 @@ exports[`AppBar > renders 1`] = `
exports[`AppBar > renders with title and subtitle 1`] = ` exports[`AppBar > renders with title and subtitle 1`] = `
<div> <div>
<div <div
class="bar" class="_bar_221541"
> >
<header> <header>
<button <button
aria-labelledby="_r_6_" aria-labelledby="_r_6_"
class="_icon-button_1215g_8 primaryButton" class="_icon-button_1215g_8 _primaryButton_221541"
data-kind="primary" data-kind="primary"
role="button" role="button"
style="--cpd-icon-button-size: 24px;" style="--cpd-icon-button-size: 24px;"
@@ -76,17 +76,17 @@ exports[`AppBar > renders with title and subtitle 1`] = `
</div> </div>
</button> </button>
<h1 <h1
class="_typography_6v6n8_153 _font-body-lg-medium_6v6n8_79 title" class="_typography_6v6n8_153 _font-body-lg-medium_6v6n8_79 _title_221541"
> >
Title Title
</h1> </h1>
<span <span
class="_typography_6v6n8_153 _font-body-lg-regular_6v6n8_69 subtitle" class="_typography_6v6n8_153 _font-body-lg-regular_6v6n8_69 _subtitle_221541"
> >
Subtitle Subtitle
</span> </span>
<div <div
class="secondaryButton" class="_secondaryButton_221541"
/> />
</header> </header>
</div> </div>

View File

@@ -3,7 +3,7 @@
exports[`the content is rendered when the modal is open 1`] = ` exports[`the content is rendered when the modal is open 1`] = `
<div <div
aria-labelledby="radix-_r_4_" aria-labelledby="radix-_r_4_"
class="overlay animate modal dialog _glass_sepwu_8" class="_overlay_2f5303 _animate_2f5303 _modal_dbeffe _dialog_dbeffe _glass_sepwu_8"
data-state="open" data-state="open"
id="radix-_r_3_" id="radix-_r_3_"
role="dialog" role="dialog"
@@ -11,10 +11,10 @@ exports[`the content is rendered when the modal is open 1`] = `
tabindex="-1" tabindex="-1"
> >
<div <div
class="content" class="_content_dbeffe"
> >
<div <div
class="header" class="_header_dbeffe"
> >
<h2 <h2
class="_typography_6v6n8_153 _font-heading-md-semibold_6v6n8_112" class="_typography_6v6n8_153 _font-heading-md-semibold_6v6n8_112"
@@ -24,7 +24,7 @@ exports[`the content is rendered when the modal is open 1`] = `
</h2> </h2>
</div> </div>
<div <div
class="body" class="_body_dbeffe"
> >
<p> <p>
This is the content. This is the content.
@@ -37,7 +37,7 @@ exports[`the content is rendered when the modal is open 1`] = `
exports[`the modal renders as a drawer in mobile viewports 1`] = ` exports[`the modal renders as a drawer in mobile viewports 1`] = `
<div <div
aria-labelledby="radix-_r_a_" aria-labelledby="radix-_r_a_"
class="overlay modal drawer" class="_overlay_2f5303 _modal_dbeffe _drawer_dbeffe"
data-state="open" data-state="open"
data-vaul-animate="true" data-vaul-animate="true"
data-vaul-custom-container="false" data-vaul-custom-container="false"
@@ -51,13 +51,13 @@ exports[`the modal renders as a drawer in mobile viewports 1`] = `
tabindex="-1" tabindex="-1"
> >
<div <div
class="content" class="_content_dbeffe"
> >
<div <div
class="header" class="_header_dbeffe"
> >
<div <div
class="handle" class="_handle_dbeffe"
/> />
<h2 <h2
id="radix-_r_a_" id="radix-_r_a_"
@@ -67,7 +67,7 @@ exports[`the modal renders as a drawer in mobile viewports 1`] = `
</h2> </h2>
</div> </div>
<div <div
class="body" class="_body_dbeffe"
> >
<p> <p>
This is the content. This is the content.

View File

@@ -2,7 +2,7 @@
exports[`QrCode > renders 1`] = ` exports[`QrCode > renders 1`] = `
<div <div
class="qrCode bar" class="_qrCode_458264 bar"
> >
<img <img
alt="QR Code" alt="QR Code"

View File

@@ -3,7 +3,7 @@
exports[`Toast > renders 1`] = ` exports[`Toast > renders 1`] = `
<button <button
aria-labelledby="radix-_r_4_" aria-labelledby="radix-_r_4_"
class="overlay animate toast" class="_overlay_2f5303 _animate_2f5303 _toast_15a045"
data-state="open" data-state="open"
id="radix-_r_3_" id="radix-_r_3_"
role="dialog" role="dialog"

View File

@@ -140,7 +140,7 @@ exports[`Can raise hand 1`] = `
aria-expanded="false" aria-expanded="false"
aria-haspopup="true" aria-haspopup="true"
aria-labelledby="_r_1j_" aria-labelledby="_r_1j_"
class="_button_1nw83_8 raisedButton _has-icon_1nw83_60 _icon-only_1nw83_53" class="_button_1nw83_8 _raisedButton_fb25ab _has-icon_1nw83_60 _icon-only_1nw83_53"
data-kind="primary" data-kind="primary"
data-size="lg" data-size="lg"
role="button" role="button"

View File

@@ -180,12 +180,12 @@ describe("MediaMuteAndSwitchButton", () => {
); );
await user.click(screen.getByRole("button", { name: "Microphone" })); await user.click(screen.getByRole("button", { name: "Microphone" }));
screen.getByRole("menuitem", { name: "Microphone 1" }); screen.getByRole("menuitemradio", { name: "Microphone 1" });
screen.getByRole("menuitem", { name: "Microphone 2" }); screen.getByRole("menuitemradio", { name: "Microphone 2" });
await user.keyboard("[Escape]"); await user.keyboard("[Escape]");
await user.click(screen.getByRole("button", { name: "Camera" })); await user.click(screen.getByRole("button", { name: "Camera" }));
screen.getByRole("menuitem", { name: "Camera 1" }); screen.getByRole("menuitemradio", { name: "Camera 1" });
screen.getByRole("menuitem", { name: "Camera 2" }); screen.getByRole("menuitemradio", { name: "Camera 2" });
}); });
test("calls select callback on menu click", async () => { test("calls select callback on menu click", async () => {
@@ -206,7 +206,9 @@ describe("MediaMuteAndSwitchButton", () => {
); );
await user.click(getByRole("button", { name: "Microphone" })); await user.click(getByRole("button", { name: "Microphone" }));
await user.click(screen.getByRole("menuitem", { name: "Microphone 2" })); await user.click(
screen.getByRole("menuitemradio", { name: "Microphone 2" }),
);
expect(onSelect).toHaveBeenCalledWith("mic2"); expect(onSelect).toHaveBeenCalledWith("mic2");
}); });
@@ -228,7 +230,9 @@ describe("MediaMuteAndSwitchButton", () => {
); );
await user.click(getByRole("button", { name: "Microphone" })); await user.click(getByRole("button", { name: "Microphone" }));
await user.click(screen.getByRole("menuitem", { name: "Microphone 1" })); await user.click(
screen.getByRole("menuitemradio", { name: "Microphone 1" }),
);
expect(onSelect).not.toHaveBeenCalled(); expect(onSelect).not.toHaveBeenCalled();
}); });
@@ -264,18 +268,24 @@ describe("MediaMuteAndSwitchButton", () => {
const { getByRole } = renderComponent(<Wrapper />); const { getByRole } = renderComponent(<Wrapper />);
await user.click(getByRole("button", { name: "Microphone" })); await user.click(getByRole("button", { name: "Microphone" }));
await user.click(screen.getByRole("menuitem", { name: "Microphone 2" })); await user.click(
screen.getByRole("menuitemradio", { name: "Microphone 2" }),
);
expect(onSelectPressed).toHaveBeenCalled(); expect(onSelectPressed).toHaveBeenCalled();
expect(onOptionUpdated).not.toHaveBeenCalled(); expect(onOptionUpdated).not.toHaveBeenCalled();
// After clicking, plannedSelection="mic2" but selectedOption is still "mic1", // After clicking, plannedSelection="mic2" but selectedOption is still "mic1",
// so a spinner should appear on the mic2 item // so mic2 should be in an activating state
const mic2Item = screen.getByRole("menuitem", { name: "Microphone 2" }); screen.getByRole("menuitemradio", {
expect(mic2Item.querySelector(".rotate")).toBeTruthy(); name: "Microphone 2 Activating…",
checked: false,
});
// The currently-selected mic1 item should not have a spinner // The currently-selected mic1 item should not be activating
const mic1Item = screen.getByRole("menuitem", { name: "Microphone 1" }); screen.getByRole("menuitemradio", {
expect(mic1Item.querySelector(".rotate")).toBeNull(); name: "Microphone 1",
checked: true,
});
await act(async () => { await act(async () => {
// resolve the promise that acutally updates the select option. // resolve the promise that acutally updates the select option.
resolve(); resolve();
@@ -284,7 +294,7 @@ describe("MediaMuteAndSwitchButton", () => {
expect(onOptionUpdated).toHaveBeenCalled(); expect(onOptionUpdated).toHaveBeenCalled();
// Spinner should now be gone since the selection has caught up // Spinner should now be gone since the selection has caught up
const mic2ItemAfter = screen.getByRole("menuitem", { const mic2ItemAfter = screen.getByRole("menuitemradio", {
name: "Microphone 2", name: "Microphone 2",
}); });
expect(mic2ItemAfter.querySelector(".rotate")).toBeNull(); expect(mic2ItemAfter.querySelector(".rotate")).toBeNull();
@@ -336,11 +346,15 @@ describe("MediaMuteAndSwitchButton", () => {
await user.click(getByRole("button", { name: "Microphone" })); await user.click(getByRole("button", { name: "Microphone" }));
// The selected item (mic2) renders both an IconOptions SVG and a CheckIcon SVG // The selected item (mic2) renders both an IconOptions SVG and a CheckIcon SVG
const mic1Item = screen.getByRole("menuitem", { name: "Microphone 2" }); const mic1Item = screen.getByRole("menuitemradio", {
name: "Microphone 2",
});
expect(mic1Item.querySelectorAll("svg").length).toBe(2); expect(mic1Item.querySelectorAll("svg").length).toBe(2);
// The unselected item (mic1) only renders its IconOptions SVG // The unselected item (mic1) only renders its IconOptions SVG
const mic2Item = screen.getByRole("menuitem", { name: "Microphone 1" }); const mic2Item = screen.getByRole("menuitemradio", {
name: "Microphone 1",
});
expect(mic2Item.querySelectorAll("svg").length).toBe(1); expect(mic2Item.querySelectorAll("svg").length).toBe(1);
}); });
}); });

View File

@@ -191,6 +191,7 @@ export const MediaMuteAndSwitchButton: FC<MediaMuteAndSwitchButtonProps> = ({
width={24} width={24}
height={24} height={24}
className={styles.itemIcon} className={styles.itemIcon}
aria-hidden
/> />
) )
} }
@@ -201,10 +202,23 @@ export const MediaMuteAndSwitchButton: FC<MediaMuteAndSwitchButtonProps> = ({
onSelect?.(id); onSelect?.(id);
}} }}
key={id} key={id}
role="menuitemradio"
aria-checked={selectedOption === id}
> >
{selectedOption === id && <CheckIcon width={24} height={24} />} {selectedOption === id && (
<CheckIcon
width={24}
height={24}
aria-hidden // A label would be redundant to aria-checked above
/>
)}
{selectedOption !== id && plannedSelection === id && ( {selectedOption !== id && plannedSelection === id && (
<SpinnerIcon width={24} height={24} className={styles.rotate} /> <SpinnerIcon
width={24}
height={24}
className={styles.rotate}
aria-label={t("settings.devices.activating")}
/>
)} )}
</MenuItem> </MenuItem>
); );

View File

@@ -3,7 +3,7 @@
exports[`MediaMuteAndSwitchButton > renders 1`] = ` exports[`MediaMuteAndSwitchButton > renders 1`] = `
<div> <div>
<div <div
class="container" class="_container_e649de"
> >
<button <button
aria-busy="false" aria-busy="false"
@@ -35,7 +35,7 @@ exports[`MediaMuteAndSwitchButton > renders 1`] = `
aria-expanded="false" aria-expanded="false"
aria-haspopup="menu" aria-haspopup="menu"
aria-label="Microphone" aria-label="Microphone"
class="_button_1nw83_8 menuButton _has-icon_1nw83_60 _icon-only_1nw83_53" class="_button_1nw83_8 _menuButton_e649de _has-icon_1nw83_60 _icon-only_1nw83_53"
data-kind="tertiary" data-kind="tertiary"
data-size="lg" data-size="lg"
data-state="closed" data-state="closed"

View File

@@ -10,15 +10,15 @@ import {
type MatrixRTCSession, type MatrixRTCSession,
MatrixRTCSessionEvent, MatrixRTCSessionEvent,
} from "matrix-js-sdk/lib/matrixrtc"; } from "matrix-js-sdk/lib/matrixrtc";
import { logger as rootLogger } from "matrix-js-sdk/lib/logger"; import { logger as rootLogger, type Logger } from "matrix-js-sdk/lib/logger";
import { type CallMembershipIdentityParts } from "matrix-js-sdk/lib/matrixrtc/EncryptionManager"; import { type CallMembershipIdentityParts } from "matrix-js-sdk/lib/matrixrtc/EncryptionManager";
const logger = rootLogger.getChild("[MatrixKeyProvider]");
export class MatrixKeyProvider extends BaseKeyProvider { export class MatrixKeyProvider extends BaseKeyProvider {
private rtcSession?: MatrixRTCSession; private rtcSession?: MatrixRTCSession;
private logger: Logger;
public constructor() { public constructor() {
super({ ratchetWindowSize: 10, keyringSize: 256 }); super({ ratchetWindowSize: 10, keyringSize: 256 });
this.logger = rootLogger.getChild("[MatrixKeyProvider]");
} }
public setRTCSession(rtcSession: MatrixRTCSession): void { public setRTCSession(rtcSession: MatrixRTCSession): void {
@@ -60,12 +60,12 @@ export class MatrixKeyProvider extends BaseKeyProvider {
encryptionKeyIndex, encryptionKeyIndex,
); );
logger.debug( this.logger.debug(
`Sent new key to livekit room=${this.rtcSession?.room.roomId} participantId=${rtcBackendIdentity} (before hash: ${membershipParts.userId}:${membershipParts.deviceId}) encryptionKeyIndex=${encryptionKeyIndex}`, `Sent new key to livekit room=${this.rtcSession?.room.roomId} participantId=${rtcBackendIdentity} (before hash: ${membershipParts.userId}:${membershipParts.deviceId}) encryptionKeyIndex=${encryptionKeyIndex}`,
); );
}, },
(e) => { (e) => {
logger.error( this.logger.error(
`Failed to create key material from buffer for livekit room=${this.rtcSession?.room.roomId} participantId before hash=${membershipParts.userId}:${membershipParts.deviceId} encryptionKeyIndex=${encryptionKeyIndex}`, `Failed to create key material from buffer for livekit room=${this.rtcSession?.room.roomId} participantId before hash=${membershipParts.userId}:${membershipParts.deviceId} encryptionKeyIndex=${encryptionKeyIndex}`,
e, e,
); );

View File

@@ -14,7 +14,7 @@ import {
AudioTrack, AudioTrack,
type AudioTrackProps, type AudioTrackProps,
} from "@livekit/components-react"; } from "@livekit/components-react";
import { logger } from "matrix-js-sdk/lib/logger"; import { logger as rootLogger } from "matrix-js-sdk/lib/logger";
import { useEarpieceAudioConfig } from "../MediaDevicesContext"; import { useEarpieceAudioConfig } from "../MediaDevicesContext";
import { useReactiveState } from "../useReactiveState"; import { useReactiveState } from "../useReactiveState";
@@ -40,7 +40,6 @@ export interface MatrixAudioRendererProps {
muted?: boolean; muted?: boolean;
} }
const prefixedLogger = logger.getChild("[MatrixAudioRenderer]");
/** /**
* Takes care of handling remote participants audio tracks and makes sure that microphones and screen share are audible. * Takes care of handling remote participants audio tracks and makes sure that microphones and screen share are audible.
* *
@@ -60,6 +59,7 @@ export function LivekitRoomAudioRenderer({
validIdentities, validIdentities,
muted, muted,
}: MatrixAudioRendererProps): ReactNode { }: MatrixAudioRendererProps): ReactNode {
const logger = rootLogger.getChild("[MatrixAudioRenderer]");
const tracks = useTracks( const tracks = useTracks(
[ [
Track.Source.Microphone, Track.Source.Microphone,
@@ -80,7 +80,7 @@ export function LivekitRoomAudioRenderer({
if (!isValid) { if (!isValid) {
// TODO make sure to also skip the warn logging for the local identity // TODO make sure to also skip the warn logging for the local identity
// Log that there is an invalid identity, that means that someone is publishing audio that is not expected to be in the call. // Log that there is an invalid identity, that means that someone is publishing audio that is not expected to be in the call.
prefixedLogger.warn( logger.warn(
`Audio track ${ref.participant.identity} from ${url} has no matching matrix call member`, `Audio track ${ref.participant.identity} from ${url} has no matching matrix call member`,
`current members: ${validIdentities.join()}`, `current members: ${validIdentities.join()}`,
`track will not get rendered`, `track will not get rendered`,

View File

@@ -2,10 +2,10 @@
exports[`RaisedHandIndicator > renders a smaller indicator when miniature is specified 1`] = ` exports[`RaisedHandIndicator > renders a smaller indicator when miniature is specified 1`] = `
<div <div
class="reactionIndicatorWidget" class="_reactionIndicatorWidget_abd277"
> >
<div <div
class="reaction" class="_reaction_abd277"
> >
<span <span
aria-label="Reaction" aria-label="Reaction"
@@ -22,10 +22,10 @@ exports[`RaisedHandIndicator > renders a smaller indicator when miniature is spe
exports[`RaisedHandIndicator > renders an indicator when a hand has been raised 1`] = ` exports[`RaisedHandIndicator > renders an indicator when a hand has been raised 1`] = `
<div <div
class="reactionIndicatorWidget reactionIndicatorWidgetLarge" class="_reactionIndicatorWidget_abd277 _reactionIndicatorWidgetLarge_abd277"
> >
<div <div
class="reaction reactionLarge" class="_reaction_abd277 _reactionLarge_abd277"
> >
<span <span
aria-label="Reaction" aria-label="Reaction"
@@ -42,10 +42,10 @@ exports[`RaisedHandIndicator > renders an indicator when a hand has been raised
exports[`RaisedHandIndicator > renders an indicator when a hand has been raised with the expected time 1`] = ` exports[`RaisedHandIndicator > renders an indicator when a hand has been raised with the expected time 1`] = `
<div <div
class="reactionIndicatorWidget reactionIndicatorWidgetLarge" class="_reactionIndicatorWidget_abd277 _reactionIndicatorWidgetLarge_abd277"
> >
<div <div
class="reaction reactionLarge" class="_reaction_abd277 _reactionLarge_abd277"
> >
<span <span
aria-label="Reaction" aria-label="Reaction"

View File

@@ -94,8 +94,6 @@ declare module "react" {
} }
} }
const logger = rootLogger.getChild("[InCallView]");
export interface ActiveCallProps extends Omit< export interface ActiveCallProps extends Omit<
InCallViewProps, InCallViewProps,
"vm" | "livekitRoom" | "connState" | "footerVm" "vm" | "livekitRoom" | "connState" | "footerVm"
@@ -116,7 +114,7 @@ export const ActiveCall: FC<ActiveCallProps> = (props) => {
const mediaDevices = useMediaDevices(); const mediaDevices = useMediaDevices();
const trackProcessorState$ = useTrackProcessorObservable$(); const trackProcessorState$ = useTrackProcessorObservable$();
useEffect(() => { useEffect(() => {
logger.info("START CALL VIEW SCOPE"); rootLogger.info("START CALL VIEW SCOPE");
const scope = new ObservableScope(); const scope = new ObservableScope();
const reactionsReader = new ReactionsReader(scope, props.rtcSession); const reactionsReader = new ReactionsReader(scope, props.rtcSession);
const { autoLeaveWhenOthersLeft, waitForCallPickup, sendNotificationType } = const { autoLeaveWhenOthersLeft, waitForCallPickup, sendNotificationType } =
@@ -218,6 +216,7 @@ export const InCallView: FC<InCallViewProps> = ({
muteStates, muteStates,
onShareClick, onShareClick,
}) => { }) => {
const logger = rootLogger.getChild("[InCallView]");
const { t } = useTranslation(); const { t } = useTranslation();
const { sendReaction, toggleRaisedHand } = useReactionsSender(); const { sendReaction, toggleRaisedHand } = useReactionsSender();

View File

@@ -145,8 +145,7 @@ describe("LobbyView", () => {
.querySelector("path")! .querySelector("path")!
.getAttribute("d"); .getAttribute("d");
const primaryButtonSvgPath = container const primaryButtonSvgPath = container
.querySelector(".primaryButton") .querySelector("path")
?.querySelector("path")
?.getAttribute("d"); ?.getAttribute("d");
expect(primaryButtonSvgPath).toBe(expectedSvgPath); expect(primaryButtonSvgPath).toBe(expectedSvgPath);
expect(container).toMatchSnapshot(); expect(container).toMatchSnapshot();
@@ -169,8 +168,7 @@ describe("LobbyView", () => {
.querySelector("path")! .querySelector("path")!
.getAttribute("d"); .getAttribute("d");
const primaryButtonSvgPath = container const primaryButtonSvgPath = container
.querySelector(".primaryButton") .querySelector("path")
?.querySelector("path")
?.getAttribute("d"); ?.getAttribute("d");
expect(primaryButtonSvgPath).toBe(expectedSvgPath); expect(primaryButtonSvgPath).toBe(expectedSvgPath);
expect(container).toMatchSnapshot(); expect(container).toMatchSnapshot();

View File

@@ -3,17 +3,17 @@
exports[`ConnectionLostError: Action handling should reset error state 1`] = ` exports[`ConnectionLostError: Action handling should reset error state 1`] = `
<DocumentFragment> <DocumentFragment>
<div <div
class="page" class="_page_4be5c0"
> >
<header <header
class="header" class="_header_e4b327"
> >
<div <div
class="nav leftNav" class="_nav_e4b327 _leftNav_e4b327"
> >
<a <a
aria-label="Element Call Home" aria-label="Element Call Home"
class="headerLogo" class="_headerLogo_e4b327"
data-discover="true" data-discover="true"
href="/" href="/"
> >
@@ -95,20 +95,20 @@ exports[`ConnectionLostError: Action handling should reset error state 1`] = `
</a> </a>
</div> </div>
<div <div
class="nav rightNav" class="_nav_e4b327 _rightNav_e4b327"
/> />
</header> </header>
<div <div
class="container" class="_container_4be5c0"
> >
<div <div
class="content" class="_content_4be5c0"
> >
<div <div
class="error" class="_error_a69dc5"
> >
<div <div
class="_big-icon_1ssbv_8 icon" class="_big-icon_1ssbv_8 _icon_a69dc5"
data-kind="primary" data-kind="primary"
data-size="lg" data-size="lg"
> >
@@ -161,17 +161,17 @@ exports[`ConnectionLostError: Action handling should reset error state 1`] = `
exports[`LiveKit ConnectionError variants > should display LiveKit 'internal' error correctly 1`] = ` exports[`LiveKit ConnectionError variants > should display LiveKit 'internal' error correctly 1`] = `
<DocumentFragment> <DocumentFragment>
<div <div
class="page" class="_page_4be5c0"
> >
<header <header
class="header" class="_header_e4b327"
> >
<div <div
class="nav leftNav" class="_nav_e4b327 _leftNav_e4b327"
> >
<a <a
aria-label="Element Call Home" aria-label="Element Call Home"
class="headerLogo" class="_headerLogo_e4b327"
data-discover="true" data-discover="true"
href="/" href="/"
> >
@@ -253,20 +253,20 @@ exports[`LiveKit ConnectionError variants > should display LiveKit 'internal' er
</a> </a>
</div> </div>
<div <div
class="nav rightNav" class="_nav_e4b327 _rightNav_e4b327"
/> />
</header> </header>
<div <div
class="container" class="_container_4be5c0"
> >
<div <div
class="content" class="_content_4be5c0"
> >
<div <div
class="error" class="_error_a69dc5"
> >
<div <div
class="_big-icon_1ssbv_8 icon" class="_big-icon_1ssbv_8 _icon_a69dc5"
data-kind="primary" data-kind="primary"
data-size="lg" data-size="lg"
> >
@@ -318,17 +318,17 @@ exports[`LiveKit ConnectionError variants > should display LiveKit 'internal' er
exports[`LiveKit ConnectionError variants > should display LiveKit 'notAllowed' error correctly 1`] = ` exports[`LiveKit ConnectionError variants > should display LiveKit 'notAllowed' error correctly 1`] = `
<DocumentFragment> <DocumentFragment>
<div <div
class="page" class="_page_4be5c0"
> >
<header <header
class="header" class="_header_e4b327"
> >
<div <div
class="nav leftNav" class="_nav_e4b327 _leftNav_e4b327"
> >
<a <a
aria-label="Element Call Home" aria-label="Element Call Home"
class="headerLogo" class="_headerLogo_e4b327"
data-discover="true" data-discover="true"
href="/" href="/"
> >
@@ -410,20 +410,20 @@ exports[`LiveKit ConnectionError variants > should display LiveKit 'notAllowed'
</a> </a>
</div> </div>
<div <div
class="nav rightNav" class="_nav_e4b327 _rightNav_e4b327"
/> />
</header> </header>
<div <div
class="container" class="_container_4be5c0"
> >
<div <div
class="content" class="_content_4be5c0"
> >
<div <div
class="error" class="_error_a69dc5"
> >
<div <div
class="_big-icon_1ssbv_8 icon" class="_big-icon_1ssbv_8 _icon_a69dc5"
data-kind="primary" data-kind="primary"
data-size="lg" data-size="lg"
> >
@@ -475,17 +475,17 @@ exports[`LiveKit ConnectionError variants > should display LiveKit 'notAllowed'
exports[`LiveKit ConnectionError variants > should display LiveKit 'serverUnreachable' error correctly 1`] = ` exports[`LiveKit ConnectionError variants > should display LiveKit 'serverUnreachable' error correctly 1`] = `
<DocumentFragment> <DocumentFragment>
<div <div
class="page" class="_page_4be5c0"
> >
<header <header
class="header" class="_header_e4b327"
> >
<div <div
class="nav leftNav" class="_nav_e4b327 _leftNav_e4b327"
> >
<a <a
aria-label="Element Call Home" aria-label="Element Call Home"
class="headerLogo" class="_headerLogo_e4b327"
data-discover="true" data-discover="true"
href="/" href="/"
> >
@@ -567,20 +567,20 @@ exports[`LiveKit ConnectionError variants > should display LiveKit 'serverUnreac
</a> </a>
</div> </div>
<div <div
class="nav rightNav" class="_nav_e4b327 _rightNav_e4b327"
/> />
</header> </header>
<div <div
class="container" class="_container_4be5c0"
> >
<div <div
class="content" class="_content_4be5c0"
> >
<div <div
class="error" class="_error_a69dc5"
> >
<div <div
class="_big-icon_1ssbv_8 icon" class="_big-icon_1ssbv_8 _icon_a69dc5"
data-kind="primary" data-kind="primary"
data-size="lg" data-size="lg"
> >
@@ -632,17 +632,17 @@ exports[`LiveKit ConnectionError variants > should display LiveKit 'serverUnreac
exports[`LiveKit ConnectionError variants > should display LiveKit 'serviceNotFound' error correctly 1`] = ` exports[`LiveKit ConnectionError variants > should display LiveKit 'serviceNotFound' error correctly 1`] = `
<DocumentFragment> <DocumentFragment>
<div <div
class="page" class="_page_4be5c0"
> >
<header <header
class="header" class="_header_e4b327"
> >
<div <div
class="nav leftNav" class="_nav_e4b327 _leftNav_e4b327"
> >
<a <a
aria-label="Element Call Home" aria-label="Element Call Home"
class="headerLogo" class="_headerLogo_e4b327"
data-discover="true" data-discover="true"
href="/" href="/"
> >
@@ -724,20 +724,20 @@ exports[`LiveKit ConnectionError variants > should display LiveKit 'serviceNotFo
</a> </a>
</div> </div>
<div <div
class="nav rightNav" class="_nav_e4b327 _rightNav_e4b327"
/> />
</header> </header>
<div <div
class="container" class="_container_4be5c0"
> >
<div <div
class="content" class="_content_4be5c0"
> >
<div <div
class="error" class="_error_a69dc5"
> >
<div <div
class="_big-icon_1ssbv_8 icon" class="_big-icon_1ssbv_8 _icon_a69dc5"
data-kind="primary" data-kind="primary"
data-size="lg" data-size="lg"
> >
@@ -789,17 +789,17 @@ exports[`LiveKit ConnectionError variants > should display LiveKit 'serviceNotFo
exports[`LiveKit ConnectionError variants > should display LiveKit 'timeout' error correctly 1`] = ` exports[`LiveKit ConnectionError variants > should display LiveKit 'timeout' error correctly 1`] = `
<DocumentFragment> <DocumentFragment>
<div <div
class="page" class="_page_4be5c0"
> >
<header <header
class="header" class="_header_e4b327"
> >
<div <div
class="nav leftNav" class="_nav_e4b327 _leftNav_e4b327"
> >
<a <a
aria-label="Element Call Home" aria-label="Element Call Home"
class="headerLogo" class="_headerLogo_e4b327"
data-discover="true" data-discover="true"
href="/" href="/"
> >
@@ -881,20 +881,20 @@ exports[`LiveKit ConnectionError variants > should display LiveKit 'timeout' err
</a> </a>
</div> </div>
<div <div
class="nav rightNav" class="_nav_e4b327 _rightNav_e4b327"
/> />
</header> </header>
<div <div
class="container" class="_container_4be5c0"
> >
<div <div
class="content" class="_content_4be5c0"
> >
<div <div
class="error" class="_error_a69dc5"
> >
<div <div
class="_big-icon_1ssbv_8 icon" class="_big-icon_1ssbv_8 _icon_a69dc5"
data-kind="primary" data-kind="primary"
data-size="lg" data-size="lg"
> >
@@ -946,17 +946,17 @@ exports[`LiveKit ConnectionError variants > should display LiveKit 'timeout' err
exports[`LiveKit ConnectionError variants > should link to troubleshoot guide when timeout error 1`] = ` exports[`LiveKit ConnectionError variants > should link to troubleshoot guide when timeout error 1`] = `
<DocumentFragment> <DocumentFragment>
<div <div
class="page" class="_page_4be5c0"
> >
<header <header
class="header" class="_header_e4b327"
> >
<div <div
class="nav leftNav" class="_nav_e4b327 _leftNav_e4b327"
> >
<a <a
aria-label="Element Call Home" aria-label="Element Call Home"
class="headerLogo" class="_headerLogo_e4b327"
data-discover="true" data-discover="true"
href="/" href="/"
> >
@@ -1038,20 +1038,20 @@ exports[`LiveKit ConnectionError variants > should link to troubleshoot guide wh
</a> </a>
</div> </div>
<div <div
class="nav rightNav" class="_nav_e4b327 _rightNav_e4b327"
/> />
</header> </header>
<div <div
class="container" class="_container_4be5c0"
> >
<div <div
class="content" class="_content_4be5c0"
> >
<div <div
class="error" class="_error_a69dc5"
> >
<div <div
class="_big-icon_1ssbv_8 icon" class="_big-icon_1ssbv_8 _icon_a69dc5"
data-kind="primary" data-kind="primary"
data-size="lg" data-size="lg"
> >
@@ -1103,17 +1103,17 @@ exports[`LiveKit ConnectionError variants > should link to troubleshoot guide wh
exports[`should have a close button in widget mode 1`] = ` exports[`should have a close button in widget mode 1`] = `
<DocumentFragment> <DocumentFragment>
<div <div
class="page" class="_page_4be5c0"
> >
<header <header
class="header" class="_header_e4b327"
> >
<div <div
class="nav leftNav" class="_nav_e4b327 _leftNav_e4b327"
> >
<a <a
aria-label="Element Call Home" aria-label="Element Call Home"
class="headerLogo" class="_headerLogo_e4b327"
data-discover="true" data-discover="true"
href="/" href="/"
> >
@@ -1195,20 +1195,20 @@ exports[`should have a close button in widget mode 1`] = `
</a> </a>
</div> </div>
<div <div
class="nav rightNav" class="_nav_e4b327 _rightNav_e4b327"
/> />
</header> </header>
<div <div
class="container" class="_container_4be5c0"
> >
<div <div
class="content" class="_content_4be5c0"
> >
<div <div
class="error" class="_error_a69dc5"
> >
<div <div
class="_big-icon_1ssbv_8 icon" class="_big-icon_1ssbv_8 _icon_a69dc5"
data-kind="primary" data-kind="primary"
data-size="lg" data-size="lg"
> >
@@ -1257,17 +1257,17 @@ exports[`should have a close button in widget mode 1`] = `
exports[`should render the error page with link back to home 1`] = ` exports[`should render the error page with link back to home 1`] = `
<DocumentFragment> <DocumentFragment>
<div <div
class="page" class="_page_4be5c0"
> >
<header <header
class="header" class="_header_e4b327"
> >
<div <div
class="nav leftNav" class="_nav_e4b327 _leftNav_e4b327"
> >
<a <a
aria-label="Element Call Home" aria-label="Element Call Home"
class="headerLogo" class="_headerLogo_e4b327"
data-discover="true" data-discover="true"
href="/" href="/"
> >
@@ -1349,20 +1349,20 @@ exports[`should render the error page with link back to home 1`] = `
</a> </a>
</div> </div>
<div <div
class="nav rightNav" class="_nav_e4b327 _rightNav_e4b327"
/> />
</header> </header>
<div <div
class="container" class="_container_4be5c0"
> >
<div <div
class="content" class="_content_4be5c0"
> >
<div <div
class="error" class="_error_a69dc5"
> >
<div <div
class="_big-icon_1ssbv_8 icon" class="_big-icon_1ssbv_8 _icon_a69dc5"
data-kind="primary" data-kind="primary"
data-size="lg" data-size="lg"
> >
@@ -1411,17 +1411,17 @@ exports[`should render the error page with link back to home 1`] = `
exports[`should report correct error for 'Call is not supported' 1`] = ` exports[`should report correct error for 'Call is not supported' 1`] = `
<DocumentFragment> <DocumentFragment>
<div <div
class="page" class="_page_4be5c0"
> >
<header <header
class="header" class="_header_e4b327"
> >
<div <div
class="nav leftNav" class="_nav_e4b327 _leftNav_e4b327"
> >
<a <a
aria-label="Element Call Home" aria-label="Element Call Home"
class="headerLogo" class="_headerLogo_e4b327"
data-discover="true" data-discover="true"
href="/" href="/"
> >
@@ -1503,20 +1503,20 @@ exports[`should report correct error for 'Call is not supported' 1`] = `
</a> </a>
</div> </div>
<div <div
class="nav rightNav" class="_nav_e4b327 _rightNav_e4b327"
/> />
</header> </header>
<div <div
class="container" class="_container_4be5c0"
> >
<div <div
class="content" class="_content_4be5c0"
> >
<div <div
class="error" class="_error_a69dc5"
> >
<div <div
class="_big-icon_1ssbv_8 icon" class="_big-icon_1ssbv_8 _icon_a69dc5"
data-kind="primary" data-kind="primary"
data-size="lg" data-size="lg"
> >
@@ -1565,17 +1565,17 @@ exports[`should report correct error for 'Call is not supported' 1`] = `
exports[`should report correct error for 'Connection lost' 1`] = ` exports[`should report correct error for 'Connection lost' 1`] = `
<DocumentFragment> <DocumentFragment>
<div <div
class="page" class="_page_4be5c0"
> >
<header <header
class="header" class="_header_e4b327"
> >
<div <div
class="nav leftNav" class="_nav_e4b327 _leftNav_e4b327"
> >
<a <a
aria-label="Element Call Home" aria-label="Element Call Home"
class="headerLogo" class="_headerLogo_e4b327"
data-discover="true" data-discover="true"
href="/" href="/"
> >
@@ -1657,20 +1657,20 @@ exports[`should report correct error for 'Connection lost' 1`] = `
</a> </a>
</div> </div>
<div <div
class="nav rightNav" class="_nav_e4b327 _rightNav_e4b327"
/> />
</header> </header>
<div <div
class="container" class="_container_4be5c0"
> >
<div <div
class="content" class="_content_4be5c0"
> >
<div <div
class="error" class="_error_a69dc5"
> >
<div <div
class="_big-icon_1ssbv_8 icon" class="_big-icon_1ssbv_8 _icon_a69dc5"
data-kind="primary" data-kind="primary"
data-size="lg" data-size="lg"
> >
@@ -1723,17 +1723,17 @@ exports[`should report correct error for 'Connection lost' 1`] = `
exports[`should report correct error for 'Homeserver does not support Matrix 2.…' 1`] = ` exports[`should report correct error for 'Homeserver does not support Matrix 2.…' 1`] = `
<DocumentFragment> <DocumentFragment>
<div <div
class="page" class="_page_4be5c0"
> >
<header <header
class="header" class="_header_e4b327"
> >
<div <div
class="nav leftNav" class="_nav_e4b327 _leftNav_e4b327"
> >
<a <a
aria-label="Element Call Home" aria-label="Element Call Home"
class="headerLogo" class="_headerLogo_e4b327"
data-discover="true" data-discover="true"
href="/" href="/"
> >
@@ -1815,20 +1815,20 @@ exports[`should report correct error for 'Homeserver does not support Matrix 2.
</a> </a>
</div> </div>
<div <div
class="nav rightNav" class="_nav_e4b327 _rightNav_e4b327"
/> />
</header> </header>
<div <div
class="container" class="_container_4be5c0"
> >
<div <div
class="content" class="_content_4be5c0"
> >
<div <div
class="error" class="_error_a69dc5"
> >
<div <div
class="_big-icon_1ssbv_8 icon" class="_big-icon_1ssbv_8 _icon_a69dc5"
data-kind="primary" data-kind="primary"
data-size="lg" data-size="lg"
> >
@@ -1877,17 +1877,17 @@ exports[`should report correct error for 'Homeserver does not support Matrix 2.
exports[`should report correct error for 'Incompatible browser' 1`] = ` exports[`should report correct error for 'Incompatible browser' 1`] = `
<DocumentFragment> <DocumentFragment>
<div <div
class="page" class="_page_4be5c0"
> >
<header <header
class="header" class="_header_e4b327"
> >
<div <div
class="nav leftNav" class="_nav_e4b327 _leftNav_e4b327"
> >
<a <a
aria-label="Element Call Home" aria-label="Element Call Home"
class="headerLogo" class="_headerLogo_e4b327"
data-discover="true" data-discover="true"
href="/" href="/"
> >
@@ -1969,20 +1969,20 @@ exports[`should report correct error for 'Incompatible browser' 1`] = `
</a> </a>
</div> </div>
<div <div
class="nav rightNav" class="_nav_e4b327 _rightNav_e4b327"
/> />
</header> </header>
<div <div
class="container" class="_container_4be5c0"
> >
<div <div
class="content" class="_content_4be5c0"
> >
<div <div
class="error" class="_error_a69dc5"
> >
<div <div
class="_big-icon_1ssbv_8 icon" class="_big-icon_1ssbv_8 _icon_a69dc5"
data-kind="primary" data-kind="primary"
data-size="lg" data-size="lg"
> >
@@ -2026,17 +2026,17 @@ exports[`should report correct error for 'Incompatible browser' 1`] = `
exports[`should report correct error for 'Insufficient capacity' 1`] = ` exports[`should report correct error for 'Insufficient capacity' 1`] = `
<DocumentFragment> <DocumentFragment>
<div <div
class="page" class="_page_4be5c0"
> >
<header <header
class="header" class="_header_e4b327"
> >
<div <div
class="nav leftNav" class="_nav_e4b327 _leftNav_e4b327"
> >
<a <a
aria-label="Element Call Home" aria-label="Element Call Home"
class="headerLogo" class="_headerLogo_e4b327"
data-discover="true" data-discover="true"
href="/" href="/"
> >
@@ -2118,20 +2118,20 @@ exports[`should report correct error for 'Insufficient capacity' 1`] = `
</a> </a>
</div> </div>
<div <div
class="nav rightNav" class="_nav_e4b327 _rightNav_e4b327"
/> />
</header> </header>
<div <div
class="container" class="_container_4be5c0"
> >
<div <div
class="content" class="_content_4be5c0"
> >
<div <div
class="error" class="_error_a69dc5"
> >
<div <div
class="_big-icon_1ssbv_8 icon" class="_big-icon_1ssbv_8 _icon_a69dc5"
data-kind="primary" data-kind="primary"
data-size="lg" data-size="lg"
> >

View File

@@ -3,28 +3,28 @@
exports[`InCallView > rendering > renders 1`] = ` exports[`InCallView > rendering > renders 1`] = `
<div> <div>
<div <div
class="inRoom" class="_inRoom_4e7ff8"
> >
<header <header
class="header header" class="_header_e4b327 _header_4e7ff8"
> >
<div <div
class="nav leftNav" class="_nav_e4b327 _leftNav_e4b327"
> >
<div <div
class="roomHeaderInfo" class="_roomHeaderInfo_e4b327"
data-size="lg" data-size="lg"
> >
<span <span
aria-label="" aria-label=""
class="_avatar_va14e_8 roomAvatar _avatar-imageless_va14e_55" class="_avatar_va14e_8 _roomAvatar_e4b327 _avatar-imageless_va14e_55"
data-color="1" data-color="1"
data-type="round" data-type="round"
role="img" role="img"
style="--cpd-avatar-size: 56px;" style="--cpd-avatar-size: 56px;"
/> />
<div <div
class="nameLine" class="_nameLine_e4b327"
> >
<h1 <h1
class="_typography_6v6n8_153 _font-heading-md-semibold_6v6n8_112" class="_typography_6v6n8_153 _font-heading-md-semibold_6v6n8_112"
@@ -35,7 +35,7 @@ exports[`InCallView > rendering > renders 1`] = `
> >
<svg <svg
aria-labelledby="_r_0_" aria-labelledby="_r_0_"
class="lock" class="_lock_edc97d"
data-encrypted="false" data-encrypted="false"
fill="currentColor" fill="currentColor"
height="16" height="16"
@@ -50,7 +50,7 @@ exports[`InCallView > rendering > renders 1`] = `
</span> </span>
</div> </div>
<div <div
class="participantsLine" class="_participantsLine_e4b327"
> >
<svg <svg
aria-label="Participants" aria-label="Participants"
@@ -80,21 +80,21 @@ exports[`InCallView > rendering > renders 1`] = `
</div> </div>
</div> </div>
<div <div
class="nav rightNav" class="_nav_e4b327 _rightNav_e4b327"
/> />
</header> </header>
<div <div
class="scrollingGrid grid" class="_scrollingGrid_4e7ff8 _grid_b0d1cd"
> >
<div <div
class="layer" class="_layer_b00c5f"
> >
<div <div
class="container slot" class="_container_b00c5f _slot_b0d1cd"
data-id="1" data-id="1"
> >
<div <div
class="slot local slot" class="_slot_b00c5f _local_b00c5f _slot_b0d1cd"
data-block-alignment="start" data-block-alignment="start"
data-id="0" data-id="0"
data-inline-alignment="end" data-inline-alignment="end"
@@ -103,22 +103,22 @@ exports[`InCallView > rendering > renders 1`] = `
</div> </div>
</div> </div>
<div <div
class="fixedGrid grid" class="_fixedGrid_4e7ff8 _grid_b0d1cd"
style="inset-block-start: NaNpx;" style="inset-block-start: NaNpx;"
> >
<div /> <div />
</div> </div>
<div <div
class="bg animate" class="_bg_2f5303 _animate_2f5303"
data-state="closed" data-state="closed"
/> />
<div <div
aria-hidden="true" aria-hidden="true"
class="overlay" class="_overlay_eb6724"
data-show="false" data-show="false"
> >
<div <div
class="_big-icon_1ssbv_8 icon" class="_big-icon_1ssbv_8 _icon_eb6724"
data-kind="primary" data-kind="primary"
data-size="lg" data-size="lg"
> >
@@ -157,22 +157,22 @@ exports[`InCallView > rendering > renders 1`] = `
Back to Speaker Mode Back to Speaker Mode
</button> </button>
<div <div
class="spacer" class="_spacer_eb6724"
/> />
</div> </div>
<div <div
class="container" class="_container_8084b5"
/> />
<div <div
class="footer footer" class="_footer_4e7ff8 _footer_20b7b4"
data-testid="footer-container" data-testid="footer-container"
> >
<div <div
class="settingsLogoContainer" class="_settingsLogoContainer_20b7b4"
> >
<button <button
aria-labelledby="_r_8_" aria-labelledby="_r_8_"
class="_icon-button_1215g_8 settingsOnlyShowWide" class="_icon-button_1215g_8 _settingsOnlyShowWide_20b7b4"
data-kind="secondary" data-kind="secondary"
data-testid="settings-bottom-left" data-testid="settings-bottom-left"
role="button" role="button"
@@ -198,7 +198,7 @@ exports[`InCallView > rendering > renders 1`] = `
</div> </div>
</button> </button>
<div <div
class="logo" class="_logo_20b7b4"
> >
<svg <svg
aria-hidden="true" aria-hidden="true"
@@ -303,11 +303,11 @@ exports[`InCallView > rendering > renders 1`] = `
</div> </div>
</div> </div>
<div <div
class="buttons" class="_buttons_20b7b4"
> >
<button <button
aria-labelledby="_r_d_" aria-labelledby="_r_d_"
class="_button_1nw83_8 settingsOnlyShowNarrow _has-icon_1nw83_60 _icon-only_1nw83_53" class="_button_1nw83_8 _settingsOnlyShowNarrow_20b7b4 _has-icon_1nw83_60 _icon-only_1nw83_53"
data-kind="secondary" data-kind="secondary"
data-size="lg" data-size="lg"
data-testid="settings-bottom-center" data-testid="settings-bottom-center"
@@ -382,7 +382,7 @@ exports[`InCallView > rendering > renders 1`] = `
aria-expanded="false" aria-expanded="false"
aria-haspopup="true" aria-haspopup="true"
aria-labelledby="_r_s_" aria-labelledby="_r_s_"
class="_button_1nw83_8 raiseHand _has-icon_1nw83_60 _icon-only_1nw83_53" class="_button_1nw83_8 _raiseHand_20b7b4 _has-icon_1nw83_60 _icon-only_1nw83_53"
data-kind="secondary" data-kind="secondary"
data-size="lg" data-size="lg"
role="button" role="button"
@@ -405,7 +405,7 @@ exports[`InCallView > rendering > renders 1`] = `
</button> </button>
<button <button
aria-labelledby="_r_14_" aria-labelledby="_r_14_"
class="_button_1nw83_8 endCall _has-icon_1nw83_60 _icon-only_1nw83_53 _destructive_1nw83_110" class="_button_1nw83_8 _endCall_204dcb _has-icon_1nw83_60 _icon-only_1nw83_53 _destructive_1nw83_110"
data-kind="primary" data-kind="primary"
data-size="lg" data-size="lg"
data-testid="incall_leave" data-testid="incall_leave"
@@ -428,7 +428,7 @@ exports[`InCallView > rendering > renders 1`] = `
</div> </div>
<fieldset <fieldset
aria-label="Layout" aria-label="Layout"
class="_toggle_13rnk_9 layout" class="_toggle_13rnk_9 _layout_20b7b4"
data-size="lg" data-size="lg"
> >
<input <input

View File

@@ -3,12 +3,12 @@
exports[`LobbyView > renders with AppBar android 1`] = ` exports[`LobbyView > renders with AppBar android 1`] = `
<div> <div>
<div <div
class="bar" class="_bar_221541"
> >
<header> <header>
<button <button
aria-labelledby="_r_36_" aria-labelledby="_r_36_"
class="_icon-button_1215g_8 primaryButton" class="_icon-button_1215g_8 _primaryButton_221541"
data-kind="primary" data-kind="primary"
role="button" role="button"
style="--cpd-icon-button-size: 32px;" style="--cpd-icon-button-size: 32px;"
@@ -33,18 +33,18 @@ exports[`LobbyView > renders with AppBar android 1`] = `
</div> </div>
</button> </button>
<div <div
class="secondaryButton" class="_secondaryButton_221541"
/> />
</header> </header>
</div> </div>
<div <div
class="inRoom" class="_inRoom_4e7ff8"
> >
<div <div
class="content" class="_content_f9ee84"
> >
<div <div
class="preview" class="_preview_dd2178"
> >
<video <video
disablepictureinpicture="" disablepictureinpicture=""
@@ -52,7 +52,7 @@ exports[`LobbyView > renders with AppBar android 1`] = `
tabindex="-1" tabindex="-1"
/> />
<div <div
class="avatarContainer" class="_avatarContainer_dd2178"
> >
<div> <div>
<span <span
@@ -68,11 +68,11 @@ exports[`LobbyView > renders with AppBar android 1`] = `
</div> </div>
</div> </div>
<div <div
class="buttonBar" class="_buttonBar_dd2178"
> >
<button <button
aria-disabled="true" aria-disabled="true"
class="_button_1nw83_8 join wait" class="_button_1nw83_8 _join_f9ee84 _wait_f9ee84"
data-kind="primary" data-kind="primary"
data-size="md" data-size="md"
data-testid="lobby_joinCall" data-testid="lobby_joinCall"
@@ -94,15 +94,15 @@ exports[`LobbyView > renders with AppBar android 1`] = `
</a> </a>
</div> </div>
<div <div
class="footer" class="_footer_20b7b4"
data-testid="footer-container" data-testid="footer-container"
> >
<div <div
class="settingsLogoContainer" class="_settingsLogoContainer_20b7b4"
> >
<button <button
aria-labelledby="_r_3c_" aria-labelledby="_r_3c_"
class="_icon-button_1215g_8 settingsOnlyShowWide" class="_icon-button_1215g_8 _settingsOnlyShowWide_20b7b4"
data-kind="secondary" data-kind="secondary"
data-testid="settings-bottom-left" data-testid="settings-bottom-left"
role="button" role="button"
@@ -129,11 +129,11 @@ exports[`LobbyView > renders with AppBar android 1`] = `
</button> </button>
</div> </div>
<div <div
class="buttons" class="_buttons_20b7b4"
> >
<button <button
aria-labelledby="_r_3h_" aria-labelledby="_r_3h_"
class="_button_1nw83_8 settingsOnlyShowNarrow _has-icon_1nw83_60 _icon-only_1nw83_53" class="_button_1nw83_8 _settingsOnlyShowNarrow_20b7b4 _has-icon_1nw83_60 _icon-only_1nw83_53"
data-kind="secondary" data-kind="secondary"
data-size="lg" data-size="lg"
data-testid="settings-bottom-center" data-testid="settings-bottom-center"
@@ -205,7 +205,7 @@ exports[`LobbyView > renders with AppBar android 1`] = `
</button> </button>
<button <button
aria-labelledby="_r_40_" aria-labelledby="_r_40_"
class="_button_1nw83_8 endCall _has-icon_1nw83_60 _icon-only_1nw83_53 _destructive_1nw83_110" class="_button_1nw83_8 _endCall_204dcb _has-icon_1nw83_60 _icon-only_1nw83_53 _destructive_1nw83_110"
data-kind="primary" data-kind="primary"
data-size="lg" data-size="lg"
data-testid="incall_leave" data-testid="incall_leave"
@@ -234,12 +234,12 @@ exports[`LobbyView > renders with AppBar android 1`] = `
exports[`LobbyView > renders with AppBar ios 1`] = ` exports[`LobbyView > renders with AppBar ios 1`] = `
<div> <div>
<div <div
class="bar" class="_bar_221541"
> >
<header> <header>
<button <button
aria-labelledby="_r_4a_" aria-labelledby="_r_4a_"
class="_icon-button_1215g_8 primaryButton" class="_icon-button_1215g_8 _primaryButton_221541"
data-kind="primary" data-kind="primary"
role="button" role="button"
style="--cpd-icon-button-size: 32px;" style="--cpd-icon-button-size: 32px;"
@@ -264,18 +264,18 @@ exports[`LobbyView > renders with AppBar ios 1`] = `
</div> </div>
</button> </button>
<div <div
class="secondaryButton" class="_secondaryButton_221541"
/> />
</header> </header>
</div> </div>
<div <div
class="inRoom" class="_inRoom_4e7ff8"
> >
<div <div
class="content" class="_content_f9ee84"
> >
<div <div
class="preview" class="_preview_dd2178"
> >
<video <video
disablepictureinpicture="" disablepictureinpicture=""
@@ -283,7 +283,7 @@ exports[`LobbyView > renders with AppBar ios 1`] = `
tabindex="-1" tabindex="-1"
/> />
<div <div
class="avatarContainer" class="_avatarContainer_dd2178"
> >
<div> <div>
<span <span
@@ -299,11 +299,11 @@ exports[`LobbyView > renders with AppBar ios 1`] = `
</div> </div>
</div> </div>
<div <div
class="buttonBar" class="_buttonBar_dd2178"
> >
<button <button
aria-disabled="true" aria-disabled="true"
class="_button_1nw83_8 join wait" class="_button_1nw83_8 _join_f9ee84 _wait_f9ee84"
data-kind="primary" data-kind="primary"
data-size="md" data-size="md"
data-testid="lobby_joinCall" data-testid="lobby_joinCall"
@@ -325,15 +325,15 @@ exports[`LobbyView > renders with AppBar ios 1`] = `
</a> </a>
</div> </div>
<div <div
class="footer" class="_footer_20b7b4"
data-testid="footer-container" data-testid="footer-container"
> >
<div <div
class="settingsLogoContainer" class="_settingsLogoContainer_20b7b4"
> >
<button <button
aria-labelledby="_r_4g_" aria-labelledby="_r_4g_"
class="_icon-button_1215g_8 settingsOnlyShowWide" class="_icon-button_1215g_8 _settingsOnlyShowWide_20b7b4"
data-kind="secondary" data-kind="secondary"
data-testid="settings-bottom-left" data-testid="settings-bottom-left"
role="button" role="button"
@@ -360,11 +360,11 @@ exports[`LobbyView > renders with AppBar ios 1`] = `
</button> </button>
</div> </div>
<div <div
class="buttons" class="_buttons_20b7b4"
> >
<button <button
aria-labelledby="_r_4l_" aria-labelledby="_r_4l_"
class="_button_1nw83_8 settingsOnlyShowNarrow _has-icon_1nw83_60 _icon-only_1nw83_53" class="_button_1nw83_8 _settingsOnlyShowNarrow_20b7b4 _has-icon_1nw83_60 _icon-only_1nw83_53"
data-kind="secondary" data-kind="secondary"
data-size="lg" data-size="lg"
data-testid="settings-bottom-center" data-testid="settings-bottom-center"
@@ -436,7 +436,7 @@ exports[`LobbyView > renders with AppBar ios 1`] = `
</button> </button>
<button <button
aria-labelledby="_r_54_" aria-labelledby="_r_54_"
class="_button_1nw83_8 endCall _has-icon_1nw83_60 _icon-only_1nw83_53 _destructive_1nw83_110" class="_button_1nw83_8 _endCall_204dcb _has-icon_1nw83_60 _icon-only_1nw83_53 _destructive_1nw83_110"
data-kind="primary" data-kind="primary"
data-size="lg" data-size="lg"
data-testid="incall_leave" data-testid="incall_leave"
@@ -465,21 +465,21 @@ exports[`LobbyView > renders with AppBar ios 1`] = `
exports[`LobbyView > renders with header and participant count 1`] = ` exports[`LobbyView > renders with header and participant count 1`] = `
<div> <div>
<div <div
class="inRoom" class="_inRoom_4e7ff8"
> >
<header <header
class="header" class="_header_e4b327"
> >
<div <div
class="nav leftNav" class="_nav_e4b327 _leftNav_e4b327"
> >
<div <div
class="roomHeaderInfo" class="_roomHeaderInfo_e4b327"
data-size="lg" data-size="lg"
> >
<span <span
aria-label="!room:example.org" aria-label="!room:example.org"
class="_avatar_va14e_8 roomAvatar _avatar-imageless_va14e_55" class="_avatar_va14e_8 _roomAvatar_e4b327 _avatar-imageless_va14e_55"
data-color="3" data-color="3"
data-type="round" data-type="round"
role="img" role="img"
@@ -488,7 +488,7 @@ exports[`LobbyView > renders with header and participant count 1`] = `
T T
</span> </span>
<div <div
class="nameLine" class="_nameLine_e4b327"
> >
<h1 <h1
class="_typography_6v6n8_153 _font-heading-md-semibold_6v6n8_112" class="_typography_6v6n8_153 _font-heading-md-semibold_6v6n8_112"
@@ -501,7 +501,7 @@ exports[`LobbyView > renders with header and participant count 1`] = `
> >
<svg <svg
aria-labelledby="_r_0_" aria-labelledby="_r_0_"
class="lock" class="_lock_edc97d"
data-encrypted="false" data-encrypted="false"
fill="currentColor" fill="currentColor"
height="16" height="16"
@@ -516,7 +516,7 @@ exports[`LobbyView > renders with header and participant count 1`] = `
</span> </span>
</div> </div>
<div <div
class="participantsLine" class="_participantsLine_e4b327"
> >
<svg <svg
aria-label="Participants" aria-label="Participants"
@@ -546,14 +546,14 @@ exports[`LobbyView > renders with header and participant count 1`] = `
</div> </div>
</div> </div>
<div <div
class="nav rightNav" class="_nav_e4b327 _rightNav_e4b327"
/> />
</header> </header>
<div <div
class="content" class="_content_f9ee84"
> >
<div <div
class="preview" class="_preview_dd2178"
> >
<video <video
disablepictureinpicture="" disablepictureinpicture=""
@@ -561,7 +561,7 @@ exports[`LobbyView > renders with header and participant count 1`] = `
tabindex="-1" tabindex="-1"
/> />
<div <div
class="avatarContainer" class="_avatarContainer_dd2178"
> >
<div> <div>
<span <span
@@ -577,10 +577,10 @@ exports[`LobbyView > renders with header and participant count 1`] = `
</div> </div>
</div> </div>
<div <div
class="buttonBar" class="_buttonBar_dd2178"
> >
<button <button
class="_button_1nw83_8 join" class="_button_1nw83_8 _join_f9ee84"
data-kind="primary" data-kind="primary"
data-size="lg" data-size="lg"
data-testid="lobby_joinCall" data-testid="lobby_joinCall"
@@ -602,15 +602,15 @@ exports[`LobbyView > renders with header and participant count 1`] = `
</a> </a>
</div> </div>
<div <div
class="footer" class="_footer_20b7b4"
data-testid="footer-container" data-testid="footer-container"
> >
<div <div
class="settingsLogoContainer" class="_settingsLogoContainer_20b7b4"
> >
<button <button
aria-labelledby="_r_6_" aria-labelledby="_r_6_"
class="_icon-button_1215g_8 settingsOnlyShowWide" class="_icon-button_1215g_8 _settingsOnlyShowWide_20b7b4"
data-kind="secondary" data-kind="secondary"
data-testid="settings-bottom-left" data-testid="settings-bottom-left"
role="button" role="button"
@@ -636,7 +636,7 @@ exports[`LobbyView > renders with header and participant count 1`] = `
</div> </div>
</button> </button>
<div <div
class="logo" class="_logo_20b7b4"
> >
<svg <svg
aria-hidden="true" aria-hidden="true"
@@ -741,11 +741,11 @@ exports[`LobbyView > renders with header and participant count 1`] = `
</div> </div>
</div> </div>
<div <div
class="buttons" class="_buttons_20b7b4"
> >
<button <button
aria-labelledby="_r_b_" aria-labelledby="_r_b_"
class="_button_1nw83_8 settingsOnlyShowNarrow _has-icon_1nw83_60 _icon-only_1nw83_53" class="_button_1nw83_8 _settingsOnlyShowNarrow_20b7b4 _has-icon_1nw83_60 _icon-only_1nw83_53"
data-kind="secondary" data-kind="secondary"
data-size="lg" data-size="lg"
data-testid="settings-bottom-center" data-testid="settings-bottom-center"
@@ -817,7 +817,7 @@ exports[`LobbyView > renders with header and participant count 1`] = `
</button> </button>
<button <button
aria-labelledby="_r_q_" aria-labelledby="_r_q_"
class="_button_1nw83_8 endCall _has-icon_1nw83_60 _icon-only_1nw83_53 _destructive_1nw83_110" class="_button_1nw83_8 _endCall_204dcb _has-icon_1nw83_60 _icon-only_1nw83_53 _destructive_1nw83_110"
data-kind="primary" data-kind="primary"
data-size="lg" data-size="lg"
data-testid="incall_leave" data-testid="incall_leave"

View File

@@ -18,10 +18,10 @@ exports[`DeveloperSettingsTab > renders and matches snapshot 1`] = `
Device ID: DEVICE123 Device ID: DEVICE123
</p> </p>
<div <div
class="fieldRow" class="_fieldRow_1bd8c0"
> >
<div <div
class="field inputField" class="_field_1bd8c0 _inputField_1bd8c0"
> >
<input <input
aria-describedby="_r_1_" aria-describedby="_r_1_"
@@ -38,10 +38,10 @@ exports[`DeveloperSettingsTab > renders and matches snapshot 1`] = `
</div> </div>
</div> </div>
<div <div
class="fieldRow" class="_fieldRow_1bd8c0"
> >
<div <div
class="field checkboxField" class="_field_1bd8c0 _checkboxField_1bd8c0"
> >
<input <input
aria-describedby="_r_2_" aria-describedby="_r_2_"
@@ -52,7 +52,7 @@ exports[`DeveloperSettingsTab > renders and matches snapshot 1`] = `
for="debugTileLayout" for="debugTileLayout"
> >
<div <div
class="checkbox" class="_checkbox_1bd8c0"
> >
<svg <svg
fill="none" fill="none"
@@ -75,10 +75,10 @@ exports[`DeveloperSettingsTab > renders and matches snapshot 1`] = `
</div> </div>
</div> </div>
<div <div
class="fieldRow" class="_fieldRow_1bd8c0"
> >
<div <div
class="field checkboxField" class="_field_1bd8c0 _checkboxField_1bd8c0"
> >
<input <input
aria-describedby="_r_3_" aria-describedby="_r_3_"
@@ -89,7 +89,7 @@ exports[`DeveloperSettingsTab > renders and matches snapshot 1`] = `
for="showConnectionStats" for="showConnectionStats"
> >
<div <div
class="checkbox" class="_checkbox_1bd8c0"
> >
<svg <svg
fill="none" fill="none"
@@ -112,10 +112,10 @@ exports[`DeveloperSettingsTab > renders and matches snapshot 1`] = `
</div> </div>
</div> </div>
<div <div
class="fieldRow" class="_fieldRow_1bd8c0"
> >
<div <div
class="field checkboxField" class="_field_1bd8c0 _checkboxField_1bd8c0"
> >
<input <input
aria-describedby="_r_4_" aria-describedby="_r_4_"
@@ -126,7 +126,7 @@ exports[`DeveloperSettingsTab > renders and matches snapshot 1`] = `
for="muteAllAudio" for="muteAllAudio"
> >
<div <div
class="checkbox" class="_checkbox_1bd8c0"
> >
<svg <svg
fill="none" fill="none"
@@ -150,10 +150,10 @@ exports[`DeveloperSettingsTab > renders and matches snapshot 1`] = `
</div> </div>
<div <div
class="fieldRow" class="_fieldRow_1bd8c0"
> >
<div <div
class="field checkboxField" class="_field_1bd8c0 _checkboxField_1bd8c0"
> >
<input <input
aria-describedby="_r_5_" aria-describedby="_r_5_"
@@ -164,7 +164,7 @@ exports[`DeveloperSettingsTab > renders and matches snapshot 1`] = `
for="alwaysShowIphoneEarpiece" for="alwaysShowIphoneEarpiece"
> >
<div <div
class="checkbox" class="_checkbox_1bd8c0"
> >
<svg <svg
fill="none" fill="none"
@@ -187,10 +187,10 @@ exports[`DeveloperSettingsTab > renders and matches snapshot 1`] = `
</div> </div>
</div> </div>
<div <div
class="fieldRow" class="_fieldRow_1bd8c0"
> >
<div <div
class="field checkboxField" class="_field_1bd8c0 _checkboxField_1bd8c0"
> >
<input <input
aria-describedby="_r_6_" aria-describedby="_r_6_"
@@ -201,7 +201,7 @@ exports[`DeveloperSettingsTab > renders and matches snapshot 1`] = `
for="enableLivekitExtendedLogs" for="enableLivekitExtendedLogs"
> >
<div <div
class="checkbox" class="_checkbox_1bd8c0"
> >
<svg <svg
fill="none" fill="none"
@@ -386,7 +386,7 @@ exports[`DeveloperSettingsTab > renders and matches snapshot 1`] = `
</div> </div>
</form> </form>
<div <div
class="livekit_room_box" class="_livekit_room_box_2ddec4"
> >
<h4> <h4>
LiveKit SFU: wss://local-sfu.example.org LiveKit SFU: wss://local-sfu.example.org
@@ -427,7 +427,7 @@ exports[`DeveloperSettingsTab > renders and matches snapshot 1`] = `
<ul /> <ul />
</div> </div>
<div <div
class="livekit_room_box" class="_livekit_room_box_2ddec4"
> >
<h4> <h4>
LiveKit SFU: wss://remote-sfu.example.org LiveKit SFU: wss://remote-sfu.example.org

View File

@@ -467,7 +467,7 @@ declare global {
// eslint-disable-next-line no-var, camelcase // eslint-disable-next-line no-var, camelcase
var mx_rage_initStoragePromise: Promise<void> | undefined; var mx_rage_initStoragePromise: Promise<void> | undefined;
} }
export let rageshakeLogger: Logger;
/** /**
* Configure rage shaking support for sending bug reports. * Configure rage shaking support for sending bug reports.
* Modifies globals. * Modifies globals.
@@ -477,7 +477,8 @@ export async function init(): Promise<void> {
global.mx_rage_logger = new ConsoleLogger(); global.mx_rage_logger = new ConsoleLogger();
// configure loglevel based loggers: // configure loglevel based loggers:
setLogExtension(logger, global.mx_rage_logger.log); rageshakeLogger = logger;
setLogExtension(rageshakeLogger, global.mx_rage_logger.log);
// intercept console logging so that we can get matrix_sdk logs: // intercept console logging so that we can get matrix_sdk logs:
// this is nasty, but no logging hooks are provided // this is nasty, but no logging hooks are provided

View File

@@ -39,8 +39,6 @@ import { type Behavior } from "../Behavior";
import { type Epoch, type ObservableScope } from "../ObservableScope"; import { type Epoch, type ObservableScope } from "../ObservableScope";
import { type RoomMemberMap } from "./remoteMembers/MatrixMemberMetadata"; import { type RoomMemberMap } from "./remoteMembers/MatrixMemberMetadata";
const logger = rootLogger.getChild("[CallNotificationLifecycle]");
export type AutoLeaveReason = "allOthersLeft" | "timeout" | "decline"; export type AutoLeaveReason = "allOthersLeft" | "timeout" | "decline";
export interface RingAttempt { export interface RingAttempt {
@@ -114,6 +112,7 @@ export function createCallNotificationLifecycle$({
*/ */
autoLeave$: Observable<AutoLeaveReason>; autoLeave$: Observable<AutoLeaveReason>;
} { } {
const logger = rootLogger.getChild("[CallNotificationLifecycle]");
let ringAttempts$: Observable<RingAttempt> = NEVER; let ringAttempts$: Observable<RingAttempt> = NEVER;
if (options.waitForCallPickup) if (options.waitForCallPickup)
ringAttempts$ = sentCallNotification$.pipe( ringAttempts$ = sentCallNotification$.pipe(

View File

@@ -40,7 +40,7 @@ import {
timer, timer,
takeUntil, takeUntil,
} from "rxjs"; } from "rxjs";
import { logger as rootLogger } from "matrix-js-sdk/lib/logger"; import { type Logger, logger as rootLogger } from "matrix-js-sdk/lib/logger";
import { import {
MembershipManagerEvent, MembershipManagerEvent,
type LivekitTransportConfig, type LivekitTransportConfig,
@@ -157,7 +157,6 @@ import {
} from "../media/RingingMediaViewModel.ts"; } from "../media/RingingMediaViewModel.ts";
import { type GridTileViewModel } from "../TileViewModel.ts"; import { type GridTileViewModel } from "../TileViewModel.ts";
const logger = rootLogger.getChild("[CallViewModel]");
//TODO //TODO
// Larger rename // Larger rename
// member,membership -> rtcMember // member,membership -> rtcMember
@@ -416,6 +415,7 @@ export function createCallViewModel$(
reactionsSubject$: Observable<Record<string, ReactionInfo>>, reactionsSubject$: Observable<Record<string, ReactionInfo>>,
trackProcessorState$: Behavior<ProcessorState>, trackProcessorState$: Behavior<ProcessorState>,
): CallViewModel { ): CallViewModel {
const logger = rootLogger.getChild("[CallViewModel]");
const client = matrixRoom.client; const client = matrixRoom.client;
const userId = client.getUserId(); const userId = client.getUserId();
const deviceId = client.getDeviceId(); const deviceId = client.getDeviceId();
@@ -425,6 +425,7 @@ export function createCallViewModel$(
const livekitKeyProvider = getE2eeKeyProvider( const livekitKeyProvider = getE2eeKeyProvider(
options.encryptionSystem, options.encryptionSystem,
matrixRTCSession, matrixRTCSession,
logger,
); );
// matrix_rtc_mode in config.json overrides the user's Developer Settings choice. // matrix_rtc_mode in config.json overrides the user's Developer Settings choice.
// It is validated at config load (src/config/Config.ts) so the cast is safe. // It is validated at config load (src/config/Config.ts) so the cast is safe.
@@ -1809,6 +1810,7 @@ export function createCallViewModel$(
function getE2eeKeyProvider( function getE2eeKeyProvider(
e2eeSystem: EncryptionSystem, e2eeSystem: EncryptionSystem,
rtcSession: MatrixRTCSession, rtcSession: MatrixRTCSession,
logger: Logger,
): BaseKeyProvider | undefined { ): BaseKeyProvider | undefined {
if (e2eeSystem.kind === E2eeType.NONE) return undefined; if (e2eeSystem.kind === E2eeType.NONE) return undefined;

View File

@@ -31,11 +31,6 @@ import { type ObservableScope } from "../../ObservableScope";
import { type Behavior } from "../../Behavior"; import { type Behavior } from "../../Behavior";
import { type NodeStyleEventEmitter } from "../../../utils/test"; import { type NodeStyleEventEmitter } from "../../../utils/test";
/**
* Logger instance (scoped child) for homeserver connection updates.
*/
const logger = rootLogger.getChild("[HomeserverConnected]");
export type HomeserverDisconnectReason = "sync" | "membership" | "probablyLeft"; export type HomeserverDisconnectReason = "sync" | "membership" | "probablyLeft";
export interface HomeserverConnected { export interface HomeserverConnected {
@@ -70,6 +65,7 @@ export function createHomeserverConnected$(
Pick<MatrixRTCSession, "membershipStatus" | "probablyLeft">, Pick<MatrixRTCSession, "membershipStatus" | "probablyLeft">,
gracePeriodMs?: number, gracePeriodMs?: number,
): HomeserverConnected { ): HomeserverConnected {
const logger = rootLogger.getChild("[HomeserverConnected]");
// Get grace period from parameter or config (default 10000ms) // Get grace period from parameter or config (default 10000ms)
const graceMs = gracePeriodMs ?? Config.get().sync_disconnect_grace_period_ms; const graceMs = gracePeriodMs ?? Config.get().sync_disconnect_grace_period_ms;

View File

@@ -25,7 +25,7 @@ import {
switchMap, switchMap,
tap, tap,
} from "rxjs"; } from "rxjs";
import { logger as rootLogger } from "matrix-js-sdk/lib/logger"; import { logger as rootLogger, type Logger } from "matrix-js-sdk/lib/logger";
import { AutoDiscovery } from "matrix-js-sdk/lib/autodiscovery"; import { AutoDiscovery } from "matrix-js-sdk/lib/autodiscovery";
import { type CallMembershipIdentityParts } from "matrix-js-sdk/lib/matrixrtc/EncryptionManager"; import { type CallMembershipIdentityParts } from "matrix-js-sdk/lib/matrixrtc/EncryptionManager";
@@ -46,8 +46,6 @@ import { areLivekitTransportsEqual } from "../remoteMembers/MatrixLivekitMembers
import { customLivekitUrl } from "../../../settings/settings.ts"; import { customLivekitUrl } from "../../../settings/settings.ts";
import { RtcTransportAutoDiscovery } from "./RtcTransportAutoDiscovery.ts"; import { RtcTransportAutoDiscovery } from "./RtcTransportAutoDiscovery.ts";
const logger = rootLogger.getChild("[LocalTransport]");
/* /*
* It figures out “which LiveKit focus URL/alias the local user should use,” * It figures out “which LiveKit focus URL/alias the local user should use,”
* optionally aligning with the oldest member, and ensures the SFU path is primed * optionally aligning with the oldest member, and ensures the SFU path is primed
@@ -140,9 +138,14 @@ export const createLocalTransport$ = ({
forceJwtEndpoint, forceJwtEndpoint,
delayId$, delayId$,
}: Props): LocalTransport => { }: Props): LocalTransport => {
const logger = rootLogger.getChild("[LocalTransport]");
// The LiveKit transport in use by the oldest RTC membership. `null` when the // The LiveKit transport in use by the oldest RTC membership. `null` when the
// oldest member has no such transport. // oldest member has no such transport.
const oldestMemberTransport$ = observerOldestMembership$(scope, memberships$); const oldestMemberTransport$ = observerOldestMembership$(
scope,
memberships$,
logger,
);
const transportDiscovery = new RtcTransportAutoDiscovery({ const transportDiscovery = new RtcTransportAutoDiscovery({
client: client, client: client,
@@ -190,6 +193,7 @@ export const createLocalTransport$ = ({
roomId, roomId,
client, client,
delayId ?? undefined, delayId ?? undefined,
logger,
); );
} catch (e) { } catch (e) {
logger.error( logger.error(
@@ -209,6 +213,7 @@ export const createLocalTransport$ = ({
client, client,
ownMembershipIdentity, ownMembershipIdentity,
roomId, roomId,
logger,
); );
} }
@@ -248,6 +253,7 @@ export const createLocalTransport$ = ({
function observerOldestMembership$( function observerOldestMembership$(
scope: ObservableScope, scope: ObservableScope,
memberships$: Behavior<Epoch<CallMembership[]>>, memberships$: Behavior<Epoch<CallMembership[]>>,
logger: Logger,
): Behavior<LivekitTransportConfig | null> { ): Behavior<LivekitTransportConfig | null> {
return scope.behavior<LivekitTransportConfig | null>( return scope.behavior<LivekitTransportConfig | null>(
memberships$.pipe( memberships$.pipe(
@@ -307,6 +313,7 @@ async function doOpenIdAndJWTFromUrl(
> & > &
OpenIDClientParts, OpenIDClientParts,
delayId?: string, delayId?: string,
logger?: Logger,
): Promise<LocalTransportWithSFUConfig> { ): Promise<LocalTransportWithSFUConfig> {
const sfuConfig = await getSFUConfigWithOpenID( const sfuConfig = await getSFUConfigWithOpenID(
client, client,
@@ -337,6 +344,7 @@ function observeLocalTransportForOldestMembership(
OpenIDClientParts, OpenIDClientParts,
ownMembershipIdentity: CallMembershipIdentityParts, ownMembershipIdentity: CallMembershipIdentityParts,
roomId: string, roomId: string,
logger: Logger,
): LocalTransport { ): LocalTransport {
// Ensure we can authenticate with the SFU. // Ensure we can authenticate with the SFU.
const authenticatedOldestMemberTransport$ = oldestMemberTransport$.pipe( const authenticatedOldestMemberTransport$ = oldestMemberTransport$.pipe(
@@ -355,6 +363,7 @@ function observeLocalTransportForOldestMembership(
roomId, roomId,
client, client,
undefined, undefined,
logger,
), ),
).pipe( ).pipe(
catchError((e: unknown) => { catchError((e: unknown) => {

View File

@@ -22,8 +22,6 @@ import {
} from "../../../utils/displayname"; } from "../../../utils/displayname";
import { type Behavior } from "../../Behavior"; import { type Behavior } from "../../Behavior";
const logger = rootLogger.getChild("[MatrixMemberMetadata]");
export type RoomMemberMap = Map< export type RoomMemberMap = Map<
string, string,
Pick<RoomMember, "userId" | "getMxcAvatarUrl" | "rawDisplayName"> Pick<RoomMember, "userId" | "getMxcAvatarUrl" | "rawDisplayName">
@@ -67,6 +65,7 @@ export const memberDisplaynames$ = (
memberships$: Behavior<Pick<CallMembership, "userId">[]>, memberships$: Behavior<Pick<CallMembership, "userId">[]>,
roomMembers$: Behavior<RoomMemberMap>, roomMembers$: Behavior<RoomMemberMap>,
): Behavior<Map<string, string>> => { ): Behavior<Map<string, string>> => {
const logger = rootLogger.getChild("[MatrixMemberMetadata]");
// This map tracks userIds that at some point needed disambiguation. // This map tracks userIds that at some point needed disambiguation.
// This is a memory leak bound to the number of participants. // This is a memory leak bound to the number of participants.
// A call application will always increase the memory if there have been more members in a call. // A call application will always increase the memory if there have been more members in a call.

View File

@@ -6,22 +6,22 @@ Please see LICENSE in the repository root for full details.
*/ */
import { expect, describe, it } from "vitest"; import { expect, describe, it } from "vitest";
import { render } from "@testing-library/react"; import { render, screen } from "@testing-library/react";
import { TileAvatar } from "./TileAvatar"; import { TileAvatar } from "./TileAvatar";
describe("TileAvatar", () => { describe("TileAvatar", () => {
it("should show loading spinner when loading", () => { it("should show loading spinner when loading", () => {
const { container } = render( render(
<TileAvatar id="@a:example.org" name="Alice" size={96} loading={true} />, <TileAvatar id="@a:example.org" name="Alice" size={96} loading={true} />,
); );
expect(container.querySelector(".loading")).toBeInTheDocument(); screen.getByLabelText("Loading");
}); });
it("should not show loading spinner when not loading", () => { it("should not show loading spinner when not loading", () => {
const { container } = render( render(
<TileAvatar id="@a:example.org" name="Alice" size={96} loading={false} />, <TileAvatar id="@a:example.org" name="Alice" size={96} loading={false} />,
); );
expect(container.querySelector(".loading")).not.toBeInTheDocument(); expect(screen.queryByLabelText("Loading")).toBe(null);
}); });
}); });

View File

@@ -7,6 +7,7 @@ Please see LICENSE in the repository root for full details.
import { type FC } from "react"; import { type FC } from "react";
import { InlineSpinner } from "@vector-im/compound-web"; import { InlineSpinner } from "@vector-im/compound-web";
import { useTranslation } from "react-i18next";
import styles from "./TileAvatar.module.css"; import styles from "./TileAvatar.module.css";
import { Avatar, type Props as AvatarProps } from "../Avatar"; import { Avatar, type Props as AvatarProps } from "../Avatar";
@@ -17,11 +18,12 @@ interface Props extends AvatarProps {
} }
export const TileAvatar: FC<Props> = ({ size, loading, ...props }) => { export const TileAvatar: FC<Props> = ({ size, loading, ...props }) => {
const { t } = useTranslation();
return ( return (
<div> <div>
{loading && ( {loading && (
<div className={styles.loading}> <div className={styles.loading}>
<InlineSpinner size={size / 3} /> <InlineSpinner size={size / 3} aria-label={t("common.loading")} />
</div> </div>
)} )}
<Avatar size={size} {...props} /> <Avatar size={size} {...props} />

View File

@@ -18,12 +18,7 @@ export default defineConfig((configEnv) =>
extends: true, extends: true,
test: { test: {
name: "unit", name: "unit",
css: { css: { include: /.+/ },
include: /.+/,
modules: {
classNameStrategy: "non-scoped",
},
},
setupFiles: ["src/vitest.setup.ts"], setupFiles: ["src/vitest.setup.ts"],
environment: "jsdom", environment: "jsdom",
include: ["src/**/*.test.ts", "src/**/*.test.tsx"], include: ["src/**/*.test.ts", "src/**/*.test.tsx"],