mirror of
https://github.com/vector-im/element-call.git
synced 2026-09-10 21:55:19 +00:00
Element Call reached the widget API through a mutable module-level binding, which every consumer imported directly. Nothing outside the app shell needs it any more, so hand it back from initializeWidget and thread it through: the initializer returns it, main passes it to App, and App uses it to build the host bridge and to await the client the host is lending us. ClientContext's loadClient is now only about restoring or creating a session of Element Call's own, since a widget's client arrives as a prop like any other host's would. Also fixes an early return added in the previous commit, which skipped starting the analytics settings listener when a client was supplied. That was harmless until now, but would have stopped analytics following the user's choices in widget mode. sdk/main.ts asked the host to close by hand; it now uses the bridge, which also stops the transport as the app does.
72 lines
2.1 KiB
TypeScript
72 lines
2.1 KiB
TypeScript
/*
|
|
Copyright 2021-2024 New Vector Ltd.
|
|
|
|
SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
|
|
Please see LICENSE in the repository root for full details.
|
|
*/
|
|
|
|
// We need to import this somewhere, once, so that the correct 'request'
|
|
// function gets set. It needs to be not in the same file as we use
|
|
// createClient, or the typescript transpiler gets confused about
|
|
// dependency references.
|
|
import "matrix-js-sdk/lib/browser-index";
|
|
|
|
import { StrictMode } from "react";
|
|
import { createRoot } from "react-dom/client";
|
|
import "./index.css";
|
|
import { logger } from "matrix-js-sdk/lib/logger";
|
|
|
|
import { App } from "./App";
|
|
import { init as initRageshake } from "./settings/rageshake";
|
|
import { Initializer } from "./initializer";
|
|
import { AppViewModel } from "./state/AppViewModel";
|
|
import { globalScope } from "./state/ObservableScope";
|
|
import { getUrlParams } from "./UrlParams";
|
|
|
|
initRageshake().catch((e) => {
|
|
logger.error("Failed to initialize rageshake", e);
|
|
});
|
|
|
|
logger.info(`Element Call ${import.meta.env.VITE_APP_VERSION || "dev"}`);
|
|
|
|
const root = createRoot(document.getElementById("root")!);
|
|
|
|
let fatalError: Error | null = null;
|
|
|
|
if (!window.isSecureContext) {
|
|
fatalError = new Error(
|
|
"This app cannot run in an insecure context. To fix this, access the app " +
|
|
"via a local loopback address, or serve it over HTTPS.\n" +
|
|
"https://developer.mozilla.org/en-US/docs/Web/Security/Secure_Contexts",
|
|
);
|
|
} else if (!navigator.mediaDevices) {
|
|
fatalError = new Error("Your browser does not support WebRTC.");
|
|
}
|
|
|
|
if (fatalError !== null) {
|
|
root.render(fatalError.message);
|
|
throw fatalError; // Stop the app early
|
|
}
|
|
|
|
Initializer.initBeforeReact()
|
|
.then((widget) => {
|
|
const { controlledAudioDevices, callIntent } = getUrlParams();
|
|
root.render(
|
|
<StrictMode>
|
|
<App
|
|
vm={
|
|
new AppViewModel(globalScope, {
|
|
controlledAudioDevices,
|
|
callIntent,
|
|
})
|
|
}
|
|
widget={widget}
|
|
/>
|
|
</StrictMode>,
|
|
);
|
|
})
|
|
.catch((e) => {
|
|
logger.error(`Failed to initialize app ${e.message}`, e);
|
|
root.render(e.message);
|
|
});
|