From 619e3c4852cbd630ab0497d37746a11309896cc7 Mon Sep 17 00:00:00 2001 From: Timo K Date: Thu, 7 Jul 2022 23:40:29 +0200 Subject: [PATCH 1/5] form --- src/form/{Form.jsx => Form.tsx} | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) rename src/form/{Form.jsx => Form.tsx} (72%) diff --git a/src/form/Form.jsx b/src/form/Form.tsx similarity index 72% rename from src/form/Form.jsx rename to src/form/Form.tsx index 011fbb26..fbe7fe00 100644 --- a/src/form/Form.jsx +++ b/src/form/Form.tsx @@ -16,12 +16,15 @@ limitations under the License. import classNames from "classnames"; import React, { forwardRef } from "react"; + import styles from "./Form.module.css"; -export const Form = forwardRef(({ children, className, ...rest }, ref) => { - return ( -
- {children} -
- ); -}); +export const Form = forwardRef( + ({ children, className, ...rest }, ref) => { + return ( +
+ {children} +
+ ); + } +); From e17a7cedb6cf01889532f099fb885e03b40efd80 Mon Sep 17 00:00:00 2001 From: Timo K Date: Thu, 14 Jul 2022 19:20:52 +0200 Subject: [PATCH 2/5] form_home --- src/ClientContext.tsx | 1 + src/button/CopyButton.tsx | 4 +-- src/home/{CallList.jsx => CallList.tsx} | 25 ++++++++++++---- src/home/{HomePage.jsx => HomePage.tsx} | 0 ...allModal.jsx => JoinExistingCallModal.tsx} | 12 ++++++-- ...{RegisteredView.jsx => RegisteredView.tsx} | 18 +++++++----- ...GroupCallRooms.js => useGroupCallRooms.ts} | 29 ++++++++++++++----- 7 files changed, 64 insertions(+), 25 deletions(-) rename src/home/{CallList.jsx => CallList.tsx} (81%) rename src/home/{HomePage.jsx => HomePage.tsx} (100%) rename src/home/{JoinExistingCallModal.jsx => JoinExistingCallModal.tsx} (79%) rename src/home/{RegisteredView.jsx => RegisteredView.tsx} (91%) rename src/home/{useGroupCallRooms.js => useGroupCallRooms.ts} (72%) diff --git a/src/ClientContext.tsx b/src/ClientContext.tsx index 09d910b5..ee4fef0a 100644 --- a/src/ClientContext.tsx +++ b/src/ClientContext.tsx @@ -59,6 +59,7 @@ interface ClientState { isPasswordlessUser: boolean; client: MatrixClient; userName: string; + error: Error; changePassword: (password: string) => Promise; logout: () => void; setClient: (client: MatrixClient, session: Session) => void; diff --git a/src/button/CopyButton.tsx b/src/button/CopyButton.tsx index 480cd444..87c58da3 100644 --- a/src/button/CopyButton.tsx +++ b/src/button/CopyButton.tsx @@ -23,10 +23,10 @@ import { Button, ButtonVariant } from "./Button"; interface Props { value: string; - children: JSX.Element; + children?: JSX.Element; className: string; variant: ButtonVariant; - copiedMessage: string; + copiedMessage?: string; } export function CopyButton({ value, diff --git a/src/home/CallList.jsx b/src/home/CallList.tsx similarity index 81% rename from src/home/CallList.jsx rename to src/home/CallList.tsx index e4badf26..c9c29d84 100644 --- a/src/home/CallList.jsx +++ b/src/home/CallList.tsx @@ -16,14 +16,22 @@ limitations under the License. import React from "react"; import { Link } from "react-router-dom"; +import { MatrixClient, Room, RoomMember } from "matrix-js-sdk"; + import { CopyButton } from "../button"; import { Facepile } from "../Facepile"; -import { Avatar } from "../Avatar"; +import { Avatar, Size } from "../Avatar"; import styles from "./CallList.module.css"; import { getRoomUrl } from "../matrix-utils"; import { Body, Caption } from "../typography/Typography"; +import { GroupCallRoom } from "./useGroupCallRooms"; -export function CallList({ rooms, client, disableFacepile }) { +interface CallListProps { + rooms: GroupCallRoom[]; + client: MatrixClient; + disableFacepile: boolean; +} +export function CallList({ rooms, client, disableFacepile }: CallListProps) { return ( <>
@@ -48,7 +56,14 @@ export function CallList({ rooms, client, disableFacepile }) { ); } - +interface CallTileProps { + name: string; + avatarUrl: string; + roomId: string; + participants: RoomMember[]; + client: MatrixClient; + disableFacepile: boolean; +} function CallTile({ name, avatarUrl, @@ -56,12 +71,12 @@ function CallTile({ participants, client, disableFacepile, -}) { +}: CallTileProps) { return (
void; + onClose: (e: PressEvent) => void; + [index: string]: unknown; +} +export function JoinExistingCallModal({ onJoin, onClose, ...rest }: Props) { return (

This call already exists, would you like to join?

- +
diff --git a/src/home/RegisteredView.jsx b/src/home/RegisteredView.tsx similarity index 91% rename from src/home/RegisteredView.jsx rename to src/home/RegisteredView.tsx index 1d07d1c7..5f826a7e 100644 --- a/src/home/RegisteredView.jsx +++ b/src/home/RegisteredView.tsx @@ -15,6 +15,9 @@ limitations under the License. */ import React, { useState, useCallback } from "react"; +import { useHistory } from "react-router-dom"; +import { MatrixClient } from "matrix-js-sdk"; + import { createRoom, roomAliasLocalpartFromRoomName } from "../matrix-utils"; import { useGroupCallRooms } from "./useGroupCallRooms"; import { Header, HeaderLogo, LeftNav, RightNav } from "../Header"; @@ -26,21 +29,23 @@ import { CallList } from "./CallList"; import { UserMenuContainer } from "../UserMenuContainer"; import { useModalTriggerState } from "../Modal"; import { JoinExistingCallModal } from "./JoinExistingCallModal"; -import { useHistory } from "react-router-dom"; import { Title } from "../typography/Typography"; import { Form } from "../form/Form"; import { CallType, CallTypeDropdown } from "./CallTypeDropdown"; -export function RegisteredView({ client }) { +export function RegisteredView({ client }: { client: MatrixClient }) { const [callType, setCallType] = useState(CallType.Video); const [loading, setLoading] = useState(false); - const [error, setError] = useState(); + const [error, setError] = useState(); const history = useHistory(); + const { modalState, modalProps } = useModalTriggerState(); + const onSubmit = useCallback( (e) => { e.preventDefault(); const data = new FormData(e.target); - const roomName = data.get("callName"); + const roomNameData = data.get("callName"); + const roomName = typeof roomNameData === "string" ? roomNameData : ""; const ptt = callType === CallType.Radio; async function submit() { @@ -68,13 +73,12 @@ export function RegisteredView({ client }) { } }); }, - [client, callType] + [callType, client, history, modalState] ); const recentRooms = useGroupCallRooms(client); - const { modalState, modalProps } = useModalTriggerState(); - const [existingRoomId, setExistingRoomId] = useState(); + const [existingRoomId, setExistingRoomId] = useState(); const onJoinExistingRoom = useCallback(() => { history.push(`/${existingRoomId}`); }, [history, existingRoomId]); diff --git a/src/home/useGroupCallRooms.js b/src/home/useGroupCallRooms.ts similarity index 72% rename from src/home/useGroupCallRooms.js rename to src/home/useGroupCallRooms.ts index 4177a5fe..cf15a267 100644 --- a/src/home/useGroupCallRooms.js +++ b/src/home/useGroupCallRooms.ts @@ -14,11 +14,21 @@ See the License for the specific language governing permissions and limitations under the License. */ +import { GroupCall, MatrixClient, Room, RoomMember } from "matrix-js-sdk"; +import { GroupCallEventHandlerEvent } from "matrix-js-sdk/src/webrtc/groupCallEventHandler"; import { useState, useEffect } from "react"; -const tsCache = {}; +export interface GroupCallRoom { + roomId: string; + roomName: string; + avatarUrl: string; + room: Room; + groupCall: GroupCall; + participants: RoomMember[]; +} +const tsCache: { [index: string]: number } = {}; -function getLastTs(client, r) { +function getLastTs(client: MatrixClient, r: Room) { if (tsCache[r.roomId]) { return tsCache[r.roomId]; } @@ -59,13 +69,13 @@ function getLastTs(client, r) { return ts; } -function sortRooms(client, rooms) { +function sortRooms(client: MatrixClient, rooms: Room[]): Room[] { return rooms.sort((a, b) => { return getLastTs(client, b) - getLastTs(client, a); }); } -export function useGroupCallRooms(client) { +export function useGroupCallRooms(client: MatrixClient): GroupCallRoom[] { const [rooms, setRooms] = useState([]); useEffect(() => { @@ -90,12 +100,15 @@ export function useGroupCallRooms(client) { updateRooms(); - client.on("GroupCall.incoming", updateRooms); - client.on("GroupCall.participants", updateRooms); + client.on(GroupCallEventHandlerEvent.Incoming, updateRooms); + client.on(GroupCallEventHandlerEvent.Participants, updateRooms); return () => { - client.removeListener("GroupCall.incoming", updateRooms); - client.removeListener("GroupCall.participants", updateRooms); + client.removeListener(GroupCallEventHandlerEvent.Incoming, updateRooms); + client.removeListener( + GroupCallEventHandlerEvent.Participants, + updateRooms + ); }; }, [client]); From 3727bfb67fedaac27fea60dcbac28ae638480f8b Mon Sep 17 00:00:00 2001 From: Timo K Date: Thu, 28 Jul 2022 00:17:09 +0200 Subject: [PATCH 3/5] more types --- src/form/Form.tsx | 27 ++++++++++++++++++--------- src/home/CallList.tsx | 2 +- src/home/HomePage.tsx | 1 + src/home/JoinExistingCallModal.tsx | 1 + src/home/RegisteredView.tsx | 26 +++++++++++++++++--------- 5 files changed, 38 insertions(+), 19 deletions(-) diff --git a/src/form/Form.tsx b/src/form/Form.tsx index fbe7fe00..944724bb 100644 --- a/src/form/Form.tsx +++ b/src/form/Form.tsx @@ -15,16 +15,25 @@ limitations under the License. */ import classNames from "classnames"; -import React, { forwardRef } from "react"; +import React, { FormEventHandler, forwardRef } from "react"; import styles from "./Form.module.css"; -export const Form = forwardRef( - ({ children, className, ...rest }, ref) => { - return ( -
- {children} -
- ); +export const Form = forwardRef< + HTMLFormElement, + { + className: string; + onSubmit: FormEventHandler; + children: JSX.Element[]; } -); +>(({ children, className, onSubmit }, ref) => { + return ( +
+ {children} +
+ ); +}); diff --git a/src/home/CallList.tsx b/src/home/CallList.tsx index c9c29d84..b7611aa2 100644 --- a/src/home/CallList.tsx +++ b/src/home/CallList.tsx @@ -16,7 +16,7 @@ limitations under the License. import React from "react"; import { Link } from "react-router-dom"; -import { MatrixClient, Room, RoomMember } from "matrix-js-sdk"; +import { MatrixClient, RoomMember } from "matrix-js-sdk"; import { CopyButton } from "../button"; import { Facepile } from "../Facepile"; diff --git a/src/home/HomePage.tsx b/src/home/HomePage.tsx index 89c9ecec..00f770fd 100644 --- a/src/home/HomePage.tsx +++ b/src/home/HomePage.tsx @@ -15,6 +15,7 @@ limitations under the License. */ import React from "react"; + import { useClient } from "../ClientContext"; import { ErrorView, LoadingView } from "../FullScreenView"; import { UnauthenticatedView } from "./UnauthenticatedView"; diff --git a/src/home/JoinExistingCallModal.tsx b/src/home/JoinExistingCallModal.tsx index 36b508fc..0c17ede0 100644 --- a/src/home/JoinExistingCallModal.tsx +++ b/src/home/JoinExistingCallModal.tsx @@ -24,6 +24,7 @@ import styles from "./JoinExistingCallModal.module.css"; interface Props { onJoin: (e: PressEvent) => void; onClose: (e: PressEvent) => void; + // TODO: add used parameters for [index: string]: unknown; } export function JoinExistingCallModal({ onJoin, onClose, ...rest }: Props) { diff --git a/src/home/RegisteredView.tsx b/src/home/RegisteredView.tsx index 8df30ab3..7a87bdc2 100644 --- a/src/home/RegisteredView.tsx +++ b/src/home/RegisteredView.tsx @@ -14,7 +14,12 @@ See the License for the specific language governing permissions and limitations under the License. */ -import React, { useState, useCallback } from "react"; +import React, { + useState, + useCallback, + FormEvent, + FormEventHandler, +} from "react"; import { useHistory } from "react-router-dom"; import { MatrixClient } from "matrix-js-sdk"; @@ -32,27 +37,31 @@ import { JoinExistingCallModal } from "./JoinExistingCallModal"; import { Title } from "../typography/Typography"; import { Form } from "../form/Form"; import { CallType, CallTypeDropdown } from "./CallTypeDropdown"; +interface Props { + client: MatrixClient; + isPasswordlessUser: boolean; +} -export function RegisteredView({ client }: { client: MatrixClient }) { +export function RegisteredView({ client, isPasswordlessUser }: Props) { const [callType, setCallType] = useState(CallType.Video); const [loading, setLoading] = useState(false); const [error, setError] = useState(); const history = useHistory(); const { modalState, modalProps } = useModalTriggerState(); - const onSubmit = useCallback( - (e) => { + const onSubmit: FormEventHandler = useCallback( + (e: FormEvent) => { e.preventDefault(); - const data = new FormData(e.target); + const data = new FormData(e.target as HTMLFormElement); const roomNameData = data.get("callName"); const roomName = typeof roomNameData === "string" ? roomNameData : ""; - const ptt = callType === CallType.Radio; + // const ptt = callType === CallType.Radio; async function submit() { setError(undefined); setLoading(true); - const [roomIdOrAlias] = await createRoom(client, roomName, ptt); + const [roomIdOrAlias] = await createRoom(client, roomName); if (roomIdOrAlias) { history.push(`/room/${roomIdOrAlias}`); @@ -69,11 +78,10 @@ export function RegisteredView({ client }: { client: MatrixClient }) { console.error(error); setLoading(false); setError(error); - reset(); } }); }, - [callType, client, history, modalState] + [client, history, modalState] ); const recentRooms = useGroupCallRooms(client); From 4f36d149d73c03afd5671dd5b323bb8c2deeece0 Mon Sep 17 00:00:00 2001 From: Timo K Date: Thu, 28 Jul 2022 00:22:48 +0200 Subject: [PATCH 4/5] make error optional in ClientState --- src/ClientContext.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ClientContext.tsx b/src/ClientContext.tsx index ca2a659d..5e0c3c1c 100644 --- a/src/ClientContext.tsx +++ b/src/ClientContext.tsx @@ -59,10 +59,10 @@ interface ClientState { isPasswordlessUser: boolean; client: MatrixClient; userName: string; - error: Error; changePassword: (password: string) => Promise; logout: () => void; setClient: (client: MatrixClient, session: Session) => void; + error?: Error; } const ClientContext = createContext(null); From cb5b3e946811af701688039586e14b436d9030f7 Mon Sep 17 00:00:00 2001 From: Timo K Date: Fri, 29 Jul 2022 15:07:35 +0200 Subject: [PATCH 5/5] review changes --- src/form/Form.tsx | 35 +++++++++++++++--------------- src/home/CallList.tsx | 4 ++-- src/home/JoinExistingCallModal.tsx | 1 + src/home/RegisteredView.tsx | 1 + 4 files changed, 22 insertions(+), 19 deletions(-) diff --git a/src/form/Form.tsx b/src/form/Form.tsx index 944724bb..55dadaed 100644 --- a/src/form/Form.tsx +++ b/src/form/Form.tsx @@ -19,21 +19,22 @@ import React, { FormEventHandler, forwardRef } from "react"; import styles from "./Form.module.css"; -export const Form = forwardRef< - HTMLFormElement, - { - className: string; - onSubmit: FormEventHandler; - children: JSX.Element[]; +interface FormProps { + className: string; + onSubmit: FormEventHandler; + children: JSX.Element[]; +} + +export const Form = forwardRef( + ({ children, className, onSubmit }, ref) => { + return ( +
+ {children} +
+ ); } ->(({ children, className, onSubmit }, ref) => { - return ( -
- {children} -
- ); -}); +); diff --git a/src/home/CallList.tsx b/src/home/CallList.tsx index b7611aa2..8b257234 100644 --- a/src/home/CallList.tsx +++ b/src/home/CallList.tsx @@ -29,7 +29,7 @@ import { GroupCallRoom } from "./useGroupCallRooms"; interface CallListProps { rooms: GroupCallRoom[]; client: MatrixClient; - disableFacepile: boolean; + disableFacepile?: boolean; } export function CallList({ rooms, client, disableFacepile }: CallListProps) { return ( @@ -62,7 +62,7 @@ interface CallTileProps { roomId: string; participants: RoomMember[]; client: MatrixClient; - disableFacepile: boolean; + disableFacepile?: boolean; } function CallTile({ name, diff --git a/src/home/JoinExistingCallModal.tsx b/src/home/JoinExistingCallModal.tsx index 0c17ede0..b26c45d9 100644 --- a/src/home/JoinExistingCallModal.tsx +++ b/src/home/JoinExistingCallModal.tsx @@ -21,6 +21,7 @@ import { Modal, ModalContent } from "../Modal"; import { Button } from "../button"; import { FieldRow } from "../input/Input"; import styles from "./JoinExistingCallModal.module.css"; + interface Props { onJoin: (e: PressEvent) => void; onClose: (e: PressEvent) => void; diff --git a/src/home/RegisteredView.tsx b/src/home/RegisteredView.tsx index 7a87bdc2..4d190dde 100644 --- a/src/home/RegisteredView.tsx +++ b/src/home/RegisteredView.tsx @@ -37,6 +37,7 @@ import { JoinExistingCallModal } from "./JoinExistingCallModal"; import { Title } from "../typography/Typography"; import { Form } from "../form/Form"; import { CallType, CallTypeDropdown } from "./CallTypeDropdown"; + interface Props { client: MatrixClient; isPasswordlessUser: boolean;