Say outright whether the profile is ours to change

Whether to offer the profile settings was inferred from whether the host
could close Element Call. For a component with no host bridge — the
default — nothing could, so an embedded Element Call let the user edit
the profile of an account that belongs to the host application.

`HostBridge.supportsProfileChanges` states it directly: true standalone,
where Element Call signed the user in itself; false for a widget's host
and for anything embedding the component (which sets it itself, since
the client it hands over is its own). The profile tab and the profile
shortcut follow that. What a host's ability to close us still decides —
what to show after the call ends — is a question about who owns our
lifetime, and stays keyed on `close`.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Timo K.
2026-09-08 15:38:59 +02:00
co-authored by Claude Fable 5.1
parent f0359259f9
commit 7cd21476f7
7 changed files with 53 additions and 17 deletions
+2 -2
View File
@@ -10,7 +10,7 @@ import { NEVER, Subject } from "rxjs";
import {
type DeviceMuteRequest,
type DeviceMuteState,
type HostBridge,
type ElementCallHostBridge,
type HostRequest,
} from "../index";
@@ -19,7 +19,7 @@ import {
* so that the harness can watch both directions of the conversation between
* Element Call and its host.
*/
export interface DevHostBridge extends HostBridge {
export interface DevHostBridge extends ElementCallHostBridge {
/** Tells Element Call the host has changed theme. */
requestTheme(name: string): void;
/** Tells Element Call to leave the call. */
+21 -2
View File
@@ -100,6 +100,14 @@ export {
*/
export type ElementCallConfiguration = Partial<UrlParams>;
/**
* What a host embedding Element Call implements to talk to it. This is the
* {@link HostBridge} less what Element Call already knows about such a host:
* the account is the host's, since the client is, so the profile is not
* Element Call's to change.
*/
export type ElementCallHostBridge = Omit<HostBridge, "supportsProfileChanges">;
export interface ElementCallProps {
/**
* The client to place the call with. Element Call does not authenticate
@@ -132,7 +140,7 @@ export interface ElementCallProps {
* joined or hung up, to be asked to keep the call on screen, and so on.
* Without one, Element Call assumes it has no host to talk to.
*/
hostBridge?: HostBridge;
hostBridge?: ElementCallHostBridge;
}
/**
@@ -181,8 +189,19 @@ export const ElementCall: FC<ElementCallProps> = ({
roomId,
intent = UserIntent.JoinExistingCall,
config,
hostBridge = nullHostBridge,
hostBridge: suppliedHostBridge = nullHostBridge,
}): ReactNode => {
// Whatever the host says or does not say, the account is its own: it signed
// the user in and handed us the client. So Element Call never offers to edit
// the profile from inside a component.
const hostBridge = useMemo(
(): HostBridge => ({
...suppliedHostBridge,
supportsProfileChanges: false,
}),
[suppliedHostBridge],
);
// The container is what Element Call decorates and portals into, so nothing
// inside can render until we have it.
const [container, setContainer] = useState<HTMLDivElement | null>(null);