Join existing call modal

This commit is contained in:
Robert Long 2021-12-17 15:01:59 -08:00
parent 591211f698
commit 8203715bc0
5 changed files with 88 additions and 104 deletions

View File

@ -28,7 +28,6 @@ import {
GroupCallType,
} from "matrix-js-sdk/src/browser-index";
import { useHistory } from "react-router-dom";
import { randomString } from "matrix-js-sdk/src/randomstring";
const ClientContext = createContext();
@ -432,7 +431,7 @@ export function useClient() {
return useContext(ClientContext);
}
function roomAliasFromRoomName(roomName) {
export function roomAliasFromRoomName(roomName) {
return roomName
.trim()
.replace(/\s/g, "-")
@ -485,41 +484,6 @@ export async function createRoom(client, name) {
return room_alias || room_id;
}
export function useCreateRoom() {
const { register, client } = useClient();
const [creatingRoom, setCreatingRoom] = useState(false);
const [createRoomError, setCreateRoomError] = useState();
const onCreateRoom = useCallback(
(roomName, userName) => {
async function onCreateRoom(roomName, userName) {
let _client = client;
if (!_client) {
_client = await register(userName, randomString(16), true);
}
return await createRoom(_client, roomName);
}
setCreateRoomError(undefined);
setCreatingRoom(true);
return onCreateRoom(roomName, userName).catch((error) => {
setCreateRoomError(error);
setCreatingRoom(false);
});
},
[register, client]
);
return {
creatingRoom,
createRoomError,
createRoom: onCreateRoom,
};
}
export function useLoadGroupCall(client, roomId, viaServers) {
const [state, setState] = useState({
loading: true,

View File

@ -14,13 +14,14 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import React, { useCallback } from "react";
import React, { useCallback, useState } from "react";
import { useHistory, Link } from "react-router-dom";
import {
useClient,
useGroupCallRooms,
usePublicRooms,
useCreateRoom,
createRoom,
roomAliasFromRoomName,
} from "./ConferenceCallManagerHooks";
import { Header, HeaderLogo, LeftNav, RightNav } from "./Header";
import styles from "./Home.module.css";
@ -30,6 +31,9 @@ import { Button } from "./button";
import { CallList } from "./CallList";
import classNames from "classnames";
import { ErrorView, LoadingView } from "./FullScreenView";
import { useModalTriggerState } from "./Modal";
import { randomString } from "matrix-js-sdk/src/randomstring";
import { JoinExistingCallModal } from "./JoinExistingCallModal";
export function Home() {
const {
@ -39,10 +43,14 @@ export function Home() {
loading,
error,
client,
register,
} = useClient();
const history = useHistory();
const { createRoomError, creatingRoom, createRoom } = useCreateRoom();
const [creatingRoom, setCreatingRoom] = useState(false);
const [createRoomError, setCreateRoomError] = useState();
const { modalState, modalProps } = useModalTriggerState();
const [existingRoomId, setExistingRoomId] = useState();
const onCreateRoom = useCallback(
(e) => {
@ -51,13 +59,36 @@ export function Home() {
const roomName = data.get("roomName");
const userName = data.get("userName");
createRoom(roomName, userName).then((roomIdOrAlias) => {
async function onCreateRoom() {
let _client = client;
if (!_client) {
_client = await register(userName, randomString(16), true);
}
const roomIdOrAlias = await createRoom(_client, roomName);
if (roomIdOrAlias) {
history.push(`/room/${roomIdOrAlias}`);
}
}
setCreateRoomError(undefined);
setCreatingRoom(true);
return onCreateRoom().catch((error) => {
if (error.errcode === "M_ROOM_IN_USE") {
setExistingRoomId(roomAliasFromRoomName(roomName));
setCreateRoomError(undefined);
modalState.open();
} else {
setCreateRoomError(error);
}
setCreatingRoom(false);
});
},
[history]
[client, history, register]
);
const onJoinRoom = useCallback(
@ -70,30 +101,39 @@ export function Home() {
[history]
);
const onJoinExistingRoom = useCallback(() => {
history.push(`/${existingRoomId}`);
}, [history, existingRoomId]);
if (loading) {
return <LoadingView />;
} else if (error || createRoomError) {
return <ErrorView error={error || createRoomError} />;
} else if (!isAuthenticated || isGuest) {
return (
<UnregisteredView
onCreateRoom={onCreateRoom}
createRoomError={createRoomError}
creatingRoom={creatingRoom}
onJoinRoom={onJoinRoom}
/>
);
} else if (error) {
return <ErrorView error={error} />;
} else {
return (
<RegisteredView
client={client}
isPasswordlessUser={isPasswordlessUser}
isGuest={isGuest}
onCreateRoom={onCreateRoom}
createRoomError={createRoomError}
creatingRoom={creatingRoom}
onJoinRoom={onJoinRoom}
/>
<>
{!isAuthenticated || isGuest ? (
<UnregisteredView
onCreateRoom={onCreateRoom}
createRoomError={createRoomError}
creatingRoom={creatingRoom}
onJoinRoom={onJoinRoom}
/>
) : (
<RegisteredView
client={client}
isPasswordlessUser={isPasswordlessUser}
isGuest={isGuest}
onCreateRoom={onCreateRoom}
createRoomError={createRoomError}
creatingRoom={creatingRoom}
onJoinRoom={onJoinRoom}
/>
)}
{modalState.isOpen && (
<JoinExistingCallModal onJoin={onJoinExistingRoom} {...modalProps} />
)}
</>
);
}
}

View File

@ -0,0 +1,19 @@
import React from "react";
import { Modal, ModalContent } from "./Modal";
import { Button } from "./button";
import { FieldRow } from "./Input";
import styles from "./JoinExistingCallModal.module.css";
export function JoinExistingCallModal({ onJoin, ...rest }) {
return (
<Modal title="Join existing call?" isDismissable {...rest}>
<ModalContent>
<p>This call already exists, would you like to join?</p>
<FieldRow rightAlign className={styles.buttons}>
<Button onPress={rest.onClose}>No</Button>
<Button onPress={onJoin}>Yes, join call</Button>
</FieldRow>
</ModalContent>
</Modal>
);
}

View File

@ -0,0 +1,3 @@
.buttons {
margin-bottom: 0;
}

View File

@ -1,42 +0,0 @@
/*
Copyright 2018 New Vector Ltd
Copyright 2019 The Matrix.org Foundation C.I.C.
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.
*/
const LOWERCASE = "abcdefghijklmnopqrstuvwxyz";
const UPPERCASE = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const DIGITS = "0123456789";
export function randomString(len) {
return randomStringFrom(len, UPPERCASE + LOWERCASE + DIGITS);
}
export function randomLowercaseString(len) {
return randomStringFrom(len, LOWERCASE);
}
export function randomUppercaseString(len) {
return randomStringFrom(len, UPPERCASE);
}
function randomStringFrom(len, chars) {
let ret = "";
for (let i = 0; i < len; ++i) {
ret += chars.charAt(Math.floor(Math.random() * chars.length));
}
return ret;
}