fix: rank from: autocomplete suggestions by homeserver + shared rooms

Users on the same homeserver (matrix.lotusguild.org) get +1000 to their
score, everyone else starts at +1 per shared room. Sorting by score
descending means @jared:matrix.lotusguild.org always appears before
@jared:matrix.org when both match the query.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-28 23:05:56 -04:00
parent 64029d9e8e
commit 2255795cae
@@ -21,7 +21,7 @@ import {
Text,
} from 'folds';
import { useMatrixClient } from '../../hooks/useMatrixClient';
import { getMxIdLocalPart, mxcUrlToHttp } from '../../utils/matrix';
import { getMxIdLocalPart, getMxIdServer, mxcUrlToHttp } from '../../utils/matrix';
import { UserAvatar } from '../../components/user-avatar';
import { useMediaAuthentication } from '../../hooks/useMediaAuthentication';
@@ -59,23 +59,33 @@ export function SearchInput({
const [fromQuery, setFromQuery] = useState('');
const [showSuggestions, setShowSuggestions] = useState(false);
// Collect users from room member lists — more reliable than mx.getUsers()
// which is sparse with lazy member loading enabled.
// Collect users from room member lists, scored for relevance.
// Score: same homeserver → +1000, each shared room → +1.
// This ensures @user:matrix.lotusguild.org ranks above @user:matrix.org.
const allUsers = useMemo<UserSuggestion[]>(() => {
const map = new Map<string, UserSuggestion>();
const myId = mx.getUserId();
const myServer = myId ? getMxIdServer(myId) : undefined;
const map = new Map<string, UserSuggestion & { score: number }>();
mx.getRooms().forEach((room) => {
room.getMembers().forEach((member) => {
if (member.userId !== myId && !map.has(member.userId)) {
if (member.userId === myId) return;
const existing = map.get(member.userId);
if (existing) {
existing.score += 1; // +1 per additional shared room
} else {
const homeserver = getMxIdServer(member.userId);
map.set(member.userId, {
userId: member.userId,
displayName: member.name ?? undefined,
avatarUrl: member.getMxcAvatarUrl() ?? undefined,
score: myServer && homeserver === myServer ? 1000 : 1,
});
}
});
});
return Array.from(map.values());
return Array.from(map.values()).sort((a, b) => b.score - a.score);
}, [mx]);
const suggestedUsers = useMemo(() => {