mirror of
https://github.com/vector-im/element-call.git
synced 2026-09-10 21:55:19 +00:00
ci
This commit is contained in:
+2
-4
@@ -141,8 +141,7 @@ export function useComponentHostBridge(
|
|||||||
requests.themeChange$.next({ data: { name: theme }, reply: () => {} });
|
requests.themeChange$.next({ data: { name: theme }, reply: () => {} });
|
||||||
}, [requests, theme]);
|
}, [requests, theme]);
|
||||||
|
|
||||||
const bridge = useInitial(
|
const bridge = useInitial((): HostBridge => ({
|
||||||
(): HostBridge => ({
|
|
||||||
setAlwaysOnScreen: async (alwaysOnScreen) => {
|
setAlwaysOnScreen: async (alwaysOnScreen) => {
|
||||||
await latest.current.setAlwaysOnScreen?.(alwaysOnScreen);
|
await latest.current.setAlwaysOnScreen?.(alwaysOnScreen);
|
||||||
},
|
},
|
||||||
@@ -180,8 +179,7 @@ export function useComponentHostBridge(
|
|||||||
// offers to edit the profile from inside a component.
|
// offers to edit the profile from inside a component.
|
||||||
supportsProfileChanges: false,
|
supportsProfileChanges: false,
|
||||||
...requests,
|
...requests,
|
||||||
}),
|
}));
|
||||||
);
|
|
||||||
|
|
||||||
useImperativeHandle(
|
useImperativeHandle(
|
||||||
ref,
|
ref,
|
||||||
|
|||||||
+18
-3
@@ -40,6 +40,7 @@ import {
|
|||||||
useEffect,
|
useEffect,
|
||||||
useLayoutEffect,
|
useLayoutEffect,
|
||||||
useMemo,
|
useMemo,
|
||||||
|
useRef,
|
||||||
useState,
|
useState,
|
||||||
} from "react";
|
} from "react";
|
||||||
import { type MatrixClient } from "matrix-js-sdk";
|
import { type MatrixClient } from "matrix-js-sdk";
|
||||||
@@ -298,14 +299,28 @@ export const ElementCall: FC<ElementCallProps> = ({
|
|||||||
`Element Call was asked to call in ${roomId}, which its host's client does not know about`,
|
`Element Call was asked to call in ${roomId}, which its host's client does not know about`,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Everything the call needs is in hand once these exist, and the first
|
||||||
|
// render with them is where the call itself appears: the moment the host
|
||||||
|
// is told that Element Call has loaded, as the widget tells its client once
|
||||||
|
// its own initialisation is over. Once per mount, however often the pieces
|
||||||
|
// are later swapped out.
|
||||||
|
const ready =
|
||||||
|
container !== null && rtcSession !== null && mediaDevices !== null;
|
||||||
|
const announcedLoaded = useRef(false);
|
||||||
|
useEffect(() => {
|
||||||
|
if (!ready || announcedLoaded.current) return;
|
||||||
|
announcedLoaded.current = true;
|
||||||
|
hostBridge
|
||||||
|
.contentLoaded()
|
||||||
|
.catch((e) => logger.error("Could not tell the host we had loaded", e));
|
||||||
|
}, [ready, hostBridge]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<I18nextProvider i18n={i18n}>
|
<I18nextProvider i18n={i18n}>
|
||||||
<HostBridgeProvider value={hostBridge}>
|
<HostBridgeProvider value={hostBridge}>
|
||||||
<UrlParamsProvider value={params}>
|
<UrlParamsProvider value={params}>
|
||||||
<div ref={setContainer} className={styles.root}>
|
<div ref={setContainer} className={styles.root}>
|
||||||
{container !== null &&
|
{ready && (
|
||||||
rtcSession !== null &&
|
|
||||||
mediaDevices !== null && (
|
|
||||||
<RootElementProvider value={container}>
|
<RootElementProvider value={container}>
|
||||||
{/* Whatever goes wrong in here is shown in here. Left to
|
{/* Whatever goes wrong in here is shown in here. Left to
|
||||||
propagate, an error would unmount the host's own tree. */}
|
propagate, an error would unmount the host's own tree. */}
|
||||||
|
|||||||
@@ -86,6 +86,11 @@ export default defineConfig({
|
|||||||
// enumerateDevices work on CI runners without real hardware.
|
// enumerateDevices work on CI runners without real hardware.
|
||||||
"media.navigator.streams.fake": true,
|
"media.navigator.streams.fake": true,
|
||||||
"media.navigator.permission.disabled": true,
|
"media.navigator.permission.disabled": true,
|
||||||
|
// Vite serves HTTPS over HTTP/2, and Firefox intermittently stalls
|
||||||
|
// on Node's HTTP/2 server with a page that never finishes loading
|
||||||
|
// (one run in five or so, locally). Every server in the suite
|
||||||
|
// still speaks HTTP/1.1, so nothing is lost by insisting on it.
|
||||||
|
"network.http.http2.enabled": false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -25,6 +25,11 @@ import { SpaHelpers } from "../spa-helpers.ts";
|
|||||||
* guaranteed both.
|
* guaranteed both.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// Each test signs in twice, sets up crypto twice and syncs twice before
|
||||||
|
// anything is on screen, and then waits for media to connect; the waits below
|
||||||
|
// are sized for that, so the tests have to be too
|
||||||
|
test.describe.configure({ timeout: 180_000 });
|
||||||
|
|
||||||
/** The settings button, whichever of the two the footer is currently showing. */
|
/** The settings button, whichever of the two the footer is currently showing. */
|
||||||
function settingsButton(pane: Locator): Locator {
|
function settingsButton(pane: Locator): Locator {
|
||||||
return pane
|
return pane
|
||||||
@@ -206,16 +211,18 @@ test("looks the same in a small container as in a small window", async ({
|
|||||||
browser,
|
browser,
|
||||||
}) => {
|
}) => {
|
||||||
// Two calls to set up, one of them through the harness's two logins
|
// Two calls to set up, one of them through the harness's two logins
|
||||||
test.setTimeout(240_000);
|
test.setTimeout(300_000);
|
||||||
const size = { width: 300, height: 300 };
|
const size = { width: 300, height: 300 };
|
||||||
|
|
||||||
// The reference is Element Call owning a window of that size, which is what
|
// The reference is Element Call owning a window of that size, which is what
|
||||||
// a mobile app's webview or a browser's picture-in-picture gives it, and
|
// a mobile app's webview or a browser's picture-in-picture gives it, and
|
||||||
// what its small-window styling was written for.
|
// what its small-window styling was written for.
|
||||||
|
// No permissions to grant: each browser is launched with fake media that is
|
||||||
|
// handed out without asking (see playwright.config.ts), and Firefox rejects
|
||||||
|
// a request for `camera` or `microphone` outright
|
||||||
const referenceContext = await browser.newContext({
|
const referenceContext = await browser.newContext({
|
||||||
viewport: size,
|
viewport: size,
|
||||||
ignoreHTTPSErrors: true,
|
ignoreHTTPSErrors: true,
|
||||||
permissions: ["microphone", "camera"],
|
|
||||||
});
|
});
|
||||||
const referencePage = await referenceContext.newPage();
|
const referencePage = await referenceContext.newPage();
|
||||||
await referencePage.goto("/");
|
await referencePage.goto("/");
|
||||||
|
|||||||
Reference in New Issue
Block a user