getSpaceRoomPath,
} from '../pages/pathUtils';
import { useMatrixClient } from './useMatrixClient';
-import { getOrphanParents } from '../utils/room';
+import { getOrphanParents, guessPerfectParent } from '../utils/room';
import { roomToParentsAtom } from '../state/room/roomToParents';
import { mDirectAtom } from '../state/mDirectList';
import { useSelectedSpace } from './router/useSelectedSpace';
const orphanParents = openSpaceTimeline ? [roomId] : getOrphanParents(roomToParents, roomId);
if (orphanParents.length > 0) {
- const pSpaceIdOrAlias = getCanonicalAliasOrRoomId(
- mx,
- spaceSelectedId && orphanParents.includes(spaceSelectedId)
- ? spaceSelectedId
- : orphanParents[0] // TODO: better orphan parent selection.
- );
-
- if (openSpaceTimeline) {
- navigate(getSpaceRoomPath(pSpaceIdOrAlias, roomId, eventId), opts);
- return;
+ let parentSpace: string;
+ if (spaceSelectedId && orphanParents.includes(spaceSelectedId)) {
+ parentSpace = spaceSelectedId;
+ } else {
+ parentSpace = guessPerfectParent(mx, roomId, orphanParents) ?? orphanParents[0];
}
- navigate(getSpaceRoomPath(pSpaceIdOrAlias, roomIdOrAlias, eventId), opts);
+ const pSpaceIdOrAlias = getCanonicalAliasOrRoomId(mx, parentSpace);
+
+ navigate(
+ getSpaceRoomPath(pSpaceIdOrAlias, openSpaceTimeline ? roomId : roomIdOrAlias, eventId),
+ opts
+ );
return;
}
EventTimelineSet,
EventType,
IMentions,
+ IPowerLevelsContent,
IPushRule,
IPushRules,
JoinRule,
const banned = room.hasMembershipState(otherUserId, Membership.Ban);
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;
+};