diff --git a/src/app/plugins/via-servers.ts b/src/app/plugins/via-servers.ts index 75470999..d825a1fd 100644 --- a/src/app/plugins/via-servers.ts +++ b/src/app/plugins/via-servers.ts @@ -1,11 +1,19 @@ import { Room } from 'matrix-js-sdk'; import { IPowerLevels } from '../hooks/usePowerLevels'; -import { getMxIdServer } from '../utils/matrix'; -import { StateEvent } from '../../types/matrix/room'; +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().room_version) + ) { + return creatorEvent.getSender(); + } + const powerLevels = getStateEvent(room, StateEvent.RoomPowerLevels)?.getContent(); if (!powerLevels) return undefined; diff --git a/src/app/utils/room.ts b/src/app/utils/room.ts index a962c45d..b4bba2ad 100644 --- a/src/app/utils/room.ts +++ b/src/app/utils/room.ts @@ -20,6 +20,7 @@ import { import { CryptoBackend } from 'matrix-js-sdk/lib/common-crypto/CryptoBackend'; import { AccountDataEvent } from '../../types/matrix/accountData'; import { + IRoomCreateContent, Membership, MessageEvent, NotificationType, @@ -43,7 +44,7 @@ export const getStateEvents = (room: Room, eventType: StateEvent): MatrixEvent[] export const getAccountData = ( mx: MatrixClient, eventType: AccountDataEvent -): MatrixEvent | undefined => mx.getAccountData(eventType); +): MatrixEvent | undefined => mx.getAccountData(eventType as any); export const getMDirects = (mDirectEvent: MatrixEvent): Set => { const roomIds = new Set(); @@ -480,6 +481,23 @@ export const bannedInRooms = (mx: MatrixClient, rooms: string[], otherUserId: st return banned; }); +export const getAllVersionsRoomCreator = (room: Room): Set => { + const creators = new Set(); + + const createEvent = getStateEvent(room, StateEvent.RoomCreate); + const createContent = createEvent?.getContent(); + const creator = createEvent?.getSender(); + if (typeof creator === 'string') creators.add(creator); + + if (createContent && Array.isArray(createContent.additional_creators)) { + createContent.additional_creators.forEach((c) => { + if (typeof c === 'string') creators.add(c); + }); + } + + return creators; +}; + export const guessPerfectParent = ( mx: MatrixClient, roomId: string, @@ -490,15 +508,29 @@ export const guessPerfectParent = ( } const getSpecialUsers = (rId: string): string[] => { + const specialUsers: Set = new Set(); + const r = mx.getRoom(rId); - const powerLevels = - r && getStateEvent(r, StateEvent.RoomPowerLevels)?.getContent(); + if (!r) return []; + + getAllVersionsRoomCreator(r).forEach((c) => specialUsers.add(c)); + + const powerLevels = getStateEvent( + r, + StateEvent.RoomPowerLevels + )?.getContent(); 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); + + if (typeof users === 'object') + Object.keys(users).forEach((userId) => { + if (users[userId] > defaultPower) { + specialUsers.add(userId); + } + }); + + return Array.from(specialUsers); }; let perfectParent: string | undefined; diff --git a/src/types/matrix/room.ts b/src/types/matrix/room.ts index f0927b3c..b866fd77 100644 --- a/src/types/matrix/room.ts +++ b/src/types/matrix/room.ts @@ -70,6 +70,7 @@ export type IRoomCreateContent = { ['m.federate']?: boolean; room_version: string; type?: string; + additional_creators?: string[]; predecessor?: { event_id?: string; room_id: string;