Merge pull request #1471 from robintown/remove-walkie-talkie

Fully remove walkie-talkie mode
This commit is contained in:
Robin
2023-09-18 12:03:38 -04:00
committed by GitHub
12 changed files with 29 additions and 176 deletions

View File

@@ -22,7 +22,6 @@
"By clicking \"Join call now\", you agree to our <2>End User Licensing Agreement (EULA)</2>": "By clicking \"Join call now\", you agree to our <2>End User Licensing Agreement (EULA)</2>",
"By participating in this beta, you consent to the collection of anonymous data, which we use to improve the product. You can find more information about which data we track in our <2>Privacy Policy</2> and our <5>Cookie Policy</5>.": "By participating in this beta, you consent to the collection of anonymous data, which we use to improve the product. You can find more information about which data we track in our <2>Privacy Policy</2> and our <5>Cookie Policy</5>.",
"Call link copied": "Call link copied",
"Call type menu": "Call type menu",
"Camera": "Camera",
"Close": "Close",
"Confirm password": "Confirm password",
@@ -68,6 +67,7 @@
"Microphone on": "Microphone on",
"More": "More",
"Mute microphone": "Mute microphone",
"Name of call": "Name of call",
"No": "No",
"Not encrypted": "Not encrypted",
"Not now, return to home screen": "Not now, return to home screen",
@@ -101,6 +101,7 @@
"Sign out": "Sign out",
"Speaker": "Speaker",
"Spotlight": "Spotlight",
"Start new call": "Start new call",
"Start video": "Start video",
"Stop video": "Stop video",
"Submit": "Submit",
@@ -116,14 +117,9 @@
"Username": "Username",
"Version: {{version}}": "Version: {{version}}",
"Video": "Video",
"Video call": "Video call",
"Video call name": "Video call name",
"Waiting for other participants…": "Waiting for other participants…",
"Walkie-talkie call": "Walkie-talkie call",
"Walkie-talkie call name": "Walkie-talkie call name",
"Yes, join call": "Yes, join call",
"You": "You",
"You were disconnected from the call": "You were disconnected from the call",
"Your feedback": "Your feedback",
"Your recent calls": "Your recent calls"
"Your feedback": "Your feedback"
}

View File

@@ -31,7 +31,7 @@ import { ReactComponent as CloseIcon } from "@vector-im/compound-design-tokens/i
import classNames from "classnames";
import { Heading } from "@vector-im/compound-web";
import styles from "./NewModal.module.css";
import styles from "./Modal.module.css";
import { useMediaQuery } from "./useMediaQuery";
import { Glass } from "./Glass";

View File

