mirror of
https://github.com/vector-im/element-call.git
synced 2026-10-16 23:45:50 +00:00
Let developers override the whole transport
The developer setting that overrode the LiveKit service URL becomes a JSON transport, so that a `url`-only or combined transport can be tested against a homeserver that does not advertise one yet. The settings modal shows each LiveKit room's role instead of a never-populated isLocal flag.
This commit is contained in:
+3
-3
@@ -59,10 +59,10 @@
|
|||||||
"developer_mode": {
|
"developer_mode": {
|
||||||
"always_show_iphone_earpiece": "Show iPhone earpiece option on all platforms",
|
"always_show_iphone_earpiece": "Show iPhone earpiece option on all platforms",
|
||||||
"crypto_version": "Crypto version: {{version}}",
|
"crypto_version": "Crypto version: {{version}}",
|
||||||
"custom_livekit_url": {
|
"custom_transport": {
|
||||||
"current_url": "Currently set to: ",
|
"current": "Currently set to: ",
|
||||||
"from_config": "Currently, no overwrite is set. Url from config is used.",
|
"from_config": "Currently, no overwrite is set. Url from config is used.",
|
||||||
"label": "Custom Livekit-url",
|
"label": "Custom transport JSON",
|
||||||
"reset": "Reset overwrite",
|
"reset": "Reset overwrite",
|
||||||
"save": "Save",
|
"save": "Save",
|
||||||
"saving": "Saving..."
|
"saving": "Saving..."
|
||||||
|
|||||||
+13
-12
@@ -694,18 +694,19 @@ export const InCallView: FC<InCallViewProps> = ({
|
|||||||
tab={settingsTab}
|
tab={settingsTab}
|
||||||
onTabChange={setSettingsTab}
|
onTabChange={setSettingsTab}
|
||||||
developerSettingsVm={developerSettingsVm}
|
developerSettingsVm={developerSettingsVm}
|
||||||
livekitRooms={allConnections.map((connectionItem) => ({
|
livekitRooms={allConnections.map(
|
||||||
room: connectionItem.livekitRoom,
|
({ livekitRoom: room, livekitAlias, transport, role }) => ({
|
||||||
livekitAlias: connectionItem.livekitAlias,
|
room,
|
||||||
// TODO compute is local or tag it in the livekit room items already
|
livekitAlias,
|
||||||
isLocal: undefined,
|
role,
|
||||||
url:
|
url:
|
||||||
// It should be relatively clear to the user which kind of URL
|
// It should be relatively clear to the user which kind of URL
|
||||||
// this is, based on the scheme (ws:// vs. http://)
|
// this is, based on the scheme (ws:// vs. http://)
|
||||||
"url" in connectionItem.transport
|
"url" in transport
|
||||||
? connectionItem.transport.url
|
? transport.url
|
||||||
: connectionItem.transport.livekit_service_url,
|
: transport.livekit_service_url,
|
||||||
}))}
|
}),
|
||||||
|
)}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ Please see LICENSE in the repository root for full details.
|
|||||||
|
|
||||||
import { afterEach, describe, expect, it, type Mock, vi } from "vitest";
|
import { afterEach, describe, expect, it, type Mock, vi } from "vitest";
|
||||||
import { render, waitFor, screen } from "@testing-library/react";
|
import { render, waitFor, screen } from "@testing-library/react";
|
||||||
import userEvent from "@testing-library/user-event";
|
import userEvent, { type UserEvent } from "@testing-library/user-event";
|
||||||
import { TooltipProvider } from "@vector-im/compound-web";
|
import { TooltipProvider } from "@vector-im/compound-web";
|
||||||
|
|
||||||
import type { MatrixClient } from "matrix-js-sdk";
|
import type { MatrixClient } from "matrix-js-sdk";
|
||||||
@@ -19,12 +19,12 @@ import {
|
|||||||
import { outOfCallDeveloperSettingsTabViewModel } from "./DeveloperSettingsTabViewModel";
|
import { outOfCallDeveloperSettingsTabViewModel } from "./DeveloperSettingsTabViewModel";
|
||||||
import { createStaticViewModel } from "../state/ViewModel";
|
import { createStaticViewModel } from "../state/ViewModel";
|
||||||
import {
|
import {
|
||||||
customLivekitUrl as customLivekitUrlSetting,
|
customTransport as customTransportSetting,
|
||||||
enableExtendedLivekitLogs as enableExtendedLivekitLogsSetting,
|
enableExtendedLivekitLogs as enableExtendedLivekitLogsSetting,
|
||||||
matrixRTCMode as matrixRTCModeSetting,
|
matrixRTCMode as matrixRTCModeSetting,
|
||||||
} from "./settings";
|
} from "./settings";
|
||||||
import { MatrixRTCMode } from "../config/ConfigOptions";
|
import { MatrixRTCMode } from "../config/ConfigOptions";
|
||||||
import { mockConfig } from "../utils/test";
|
import { exampleTransport, mockConfig } from "../utils/test";
|
||||||
import { getSFUConfig } from "../livekit/auth";
|
import { getSFUConfig } from "../livekit/auth";
|
||||||
|
|
||||||
// Mock url params hook to avoid environment-dependent snapshot churn.
|
// Mock url params hook to avoid environment-dependent snapshot churn.
|
||||||
@@ -77,6 +77,21 @@ function createMockMatrixClient(): MatrixClient {
|
|||||||
} as unknown as MatrixClient;
|
} as unknown as MatrixClient;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Types the JSON representation of an object into the given element.
|
||||||
|
*/
|
||||||
|
async function typeJson(
|
||||||
|
user: UserEvent,
|
||||||
|
element: Element,
|
||||||
|
object: object,
|
||||||
|
): Promise<void> {
|
||||||
|
// `user.type` requires us to escape brackets by doubling them
|
||||||
|
await user.type(
|
||||||
|
element,
|
||||||
|
JSON.stringify(object).replace(/([{[\]])/g, (c) => c + c),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
describe("DeveloperSettingsTab", () => {
|
describe("DeveloperSettingsTab", () => {
|
||||||
it("renders and matches snapshot", async () => {
|
it("renders and matches snapshot", async () => {
|
||||||
const client = createMockMatrixClient();
|
const client = createMockMatrixClient();
|
||||||
@@ -124,9 +139,9 @@ describe("DeveloperSettingsTab", () => {
|
|||||||
|
|
||||||
expect(container).toMatchSnapshot();
|
expect(container).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
describe("custom livekit url", () => {
|
describe("custom transport", () => {
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
customLivekitUrlSetting.setValue(null);
|
customTransportSetting.setValue(null);
|
||||||
});
|
});
|
||||||
const client = {
|
const client = {
|
||||||
doesServerSupportUnstableFeature: vi.fn().mockResolvedValue(true),
|
doesServerSupportUnstableFeature: vi.fn().mockResolvedValue(true),
|
||||||
@@ -135,7 +150,7 @@ describe("DeveloperSettingsTab", () => {
|
|||||||
getDeviceId: () => "DEVICE",
|
getDeviceId: () => "DEVICE",
|
||||||
getDomain: () => "hs",
|
getDomain: () => "hs",
|
||||||
} as unknown as MatrixClient;
|
} as unknown as MatrixClient;
|
||||||
it("will not update custom livekit url without roomId", async () => {
|
it("will not update custom transport without roomId", async () => {
|
||||||
const user = userEvent.setup();
|
const user = userEvent.setup();
|
||||||
|
|
||||||
render(
|
render(
|
||||||
@@ -148,17 +163,17 @@ describe("DeveloperSettingsTab", () => {
|
|||||||
</TooltipProvider>,
|
</TooltipProvider>,
|
||||||
);
|
);
|
||||||
|
|
||||||
const input = screen.getByLabelText("Custom Livekit-url");
|
const input = screen.getByLabelText("Custom transport JSON");
|
||||||
await user.clear(input);
|
await user.clear(input);
|
||||||
await user.type(input, "wss://example.livekit.invalid");
|
await typeJson(user, input, exampleTransport);
|
||||||
|
|
||||||
const saveButton = screen.getByRole("button", { name: "Save" });
|
const saveButton = screen.getByRole("button", { name: "Save" });
|
||||||
await user.click(saveButton);
|
await user.click(saveButton);
|
||||||
expect(getSFUConfig).not.toHaveBeenCalled();
|
expect(getSFUConfig).not.toHaveBeenCalled();
|
||||||
|
|
||||||
expect(customLivekitUrlSetting.getValue()).toBe(null);
|
expect(customTransportSetting.getValue()).toBe(null);
|
||||||
});
|
});
|
||||||
it("will not update custom livekit url without text in input", async () => {
|
it("will not update custom transport without text in input", async () => {
|
||||||
const user = userEvent.setup();
|
const user = userEvent.setup();
|
||||||
|
|
||||||
render(
|
render(
|
||||||
@@ -172,16 +187,16 @@ describe("DeveloperSettingsTab", () => {
|
|||||||
</TooltipProvider>,
|
</TooltipProvider>,
|
||||||
);
|
);
|
||||||
|
|
||||||
const input = screen.getByLabelText("Custom Livekit-url");
|
const input = screen.getByLabelText("Custom transport JSON");
|
||||||
await user.clear(input);
|
await user.clear(input);
|
||||||
|
|
||||||
const saveButton = screen.getByRole("button", { name: "Save" });
|
const saveButton = screen.getByRole("button", { name: "Save" });
|
||||||
await user.click(saveButton);
|
await user.click(saveButton);
|
||||||
expect(getSFUConfig).not.toHaveBeenCalled();
|
expect(getSFUConfig).not.toHaveBeenCalled();
|
||||||
|
|
||||||
expect(customLivekitUrlSetting.getValue()).toBe(null);
|
expect(customTransportSetting.getValue()).toBe(null);
|
||||||
});
|
});
|
||||||
it("will not update custom livekit url when pressing cancel", async () => {
|
it("will not update custom transport when pressing cancel", async () => {
|
||||||
const user = userEvent.setup();
|
const user = userEvent.setup();
|
||||||
|
|
||||||
render(
|
render(
|
||||||
@@ -195,7 +210,7 @@ describe("DeveloperSettingsTab", () => {
|
|||||||
</TooltipProvider>,
|
</TooltipProvider>,
|
||||||
);
|
);
|
||||||
|
|
||||||
const input = screen.getByLabelText("Custom Livekit-url");
|
const input = screen.getByLabelText("Custom transport JSON");
|
||||||
await user.clear(input);
|
await user.clear(input);
|
||||||
await user.type(input, "wss://example.livekit.invalid");
|
await user.type(input, "wss://example.livekit.invalid");
|
||||||
|
|
||||||
@@ -205,9 +220,9 @@ describe("DeveloperSettingsTab", () => {
|
|||||||
await user.click(cancelButton);
|
await user.click(cancelButton);
|
||||||
expect(getSFUConfig).not.toHaveBeenCalled();
|
expect(getSFUConfig).not.toHaveBeenCalled();
|
||||||
|
|
||||||
expect(customLivekitUrlSetting.getValue()).toBe(null);
|
expect(customTransportSetting.getValue()).toBe(null);
|
||||||
});
|
});
|
||||||
it("will update custom livekit url", async () => {
|
it("will update custom transport", async () => {
|
||||||
const user = userEvent.setup();
|
const user = userEvent.setup();
|
||||||
|
|
||||||
render(
|
render(
|
||||||
@@ -221,27 +236,28 @@ describe("DeveloperSettingsTab", () => {
|
|||||||
</TooltipProvider>,
|
</TooltipProvider>,
|
||||||
);
|
);
|
||||||
|
|
||||||
const input = screen.getByLabelText("Custom Livekit-url");
|
const input = screen.getByLabelText("Custom transport JSON");
|
||||||
await user.clear(input);
|
await user.clear(input);
|
||||||
await user.type(input, "wss://example.livekit.valid");
|
await typeJson(user, input, {
|
||||||
|
type: "livekit",
|
||||||
|
url: "wss://example.livekit.valid",
|
||||||
|
});
|
||||||
|
|
||||||
const saveButton = screen.getByRole("button", { name: "Save" });
|
const saveButton = screen.getByRole("button", { name: "Save" });
|
||||||
await user.click(saveButton);
|
await user.click(saveButton);
|
||||||
expect(getSFUConfig).toHaveBeenCalledWith(
|
expect(getSFUConfig).toHaveBeenCalledWith(
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
transport: {
|
transport: { type: "livekit", url: "wss://example.livekit.valid" },
|
||||||
type: "livekit",
|
|
||||||
livekit_service_url: "wss://example.livekit.valid",
|
|
||||||
},
|
|
||||||
roomId: "#testRoom",
|
roomId: "#testRoom",
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(customLivekitUrlSetting.getValue()).toBe(
|
expect(customTransportSetting.getValue()).toEqual({
|
||||||
"wss://example.livekit.valid",
|
type: "livekit",
|
||||||
);
|
url: "wss://example.livekit.valid",
|
||||||
|
});
|
||||||
});
|
});
|
||||||
it("will show error on invalid url", async () => {
|
it("will show error on unreachable transport", async () => {
|
||||||
const user = userEvent.setup();
|
const user = userEvent.setup();
|
||||||
|
|
||||||
render(
|
render(
|
||||||
@@ -255,24 +271,27 @@ describe("DeveloperSettingsTab", () => {
|
|||||||
</TooltipProvider>,
|
</TooltipProvider>,
|
||||||
);
|
);
|
||||||
|
|
||||||
const input = screen.getByLabelText("Custom Livekit-url");
|
const input = screen.getByLabelText("Custom transport JSON");
|
||||||
await user.clear(input);
|
await user.clear(input);
|
||||||
await user.type(input, "wss://example.livekit.valid");
|
await typeJson(user, input, {
|
||||||
|
type: "livekit",
|
||||||
|
url: "wss://example.livekit.valid",
|
||||||
|
});
|
||||||
|
|
||||||
const saveButton = screen.getByRole("button", { name: "Save" });
|
const saveButton = screen.getByRole("button", { name: "Save" });
|
||||||
(getSFUConfig as Mock).mockImplementation(() => {
|
(getSFUConfig as Mock).mockImplementation(() => {
|
||||||
throw new Error("Invalid URL");
|
throw new Error("Failed to get SFU config");
|
||||||
});
|
});
|
||||||
await user.click(saveButton);
|
await user.click(saveButton);
|
||||||
expect(
|
expect(
|
||||||
screen.getByText("invalid URL (did not update)"),
|
screen.getByText("invalid transport (did not update)"),
|
||||||
).toBeInTheDocument();
|
).toBeInTheDocument();
|
||||||
expect(customLivekitUrlSetting.getValue()).toBe(null);
|
expect(customTransportSetting.getValue()).toBe(null);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Add this test inside the describe("DeveloperSettingsTab", () => { block,
|
// Add this test inside the describe("DeveloperSettingsTab", () => { block,
|
||||||
// after the custom livekit url tests:
|
// after the custom transport tests:
|
||||||
|
|
||||||
describe("enable extended livekit logs", () => {
|
describe("enable extended livekit logs", () => {
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ import {
|
|||||||
muteAllAudio as muteAllAudioSetting,
|
muteAllAudio as muteAllAudioSetting,
|
||||||
alwaysShowIphoneEarpiece as alwaysShowIphoneEarpieceSetting,
|
alwaysShowIphoneEarpiece as alwaysShowIphoneEarpieceSetting,
|
||||||
matrixRTCMode as matrixRTCModeSetting,
|
matrixRTCMode as matrixRTCModeSetting,
|
||||||
customLivekitUrl as customLivekitUrlSetting,
|
customTransport as customTransportSetting,
|
||||||
advancedScreenShare as advancedScreenShareSetting,
|
advancedScreenShare as advancedScreenShareSetting,
|
||||||
screenShareResolution as screenShareResolutionSetting,
|
screenShareResolution as screenShareResolutionSetting,
|
||||||
screenShareFramerate as screenShareFramerateSetting,
|
screenShareFramerate as screenShareFramerateSetting,
|
||||||
@@ -167,16 +167,18 @@ export const DeveloperSettingsTab: FC<Props> = ({
|
|||||||
enableExtendedLivekitLogsSetting,
|
enableExtendedLivekitLogsSetting,
|
||||||
);
|
);
|
||||||
|
|
||||||
const [customLivekitUrlUpdateError, setCustomLivekitUrlUpdateError] =
|
const [customTransportUpdateError, setCustomLivekitUrlUpdateError] = useState<
|
||||||
useState<string | null>(null);
|
string | null
|
||||||
const [customLivekitUrl, setCustomLivekitUrl] = useSetting(
|
>(null);
|
||||||
customLivekitUrlSetting,
|
const [customTransport, setCustomTransport] = useSetting(
|
||||||
|
customTransportSetting,
|
||||||
|
);
|
||||||
|
const [customTransportTextBuffer, setCustomLivekitUrlTextBuffer] = useState(
|
||||||
|
() => JSON.stringify(customTransport),
|
||||||
);
|
);
|
||||||
const [customLivekitUrlTextBuffer, setCustomLivekitUrlTextBuffer] =
|
|
||||||
useState(customLivekitUrl);
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setCustomLivekitUrlTextBuffer(customLivekitUrl);
|
setCustomLivekitUrlTextBuffer(JSON.stringify(customTransport));
|
||||||
}, [customLivekitUrl]);
|
}, [customTransport]);
|
||||||
|
|
||||||
const [muteAllAudio, setMuteAllAudio] = useSetting(muteAllAudioSetting);
|
const [muteAllAudio, setMuteAllAudio] = useSetting(muteAllAudioSetting);
|
||||||
|
|
||||||
@@ -491,23 +493,23 @@ export const DeveloperSettingsTab: FC<Props> = ({
|
|||||||
<EditInPlace
|
<EditInPlace
|
||||||
onSubmit={(e) => e.preventDefault()}
|
onSubmit={(e) => e.preventDefault()}
|
||||||
helpLabel={
|
helpLabel={
|
||||||
customLivekitUrl === null
|
customTransport === null
|
||||||
? t("developer_mode.custom_livekit_url.from_config")
|
? t("developer_mode.custom_transport.from_config")
|
||||||
: t("developer_mode.custom_livekit_url.current_url") +
|
: t("developer_mode.custom_transport.current") +
|
||||||
customLivekitUrl
|
JSON.stringify(customTransport)
|
||||||
}
|
}
|
||||||
label={t("developer_mode.custom_livekit_url.label")}
|
label={t("developer_mode.custom_transport.label")}
|
||||||
saveButtonLabel={t("developer_mode.custom_livekit_url.save")}
|
saveButtonLabel={t("developer_mode.custom_transport.save")}
|
||||||
savingLabel={t("developer_mode.custom_livekit_url.saving")}
|
savingLabel={t("developer_mode.custom_transport.saving")}
|
||||||
cancelButtonLabel={t("developer_mode.custom_livekit_url.reset")}
|
cancelButtonLabel={t("developer_mode.custom_transport.reset")}
|
||||||
onSave={useCallback(
|
onSave={useCallback(
|
||||||
async (e: React.FormEvent<HTMLFormElement>): Promise<void> => {
|
async (e: React.FormEvent<HTMLFormElement>): Promise<void> => {
|
||||||
if (
|
if (
|
||||||
roomId === undefined ||
|
roomId === undefined ||
|
||||||
customLivekitUrlTextBuffer === "" ||
|
customTransportTextBuffer === "" ||
|
||||||
customLivekitUrlTextBuffer === null
|
customTransportTextBuffer === null
|
||||||
) {
|
) {
|
||||||
setCustomLivekitUrl(null);
|
setCustomTransport(null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -518,13 +520,12 @@ export const DeveloperSettingsTab: FC<Props> = ({
|
|||||||
if (userId === null || deviceId === null) {
|
if (userId === null || deviceId === null) {
|
||||||
throw new Error("Invalid user or device ID");
|
throw new Error("Invalid user or device ID");
|
||||||
}
|
}
|
||||||
|
const transport = JSON.parse(customTransportTextBuffer);
|
||||||
|
// Validate the transport by attempting to get a token for it
|
||||||
await getSFUConfig({
|
await getSFUConfig({
|
||||||
client,
|
client,
|
||||||
membership: { userId, deviceId, memberId: "" },
|
membership: { userId, deviceId, memberId: "" },
|
||||||
transport: {
|
transport,
|
||||||
type: "livekit",
|
|
||||||
livekit_service_url: customLivekitUrlTextBuffer,
|
|
||||||
},
|
|
||||||
serverName: client.getDomain()!,
|
serverName: client.getDomain()!,
|
||||||
roomId,
|
roomId,
|
||||||
slotId: "org.example.fake-slot#room",
|
slotId: "org.example.fake-slot#room",
|
||||||
@@ -532,14 +533,16 @@ export const DeveloperSettingsTab: FC<Props> = ({
|
|||||||
logger,
|
logger,
|
||||||
});
|
});
|
||||||
setCustomLivekitUrlUpdateError(null);
|
setCustomLivekitUrlUpdateError(null);
|
||||||
setCustomLivekitUrl(customLivekitUrlTextBuffer);
|
setCustomTransport(transport);
|
||||||
} catch {
|
} catch {
|
||||||
setCustomLivekitUrlUpdateError("invalid URL (did not update)");
|
setCustomLivekitUrlUpdateError(
|
||||||
|
"invalid transport (did not update)",
|
||||||
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[customLivekitUrlTextBuffer, setCustomLivekitUrl, client, roomId],
|
[customTransportTextBuffer, setCustomTransport, client, roomId],
|
||||||
)}
|
)}
|
||||||
value={customLivekitUrlTextBuffer ?? ""}
|
value={customTransportTextBuffer ?? ""}
|
||||||
onChange={useCallback(
|
onChange={useCallback(
|
||||||
(event: ChangeEvent<HTMLInputElement>): void => {
|
(event: ChangeEvent<HTMLInputElement>): void => {
|
||||||
setCustomLivekitUrlTextBuffer(event.target.value);
|
setCustomLivekitUrlTextBuffer(event.target.value);
|
||||||
@@ -548,14 +551,14 @@ export const DeveloperSettingsTab: FC<Props> = ({
|
|||||||
)}
|
)}
|
||||||
onCancel={useCallback(
|
onCancel={useCallback(
|
||||||
(e: React.FormEvent<HTMLFormElement>) => {
|
(e: React.FormEvent<HTMLFormElement>) => {
|
||||||
setCustomLivekitUrl(null);
|
setCustomTransport(null);
|
||||||
},
|
},
|
||||||
[setCustomLivekitUrl],
|
[setCustomTransport],
|
||||||
)}
|
)}
|
||||||
serverInvalid={customLivekitUrlUpdateError !== null}
|
serverInvalid={customTransportUpdateError !== null}
|
||||||
>
|
>
|
||||||
{customLivekitUrlUpdateError !== null && (
|
{customTransportUpdateError !== null && (
|
||||||
<ErrorMessage>{customLivekitUrlUpdateError}</ErrorMessage>
|
<ErrorMessage>{customTransportUpdateError}</ErrorMessage>
|
||||||
)}
|
)}
|
||||||
</EditInPlace>
|
</EditInPlace>
|
||||||
<Separator />
|
<Separator />
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ interface Props {
|
|||||||
livekitRooms?: {
|
livekitRooms?: {
|
||||||
room: LivekitRoom;
|
room: LivekitRoom;
|
||||||
url: string;
|
url: string;
|
||||||
isLocal?: boolean;
|
role: "publisher" | "subscriber";
|
||||||
}[];
|
}[];
|
||||||
/** Only available while in a call. Used by the developer tab. */
|
/** Only available while in a call. Used by the developer tab. */
|
||||||
developerSettingsVm?: ViewModel<DeveloperSettingsSnapshot>;
|
developerSettingsVm?: ViewModel<DeveloperSettingsSnapshot>;
|
||||||
|
|||||||
@@ -239,7 +239,7 @@ exports[`DeveloperSettingsTab > renders and matches snapshot 1`] = `
|
|||||||
class="_label_1o4d9_60"
|
class="_label_1o4d9_60"
|
||||||
for="radix-_r_7_"
|
for="radix-_r_7_"
|
||||||
>
|
>
|
||||||
Custom Livekit-url
|
Custom transport JSON
|
||||||
</label>
|
</label>
|
||||||
<div
|
<div
|
||||||
class="_controls_17lij_8"
|
class="_controls_17lij_8"
|
||||||
@@ -250,7 +250,7 @@ exports[`DeveloperSettingsTab > renders and matches snapshot 1`] = `
|
|||||||
id="radix-_r_7_"
|
id="radix-_r_7_"
|
||||||
name="input"
|
name="input"
|
||||||
title=""
|
title=""
|
||||||
value=""
|
value="null"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<span
|
<span
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import { PosthogAnalytics } from "../analytics/PosthogAnalytics";
|
|||||||
import { type Behavior } from "../state/Behavior";
|
import { type Behavior } from "../state/Behavior";
|
||||||
import { useBehavior } from "../useBehavior";
|
import { useBehavior } from "../useBehavior";
|
||||||
import { MatrixRTCMode } from "../config/ConfigOptions";
|
import { MatrixRTCMode } from "../config/ConfigOptions";
|
||||||
|
import { type UnstableLivekitTransport } from "matrix-js-sdk/lib/matrixrtc";
|
||||||
|
|
||||||
export class Setting<T> {
|
export class Setting<T> {
|
||||||
public constructor(
|
public constructor(
|
||||||
@@ -153,8 +154,8 @@ export const matrixRTCMode = new Setting<MatrixRTCMode>(
|
|||||||
MatrixRTCMode.Compatibility,
|
MatrixRTCMode.Compatibility,
|
||||||
);
|
);
|
||||||
|
|
||||||
export const customLivekitUrl = new Setting<string | null>(
|
export const customTransport = new Setting<UnstableLivekitTransport | null>(
|
||||||
"custom-livekit-url",
|
"custom-transport",
|
||||||
null,
|
null,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ import fetchMock from "fetch-mock";
|
|||||||
import { mockConfig } from "../../../utils/test";
|
import { mockConfig } from "../../../utils/test";
|
||||||
import { getLocalTransport } from "./LocalTransport";
|
import { getLocalTransport } from "./LocalTransport";
|
||||||
import { MatrixRTCTransportMissingError } from "../../../utils/errors";
|
import { MatrixRTCTransportMissingError } from "../../../utils/errors";
|
||||||
import { customLivekitUrl } from "../../../settings/settings";
|
import { customTransport } from "../../../settings/settings";
|
||||||
import { type MatrixClient } from "matrix-js-sdk";
|
import { type MatrixClient } from "matrix-js-sdk";
|
||||||
|
|
||||||
describe("LocalTransport", () => {
|
describe("LocalTransport", () => {
|
||||||
@@ -60,7 +60,7 @@ describe("LocalTransport", () => {
|
|||||||
>;
|
>;
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
mockConfig({});
|
mockConfig({});
|
||||||
customLivekitUrl.setValue(customLivekitUrl.defaultValue);
|
customTransport.setValue(customTransport.defaultValue);
|
||||||
client = {
|
client = {
|
||||||
getDomain: vi.fn().mockReturnValue("example.org"),
|
getDomain: vi.fn().mockReturnValue("example.org"),
|
||||||
_unstable_getRTCTransports: vi.fn().mockResolvedValue([]),
|
_unstable_getRTCTransports: vi.fn().mockResolvedValue([]),
|
||||||
@@ -86,7 +86,10 @@ describe("LocalTransport", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("supports getting transport via user settings", async () => {
|
it("supports getting transport via user settings", async () => {
|
||||||
customLivekitUrl.setValue("https://lk.example.org");
|
customTransport.setValue({
|
||||||
|
type: "livekit",
|
||||||
|
livekit_service_url: "https://lk.example.org",
|
||||||
|
});
|
||||||
|
|
||||||
expect(await getLocalTransport(client)).toStrictEqual({
|
expect(await getLocalTransport(client)).toStrictEqual({
|
||||||
transport: {
|
transport: {
|
||||||
|
|||||||
@@ -5,13 +5,12 @@ SPDX-License-IdFentifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
|
|||||||
Please see LICENSE in the repository root for full details.
|
Please see LICENSE in the repository root for full details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { type UnstableLivekitTransport } from "matrix-js-sdk/lib/matrixrtc";
|
|
||||||
import { type MatrixClient } from "matrix-js-sdk";
|
import { type MatrixClient } from "matrix-js-sdk";
|
||||||
import { logger as rootLogger } from "matrix-js-sdk/lib/logger";
|
import { logger as rootLogger } from "matrix-js-sdk/lib/logger";
|
||||||
|
|
||||||
import { Config } from "../../../config/Config.ts";
|
import { Config } from "../../../config/Config.ts";
|
||||||
import { MatrixRTCTransportMissingError } from "../../../utils/errors.ts";
|
import { MatrixRTCTransportMissingError } from "../../../utils/errors.ts";
|
||||||
import { customLivekitUrl } from "../../../settings/settings.ts";
|
import { customTransport as customTransportSetting } from "../../../settings/settings.ts";
|
||||||
import { RtcTransportAutoDiscovery } from "./RtcTransportAutoDiscovery.ts";
|
import { RtcTransportAutoDiscovery } from "./RtcTransportAutoDiscovery.ts";
|
||||||
import { type TransportLocator } from "../../../livekit/auth/types.ts";
|
import { type TransportLocator } from "../../../livekit/auth/types.ts";
|
||||||
|
|
||||||
@@ -30,12 +29,11 @@ export async function getLocalTransport(
|
|||||||
resolvedConfig: Config.get(),
|
resolvedConfig: Config.get(),
|
||||||
logger: rootLogger.getChild("[LocalTransport]"),
|
logger: rootLogger.getChild("[LocalTransport]"),
|
||||||
});
|
});
|
||||||
const customUrl = customLivekitUrl.value$.value;
|
|
||||||
|
|
||||||
// Respect the user's custom URL, if set
|
// Respect the user's custom transport, if set
|
||||||
const transport: UnstableLivekitTransport | null = customUrl
|
const transport =
|
||||||
? { type: "livekit", livekit_service_url: customUrl }
|
customTransportSetting.value$.value ??
|
||||||
: await discovery.discoverPreferredTransport();
|
(await discovery.discoverPreferredTransport());
|
||||||
|
|
||||||
if (transport === null) throw new MatrixRTCTransportMissingError(serverName);
|
if (transport === null) throw new MatrixRTCTransportMissingError(serverName);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user