Merge branch 'dev' into feature/presence

This commit is contained in:
Kris Hu 2025-07-15 10:51:43 +08:00 committed by GitHub
commit aabe528037
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 58 additions and 13 deletions

View file

@ -9,7 +9,7 @@ import {
getSpaceRoomPath, getSpaceRoomPath,
} from '../pages/pathUtils'; } from '../pages/pathUtils';
import { useMatrixClient } from './useMatrixClient'; import { useMatrixClient } from './useMatrixClient';
import { getOrphanParents } from '../utils/room'; import { getOrphanParents, guessPerfectParent } from '../utils/room';
import { roomToParentsAtom } from '../state/room/roomToParents'; import { roomToParentsAtom } from '../state/room/roomToParents';
import { mDirectAtom } from '../state/mDirectList'; import { mDirectAtom } from '../state/mDirectList';
import { useSelectedSpace } from './router/useSelectedSpace'; import { useSelectedSpace } from './router/useSelectedSpace';
@ -39,19 +39,19 @@ export const useRoomNavigate = () => {
const orphanParents = openSpaceTimeline ? [roomId] : getOrphanParents(roomToParents, roomId); const orphanParents = openSpaceTimeline ? [roomId] : getOrphanParents(roomToParents, roomId);
if (orphanParents.length > 0) { if (orphanParents.length > 0) {
const pSpaceIdOrAlias = getCanonicalAliasOrRoomId( let parentSpace: string;
mx, if (spaceSelectedId && orphanParents.includes(spaceSelectedId)) {
spaceSelectedId && orphanParents.includes(spaceSelectedId) parentSpace = spaceSelectedId;
? spaceSelectedId } else {
: orphanParents[0] // TODO: better orphan parent selection. parentSpace = guessPerfectParent(mx, roomId, orphanParents) ?? orphanParents[0];
);
if (openSpaceTimeline) {
navigate(getSpaceRoomPath(pSpaceIdOrAlias, roomId, eventId), opts);
return;
} }
navigate(getSpaceRoomPath(pSpaceIdOrAlias, roomIdOrAlias, eventId), opts); const pSpaceIdOrAlias = getCanonicalAliasOrRoomId(mx, parentSpace);
navigate(
getSpaceRoomPath(pSpaceIdOrAlias, openSpaceTimeline ? roomId : roomIdOrAlias, eventId),
opts
);
return; return;
} }

View file

@ -50,7 +50,11 @@ export const getCanonicalAliasOrRoomId = (mx: MatrixClient, roomId: string): str
const room = mx.getRoom(roomId); const room = mx.getRoom(roomId);
if (!room) return roomId; if (!room) return roomId;
if (getStateEvent(room, StateEvent.RoomTombstone) !== undefined) return roomId; if (getStateEvent(room, StateEvent.RoomTombstone) !== undefined) return roomId;
return room.getCanonicalAlias() || roomId; const alias = room.getCanonicalAlias();
if (alias && getCanonicalAliasRoomId(mx, alias) === roomId) {
return alias;
}
return roomId;
}; };
export const getImageInfo = (img: HTMLImageElement, fileOrBlob: File | Blob): IImageInfo => { export const getImageInfo = (img: HTMLImageElement, fileOrBlob: File | Blob): IImageInfo => {

View file

@ -5,6 +5,7 @@ import {
EventTimelineSet, EventTimelineSet,
EventType, EventType,
IMentions, IMentions,
IPowerLevelsContent,
IPushRule, IPushRule,
IPushRules, IPushRules,
JoinRule, JoinRule,
@ -473,3 +474,43 @@ export const bannedInRooms = (mx: MatrixClient, rooms: string[], otherUserId: st
const banned = room.hasMembershipState(otherUserId, Membership.Ban); const banned = room.hasMembershipState(otherUserId, Membership.Ban);
return banned; return banned;
}); });
export const guessPerfectParent = (
mx: MatrixClient,
roomId: string,
parents: string[]
): string | undefined => {
if (parents.length === 1) {
return parents[0];
}
const getSpecialUsers = (rId: string): string[] => {
const r = mx.getRoom(rId);
const powerLevels =
r && getStateEvent(r, StateEvent.RoomPowerLevels)?.getContent<IPowerLevelsContent>();
const { users_default: usersDefault, users } = powerLevels ?? {};
if (typeof users !== 'object') return [];
const defaultPower = typeof usersDefault === 'number' ? usersDefault : 0;
return Object.keys(users).filter((userId) => users[userId] > defaultPower);
};
let perfectParent: string | undefined;
let score = 0;
const roomSpecialUsers = getSpecialUsers(roomId);
parents.forEach((parentId) => {
const parentSpecialUsers = getSpecialUsers(parentId);
const matchedUsersCount = parentSpecialUsers.filter((userId) =>
roomSpecialUsers.includes(userId)
).length;
if (matchedUsersCount > score) {
score = matchedUsersCount;
perfectParent = parentId;
}
});
return perfectParent;
};