@@ -43,10 +43,6 @@ interface UrlParams {
* Whether to hide the screen-sharing button.
*/
hideScreensharing: boolean;
/**
* Whether to start a walkie-talkie call instead of a video call.
*/
isPtt: boolean;
/**
* Whether to use end-to-end encryption.
*/
@@ -195,7 +191,6 @@ export const getUrlParams = (
preload: hasParam("preload"),
hideHeader: hasParam("hideHeader"),
hideScreensharing: hasParam("hideScreensharing"),
isPtt: hasParam("ptt"),
e2eEnabled: getParam("enableE2e") !== "false", // Defaults to true
userId: getParam("userId"),
displayName: getParam("displayName"),

View File

@@ -1,19 +0,0 @@
/*
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.
*/
.label {
margin-bottom: 0;
}

View File

@@ -1,85 +0,0 @@
/*
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 { FC } from "react";
import { Item } from "@react-stately/collections";
import { useTranslation } from "react-i18next";
import { Headline } from "../typography/Typography";
import { Button } from "../button";
import { PopoverMenuTrigger } from "../popover/PopoverMenu";
import { ReactComponent as VideoIcon } from "../icons/Video.svg";
import { ReactComponent as MicIcon } from "../icons/Mic.svg";
import { ReactComponent as CheckIcon } from "../icons/Check.svg";
import styles from "./CallTypeDropdown.module.css";
import commonStyles from "./common.module.css";
import menuStyles from "../Menu.module.css";
import { Menu } from "../Menu";
export enum CallType {
Video = "video",
Radio = "radio",
}
interface Props {
callType: CallType;
setCallType: (value: CallType) => void;
}
export const CallTypeDropdown: FC<Props> = ({ callType, setCallType }) => {
const { t } = useTranslation();
const onAction = (key: React.Key) => {
setCallType(key.toString() as CallType);
};
const onClose = () => {};
return (
<PopoverMenuTrigger placement="bottom">
<Button variant="dropdown" className={commonStyles.headline}>
<Headline className={styles.label}>
{callType === CallType.Video
? t("Video call")
: t("Walkie-talkie call")}
</Headline>
</Button>
{(props: JSX.IntrinsicAttributes) => (
<Menu
{...props}
label={t("Call type menu")}
onAction={onAction}
onClose={onClose}
>
<Item key={CallType.Video} textValue={t("Video call")}>
<VideoIcon />
<span>{t("Video call")}</span>
{callType === CallType.Video && (
<CheckIcon className={menuStyles.checkIcon} />
)}
</Item>
<Item key={CallType.Radio} textValue={t("Walkie-talkie call")}>
<MicIcon />
<span>{t("Walkie-talkie call")}</span>
{callType === CallType.Radio && (
<CheckIcon className={menuStyles.checkIcon} />
)}
</Item>
</Menu>
)}
</PopoverMenuTrigger>
);
};

View File

@@ -34,10 +34,7 @@ export function HomePage() {
return <ErrorView error={clientState.error} />;
} else {
return clientState.authenticated ? (
<RegisteredView
isPasswordlessUser={clientState.authenticated.isPasswordlessUser}
client={clientState.authenticated.client}
/>
<RegisteredView client={clientState.authenticated.client} />
) : (
<UnauthenticatedView />
);

View File

@@ -19,6 +19,7 @@ import { useHistory } from "react-router-dom";
import { MatrixClient } from "matrix-js-sdk/src/client";
import { randomString } from "matrix-js-sdk/src/randomstring";
import { useTranslation } from "react-i18next";
import { Heading } from "@vector-im/compound-web";
import {
createRoom,
@@ -34,9 +35,8 @@ import { Button } from "../button";
import { CallList } from "./CallList";
import { UserMenuContainer } from "../UserMenuContainer";
import { JoinExistingCallModal } from "./JoinExistingCallModal";
import { Caption, Title } from "../typography/Typography";
import { Caption } from "../typography/Typography";
import { Form } from "../form/Form";
import { CallType, CallTypeDropdown } from "./CallTypeDropdown";
import { useEnableE2EE, useOptInAnalytics } from "../settings/useSetting";
import { AnalyticsNotice } from "../analytics/AnalyticsNotice";
import { E2EEBanner } from "../E2EEBanner";
@@ -45,11 +45,9 @@ import { getRoomSharedKeyLocalStorageKey } from "../e2ee/sharedKeyManagement";
interface Props {
client: MatrixClient;
isPasswordlessUser: boolean;
}
export function RegisteredView({ client, isPasswordlessUser }: Props) {
const [callType, setCallType] = useState(CallType.Video);
export function RegisteredView({ client }: Props) {
const [loading, setLoading] = useState(false);
const [error, setError] = useState<Error>();
const [optInAnalytics] = useOptInAnalytics();
@@ -72,14 +70,13 @@ export function RegisteredView({ client, isPasswordlessUser }: Props) {
typeof roomNameData === "string"
? sanitiseRoomNameInput(roomNameData)
: "";
const ptt = callType === CallType.Radio;
async function submit() {
setError(undefined);
setLoading(true);
const roomId = (
await createRoom(client, roomName, ptt, e2eeEnabled ?? false)
await createRoom(client, roomName, e2eeEnabled ?? false)
)[1];
if (e2eeEnabled) {
@@ -105,7 +102,7 @@ export function RegisteredView({ client, isPasswordlessUser }: Props) {
}
});
},
[client, history, setJoinExistingCallModalOpen, callType, e2eeEnabled]
[client, history, setJoinExistingCallModalOpen, e2eeEnabled]
);
const recentRooms = useGroupCallRooms(client);
@@ -115,11 +112,6 @@ export function RegisteredView({ client, isPasswordlessUser }: Props) {
history.push(`/${existingAlias}`);
}, [history, existingAlias]);
const callNameLabel =
callType === CallType.Video
? t("Video call name")
: t("Walkie-talkie call name");
return (
<>
<Header>
@@ -133,14 +125,16 @@ export function RegisteredView({ client, isPasswordlessUser }: Props) {
<div className={commonStyles.container}>
<main className={commonStyles.main}>
<HeaderLogo className={commonStyles.logo} />
<CallTypeDropdown callType={callType} setCallType={setCallType} />
<Heading size="lg" weight="semibold">
{t("Start new call")}
</Heading>
<Form className={styles.form} onSubmit={onSubmit}>
<FieldRow className={styles.fieldRow}>
<InputField
id="callName"
name="callName"
label={callNameLabel}
placeholder={callNameLabel}
label={t("Name of call")}
placeholder={t("Name of call")}
type="text"
required
autoComplete="off"
@@ -170,12 +164,7 @@ export function RegisteredView({ client, isPasswordlessUser }: Props) {
)}
</Form>
{recentRooms.length > 0 && (
<>
<Title className={styles.recentCallsTitle}>
{t("Your recent calls")}
</Title>
<CallList rooms={recentRooms} client={client} />
</>
<CallList rooms={recentRooms} client={client} />
)}
</main>
</div>

View File

@@ -18,6 +18,7 @@ import { FC, useCallback, useState, FormEventHandler } from "react";
import { useHistory } from "react-router-dom";
import { randomString } from "matrix-js-sdk/src/randomstring";
import { Trans, useTranslation } from "react-i18next";
import { Heading } from "@vector-im/compound-web";
import { useClient } from "../ClientContext";
import { Header, HeaderLogo, LeftNav, RightNav } from "../Header";
@@ -34,7 +35,6 @@ import { JoinExistingCallModal } from "./JoinExistingCallModal";
import { useRecaptcha } from "../auth/useRecaptcha";
import { Body, Caption, Link } from "../typography/Typography";
import { Form } from "../form/Form";
import { CallType, CallTypeDropdown } from "./CallTypeDropdown";
import styles from "./UnauthenticatedView.module.css";
import commonStyles from "./common.module.css";
import { generateRandomName } from "../auth/generateRandomName";
@@ -47,7 +47,6 @@ import { setLocalStorageItem } from "../useLocalStorage";
export const UnauthenticatedView: FC = () => {
const { setClient } = useClient();
const [callType, setCallType] = useState(CallType.Video);
const [loading, setLoading] = useState(false);
const [error, setError] = useState<Error>();
const [optInAnalytics] = useOptInAnalytics();
@@ -72,7 +71,6 @@ export const UnauthenticatedView: FC = () => {
const data = new FormData(e.target as HTMLFormElement);
const roomName = sanitiseRoomNameInput(data.get("callName") as string);
const displayName = data.get("displayName") as string;
const ptt = callType === CallType.Radio;
async function submit() {
setError(undefined);
@@ -90,7 +88,7 @@ export const UnauthenticatedView: FC = () => {
let roomId: string;
try {
roomId = (
await createRoom(client, roomName, ptt, e2eeEnabled ?? false)
await createRoom(client, roomName, e2eeEnabled ?? false)
)[1];
if (e2eeEnabled) {
@@ -142,18 +140,12 @@ export const UnauthenticatedView: FC = () => {
reset,
execute,
history,
callType,
setJoinExistingCallModalOpen,
setClient,
e2eeEnabled,
]
);
const callNameLabel =
callType === CallType.Video
? t("Video call name")
: t("Walkie-talkie call name");
return (
<>
<Header>
@@ -167,14 +159,16 @@ export const UnauthenticatedView: FC = () => {
<div className={commonStyles.container}>
<main className={commonStyles.main}>
<HeaderLogo className={commonStyles.logo} />
<CallTypeDropdown callType={callType} setCallType={setCallType} />
<Heading size="lg" weight="semibold">
{t("Start new call")}
</Heading>
<Form className={styles.form} onSubmit={onSubmit}>
<FieldRow>
<InputField
id="callName"
name="callName"
label={callNameLabel}
placeholder={callNameLabel}
label={t("Name of call")}
placeholder={t("Name of call")}
type="text"
required
autoComplete="off"

View File

@@ -272,7 +272,6 @@ export function isLocalRoomId(roomId: string, client: MatrixClient): boolean {
export async function createRoom(
client: MatrixClient,
name: string,
ptt: boolean,
e2ee: boolean
): Promise<[string, string]> {
logger.log(`Creating room for group call`);
@@ -327,14 +326,12 @@ export async function createRoom(
const result = await createPromise;
logger.log(
`Creating ${ptt ? "PTT" : "video"} group call in ${result.room_id}`
);
logger.log(`Creating group call in ${result.room_id}`);
await client.createGroupCall(
result.room_id,
ptt ? GroupCallType.Voice : GroupCallType.Video,
ptt,
GroupCallType.Video,
false,
GroupCallIntent.Room,
true
);

View File

@@ -27,7 +27,6 @@ interface Props {
roomIdOrAlias: string;
viaServers: string[];
children: (rtcSession: MatrixRTCSession) => ReactNode;
createPtt: boolean;
}
export function GroupCallLoader({
@@ -35,15 +34,9 @@ export function GroupCallLoader({
roomIdOrAlias,
viaServers,
children,
createPtt,
}: Props): JSX.Element {
const { t } = useTranslation();
const groupCallState = useLoadGroupCall(
client,
roomIdOrAlias,
viaServers,
createPtt
);
const groupCallState = useLoadGroupCall(client, roomIdOrAlias, viaServers);
switch (groupCallState.kind) {
case "loading":

View File

@@ -37,7 +37,6 @@ export const RoomPage: FC = () => {
isEmbedded,
preload,
hideHeader,
isPtt,
displayName,
} = useUrlParams();
const roomIdOrAlias = roomId ?? roomAlias;
@@ -104,7 +103,6 @@ export const RoomPage: FC = () => {
client={client}
roomIdOrAlias={roomIdOrAlias}
viaServers={viaServers}
createPtt={isPtt}
>
{groupCallView}
</GroupCallLoader>

View File

@@ -56,8 +56,7 @@ export interface GroupCallLoadState {
export const useLoadGroupCall = (
client: MatrixClient,
roomIdOrAlias: string,
viaServers: string[],
createPtt: boolean
viaServers: string[]
): GroupCallStatus => {
const { t } = useTranslation();
const [state, setState] = useState<GroupCallStatus>({ kind: "loading" });
@@ -101,7 +100,6 @@ export const useLoadGroupCall = (
const [, roomId] = await createRoom(
client,
roomNameFromRoomId(roomIdOrAlias),
createPtt,
e2eeEnabled ?? false
);
@@ -151,7 +149,7 @@ export const useLoadGroupCall = (
.then(fetchOrCreateGroupCall)
.then((rtcSession) => setState({ kind: "loaded", rtcSession }))
.catch((error) => setState({ kind: "failed", error }));
}, [client, roomIdOrAlias, viaServers, createPtt, t, e2eeEnabled]);
}, [client, roomIdOrAlias, viaServers, t, e2eeEnabled]);
return state;
};