mirror of
https://github.com/element-hq/element-call.git
synced 2026-09-10 13:45:51 +00:00
The component exposed the internal HostBridge to hosts as-is, which carried the host's requests as rxjs observables. That made rxjs part of the public API of a package that bundles its own copy of it, so a host would build bridges with a different rxjs than the one Element Call consumed them with — and asked every host to learn rxjs to change the theme. A component host now implements plain async callbacks for what Element Call tells it (`ElementCallHostBridge`, all optional), and makes its own requests through an imperative handle on the component's `ref` (`ElementCallHandle`: setTheme, join, hangUp, setDeviceMute), each resolving once Element Call has acted and rejecting when nothing in Element Call can. `component/host.ts` adapts that to the HostBridge the rest of Element Call still speaks, with a bridge whose identity never changes, so a host re-creating its callbacks on render restarts nothing. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
47 lines
1.7 KiB
TypeScript
47 lines
1.7 KiB
TypeScript
/*
|
|
Copyright 2026 Element Creations Ltd.
|
|
|
|
SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
|
|
Please see LICENSE in the repository root for full details.
|
|
*/
|
|
|
|
import { type ElementCallHostBridge } from "../index";
|
|
|
|
/**
|
|
* A host bridge that reports everything it is told, so that the harness can
|
|
* watch what Element Call says to its host. (What the host says to Element
|
|
* Call goes through the component's handle, and is logged by the pane.)
|
|
*/
|
|
export function createDevHostBridge(
|
|
log: (message: string) => void,
|
|
/** What the host does when Element Call asks to be closed. */
|
|
onClose: () => void,
|
|
): ElementCallHostBridge {
|
|
/**
|
|
* Records something Element Call told the host. Nothing is sent anywhere, so
|
|
* this is only asynchronous because a real host's answer would have to be.
|
|
*/
|
|
const told = async (message: string): Promise<void> => {
|
|
log(`→ ${message}`);
|
|
await Promise.resolve();
|
|
};
|
|
|
|
return {
|
|
setAlwaysOnScreen: async (alwaysOnScreen): Promise<void> =>
|
|
await told(`setAlwaysOnScreen(${alwaysOnScreen})`),
|
|
contentLoaded: async (): Promise<void> => await told("contentLoaded"),
|
|
notifyJoined: async (): Promise<void> => await told("notifyJoined"),
|
|
notifyHungUp: async (): Promise<void> => await told("notifyHungUp"),
|
|
notifyDeviceMute: async (state): Promise<void> =>
|
|
await told(
|
|
`notifyDeviceMute(audio: ${state.audio_enabled}, video: ${state.video_enabled})`,
|
|
),
|
|
// Present because this host really can dismiss Element Call, which is what
|
|
// makes it offer a close affordance at all
|
|
close: async (): Promise<void> => {
|
|
await told("close");
|
|
onClose();
|
|
},
|
|
};
|
|
}
|