DP18: add getMemberName helper and dedup name-fallback sites

Add a pure `getMemberName(room, userId): string` helper in utils/room.ts
(= getMemberDisplayName ?? getMxIdLocalPart ?? userId) and replace the
inline `getMemberDisplayName(room, id) ?? getMxIdLocalPart(id) ?? id`
fallback across the codebase. No behavior change.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-07 23:01:32 -04:00
co-authored by Claude Opus 4.8
parent 165714e133
commit 8c0e2b4250
22 changed files with 62 additions and 98 deletions
+3 -7
View File
@@ -42,7 +42,7 @@ import {
} from '../../hooks/useAsyncSearch';
import { useDebounce } from '../../hooks/useDebounce';
import { TypingIndicator } from '../../components/typing-indicator';
import { getMemberDisplayName, getMemberSearchStr } from '../../utils/room';
import { getMemberName, getMemberSearchStr } from '../../utils/room';
import { getMxIdLocalPart } from '../../utils/matrix';
import { useSetSetting, useSetting } from '../../state/hooks/settings';
import { settingsAtom } from '../../state/settings';
@@ -134,8 +134,7 @@ function MemberItem({
typing,
showEncryption,
}: MemberItemProps) {
const name =
getMemberDisplayName(room, member.userId) ?? getMxIdLocalPart(member.userId) ?? member.userId;
const name = getMemberName(room, member.userId);
const avatarMxcUrl = member.getMxcAvatarUrl();
const avatarUrl = avatarMxcUrl
? mx.mxcUrlToHttp(avatarMxcUrl, 100, 100, 'crop', undefined, false, useAuthentication)
@@ -418,10 +417,7 @@ export function MembersDrawer({ room, members }: MembersDrawerProps) {
Pending Requests
</Text>
{knockMembers.map((knockMember) => {
const knockName =
getMemberDisplayName(room, knockMember.userId) ??
getMxIdLocalPart(knockMember.userId) ??
knockMember.userId;
const knockName = getMemberName(room, knockMember.userId);
const knockAvatarMxc = knockMember.getMxcAvatarUrl();
const knockAvatarUrl = knockAvatarMxc
? mx.mxcUrlToHttp(
+2 -7
View File
@@ -65,7 +65,6 @@ import {
TUploadContent,
encryptFile,
getImageInfo,
getMxIdLocalPart,
mxcUrlToHttp,
tryDeleteMxcContent,
} from '../../utils/matrix';
@@ -111,7 +110,7 @@ import {
getImageMsgContent,
getVideoMsgContent,
} from './msgContent';
import { getMemberDisplayName, getMentionContent, trimReplyFromBody } from '../../utils/room';
import { getMemberName, getMentionContent, trimReplyFromBody } from '../../utils/room';
import { CommandAutocomplete } from './CommandAutocomplete';
import { Command, SHRUG, TABLEFLIP, UNFLIP, useCommands } from '../../hooks/useCommands';
import { mobileOrTablet } from '../../utils/user-agent';
@@ -993,11 +992,7 @@ export const RoomInput = forwardRef<HTMLDivElement, RoomInputProps>(
userColor={replyUsernameColor}
username={
<Text size="T300" truncate>
<b>
{getMemberDisplayName(room, replyDraft.userId) ??
getMxIdLocalPart(replyDraft.userId) ??
replyDraft.userId}
</b>
<b>{getMemberName(room, replyDraft.userId)}</b>
</Text>
}
>
+4 -5
View File
@@ -81,6 +81,7 @@ import {
getEventReactions,
getLatestEditableEvt,
getMemberDisplayName,
getMemberName,
getReactionContent,
isMembershipChanged,
reactionOrEditEvent,
@@ -1007,7 +1008,7 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli
console.warn('Button should have "data-user-id" attribute!');
return;
}
const name = getMemberDisplayName(room, userId) ?? getMxIdLocalPart(userId) ?? userId;
const name = getMemberName(room, userId);
editor.insertNode(
createMentionElement(
userId,
@@ -1106,8 +1107,7 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli
editedEvent?.getContent()['m.new_content'] ?? mEvent.getContent()) as GetContentCallback;
const senderId = mEvent.getSender() ?? '';
const senderDisplayName =
getMemberDisplayName(room, senderId) ?? getMxIdLocalPart(senderId) ?? senderId;
const senderDisplayName = getMemberName(room, senderId);
return (
<Message
@@ -1290,8 +1290,7 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli
mEvent.getContent()) as GetContentCallback;
const senderId = mEvent.getSender() ?? '';
const senderDisplayName =
getMemberDisplayName(room, senderId) ?? getMxIdLocalPart(senderId) ?? senderId;
const senderDisplayName = getMemberName(room, senderId);
return (
<RenderMessageContent
displayName={senderDisplayName}
+2 -6
View File
@@ -15,8 +15,7 @@ import { Room } from 'matrix-js-sdk';
import classNames from 'classnames';
import FocusTrap from 'focus-trap-react';
import { getMemberDisplayName } from '../../utils/room';
import { getMxIdLocalPart } from '../../utils/matrix';
import { getMemberName } from '../../utils/room';
import * as css from './RoomViewFollowing.css';
import { useMatrixClient } from '../../hooks/useMatrixClient';
import { useRoomLatestRenderedEvent } from '../../hooks/useRoomLatestRenderedEvent';
@@ -39,10 +38,7 @@ export const RoomViewFollowing = as<'div', RoomViewFollowingProps>(
const latestEventReaders = useRoomEventReaders(room, latestEvent?.getId());
const names = latestEventReaders
.filter((readerId) => readerId !== mx.getUserId())
.map(
(readerId) =>
getMemberDisplayName(room, readerId) ?? getMxIdLocalPart(readerId) ?? readerId,
);
.map((readerId) => getMemberName(room, readerId));
const eventId = latestEvent?.getId();
+3 -4
View File
@@ -53,9 +53,9 @@ import {
canEditEvent,
getEventEdits,
getMemberAvatarMxc,
getMemberDisplayName,
getMemberName,
} from '../../../utils/room';
import { getMxIdLocalPart, mxcUrlToHttp } from '../../../utils/matrix';
import { mxcUrlToHttp } from '../../../utils/matrix';
import { messageAriaLabel } from '../../../utils/a11y';
import { MessageLayout, MessageSpacing } from '../../../state/settings';
import { useMatrixClient } from '../../../hooks/useMatrixClient';
@@ -809,8 +809,7 @@ export const Message = React.memo(
const [remindOpen, setRemindOpen] = useState(false);
const { addBookmark, removeBookmark, isBookmarked } = useBookmarks();
const senderDisplayName =
getMemberDisplayName(room, senderId) ?? getMxIdLocalPart(senderId) ?? senderId;
const senderDisplayName = getMemberName(room, senderId);
const senderAvatarMxc = getMemberAvatarMxc(room, senderId);
const tagColor = memberPowerTag?.color
@@ -53,11 +53,10 @@ import { AsyncStatus, useAsyncCallback } from '../../../hooks/useAsyncCallback';
import { useMatrixClient } from '../../../hooks/useMatrixClient';
import {
getEditedEvent,
getMemberDisplayName,
getMemberName,
getMentionContent,
trimReplyFromFormattedBody,
} from '../../../utils/room';
import { getMxIdLocalPart } from '../../../utils/matrix';
import { mobileOrTablet } from '../../../utils/user-agent';
import { useComposingCheck } from '../../../hooks/useComposingCheck';
@@ -75,9 +74,7 @@ export const MessageEditor = as<'div', MessageEditorProps>(
// Accessible name for the edit textbox so screen readers announce which
// message is being edited (a11y, P3-4).
const editSenderId = mEvent.getSender();
const editSenderName = editSenderId
? (getMemberDisplayName(room, editSenderId) ?? getMxIdLocalPart(editSenderId) ?? editSenderId)
: '';
const editSenderName = editSenderId ? getMemberName(room, editSenderId) : '';
const [enterForNewline] = useSetting(settingsAtom, 'enterForNewline');
const [globalToolbar] = useSetting(settingsAtom, 'editorToolbar');
const [isMarkdown] = useSetting(settingsAtom, 'isMarkdown');
@@ -16,7 +16,7 @@ import {
} from 'folds';
import { MatrixEvent, Room, RoomMember } from 'matrix-js-sdk';
import { Relations } from 'matrix-js-sdk/lib/models/relations';
import { getMemberDisplayName } from '../../../utils/room';
import { getMemberName } from '../../../utils/room';
import { eventWithShortcode, getMxIdLocalPart } from '../../../utils/matrix';
import * as css from './ReactionViewer.css';
import { useMatrixClient } from '../../../hooks/useMatrixClient';
@@ -67,8 +67,7 @@ export const ReactionViewer = as<'div', ReactionViewerProps>(
}
};
const getName = (member: RoomMember) =>
getMemberDisplayName(room, member.userId) ?? getMxIdLocalPart(member.userId) ?? member.userId;
const getName = (member: RoomMember) => getMemberName(room, member.userId);
const getReactionsForKey = (key: string): MatrixEvent[] => {
const reactSet = reactions.find(([k]) => k === key)?.[1];
@@ -40,12 +40,12 @@ import {
UsernameBold,
} from '../../../components/message';
import { UserAvatar } from '../../../components/user-avatar';
import { getMxIdLocalPart, mxcUrlToHttp } from '../../../utils/matrix';
import { mxcUrlToHttp } from '../../../utils/matrix';
import { useMatrixClient } from '../../../hooks/useMatrixClient';
import {
getEditedEvent,
getMemberAvatarMxc,
getMemberDisplayName,
getMemberName,
getStateEvent,
} from '../../../utils/room';
import { GetContentCallback, MessageEvent, StateEvent } from '../../../../types/matrix/room';
@@ -175,7 +175,7 @@ function PinnedMessage({
);
const sender = pinnedEvent.getSender()!;
const displayName = getMemberDisplayName(room, sender) ?? getMxIdLocalPart(sender) ?? sender;
const displayName = getMemberName(room, sender);
const senderAvatarMxc = getMemberAvatarMxc(room, sender);
const getContent = (() => pinnedEvent.getContent()) as GetContentCallback;
@@ -32,7 +32,7 @@ import { useAtomValue, useSetAtom } from 'jotai';
import { Badge, Box, Chip, Icon, Icons, Line, Scroll, Spinner, Text, color, config } from 'folds';
import classNames from 'classnames';
import { Opts as LinkifyOpts } from 'linkifyjs';
import { eventWithShortcode, factoryEventSentBy, getMxIdLocalPart } from '../../../utils/matrix';
import { eventWithShortcode, factoryEventSentBy } from '../../../utils/matrix';
import { useMatrixClient } from '../../../hooks/useMatrixClient';
import { useVirtualPaginator, ItemRange } from '../../../hooks/useVirtualPaginator';
import { useAlive } from '../../../hooks/useAlive';
@@ -58,7 +58,7 @@ import {
decryptAllTimelineEvent,
getEditedEvent,
getEventReactions,
getMemberDisplayName,
getMemberName,
getReactionContent,
reactionOrEditEvent,
} from '../../../utils/room';
@@ -503,7 +503,7 @@ export function ThreadTimeline({ room, thread, editor }: ThreadTimelineProps) {
evt.preventDefault();
const userId = evt.currentTarget.getAttribute('data-user-id');
if (!userId) return;
const name = getMemberDisplayName(room, userId) ?? getMxIdLocalPart(userId) ?? userId;
const name = getMemberName(room, userId);
editor.insertNode(
createMentionElement(
userId,
@@ -651,8 +651,7 @@ export function ThreadTimeline({ room, thread, editor }: ThreadTimelineProps) {
const getContent = (() =>
editedEvent?.getContent()['m.new_content'] ?? mEvent.getContent()) as GetContentCallback;
const senderId = mEvent.getSender() ?? '';
const senderDisplayName =
getMemberDisplayName(room, senderId) ?? getMxIdLocalPart(senderId) ?? senderId;
const senderDisplayName = getMemberName(room, senderId);
return (
<RenderMessageContent
displayName={senderDisplayName}