Skip to content

Commit

Permalink
WIP closes element-hq#1764
Browse files Browse the repository at this point in the history
  • Loading branch information
robintown committed Dec 6, 2023
1 parent f936139 commit d3fa33b
Show file tree
Hide file tree
Showing 10 changed files with 604 additions and 499 deletions.
11 changes: 6 additions & 5 deletions src/UserMenuContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { useHistory, useLocation } from "react-router-dom";

import { useClientLegacy } from "./ClientContext";
import { useProfile } from "./profile/useProfile";
import { SettingsModal } from "./settings/SettingsModal";
import { defaultSettingsTab, SettingsModal } from "./settings/SettingsModal";
import { UserMenu } from "./UserMenu";

interface Props {
Expand All @@ -37,17 +37,17 @@ export const UserMenuContainer: FC<Props> = ({ preventNavigation = false }) => {
[setSettingsModalOpen],
);

const [defaultSettingsTab, setDefaultSettingsTab] = useState<string>();
const [settingsTab, setSettingsTab] = useState(defaultSettingsTab);

const onAction = useCallback(
async (value: string) => {
switch (value) {
case "user":
setDefaultSettingsTab("profile");
setSettingsTab("profile");
setSettingsModalOpen(true);
break;
case "settings":
setDefaultSettingsTab("audio");
setSettingsTab("audio");
setSettingsModalOpen(true);
break;
case "logout":
Expand Down Expand Up @@ -76,9 +76,10 @@ export const UserMenuContainer: FC<Props> = ({ preventNavigation = false }) => {
{client && (
<SettingsModal
client={client}
defaultTab={defaultSettingsTab}
open={settingsModalOpen}
onDismiss={onDismissSettingsModal}
tab={settingsTab}
onTabChange={setSettingsTab}
/>
)}
</>
Expand Down
26 changes: 17 additions & 9 deletions src/room/InCallView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ import {
} from "../button";
import { Header, LeftNav, RightNav, RoomHeaderInfo } from "../Header";
import { useVideoGridLayout, VideoGrid } from "../video-grid/VideoGrid";
import { useShowConnectionStats } from "../settings/useSetting";
import { useUrlParams } from "../UrlParams";
import { useCallViewKeyboardShortcuts } from "../useCallViewKeyboardShortcuts";
import { usePrefersReducedMotion } from "../usePrefersReducedMotion";
Expand All @@ -61,7 +60,7 @@ import styles from "./InCallView.module.css";
import { VideoTile } from "../video-grid/VideoTile";
import { NewVideoGrid } from "../video-grid/NewVideoGrid";
import { OTelGroupCallMembership } from "../otel/OTelGroupCallMembership";
import { SettingsModal } from "../settings/SettingsModal";
import { SettingsModal, defaultSettingsTab } from "../settings/SettingsModal";
import { useRageshakeRequestModal } from "../settings/submit-rageshake";
import { RageshakeRequestModal } from "./RageshakeRequestModal";
import { E2EEConfig, useLiveKit } from "../livekit/useLiveKit";
Expand Down Expand Up @@ -167,8 +166,6 @@ export const InCallView: FC<InCallViewProps> = subscribe(
screenSharingTracks.length > 0,
);

const [showConnectionStats] = useShowConnectionStats();

const { hideScreensharing, showControls } = useUrlParams();

const { isScreenShareEnabled, localParticipant } = useLocalParticipant({
Expand Down Expand Up @@ -238,7 +235,12 @@ export const InCallView: FC<InCallViewProps> = subscribe(
const reducedControls = boundsValid && bounds.width <= 340;
const noControls = reducedControls && bounds.height <= 400;

const vm = useCallViewModel(rtcSession.room, livekitRoom, connState);
const vm = useCallViewModel(
rtcSession.room,
livekitRoom,
matrixInfo.roomEncrypted,
connState,
);
const items = useStateObservable(vm.tiles);
const { fullscreenItem, toggleFullscreen, exitFullscreen } =
useFullscreen(items);
Expand Down Expand Up @@ -283,8 +285,7 @@ export const InCallView: FC<InCallViewProps> = subscribe(
targetWidth={bounds.width}
key={maximisedParticipant.id}
showSpeakingIndicator={false}
showConnectionStats={showConnectionStats}
matrixInfo={matrixInfo}
onOpenProfile={openProfile}
/>
);
}
Expand All @@ -303,8 +304,7 @@ export const InCallView: FC<InCallViewProps> = subscribe(
fullscreen={false}
onToggleFullscreen={toggleFullscreen}
showSpeakingIndicator={items.length > 2}
showConnectionStats={showConnectionStats}
matrixInfo={matrixInfo}
onOpenProfile={openProfile}
{...props}
ref={props.ref as Ref<HTMLDivElement>}
/>
Expand All @@ -318,6 +318,7 @@ export const InCallView: FC<InCallViewProps> = subscribe(
);

const [settingsModalOpen, setSettingsModalOpen] = useState(false);
const [settingsTab, setSettingsTab] = useState(defaultSettingsTab);

const openSettings = useCallback(
() => setSettingsModalOpen(true),
Expand All @@ -328,6 +329,11 @@ export const InCallView: FC<InCallViewProps> = subscribe(
[setSettingsModalOpen],
);

const openProfile = useCallback(() => {
setSettingsTab("profile");
setSettingsModalOpen(true);
}, [setSettingsTab, setSettingsModalOpen]);

const toggleScreensharing = useCallback(async () => {
exitFullscreen();
await localParticipant.setScreenShareEnabled(!isScreenShareEnabled, {
Expand Down Expand Up @@ -450,6 +456,8 @@ export const InCallView: FC<InCallViewProps> = subscribe(
roomId={rtcSession.room.roomId}
open={settingsModalOpen}
onDismiss={closeSettings}
tab={settingsTab}
onTabChange={setSettingsTab}
/>
</div>
);
Expand Down
7 changes: 5 additions & 2 deletions src/room/LobbyView.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright 2022 New Vector Ltd
Copyright 2022-2023 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -34,7 +34,7 @@ import {
SettingsButton,
VideoButton,
} from "../button/Button";
import { SettingsModal } from "../settings/SettingsModal";
import { SettingsModal, defaultSettingsTab } from "../settings/SettingsModal";
import { useMediaQuery } from "../useMediaQuery";

interface Props {
Expand Down Expand Up @@ -71,6 +71,7 @@ export const LobbyView: FC<Props> = ({
);

const [settingsModalOpen, setSettingsModalOpen] = useState(false);
const [settingsTab, setSettingsTab] = useState(defaultSettingsTab);

const openSettings = useCallback(
() => setSettingsModalOpen(true),
Expand Down Expand Up @@ -148,6 +149,8 @@ export const LobbyView: FC<Props> = ({
client={client}
open={settingsModalOpen}
onDismiss={closeSettings}
tab={settingsTab}
onTabChange={setSettingsTab}
/>
)}
</>
Expand Down
47 changes: 28 additions & 19 deletions src/settings/SettingsModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/

import { ChangeEvent, FC, Key, ReactNode, useCallback, useState } from "react";
import { ChangeEvent, FC, Key, ReactNode } from "react";
import { Item } from "@react-stately/collections";
import { Trans, useTranslation } from "react-i18next";
import { MatrixClient } from "matrix-js-sdk";
Expand Down Expand Up @@ -47,15 +47,33 @@ import {
} from "../livekit/MediaDevicesContext";
import { widget } from "../widget";

type SettingsTab =
| "audio"
| "video"
| "profile"
| "feedback"
| "more"
| "developer";

interface Props {
open: boolean;
onDismiss: () => void;
tab: SettingsTab;
onTabChange: (tab: SettingsTab) => void;
client: MatrixClient;
roomId?: string;
defaultTab?: string;
}

export const SettingsModal: FC<Props> = (props) => {
export const defaultSettingsTab: SettingsTab = "audio";

export const SettingsModal: FC<Props> = ({
open,
onDismiss,
tab,
onTabChange,
client,
roomId,
}) => {
const { t } = useTranslation();

const [optInAnalytics, setOptInAnalytics] = useOptInAnalytics();
Expand Down Expand Up @@ -92,15 +110,6 @@ export const SettingsModal: FC<Props> = (props) => {
);
};

const [selectedTab, setSelectedTab] = useState<string | undefined>();

const onSelectedTabChanged = useCallback(
(tab: Key) => {
setSelectedTab(tab.toString());
},
[setSelectedTab],
);

const optInDescription = (
<Caption>
<Trans i18nKey="settings.opt_in_description">
Expand All @@ -113,7 +122,7 @@ export const SettingsModal: FC<Props> = (props) => {
);

const devices = useMediaDevices();
useMediaDeviceNames(devices, props.open);
useMediaDeviceNames(devices, open);

const audioTab = (
<TabItem
Expand Down Expand Up @@ -158,7 +167,7 @@ export const SettingsModal: FC<Props> = (props) => {
</>
}
>
<ProfileSettingsTab client={props.client} />
<ProfileSettingsTab client={client} />
</TabItem>
);

Expand All @@ -172,7 +181,7 @@ export const SettingsModal: FC<Props> = (props) => {
</>
}
>
<FeedbackSettingsTab roomId={props.roomId} />
<FeedbackSettingsTab roomId={roomId} />
</TabItem>
);

Expand Down Expand Up @@ -260,12 +269,12 @@ export const SettingsModal: FC<Props> = (props) => {
<Modal
title={t("common.settings")}
className={styles.settingsModal}
open={props.open}
onDismiss={props.onDismiss}
open={open}
onDismiss={onDismiss}
>
<TabContainer
onSelectionChange={onSelectedTabChanged}
selectedKey={selectedTab ?? props.defaultTab ?? "audio"}
onSelectionChange={onTabChange as (tab: Key) => void}
selectedKey={tab}
className={styles.tabContainer}
>
{tabs}
Expand Down
17 changes: 13 additions & 4 deletions src/state/CallViewModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ export class CallViewModel extends ViewModel {
},
);

// TODO: destroy tiles
public readonly tiles = state(
combineLatest([
this.remoteParticipants,
Expand Down Expand Up @@ -201,7 +202,7 @@ export class CallViewModel extends ViewModel {
largeBaseSize: false,
data:
tilesById.get(id)?.data ??
new UserMediaTileViewModel(id, member, p),
new UserMediaTileViewModel(member, p, this.encrypted),
};

if (p.isScreenShareEnabled) {
Expand All @@ -216,8 +217,8 @@ export class CallViewModel extends ViewModel {
largeBaseSize: true,
placeNear: id,
data:
tilesById.get(id)?.data ??
new ScreenShareTileViewModel(id, member, p),
tilesById.get(screenShareId)?.data ??
new ScreenShareTileViewModel(member, p, this.encrypted),
};
return [userMediaTile, screenShareTile];
} else {
Expand All @@ -236,6 +237,7 @@ export class CallViewModel extends ViewModel {
// A call is permanently tied to a single Matrix room and LiveKit room
private readonly matrixRoom: MatrixRoom,
private readonly livekitRoom: LivekitRoom,
private readonly encrypted: boolean,
private readonly connectionState: Observable<ECConnectionState>,
) {
super();
Expand All @@ -245,18 +247,25 @@ export class CallViewModel extends ViewModel {
export function useCallViewModel(
matrixRoom: MatrixRoom,
livekitRoom: LivekitRoom,
encrypted: boolean,
connectionState: ECConnectionState,
): CallViewModel {
const prevMatrixRoom = usePrevious(matrixRoom);
const prevLivekitRoom = usePrevious(livekitRoom);
const prevEncrypted = usePrevious(encrypted);
const connectionStateObservable = useObservable(connectionState);

const vm = useRef<CallViewModel>();
if (matrixRoom !== prevMatrixRoom || livekitRoom !== prevLivekitRoom) {
if (
matrixRoom !== prevMatrixRoom ||
livekitRoom !== prevLivekitRoom ||
encrypted !== prevEncrypted
) {
vm.current?.destroy();
vm.current = new CallViewModel(
matrixRoom,
livekitRoom,
encrypted,
connectionStateObservable,
);
}
Expand Down
Loading

0 comments on commit d3fa33b

Please sign in to comment.