import { useEffect } from 'react'; import { IMessage } from '../../../definition/IMessage'; import { IRoom } from '../../../definition/IRoom'; import { IUser } from '../../../definition/IUser'; import { useStream } from '../../contexts/ServerContext'; import { MessageList } from '../../lib/lists/MessageList'; import { createFilterFromQuery, FieldExpression, Query } from '../../lib/minimongo'; type RoomMessagesRidEvent = IMessage; type NotifyRoomRidDeleteMessageEvent = { _id: IMessage['_id'] }; type NotifyRoomRidDeleteMessageBulkEvent = { rid: IMessage['rid']; excludePinned: boolean; ignoreDiscussion: boolean; ts: FieldExpression; users: string[]; }; const createDeleteCriteria = (params: NotifyRoomRidDeleteMessageBulkEvent): ((message: IMessage) => boolean) => { const query: Query = { ts: params.ts }; if (params.excludePinned) { query.pinned = { $ne: true }; } if (params.ignoreDiscussion) { query.drid = { $exists: false }; } if (params.users && params.users.length) { query['u.username'] = { $in: params.users }; } return createFilterFromQuery(query); }; export const useStreamUpdatesForMessageList = (messageList: MessageList, uid: IUser['_id'] | null, rid: IRoom['_id'] | null): void => { const subscribeToRoomMessages = useStream('room-messages'); const subscribeToNotifyRoom = useStream('notify-room'); useEffect(() => { if (!uid || !rid) { messageList.clear(); return; } const unsubscribeFromRoomMessages = subscribeToRoomMessages(rid, (message) => { messageList.handle(message); }); const unsubscribeFromDeleteMessage = subscribeToNotifyRoom(`${rid}/deleteMessage`, ({ _id: mid }) => { messageList.remove(mid); }); const unsubscribeFromDeleteMessageBulk = subscribeToNotifyRoom( `${rid}/deleteMessageBulk`, (params) => { const matchDeleteCriteria = createDeleteCriteria(params); messageList.prune(matchDeleteCriteria); }, ); return (): void => { unsubscribeFromRoomMessages(); unsubscribeFromDeleteMessage(); unsubscribeFromDeleteMessageBulk(); }; }, [subscribeToRoomMessages, subscribeToNotifyRoom, uid, rid, messageList]); };