Files
element-call/src/home/CallList.tsx
T

111 lines
3.0 KiB
TypeScript
Raw Normal View History

2022-05-04 17:09:48 +01:00
/*
Copyright 2022-2024 New Vector Ltd.
2022-05-04 17:09:48 +01:00
SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
Please see LICENSE in the repository root for full details.
2022-05-04 17:09:48 +01:00
*/
2021-12-07 17:59:55 -08:00
import { Link } from "react-router-dom";
2025-03-13 13:58:43 +01:00
import { type MatrixClient } from "matrix-js-sdk";
import { type RoomMember } from "matrix-js-sdk/src/models/room-member";
import { type Room } from "matrix-js-sdk/src/models/room";
import { type FC, useCallback, type MouseEvent, useState } from "react";
2024-09-12 09:34:07 +02:00
import { useTranslation } from "react-i18next";
import { IconButton, Text } from "@vector-im/compound-web";
2024-09-10 16:21:56 +02:00
import { CloseIcon } from "@vector-im/compound-design-tokens/assets/web/icons";
2024-09-12 09:32:24 +02:00
import classNames from "classnames";
2022-07-14 19:20:52 +02:00
import { Avatar, Size } from "../Avatar";
2021-12-09 12:58:30 -08:00
import styles from "./CallList.module.css";
import { getRelativeRoomUrl } from "../utils/matrix";
import { type GroupCallRoom } from "./useGroupCallRooms";
2024-04-23 15:15:13 +02:00
import { useRoomEncryptionSystem } from "../e2ee/sharedKeyManagement";
2021-12-07 17:59:55 -08:00
2022-07-14 19:20:52 +02:00
interface CallListProps {
rooms: GroupCallRoom[];
client: MatrixClient;
}
2023-09-22 18:05:13 -04:00
export const CallList: FC<CallListProps> = ({ rooms, client }) => {
2021-12-09 12:58:30 -08:00
return (
<>
<div className={styles.callList}>
2023-09-19 17:42:17 +01:00
{rooms.map(({ room, roomName, avatarUrl, participants }) => (
2021-12-09 12:58:30 -08:00
<CallTile
key={room.roomId}
2021-12-20 09:12:28 -08:00
client={client}
2021-12-09 12:58:30 -08:00
name={roomName}
avatarUrl={avatarUrl}
2023-09-19 18:23:44 +01:00
room={room}
2021-12-09 12:58:30 -08:00
participants={participants}
/>
))}
2022-01-05 16:12:58 -08:00
{rooms.length > 3 && (
<>
<div className={styles.callTileSpacer} />
<div className={styles.callTileSpacer} />
</>
)}
2021-12-09 12:58:30 -08:00
</div>
</>
);
2023-09-22 18:05:13 -04:00
};
2022-07-14 19:20:52 +02:00
interface CallTileProps {
name: string;
avatarUrl: string;
2023-09-19 18:23:44 +01:00
room: Room;
2022-07-14 19:20:52 +02:00
participants: RoomMember[];
client: MatrixClient;
}
2023-09-22 18:05:13 -04:00
2024-09-10 13:33:12 +02:00
const CallTile: FC<CallTileProps> = ({ name, avatarUrl, room, client }) => {
2024-09-12 09:34:07 +02:00
const { t } = useTranslation();
2024-04-23 15:15:13 +02:00
const roomEncryptionSystem = useRoomEncryptionSystem(room.roomId);
2024-09-12 09:32:24 +02:00
const [isLeaving, setIsLeaving] = useState(false);
2024-09-10 13:33:12 +02:00
const onRemove = useCallback(
(e: MouseEvent) => {
e.stopPropagation();
e.preventDefault();
2024-09-12 09:32:24 +02:00
setIsLeaving(true);
client.leave(room.roomId).catch(() => setIsLeaving(false));
2024-09-10 13:33:12 +02:00
},
[room, client],
);
2024-09-12 09:32:24 +02:00
const body = (
<>
<Avatar id={room.roomId} name={name} size={Size.LG} src={avatarUrl} />
<div className={styles.callInfo}>
<Text weight="semibold" className={styles.callName}>
2024-09-12 09:32:24 +02:00
{name}
</Text>
2024-09-12 09:32:24 +02:00
</div>
<IconButton
onClick={onRemove}
disabled={isLeaving}
aria-label={t("action.remove")}
>
<CloseIcon />
</IconButton>
</>
);
2021-12-07 17:59:55 -08:00
return (
2021-12-10 14:01:55 -08:00
<div className={styles.callTile}>
2024-09-12 09:32:24 +02:00
{isLeaving ? (
<span className={classNames(styles.callTileLink, styles.disabled)}>
{body}
</span>
) : (
<Link
to={getRelativeRoomUrl(room.roomId, roomEncryptionSystem, room.name)}
className={styles.callTileLink}
>
{body}
</Link>
)}
2021-12-10 14:01:55 -08:00
</div>
2021-12-07 17:59:55 -08:00
);
2023-09-22 18:05:13 -04:00
};