65 lines
1.9 KiB
TypeScript
65 lines
1.9 KiB
TypeScript
|
|
import { useSetAtom, WritableAtom } from 'jotai';
|
||
|
|
import { ClientEvent, MatrixClient, Room, RoomEvent } from 'matrix-js-sdk';
|
||
|
|
import { useEffect } from 'react';
|
||
|
|
import { Membership } from '../../types/matrix/room';
|
||
|
|
|
||
|
|
export type RoomsAction =
|
||
|
|
| {
|
||
|
|
type: 'INITIALIZE';
|
||
|
|
rooms: string[];
|
||
|
|
}
|
||
|
|
| {
|
||
|
|
type: 'PUT' | 'DELETE';
|
||
|
|
roomId: string;
|
||
|
|
};
|
||
|
|
|
||
|
|
export const useBindRoomsWithMembershipsAtom = (
|
||
|
|
mx: MatrixClient,
|
||
|
|
roomsAtom: WritableAtom<string[], RoomsAction>,
|
||
|
|
memberships: Membership[]
|
||
|
|
) => {
|
||
|
|
const setRoomsAtom = useSetAtom(roomsAtom);
|
||
|
|
|
||
|
|
useEffect(() => {
|
||
|
|
const satisfyMembership = (room: Room): boolean =>
|
||
|
|
!!memberships.find((membership) => membership === room.getMyMembership());
|
||
|
|
setRoomsAtom({
|
||
|
|
type: 'INITIALIZE',
|
||
|
|
rooms: mx
|
||
|
|
.getRooms()
|
||
|
|
.filter(satisfyMembership)
|
||
|
|
.map((room) => room.roomId),
|
||
|
|
});
|
||
|
|
|
||
|
|
const handleAddRoom = (room: Room) => {
|
||
|
|
if (satisfyMembership(room)) {
|
||
|
|
setRoomsAtom({ type: 'PUT', roomId: room.roomId });
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
const handleMembershipChange = (room: Room) => {
|
||
|
|
if (!satisfyMembership(room)) {
|
||
|
|
setRoomsAtom({ type: 'DELETE', roomId: room.roomId });
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
const handleDeleteRoom = (roomId: string) => {
|
||
|
|
setRoomsAtom({ type: 'DELETE', roomId });
|
||
|
|
};
|
||
|
|
|
||
|
|
mx.on(ClientEvent.Room, handleAddRoom);
|
||
|
|
mx.on(RoomEvent.MyMembership, handleMembershipChange);
|
||
|
|
mx.on(ClientEvent.DeleteRoom, handleDeleteRoom);
|
||
|
|
return () => {
|
||
|
|
mx.removeListener(ClientEvent.Room, handleAddRoom);
|
||
|
|
mx.removeListener(RoomEvent.MyMembership, handleMembershipChange);
|
||
|
|
mx.removeListener(ClientEvent.DeleteRoom, handleDeleteRoom);
|
||
|
|
};
|
||
|
|
}, [mx, memberships, setRoomsAtom]);
|
||
|
|
};
|
||
|
|
|
||
|
|
export const compareRoomsEqual = (a: string[], b: string[]) => {
|
||
|
|
if (a.length !== b.length) return false;
|
||
|
|
return a.every((roomId, roomIdIndex) => roomId === b[roomIdIndex]);
|
||
|
|
};
|