vojo/src/app/plugins/via-servers.ts
Ajay Bura 1ad7fe8deb
Fix missing creators support using via (#2431)
* add additional_creators in IRoomCreateContent type

* use creators in getViaServers

* consider creators in guessing perfect parent
2025-08-16 21:30:02 +10:00

73 lines
2.3 KiB
TypeScript

import { Room } from 'matrix-js-sdk';
import { IPowerLevels } from '../hooks/usePowerLevels';
import { creatorsSupported, getMxIdServer } from '../utils/matrix';
import { IRoomCreateContent, StateEvent } from '../../types/matrix/room';
import { getStateEvent } from '../utils/room';
export const getViaServers = (room: Room): string[] => {
const getHighestPowerUserId = (): string | undefined => {
const creatorEvent = getStateEvent(room, StateEvent.RoomCreate);
if (
creatorEvent &&
creatorsSupported(creatorEvent.getContent<IRoomCreateContent>().room_version)
) {
return creatorEvent.getSender();
}
const powerLevels = getStateEvent(room, StateEvent.RoomPowerLevels)?.getContent<IPowerLevels>();
if (!powerLevels) return undefined;
const userIdToPower = powerLevels.users;
if (!userIdToPower) return undefined;
let powerUserId: string | undefined;
Object.keys(userIdToPower).forEach((userId) => {
if (userIdToPower[userId] <= (powerLevels.users_default ?? 0)) return;
if (!powerUserId) {
powerUserId = userId;
return;
}
if (userIdToPower[userId] > userIdToPower[powerUserId]) {
powerUserId = userId;
}
});
return powerUserId;
};
const getServerToPopulation = (): Record<string, number> => {
const members = room.getMembers();
const serverToPop: Record<string, number> = {};
members?.forEach((member) => {
const { userId } = member;
const server = getMxIdServer(userId);
if (!server) return;
const serverPop = serverToPop[server];
if (serverPop === undefined) {
serverToPop[server] = 1;
return;
}
serverToPop[server] = serverPop + 1;
});
return serverToPop;
};
const via: string[] = [];
const userId = getHighestPowerUserId();
if (userId) {
const server = getMxIdServer(userId);
if (server) via.push(server);
}
const serverToPop = getServerToPopulation();
const sortedServers = Object.keys(serverToPop).sort(
(svrA, svrB) => serverToPop[svrB] - serverToPop[svrA]
);
const mostPop3 = sortedServers.slice(0, 3);
if (via.length === 0) return mostPop3;
if (mostPop3.includes(via[0])) {
mostPop3.splice(mostPop3.indexOf(via[0]), 1);
}
return via.concat(mostPop3.slice(0, 2));
};