mirror of
https://github.com/vector-im/element-call.git
synced 2026-03-07 05:47:03 +00:00
refactor: Split out all exports of CallViewModel to their own file
This commit is contained in:
@@ -14,7 +14,7 @@ import {
|
||||
import { distinctUntilChanged } from "rxjs";
|
||||
import { useObservableEagerState } from "observable-hooks";
|
||||
|
||||
import { type GridLayout as GridLayoutModel } from "../state/CallViewModel";
|
||||
import { type GridLayout as GridLayoutModel } from "../state/layout-types.ts";
|
||||
import styles from "./GridLayout.module.css";
|
||||
import { useInitial } from "../useInitial";
|
||||
import { type CallLayout, arrangeTiles } from "./CallLayout";
|
||||
|
||||
@@ -9,7 +9,7 @@ import { type ReactNode, useCallback, useMemo } from "react";
|
||||
import { useObservableEagerState } from "observable-hooks";
|
||||
import classNames from "classnames";
|
||||
|
||||
import { type OneOnOneLayout as OneOnOneLayoutModel } from "../state/CallViewModel";
|
||||
import { type OneOnOneLayout as OneOnOneLayoutModel } from "../state/layout-types.ts";
|
||||
import { type CallLayout, arrangeTiles } from "./CallLayout";
|
||||
import styles from "./OneOnOneLayout.module.css";
|
||||
import { type DragCallback, useUpdateLayout } from "./Grid";
|
||||
|
||||
@@ -7,7 +7,7 @@ Please see LICENSE in the repository root for full details.
|
||||
|
||||
import { type ReactNode, useCallback } from "react";
|
||||
|
||||
import { type SpotlightExpandedLayout as SpotlightExpandedLayoutModel } from "../state/CallViewModel";
|
||||
import { type SpotlightExpandedLayout as SpotlightExpandedLayoutModel } from "../state/layout-types.ts";
|
||||
import { type CallLayout } from "./CallLayout";
|
||||
import { type DragCallback, useUpdateLayout } from "./Grid";
|
||||
import styles from "./SpotlightExpandedLayout.module.css";
|
||||
|
||||
@@ -10,7 +10,7 @@ import { useObservableEagerState } from "observable-hooks";
|
||||
import classNames from "classnames";
|
||||
|
||||
import { type CallLayout } from "./CallLayout";
|
||||
import { type SpotlightLandscapeLayout as SpotlightLandscapeLayoutModel } from "../state/CallViewModel";
|
||||
import { type SpotlightLandscapeLayout as SpotlightLandscapeLayoutModel } from "../state/layout-types.ts";
|
||||
import styles from "./SpotlightLandscapeLayout.module.css";
|
||||
import { useUpdateLayout, useVisibleTiles } from "./Grid";
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ import { useObservableEagerState } from "observable-hooks";
|
||||
import classNames from "classnames";
|
||||
|
||||
import { type CallLayout, arrangeTiles } from "./CallLayout";
|
||||
import { type SpotlightPortraitLayout as SpotlightPortraitLayoutModel } from "../state/CallViewModel";
|
||||
import { type SpotlightPortraitLayout as SpotlightPortraitLayoutModel } from "../state/layout-types.ts";
|
||||
import styles from "./SpotlightPortraitLayout.module.css";
|
||||
import { useUpdateLayout, useVisibleTiles } from "./Grid";
|
||||
import { useBehavior } from "../useBehavior";
|
||||
|
||||
@@ -59,11 +59,7 @@ import { type MuteStates } from "../state/MuteStates";
|
||||
import { type MatrixInfo } from "./VideoPreview";
|
||||
import { InviteButton } from "../button/InviteButton";
|
||||
import { LayoutToggle } from "./LayoutToggle";
|
||||
import {
|
||||
CallViewModel,
|
||||
type GridMode,
|
||||
type Layout,
|
||||
} from "../state/CallViewModel";
|
||||
import { CallViewModel, GridMode } from "../state/CallViewModel";
|
||||
import { Grid, type TileProps } from "../grid/Grid";
|
||||
import { useInitial } from "../useInitial";
|
||||
import { SpotlightTile } from "../tile/SpotlightTile";
|
||||
@@ -113,6 +109,7 @@ import { useAudioContext } from "../useAudioContext";
|
||||
import ringtoneMp3 from "../sound/ringtone.mp3?url";
|
||||
import ringtoneOgg from "../sound/ringtone.ogg?url";
|
||||
import { useTrackProcessorObservable$ } from "../livekit/TrackProcessorContext.tsx";
|
||||
import { Layout } from "../state/layout-types.ts";
|
||||
|
||||
const maxTapDurationMs = 400;
|
||||
|
||||
|
||||
@@ -46,11 +46,8 @@ import {
|
||||
} from "matrix-js-sdk/lib/matrixrtc";
|
||||
import { deepCompare } from "matrix-js-sdk/lib/utils";
|
||||
|
||||
import {
|
||||
CallViewModel,
|
||||
type CallViewModelOptions,
|
||||
type Layout,
|
||||
} from "./CallViewModel";
|
||||
import { CallViewModel, type CallViewModelOptions } from "./CallViewModel";
|
||||
import { type Layout } from "./layout-types";
|
||||
import {
|
||||
mockLocalParticipant,
|
||||
mockMatrixRoom,
|
||||
|
||||
@@ -94,10 +94,6 @@ import {
|
||||
} from "../settings/settings";
|
||||
import { isFirefox } from "../Platform";
|
||||
import { setPipEnabled$ } from "../controls";
|
||||
import {
|
||||
type GridTileViewModel,
|
||||
type SpotlightTileViewModel,
|
||||
} from "./TileViewModel";
|
||||
import { TileStore } from "./TileStore";
|
||||
import { gridLikeLayout } from "./GridLikeLayout";
|
||||
import { spotlightExpandedLayout } from "./SpotlightExpandedLayout";
|
||||
@@ -133,6 +129,15 @@ import { PublishConnection } from "./PublishConnection.ts";
|
||||
import { type Async, async$, mapAsync, ready } from "./Async";
|
||||
import { sharingScreen$, UserMedia } from "./UserMedia.ts";
|
||||
import { ScreenShare } from "./ScreenShare.ts";
|
||||
import {
|
||||
GridLayoutMedia,
|
||||
Layout,
|
||||
LayoutMedia,
|
||||
OneOnOneLayoutMedia,
|
||||
SpotlightExpandedLayoutMedia,
|
||||
SpotlightLandscapeLayoutMedia,
|
||||
SpotlightPortraitLayoutMedia,
|
||||
} from "./layout-types.ts";
|
||||
|
||||
export interface CallViewModelOptions {
|
||||
encryptionSystem: EncryptionSystem;
|
||||
@@ -157,99 +162,6 @@ const smallMobileCallThreshold = 3;
|
||||
// with the interface
|
||||
const showFooterMs = 4000;
|
||||
|
||||
export interface GridLayoutMedia {
|
||||
type: "grid";
|
||||
spotlight?: MediaViewModel[];
|
||||
grid: UserMediaViewModel[];
|
||||
}
|
||||
|
||||
export interface SpotlightLandscapeLayoutMedia {
|
||||
type: "spotlight-landscape";
|
||||
spotlight: MediaViewModel[];
|
||||
grid: UserMediaViewModel[];
|
||||
}
|
||||
|
||||
export interface SpotlightPortraitLayoutMedia {
|
||||
type: "spotlight-portrait";
|
||||
spotlight: MediaViewModel[];
|
||||
grid: UserMediaViewModel[];
|
||||
}
|
||||
|
||||
export interface SpotlightExpandedLayoutMedia {
|
||||
type: "spotlight-expanded";
|
||||
spotlight: MediaViewModel[];
|
||||
pip?: UserMediaViewModel;
|
||||
}
|
||||
|
||||
export interface OneOnOneLayoutMedia {
|
||||
type: "one-on-one";
|
||||
local: UserMediaViewModel;
|
||||
remote: UserMediaViewModel;
|
||||
}
|
||||
|
||||
export interface PipLayoutMedia {
|
||||
type: "pip";
|
||||
spotlight: MediaViewModel[];
|
||||
}
|
||||
|
||||
export type LayoutMedia =
|
||||
| GridLayoutMedia
|
||||
| SpotlightLandscapeLayoutMedia
|
||||
| SpotlightPortraitLayoutMedia
|
||||
| SpotlightExpandedLayoutMedia
|
||||
| OneOnOneLayoutMedia
|
||||
| PipLayoutMedia;
|
||||
|
||||
export interface GridLayout {
|
||||
type: "grid";
|
||||
spotlight?: SpotlightTileViewModel;
|
||||
grid: GridTileViewModel[];
|
||||
setVisibleTiles: (value: number) => void;
|
||||
}
|
||||
|
||||
export interface SpotlightLandscapeLayout {
|
||||
type: "spotlight-landscape";
|
||||
spotlight: SpotlightTileViewModel;
|
||||
grid: GridTileViewModel[];
|
||||
setVisibleTiles: (value: number) => void;
|
||||
}
|
||||
|
||||
export interface SpotlightPortraitLayout {
|
||||
type: "spotlight-portrait";
|
||||
spotlight: SpotlightTileViewModel;
|
||||
grid: GridTileViewModel[];
|
||||
setVisibleTiles: (value: number) => void;
|
||||
}
|
||||
|
||||
export interface SpotlightExpandedLayout {
|
||||
type: "spotlight-expanded";
|
||||
spotlight: SpotlightTileViewModel;
|
||||
pip?: GridTileViewModel;
|
||||
}
|
||||
|
||||
export interface OneOnOneLayout {
|
||||
type: "one-on-one";
|
||||
local: GridTileViewModel;
|
||||
remote: GridTileViewModel;
|
||||
}
|
||||
|
||||
export interface PipLayout {
|
||||
type: "pip";
|
||||
spotlight: SpotlightTileViewModel;
|
||||
}
|
||||
|
||||
/**
|
||||
* A layout defining the media tiles present on screen and their visual
|
||||
* arrangement.
|
||||
*/
|
||||
export type Layout =
|
||||
| GridLayout
|
||||
| SpotlightLandscapeLayout
|
||||
| SpotlightPortraitLayout
|
||||
| SpotlightExpandedLayout
|
||||
| OneOnOneLayout
|
||||
| PipLayout;
|
||||
|
||||
export type GridMode = "grid" | "spotlight";
|
||||
|
||||
export type WindowMode = "normal" | "narrow" | "flat" | "pip";
|
||||
@@ -295,28 +207,6 @@ interface LayoutScanState {
|
||||
|
||||
type MediaItem = UserMedia | ScreenShare;
|
||||
|
||||
function getRoomMemberFromRtcMember(
|
||||
rtcMember: CallMembership,
|
||||
room: MatrixRoom,
|
||||
): { id: string; member: RoomMember | undefined } {
|
||||
// WARN! This is not exactly the sender but the user defined in the state key.
|
||||
// This will be available once we change to the new "member as object" format in the MatrixRTC object.
|
||||
let id = rtcMember.sender + ":" + rtcMember.deviceId;
|
||||
|
||||
if (!rtcMember.sender) {
|
||||
return { id, member: undefined };
|
||||
}
|
||||
if (
|
||||
rtcMember.sender === room.client.getUserId() &&
|
||||
rtcMember.deviceId === room.client.getDeviceId()
|
||||
) {
|
||||
id = "local";
|
||||
}
|
||||
|
||||
const member = room.getMember(rtcMember.sender) ?? undefined;
|
||||
return { id, member };
|
||||
}
|
||||
|
||||
export class CallViewModel extends ViewModel {
|
||||
private readonly urlParams = getUrlParams();
|
||||
|
||||
@@ -2004,3 +1894,25 @@ function getE2eeKeyProvider(
|
||||
return keyProvider;
|
||||
}
|
||||
}
|
||||
|
||||
function getRoomMemberFromRtcMember(
|
||||
rtcMember: CallMembership,
|
||||
room: MatrixRoom,
|
||||
): { id: string; member: RoomMember | undefined } {
|
||||
// WARN! This is not exactly the sender but the user defined in the state key.
|
||||
// This will be available once we change to the new "member as object" format in the MatrixRTC object.
|
||||
let id = rtcMember.sender + ":" + rtcMember.deviceId;
|
||||
|
||||
if (!rtcMember.sender) {
|
||||
return { id, member: undefined };
|
||||
}
|
||||
if (
|
||||
rtcMember.sender === room.client.getUserId() &&
|
||||
rtcMember.deviceId === room.client.getDeviceId()
|
||||
) {
|
||||
id = "local";
|
||||
}
|
||||
|
||||
const member = room.getMember(rtcMember.sender) ?? undefined;
|
||||
return { id, member };
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
|
||||
Please see LICENSE in the repository root for full details.
|
||||
*/
|
||||
|
||||
import { type Layout, type LayoutMedia } from "./CallViewModel";
|
||||
import { type Layout, type LayoutMedia } from "./layout-types.ts";
|
||||
import { type TileStore } from "./TileStore";
|
||||
|
||||
export type GridLikeLayoutType =
|
||||
|
||||
@@ -5,7 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
|
||||
Please see LICENSE in the repository root for full details.
|
||||
*/
|
||||
|
||||
import { type OneOnOneLayout, type OneOnOneLayoutMedia } from "./CallViewModel";
|
||||
import { type OneOnOneLayout, type OneOnOneLayoutMedia } from "./layout-types";
|
||||
import { type TileStore } from "./TileStore";
|
||||
|
||||
/**
|
||||
|
||||
@@ -5,7 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
|
||||
Please see LICENSE in the repository root for full details.
|
||||
*/
|
||||
|
||||
import { type PipLayout, type PipLayoutMedia } from "./CallViewModel";
|
||||
import { type PipLayout, type PipLayoutMedia } from "./layout-types.ts";
|
||||
import { type TileStore } from "./TileStore";
|
||||
|
||||
/**
|
||||
|
||||
@@ -8,7 +8,7 @@ Please see LICENSE in the repository root for full details.
|
||||
import {
|
||||
type SpotlightExpandedLayout,
|
||||
type SpotlightExpandedLayoutMedia,
|
||||
} from "./CallViewModel";
|
||||
} from "./layout-types";
|
||||
import { type TileStore } from "./TileStore";
|
||||
|
||||
/**
|
||||
|
||||
102
src/state/layout-types.ts
Normal file
102
src/state/layout-types.ts
Normal file
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
Copyright 2025 New Vector Ltd.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
|
||||
Please see LICENSE in the repository root for full details.
|
||||
*/
|
||||
|
||||
import { GridTileViewModel, SpotlightTileViewModel } from "./TileViewModel.ts";
|
||||
import { MediaViewModel, UserMediaViewModel } from "./MediaViewModel.ts";
|
||||
|
||||
export interface GridLayoutMedia {
|
||||
type: "grid";
|
||||
spotlight?: MediaViewModel[];
|
||||
grid: UserMediaViewModel[];
|
||||
}
|
||||
|
||||
export interface SpotlightLandscapeLayoutMedia {
|
||||
type: "spotlight-landscape";
|
||||
spotlight: MediaViewModel[];
|
||||
grid: UserMediaViewModel[];
|
||||
}
|
||||
|
||||
export interface SpotlightPortraitLayoutMedia {
|
||||
type: "spotlight-portrait";
|
||||
spotlight: MediaViewModel[];
|
||||
grid: UserMediaViewModel[];
|
||||
}
|
||||
|
||||
export interface SpotlightExpandedLayoutMedia {
|
||||
type: "spotlight-expanded";
|
||||
spotlight: MediaViewModel[];
|
||||
pip?: UserMediaViewModel;
|
||||
}
|
||||
|
||||
export interface OneOnOneLayoutMedia {
|
||||
type: "one-on-one";
|
||||
local: UserMediaViewModel;
|
||||
remote: UserMediaViewModel;
|
||||
}
|
||||
|
||||
export interface PipLayoutMedia {
|
||||
type: "pip";
|
||||
spotlight: MediaViewModel[];
|
||||
}
|
||||
|
||||
export type LayoutMedia =
|
||||
| GridLayoutMedia
|
||||
| SpotlightLandscapeLayoutMedia
|
||||
| SpotlightPortraitLayoutMedia
|
||||
| SpotlightExpandedLayoutMedia
|
||||
| OneOnOneLayoutMedia
|
||||
| PipLayoutMedia;
|
||||
|
||||
export interface GridLayout {
|
||||
type: "grid";
|
||||
spotlight?: SpotlightTileViewModel;
|
||||
grid: GridTileViewModel[];
|
||||
setVisibleTiles: (value: number) => void;
|
||||
}
|
||||
|
||||
export interface SpotlightLandscapeLayout {
|
||||
type: "spotlight-landscape";
|
||||
spotlight: SpotlightTileViewModel;
|
||||
grid: GridTileViewModel[];
|
||||
setVisibleTiles: (value: number) => void;
|
||||
}
|
||||
|
||||
export interface SpotlightPortraitLayout {
|
||||
type: "spotlight-portrait";
|
||||
spotlight: SpotlightTileViewModel;
|
||||
grid: GridTileViewModel[];
|
||||
setVisibleTiles: (value: number) => void;
|
||||
}
|
||||
|
||||
export interface SpotlightExpandedLayout {
|
||||
type: "spotlight-expanded";
|
||||
spotlight: SpotlightTileViewModel;
|
||||
pip?: GridTileViewModel;
|
||||
}
|
||||
|
||||
export interface OneOnOneLayout {
|
||||
type: "one-on-one";
|
||||
local: GridTileViewModel;
|
||||
remote: GridTileViewModel;
|
||||
}
|
||||
|
||||
export interface PipLayout {
|
||||
type: "pip";
|
||||
spotlight: SpotlightTileViewModel;
|
||||
}
|
||||
|
||||
/**
|
||||
* A layout defining the media tiles present on screen and their visual
|
||||
* arrangement.
|
||||
*/
|
||||
export type Layout =
|
||||
| GridLayout
|
||||
| SpotlightLandscapeLayout
|
||||
| SpotlightPortraitLayout
|
||||
| SpotlightExpandedLayout
|
||||
| OneOnOneLayout
|
||||
| PipLayout;
|
||||
Reference in New Issue
Block a user