diff --git a/public/locales/en-GB/app.json b/public/locales/en-GB/app.json index 6dd6e72b..14ee2185 100644 --- a/public/locales/en-GB/app.json +++ b/public/locales/en-GB/app.json @@ -5,7 +5,6 @@ "{{count}} stars|other": "{{count}} stars", "{{displayName}} is presenting": "{{displayName}} is presenting", "{{displayName}}, your call has ended.": "{{displayName}}, your call has ended.", - "{{names, list(style: short;)}}": "{{names, list(style: short;)}}", "<0><1>You may withdraw consent by unchecking this box. If you are currently in a call, this setting will take effect at the end of the call.": "<0><1>You may withdraw consent by unchecking this box. If you are currently in a call, this setting will take effect at the end of the call.", "<0>Already have an account?<1><0>Log in Or <2>Access as a guest": "<0>Already have an account?<1><0>Log in Or <2>Access as a guest", "<0>Create an account Or <2>Access as a guest": "<0>Create an account Or <2>Access as a guest", @@ -74,6 +73,7 @@ "Not now, return to home screen": "Not now, return to home screen", "Not registered yet? <2>Create an account": "Not registered yet? <2>Create an account", "Open in the app": "Open in the app", + "Participants": "Participants", "Password": "Password", "Passwords must match": "Passwords must match", "Profile": "Profile", diff --git a/src/Facepile.tsx b/src/Facepile.tsx deleted file mode 100644 index 7ed995ce..00000000 --- a/src/Facepile.tsx +++ /dev/null @@ -1,66 +0,0 @@ -/* -Copyright 2022 New Vector Ltd - -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. -*/ - -import { HTMLAttributes } from "react"; -import { MatrixClient } from "matrix-js-sdk/src/client"; -import { RoomMember } from "matrix-js-sdk/src/models/room-member"; -import { useTranslation } from "react-i18next"; -import { AvatarStack } from "@vector-im/compound-web"; - -import { Avatar, Size } from "./Avatar"; - -interface Props extends HTMLAttributes { - className?: string; - client: MatrixClient; - members: RoomMember[]; - max?: number; - size?: Size | number; -} - -export function Facepile({ - className, - client, - members, - max = 3, - size = Size.XS, - ...rest -}: Props) { - const { t } = useTranslation(); - - const displayedMembers = members.slice(0, max); - - return ( - m.name), - })} - {...rest} - > - {displayedMembers.map((member, i) => { - const avatarUrl = member.getMxcAvatarUrl(); - return ( - - ); - })} - - ); -} diff --git a/src/Header.module.css b/src/Header.module.css index 4f36182d..bb66034b 100644 --- a/src/Header.module.css +++ b/src/Header.module.css @@ -111,7 +111,6 @@ limitations under the License. display: flex; align-items: center; gap: var(--cpd-space-1-5x); - font: var(--cpd-font-body-sm-medium); } @media (min-width: 800px) { diff --git a/src/Header.tsx b/src/Header.tsx index 7c2937cf..2f98c83f 100644 --- a/src/Header.tsx +++ b/src/Header.tsx @@ -18,13 +18,12 @@ import classNames from "classnames"; import { FC, HTMLAttributes, ReactNode } from "react"; import { Link } from "react-router-dom"; import { useTranslation } from "react-i18next"; -import { MatrixClient, RoomMember } from "matrix-js-sdk/src/matrix"; -import { Heading } from "@vector-im/compound-web"; +import { Heading, Text } from "@vector-im/compound-web"; +import { ReactComponent as UserProfileIcon } from "@vector-im/compound-design-tokens/icons/user-profile.svg"; import styles from "./Header.module.css"; import Logo from "./icons/Logo.svg?react"; import { Avatar, Size } from "./Avatar"; -import { Facepile } from "./Facepile"; import { EncryptionLock } from "./room/EncryptionLock"; import { useMediaQuery } from "./useMediaQuery"; @@ -118,8 +117,7 @@ interface RoomHeaderInfoProps { name: string; avatarUrl: string | null; encrypted: boolean; - participants: RoomMember[]; - client: MatrixClient; + participantCount: number; } export const RoomHeaderInfo: FC = ({ @@ -127,8 +125,7 @@ export const RoomHeaderInfo: FC = ({ name, avatarUrl, encrypted, - participants, - client, + participantCount, }) => { const { t } = useTranslation(); const size = useMediaQuery("(max-width: 550px)") ? "sm" : "lg"; @@ -153,10 +150,16 @@ export const RoomHeaderInfo: FC = ({ - {participants.length > 0 && ( + {participantCount > 0 && (
- - {t("{{count, number}}", { count: participants.length })} + + + {t("{{count, number}}", { count: participantCount })} +
)} diff --git a/src/room/GroupCallView.tsx b/src/room/GroupCallView.tsx index ab96926a..eade3f52 100644 --- a/src/room/GroupCallView.tsx +++ b/src/room/GroupCallView.tsx @@ -20,7 +20,7 @@ import { MatrixClient } from "matrix-js-sdk/src/client"; import { Room, isE2EESupported } from "livekit-client"; import { logger } from "matrix-js-sdk/src/logger"; import { MatrixRTCSession } from "matrix-js-sdk/src/matrixrtc/MatrixRTCSession"; -import { JoinRule, RoomMember } from "matrix-js-sdk/src/matrix"; +import { JoinRule } from "matrix-js-sdk/src/matrix"; import { Heading, Link, Text } from "@vector-im/compound-web"; import { useTranslation } from "react-i18next"; @@ -111,18 +111,11 @@ export function GroupCallView({ client, ]); - const participatingMembers = useMemo(() => { - const members: RoomMember[] = []; - // Count each member only once, regardless of how many devices they use - const addedUserIds = new Set(); - for (const membership of memberships) { - if (!addedUserIds.has(membership.member.userId)) { - addedUserIds.add(membership.member.userId); - members.push(membership.member); - } - } - return members; - }, [memberships]); + // Count each member only once, regardless of how many devices they use + const participantCount = useMemo( + () => new Set(memberships.map((m) => m.member.userId)).size, + [memberships] + ); const deviceContext = useMediaDevices(); const latestDevices = useRef(); @@ -340,7 +333,7 @@ export function GroupCallView({ client={client} matrixInfo={matrixInfo} rtcSession={rtcSession} - participatingMembers={participatingMembers} + participantCount={participantCount} onLeave={onLeave} hideHeader={hideHeader} muteStates={muteStates} @@ -391,7 +384,7 @@ export function GroupCallView({ onEnter={() => enterRTCSession(rtcSession)} confineToRoom={confineToRoom} hideHeader={hideHeader} - participatingMembers={participatingMembers} + participantCount={participantCount} onShareClick={onShareClick} /> diff --git a/src/room/InCallView.tsx b/src/room/InCallView.tsx index bab0da04..9c96cc76 100644 --- a/src/room/InCallView.tsx +++ b/src/room/InCallView.tsx @@ -120,7 +120,7 @@ export interface InCallViewProps { rtcSession: MatrixRTCSession; livekitRoom: Room; muteStates: MuteStates; - participatingMembers: RoomMember[]; + participantCount: number; onLeave: (error?: Error) => void; hideHeader: boolean; otelGroupCallMembership?: OTelGroupCallMembership; @@ -134,7 +134,7 @@ export function InCallView({ rtcSession, livekitRoom, muteStates, - participatingMembers, + participantCount, onLeave, hideHeader, otelGroupCallMembership, @@ -411,8 +411,7 @@ export function InCallView({ name={matrixInfo.roomName} avatarUrl={matrixInfo.roomAvatar} encrypted={matrixInfo.roomEncrypted} - participants={participatingMembers} - client={client} + participantCount={participantCount} /> diff --git a/src/room/LobbyView.tsx b/src/room/LobbyView.tsx index fe8ccd9d..7703206b 100644 --- a/src/room/LobbyView.tsx +++ b/src/room/LobbyView.tsx @@ -16,7 +16,7 @@ limitations under the License. import { FC, useCallback, useState } from "react"; import { useTranslation } from "react-i18next"; -import { MatrixClient, RoomMember } from "matrix-js-sdk/src/matrix"; +import { MatrixClient } from "matrix-js-sdk/src/matrix"; import { Button, Link } from "@vector-im/compound-web"; import classNames from "classnames"; import { useHistory } from "react-router-dom"; @@ -44,7 +44,7 @@ interface Props { onEnter: () => void; confineToRoom: boolean; hideHeader: boolean; - participatingMembers: RoomMember[]; + participantCount: number; onShareClick: (() => void) | null; } @@ -55,7 +55,7 @@ export const LobbyView: FC = ({ onEnter, confineToRoom, hideHeader, - participatingMembers, + participantCount, onShareClick, }) => { const { t } = useTranslation(); @@ -104,8 +104,7 @@ export const LobbyView: FC = ({ name={matrixInfo.roomName} avatarUrl={matrixInfo.roomAvatar} encrypted={matrixInfo.roomEncrypted} - participants={participatingMembers} - client={client} + participantCount={participantCount} />