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:
+39
-41
@@ -141,47 +141,45 @@ export function useComponentHostBridge(
|
||||
requests.themeChange$.next({ data: { name: theme }, reply: () => {} });
|
||||
}, [requests, theme]);
|
||||
|
||||
const bridge = useInitial(
|
||||
(): HostBridge => ({
|
||||
setAlwaysOnScreen: async (alwaysOnScreen) => {
|
||||
await latest.current.setAlwaysOnScreen?.(alwaysOnScreen);
|
||||
},
|
||||
contentLoaded: async () => {
|
||||
await latest.current.contentLoaded?.();
|
||||
},
|
||||
notifyJoined: async () => {
|
||||
await latest.current.notifyJoined?.();
|
||||
},
|
||||
notifyHungUp: async () => {
|
||||
await latest.current.notifyHungUp?.();
|
||||
},
|
||||
notifyDeviceMute: async (state) => {
|
||||
await latest.current.notifyDeviceMute?.(state);
|
||||
},
|
||||
// Whether these exist is itself information, so they are read through
|
||||
// rather than wrapped unconditionally
|
||||
get close() {
|
||||
const close = latest.current.close;
|
||||
return close === undefined
|
||||
? undefined
|
||||
: async (): Promise<void> => await close();
|
||||
},
|
||||
// Not offered to a component host: the client it hands over holds the
|
||||
// credentials to fetch media itself. A widget's client does not, which
|
||||
// is what the internal bridge's `downloadMedia` is for.
|
||||
get supportsReactions(): boolean {
|
||||
return latest.current.supportsReactions ?? true;
|
||||
},
|
||||
get allowJoinUnmutedViaIntent(): boolean {
|
||||
return latest.current.allowJoinUnmutedViaIntent ?? false;
|
||||
},
|
||||
// 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.
|
||||
supportsProfileChanges: false,
|
||||
...requests,
|
||||
}),
|
||||
);
|
||||
const bridge = useInitial((): HostBridge => ({
|
||||
setAlwaysOnScreen: async (alwaysOnScreen) => {
|
||||
await latest.current.setAlwaysOnScreen?.(alwaysOnScreen);
|
||||
},
|
||||
contentLoaded: async () => {
|
||||
await latest.current.contentLoaded?.();
|
||||
},
|
||||
notifyJoined: async () => {
|
||||
await latest.current.notifyJoined?.();
|
||||
},
|
||||
notifyHungUp: async () => {
|
||||
await latest.current.notifyHungUp?.();
|
||||
},
|
||||
notifyDeviceMute: async (state) => {
|
||||
await latest.current.notifyDeviceMute?.(state);
|
||||
},
|
||||
// Whether these exist is itself information, so they are read through
|
||||
// rather than wrapped unconditionally
|
||||
get close() {
|
||||
const close = latest.current.close;
|
||||
return close === undefined
|
||||
? undefined
|
||||
: async (): Promise<void> => await close();
|
||||
},
|
||||
// Not offered to a component host: the client it hands over holds the
|
||||
// credentials to fetch media itself. A widget's client does not, which
|
||||
// is what the internal bridge's `downloadMedia` is for.
|
||||
get supportsReactions(): boolean {
|
||||
return latest.current.supportsReactions ?? true;
|
||||
},
|
||||
get allowJoinUnmutedViaIntent(): boolean {
|
||||
return latest.current.allowJoinUnmutedViaIntent ?? false;
|
||||
},
|
||||
// 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.
|
||||
supportsProfileChanges: false,
|
||||
...requests,
|
||||
}));
|
||||
|
||||
useImperativeHandle(
|
||||
ref,
|
||||
|
||||
+47
-32
@@ -40,6 +40,7 @@ import {
|
||||
useEffect,
|
||||
useLayoutEffect,
|
||||
useMemo,
|
||||
useRef,
|
||||
useState,
|
||||
} from "react";
|
||||
import { type MatrixClient } from "matrix-js-sdk";
|
||||
@@ -298,43 +299,57 @@ export const ElementCall: FC<ElementCallProps> = ({
|
||||
`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 (
|
||||
<I18nextProvider i18n={i18n}>
|
||||
<HostBridgeProvider value={hostBridge}>
|
||||
<UrlParamsProvider value={params}>
|
||||
<div ref={setContainer} className={styles.root}>
|
||||
{container !== null &&
|
||||
rtcSession !== null &&
|
||||
mediaDevices !== null && (
|
||||
<RootElementProvider value={container}>
|
||||
{/* Whatever goes wrong in here is shown in here. Left to
|
||||
propagate, an error would unmount the host's own tree. */}
|
||||
<ErrorBoundary
|
||||
fallback={(error) => <ErrorPage error={error} />}
|
||||
// A broken call should not hold the host on screen
|
||||
onError={() => void hostBridge.setAlwaysOnScreen(false)}
|
||||
>
|
||||
<Decoration>
|
||||
<TooltipProvider>
|
||||
<ClientProvider client={client}>
|
||||
<MediaDevicesContext value={mediaDevices}>
|
||||
<ProcessorProvider>
|
||||
<CallView
|
||||
client={client}
|
||||
rtcSession={rtcSession}
|
||||
isPasswordlessUser={false}
|
||||
confineToRoom={params.confineToRoom}
|
||||
preload={params.preload}
|
||||
skipLobby={params.skipLobby}
|
||||
/>
|
||||
</ProcessorProvider>
|
||||
</MediaDevicesContext>
|
||||
</ClientProvider>
|
||||
</TooltipProvider>
|
||||
</Decoration>
|
||||
</ErrorBoundary>
|
||||
</RootElementProvider>
|
||||
)}
|
||||
{ready && (
|
||||
<RootElementProvider value={container}>
|
||||
{/* Whatever goes wrong in here is shown in here. Left to
|
||||
propagate, an error would unmount the host's own tree. */}
|
||||
<ErrorBoundary
|
||||
fallback={(error) => <ErrorPage error={error} />}
|
||||
// A broken call should not hold the host on screen
|
||||
onError={() => void hostBridge.setAlwaysOnScreen(false)}
|
||||
>
|
||||
<Decoration>
|
||||
<TooltipProvider>
|
||||
<ClientProvider client={client}>
|
||||
<MediaDevicesContext value={mediaDevices}>
|
||||
<ProcessorProvider>
|
||||
<CallView
|
||||
client={client}
|
||||
rtcSession={rtcSession}
|
||||
isPasswordlessUser={false}
|
||||
confineToRoom={params.confineToRoom}
|
||||
preload={params.preload}
|
||||
skipLobby={params.skipLobby}
|
||||
/>
|
||||
</ProcessorProvider>
|
||||
</MediaDevicesContext>
|
||||
</ClientProvider>
|
||||
</TooltipProvider>
|
||||
</Decoration>
|
||||
</ErrorBoundary>
|
||||
</RootElementProvider>
|
||||
)}
|
||||
</div>
|
||||
</UrlParamsProvider>
|
||||
</HostBridgeProvider>
|
||||
|
||||
Reference in New Issue
Block a user