Add room utils
This commit is contained in:
parent
1c7600c3b8
commit
56a134c85c
1 changed files with 118 additions and 0 deletions
118
src/app/utils/room.ts
Normal file
118
src/app/utils/room.ts
Normal file
|
@ -0,0 +1,118 @@
|
||||||
|
import { MatrixClient, MatrixEvent, Room } from 'matrix-js-sdk';
|
||||||
|
import { AccountDataEvent } from '../../types/matrix/accountData';
|
||||||
|
import { RoomToParents, RoomType, StateEvent } from '../../types/matrix/room';
|
||||||
|
|
||||||
|
export const getStateEvent = (
|
||||||
|
room: Room,
|
||||||
|
eventType: StateEvent,
|
||||||
|
stateKey = ''
|
||||||
|
): MatrixEvent | null => room.currentState.getStateEvents(eventType, stateKey);
|
||||||
|
|
||||||
|
export const getStateEvents = (room: Room, eventType: StateEvent): MatrixEvent[] =>
|
||||||
|
room.currentState.getStateEvents(eventType);
|
||||||
|
|
||||||
|
export const getAccountData = (
|
||||||
|
mx: MatrixClient,
|
||||||
|
eventType: AccountDataEvent
|
||||||
|
): MatrixEvent | undefined => mx.getAccountData(eventType);
|
||||||
|
|
||||||
|
export const getMDirects = (mDirectEvent: MatrixEvent): Set<string> => {
|
||||||
|
const roomIds = new Set<string>();
|
||||||
|
const userIdToDirects = mDirectEvent?.getContent();
|
||||||
|
|
||||||
|
if (userIdToDirects === undefined) return roomIds;
|
||||||
|
|
||||||
|
Object.keys(userIdToDirects).forEach((userId) => {
|
||||||
|
const directs = userIdToDirects[userId];
|
||||||
|
if (Array.isArray(directs)) {
|
||||||
|
directs.forEach((id) => {
|
||||||
|
if (typeof id === 'string') roomIds.add(id);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return roomIds;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const isDirectInvite = (room: Room | null, myUserId: string | null): boolean => {
|
||||||
|
if (!room || !myUserId) return false;
|
||||||
|
const me = room.getMember(myUserId);
|
||||||
|
const memberEvent = me?.events?.member;
|
||||||
|
const content = memberEvent?.getContent();
|
||||||
|
return content?.is_direct === true;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const isSpace = (room: Room | null): boolean => {
|
||||||
|
if (!room) return false;
|
||||||
|
const event = getStateEvent(room, StateEvent.RoomCreate);
|
||||||
|
if (!event) return false;
|
||||||
|
return event.getContent().type === RoomType.Space;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const isRoom = (room: Room | null): boolean => {
|
||||||
|
if (!room) return false;
|
||||||
|
const event = getStateEvent(room, StateEvent.RoomCreate);
|
||||||
|
if (!event) return false;
|
||||||
|
return event.getContent().type === undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const isUnsupportedRoom = (room: Room | null): boolean => {
|
||||||
|
if (!room) return false;
|
||||||
|
const event = getStateEvent(room, StateEvent.RoomCreate);
|
||||||
|
if (!event) return true; // Consider room unsupported if m.room.create event doesn't exist
|
||||||
|
return event.getContent().type !== undefined && event.getContent().type !== RoomType.Space;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function isValidChild(mEvent: MatrixEvent): boolean {
|
||||||
|
return mEvent.getType() === StateEvent.SpaceChild && Object.keys(mEvent.getContent()).length > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getAllParents = (roomToParents: RoomToParents, roomId: string): Set<string> => {
|
||||||
|
const allParents = new Set<string>();
|
||||||
|
|
||||||
|
const addAllParentIds = (rId: string) => {
|
||||||
|
if (allParents.has(rId)) return;
|
||||||
|
allParents.add(rId);
|
||||||
|
|
||||||
|
const parents = roomToParents.get(rId);
|
||||||
|
parents?.forEach((id) => addAllParentIds(id));
|
||||||
|
};
|
||||||
|
addAllParentIds(roomId);
|
||||||
|
allParents.delete(roomId);
|
||||||
|
return allParents;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getSpaceChildren = (room: Room) =>
|
||||||
|
getStateEvents(room, StateEvent.SpaceChild).reduce<string[]>((filtered, mEvent) => {
|
||||||
|
const stateKey = mEvent.getStateKey();
|
||||||
|
if (isValidChild(mEvent) && stateKey) {
|
||||||
|
filtered.push(stateKey);
|
||||||
|
}
|
||||||
|
return filtered;
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
export const mapParentWithChildren = (
|
||||||
|
roomToParents: RoomToParents,
|
||||||
|
roomId: string,
|
||||||
|
children: string[]
|
||||||
|
) => {
|
||||||
|
const allParents = getAllParents(roomToParents, roomId);
|
||||||
|
children.forEach((childId) => {
|
||||||
|
if (allParents.has(childId)) {
|
||||||
|
// Space cycle detected.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const parents = roomToParents.get(childId) ?? new Set<string>();
|
||||||
|
parents.add(roomId);
|
||||||
|
roomToParents.set(childId, parents);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getRoomToParents = (mx: MatrixClient): RoomToParents => {
|
||||||
|
const map: RoomToParents = new Map();
|
||||||
|
mx.getRooms()
|
||||||
|
.filter((room) => isSpace(room))
|
||||||
|
.forEach((room) => mapParentWithChildren(map, room.roomId, getSpaceChildren(room)));
|
||||||
|
|
||||||
|
return map;
|
||||||
|
};
|
Loading…
Reference in a new issue