feat: enhance room data retrieval with server domain extraction
This commit is contained in:
@@ -5,7 +5,7 @@ import { JoinRule, MatrixClient } from 'matrix-js-sdk';
|
|||||||
import { useAtomValue } from 'jotai';
|
import { useAtomValue } from 'jotai';
|
||||||
|
|
||||||
import { createMentionElement, moveCursor, replaceWithElement } from '../utils';
|
import { createMentionElement, moveCursor, replaceWithElement } from '../utils';
|
||||||
import { getDirectRoomAvatarUrl } from '../../../utils/room';
|
import { getDirectRoomAvatarUrl, guessPerfectParent } from '../../../utils/room';
|
||||||
import { useMatrixClient } from '../../../hooks/useMatrixClient';
|
import { useMatrixClient } from '../../../hooks/useMatrixClient';
|
||||||
import { AutocompleteQuery } from './autocompleteQuery';
|
import { AutocompleteQuery } from './autocompleteQuery';
|
||||||
import { AutocompleteMenu } from './AutocompleteMenu';
|
import { AutocompleteMenu } from './AutocompleteMenu';
|
||||||
@@ -18,6 +18,7 @@ import { allRoomsAtom } from '../../../state/room-list/roomList';
|
|||||||
import { factoryRoomIdByActivity } from '../../../utils/sort';
|
import { factoryRoomIdByActivity } from '../../../utils/sort';
|
||||||
import { RoomAvatar, RoomIcon } from '../../room-avatar';
|
import { RoomAvatar, RoomIcon } from '../../room-avatar';
|
||||||
import { getViaServers } from '../../../plugins/via-servers';
|
import { getViaServers } from '../../../plugins/via-servers';
|
||||||
|
import { roomToParentsAtom } from '../../../state/room/roomToParents';
|
||||||
|
|
||||||
type MentionAutoCompleteHandler = (roomAliasOrId: string, name: string) => void;
|
type MentionAutoCompleteHandler = (roomAliasOrId: string, name: string) => void;
|
||||||
|
|
||||||
@@ -78,6 +79,7 @@ export function RoomMentionAutocomplete({
|
|||||||
}: RoomMentionAutocompleteProps) {
|
}: RoomMentionAutocompleteProps) {
|
||||||
const mx = useMatrixClient();
|
const mx = useMatrixClient();
|
||||||
const mDirects = useAtomValue(mDirectAtom);
|
const mDirects = useAtomValue(mDirectAtom);
|
||||||
|
const roomToParents = useAtomValue(roomToParentsAtom);
|
||||||
|
|
||||||
const allRooms = useAtomValue(allRoomsAtom).sort(factoryRoomIdByActivity(mx));
|
const allRooms = useAtomValue(allRoomsAtom).sort(factoryRoomIdByActivity(mx));
|
||||||
|
|
||||||
@@ -103,6 +105,42 @@ export function RoomMentionAutocomplete({
|
|||||||
else resetSearch();
|
else resetSearch();
|
||||||
}, [query.text, search, resetSearch]);
|
}, [query.text, search, resetSearch]);
|
||||||
|
|
||||||
|
// Build space hierarchy path for a room
|
||||||
|
const getSpacePath = useCallback((rId: string): string | null => {
|
||||||
|
// Skip DMs
|
||||||
|
if (mDirects.has(rId)) return null;
|
||||||
|
|
||||||
|
const buildParentChain = (currentRoomId: string): string[] => {
|
||||||
|
const parents = roomToParents.get(currentRoomId);
|
||||||
|
if (!parents || parents.size === 0) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
const parentsList = Array.from(parents);
|
||||||
|
let chosenParent: string;
|
||||||
|
|
||||||
|
if (parentsList.length === 1) {
|
||||||
|
chosenParent = parentsList[0];
|
||||||
|
} else {
|
||||||
|
const orphanParents = parentsList.filter(p => !roomToParents.has(p));
|
||||||
|
if (orphanParents.length > 0) {
|
||||||
|
chosenParent = guessPerfectParent(mx, currentRoomId, orphanParents) ?? orphanParents[0];
|
||||||
|
} else {
|
||||||
|
chosenParent = parentsList[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const parentRoom = mx.getRoom(chosenParent);
|
||||||
|
if (!parentRoom?.name) return [];
|
||||||
|
|
||||||
|
const upperChain = buildParentChain(chosenParent);
|
||||||
|
return [...upperChain, parentRoom.name];
|
||||||
|
};
|
||||||
|
|
||||||
|
const parentChain = buildParentChain(rId);
|
||||||
|
return parentChain.length > 0 ? parentChain.join(' > ') : null;
|
||||||
|
}, [mx, mDirects, roomToParents]);
|
||||||
|
|
||||||
const handleAutocomplete: MentionAutoCompleteHandler = (roomAliasOrId, name) => {
|
const handleAutocomplete: MentionAutoCompleteHandler = (roomAliasOrId, name) => {
|
||||||
const mentionRoom = mx.getRoom(roomAliasOrId);
|
const mentionRoom = mx.getRoom(roomAliasOrId);
|
||||||
const viaServers = mentionRoom ? getViaServers(mentionRoom) : undefined;
|
const viaServers = mentionRoom ? getViaServers(mentionRoom) : undefined;
|
||||||
@@ -144,6 +182,11 @@ export function RoomMentionAutocomplete({
|
|||||||
|
|
||||||
const handleSelect = () => handleAutocomplete(room.getCanonicalAlias() ?? rId, room.name);
|
const handleSelect = () => handleAutocomplete(room.getCanonicalAlias() ?? rId, room.name);
|
||||||
|
|
||||||
|
// Get space hierarchy path or canonical alias or empty string
|
||||||
|
const spacePath = getSpacePath(rId);
|
||||||
|
const alias = room.getCanonicalAlias();
|
||||||
|
const secondaryText = spacePath || alias || '';
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<MenuItem
|
<MenuItem
|
||||||
key={rId}
|
key={rId}
|
||||||
@@ -154,9 +197,11 @@ export function RoomMentionAutocomplete({
|
|||||||
}
|
}
|
||||||
onClick={handleSelect}
|
onClick={handleSelect}
|
||||||
after={
|
after={
|
||||||
<Text size="T200" priority="300" truncate>
|
secondaryText && (
|
||||||
{room.getCanonicalAlias() ?? ''}
|
<Text size="T200" priority="300" truncate>
|
||||||
</Text>
|
{secondaryText}
|
||||||
|
</Text>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
before={
|
before={
|
||||||
<Avatar size="200">
|
<Avatar size="200">
|
||||||
|
|||||||
@@ -305,12 +305,19 @@ async function getChannels(matrixClient: any) {
|
|||||||
|
|
||||||
return rooms
|
return rooms
|
||||||
.filter((room: any) => !room.isSpaceRoom())
|
.filter((room: any) => !room.isSpaceRoom())
|
||||||
.map((room: any) => ({
|
.map((room: any) => {
|
||||||
roomId: room.roomId,
|
// Extract server domain from roomId (!localpart:domain.tld)
|
||||||
name: room.name || 'Unnamed Room',
|
const serverMatch = room.roomId.match(/:(.+)$/);
|
||||||
isDirect: room.getMyMembership() === 'invite' ? false : room.guessDMUserId() !== null,
|
const server = serverMatch ? serverMatch[1] : null;
|
||||||
avatar: room.getMxcAvatarUrl() || null,
|
|
||||||
}))
|
return {
|
||||||
|
roomId: room.roomId,
|
||||||
|
name: room.name || 'Unnamed Room',
|
||||||
|
server: server,
|
||||||
|
isDirect: room.getMyMembership() === 'invite' ? false : room.guessDMUserId() !== null,
|
||||||
|
avatar: room.getMxcAvatarUrl() || null,
|
||||||
|
};
|
||||||
|
})
|
||||||
.sort((a: any, b: any) => a.name.localeCompare(b.name));
|
.sort((a: any, b: any) => a.name.localeCompare(b.name));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -362,9 +369,14 @@ async function getCurrentRoom(matrixClient: any) {
|
|||||||
throw new Error(`Current room not found: ${currentRoomId}`);
|
throw new Error(`Current room not found: ${currentRoomId}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Extract server domain from roomId (!localpart:domain.tld)
|
||||||
|
const serverMatch = room.roomId.match(/:(.+)$/);
|
||||||
|
const server = serverMatch ? serverMatch[1] : null;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
roomId: room.roomId,
|
roomId: room.roomId,
|
||||||
name: room.name || 'Unnamed Room',
|
name: room.name || 'Unnamed Room',
|
||||||
|
server: server,
|
||||||
avatar: room.getMxcAvatarUrl() || null,
|
avatar: room.getMxcAvatarUrl() || null,
|
||||||
isDirect: room.guessDMUserId() !== null,
|
isDirect: room.guessDMUserId() !== null,
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user