From a9937cb4bad6184e151d2f5369407cf552df4385 Mon Sep 17 00:00:00 2001 From: Ajay Bura <32841439+ajbura@users.noreply.github.com> Date: Tue, 27 Dec 2022 20:16:49 +0530 Subject: [PATCH] add utils for jotai atoms --- src/app/state/utils.ts | 55 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 src/app/state/utils.ts diff --git a/src/app/state/utils.ts b/src/app/state/utils.ts new file mode 100644 index 00000000..04abdc1e --- /dev/null +++ b/src/app/state/utils.ts @@ -0,0 +1,55 @@ +import { SetStateAction } from 'jotai'; +import { ClientEvent, MatrixClient, Room, RoomEvent } from 'matrix-js-sdk'; +import { Membership } from '../../types/matrix/room'; +import { disposable } from '../utils/disposable'; + +export const atomRoomsWithMemberships = disposable( + ( + setAtom: (update: SetStateAction) => void, + mx: MatrixClient, + memberships: Membership[] + ) => { + const satisfyMembership = (room: Room): boolean => + !!memberships.find((membership) => membership === room.getMyMembership()); + + setAtom( + mx + .getRooms() + .filter(satisfyMembership) + .map((room) => room.roomId) + ); + + const updateAtom = (type: 'PUT' | 'DELETE', roomId: string) => { + setAtom((ids) => { + const newIds = ids.filter((id) => id !== roomId); + if (type === 'PUT') newIds.push(roomId); + return newIds; + }); + }; + + const handleAddRoom = (room: Room) => { + if (satisfyMembership(room)) { + updateAtom('PUT', room.roomId); + } + }; + + const handleMembershipChange = (room: Room) => { + if (!satisfyMembership(room)) { + updateAtom('DELETE', room.roomId); + } + }; + + const handleDeleteRoom = (roomId: string) => { + updateAtom('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); + }; + } +);