diff --git a/src/ClientContext.tsx b/src/ClientContext.tsx index 503c3f8f..5e0c3c1c 100644 --- a/src/ClientContext.tsx +++ b/src/ClientContext.tsx @@ -62,6 +62,7 @@ interface ClientState { changePassword: (password: string) => Promise; logout: () => void; setClient: (client: MatrixClient, session: Session) => void; + error?: Error; } const ClientContext = createContext(null); 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/form/Form.jsx b/src/form/Form.tsx similarity index 58% rename from src/form/Form.jsx rename to src/form/Form.tsx index 011fbb26..55dadaed 100644 --- a/src/form/Form.jsx +++ b/src/form/Form.tsx @@ -15,13 +15,26 @@ 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} -
- ); -}); +interface FormProps { + className: string; + onSubmit: FormEventHandler; + children: JSX.Element[]; +} + +export const Form = forwardRef( + ({ children, className, onSubmit }, ref) => { + return ( +
+ {children} +
+ ); + } +); 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..8b257234 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, 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; + // TODO: add used parameters for + [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 84% rename from src/home/RegisteredView.jsx rename to src/home/RegisteredView.tsx index b5fef745..4d190dde 100644 --- a/src/home/RegisteredView.jsx +++ b/src/home/RegisteredView.tsx @@ -14,7 +14,15 @@ 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"; + import { createRoom, roomAliasLocalpartFromRoomName } from "../matrix-utils"; import { useGroupCallRooms } from "./useGroupCallRooms"; import { Header, HeaderLogo, LeftNav, RightNav } from "../Header"; @@ -26,28 +34,35 @@ 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 }) { +interface Props { + client: MatrixClient; + isPasswordlessUser: boolean; +} + +export function RegisteredView({ client, isPasswordlessUser }: Props) { const [callType, setCallType] = useState(CallType.Video); const [loading, setLoading] = useState(false); - const [error, setError] = useState(); + const [error, setError] = useState(); const history = useHistory(); - const onSubmit = useCallback( - (e) => { + const { modalState, modalProps } = useModalTriggerState(); + + const onSubmit: FormEventHandler = useCallback( + (e: FormEvent) => { e.preventDefault(); - const data = new FormData(e.target); - const roomName = data.get("callName"); - const ptt = callType === CallType.Radio; + const data = new FormData(e.target as HTMLFormElement); + const roomNameData = data.get("callName"); + const roomName = typeof roomNameData === "string" ? roomNameData : ""; + // 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}`); @@ -64,17 +79,15 @@ export function RegisteredView({ client }) { console.error(error); setLoading(false); setError(error); - reset(); } }); }, - [client, 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]);