mirror of
https://github.com/vector-im/element-call.git
synced 2024-11-15 00:04:59 +08:00
Merge branch 'main' into ts_profile
This commit is contained in:
commit
f990530031
4
.github/workflows/publish.yaml
vendored
4
.github/workflows/publish.yaml
vendored
@ -32,10 +32,14 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
||||||
|
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@dc7b9719a96d48369863986a06765841d7ea23f6
|
||||||
|
|
||||||
- name: Build and push Docker image
|
- name: Build and push Docker image
|
||||||
uses: docker/build-push-action@ad44023a93711e3deb337508980b4b5e9bcdc5dc
|
uses: docker/build-push-action@ad44023a93711e3deb337508980b4b5e9bcdc5dc
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
|
platforms: linux/amd64,linux/arm64
|
||||||
push: true
|
push: true
|
||||||
tags: ${{ steps.meta.outputs.tags }}
|
tags: ${{ steps.meta.outputs.tags }}
|
||||||
labels: ${{ steps.meta.outputs.labels }}
|
labels: ${{ steps.meta.outputs.labels }}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
FROM node:16-buster as builder
|
FROM --platform=$BUILDPLATFORM node:16-buster as builder
|
||||||
|
|
||||||
WORKDIR /src
|
WORKDIR /src
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
"build-storybook": "build-storybook",
|
"build-storybook": "build-storybook",
|
||||||
"prettier:check": "prettier -c src",
|
"prettier:check": "prettier -c src",
|
||||||
"prettier:format": "prettier -w src",
|
"prettier:format": "prettier -w src",
|
||||||
|
"lint": "yarn lint:types && yarn lint:js",
|
||||||
"lint:js": "eslint --max-warnings 0 src",
|
"lint:js": "eslint --max-warnings 0 src",
|
||||||
"lint:types": "tsc"
|
"lint:types": "tsc"
|
||||||
},
|
},
|
||||||
@ -36,7 +37,7 @@
|
|||||||
"classnames": "^2.3.1",
|
"classnames": "^2.3.1",
|
||||||
"color-hash": "^2.0.1",
|
"color-hash": "^2.0.1",
|
||||||
"events": "^3.3.0",
|
"events": "^3.3.0",
|
||||||
"matrix-js-sdk": "github:matrix-org/matrix-js-sdk#aa0d3bd1f5a006d151f826e6b8c5f286abb6e960",
|
"matrix-js-sdk": "github:matrix-org/matrix-js-sdk#404f8e130e44a78b0159c55902df1b129b3816d1",
|
||||||
"mermaid": "^8.13.8",
|
"mermaid": "^8.13.8",
|
||||||
"normalize.css": "^8.0.1",
|
"normalize.css": "^8.0.1",
|
||||||
"pako": "^2.0.4",
|
"pako": "^2.0.4",
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import classNames from "classnames";
|
import classNames from "classnames";
|
||||||
import React, { useRef } from "react";
|
import React, { useCallback, useRef } from "react";
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
import styles from "./Header.module.css";
|
import styles from "./Header.module.css";
|
||||||
import { ReactComponent as Logo } from "./icons/Logo.svg";
|
import { ReactComponent as Logo } from "./icons/Logo.svg";
|
||||||
@ -8,6 +8,9 @@ import { ReactComponent as ArrowLeftIcon } from "./icons/ArrowLeft.svg";
|
|||||||
import { useButton } from "@react-aria/button";
|
import { useButton } from "@react-aria/button";
|
||||||
import { Subtitle } from "./typography/Typography";
|
import { Subtitle } from "./typography/Typography";
|
||||||
import { Avatar } from "./Avatar";
|
import { Avatar } from "./Avatar";
|
||||||
|
import { IncompatibleVersionModal } from "./IncompatibleVersionModal";
|
||||||
|
import { useModalTriggerState } from "./Modal";
|
||||||
|
import { Button } from "./button";
|
||||||
|
|
||||||
export function Header({ children, className, ...rest }) {
|
export function Header({ children, className, ...rest }) {
|
||||||
return (
|
return (
|
||||||
@ -84,3 +87,25 @@ export function RoomSetupHeaderInfo({ roomName, avatarUrl, ...rest }) {
|
|||||||
</button>
|
</button>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function VersionMismatchWarning({ users, room }) {
|
||||||
|
const { modalState, modalProps } = useModalTriggerState();
|
||||||
|
|
||||||
|
const onDetailsClick = useCallback(() => {
|
||||||
|
modalState.open();
|
||||||
|
}, [modalState]);
|
||||||
|
|
||||||
|
if (users.size === 0) return null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<span className={styles.versionMismatchWarning}>
|
||||||
|
Incomaptible versions!
|
||||||
|
<Button variant="link" onClick={onDetailsClick}>
|
||||||
|
Details
|
||||||
|
</Button>
|
||||||
|
{modalState.isOpen && (
|
||||||
|
<IncompatibleVersionModal userIds={users} room={room} {...modalProps} />
|
||||||
|
)}
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
@ -104,6 +104,24 @@
|
|||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.versionMismatchWarning {
|
||||||
|
padding-left: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.versionMismatchWarning::before {
|
||||||
|
content: "";
|
||||||
|
display: inline-block;
|
||||||
|
position: relative;
|
||||||
|
top: 1px;
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
mask-image: url("./icons/AlertTriangleFilled.svg");
|
||||||
|
mask-repeat: no-repeat;
|
||||||
|
mask-size: contain;
|
||||||
|
background-color: var(--alert);
|
||||||
|
padding-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
@media (min-width: 800px) {
|
@media (min-width: 800px) {
|
||||||
.headerLogo,
|
.headerLogo,
|
||||||
.roomAvatar,
|
.roomAvatar,
|
||||||
|
48
src/IncompatibleVersionModal.tsx
Normal file
48
src/IncompatibleVersionModal.tsx
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2022 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.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { Room } from "matrix-js-sdk";
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
|
import { Modal, ModalContent } from "./Modal";
|
||||||
|
import { Body } from "./typography/Typography";
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
userIds: Set<string>;
|
||||||
|
room: Room;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const IncompatibleVersionModal: React.FC<Props> = ({
|
||||||
|
userIds,
|
||||||
|
room,
|
||||||
|
...rest
|
||||||
|
}) => {
|
||||||
|
const userLis = Array.from(userIds).map((u) => (
|
||||||
|
<li>{room.getMember(u).name}</li>
|
||||||
|
));
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Modal title="Incompatible Versions" isDismissable {...rest}>
|
||||||
|
<ModalContent>
|
||||||
|
<Body>
|
||||||
|
Other users are trying to join this call from incompatible versions.
|
||||||
|
These users should ensure that they have refreshed their browsers:
|
||||||
|
<ul>{userLis}</ul>
|
||||||
|
</Body>
|
||||||
|
</ModalContent>
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
};
|
@ -41,6 +41,7 @@ export const variantToClassName = {
|
|||||||
iconCopy: [styles.iconCopyButton],
|
iconCopy: [styles.iconCopyButton],
|
||||||
secondaryHangup: [styles.secondaryHangup],
|
secondaryHangup: [styles.secondaryHangup],
|
||||||
dropdown: [styles.dropdownButton],
|
dropdown: [styles.dropdownButton],
|
||||||
|
link: [styles.linkButton],
|
||||||
};
|
};
|
||||||
|
|
||||||
export const sizeToClassName = {
|
export const sizeToClassName = {
|
||||||
|
@ -207,3 +207,10 @@ limitations under the License.
|
|||||||
.lg {
|
.lg {
|
||||||
height: 40px;
|
height: 40px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.linkButton {
|
||||||
|
background-color: transparent;
|
||||||
|
border: none;
|
||||||
|
color: var(--accent);
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
@ -43,7 +43,7 @@ export const CallTypeDropdown: FC<Props> = ({ callType, setCallType }) => {
|
|||||||
<PopoverMenuTrigger placement="bottom">
|
<PopoverMenuTrigger placement="bottom">
|
||||||
<Button variant="dropdown" className={commonStyles.headline}>
|
<Button variant="dropdown" className={commonStyles.headline}>
|
||||||
<Headline className={styles.label}>
|
<Headline className={styles.label}>
|
||||||
{callType === CallType.Video ? "Video call" : "Radio call"}
|
{callType === CallType.Video ? "Video call" : "Walkie-talkie call"}
|
||||||
</Headline>
|
</Headline>
|
||||||
</Button>
|
</Button>
|
||||||
{(props) => (
|
{(props) => (
|
||||||
@ -55,9 +55,9 @@ export const CallTypeDropdown: FC<Props> = ({ callType, setCallType }) => {
|
|||||||
<CheckIcon className={menuStyles.checkIcon} />
|
<CheckIcon className={menuStyles.checkIcon} />
|
||||||
)}
|
)}
|
||||||
</Item>
|
</Item>
|
||||||
<Item key={CallType.Radio} textValue="Radio call">
|
<Item key={CallType.Radio} textValue="Walkie-talkie call">
|
||||||
<MicIcon />
|
<MicIcon />
|
||||||
<span>Radio call</span>
|
<span>Walkie-talkie call</span>
|
||||||
{callType === CallType.Radio && (
|
{callType === CallType.Radio && (
|
||||||
<CheckIcon className={menuStyles.checkIcon} />
|
<CheckIcon className={menuStyles.checkIcon} />
|
||||||
)}
|
)}
|
||||||
|
@ -80,7 +80,7 @@ export function RegisteredView({ client }) {
|
|||||||
}, [history, existingRoomId]);
|
}, [history, existingRoomId]);
|
||||||
|
|
||||||
const callNameLabel =
|
const callNameLabel =
|
||||||
callType === CallType.Video ? "Video call name" : "Radio call name";
|
callType === CallType.Video ? "Video call name" : "Walkie-talkie call name";
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
@ -104,7 +104,7 @@ export function UnauthenticatedView() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const callNameLabel =
|
const callNameLabel =
|
||||||
callType === CallType.Video ? "Video call name" : "Radio call name";
|
callType === CallType.Video ? "Video call name" : "Walkie-talkie call name";
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
3
src/icons/AlertTriangleFilled.svg
Normal file
3
src/icons/AlertTriangleFilled.svg
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<svg width="20" height="18" viewBox="0 0 20 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M2.47012 18H17.5301C19.0701 18 20.0301 16.33 19.2601 15L11.7301 1.98999C10.9601 0.659993 9.04012 0.659993 8.27012 1.98999L0.740121 15C-0.0298788 16.33 0.930121 18 2.47012 18ZM10.0001 11C9.45012 11 9.00012 10.55 9.00012 9.99999V7.99999C9.00012 7.44999 9.45012 6.99999 10.0001 6.99999C10.5501 6.99999 11.0001 7.44999 11.0001 7.99999V9.99999C11.0001 10.55 10.5501 11 10.0001 11ZM11.0001 15H9.00012V13H11.0001V15Z" fill="#737D8C"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 540 B |
@ -39,7 +39,18 @@ export function Field({ children, className, ...rest }) {
|
|||||||
|
|
||||||
export const InputField = forwardRef(
|
export const InputField = forwardRef(
|
||||||
(
|
(
|
||||||
{ id, label, className, type, checked, prefix, suffix, disabled, ...rest },
|
{
|
||||||
|
id,
|
||||||
|
label,
|
||||||
|
className,
|
||||||
|
type,
|
||||||
|
checked,
|
||||||
|
prefix,
|
||||||
|
suffix,
|
||||||
|
description,
|
||||||
|
disabled,
|
||||||
|
...rest
|
||||||
|
},
|
||||||
ref
|
ref
|
||||||
) => {
|
) => {
|
||||||
return (
|
return (
|
||||||
@ -82,6 +93,7 @@ export const InputField = forwardRef(
|
|||||||
{label}
|
{label}
|
||||||
</label>
|
</label>
|
||||||
{suffix && <span>{suffix}</span>}
|
{suffix && <span>{suffix}</span>}
|
||||||
|
{description && <p className={styles.description}>{description}</p>}
|
||||||
</Field>
|
</Field>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -118,13 +118,15 @@
|
|||||||
.checkboxField {
|
.checkboxField {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
|
flex-wrap: wrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.checkboxField label {
|
.checkboxField label {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
font-size: 13px;
|
font-size: 15px;
|
||||||
|
line-height: 24px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.checkboxField input {
|
.checkboxField input {
|
||||||
@ -176,3 +178,9 @@
|
|||||||
color: var(--alert);
|
color: var(--alert);
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.description {
|
||||||
|
color: var(--secondary-content);
|
||||||
|
margin-left: 26px;
|
||||||
|
width: 100%; /* Ensure that it breaks onto the next row */
|
||||||
|
}
|
||||||
|
@ -33,7 +33,7 @@ export function AudioPreview({
|
|||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<h1>{`${roomName} - Radio Call`}</h1>
|
<h1>{`${roomName} - Walkie-talkie call`}</h1>
|
||||||
<div className={styles.preview}>
|
<div className={styles.preview}>
|
||||||
{state === GroupCallState.LocalCallFeedUninitialized && (
|
{state === GroupCallState.LocalCallFeedUninitialized && (
|
||||||
<Body fontWeight="semiBold" className={styles.microphonePermissions}>
|
<Body fontWeight="semiBold" className={styles.microphonePermissions}>
|
||||||
|
@ -53,6 +53,7 @@ export function GroupCallView({
|
|||||||
screenshareFeeds,
|
screenshareFeeds,
|
||||||
hasLocalParticipant,
|
hasLocalParticipant,
|
||||||
participants,
|
participants,
|
||||||
|
unencryptedEventsFromUsers,
|
||||||
} = useGroupCall(groupCall);
|
} = useGroupCall(groupCall);
|
||||||
|
|
||||||
const avatarUrl = useRoomAvatar(groupCall.room);
|
const avatarUrl = useRoomAvatar(groupCall.room);
|
||||||
@ -112,6 +113,7 @@ export function GroupCallView({
|
|||||||
localScreenshareFeed={localScreenshareFeed}
|
localScreenshareFeed={localScreenshareFeed}
|
||||||
screenshareFeeds={screenshareFeeds}
|
screenshareFeeds={screenshareFeeds}
|
||||||
roomId={roomId}
|
roomId={roomId}
|
||||||
|
unencryptedEventsFromUsers={unencryptedEventsFromUsers}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,13 @@ import {
|
|||||||
VideoButton,
|
VideoButton,
|
||||||
ScreenshareButton,
|
ScreenshareButton,
|
||||||
} from "../button";
|
} from "../button";
|
||||||
import { Header, LeftNav, RightNav, RoomHeaderInfo } from "../Header";
|
import {
|
||||||
|
Header,
|
||||||
|
LeftNav,
|
||||||
|
RightNav,
|
||||||
|
RoomHeaderInfo,
|
||||||
|
VersionMismatchWarning,
|
||||||
|
} from "../Header";
|
||||||
import { VideoGrid, useVideoGridLayout } from "../video-grid/VideoGrid";
|
import { VideoGrid, useVideoGridLayout } from "../video-grid/VideoGrid";
|
||||||
import { VideoTileContainer } from "../video-grid/VideoTileContainer";
|
import { VideoTileContainer } from "../video-grid/VideoTileContainer";
|
||||||
import { GroupCallInspector } from "./GroupCallInspector";
|
import { GroupCallInspector } from "./GroupCallInspector";
|
||||||
@ -59,6 +65,7 @@ export function InCallView({
|
|||||||
isScreensharing,
|
isScreensharing,
|
||||||
screenshareFeeds,
|
screenshareFeeds,
|
||||||
roomId,
|
roomId,
|
||||||
|
unencryptedEventsFromUsers,
|
||||||
}) {
|
}) {
|
||||||
usePreventScroll();
|
usePreventScroll();
|
||||||
const [layout, setLayout] = useVideoGridLayout(screenshareFeeds.length > 0);
|
const [layout, setLayout] = useVideoGridLayout(screenshareFeeds.length > 0);
|
||||||
@ -135,6 +142,10 @@ export function InCallView({
|
|||||||
<Header>
|
<Header>
|
||||||
<LeftNav>
|
<LeftNav>
|
||||||
<RoomHeaderInfo roomName={roomName} avatarUrl={avatarUrl} />
|
<RoomHeaderInfo roomName={roomName} avatarUrl={avatarUrl} />
|
||||||
|
<VersionMismatchWarning
|
||||||
|
users={unencryptedEventsFromUsers}
|
||||||
|
room={groupCall.room}
|
||||||
|
/>
|
||||||
</LeftNav>
|
</LeftNav>
|
||||||
<RightNav>
|
<RightNav>
|
||||||
<GridLayoutMenu layout={layout} setLayout={setLayout} />
|
<GridLayoutMenu layout={layout} setLayout={setLayout} />
|
||||||
|
@ -14,11 +14,14 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { useCallback, useEffect, useState } from "react";
|
import { useCallback, useEffect, useReducer, useState } from "react";
|
||||||
import {
|
import {
|
||||||
GroupCallEvent,
|
GroupCallEvent,
|
||||||
GroupCallState,
|
GroupCallState,
|
||||||
GroupCall,
|
GroupCall,
|
||||||
|
GroupCallErrorCode,
|
||||||
|
GroupCallUnknownDeviceError,
|
||||||
|
GroupCallError,
|
||||||
} from "matrix-js-sdk/src/webrtc/groupCall";
|
} from "matrix-js-sdk/src/webrtc/groupCall";
|
||||||
import { MatrixCall } from "matrix-js-sdk/src/webrtc/call";
|
import { MatrixCall } from "matrix-js-sdk/src/webrtc/call";
|
||||||
import { CallFeed } from "matrix-js-sdk/src/webrtc/callFeed";
|
import { CallFeed } from "matrix-js-sdk/src/webrtc/callFeed";
|
||||||
@ -48,6 +51,7 @@ export interface UseGroupCallType {
|
|||||||
localDesktopCapturerSourceId: string;
|
localDesktopCapturerSourceId: string;
|
||||||
participants: RoomMember[];
|
participants: RoomMember[];
|
||||||
hasLocalParticipant: boolean;
|
hasLocalParticipant: boolean;
|
||||||
|
unencryptedEventsFromUsers: Set<string>;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface State {
|
interface State {
|
||||||
@ -106,6 +110,13 @@ export function useGroupCall(groupCall: GroupCall): UseGroupCallType {
|
|||||||
hasLocalParticipant: false,
|
hasLocalParticipant: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const [unencryptedEventsFromUsers, addUnencryptedEventUser] = useReducer(
|
||||||
|
(state: Set<string>, newVal: string) => {
|
||||||
|
return new Set(state).add(newVal);
|
||||||
|
},
|
||||||
|
new Set<string>()
|
||||||
|
);
|
||||||
|
|
||||||
const updateState = (state: Partial<State>) =>
|
const updateState = (state: Partial<State>) =>
|
||||||
setState((prevState) => ({ ...prevState, ...state }));
|
setState((prevState) => ({ ...prevState, ...state }));
|
||||||
|
|
||||||
@ -180,6 +191,13 @@ export function useGroupCall(groupCall: GroupCall): UseGroupCallType {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function onError(e: GroupCallError): void {
|
||||||
|
if (e.code === GroupCallErrorCode.UnknownDevice) {
|
||||||
|
const unknownDeviceError = e as GroupCallUnknownDeviceError;
|
||||||
|
addUnencryptedEventUser(unknownDeviceError.userId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
groupCall.on(GroupCallEvent.GroupCallStateChanged, onGroupCallStateChanged);
|
groupCall.on(GroupCallEvent.GroupCallStateChanged, onGroupCallStateChanged);
|
||||||
groupCall.on(GroupCallEvent.UserMediaFeedsChanged, onUserMediaFeedsChanged);
|
groupCall.on(GroupCallEvent.UserMediaFeedsChanged, onUserMediaFeedsChanged);
|
||||||
groupCall.on(
|
groupCall.on(
|
||||||
@ -194,6 +212,7 @@ export function useGroupCall(groupCall: GroupCall): UseGroupCallType {
|
|||||||
);
|
);
|
||||||
groupCall.on(GroupCallEvent.CallsChanged, onCallsChanged);
|
groupCall.on(GroupCallEvent.CallsChanged, onCallsChanged);
|
||||||
groupCall.on(GroupCallEvent.ParticipantsChanged, onParticipantsChanged);
|
groupCall.on(GroupCallEvent.ParticipantsChanged, onParticipantsChanged);
|
||||||
|
groupCall.on(GroupCallEvent.Error, onError);
|
||||||
|
|
||||||
updateState({
|
updateState({
|
||||||
error: null,
|
error: null,
|
||||||
@ -242,6 +261,7 @@ export function useGroupCall(groupCall: GroupCall): UseGroupCallType {
|
|||||||
GroupCallEvent.ParticipantsChanged,
|
GroupCallEvent.ParticipantsChanged,
|
||||||
onParticipantsChanged
|
onParticipantsChanged
|
||||||
);
|
);
|
||||||
|
groupCall.removeListener(GroupCallEvent.Error, onError);
|
||||||
groupCall.leave();
|
groupCall.leave();
|
||||||
};
|
};
|
||||||
}, [groupCall]);
|
}, [groupCall]);
|
||||||
@ -319,5 +339,6 @@ export function useGroupCall(groupCall: GroupCall): UseGroupCallType {
|
|||||||
localDesktopCapturerSourceId,
|
localDesktopCapturerSourceId,
|
||||||
participants,
|
participants,
|
||||||
hasLocalParticipant,
|
hasLocalParticipant,
|
||||||
|
unencryptedEventsFromUsers,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -87,9 +87,10 @@ export const SettingsModal = (props) => {
|
|||||||
<FieldRow>
|
<FieldRow>
|
||||||
<InputField
|
<InputField
|
||||||
id="spatialAudio"
|
id="spatialAudio"
|
||||||
label="Spatial audio (experimental)"
|
label="Spatial audio"
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
checked={spatialAudio}
|
checked={spatialAudio}
|
||||||
|
description="This will make a speaker's audio seem as if it is coming from where their tile is positioned on screen. (Experimental feature: this may impact the stability of audio.)"
|
||||||
onChange={(e) => setSpatialAudio(e.target.checked)}
|
onChange={(e) => setSpatialAudio(e.target.checked)}
|
||||||
/>
|
/>
|
||||||
</FieldRow>
|
</FieldRow>
|
||||||
|
@ -8597,9 +8597,9 @@ matrix-events-sdk@^0.0.1-beta.7:
|
|||||||
resolved "https://registry.yarnpkg.com/matrix-events-sdk/-/matrix-events-sdk-0.0.1-beta.7.tgz#5ffe45eba1f67cc8d7c2377736c728b322524934"
|
resolved "https://registry.yarnpkg.com/matrix-events-sdk/-/matrix-events-sdk-0.0.1-beta.7.tgz#5ffe45eba1f67cc8d7c2377736c728b322524934"
|
||||||
integrity sha512-9jl4wtWanUFSy2sr2lCjErN/oC8KTAtaeaozJtrgot1JiQcEI4Rda9OLgQ7nLKaqb4Z/QUx/fR3XpDzm5Jy1JA==
|
integrity sha512-9jl4wtWanUFSy2sr2lCjErN/oC8KTAtaeaozJtrgot1JiQcEI4Rda9OLgQ7nLKaqb4Z/QUx/fR3XpDzm5Jy1JA==
|
||||||
|
|
||||||
"matrix-js-sdk@github:matrix-org/matrix-js-sdk#aa0d3bd1f5a006d151f826e6b8c5f286abb6e960":
|
"matrix-js-sdk@github:matrix-org/matrix-js-sdk#404f8e130e44a78b0159c55902df1b129b3816d1":
|
||||||
version "17.2.0"
|
version "17.2.0"
|
||||||
resolved "https://codeload.github.com/matrix-org/matrix-js-sdk/tar.gz/aa0d3bd1f5a006d151f826e6b8c5f286abb6e960"
|
resolved "https://codeload.github.com/matrix-org/matrix-js-sdk/tar.gz/404f8e130e44a78b0159c55902df1b129b3816d1"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@babel/runtime" "^7.12.5"
|
"@babel/runtime" "^7.12.5"
|
||||||
another-json "^0.2.0"
|
another-json "^0.2.0"
|
||||||
|
Loading…
Reference in New Issue
Block a user