Add room utils

This commit is contained in:
Ajay Bura 2022-12-27 20:15:17 +05:30
parent 1c7600c3b8
commit 56a134c85c

118
src/app/utils/room.ts Normal file
View 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;
};