fix(dm-name): drop matrix-js-sdk mxid disambiguation suffix from DM room names by using peer rawDisplayName
This commit is contained in:
parent
d3e69e042f
commit
1ee1d50c41
1 changed files with 58 additions and 7 deletions
|
|
@ -1,9 +1,54 @@
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { RoomJoinRulesEventContent } from 'matrix-js-sdk/lib/types';
|
import { RoomJoinRulesEventContent } from 'matrix-js-sdk/lib/types';
|
||||||
import { Room, RoomEvent, RoomEventHandlerMap } from 'matrix-js-sdk';
|
import {
|
||||||
|
Room,
|
||||||
|
RoomEvent,
|
||||||
|
RoomEventHandlerMap,
|
||||||
|
RoomStateEvent,
|
||||||
|
} from 'matrix-js-sdk';
|
||||||
import { StateEvent } from '../../types/matrix/room';
|
import { StateEvent } from '../../types/matrix/room';
|
||||||
import { useStateEvent } from './useStateEvent';
|
import { useStateEvent } from './useStateEvent';
|
||||||
|
|
||||||
|
// matrix-js-sdk's `Room.name` for a DM with no explicit `m.room.name`
|
||||||
|
// event falls back to a disambiguated peer label and, in many SDK
|
||||||
|
// versions, suffixes the peer's MXID as `Display Name (@id:server)` —
|
||||||
|
// either always or whenever a display-name collision is suspected. That
|
||||||
|
// produces the «Alex (@test6:vojo.chat)» pattern users see in the DM
|
||||||
|
// list, chat header and room intro even though no two members share
|
||||||
|
// the same display name. The handle is already shown as a separate
|
||||||
|
// subline in the chat header, so the parenthetical is pure noise.
|
||||||
|
//
|
||||||
|
// Workaround: when the room has no explicit `m.room.name` and is a 1:1
|
||||||
|
// with exactly one other joined/invited member, take the peer's raw
|
||||||
|
// display name directly (`RoomMember.rawDisplayName` is the value from
|
||||||
|
// `m.room.member.content.displayname` without SDK disambiguation).
|
||||||
|
// Fall back to the local-part of the MXID, then the bare MXID. Group
|
||||||
|
// rooms and rooms with an explicit name keep the SDK output.
|
||||||
|
const resolveRoomName = (room: Room): string => {
|
||||||
|
const explicit = room.currentState.getStateEvents(StateEvent.RoomName, '');
|
||||||
|
if (explicit) return room.name;
|
||||||
|
|
||||||
|
const myUserId = room.client.getUserId();
|
||||||
|
if (myUserId) {
|
||||||
|
const peers = room
|
||||||
|
.getMembersWithMembership('join')
|
||||||
|
.concat(room.getMembersWithMembership('invite'))
|
||||||
|
.filter((m) => m.userId !== myUserId);
|
||||||
|
if (peers.length === 1) {
|
||||||
|
const peer = peers[0];
|
||||||
|
if (peer.rawDisplayName && peer.rawDisplayName.trim()) {
|
||||||
|
return peer.rawDisplayName.trim();
|
||||||
|
}
|
||||||
|
const local = peer.userId.startsWith('@')
|
||||||
|
? peer.userId.slice(1).split(':')[0]
|
||||||
|
: peer.userId;
|
||||||
|
return local || peer.userId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return room.name;
|
||||||
|
};
|
||||||
|
|
||||||
export const useRoomAvatar = (room: Room, dm?: boolean): string | undefined => {
|
export const useRoomAvatar = (room: Room, dm?: boolean): string | undefined => {
|
||||||
const avatarEvent = useStateEvent(room, StateEvent.RoomAvatar);
|
const avatarEvent = useStateEvent(room, StateEvent.RoomAvatar);
|
||||||
|
|
||||||
|
|
@ -17,17 +62,23 @@ export const useRoomAvatar = (room: Room, dm?: boolean): string | undefined => {
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useRoomName = (room: Room): string => {
|
export const useRoomName = (room: Room): string => {
|
||||||
const [name, setName] = useState(room.name);
|
const [name, setName] = useState(() => resolveRoomName(room));
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setName(room.name);
|
setName(resolveRoomName(room));
|
||||||
|
|
||||||
const handleRoomNameChange: RoomEventHandlerMap[RoomEvent.Name] = () => {
|
const recompute: RoomEventHandlerMap[RoomEvent.Name] = () => {
|
||||||
setName(room.name);
|
setName(resolveRoomName(room));
|
||||||
};
|
};
|
||||||
room.on(RoomEvent.Name, handleRoomNameChange);
|
// RoomEvent.Name fires when m.room.name changes;
|
||||||
|
// RoomStateEvent.Members fires on every m.room.member event,
|
||||||
|
// covering both display-name updates of the peer and membership
|
||||||
|
// flips that could change which member counts as the DM peer.
|
||||||
|
room.on(RoomEvent.Name, recompute);
|
||||||
|
room.currentState.on(RoomStateEvent.Members, recompute);
|
||||||
return () => {
|
return () => {
|
||||||
room.removeListener(RoomEvent.Name, handleRoomNameChange);
|
room.removeListener(RoomEvent.Name, recompute);
|
||||||
|
room.currentState.removeListener(RoomStateEvent.Members, recompute);
|
||||||
};
|
};
|
||||||
}, [room]);
|
}, [room]);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue