diff --git a/src/modules/BuiltinsApi.ts b/src/modules/BuiltinsApi.ts index 20bd6343e6..64c2dc4728 100644 --- a/src/modules/BuiltinsApi.ts +++ b/src/modules/BuiltinsApi.ts @@ -7,10 +7,27 @@ Please see LICENSE files in the repository root for full details. import { type RoomViewProps, type BuiltinsApi } from "@element-hq/element-web-module-api"; -import { RoomView } from "../components/structures/RoomView"; - export class ElementWebBuiltinsApi implements BuiltinsApi { + private _roomView?: React.ComponentType; + + /** + * Sets the components used to render a RoomView + * + * This only really exists here because referencing RoomView directly causes a nightmare of + * circular dependencies that break the whole app, so instead we avoid referencing it here + * and pass it in from somewhere it's already referenced (see related comment in app.tsx). + * + * @param component The RoomView component + */ + public setRoomViewComponent(component: React.ComponentType): void { + this._roomView = component; + } + public getRoomViewComponent(): React.ComponentType { - return RoomView; + if (!this._roomView) { + throw new Error("No RoomView component has been set"); + } + + return this._roomView; } } diff --git a/src/vector/app.tsx b/src/vector/app.tsx index 0d440ff963..21b21e9252 100644 --- a/src/vector/app.tsx +++ b/src/vector/app.tsx @@ -30,6 +30,8 @@ import { ModuleRunner } from "../modules/ModuleRunner"; import { parseQs } from "./url_utils"; import { getInitialScreenAfterLogin, getScreenFromLocation, init as initRouting, onNewScreen } from "./routing"; import { UserFriendlyError } from "../languageHandler"; +import { ModuleApi } from "../modules/Api"; +import { RoomView } from "../components/structures/RoomView"; logger.log(`Application is running in ${process.env.NODE_ENV} mode`); @@ -53,6 +55,11 @@ function onTokenLoginCompleted(): void { } export async function loadApp(fragParams: QueryDict, matrixChatRef: React.Ref): Promise { + // XXX: This lives here because RoomVew import so many things that importing it in a sensible place (eg. + // the builtins module or init.tsx) causes a circular dependency. Instead, we reference RoomView here where we + // already reference it indirectly via MatrixChat. + ModuleApi.instance.builtins.setRoomViewComponent(RoomView); + initRouting(); const platform = PlatformPeg.get();