diff --git a/src/components/structures/RightPanel.tsx b/src/components/structures/RightPanel.tsx index 7ad1233b96..644c1cfc41 100644 --- a/src/components/structures/RightPanel.tsx +++ b/src/components/structures/RightPanel.tsx @@ -33,7 +33,7 @@ import { IRightPanelCard, IRightPanelCardState } from "../../stores/right-panel/ import { Action } from "../../dispatcher/actions"; import { XOR } from "../../@types/common"; import ExtensionsCard from "../views/right_panel/ExtensionsCard"; -import MemberListView from "../views/rooms/MemberListView"; +import MemberListView from "../views/rooms/MemberList/MemberListView"; interface BaseProps { overwriteCard?: IRightPanelCard; // used to display a custom card and ignoring the RightPanelStore (used for UserView) diff --git a/src/components/viewmodels/MemberListViewModel.tsx b/src/components/viewmodels/memberlist/MemberListViewModel.tsx similarity index 89% rename from src/components/viewmodels/MemberListViewModel.tsx rename to src/components/viewmodels/memberlist/MemberListViewModel.tsx index 3de73b0f83..511c8c6fb9 100644 --- a/src/components/viewmodels/MemberListViewModel.tsx +++ b/src/components/viewmodels/memberlist/MemberListViewModel.tsx @@ -22,22 +22,22 @@ import { KnownMembership } from "matrix-js-sdk/src/types"; import { useCallback, useContext, useEffect, useMemo, useRef, useState } from "react"; import { throttle } from "lodash"; -import { RoomMember } from "../../models/rooms/RoomMember"; -import { mediaFromMxc } from "../../customisations/Media"; -import UserIdentifierCustomisations from "../../customisations/UserIdentifier"; -import { shouldShowComponent } from "../../customisations/helpers/UIComponents"; -import { UIComponent } from "../../settings/UIFeature"; -import { PresenceState } from "../../models/rooms/PresenceState"; -import { useMatrixClientContext } from "../../contexts/MatrixClientContext"; -import { SDKContext } from "../../contexts/SDKContext"; -import PosthogTrackers from "../../PosthogTrackers"; -import { ButtonEvent } from "../views/elements/AccessibleButton"; -import { inviteToRoom } from "../../utils/room/inviteToRoom"; -import { canInviteTo } from "../../utils/room/canInviteTo"; -import { isValid3pidInvite } from "../../RoomInvite"; -import { ThreePIDInvite } from "../../models/rooms/ThreePIDInvite"; -import { XOR } from "../../@types/common"; -import { useTypedEventEmitter } from "../../hooks/useEventEmitter"; +import { RoomMember } from "../../../models/rooms/RoomMember"; +import { mediaFromMxc } from "../../../customisations/Media"; +import UserIdentifierCustomisations from "../../../customisations/UserIdentifier"; +import { shouldShowComponent } from "../../../customisations/helpers/UIComponents"; +import { UIComponent } from "../../../settings/UIFeature"; +import { PresenceState } from "../../../models/rooms/PresenceState"; +import { useMatrixClientContext } from "../../../contexts/MatrixClientContext"; +import { SDKContext } from "../../../contexts/SDKContext"; +import PosthogTrackers from "../../../PosthogTrackers"; +import { ButtonEvent } from "../../views/elements/AccessibleButton"; +import { inviteToRoom } from "../../../utils/room/inviteToRoom"; +import { canInviteTo } from "../../../utils/room/canInviteTo"; +import { isValid3pidInvite } from "../../../RoomInvite"; +import { ThreePIDInvite } from "../../../models/rooms/ThreePIDInvite"; +import { XOR } from "../../../@types/common"; +import { useTypedEventEmitter } from "../../../hooks/useEventEmitter"; type Member = XOR<{ member: RoomMember }, { threePidInvite: ThreePIDInvite }>; diff --git a/src/components/viewmodels/MemberTileViewModel.tsx b/src/components/viewmodels/memberlist/tiles/MemberTileViewModel.tsx similarity index 81% rename from src/components/viewmodels/MemberTileViewModel.tsx rename to src/components/viewmodels/memberlist/tiles/MemberTileViewModel.tsx index 5c14510c94..e2a32c76db 100644 --- a/src/components/viewmodels/MemberTileViewModel.tsx +++ b/src/components/viewmodels/memberlist/tiles/MemberTileViewModel.tsx @@ -9,26 +9,21 @@ import { useEffect, useMemo, useState } from "react"; import { RoomStateEvent, MatrixEvent, EventType } from "matrix-js-sdk/src/matrix"; import { UserVerificationStatus, CryptoEvent } from "matrix-js-sdk/src/crypto-api"; -import dis from "../../dispatcher/dispatcher"; -import { MatrixClientPeg } from "../../MatrixClientPeg"; -import { Action } from "../../dispatcher/actions"; -import { asyncSome } from "../../utils/arrays"; -import { getUserDeviceIds } from "../../utils/crypto/deviceInfo"; -import { RoomMember } from "../../models/rooms/RoomMember"; -import { E2EState } from "../views/rooms/E2EIcon"; -import { _t, _td, TranslationKey } from "../../languageHandler"; -import UserIdentifierCustomisations from "../../customisations/UserIdentifier"; -import { ThreePIDInvite } from "../../models/rooms/ThreePIDInvite"; +import dis from "../../../../dispatcher/dispatcher"; +import { MatrixClientPeg } from "../../../../MatrixClientPeg"; +import { Action } from "../../../../dispatcher/actions"; +import { asyncSome } from "../../../../utils/arrays"; +import { getUserDeviceIds } from "../../../../utils/crypto/deviceInfo"; +import { RoomMember } from "../../../../models/rooms/RoomMember"; +import { E2EState } from "../../../views/rooms/E2EIcon"; +import { _t, _td, TranslationKey } from "../../../../languageHandler"; +import UserIdentifierCustomisations from "../../../../customisations/UserIdentifier"; interface MemberTileViewModelProps { member: RoomMember; showPresence?: boolean; } -interface ThreePidTileViewModelProps { - threePidInvite: ThreePIDInvite; -} - export interface MemberTileViewState extends MemberTileViewModelProps { e2eStatus?: E2EState; name: string; @@ -47,27 +42,6 @@ const PowerLabel: Record = { [PowerStatus.Moderator]: _td("power_level|moderator"), }; -export interface ThreePidTileViewState { - name: string; - onClick: () => void; -} - -export function useThreePidTileViewModel(props: ThreePidTileViewModelProps): ThreePidTileViewState { - const invite = props.threePidInvite; - const name = invite.event.getContent().display_name; - const onClick = (): void => { - dis.dispatch({ - action: Action.View3pidInvite, - event: invite.event, - }); - }; - - return { - name, - onClick, - }; -} - export function useMemberTileViewModel(props: MemberTileViewModelProps): MemberTileViewState { const [e2eStatus, setE2eStatus] = useState(); diff --git a/src/components/viewmodels/memberlist/tiles/ThreePidTileViewModel.tsx b/src/components/viewmodels/memberlist/tiles/ThreePidTileViewModel.tsx new file mode 100644 index 0000000000..9725c30527 --- /dev/null +++ b/src/components/viewmodels/memberlist/tiles/ThreePidTileViewModel.tsx @@ -0,0 +1,35 @@ +/* +Copyright 2024 New Vector Ltd. + +SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only +Please see LICENSE files in the repository root for full details. +*/ + +import dis from "../../../../dispatcher/dispatcher"; +import { Action } from "../../../../dispatcher/actions"; +import { ThreePIDInvite } from "../../../../models/rooms/ThreePIDInvite"; + +interface ThreePidTileViewModelProps { + threePidInvite: ThreePIDInvite; +} + +export interface ThreePidTileViewState { + name: string; + onClick: () => void; +} + +export function useThreePidTileViewModel(props: ThreePidTileViewModelProps): ThreePidTileViewState { + const invite = props.threePidInvite; + const name = invite.event.getContent().display_name; + const onClick = (): void => { + dis.dispatch({ + action: Action.View3pidInvite, + event: invite.event, + }); + }; + + return { + name, + onClick, + }; +} diff --git a/src/components/views/rooms/MemberListHeaderView.tsx b/src/components/views/rooms/MemberList/MemberListHeaderView.tsx similarity index 94% rename from src/components/views/rooms/MemberListHeaderView.tsx rename to src/components/views/rooms/MemberList/MemberListHeaderView.tsx index 998fe28105..93ce1ca665 100644 --- a/src/components/views/rooms/MemberListHeaderView.tsx +++ b/src/components/views/rooms/MemberList/MemberListHeaderView.tsx @@ -10,9 +10,9 @@ import React from "react"; import InviteIcon from "@vector-im/compound-design-tokens/assets/web/icons/user-add-solid"; import { UserAddIcon } from "@vector-im/compound-design-tokens/assets/web/icons"; -import { Flex } from "../../utils/Flex"; -import { MemberListViewState } from "../../viewmodels/MemberListViewModel"; -import { _t } from "../../../languageHandler"; +import { Flex } from "../../../utils/Flex"; +import { MemberListViewState } from "../../../viewmodels/memberlist/MemberListViewModel"; +import { _t } from "../../../../languageHandler"; interface TooltipProps { canInvite: boolean; @@ -96,7 +96,7 @@ function getHeaderLabelJSX(vm: MemberListViewState): React.ReactNode { return _t("member_list|count", { count: filteredMemberCount }); } -const MemberListHeaderView: React.FC = (props: Props) => { +export const MemberListHeaderView: React.FC = (props: Props) => { const vm = props.vm; let contentJSX: React.ReactNode; @@ -135,5 +135,3 @@ const MemberListHeaderView: React.FC = (props: Props) => { ); }; - -export default MemberListHeaderView; diff --git a/src/components/views/rooms/MemberListView.tsx b/src/components/views/rooms/MemberList/MemberListView.tsx similarity index 86% rename from src/components/views/rooms/MemberListView.tsx rename to src/components/views/rooms/MemberList/MemberListView.tsx index 00eed11302..549eda26dd 100644 --- a/src/components/views/rooms/MemberListView.tsx +++ b/src/components/views/rooms/MemberList/MemberListView.tsx @@ -10,12 +10,13 @@ import React from "react"; import { List, ListRowProps } from "react-virtualized/dist/commonjs/List"; import { AutoSizer } from "react-virtualized"; -import { Flex } from "../../utils/Flex"; -import { useMemberListViewModel } from "../../viewmodels/MemberListViewModel"; -import { RoomMemberTileView, ThreePidInviteTileView } from "./MemberTileView"; -import MemberListHeaderView from "./MemberListHeaderView"; -import BaseCard from "../right_panel/BaseCard"; -import { _t } from "../../../languageHandler"; +import { Flex } from "../../../utils/Flex"; +import { useMemberListViewModel } from "../../../viewmodels/memberlist/MemberListViewModel"; +import { RoomMemberTileView } from "./tiles/RoomMemberTileView"; +import { ThreePidInviteTileView } from "./tiles/ThreePidInviteTileView"; +import { MemberListHeaderView } from "./MemberListHeaderView"; +import BaseCard from "../../right_panel/BaseCard"; +import { _t } from "../../../../languageHandler"; interface IProps { roomId: string; diff --git a/src/components/views/rooms/MemberList/tiles/RoomMemberTileView.tsx b/src/components/views/rooms/MemberList/tiles/RoomMemberTileView.tsx new file mode 100644 index 0000000000..6d3b511e12 --- /dev/null +++ b/src/components/views/rooms/MemberList/tiles/RoomMemberTileView.tsx @@ -0,0 +1,67 @@ +/* +Copyright 2024 New Vector Ltd. + +SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only +Please see LICENSE files in the repository root for full details. +*/ + +import React from "react"; + +import DisambiguatedProfile from "../../../messages/DisambiguatedProfile"; +import { RoomMember } from "../../../../../models/rooms/RoomMember"; +import { useMemberTileViewModel } from "../../../../viewmodels/memberlist/tiles/MemberTileViewModel"; +import { E2EIconView } from "./common/E2EIconView"; +import AvatarPresenceIconView from "./common/PresenceIconView"; +import BaseAvatar from "../../../avatars/BaseAvatar"; +import { _t } from "../../../../../languageHandler"; +import { MemberTileLayout } from "./common/MemberTileLayout"; + +interface IProps { + member: RoomMember; + showPresence?: boolean; +} + +export function RoomMemberTileView(props: IProps): JSX.Element { + const vm = useMemberTileViewModel(props); + const member = vm.member; + const av = ( + + ); + const name = vm.name; + const nameJSX = ; + + const presenceState = member.presenceState; + let presenceJSX: JSX.Element | undefined; + if (vm.showPresence && presenceState) { + presenceJSX = ; + } + + let userLabelJSX; + if (vm.userLabel) { + userLabelJSX =
{vm.userLabel}
; + } + + let e2eIcon; + if (vm.e2eStatus) { + e2eIcon = ; + } + + return ( + + ); +} diff --git a/src/components/views/rooms/MemberList/tiles/ThreePidInviteTileView.tsx b/src/components/views/rooms/MemberList/tiles/ThreePidInviteTileView.tsx new file mode 100644 index 0000000000..2058f090c8 --- /dev/null +++ b/src/components/views/rooms/MemberList/tiles/ThreePidInviteTileView.tsx @@ -0,0 +1,23 @@ +/* +Copyright 2024 New Vector Ltd. + +SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only +Please see LICENSE files in the repository root for full details. +*/ + +import React from "react"; + +import { useThreePidTileViewModel } from "../../../../viewmodels/memberlist/tiles/ThreePidTileViewModel"; +import { ThreePIDInvite } from "../../../../../models/rooms/ThreePIDInvite"; +import BaseAvatar from "../../../avatars/BaseAvatar"; +import { MemberTileLayout } from "./common/MemberTileLayout"; + +interface Props { + threePidInvite: ThreePIDInvite; +} + +export function ThreePidInviteTileView(props: Props): JSX.Element { + const vm = useThreePidTileViewModel(props); + const av =