Add customisation point for mxid display (#7595)

* add wrapping component for hiding UI

Signed-off-by: Kerry Archibald <kerrya@element.io>

* add Setting

Signed-off-by: Kerry Archibald <kerrya@element.io>

* apply setting to profile settings, user menu, invite dialog, userinfo

Signed-off-by: Kerry Archibald <kerrya@element.io>

* hide mxids in user autocomplete

* remove mxids from title in memeber list and timeline

Signed-off-by: Kerry Archibald <kerrya@element.io>

* hide mxid in ConfirmUserActionDialog

Signed-off-by: Kerry Archibald <kerrya@element.io>

* use name in power level event message when displayMxids is falsy

Signed-off-by: Kerry Archibald <kerrya@element.io>

* add customisation point for mxid display

Signed-off-by: Kerry Archibald <kerrya@element.io>

* use userid customisation

Signed-off-by: Kerry Archibald <kerrya@element.io>

* use customisation in sender profile

Signed-off-by: Kerry Archibald <kerrya@element.io>

* hide profile settings mxid if falsy

Signed-off-by: Kerry Archibald <kerrya@element.io>

* rename and move to components

Signed-off-by: Kerry Archibald <kerrya@element.io>

* remove change to UIFeature.ts

Signed-off-by: Kerry Archibald <kerrya@element.io>

* improvements from pr

Signed-off-by: Kerry Archibald <kerrya@element.io>

* lint fix

Signed-off-by: Kerry Archibald <kerrya@element.io>
This commit is contained in:
Kerry 2022-01-25 10:40:02 +01:00 committed by GitHub
parent b481fc069e
commit 502b805164
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 154 additions and 23 deletions

View file

@ -26,6 +26,7 @@ import BaseAvatar from "./BaseAvatar";
import { replaceableComponent } from "../../../utils/replaceableComponent";
import { mediaFromMxc } from "../../../customisations/Media";
import { CardContext } from '../right_panel/BaseCard';
import UserIdentifierCustomisations from '../../../customisations/UserIdentifier';
interface IProps extends Omit<React.ComponentProps<typeof BaseAvatar>, "name" | "idName" | "url"> {
member: RoomMember;
@ -70,6 +71,9 @@ export default class MemberAvatar extends React.Component<IProps, IState> {
private static getState(props: IProps): IState {
if (props.member?.name) {
let imageUrl = null;
const userTitle = UserIdentifierCustomisations.getDisplayUserIdentifier(
props.member.userId, { roomId: props.member?.roomId },
);
if (props.member.getMxcAvatarUrl()) {
imageUrl = mediaFromMxc(props.member.getMxcAvatarUrl()).getThumbnailOfSourceHttp(
props.width,
@ -79,7 +83,7 @@ export default class MemberAvatar extends React.Component<IProps, IState> {
}
return {
name: props.member.name,
title: props.title || props.member.userId,
title: props.title || userTitle,
imageUrl: imageUrl,
};
} else if (props.fallbackUserId) {

View file

@ -67,6 +67,7 @@ const ConfirmSpaceUserActionDialog: React.FC<IProps> = ({
onFinished(success, reason, roomsToLeave);
}}
className="mx_ConfirmSpaceUserActionDialog"
roomId={space.roomId}
>
{ warning }
<SpaceChildrenPicker

View file

@ -28,6 +28,7 @@ import BaseAvatar from '../avatars/BaseAvatar';
import BaseDialog from "./BaseDialog";
import DialogButtons from "../elements/DialogButtons";
import Field from '../elements/Field';
import UserIdentifierCustomisations from '../../../customisations/UserIdentifier';
interface IProps {
// matrix-js-sdk (room) member object. Supply either this or 'groupMember'
@ -46,6 +47,7 @@ interface IProps {
danger?: boolean;
children?: ReactNode;
className?: string;
roomId?: string;
onFinished: (success: boolean, reason?: string) => void;
}
@ -126,6 +128,10 @@ export default class ConfirmUserActionDialog extends React.Component<IProps, ISt
avatar = <BaseAvatar name={name} url={httpAvatarUrl} width={48} height={48} />;
}
const displayUserIdentifier = UserIdentifierCustomisations.getDisplayUserIdentifier(
userId, { roomId: this.props.roomId, withDisplayName: true },
);
return (
<BaseDialog
className={classNames("mx_ConfirmUserActionDialog", this.props.className)}
@ -139,7 +145,7 @@ export default class ConfirmUserActionDialog extends React.Component<IProps, ISt
{ avatar }
</div>
<div className="mx_ConfirmUserActionDialog_name">{ name }</div>
<div className="mx_ConfirmUserActionDialog_userId">{ userId }</div>
<div className="mx_ConfirmUserActionDialog_userId">{ displayUserIdentifier }</div>
</div>
{ reasonBox }

View file

@ -72,6 +72,7 @@ import BaseDialog from "./BaseDialog";
import DialPadBackspaceButton from "../elements/DialPadBackspaceButton";
import SpaceStore from "../../../stores/spaces/SpaceStore";
import CallHandler from "../../../CallHandler";
import UserIdentifierCustomisations from '../../../customisations/UserIdentifier';
// we have a number of types defined from the Matrix spec which can't reasonably be altered here.
/* eslint-disable camelcase */
@ -329,9 +330,13 @@ class DMRoomTile extends React.PureComponent<IDMRoomTileProps> {
</span>
);
const userIdentifier = UserIdentifierCustomisations.getDisplayUserIdentifier(
this.props.member.userId, { withDisplayName: true },
);
const caption = (this.props.member as ThreepidMember).isEmail
? _t("Invite by email")
: this.highlightName(this.props.member.userId);
: this.highlightName(userIdentifier);
return (
<div className='mx_InviteDialog_roomTile' onClick={this.onClick}>

View file

@ -23,6 +23,7 @@ import FlairStore from '../../../stores/FlairStore';
import { getUserNameColorClass } from '../../../utils/FormattingUtils';
import MatrixClientContext from "../../../contexts/MatrixClientContext";
import { replaceableComponent } from "../../../utils/replaceableComponent";
import UserIdentifier from '../../../customisations/UserIdentifier';
interface IProps {
mxEvent: MatrixEvent;
@ -116,7 +117,9 @@ export default class SenderProfile extends React.Component<IProps, IState> {
if (disambiguate) {
mxidElement = (
<span className="mx_SenderProfile_mxid">
{ mxid }
{ UserIdentifier.getDisplayUserIdentifier(
mxid, { withDisplayName: true, roomId: mxEvent.getRoomId() },
) }
</span>
);
}

View file

@ -77,6 +77,7 @@ import { TimelineRenderingType } from "../../../contexts/RoomContext";
import RightPanelStore from '../../../stores/right-panel/RightPanelStore';
import { IRightPanelCardState } from '../../../stores/right-panel/RightPanelStoreIPanelState';
import { useUserStatusMessage } from "../../../hooks/useUserStatusMessage";
import UserIdentifierCustomisations from '../../../customisations/UserIdentifier';
export interface IDevice {
deviceId: string;
@ -1517,7 +1518,8 @@ export type Member = User | RoomMember | GroupMember;
const UserInfoHeader: React.FC<{
member: Member;
e2eStatus: E2EStatus;
}> = ({ member, e2eStatus }) => {
roomId: string;
}> = ({ member, e2eStatus, roomId }) => {
const cli = useContext(MatrixClientContext);
const statusMessage = useUserStatusMessage(member);
@ -1604,7 +1606,7 @@ const UserInfoHeader: React.FC<{
</span>
</h2>
</div>
<div>{ member.userId }</div>
<div>{ UserIdentifierCustomisations.getDisplayUserIdentifier(member.userId, { roomId, withDisplayName: true }) }</div>
<div className="mx_UserInfo_profileStatus">
{ presenceLabel }
{ statusLabel }
@ -1708,7 +1710,7 @@ const UserInfo: React.FC<IProps> = ({
const header = <React.Fragment>
{ scopeHeader }
<UserInfoHeader member={member} e2eStatus={e2eStatus} />
<UserInfoHeader member={member} e2eStatus={e2eStatus} roomId={room.roomId} />
</React.Fragment>;
return <BaseCard
className={classes.join(" ")}

View file

@ -29,6 +29,7 @@ import { Action } from "../../../dispatcher/actions";
import { replaceableComponent } from "../../../utils/replaceableComponent";
import EntityTile, { PowerStatus } from "./EntityTile";
import MemberAvatar from "./../avatars/MemberAvatar";
import UserIdentifierCustomisations from '../../../customisations/UserIdentifier';
interface IProps {
member: RoomMember;
@ -209,9 +210,11 @@ export default class MemberTile extends React.Component<IProps, IState> {
private getPowerLabel(): string {
return _t("%(userName)s (power %(powerLevelNumber)s)", {
userName: this.props.member.userId,
userName: UserIdentifierCustomisations.getDisplayUserIdentifier(
this.props.member.userId, { roomId: this.props.member.roomId },
),
powerLevelNumber: this.props.member.powerLevel,
});
}).trim();
}
render() {

View file

@ -34,9 +34,9 @@ import InviteReason from "../elements/InviteReason";
import { IOOBData } from "../../../stores/ThreepidInviteStore";
import Spinner from "../elements/Spinner";
import AccessibleButton from "../elements/AccessibleButton";
import { UIFeature } from "../../../settings/UIFeature";
import SettingsStore from "../../../settings/SettingsStore";
import RoomAvatar from "../avatars/RoomAvatar";
import SettingsStore from "../../../settings/SettingsStore";
import { UIFeature } from "../../../settings/UIFeature";
const MemberEventHtmlReasonField = "io.element.html_reason";

View file

@ -29,6 +29,7 @@ import { mediaFromMxc } from "../../../customisations/Media";
import AccessibleButton from '../elements/AccessibleButton';
import AvatarSetting from './AvatarSetting';
import ExternalLink from '../elements/ExternalLink';
import UserIdentifierCustomisations from '../../../customisations/UserIdentifier';
interface IState {
userId?: string;
@ -162,7 +163,7 @@ export default class ProfileSettings extends React.Component<{}, IState> {
const hostingSignupLink = getHostingLink('user-settings');
let hostingSignup = null;
if (hostingSignupLink) {
hostingSignup = <span className="mx_ProfileSettings_hostingSignup">
hostingSignup = <span>
{ _t(
"<a>Upgrade</a> to your own domain", {},
{
@ -174,6 +175,10 @@ export default class ProfileSettings extends React.Component<{}, IState> {
</span>;
}
const userIdentifier = UserIdentifierCustomisations.getDisplayUserIdentifier(
this.state.userId, { withDisplayName: true },
);
return (
<form
onSubmit={this.saveProfile}
@ -199,7 +204,9 @@ export default class ProfileSettings extends React.Component<{}, IState> {
onChange={this.onDisplayNameChanged}
/>
<p>
{ this.state.userId }
{ userIdentifier && <span className="mx_ProfileSettings_userId">
{ userIdentifier }
</span> }
{ hostingSignup }
</p>
</div>