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
parent 165714e133
commit 8c0e2b4250
22 changed files with 62 additions and 98 deletions
+4 -8
View File
@@ -59,7 +59,7 @@ import { useTheme, ThemeKind } from '../hooks/useTheme';
import { useReducedMotion } from '../hooks/useReducedMotion'; import { useReducedMotion } from '../hooks/useReducedMotion';
import { useSetting } from '../state/hooks/settings'; import { useSetting } from '../state/hooks/settings';
import { settingsAtom } from '../state/settings'; import { settingsAtom } from '../state/settings';
import { getStateEvent, getStateEvents, getMemberDisplayName } from '../utils/room'; import { getStateEvent, getStateEvents, getMemberName } from '../utils/room';
import { StateEvent } from '../../types/matrix/room'; import { StateEvent } from '../../types/matrix/room';
import { getPowersLevelFromMatrixEvent } from '../hooks/usePowerLevels'; import { getPowersLevelFromMatrixEvent } from '../hooks/usePowerLevels';
import { getRoomCreatorsForRoomId } from '../hooks/useRoomCreators'; import { getRoomCreatorsForRoomId } from '../hooks/useRoomCreators';
@@ -161,9 +161,7 @@ function IncomingCall({ dm, info, onIgnore, onAnswer, onReject }: IncomingCallPr
<Dialog style={{ maxWidth: toRem(324) }}> <Dialog style={{ maxWidth: toRem(324) }}>
<Box style={{ padding: config.space.S400 }} direction="Column" gap="700"> <Box style={{ padding: config.space.S400 }} direction="Column" gap="700">
<Text size="T200" align="Center"> <Text size="T200" align="Center">
{getMemberDisplayName(info.room, info.sender) ?? {getMemberName(info.room, info.sender)}
getMxIdLocalPart(info.sender) ??
info.sender}
</Text> </Text>
<Box direction="Column" gap="500" alignItems="Center"> <Box direction="Column" gap="500" alignItems="Center">
<Box shrink="No"> <Box shrink="No">
@@ -316,8 +314,7 @@ function IncomingCallBanner({ dm, info, onIgnore, onAnswer, onReject }: Incoming
return () => clearTimeout(id); return () => clearTimeout(id);
}, [info.senderTs, info.lifetime, onIgnore]); }, [info.senderTs, info.lifetime, onIgnore]);
const callerName = const callerName = getMemberName(info.room, info.sender);
getMemberDisplayName(info.room, info.sender) ?? getMxIdLocalPart(info.sender) ?? info.sender;
return ( return (
<Box <Box
@@ -453,8 +450,7 @@ function IncomingCallListener({ callEmbed, joined }: IncomingCallListenerProps)
decliner !== mx.getSafeUserId() && decliner !== mx.getSafeUserId() &&
callEmbed?.roomId === room.roomId callEmbed?.roomId === room.roomId
) { ) {
const declinerName = const declinerName = getMemberName(room, decliner);
getMemberDisplayName(room, decliner) ?? getMxIdLocalPart(decliner) ?? decliner;
setToast({ setToast({
id: `rtc-decline-${event.getId() ?? decliner}`, id: `rtc-decline-${event.getId() ?? decliner}`,
displayName: declinerName, displayName: declinerName,
@@ -16,7 +16,7 @@ import { onTabPress } from '../../../utils/keyboard';
import { createMentionElement, moveCursor, replaceWithElement } from '../utils'; import { createMentionElement, moveCursor, replaceWithElement } from '../utils';
import { useKeyDown } from '../../../hooks/useKeyDown'; import { useKeyDown } from '../../../hooks/useKeyDown';
import { getMxIdLocalPart, getMxIdServer, isUserId } from '../../../utils/matrix'; import { getMxIdLocalPart, getMxIdServer, isUserId } from '../../../utils/matrix';
import { getMemberDisplayName, getMemberSearchStr } from '../../../utils/room'; import { getMemberName, getMemberSearchStr } from '../../../utils/room';
import { UserAvatar } from '../../user-avatar'; import { UserAvatar } from '../../user-avatar';
import { useMediaAuthentication } from '../../../hooks/useMediaAuthentication'; import { useMediaAuthentication } from '../../../hooks/useMediaAuthentication';
import { Membership } from '../../../../types/matrix/room'; import { Membership } from '../../../../types/matrix/room';
@@ -140,8 +140,7 @@ export function UserMentionAutocomplete({
}); });
}); });
const getName = (member: RoomMember) => const getName = (member: RoomMember) => getMemberName(room, member.userId);
getMemberDisplayName(room, member.userId) ?? getMxIdLocalPart(member.userId) ?? member.userId;
return ( return (
<AutocompleteMenu headerContent={<Text size="L400">Mentions</Text>} requestClose={requestClose}> <AutocompleteMenu headerContent={<Text size="L400">Mentions</Text>} requestClose={requestClose}>
@@ -1,13 +1,12 @@
import React, { ReactNode } from 'react'; import React, { ReactNode } from 'react';
import { as, Avatar, Box, Icon, Icons, Text } from 'folds'; import { as, Avatar, Box, Icon, Icons, Text } from 'folds';
import { MatrixClient, Room, RoomMember } from 'matrix-js-sdk'; import { MatrixClient, Room, RoomMember } from 'matrix-js-sdk';
import { getMemberDisplayName } from '../../utils/room'; import { getMemberName } from '../../utils/room';
import { getMxIdLocalPart } from '../../utils/matrix'; import { getMxIdLocalPart } from '../../utils/matrix';
import { UserAvatar } from '../user-avatar'; import { UserAvatar } from '../user-avatar';
import * as css from './style.css'; import * as css from './style.css';
const getName = (room: Room, member: RoomMember) => const getName = (room: Room, member: RoomMember) => getMemberName(room, member.userId);
getMemberDisplayName(room, member.userId) ?? getMxIdLocalPart(member.userId) ?? member.userId;
type MemberTileProps = { type MemberTileProps = {
mx: MatrixClient; mx: MatrixClient;
+3 -4
View File
@@ -20,8 +20,8 @@ import FocusTrap from 'focus-trap-react';
import { Room } from 'matrix-js-sdk'; import { Room } from 'matrix-js-sdk';
import * as css from './styles.css'; import * as css from './styles.css';
import { stopPropagation } from '../../utils/keyboard'; import { stopPropagation } from '../../utils/keyboard';
import { getMemberAvatarMxc, getMemberDisplayName } from '../../utils/room'; import { getMemberAvatarMxc, getMemberName } from '../../utils/room';
import { getMxIdLocalPart, mxcUrlToHttp } from '../../utils/matrix'; import { mxcUrlToHttp } from '../../utils/matrix';
import { useMatrixClient } from '../../hooks/useMatrixClient'; import { useMatrixClient } from '../../hooks/useMatrixClient';
import { useMediaAuthentication } from '../../hooks/useMediaAuthentication'; import { useMediaAuthentication } from '../../hooks/useMediaAuthentication';
import { UserAvatar } from '../../components/user-avatar'; import { UserAvatar } from '../../components/user-avatar';
@@ -77,8 +77,7 @@ export function LiveChip({ count, room, members }: LiveChipProps) {
{members.map((callMember) => { {members.map((callMember) => {
const userId = callMember.sender; const userId = callMember.sender;
if (!userId) return null; if (!userId) return null;
const name = const name = getMemberName(room, userId);
getMemberDisplayName(room, userId) ?? getMxIdLocalPart(userId) ?? userId;
const avatarMxc = getMemberAvatarMxc(room, userId); const avatarMxc = getMemberAvatarMxc(room, userId);
const avatarUrl = avatarMxc const avatarUrl = avatarMxc
? (mxcUrlToHttp(mx, avatarMxc, useAuthentication, 96, 96) ?? undefined) ? (mxcUrlToHttp(mx, avatarMxc, useAuthentication, 96, 96) ?? undefined)
@@ -4,8 +4,8 @@ import React, { useState } from 'react';
import FocusTrap from 'focus-trap-react'; import FocusTrap from 'focus-trap-react';
import { Room } from 'matrix-js-sdk'; import { Room } from 'matrix-js-sdk';
import { UserAvatar } from '../../components/user-avatar'; import { UserAvatar } from '../../components/user-avatar';
import { getMemberAvatarMxc, getMemberDisplayName } from '../../utils/room'; import { getMemberAvatarMxc, getMemberName } from '../../utils/room';
import { getMxIdLocalPart, mxcUrlToHttp } from '../../utils/matrix'; import { mxcUrlToHttp } from '../../utils/matrix';
import { useMatrixClient } from '../../hooks/useMatrixClient'; import { useMatrixClient } from '../../hooks/useMatrixClient';
import { useMediaAuthentication } from '../../hooks/useMediaAuthentication'; import { useMediaAuthentication } from '../../hooks/useMediaAuthentication';
import { StackedAvatar } from '../../components/stacked-avatar'; import { StackedAvatar } from '../../components/stacked-avatar';
@@ -128,7 +128,7 @@ export function MemberGlance({ room, members, speakers, callEmbed, max = 6 }: Me
{visibleMembers.map((callMember) => { {visibleMembers.map((callMember) => {
const { userId } = callMember; const { userId } = callMember;
if (!userId) return null; if (!userId) return null;
const name = getMemberDisplayName(room, userId) ?? getMxIdLocalPart(userId) ?? userId; const name = getMemberName(room, userId);
const avatarMxc = getMemberAvatarMxc(room, userId); const avatarMxc = getMemberAvatarMxc(room, userId);
const avatarUrl = avatarMxc const avatarUrl = avatarMxc
? (mxcUrlToHttp(mx, avatarMxc, useAuthentication, 96, 96) ?? undefined) ? (mxcUrlToHttp(mx, avatarMxc, useAuthentication, 96, 96) ?? undefined)
@@ -1,17 +1,14 @@
import { Room } from 'matrix-js-sdk'; import { Room } from 'matrix-js-sdk';
import React from 'react'; import React from 'react';
import { Box, Icon, Icons, Text } from 'folds'; import { Box, Icon, Icons, Text } from 'folds';
import { getMemberDisplayName } from '../../utils/room'; import { getMemberName } from '../../utils/room';
import { getMxIdLocalPart } from '../../utils/matrix';
type MemberSpeakingProps = { type MemberSpeakingProps = {
room: Room; room: Room;
speakers: Set<string>; speakers: Set<string>;
}; };
export function MemberSpeaking({ room, speakers }: MemberSpeakingProps) { export function MemberSpeaking({ room, speakers }: MemberSpeakingProps) {
const speakingNames = Array.from(speakers).map( const speakingNames = Array.from(speakers).map((userId) => getMemberName(room, userId));
(userId) => getMemberDisplayName(room, userId) ?? getMxIdLocalPart(userId) ?? userId,
);
return ( return (
<Box alignItems="Center" gap="100"> <Box alignItems="Center" gap="100">
<Icon size="100" src={Icons.Mic} filled /> <Icon size="100" src={Icons.Mic} filled />
+3 -3
View File
@@ -5,9 +5,9 @@ import { useMatrixClient } from '../../hooks/useMatrixClient';
import { useMediaAuthentication } from '../../hooks/useMediaAuthentication'; import { useMediaAuthentication } from '../../hooks/useMediaAuthentication';
import { useOpenUserRoomProfile } from '../../state/hooks/userRoomProfile'; import { useOpenUserRoomProfile } from '../../state/hooks/userRoomProfile';
import { SequenceCard } from '../../components/sequence-card'; import { SequenceCard } from '../../components/sequence-card';
import { getMemberAvatarMxc, getMemberDisplayName } from '../../utils/room'; import { getMemberAvatarMxc, getMemberName } from '../../utils/room';
import { useRoom } from '../../hooks/useRoom'; import { useRoom } from '../../hooks/useRoom';
import { getMxIdLocalPart, mxcUrlToHttp } from '../../utils/matrix'; import { mxcUrlToHttp } from '../../utils/matrix';
import { UserAvatar } from '../../components/user-avatar'; import { UserAvatar } from '../../components/user-avatar';
import { AvatarDecoration } from '../../components/avatar-decoration/AvatarDecoration'; import { AvatarDecoration } from '../../components/avatar-decoration/AvatarDecoration';
import { getMouseEventCords } from '../../utils/dom'; import { getMouseEventCords } from '../../utils/dom';
@@ -26,7 +26,7 @@ export function CallMemberCard({ member }: CallMemberCardProps) {
const { userId } = member; const { userId } = member;
if (!userId) return null; if (!userId) return null;
const name = getMemberDisplayName(room, userId) ?? getMxIdLocalPart(userId) ?? userId; const name = getMemberName(room, userId);
const avatarMxc = getMemberAvatarMxc(room, userId); const avatarMxc = getMemberAvatarMxc(room, userId);
const avatarUrl = avatarMxc const avatarUrl = avatarMxc
? (mxcUrlToHttp(mx, avatarMxc, useAuthentication, 96, 96) ?? undefined) ? (mxcUrlToHttp(mx, avatarMxc, useAuthentication, 96, 96) ?? undefined)
@@ -12,7 +12,7 @@ import {
makeMentionCustomProps, makeMentionCustomProps,
renderMatrixMention, renderMatrixMention,
} from '../../plugins/react-custom-html-parser'; } from '../../plugins/react-custom-html-parser';
import { getMxIdLocalPart, mxcUrlToHttp } from '../../utils/matrix'; import { mxcUrlToHttp } from '../../utils/matrix';
import { useMatrixEventRenderer } from '../../hooks/useMatrixEventRenderer'; import { useMatrixEventRenderer } from '../../hooks/useMatrixEventRenderer';
import { GetContentCallback, MessageEvent, StateEvent } from '../../../types/matrix/room'; import { GetContentCallback, MessageEvent, StateEvent } from '../../../types/matrix/room';
import { import {
@@ -31,7 +31,7 @@ import { Image } from '../../components/media';
import { ImageViewer } from '../../components/image-viewer'; import { ImageViewer } from '../../components/image-viewer';
import * as customHtmlCss from '../../styles/CustomHtml.css'; import * as customHtmlCss from '../../styles/CustomHtml.css';
import { RoomAvatar, RoomIcon } from '../../components/room-avatar'; import { RoomAvatar, RoomIcon } from '../../components/room-avatar';
import { getMemberAvatarMxc, getMemberDisplayName, getRoomAvatarUrl } from '../../utils/room'; import { getMemberAvatarMxc, getMemberName, getRoomAvatarUrl } from '../../utils/room';
import { ResultItem } from './useMessageSearch'; import { ResultItem } from './useMessageSearch';
import { SequenceCard } from '../../components/sequence-card'; import { SequenceCard } from '../../components/sequence-card';
import { UserAvatar } from '../../components/user-avatar'; import { UserAvatar } from '../../components/user-avatar';
@@ -220,10 +220,7 @@ export function SearchResultGroup({
{items.map((item) => { {items.map((item) => {
const { event } = item; const { event } = item;
const displayName = const displayName = getMemberName(room, event.sender);
getMemberDisplayName(room, event.sender) ??
getMxIdLocalPart(event.sender) ??
event.sender;
const senderAvatarMxc = getMemberAvatarMxc(room, event.sender); const senderAvatarMxc = getMemberAvatarMxc(room, event.sender);
const relation = event.content['m.relates_to']; const relation = event.content['m.relates_to'];
@@ -6,8 +6,8 @@ import { SequenceCard } from '../../components/sequence-card';
import { useRoom } from '../../hooks/useRoom'; import { useRoom } from '../../hooks/useRoom';
import { useMatrixClient } from '../../hooks/useMatrixClient'; import { useMatrixClient } from '../../hooks/useMatrixClient';
import { useMediaAuthentication } from '../../hooks/useMediaAuthentication'; import { useMediaAuthentication } from '../../hooks/useMediaAuthentication';
import { getMemberAvatarMxc, getMemberDisplayName } from '../../utils/room'; import { getMemberAvatarMxc, getMemberName } from '../../utils/room';
import { getMxIdLocalPart, mxcUrlToHttp } from '../../utils/matrix'; import { mxcUrlToHttp } from '../../utils/matrix';
import { UserAvatar } from '../../components/user-avatar'; import { UserAvatar } from '../../components/user-avatar';
// ── Helpers ─────────────────────────────────────────────────────────────────── // ── Helpers ───────────────────────────────────────────────────────────────────
@@ -297,8 +297,7 @@ export function RoomInsights({ requestClose }: RoomInsightsProps) {
<SectionHeader label="Most Active Members" /> <SectionHeader label="Most Active Members" />
<Box direction="Column" gap="200"> <Box direction="Column" gap="200">
{stats.top5.map(([userId, count], index) => { {stats.top5.map(([userId, count], index) => {
const displayName = const displayName = getMemberName(room, userId);
getMemberDisplayName(room, userId) ?? getMxIdLocalPart(userId) ?? userId;
const avatarMxc = getMemberAvatarMxc(room, userId); const avatarMxc = getMemberAvatarMxc(room, userId);
const avatarUrl = avatarMxc const avatarUrl = avatarMxc
? (mxcUrlToHttp(mx, avatarMxc, useAuthentication, 32, 32, 'crop') ?? ? (mxcUrlToHttp(mx, avatarMxc, useAuthentication, 32, 32, 'crop') ??
+3 -7
View File
@@ -42,7 +42,7 @@ import {
} from '../../hooks/useAsyncSearch'; } from '../../hooks/useAsyncSearch';
import { useDebounce } from '../../hooks/useDebounce'; import { useDebounce } from '../../hooks/useDebounce';
import { TypingIndicator } from '../../components/typing-indicator'; import { TypingIndicator } from '../../components/typing-indicator';
import { getMemberDisplayName, getMemberSearchStr } from '../../utils/room'; import { getMemberName, getMemberSearchStr } from '../../utils/room';
import { getMxIdLocalPart } from '../../utils/matrix'; import { getMxIdLocalPart } from '../../utils/matrix';
import { useSetSetting, useSetting } from '../../state/hooks/settings'; import { useSetSetting, useSetting } from '../../state/hooks/settings';
import { settingsAtom } from '../../state/settings'; import { settingsAtom } from '../../state/settings';
@@ -134,8 +134,7 @@ function MemberItem({
typing, typing,
showEncryption, showEncryption,
}: MemberItemProps) { }: MemberItemProps) {
const name = const name = getMemberName(room, member.userId);
getMemberDisplayName(room, member.userId) ?? getMxIdLocalPart(member.userId) ?? member.userId;
const avatarMxcUrl = member.getMxcAvatarUrl(); const avatarMxcUrl = member.getMxcAvatarUrl();
const avatarUrl = avatarMxcUrl const avatarUrl = avatarMxcUrl
? mx.mxcUrlToHttp(avatarMxcUrl, 100, 100, 'crop', undefined, false, useAuthentication) ? mx.mxcUrlToHttp(avatarMxcUrl, 100, 100, 'crop', undefined, false, useAuthentication)
@@ -418,10 +417,7 @@ export function MembersDrawer({ room, members }: MembersDrawerProps) {
Pending Requests Pending Requests
</Text> </Text>
{knockMembers.map((knockMember) => { {knockMembers.map((knockMember) => {
const knockName = const knockName = getMemberName(room, knockMember.userId);
getMemberDisplayName(room, knockMember.userId) ??
getMxIdLocalPart(knockMember.userId) ??
knockMember.userId;
const knockAvatarMxc = knockMember.getMxcAvatarUrl(); const knockAvatarMxc = knockMember.getMxcAvatarUrl();
const knockAvatarUrl = knockAvatarMxc const knockAvatarUrl = knockAvatarMxc
? mx.mxcUrlToHttp( ? mx.mxcUrlToHttp(
+2 -7
View File
@@ -65,7 +65,6 @@ import {
TUploadContent, TUploadContent,
encryptFile, encryptFile,
getImageInfo, getImageInfo,
getMxIdLocalPart,
mxcUrlToHttp, mxcUrlToHttp,
tryDeleteMxcContent, tryDeleteMxcContent,
} from '../../utils/matrix'; } from '../../utils/matrix';
@@ -111,7 +110,7 @@ import {
getImageMsgContent, getImageMsgContent,
getVideoMsgContent, getVideoMsgContent,
} from './msgContent'; } from './msgContent';
import { getMemberDisplayName, getMentionContent, trimReplyFromBody } from '../../utils/room'; import { getMemberName, getMentionContent, trimReplyFromBody } from '../../utils/room';
import { CommandAutocomplete } from './CommandAutocomplete'; import { CommandAutocomplete } from './CommandAutocomplete';
import { Command, SHRUG, TABLEFLIP, UNFLIP, useCommands } from '../../hooks/useCommands'; import { Command, SHRUG, TABLEFLIP, UNFLIP, useCommands } from '../../hooks/useCommands';
import { mobileOrTablet } from '../../utils/user-agent'; import { mobileOrTablet } from '../../utils/user-agent';
@@ -993,11 +992,7 @@ export const RoomInput = forwardRef<HTMLDivElement, RoomInputProps>(
userColor={replyUsernameColor} userColor={replyUsernameColor}
username={ username={
<Text size="T300" truncate> <Text size="T300" truncate>
<b> <b>{getMemberName(room, replyDraft.userId)}</b>
{getMemberDisplayName(room, replyDraft.userId) ??
getMxIdLocalPart(replyDraft.userId) ??
replyDraft.userId}
</b>
</Text> </Text>
} }
> >
+4 -5
View File
@@ -81,6 +81,7 @@ import {
getEventReactions, getEventReactions,
getLatestEditableEvt, getLatestEditableEvt,
getMemberDisplayName, getMemberDisplayName,
getMemberName,
getReactionContent, getReactionContent,
isMembershipChanged, isMembershipChanged,
reactionOrEditEvent, reactionOrEditEvent,
@@ -1007,7 +1008,7 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli
console.warn('Button should have "data-user-id" attribute!'); console.warn('Button should have "data-user-id" attribute!');
return; return;
} }
const name = getMemberDisplayName(room, userId) ?? getMxIdLocalPart(userId) ?? userId; const name = getMemberName(room, userId);
editor.insertNode( editor.insertNode(
createMentionElement( createMentionElement(
userId, userId,
@@ -1106,8 +1107,7 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli
editedEvent?.getContent()['m.new_content'] ?? mEvent.getContent()) as GetContentCallback; editedEvent?.getContent()['m.new_content'] ?? mEvent.getContent()) as GetContentCallback;
const senderId = mEvent.getSender() ?? ''; const senderId = mEvent.getSender() ?? '';
const senderDisplayName = const senderDisplayName = getMemberName(room, senderId);
getMemberDisplayName(room, senderId) ?? getMxIdLocalPart(senderId) ?? senderId;
return ( return (
<Message <Message
@@ -1290,8 +1290,7 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli
mEvent.getContent()) as GetContentCallback; mEvent.getContent()) as GetContentCallback;
const senderId = mEvent.getSender() ?? ''; const senderId = mEvent.getSender() ?? '';
const senderDisplayName = const senderDisplayName = getMemberName(room, senderId);
getMemberDisplayName(room, senderId) ?? getMxIdLocalPart(senderId) ?? senderId;
return ( return (
<RenderMessageContent <RenderMessageContent
displayName={senderDisplayName} displayName={senderDisplayName}
+2 -6
View File
@@ -15,8 +15,7 @@ import { Room } from 'matrix-js-sdk';
import classNames from 'classnames'; import classNames from 'classnames';
import FocusTrap from 'focus-trap-react'; import FocusTrap from 'focus-trap-react';
import { getMemberDisplayName } from '../../utils/room'; import { getMemberName } from '../../utils/room';
import { getMxIdLocalPart } from '../../utils/matrix';
import * as css from './RoomViewFollowing.css'; import * as css from './RoomViewFollowing.css';
import { useMatrixClient } from '../../hooks/useMatrixClient'; import { useMatrixClient } from '../../hooks/useMatrixClient';
import { useRoomLatestRenderedEvent } from '../../hooks/useRoomLatestRenderedEvent'; import { useRoomLatestRenderedEvent } from '../../hooks/useRoomLatestRenderedEvent';
@@ -39,10 +38,7 @@ export const RoomViewFollowing = as<'div', RoomViewFollowingProps>(
const latestEventReaders = useRoomEventReaders(room, latestEvent?.getId()); const latestEventReaders = useRoomEventReaders(room, latestEvent?.getId());
const names = latestEventReaders const names = latestEventReaders
.filter((readerId) => readerId !== mx.getUserId()) .filter((readerId) => readerId !== mx.getUserId())
.map( .map((readerId) => getMemberName(room, readerId));
(readerId) =>
getMemberDisplayName(room, readerId) ?? getMxIdLocalPart(readerId) ?? readerId,
);
const eventId = latestEvent?.getId(); const eventId = latestEvent?.getId();
+3 -4
View File
@@ -53,9 +53,9 @@ import {
canEditEvent, canEditEvent,
getEventEdits, getEventEdits,
getMemberAvatarMxc, getMemberAvatarMxc,
getMemberDisplayName, getMemberName,
} from '../../../utils/room'; } from '../../../utils/room';
import { getMxIdLocalPart, mxcUrlToHttp } from '../../../utils/matrix'; import { mxcUrlToHttp } from '../../../utils/matrix';
import { messageAriaLabel } from '../../../utils/a11y'; import { messageAriaLabel } from '../../../utils/a11y';
import { MessageLayout, MessageSpacing } from '../../../state/settings'; import { MessageLayout, MessageSpacing } from '../../../state/settings';
import { useMatrixClient } from '../../../hooks/useMatrixClient'; import { useMatrixClient } from '../../../hooks/useMatrixClient';
@@ -809,8 +809,7 @@ export const Message = React.memo(
const [remindOpen, setRemindOpen] = useState(false); const [remindOpen, setRemindOpen] = useState(false);
const { addBookmark, removeBookmark, isBookmarked } = useBookmarks(); const { addBookmark, removeBookmark, isBookmarked } = useBookmarks();
const senderDisplayName = const senderDisplayName = getMemberName(room, senderId);
getMemberDisplayName(room, senderId) ?? getMxIdLocalPart(senderId) ?? senderId;
const senderAvatarMxc = getMemberAvatarMxc(room, senderId); const senderAvatarMxc = getMemberAvatarMxc(room, senderId);
const tagColor = memberPowerTag?.color const tagColor = memberPowerTag?.color
@@ -53,11 +53,10 @@ import { AsyncStatus, useAsyncCallback } from '../../../hooks/useAsyncCallback';
import { useMatrixClient } from '../../../hooks/useMatrixClient'; import { useMatrixClient } from '../../../hooks/useMatrixClient';
import { import {
getEditedEvent, getEditedEvent,
getMemberDisplayName, getMemberName,
getMentionContent, getMentionContent,
trimReplyFromFormattedBody, trimReplyFromFormattedBody,
} from '../../../utils/room'; } from '../../../utils/room';
import { getMxIdLocalPart } from '../../../utils/matrix';
import { mobileOrTablet } from '../../../utils/user-agent'; import { mobileOrTablet } from '../../../utils/user-agent';
import { useComposingCheck } from '../../../hooks/useComposingCheck'; 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 // Accessible name for the edit textbox so screen readers announce which
// message is being edited (a11y, P3-4). // message is being edited (a11y, P3-4).
const editSenderId = mEvent.getSender(); const editSenderId = mEvent.getSender();
const editSenderName = editSenderId const editSenderName = editSenderId ? getMemberName(room, editSenderId) : '';
? (getMemberDisplayName(room, editSenderId) ?? getMxIdLocalPart(editSenderId) ?? editSenderId)
: '';
const [enterForNewline] = useSetting(settingsAtom, 'enterForNewline'); const [enterForNewline] = useSetting(settingsAtom, 'enterForNewline');
const [globalToolbar] = useSetting(settingsAtom, 'editorToolbar'); const [globalToolbar] = useSetting(settingsAtom, 'editorToolbar');
const [isMarkdown] = useSetting(settingsAtom, 'isMarkdown'); const [isMarkdown] = useSetting(settingsAtom, 'isMarkdown');
@@ -16,7 +16,7 @@ import {
} from 'folds'; } from 'folds';
import { MatrixEvent, Room, RoomMember } from 'matrix-js-sdk'; import { MatrixEvent, Room, RoomMember } from 'matrix-js-sdk';
import { Relations } from 'matrix-js-sdk/lib/models/relations'; 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 { eventWithShortcode, getMxIdLocalPart } from '../../../utils/matrix';
import * as css from './ReactionViewer.css'; import * as css from './ReactionViewer.css';
import { useMatrixClient } from '../../../hooks/useMatrixClient'; import { useMatrixClient } from '../../../hooks/useMatrixClient';
@@ -67,8 +67,7 @@ export const ReactionViewer = as<'div', ReactionViewerProps>(
} }
}; };
const getName = (member: RoomMember) => const getName = (member: RoomMember) => getMemberName(room, member.userId);
getMemberDisplayName(room, member.userId) ?? getMxIdLocalPart(member.userId) ?? member.userId;
const getReactionsForKey = (key: string): MatrixEvent[] => { const getReactionsForKey = (key: string): MatrixEvent[] => {
const reactSet = reactions.find(([k]) => k === key)?.[1]; const reactSet = reactions.find(([k]) => k === key)?.[1];
@@ -40,12 +40,12 @@ import {
UsernameBold, UsernameBold,
} from '../../../components/message'; } from '../../../components/message';
import { UserAvatar } from '../../../components/user-avatar'; import { UserAvatar } from '../../../components/user-avatar';
import { getMxIdLocalPart, mxcUrlToHttp } from '../../../utils/matrix'; import { mxcUrlToHttp } from '../../../utils/matrix';
import { useMatrixClient } from '../../../hooks/useMatrixClient'; import { useMatrixClient } from '../../../hooks/useMatrixClient';
import { import {
getEditedEvent, getEditedEvent,
getMemberAvatarMxc, getMemberAvatarMxc,
getMemberDisplayName, getMemberName,
getStateEvent, getStateEvent,
} from '../../../utils/room'; } from '../../../utils/room';
import { GetContentCallback, MessageEvent, StateEvent } from '../../../../types/matrix/room'; import { GetContentCallback, MessageEvent, StateEvent } from '../../../../types/matrix/room';
@@ -175,7 +175,7 @@ function PinnedMessage({
); );
const sender = pinnedEvent.getSender()!; const sender = pinnedEvent.getSender()!;
const displayName = getMemberDisplayName(room, sender) ?? getMxIdLocalPart(sender) ?? sender; const displayName = getMemberName(room, sender);
const senderAvatarMxc = getMemberAvatarMxc(room, sender); const senderAvatarMxc = getMemberAvatarMxc(room, sender);
const getContent = (() => pinnedEvent.getContent()) as GetContentCallback; 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 { Badge, Box, Chip, Icon, Icons, Line, Scroll, Spinner, Text, color, config } from 'folds';
import classNames from 'classnames'; import classNames from 'classnames';
import { Opts as LinkifyOpts } from 'linkifyjs'; 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 { useMatrixClient } from '../../../hooks/useMatrixClient';
import { useVirtualPaginator, ItemRange } from '../../../hooks/useVirtualPaginator'; import { useVirtualPaginator, ItemRange } from '../../../hooks/useVirtualPaginator';
import { useAlive } from '../../../hooks/useAlive'; import { useAlive } from '../../../hooks/useAlive';
@@ -58,7 +58,7 @@ import {
decryptAllTimelineEvent, decryptAllTimelineEvent,
getEditedEvent, getEditedEvent,
getEventReactions, getEventReactions,
getMemberDisplayName, getMemberName,
getReactionContent, getReactionContent,
reactionOrEditEvent, reactionOrEditEvent,
} from '../../../utils/room'; } from '../../../utils/room';
@@ -503,7 +503,7 @@ export function ThreadTimeline({ room, thread, editor }: ThreadTimelineProps) {
evt.preventDefault(); evt.preventDefault();
const userId = evt.currentTarget.getAttribute('data-user-id'); const userId = evt.currentTarget.getAttribute('data-user-id');
if (!userId) return; if (!userId) return;
const name = getMemberDisplayName(room, userId) ?? getMxIdLocalPart(userId) ?? userId; const name = getMemberName(room, userId);
editor.insertNode( editor.insertNode(
createMentionElement( createMentionElement(
userId, userId,
@@ -651,8 +651,7 @@ export function ThreadTimeline({ room, thread, editor }: ThreadTimelineProps) {
const getContent = (() => const getContent = (() =>
editedEvent?.getContent()['m.new_content'] ?? mEvent.getContent()) as GetContentCallback; editedEvent?.getContent()['m.new_content'] ?? mEvent.getContent()) as GetContentCallback;
const senderId = mEvent.getSender() ?? ''; const senderId = mEvent.getSender() ?? '';
const senderDisplayName = const senderDisplayName = getMemberName(room, senderId);
getMemberDisplayName(room, senderId) ?? getMxIdLocalPart(senderId) ?? senderId;
return ( return (
<RenderMessageContent <RenderMessageContent
displayName={senderDisplayName} displayName={senderDisplayName}
+3 -3
View File
@@ -27,13 +27,13 @@ import { useMatrixClient } from '../../hooks/useMatrixClient';
import { getDirectRoomPath, getHomeRoomPath, getInboxInvitesPath } from '../pathUtils'; import { getDirectRoomPath, getHomeRoomPath, getInboxInvitesPath } from '../pathUtils';
import { mDirectAtom } from '../../state/mDirectList'; import { mDirectAtom } from '../../state/mDirectList';
import { import {
getMemberDisplayName, getMemberName,
getNotificationType, getNotificationType,
getUnreadInfo, getUnreadInfo,
isNotificationEvent, isNotificationEvent,
} from '../../utils/room'; } from '../../utils/room';
import { NotificationType } from '../../../types/matrix/room'; import { NotificationType } from '../../../types/matrix/room';
import { getMxIdLocalPart, mxcUrlToHttp } from '../../utils/matrix'; import { mxcUrlToHttp } from '../../utils/matrix';
import { useSelectedRoom } from '../../hooks/router/useSelectedRoom'; import { useSelectedRoom } from '../../hooks/router/useSelectedRoom';
import { useInboxNotificationsSelected } from '../../hooks/router/useInbox'; import { useInboxNotificationsSelected } from '../../hooks/router/useInbox';
import { useMediaAuthentication } from '../../hooks/useMediaAuthentication'; import { useMediaAuthentication } from '../../hooks/useMediaAuthentication';
@@ -501,7 +501,7 @@ function MessageNotifications() {
roomAvatar: avatarMxc roomAvatar: avatarMxc
? (mxcUrlToHttp(mx, avatarMxc, useAuthentication, 96, 96, 'crop') ?? undefined) ? (mxcUrlToHttp(mx, avatarMxc, useAuthentication, 96, 96, 'crop') ?? undefined)
: undefined, : undefined,
username: getMemberDisplayName(room, sender) ?? getMxIdLocalPart(sender) ?? sender, username: getMemberName(room, sender),
roomId: room.roomId, roomId: room.roomId,
eventId, eventId,
body: (mEvent.getContent().body as string | undefined) ?? '', body: (mEvent.getContent().body as string | undefined) ?? '',
+2 -5
View File
@@ -37,7 +37,7 @@ import {
bannedInRooms, bannedInRooms,
getCommonRooms, getCommonRooms,
getDirectRoomAvatarUrl, getDirectRoomAvatarUrl,
getMemberDisplayName, getMemberName,
getRoomAvatarUrl, getRoomAvatarUrl,
getStateEvent, getStateEvent,
isDirectInvite, isDirectInvite,
@@ -48,7 +48,6 @@ import { RoomAvatar } from '../../../components/room-avatar';
import { import {
addRoomIdToMDirect, addRoomIdToMDirect,
declineInvite, declineInvite,
getMxIdLocalPart,
guessDmRoomUserId, guessDmRoomUserId,
rateLimitedActions, rateLimitedActions,
} from '../../../utils/matrix'; } from '../../../utils/matrix';
@@ -107,9 +106,7 @@ const makeInviteData = (mx: MatrixClient, room: Room, useAuthentication: boolean
const content = memberEvent?.getContent(); const content = memberEvent?.getContent();
const senderId = memberEvent?.getSender(); const senderId = memberEvent?.getSender();
const senderName = senderId const senderName = senderId ? getMemberName(room, senderId) : undefined;
? (getMemberDisplayName(room, senderId) ?? getMxIdLocalPart(senderId) ?? senderId)
: undefined;
const inviteTs = memberEvent?.getTs(); const inviteTs = memberEvent?.getTs();
const reason = const reason =
content && 'reason' in content && typeof content.reason === 'string' content && 'reason' in content && typeof content.reason === 'string'
+3 -6
View File
@@ -28,7 +28,7 @@ import { Opts as LinkifyOpts } from 'linkifyjs';
import { useAtomValue } from 'jotai'; import { useAtomValue } from 'jotai';
import { Page, PageContent, PageContentCenter, PageHeader } from '../../../components/page'; import { Page, PageContent, PageContentCenter, PageHeader } from '../../../components/page';
import { useMatrixClient } from '../../../hooks/useMatrixClient'; import { useMatrixClient } from '../../../hooks/useMatrixClient';
import { getMxIdLocalPart, mxcUrlToHttp } from '../../../utils/matrix'; import { mxcUrlToHttp } from '../../../utils/matrix';
import { InboxNotificationsPathSearchParams } from '../../paths'; import { InboxNotificationsPathSearchParams } from '../../paths';
import { AsyncStatus, useAsyncCallback } from '../../../hooks/useAsyncCallback'; import { AsyncStatus, useAsyncCallback } from '../../../hooks/useAsyncCallback';
import { SequenceCard } from '../../../components/sequence-card'; import { SequenceCard } from '../../../components/sequence-card';
@@ -36,7 +36,7 @@ import { RoomAvatar, RoomIcon } from '../../../components/room-avatar';
import { import {
getEditedEvent, getEditedEvent,
getMemberAvatarMxc, getMemberAvatarMxc,
getMemberDisplayName, getMemberName,
getRoomAvatarUrl, getRoomAvatarUrl,
} from '../../../utils/room'; } from '../../../utils/room';
import { ScrollTopContainer } from '../../../components/scroll-top-container'; import { ScrollTopContainer } from '../../../components/scroll-top-container';
@@ -448,10 +448,7 @@ function RoomNotificationsGroupComp({
{notifications.map((notification) => { {notifications.map((notification) => {
const { event } = notification; const { event } = notification;
const displayName = const displayName = getMemberName(room, event.sender);
getMemberDisplayName(room, event.sender) ??
getMxIdLocalPart(event.sender) ??
event.sender;
const senderAvatarMxc = getMemberAvatarMxc(room, event.sender); const senderAvatarMxc = getMemberAvatarMxc(room, event.sender);
const getContent = (() => event.content) as GetContentCallback; const getContent = (() => event.content) as GetContentCallback;
+4
View File
@@ -30,6 +30,7 @@ import {
UnreadInfo, UnreadInfo,
} from '../../types/matrix/room'; } from '../../types/matrix/room';
import { getMutedThreads, ThreadNotificationsContent } from './threadNotifications'; import { getMutedThreads, ThreadNotificationsContent } from './threadNotifications';
import { getMxIdLocalPart } from './matrix';
export const getStateEvent = ( export const getStateEvent = (
room: Room, room: Room,
@@ -405,6 +406,9 @@ export const getMemberDisplayName = (room: Room, userId: string): string | undef
return name; return name;
}; };
export const getMemberName = (room: Room, userId: string): string =>
getMemberDisplayName(room, userId) ?? getMxIdLocalPart(userId) ?? userId;
export const getMemberSearchStr = ( export const getMemberSearchStr = (
member: RoomMember, member: RoomMember,
query: string, query: string,