From aadf760e3c82e5d26c6c31856830fbfe09892fcf Mon Sep 17 00:00:00 2001 From: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> Date: Thu, 16 Apr 2026 17:19:52 +0100 Subject: [PATCH] Factor DMRoomTile out to its own file (#33170) I'm going to use this from a new component --- .../components/views/dialogs/InviteDialog.tsx | 63 +--------------- .../views/dialogs/invite/DMRoomTile.tsx | 74 +++++++++++++++++++ 2 files changed, 76 insertions(+), 61 deletions(-) create mode 100644 apps/web/src/components/views/dialogs/invite/DMRoomTile.tsx diff --git a/apps/web/src/components/views/dialogs/InviteDialog.tsx b/apps/web/src/components/views/dialogs/InviteDialog.tsx index 94b6365774..be208b24a2 100644 --- a/apps/web/src/components/views/dialogs/InviteDialog.tsx +++ b/apps/web/src/components/views/dialogs/InviteDialog.tsx @@ -12,10 +12,9 @@ import { KnownMembership } from "matrix-js-sdk/src/types"; import { type MatrixCall } from "matrix-js-sdk/src/webrtc/call"; import { logger } from "matrix-js-sdk/src/logger"; import { uniqBy } from "lodash"; -import { RichList, RichItem, PillInput, Pill } from "@element-hq/web-shared-components"; +import { Pill, PillInput, RichList } from "@element-hq/web-shared-components"; import { DialPadIcon, UserProfileSolidIcon } from "@vector-im/compound-design-tokens/assets/web/icons"; -import { Icon as EmailPillAvatarIcon } from "../../../../res/img/icon-email-pill-avatar.svg"; import { _t, _td } from "../../../languageHandler"; import { MatrixClientPeg } from "../../../MatrixClientPeg"; import { makeRoomPermalink, makeUserPermalink } from "../../../utils/permalinks/Permalinks"; @@ -31,8 +30,6 @@ import { DefaultTagID } from "../../../stores/room-list-v3/skip-list/tag"; import RoomListStore from "../../../stores/room-list/RoomListStore"; import SettingsStore from "../../../settings/SettingsStore"; import { UIFeature } from "../../../settings/UIFeature"; -import { mediaFromMxc } from "../../../customisations/Media"; -import BaseAvatar from "../avatars/BaseAvatar"; import { SearchResultAvatar } from "../avatars/SearchResultAvatar"; import AccessibleButton, { type ButtonEvent } from "../elements/AccessibleButton"; import { selectText } from "../../../utils/strings"; @@ -43,7 +40,6 @@ import QuestionDialog from "./QuestionDialog"; import BaseDialog from "./BaseDialog"; import DialPadBackspaceButton from "../elements/DialPadBackspaceButton"; import LegacyCallHandler from "../../../LegacyCallHandler"; -import UserIdentifierCustomisations from "../../../customisations/UserIdentifier"; import CopyableText from "../elements/CopyableText"; import { type ScreenName } from "../../../PosthogTrackers"; import { KeyBindingAction } from "../../../accessibility/KeyboardShortcuts"; @@ -64,6 +60,7 @@ import { SdkContextClass } from "../../../contexts/SDKContext"; import { type UserProfilesStore } from "../../../stores/UserProfilesStore"; import InviteProgressBody from "./InviteProgressBody.tsx"; import MultiInviter, { type CompletionStates as MultiInviterCompletionStates } from "../../../utils/MultiInviter.ts"; +import { DMRoomTile } from "./invite/DMRoomTile.tsx"; interface Result { userId: string; @@ -114,62 +111,6 @@ const toMember = (member: RoomMember | Member): Member => { : member; }; -interface IDMRoomTileProps { - member: Member; - lastActiveTs?: number; - onToggle(member: Member): void; - isSelected: boolean; -} - -class DMRoomTile extends React.PureComponent { - private onClick = (e: ButtonEvent): void => { - // Stop the browser from highlighting text - e.preventDefault(); - e.stopPropagation(); - - this.props.onToggle(this.props.member); - }; - - public render(): React.ReactNode { - const avatarSize = "32px"; - const avatar = (this.props.member as ThreepidMember).isEmail ? ( - - ) : ( - - ); - - const userIdentifier = UserIdentifierCustomisations.getDisplayUserIdentifier(this.props.member.userId, { - withDisplayName: true, - }); - - const caption = (this.props.member as ThreepidMember).isEmail - ? _t("invite|email_caption") - : userIdentifier || this.props.member.userId; - - return ( - - ); - } -} - interface BaseProps { // Takes a boolean which is true if a user / users were invited / // a call transfer was initiated or false if the dialog was cancelled diff --git a/apps/web/src/components/views/dialogs/invite/DMRoomTile.tsx b/apps/web/src/components/views/dialogs/invite/DMRoomTile.tsx new file mode 100644 index 0000000000..954e792b17 --- /dev/null +++ b/apps/web/src/components/views/dialogs/invite/DMRoomTile.tsx @@ -0,0 +1,74 @@ +/* + Copyright 2026 Element Creations Ltd. + + SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial + Please see LICENSE files in the repository root for full details. + */ + +import React from "react"; +import { RichItem } from "@element-hq/web-shared-components"; + +import { type Member, type ThreepidMember } from "../../../../utils/direct-messages.ts"; +import type { ButtonEvent } from "../../elements/AccessibleButton.tsx"; +import BaseAvatar from "../../avatars/BaseAvatar.tsx"; +import { mediaFromMxc } from "../../../../customisations/Media.ts"; +import UserIdentifierCustomisations from "../../../../customisations/UserIdentifier.ts"; +import { _t } from "../../../../languageHandler.tsx"; +import { Icon as EmailPillAvatarIcon } from "../../../../../res/img/icon-email-pill-avatar.svg"; + +interface IDMRoomTileProps { + member: Member; + lastActiveTs?: number; + onToggle(member: Member): void; + isSelected: boolean; +} + +/** A tile representing a single user in the "suggestions"/"recents" section of the invite dialog. */ +export class DMRoomTile extends React.PureComponent { + private onClick = (e: ButtonEvent): void => { + // Stop the browser from highlighting text + e.preventDefault(); + e.stopPropagation(); + + this.props.onToggle(this.props.member); + }; + + public render(): React.ReactNode { + const avatarSize = "32px"; + const avatar = (this.props.member as ThreepidMember).isEmail ? ( + + ) : ( + + ); + + const userIdentifier = UserIdentifierCustomisations.getDisplayUserIdentifier(this.props.member.userId, { + withDisplayName: true, + }); + + const caption = (this.props.member as ThreepidMember).isEmail + ? _t("invite|email_caption") + : userIdentifier || this.props.member.userId; + + return ( + + ); + } +}