Merge remote-tracking branch 'origin/livekit' into dbkr/matrixrtcsession
This commit is contained in:
@@ -23,8 +23,7 @@ import {
|
||||
useTracks,
|
||||
} from "@livekit/components-react";
|
||||
import { usePreventScroll } from "@react-aria/overlays";
|
||||
import classNames from "classnames";
|
||||
import { Room, Track, ConnectionState } from "livekit-client";
|
||||
import { ConnectionState, Room, Track } from "livekit-client";
|
||||
import { MatrixClient } from "matrix-js-sdk/src/client";
|
||||
import { RoomMember } from "matrix-js-sdk/src/models/room-member";
|
||||
import { Room as MatrixRoom } from "matrix-js-sdk/src/models/room";
|
||||
@@ -32,10 +31,11 @@ import { Ref, useCallback, useEffect, useMemo, useRef } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import useMeasure from "react-use-measure";
|
||||
import { OverlayTriggerState } from "@react-stately/overlays";
|
||||
import { JoinRule } from "matrix-js-sdk/src/@types/partials";
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
import { MatrixRTCSession } from "matrix-js-sdk/src/matrixrtc/MatrixRTCSession";
|
||||
|
||||
import { ReactComponent as LogoMark } from "../icons/LogoMark.svg";
|
||||
import { ReactComponent as LogoType } from "../icons/LogoType.svg";
|
||||
import type { IWidgetApiRequest } from "matrix-widget-api";
|
||||
import {
|
||||
HangupButton,
|
||||
@@ -43,7 +43,6 @@ import {
|
||||
VideoButton,
|
||||
ScreenshareButton,
|
||||
SettingsButton,
|
||||
InviteButton,
|
||||
} from "../button";
|
||||
import { Header, LeftNav, RightNav, RoomHeaderInfo } from "../Header";
|
||||
import {
|
||||
@@ -58,26 +57,24 @@ import { useUrlParams } from "../UrlParams";
|
||||
import { useCallViewKeyboardShortcuts } from "../useCallViewKeyboardShortcuts";
|
||||
import { usePrefersReducedMotion } from "../usePrefersReducedMotion";
|
||||
import { ElementWidgetActions, widget } from "../widget";
|
||||
import { GridLayoutMenu } from "./GridLayoutMenu";
|
||||
import styles from "./InCallView.module.css";
|
||||
import { useJoinRule } from "./useJoinRule";
|
||||
import { ItemData, TileContent, VideoTile } from "../video-grid/VideoTile";
|
||||
import { NewVideoGrid } from "../video-grid/NewVideoGrid";
|
||||
import { OTelGroupCallMembership } from "../otel/OTelGroupCallMembership";
|
||||
import { SettingsModal } from "../settings/SettingsModal";
|
||||
import { InviteModal } from "./InviteModal";
|
||||
import { useRageshakeRequestModal } from "../settings/submit-rageshake";
|
||||
import { RageshakeRequestModal } from "./RageshakeRequestModal";
|
||||
import { E2EEConfig, useLiveKit } from "../livekit/useLiveKit";
|
||||
import { useFullscreen } from "./useFullscreen";
|
||||
import { useLayoutStates } from "../video-grid/Layout";
|
||||
import { E2EELock } from "../E2EELock";
|
||||
import { useWakeLock } from "../useWakeLock";
|
||||
import { useMergedRefs } from "../useMergedRefs";
|
||||
import { MuteStates } from "./MuteStates";
|
||||
import { useIsRoomE2EE } from "../e2ee/sharedKeyManagement";
|
||||
import { useOpenIDSFU } from "../livekit/openIDSFU";
|
||||
import { MatrixInfo } from "./VideoPreview";
|
||||
import { ShareButton } from "../button/ShareButton";
|
||||
import { LayoutToggle } from "./LayoutToggle";
|
||||
import { ECConnectionState } from "../livekit/useECConnectionState";
|
||||
import { useOpenIDSFU } from "../livekit/openIDSFU";
|
||||
|
||||
const canScreenshare = "getDisplayMedia" in (navigator.mediaDevices ?? {});
|
||||
// There is currently a bug in Safari our our code with cloning and sending MediaStreams
|
||||
@@ -115,24 +112,30 @@ export function ActiveCall(props: ActiveCallProps) {
|
||||
|
||||
export interface InCallViewProps {
|
||||
client: MatrixClient;
|
||||
matrixInfo: MatrixInfo;
|
||||
rtcSession: MatrixRTCSession;
|
||||
livekitRoom: Room;
|
||||
muteStates: MuteStates;
|
||||
participatingMembers: RoomMember[];
|
||||
onLeave: (error?: Error) => void;
|
||||
hideHeader: boolean;
|
||||
otelGroupCallMembership?: OTelGroupCallMembership;
|
||||
connState: ECConnectionState;
|
||||
onShareClick: (() => void) | null;
|
||||
}
|
||||
|
||||
export function InCallView({
|
||||
client,
|
||||
matrixInfo,
|
||||
rtcSession,
|
||||
livekitRoom,
|
||||
muteStates,
|
||||
participatingMembers,
|
||||
onLeave,
|
||||
hideHeader,
|
||||
otelGroupCallMembership,
|
||||
connState,
|
||||
onShareClick,
|
||||
}: InCallViewProps) {
|
||||
const { t } = useTranslation();
|
||||
usePreventScroll();
|
||||
@@ -146,8 +149,6 @@ export function InCallView({
|
||||
}
|
||||
}, [connState, onLeave]);
|
||||
|
||||
const isRoomE2EE = useIsRoomE2EE(rtcSession.room.roomId);
|
||||
|
||||
const containerRef1 = useRef<HTMLDivElement | null>(null);
|
||||
const [containerRef2, bounds] = useMeasure({ polyfill: ResizeObserver });
|
||||
const boundsValid = bounds.height > 0;
|
||||
@@ -182,8 +183,6 @@ export function InCallView({
|
||||
[muteStates]
|
||||
);
|
||||
|
||||
const joinRule = useJoinRule(rtcSession.room);
|
||||
|
||||
// This function incorrectly assumes that there is a camera and microphone, which is not always the case.
|
||||
// TODO: Make sure that this module is resilient when it comes to camera/microphone availability!
|
||||
useCallViewKeyboardShortcuts(
|
||||
@@ -199,7 +198,7 @@ export function InCallView({
|
||||
|
||||
useEffect(() => {
|
||||
widget?.api.transport.send(
|
||||
layout === "freedom"
|
||||
layout === "grid"
|
||||
? ElementWidgetActions.TileLayout
|
||||
: ElementWidgetActions.SpotlightLayout,
|
||||
{}
|
||||
@@ -209,7 +208,7 @@ export function InCallView({
|
||||
useEffect(() => {
|
||||
if (widget) {
|
||||
const onTileLayout = async (ev: CustomEvent<IWidgetApiRequest>) => {
|
||||
setLayout("freedom");
|
||||
setLayout("grid");
|
||||
await widget!.api.transport.reply(ev.detail, {});
|
||||
};
|
||||
const onSpotlightLayout = async (ev: CustomEvent<IWidgetApiRequest>) => {
|
||||
@@ -233,7 +232,8 @@ export function InCallView({
|
||||
}
|
||||
}, [setLayout]);
|
||||
|
||||
const reducedControls = boundsValid && bounds.width <= 400;
|
||||
const mobile = boundsValid && bounds.width <= 660;
|
||||
const reducedControls = boundsValid && bounds.width <= 340;
|
||||
const noControls = reducedControls && bounds.height <= 400;
|
||||
|
||||
const items = useParticipantTiles(livekitRoom, rtcSession.room);
|
||||
@@ -253,7 +253,7 @@ export function InCallView({
|
||||
);
|
||||
|
||||
const Grid =
|
||||
items.length > 12 && layout === "freedom" ? NewVideoGrid : VideoGrid;
|
||||
items.length > 12 && layout === "grid" ? NewVideoGrid : VideoGrid;
|
||||
|
||||
const prefersReducedMotion = usePrefersReducedMotion();
|
||||
|
||||
@@ -327,25 +327,6 @@ export function InCallView({
|
||||
settingsModalState.open();
|
||||
}, [settingsModalState]);
|
||||
|
||||
const {
|
||||
modalState: inviteModalState,
|
||||
modalProps: inviteModalProps,
|
||||
}: {
|
||||
modalState: OverlayTriggerState;
|
||||
modalProps: {
|
||||
isOpen: boolean;
|
||||
onClose: () => void;
|
||||
};
|
||||
} = useModalTriggerState();
|
||||
|
||||
const openInvite = useCallback(() => {
|
||||
inviteModalState.open();
|
||||
}, [inviteModalState]);
|
||||
|
||||
const containerClasses = classNames(styles.inRoom, {
|
||||
[styles.maximised]: undefined,
|
||||
});
|
||||
|
||||
const toggleScreensharing = useCallback(async () => {
|
||||
exitFullscreen();
|
||||
await localParticipant.setScreenShareEnabled(!isScreenShareEnabled, {
|
||||
@@ -397,21 +378,43 @@ export function InCallView({
|
||||
buttons.push(
|
||||
<HangupButton key="6" onPress={onLeavePress} data-testid="incall_leave" />
|
||||
);
|
||||
footer = <div className={styles.footer}>{buttons}</div>;
|
||||
footer = (
|
||||
<div className={styles.footer}>
|
||||
{!mobile && !hideHeader && (
|
||||
<div className={styles.logo}>
|
||||
<LogoMark width={24} height={24} />
|
||||
<LogoType width={80} height={11} />
|
||||
</div>
|
||||
)}
|
||||
<div className={styles.buttons}>{buttons}</div>
|
||||
{!mobile && !hideHeader && (
|
||||
<LayoutToggle
|
||||
className={styles.layout}
|
||||
layout={layout}
|
||||
setLayout={setLayout}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={containerClasses} ref={containerRef}>
|
||||
<div className={styles.inRoom} ref={containerRef}>
|
||||
{!hideHeader && maximisedParticipant === null && (
|
||||
<Header>
|
||||
<LeftNav>
|
||||
<RoomHeaderInfo roomName={rtcSession.room.name} />
|
||||
{!isRoomE2EE && <E2EELock />}
|
||||
<RoomHeaderInfo
|
||||
id={matrixInfo.roomId}
|
||||
name={matrixInfo.roomName}
|
||||
avatarUrl={matrixInfo.roomAvatar}
|
||||
encrypted={matrixInfo.roomEncrypted}
|
||||
participants={participatingMembers}
|
||||
client={client}
|
||||
/>
|
||||
</LeftNav>
|
||||
<RightNav>
|
||||
<GridLayoutMenu layout={layout} setLayout={setLayout} />
|
||||
{joinRule === JoinRule.Public && (
|
||||
<InviteButton variant="icon" onClick={openInvite} />
|
||||
{!reducedControls && onShareClick !== null && (
|
||||
<ShareButton onClick={onShareClick} />
|
||||
)}
|
||||
</RightNav>
|
||||
</Header>
|
||||
@@ -442,9 +445,6 @@ export function InCallView({
|
||||
{...settingsModalProps}
|
||||
/>
|
||||
)}
|
||||
{inviteModalState.isOpen && (
|
||||
<InviteModal roomId={rtcSession.room.roomId} {...inviteModalProps} />
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user