diff --git a/src/app/features/room/message/ForwardMessageDialog.tsx b/src/app/features/room/message/ForwardMessageDialog.tsx index 0a75c80e5..ef6f745e2 100644 --- a/src/app/features/room/message/ForwardMessageDialog.tsx +++ b/src/app/features/room/message/ForwardMessageDialog.tsx @@ -48,6 +48,7 @@ import { addRecentForwardTarget, } from '../../../state/recentForwardTargets'; import { buildForwardContent, buildPlaintextAttachmentContent } from './forwardContent'; +import { useLocalRoomNames } from '../../../hooks/useRoomMeta'; type RoomRowProps = { room: Room; @@ -58,6 +59,7 @@ type RoomRowProps = { sending: boolean; }; function RoomRow({ room, dm, useAuthentication, selected, onToggle, sending }: RoomRowProps) { + const localNames = useLocalRoomNames(); const mx = useMatrixClient(); const avatarMxc = room.getMxcAvatarUrl(); const avatarUrl = avatarMxc @@ -97,7 +99,7 @@ function RoomRow({ room, dm, useAuthentication, selected, onToggle, sending }: R > - {room.name} + {localNames[room.roomId] ?? room.name} {dm && ( @@ -212,6 +214,7 @@ function RecentChip({ onToggle: () => void; sending: boolean; }) { + const localNames = useLocalRoomNames(); const mx = useMatrixClient(); const avatarMxc = room.getMxcAvatarUrl(); const avatarUrl = avatarMxc @@ -240,7 +243,7 @@ function RecentChip({ } > - {room.name} + {localNames[room.roomId] ?? room.name} ); @@ -252,6 +255,7 @@ type Props = { }; export function ForwardMessageDialog({ mEvent, onClose }: Props) { + const localNames = useLocalRoomNames(); const mx = useMatrixClient(); const modalStyle = useModalStyle(400); const directs = useAtomValue(mDirectAtom); @@ -296,8 +300,10 @@ export function ForwardMessageDialog({ mEvent, onClose }: Props) { const filtered = useMemo(() => { if (!query) return allRooms; const q = query.toLowerCase(); - return allRooms.filter((r) => r.name.toLowerCase().includes(q)); - }, [allRooms, query]); + return allRooms.filter((r) => + [r.name, localNames[r.roomId]].some((nm) => nm?.toLowerCase().includes(q)), + ); + }, [allRooms, query, localNames]); // Resolve recent target ids to still-joined rooms (drop ones left/gone). const recentRooms = useMemo( diff --git a/src/app/features/search/Search.tsx b/src/app/features/search/Search.tsx index bafe6213d..88f1401bd 100644 --- a/src/app/features/search/Search.tsx +++ b/src/app/features/search/Search.tsx @@ -37,6 +37,7 @@ import { useAsyncSearch, UseAsyncSearchOptions, } from '../../hooks/useAsyncSearch'; +import { useLocalRoomNames } from '../../hooks/useRoomMeta'; import { useAllJoinedRoomsSet, useGetRoom } from '../../hooks/useGetRoom'; import { RoomAvatar, RoomIcon } from '../../components/room-avatar'; import { @@ -157,17 +158,20 @@ export function Search({ requestClose }: SearchProps) { const topActiveRooms = useTopActiveRooms(searchRoomType, rooms, directs, spaces); const targetRooms = useSearchTargetRooms(searchRoomType, rooms, directs, spaces); + const localNames = useLocalRoomNames(); const getTargetStr: SearchItemStrGetter = useCallback( (roomId: string) => { const roomName = getRoom(roomId)?.name ?? roomId; + // [Gitea #336] Match the user's own "Rename for me" name as well. + const names = localNames[roomId] ? [localNames[roomId], roomName] : [roomName]; if (mDirects.has(roomId)) { const targetUserId = getDmUserId(roomId, getRoom, mx.getSafeUserId()); const targetUsername = targetUserId && getMxIdLocalPart(targetUserId); - if (targetUsername) return [roomName, targetUsername]; + if (targetUsername) return [...names, targetUsername]; } - return roomName; + return names.length === 1 ? names[0] : names; }, - [getRoom, mDirects, mx], + [getRoom, mDirects, mx, localNames], ); const [result, search, resetSearch] = useAsyncSearch(targetRooms, getTargetStr, SEARCH_OPTIONS); @@ -388,8 +392,10 @@ export function Search({ requestClose }: SearchProps) { {queryHighlighRegex - ? highlightText(queryHighlighRegex, [room.name]) - : room.name} + ? highlightText(queryHighlighRegex, [ + localNames[room.roomId] ?? room.name, + ]) + : (localNames[room.roomId] ?? room.name)} {dmUsername && ( diff --git a/src/app/hooks/useRoomMeta.ts b/src/app/hooks/useRoomMeta.ts index abdd83c30..2ec70157c 100644 --- a/src/app/hooks/useRoomMeta.ts +++ b/src/app/hooks/useRoomMeta.ts @@ -102,6 +102,22 @@ export const useLocalRoomName = (room: Room): string => { return localNames[room.roomId] ?? name; }; +/** + * [Gitea #336] The whole "Rename for me" map, for lists that show many rooms + * (quick switcher, forward/share pickers) so they use the name the user sees in + * the sidebar, not the server name. + */ +export const useLocalRoomNames = (): Readonly> => { + const mx = useMatrixClient(); + return roomNamesStore.useValue(mx); +}; + +/** Non-hook read for notification paths (toast / OS notification titles). */ +export const getLocalRoomName = ( + mx: ReturnType, + roomId: string, +): string | undefined => roomNamesStore.getLatest(mx)[roomId]; + export const useHasLocalRoomName = (roomId: string): boolean => { const mx = useMatrixClient(); const localNames = roomNamesStore.useValue(mx); diff --git a/src/app/pages/client/ClientNonUIFeatures.tsx b/src/app/pages/client/ClientNonUIFeatures.tsx index f2b84ffed..84e3e9f8f 100644 --- a/src/app/pages/client/ClientNonUIFeatures.tsx +++ b/src/app/pages/client/ClientNonUIFeatures.tsx @@ -14,6 +14,7 @@ import { ThreadEvent, } from 'matrix-js-sdk'; import { useNotificationsQuiet } from '../../hooks/useNotificationsQuiet'; +import { getLocalRoomName } from '../../hooks/useRoomMeta'; import { roomToUnreadAtom } from '../../state/room/roomToUnread'; import NotificationSound from '../../../../public/sound/notification.ogg'; import InviteSound from '../../../../public/sound/invite.ogg'; @@ -639,7 +640,8 @@ function MessageNotifications() { const avatarMxc = room.getAvatarFallbackMember()?.getMxcAvatarUrl() ?? room.getMxcAvatarUrl(); notify({ - roomName: room.name ?? 'Unknown', + // [Gitea #336] the user's own "Rename for me" name when they set one + roomName: getLocalRoomName(mx, room.roomId) ?? room.name ?? 'Unknown', roomAvatar: avatarMxc ? (mxcUrlToHttp(mx, avatarMxc, useAuthentication, 96, 96, 'crop') ?? undefined) : undefined, @@ -808,7 +810,7 @@ function ReminderMonitor() { if (!firedRef.current.has(key)) { firedRef.current.add(key); const room = mx.getRoom(r.roomId); - const roomName = room?.name ?? 'Unknown Room'; + const roomName = getLocalRoomName(mx, r.roomId) ?? room?.name ?? 'Unknown Room'; // Reminders for E2EE rooms carry no text (account data is server- // readable), so resolve the body from the local timeline at fire time. const localBody = room?.findEventById(r.eventId)?.getContent()?.body; diff --git a/src/app/pages/client/share/Share.tsx b/src/app/pages/client/share/Share.tsx index 4c8391474..9e04fffd7 100644 --- a/src/app/pages/client/share/Share.tsx +++ b/src/app/pages/client/share/Share.tsx @@ -38,6 +38,7 @@ import { import { BlockType } from '../../../components/editor'; import { bytesToSize } from '../../../utils/common'; import { getHomePath } from '../../pathUtils'; +import { useLocalRoomNames } from '../../../hooks/useRoomMeta'; type Shared = { payload: SharePayload; files: File[] }; @@ -47,6 +48,7 @@ type Shared = { payload: SharePayload; files: File[] }; * as the draft) — the user still presses Send. */ export function Share() { + const localNames = useLocalRoomNames(); const mx = useMatrixClient(); const navigate = useNavigate(); const { navigateRoom } = useRoomNavigate(); @@ -69,8 +71,12 @@ export function Share() { .filter((r) => r.getMyMembership() === 'join' && !r.isSpaceRoom()) .sort((a, b) => (b.getLastActiveTimestamp() ?? 0) - (a.getLastActiveTimestamp() ?? 0)); const q = query.trim().toLowerCase(); - return q ? all.filter((r) => r.name.toLowerCase().includes(q)) : all; - }, [mx, query]); + return q + ? all.filter((r) => + [r.name, localNames[r.roomId]].some((nm) => nm?.toLowerCase().includes(q)), + ) + : all; + }, [mx, query, localNames]); // Written straight into the room's draft atoms so its composer shows the // upload board + text as soon as it mounts. @@ -210,6 +216,7 @@ function ShareRoomRow({ disabled: boolean; onPick: (room: Room) => void; }) { + const localNames = useLocalRoomNames(); const mx = useMatrixClient(); const avatarMxc = room.getMxcAvatarUrl(); const avatarUrl = avatarMxc @@ -237,7 +244,7 @@ function ShareRoomRow({ > - {room.name} + {localNames[room.roomId] ?? room.name} {dm && (