diff --git a/src/components/views/avatars/MemberAvatar.tsx b/src/components/views/avatars/MemberAvatar.tsx index 6ef08775fd..4ca2fb8ac8 100644 --- a/src/components/views/avatars/MemberAvatar.tsx +++ b/src/components/views/avatars/MemberAvatar.tsx @@ -1,6 +1,6 @@ /* Copyright 2015, 2016 OpenMarket Ltd -Copyright 2019 The Matrix.org Foundation C.I.C. +Copyright 2019 - 2022 The Matrix.org Foundation C.I.C. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -27,6 +27,8 @@ import { replaceableComponent } from "../../../utils/replaceableComponent"; import { mediaFromMxc } from "../../../customisations/Media"; import { CardContext } from '../right_panel/BaseCard'; import UserIdentifierCustomisations from '../../../customisations/UserIdentifier'; +import SettingsStore from "../../../settings/SettingsStore"; +import { MatrixClientPeg } from "../../../MatrixClientPeg"; interface IProps extends Omit, "name" | "idName" | "url"> { member: RoomMember; @@ -41,6 +43,7 @@ interface IProps extends Omit, "name" | pushUserOnClick?: boolean; title?: string; style?: any; + forceHistorical?: boolean; // true to deny `feature_use_only_current_profiles` usage. Default false. } interface IState { @@ -50,7 +53,7 @@ interface IState { } @replaceableComponent("views.avatars.MemberAvatar") -export default class MemberAvatar extends React.Component { +export default class MemberAvatar extends React.PureComponent { public static defaultProps = { width: 40, height: 40, @@ -69,20 +72,27 @@ export default class MemberAvatar extends React.Component { } private static getState(props: IProps): IState { - if (props.member?.name) { + let member = props.member; + if (member && !props.forceHistorical && SettingsStore.getValue("feature_use_only_current_profiles")) { + const room = MatrixClientPeg.get().getRoom(member.roomId); + if (room) { + member = room.getMember(member.userId); + } + } + if (member?.name) { let imageUrl = null; const userTitle = UserIdentifierCustomisations.getDisplayUserIdentifier( - props.member.userId, { roomId: props.member?.roomId }, + member.userId, { roomId: member?.roomId }, ); - if (props.member.getMxcAvatarUrl()) { - imageUrl = mediaFromMxc(props.member.getMxcAvatarUrl()).getThumbnailOfSourceHttp( + if (member.getMxcAvatarUrl()) { + imageUrl = mediaFromMxc(member.getMxcAvatarUrl()).getThumbnailOfSourceHttp( props.width, props.height, props.resizeMethod, ); } return { - name: props.member.name, + name: member.name, title: props.title || userTitle, imageUrl: imageUrl, }; diff --git a/src/components/views/messages/SenderProfile.tsx b/src/components/views/messages/SenderProfile.tsx index 45d44ff88a..d363bdef94 100644 --- a/src/components/views/messages/SenderProfile.tsx +++ b/src/components/views/messages/SenderProfile.tsx @@ -25,6 +25,8 @@ import MatrixClientContext from "../../../contexts/MatrixClientContext"; import { replaceableComponent } from "../../../utils/replaceableComponent"; import UserIdentifier from '../../../customisations/UserIdentifier'; import { TileShape } from '../rooms/EventTile'; +import SettingsStore from "../../../settings/SettingsStore"; +import { MatrixClientPeg } from "../../../MatrixClientPeg"; interface IProps { mxEvent: MatrixEvent; @@ -107,9 +109,17 @@ export default class SenderProfile extends React.Component { const colorClass = getUserNameColorClass(mxEvent.getSender()); const { msgtype } = mxEvent.getContent(); - const disambiguate = mxEvent.sender?.disambiguate; - const displayName = mxEvent.sender?.rawDisplayName || mxEvent.getSender() || ""; - const mxid = mxEvent.sender?.userId || mxEvent.getSender() || ""; + let member = mxEvent.sender; + if (SettingsStore.getValue("feature_use_only_current_profiles")) { + const room = MatrixClientPeg.get().getRoom(mxEvent.getRoomId()); + if (room) { + member = room.getMember(member.userId); + } + } + + const disambiguate = member?.disambiguate || mxEvent.sender?.disambiguate; + const displayName = member?.rawDisplayName || mxEvent.getSender() || ""; + const mxid = member?.userId || mxEvent.getSender() || ""; if (msgtype === MsgType.Emote && this.props.tileShape !== TileShape.ThreadPanel) { return null; // emote message must include the name so don't duplicate it diff --git a/src/components/views/rooms/EventTile.tsx b/src/components/views/rooms/EventTile.tsx index f1f5a4f36d..ea0213099e 100644 --- a/src/components/views/rooms/EventTile.tsx +++ b/src/components/views/rooms/EventTile.tsx @@ -1260,6 +1260,7 @@ export default class EventTile extends React.Component { width={avatarSize} height={avatarSize} viewUserOnClick={true} + forceHistorical={this.props.mxEvent.getType() === EventType.RoomMember} /> ); diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 997bebff28..b6df13752c 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -884,6 +884,7 @@ "Show message previews for reactions in all rooms": "Show message previews for reactions in all rooms", "Offline encrypted messaging using dehydrated devices": "Offline encrypted messaging using dehydrated devices", "Show extensible event representation of events": "Show extensible event representation of events", + "Show current avatar and name for users in message history": "Show current avatar and name for users in message history", "Show info about bridges in room settings": "Show info about bridges in room settings", "Use new room breadcrumbs": "Use new room breadcrumbs", "New search experience": "New search experience", diff --git a/src/settings/Settings.tsx b/src/settings/Settings.tsx index 004cbd2174..a98dc51f47 100644 --- a/src/settings/Settings.tsx +++ b/src/settings/Settings.tsx @@ -307,6 +307,13 @@ export const SETTINGS: {[setting: string]: ISetting} = { displayName: _td("Show extensible event representation of events"), default: false, }, + "feature_use_only_current_profiles": { + isFeature: true, + labsGroup: LabGroup.Rooms, + supportedLevels: LEVELS_FEATURE, + displayName: _td("Show current avatar and name for users in message history"), + default: false, + }, "doNotDisturb": { supportedLevels: [SettingLevel.DEVICE], default: false,