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. Folds "Avoid null in transport dev setting" from the same PR. The setting feeds the SDK's transport option; the config fallback becomes a transport the host builds. Co-authored-by: Johannes Marbach <n0-0ne+github@mailbox.org>
This commit is contained in:
committed by
Timo
co-authored by
Johannes Marbach
parent
f97dd2adab
commit
289260531b
@@ -83,7 +83,7 @@ import {
|
||||
cameraCodec,
|
||||
cameraFramerate,
|
||||
cameraResolution,
|
||||
customLivekitUrl,
|
||||
customTransport,
|
||||
echoCancellationSetting,
|
||||
matrixRTCMode as matrixRTCModeSetting,
|
||||
noiseSuppressionSetting,
|
||||
@@ -823,7 +823,10 @@ export function rtcParticipationOptions(
|
||||
delegatedDelayedLeave: session.delegated_delayed_leave,
|
||||
},
|
||||
mediaQuality: config.media_quality,
|
||||
transportUrl: customLivekitUrl.value$.value ?? undefined,
|
||||
fallbackTransportUrl: config.livekit?.livekit_service_url,
|
||||
transport: customTransport.value$.value ?? undefined,
|
||||
fallbackTransport: config.livekit && {
|
||||
type: "livekit",
|
||||
livekit_service_url: config.livekit.livekit_service_url,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ import {
|
||||
MatrixRTCMode,
|
||||
} from "@element-hq/matrixrtc-sdk";
|
||||
import type * as MatrixRTCSdk from "@element-hq/matrixrtc-sdk";
|
||||
import { mockConfig } from "../utils/test";
|
||||
import { exampleTransport, mockConfig } from "../utils/test";
|
||||
|
||||
// Mock url params hook to avoid environment-dependent snapshot churn.
|
||||
vi.mock("../UrlParams", () => ({
|
||||
@@ -232,10 +232,12 @@ describe("DeveloperSettingsTab", () => {
|
||||
const saveButton = screen.getByRole("button", { name: "Save" });
|
||||
await user.click(saveButton);
|
||||
expect(authenticateWithTransport).toHaveBeenCalledWith(
|
||||
expect.anything(),
|
||||
expect.anything(),
|
||||
"wss://example.livekit.valid",
|
||||
"#testRoom",
|
||||
expect.objectContaining({
|
||||
transport: { type: "livekit", url: "wss://example.livekit.valid" },
|
||||
serverName: "hs",
|
||||
roomId: "#testRoom",
|
||||
role: "publisher",
|
||||
}),
|
||||
);
|
||||
|
||||
expect(customTransportSetting.getValue()).toEqual({
|
||||
@@ -266,7 +268,7 @@ describe("DeveloperSettingsTab", () => {
|
||||
|
||||
const saveButton = screen.getByRole("button", { name: "Save" });
|
||||
(authenticateWithTransport as Mock).mockImplementation(() => {
|
||||
throw new Error("Invalid URL");
|
||||
throw new Error("Failed to get SFU config");
|
||||
});
|
||||
await user.click(saveButton);
|
||||
expect(
|
||||
@@ -276,9 +278,6 @@ describe("DeveloperSettingsTab", () => {
|
||||
});
|
||||
});
|
||||
|
||||
// Add this test inside the describe("DeveloperSettingsTab", () => { block,
|
||||
// after the custom transport tests:
|
||||
|
||||
describe("enable extended livekit logs", () => {
|
||||
afterEach(() => {
|
||||
enableExtendedLivekitLogsSetting.setValue(false);
|
||||
|
||||
@@ -20,6 +20,7 @@ import {
|
||||
type MatrixClient,
|
||||
} from "matrix-js-sdk";
|
||||
import { logger } from "matrix-js-sdk/lib/logger";
|
||||
import { type UnstableLivekitTransport } from "matrix-js-sdk/lib/matrixrtc";
|
||||
import {
|
||||
EditInPlace,
|
||||
ErrorMessage,
|
||||
@@ -173,17 +174,17 @@ export const DeveloperSettingsTab: FC<Props> = ({
|
||||
enableExtendedLivekitLogsSetting,
|
||||
);
|
||||
|
||||
const [customTransportUpdateError, setCustomLivekitUrlUpdateError] = useState<
|
||||
const [customTransportUpdateError, setCustomTransportUpdateError] = useState<
|
||||
string | null
|
||||
>(null);
|
||||
const [customTransport, setCustomTransport] = useSetting(
|
||||
customTransportSetting,
|
||||
);
|
||||
const [customTransportTextBuffer, setCustomLivekitUrlTextBuffer] = useState(
|
||||
const [customTransportTextBuffer, setCustomTransportTextBuffer] = useState(
|
||||
() => transportText(customTransport),
|
||||
);
|
||||
useEffect(() => {
|
||||
setCustomLivekitUrlTextBuffer(transportText(customTransport));
|
||||
setCustomTransportTextBuffer(transportText(customTransport));
|
||||
}, [customTransport]);
|
||||
|
||||
const [muteAllAudio, setMuteAllAudio] = useSetting(muteAllAudioSetting);
|
||||
@@ -499,11 +500,7 @@ export const DeveloperSettingsTab: FC<Props> = ({
|
||||
cancelButtonLabel={t("developer_mode.custom_transport.reset")}
|
||||
onSave={useCallback(
|
||||
async (e: React.FormEvent<HTMLFormElement>): Promise<void> => {
|
||||
if (
|
||||
roomId === undefined ||
|
||||
customTransportTextBuffer === "" ||
|
||||
customTransportTextBuffer === null
|
||||
) {
|
||||
if (roomId === undefined || customTransportTextBuffer === "") {
|
||||
setCustomTransport(null);
|
||||
return;
|
||||
}
|
||||
@@ -511,36 +508,39 @@ export const DeveloperSettingsTab: FC<Props> = ({
|
||||
try {
|
||||
const userId = client.getUserId();
|
||||
const deviceId = client.getDeviceId();
|
||||
const serverName = client.getDomain();
|
||||
|
||||
if (userId === null || deviceId === null) {
|
||||
throw new Error("Invalid user or device ID");
|
||||
if (userId === null || deviceId === null || serverName === null) {
|
||||
throw new Error("Invalid user, device ID or server name");
|
||||
}
|
||||
await authenticateWithTransport(
|
||||
const transport = JSON.parse(customTransportTextBuffer);
|
||||
// Validate the transport by attempting to get a token for it
|
||||
await authenticateWithTransport({
|
||||
client,
|
||||
membership: { userId, deviceId, memberId: "" },
|
||||
transport,
|
||||
serverName: client.getDomain()!,
|
||||
serverName,
|
||||
roomId,
|
||||
slotId: "org.example.fake-slot#room",
|
||||
role: "publisher",
|
||||
logger,
|
||||
});
|
||||
setCustomLivekitUrlUpdateError(null);
|
||||
setCustomTransportUpdateError(null);
|
||||
setCustomTransport(transport);
|
||||
} catch {
|
||||
setCustomLivekitUrlUpdateError(
|
||||
setCustomTransportUpdateError(
|
||||
"invalid transport (did not update)",
|
||||
);
|
||||
}
|
||||
},
|
||||
[customTransportTextBuffer, setCustomTransport, client, roomId],
|
||||
)}
|
||||
value={customTransportTextBuffer ?? ""}
|
||||
value={customTransportTextBuffer}
|
||||
onChange={useCallback(
|
||||
(event: ChangeEvent<HTMLInputElement>): void => {
|
||||
setCustomLivekitUrlTextBuffer(event.target.value);
|
||||
setCustomTransportTextBuffer(event.target.value);
|
||||
},
|
||||
[setCustomLivekitUrlTextBuffer],
|
||||
[setCustomTransportTextBuffer],
|
||||
)}
|
||||
onCancel={useCallback(
|
||||
(e: React.FormEvent<HTMLFormElement>) => {
|
||||
@@ -659,6 +659,11 @@ export const DeveloperSettingsTab: FC<Props> = ({
|
||||
);
|
||||
};
|
||||
|
||||
/** The text shown in the custom transport field for a given setting value. */
|
||||
function transportText(transport: UnstableLivekitTransport | null): string {
|
||||
return transport === null ? "" : JSON.stringify(transport);
|
||||
}
|
||||
|
||||
const TransportBox: FC<TransportInfo> = ({ transport, local }) => {
|
||||
const { t } = useTranslation();
|
||||
const resolved = useBehavior(transport.resolved$);
|
||||
|
||||
Reference in New Issue
Block a user