form_home
This commit is contained in:
		
					parent
					
						
							
								619e3c4852
							
						
					
				
			
			
				commit
				
					
						e17a7cedb6
					
				
			
		
					 7 changed files with 64 additions and 25 deletions
				
			
		| 
						 | 
					@ -59,6 +59,7 @@ interface ClientState {
 | 
				
			||||||
  isPasswordlessUser: boolean;
 | 
					  isPasswordlessUser: boolean;
 | 
				
			||||||
  client: MatrixClient;
 | 
					  client: MatrixClient;
 | 
				
			||||||
  userName: string;
 | 
					  userName: string;
 | 
				
			||||||
 | 
					  error: Error;
 | 
				
			||||||
  changePassword: (password: string) => Promise<void>;
 | 
					  changePassword: (password: string) => Promise<void>;
 | 
				
			||||||
  logout: () => void;
 | 
					  logout: () => void;
 | 
				
			||||||
  setClient: (client: MatrixClient, session: Session) => void;
 | 
					  setClient: (client: MatrixClient, session: Session) => void;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -23,10 +23,10 @@ import { Button, ButtonVariant } from "./Button";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
interface Props {
 | 
					interface Props {
 | 
				
			||||||
  value: string;
 | 
					  value: string;
 | 
				
			||||||
  children: JSX.Element;
 | 
					  children?: JSX.Element;
 | 
				
			||||||
  className: string;
 | 
					  className: string;
 | 
				
			||||||
  variant: ButtonVariant;
 | 
					  variant: ButtonVariant;
 | 
				
			||||||
  copiedMessage: string;
 | 
					  copiedMessage?: string;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
export function CopyButton({
 | 
					export function CopyButton({
 | 
				
			||||||
  value,
 | 
					  value,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -16,14 +16,22 @@ limitations under the License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import React from "react";
 | 
					import React from "react";
 | 
				
			||||||
import { Link } from "react-router-dom";
 | 
					import { Link } from "react-router-dom";
 | 
				
			||||||
 | 
					import { MatrixClient, Room, RoomMember } from "matrix-js-sdk";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { CopyButton } from "../button";
 | 
					import { CopyButton } from "../button";
 | 
				
			||||||
import { Facepile } from "../Facepile";
 | 
					import { Facepile } from "../Facepile";
 | 
				
			||||||
import { Avatar } from "../Avatar";
 | 
					import { Avatar, Size } from "../Avatar";
 | 
				
			||||||
import styles from "./CallList.module.css";
 | 
					import styles from "./CallList.module.css";
 | 
				
			||||||
import { getRoomUrl } from "../matrix-utils";
 | 
					import { getRoomUrl } from "../matrix-utils";
 | 
				
			||||||
import { Body, Caption } from "../typography/Typography";
 | 
					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 (
 | 
					  return (
 | 
				
			||||||
    <>
 | 
					    <>
 | 
				
			||||||
      <div className={styles.callList}>
 | 
					      <div className={styles.callList}>
 | 
				
			||||||
| 
						 | 
					@ -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({
 | 
					function CallTile({
 | 
				
			||||||
  name,
 | 
					  name,
 | 
				
			||||||
  avatarUrl,
 | 
					  avatarUrl,
 | 
				
			||||||
| 
						 | 
					@ -56,12 +71,12 @@ function CallTile({
 | 
				
			||||||
  participants,
 | 
					  participants,
 | 
				
			||||||
  client,
 | 
					  client,
 | 
				
			||||||
  disableFacepile,
 | 
					  disableFacepile,
 | 
				
			||||||
}) {
 | 
					}: CallTileProps) {
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <div className={styles.callTile}>
 | 
					    <div className={styles.callTile}>
 | 
				
			||||||
      <Link to={`/room/${roomId}`} className={styles.callTileLink}>
 | 
					      <Link to={`/room/${roomId}`} className={styles.callTileLink}>
 | 
				
			||||||
        <Avatar
 | 
					        <Avatar
 | 
				
			||||||
          size="lg"
 | 
					          size={Size.LG}
 | 
				
			||||||
          bgKey={name}
 | 
					          bgKey={name}
 | 
				
			||||||
          src={avatarUrl}
 | 
					          src={avatarUrl}
 | 
				
			||||||
          fallback={name.slice(0, 1).toUpperCase()}
 | 
					          fallback={name.slice(0, 1).toUpperCase()}
 | 
				
			||||||
| 
						 | 
					@ -15,18 +15,24 @@ limitations under the License.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import React from "react";
 | 
					import React from "react";
 | 
				
			||||||
 | 
					import { PressEvent } from "@react-types/shared";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { Modal, ModalContent } from "../Modal";
 | 
					import { Modal, ModalContent } from "../Modal";
 | 
				
			||||||
import { Button } from "../button";
 | 
					import { Button } from "../button";
 | 
				
			||||||
import { FieldRow } from "../input/Input";
 | 
					import { FieldRow } from "../input/Input";
 | 
				
			||||||
import styles from "./JoinExistingCallModal.module.css";
 | 
					import styles from "./JoinExistingCallModal.module.css";
 | 
				
			||||||
 | 
					interface Props {
 | 
				
			||||||
export function JoinExistingCallModal({ onJoin, ...rest }) {
 | 
					  onJoin: (e: PressEvent) => void;
 | 
				
			||||||
 | 
					  onClose: (e: PressEvent) => void;
 | 
				
			||||||
 | 
					  [index: string]: unknown;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					export function JoinExistingCallModal({ onJoin, onClose, ...rest }: Props) {
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <Modal title="Join existing call?" isDismissable {...rest}>
 | 
					    <Modal title="Join existing call?" isDismissable {...rest}>
 | 
				
			||||||
      <ModalContent>
 | 
					      <ModalContent>
 | 
				
			||||||
        <p>This call already exists, would you like to join?</p>
 | 
					        <p>This call already exists, would you like to join?</p>
 | 
				
			||||||
        <FieldRow rightAlign className={styles.buttons}>
 | 
					        <FieldRow rightAlign className={styles.buttons}>
 | 
				
			||||||
          <Button onPress={rest.onClose}>No</Button>
 | 
					          <Button onPress={onClose}>No</Button>
 | 
				
			||||||
          <Button onPress={onJoin}>Yes, join call</Button>
 | 
					          <Button onPress={onJoin}>Yes, join call</Button>
 | 
				
			||||||
        </FieldRow>
 | 
					        </FieldRow>
 | 
				
			||||||
      </ModalContent>
 | 
					      </ModalContent>
 | 
				
			||||||
| 
						 | 
					@ -15,6 +15,9 @@ limitations under the License.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import React, { useState, useCallback } from "react";
 | 
					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 { createRoom, roomAliasLocalpartFromRoomName } from "../matrix-utils";
 | 
				
			||||||
import { useGroupCallRooms } from "./useGroupCallRooms";
 | 
					import { useGroupCallRooms } from "./useGroupCallRooms";
 | 
				
			||||||
import { Header, HeaderLogo, LeftNav, RightNav } from "../Header";
 | 
					import { Header, HeaderLogo, LeftNav, RightNav } from "../Header";
 | 
				
			||||||
| 
						 | 
					@ -26,21 +29,23 @@ import { CallList } from "./CallList";
 | 
				
			||||||
import { UserMenuContainer } from "../UserMenuContainer";
 | 
					import { UserMenuContainer } from "../UserMenuContainer";
 | 
				
			||||||
import { useModalTriggerState } from "../Modal";
 | 
					import { useModalTriggerState } from "../Modal";
 | 
				
			||||||
import { JoinExistingCallModal } from "./JoinExistingCallModal";
 | 
					import { JoinExistingCallModal } from "./JoinExistingCallModal";
 | 
				
			||||||
import { useHistory } from "react-router-dom";
 | 
					 | 
				
			||||||
import { Title } from "../typography/Typography";
 | 
					import { Title } from "../typography/Typography";
 | 
				
			||||||
import { Form } from "../form/Form";
 | 
					import { Form } from "../form/Form";
 | 
				
			||||||
import { CallType, CallTypeDropdown } from "./CallTypeDropdown";
 | 
					import { CallType, CallTypeDropdown } from "./CallTypeDropdown";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function RegisteredView({ client }) {
 | 
					export function RegisteredView({ client }: { client: MatrixClient }) {
 | 
				
			||||||
  const [callType, setCallType] = useState(CallType.Video);
 | 
					  const [callType, setCallType] = useState(CallType.Video);
 | 
				
			||||||
  const [loading, setLoading] = useState(false);
 | 
					  const [loading, setLoading] = useState(false);
 | 
				
			||||||
  const [error, setError] = useState();
 | 
					  const [error, setError] = useState<Error>();
 | 
				
			||||||
  const history = useHistory();
 | 
					  const history = useHistory();
 | 
				
			||||||
 | 
					  const { modalState, modalProps } = useModalTriggerState();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const onSubmit = useCallback(
 | 
					  const onSubmit = useCallback(
 | 
				
			||||||
    (e) => {
 | 
					    (e) => {
 | 
				
			||||||
      e.preventDefault();
 | 
					      e.preventDefault();
 | 
				
			||||||
      const data = new FormData(e.target);
 | 
					      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;
 | 
					      const ptt = callType === CallType.Radio;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      async function submit() {
 | 
					      async function submit() {
 | 
				
			||||||
| 
						 | 
					@ -68,13 +73,12 @@ export function RegisteredView({ client }) {
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      });
 | 
					      });
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    [client, callType]
 | 
					    [callType, client, history, modalState]
 | 
				
			||||||
  );
 | 
					  );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const recentRooms = useGroupCallRooms(client);
 | 
					  const recentRooms = useGroupCallRooms(client);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const { modalState, modalProps } = useModalTriggerState();
 | 
					  const [existingRoomId, setExistingRoomId] = useState<string>();
 | 
				
			||||||
  const [existingRoomId, setExistingRoomId] = useState();
 | 
					 | 
				
			||||||
  const onJoinExistingRoom = useCallback(() => {
 | 
					  const onJoinExistingRoom = useCallback(() => {
 | 
				
			||||||
    history.push(`/${existingRoomId}`);
 | 
					    history.push(`/${existingRoomId}`);
 | 
				
			||||||
  }, [history, existingRoomId]);
 | 
					  }, [history, existingRoomId]);
 | 
				
			||||||
| 
						 | 
					@ -14,11 +14,21 @@ See the License for the specific language governing permissions and
 | 
				
			||||||
limitations under the License.
 | 
					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";
 | 
					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]) {
 | 
					  if (tsCache[r.roomId]) {
 | 
				
			||||||
    return tsCache[r.roomId];
 | 
					    return tsCache[r.roomId];
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
| 
						 | 
					@ -59,13 +69,13 @@ function getLastTs(client, r) {
 | 
				
			||||||
  return ts;
 | 
					  return ts;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function sortRooms(client, rooms) {
 | 
					function sortRooms(client: MatrixClient, rooms: Room[]): Room[] {
 | 
				
			||||||
  return rooms.sort((a, b) => {
 | 
					  return rooms.sort((a, b) => {
 | 
				
			||||||
    return getLastTs(client, b) - getLastTs(client, a);
 | 
					    return getLastTs(client, b) - getLastTs(client, a);
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function useGroupCallRooms(client) {
 | 
					export function useGroupCallRooms(client: MatrixClient): GroupCallRoom[] {
 | 
				
			||||||
  const [rooms, setRooms] = useState([]);
 | 
					  const [rooms, setRooms] = useState([]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  useEffect(() => {
 | 
					  useEffect(() => {
 | 
				
			||||||
| 
						 | 
					@ -90,12 +100,15 @@ export function useGroupCallRooms(client) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    updateRooms();
 | 
					    updateRooms();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    client.on("GroupCall.incoming", updateRooms);
 | 
					    client.on(GroupCallEventHandlerEvent.Incoming, updateRooms);
 | 
				
			||||||
    client.on("GroupCall.participants", updateRooms);
 | 
					    client.on(GroupCallEventHandlerEvent.Participants, updateRooms);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return () => {
 | 
					    return () => {
 | 
				
			||||||
      client.removeListener("GroupCall.incoming", updateRooms);
 | 
					      client.removeListener(GroupCallEventHandlerEvent.Incoming, updateRooms);
 | 
				
			||||||
      client.removeListener("GroupCall.participants", updateRooms);
 | 
					      client.removeListener(
 | 
				
			||||||
 | 
					        GroupCallEventHandlerEvent.Participants,
 | 
				
			||||||
 | 
					        updateRooms
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
  }, [client]);
 | 
					  }, [client]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue