mirror of
https://github.com/vector-im/element-call.git
synced 2026-08-02 19:49:23 +00:00
move show footer logic to callViewModel
Also remove header prop. This is accesible via urlParams.
This commit is contained in:
@@ -1,3 +1,10 @@
|
|||||||
|
/*
|
||||||
|
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 { StorybookConfig } from "@storybook/react-vite";
|
import type { StorybookConfig } from "@storybook/react-vite";
|
||||||
|
|
||||||
const config: StorybookConfig = {
|
const config: StorybookConfig = {
|
||||||
|
|||||||
@@ -1,3 +1,10 @@
|
|||||||
|
/*
|
||||||
|
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 { create } from "storybook/theming";
|
import { create } from "storybook/theming";
|
||||||
import { addons } from "storybook/manager-api";
|
import { addons } from "storybook/manager-api";
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,10 @@
|
|||||||
|
/*
|
||||||
|
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 { Preview } from "@storybook/react-vite";
|
import type { Preview } from "@storybook/react-vite";
|
||||||
import { TooltipProvider } from "@vector-im/compound-web";
|
import { TooltipProvider } from "@vector-im/compound-web";
|
||||||
import i18n from "i18next";
|
import i18n from "i18next";
|
||||||
|
|||||||
@@ -14,11 +14,13 @@ import {
|
|||||||
type RTCNotificationType,
|
type RTCNotificationType,
|
||||||
} from "matrix-js-sdk/lib/matrixrtc";
|
} from "matrix-js-sdk/lib/matrixrtc";
|
||||||
import { pickBy } from "lodash-es";
|
import { pickBy } from "lodash-es";
|
||||||
|
import { BehaviorSubject } from "rxjs";
|
||||||
|
|
||||||
import { Config } from "./config/Config";
|
import { Config } from "./config/Config";
|
||||||
import { type EncryptionSystem } from "./e2ee/sharedKeyManagement";
|
import { type EncryptionSystem } from "./e2ee/sharedKeyManagement";
|
||||||
import { E2eeType } from "./e2ee/e2eeType";
|
import { E2eeType } from "./e2ee/e2eeType";
|
||||||
import { platform } from "./Platform";
|
import { platform } from "./Platform";
|
||||||
|
import { type ObservableScope } from "./state/ObservableScope";
|
||||||
|
|
||||||
interface RoomIdentifier {
|
interface RoomIdentifier {
|
||||||
roomAlias: string | null;
|
roomAlias: string | null;
|
||||||
@@ -607,6 +609,24 @@ export const useRoomIdentifier = (): RoomIdentifier => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let urlParams$ = undefined as BehaviorSubject<UrlParams> | undefined;
|
||||||
|
export const observerUrlParams$ = (
|
||||||
|
scope: ObservableScope,
|
||||||
|
): BehaviorSubject<UrlParams> => {
|
||||||
|
if (urlParams$ !== undefined) return urlParams$;
|
||||||
|
function updateUrlParams(): void {
|
||||||
|
console.log("[observerUrlParams$] update urlParams$");
|
||||||
|
urlParams$!.next(getUrlParams());
|
||||||
|
}
|
||||||
|
|
||||||
|
urlParams$ = new BehaviorSubject(getUrlParams());
|
||||||
|
window.addEventListener("hashchange", updateUrlParams);
|
||||||
|
scope.onEnd(() => {
|
||||||
|
window.removeEventListener("hashchange", updateUrlParams);
|
||||||
|
});
|
||||||
|
return urlParams$;
|
||||||
|
};
|
||||||
|
|
||||||
export function generateUrlSearchParams(
|
export function generateUrlSearchParams(
|
||||||
roomId: string,
|
roomId: string,
|
||||||
encryptionSystem: EncryptionSystem,
|
encryptionSystem: EncryptionSystem,
|
||||||
|
|||||||
@@ -93,7 +93,6 @@ interface Props {
|
|||||||
confineToRoom: boolean;
|
confineToRoom: boolean;
|
||||||
preload: UrlParams["preload"];
|
preload: UrlParams["preload"];
|
||||||
skipLobby: UrlParams["skipLobby"];
|
skipLobby: UrlParams["skipLobby"];
|
||||||
header: HeaderStyle;
|
|
||||||
rtcSession: MatrixRTCSession;
|
rtcSession: MatrixRTCSession;
|
||||||
joined: boolean;
|
joined: boolean;
|
||||||
setJoined: (value: boolean) => void;
|
setJoined: (value: boolean) => void;
|
||||||
@@ -107,7 +106,6 @@ export const GroupCallView: FC<Props> = ({
|
|||||||
confineToRoom,
|
confineToRoom,
|
||||||
preload,
|
preload,
|
||||||
skipLobby,
|
skipLobby,
|
||||||
header,
|
|
||||||
rtcSession,
|
rtcSession,
|
||||||
joined,
|
joined,
|
||||||
setJoined,
|
setJoined,
|
||||||
@@ -182,6 +180,7 @@ export const GroupCallView: FC<Props> = ({
|
|||||||
perParticipantE2EE,
|
perParticipantE2EE,
|
||||||
returnToLobby,
|
returnToLobby,
|
||||||
password: passwordFromUrl,
|
password: passwordFromUrl,
|
||||||
|
header,
|
||||||
} = useUrlParams();
|
} = useUrlParams();
|
||||||
const e2eeSystem = useRoomEncryptionSystem(room.roomId);
|
const e2eeSystem = useRoomEncryptionSystem(room.roomId);
|
||||||
|
|
||||||
@@ -463,7 +462,6 @@ export const GroupCallView: FC<Props> = ({
|
|||||||
rtcSession={rtcSession as MatrixRTCSession}
|
rtcSession={rtcSession as MatrixRTCSession}
|
||||||
matrixRoom={room}
|
matrixRoom={room}
|
||||||
onLeft={onLeft}
|
onLeft={onLeft}
|
||||||
header={header}
|
|
||||||
muteStates={muteStates}
|
muteStates={muteStates}
|
||||||
e2eeSystem={e2eeSystem}
|
e2eeSystem={e2eeSystem}
|
||||||
//otelGroupCallMembership={otelGroupCallMembership}
|
//otelGroupCallMembership={otelGroupCallMembership}
|
||||||
|
|||||||
@@ -39,7 +39,6 @@ import { ReactionsSenderProvider } from "../reactions/useReactionsSender";
|
|||||||
import { useRoomEncryptionSystem } from "../e2ee/sharedKeyManagement";
|
import { useRoomEncryptionSystem } from "../e2ee/sharedKeyManagement";
|
||||||
import { LivekitRoomAudioRenderer } from "../livekit/MatrixAudioRenderer";
|
import { LivekitRoomAudioRenderer } from "../livekit/MatrixAudioRenderer";
|
||||||
import { MediaDevicesContext } from "../MediaDevicesContext";
|
import { MediaDevicesContext } from "../MediaDevicesContext";
|
||||||
import { HeaderStyle } from "../UrlParams";
|
|
||||||
import { type MediaDevices as ECMediaDevices } from "../state/MediaDevices";
|
import { type MediaDevices as ECMediaDevices } from "../state/MediaDevices";
|
||||||
import { initializeWidget } from "../widget";
|
import { initializeWidget } from "../widget";
|
||||||
|
|
||||||
@@ -131,7 +130,6 @@ function createInCallView(args: CreateInCallViewArgs = {}): RenderResult & {
|
|||||||
<RoomContext value={livekitRoom}>
|
<RoomContext value={livekitRoom}>
|
||||||
<InCallView
|
<InCallView
|
||||||
client={client}
|
client={client}
|
||||||
header={HeaderStyle.Standard}
|
|
||||||
rtcSession={rtcSession.asMockedSession()}
|
rtcSession={rtcSession.asMockedSession()}
|
||||||
muteStates={muteState}
|
muteStates={muteState}
|
||||||
vm={vm}
|
vm={vm}
|
||||||
|
|||||||
@@ -171,7 +171,6 @@ export interface InCallViewProps {
|
|||||||
rtcSession: MatrixRTCSession;
|
rtcSession: MatrixRTCSession;
|
||||||
matrixRoom: MatrixRoom;
|
matrixRoom: MatrixRoom;
|
||||||
muteStates: MuteStates;
|
muteStates: MuteStates;
|
||||||
header: HeaderStyle;
|
|
||||||
onShareClick: (() => void) | null;
|
onShareClick: (() => void) | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -181,8 +180,6 @@ export const InCallView: FC<InCallViewProps> = ({
|
|||||||
matrixInfo,
|
matrixInfo,
|
||||||
matrixRoom,
|
matrixRoom,
|
||||||
muteStates,
|
muteStates,
|
||||||
|
|
||||||
header: headerStyle,
|
|
||||||
onShareClick,
|
onShareClick,
|
||||||
}) => {
|
}) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
@@ -206,7 +203,7 @@ export const InCallView: FC<InCallViewProps> = ({
|
|||||||
// Merge the refs so they can attach to the same element
|
// Merge the refs so they can attach to the same element
|
||||||
const containerRef = useMergedRefs(containerRef1, containerRef2);
|
const containerRef = useMergedRefs(containerRef1, containerRef2);
|
||||||
|
|
||||||
const { showControls } = useUrlParams();
|
const { showControls, header: headerStyle } = useUrlParams();
|
||||||
|
|
||||||
const muteAllAudio = useBehavior(muteAllAudio$);
|
const muteAllAudio = useBehavior(muteAllAudio$);
|
||||||
|
|
||||||
@@ -565,14 +562,11 @@ export const InCallView: FC<InCallViewProps> = ({
|
|||||||
<SettingsButton key="settings" onClick={openSettings} />,
|
<SettingsButton key="settings" onClick={openSettings} />,
|
||||||
);
|
);
|
||||||
|
|
||||||
const footerNotNeeded =
|
|
||||||
showControls === false && headerStyle === HeaderStyle.None;
|
|
||||||
const footer = (
|
const footer = (
|
||||||
<InCallFooter
|
<InCallFooter
|
||||||
ref={footerRef}
|
ref={footerRef}
|
||||||
asOverlay={windowMode === "flat"}
|
asOverlay={windowMode === "flat"}
|
||||||
// TODO this should be computed in the view model!
|
showFooter={showFooter}
|
||||||
showFooter={showFooter && !footerNotNeeded}
|
|
||||||
showControls={showControls}
|
showControls={showControls}
|
||||||
showLogo={headerStyle !== HeaderStyle.None}
|
showLogo={headerStyle !== HeaderStyle.None}
|
||||||
showSettingsButton={headerStyle !== HeaderStyle.AppBar}
|
showSettingsButton={headerStyle !== HeaderStyle.AppBar}
|
||||||
|
|||||||
@@ -136,7 +136,6 @@ export const RoomPage: FC = () => {
|
|||||||
confineToRoom={confineToRoom}
|
confineToRoom={confineToRoom}
|
||||||
preload={preload}
|
preload={preload}
|
||||||
skipLobby={skipLobby || wasInWaitForInviteState.current}
|
skipLobby={skipLobby || wasInWaitForInviteState.current}
|
||||||
header={header}
|
|
||||||
muteStates={muteStates}
|
muteStates={muteStates}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ import { v4 as uuidv4 } from "uuid";
|
|||||||
import { type IMembershipManager } from "matrix-js-sdk/lib/matrixrtc/IMembershipManager";
|
import { type IMembershipManager } from "matrix-js-sdk/lib/matrixrtc/IMembershipManager";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
and$,
|
||||||
createToggle$,
|
createToggle$,
|
||||||
filterBehavior,
|
filterBehavior,
|
||||||
generateItem,
|
generateItem,
|
||||||
@@ -82,7 +83,7 @@ import { constant, type Behavior } from "../Behavior";
|
|||||||
import { E2eeType } from "../../e2ee/e2eeType";
|
import { E2eeType } from "../../e2ee/e2eeType";
|
||||||
import { MatrixKeyProvider } from "../../e2ee/matrixKeyProvider";
|
import { MatrixKeyProvider } from "../../e2ee/matrixKeyProvider";
|
||||||
import { type MuteStates } from "../MuteStates";
|
import { type MuteStates } from "../MuteStates";
|
||||||
import { getUrlParams } from "../../UrlParams";
|
import { getUrlParams, HeaderStyle, observerUrlParams$ } from "../../UrlParams";
|
||||||
import { type ProcessorState } from "../../livekit/TrackProcessorContext";
|
import { type ProcessorState } from "../../livekit/TrackProcessorContext";
|
||||||
import { ElementWidgetActions, widget } from "../../widget";
|
import { ElementWidgetActions, widget } from "../../widget";
|
||||||
import {
|
import {
|
||||||
@@ -1316,7 +1317,15 @@ export function createCallViewModel$(
|
|||||||
windowMode$.pipe(map((mode) => mode !== "pip" && mode !== "flat")),
|
windowMode$.pipe(map((mode) => mode !== "pip" && mode !== "flat")),
|
||||||
);
|
);
|
||||||
|
|
||||||
const showFooter$ = scope.behavior<boolean>(
|
const urlParams$ = observerUrlParams$(scope);
|
||||||
|
const showFooterUrlParams$ = urlParams$.pipe(
|
||||||
|
map(
|
||||||
|
({ header, showControls }) =>
|
||||||
|
// with no header and no controls we always set showFooter to false.
|
||||||
|
!(header === HeaderStyle.None && showControls === false),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
const showFooterLayout$ = scope.behavior<boolean>(
|
||||||
windowMode$.pipe(
|
windowMode$.pipe(
|
||||||
switchMap((mode) => {
|
switchMap((mode) => {
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
@@ -1370,7 +1379,9 @@ export function createCallViewModel$(
|
|||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
const showFooter$ = scope.behavior(
|
||||||
|
and$(showFooterLayout$, showFooterUrlParams$),
|
||||||
|
);
|
||||||
/**
|
/**
|
||||||
* Whether audio is currently being output through the earpiece.
|
* Whether audio is currently being output through the earpiece.
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user