import { Room } from 'matrix-js-sdk'; import { useCallback, useMemo, useState } from 'react'; import { AccountDataEvent } from '../../types/matrix/accountData'; import { StateEvent } from '../../types/matrix/room'; import { getGlobalImagePacks, getRoomImagePack, getRoomImagePacks, getUserImagePack, ImagePack, ImageUsage, } from '../plugins/custom-emoji'; import { useMatrixClient } from './useMatrixClient'; import { useAccountDataCallback } from './useAccountDataCallback'; import { useStateEventCallback } from './useStateEventCallback'; export const useUserImagePack = (): ImagePack | undefined => { const mx = useMatrixClient(); const [userPack, setUserPack] = useState(() => getUserImagePack(mx)); useAccountDataCallback( mx, useCallback( (mEvent) => { if (mEvent.getType() === AccountDataEvent.PoniesUserEmotes) { setUserPack(getUserImagePack(mx)); } }, [mx] ) ); return userPack; }; export const useGlobalImagePacks = (): ImagePack[] => { const mx = useMatrixClient(); const [globalPacks, setGlobalPacks] = useState(() => getGlobalImagePacks(mx)); useAccountDataCallback( mx, useCallback( (mEvent) => { if (mEvent.getType() === AccountDataEvent.PoniesEmoteRooms) { setGlobalPacks(getGlobalImagePacks(mx)); } }, [mx] ) ); useStateEventCallback( mx, useCallback( (mEvent) => { const eventType = mEvent.getType(); const roomId = mEvent.getRoomId(); const stateKey = mEvent.getStateKey(); if (eventType === StateEvent.PoniesRoomEmotes && roomId && typeof stateKey === 'string') { const global = !!globalPacks.find( (pack) => pack.address && pack.address.roomId === roomId && pack.address.stateKey === stateKey ); if (global) { setGlobalPacks(getGlobalImagePacks(mx)); } } }, [mx, globalPacks] ) ); return globalPacks; }; export const useRoomImagePack = (room: Room, stateKey: string): ImagePack | undefined => { const mx = useMatrixClient(); const [roomPack, setRoomPack] = useState(() => getRoomImagePack(room, stateKey)); useStateEventCallback( mx, useCallback( (mEvent) => { if ( mEvent.getRoomId() === room.roomId && mEvent.getType() === StateEvent.PoniesRoomEmotes && mEvent.getStateKey() === stateKey ) { setRoomPack(getRoomImagePack(room, stateKey)); } }, [room, stateKey] ) ); return roomPack; }; export const useRoomImagePacks = (room: Room): ImagePack[] => { const mx = useMatrixClient(); const [roomPacks, setRoomPacks] = useState(() => getRoomImagePacks(room)); useStateEventCallback( mx, useCallback( (mEvent) => { if ( mEvent.getRoomId() === room.roomId && mEvent.getType() === StateEvent.PoniesRoomEmotes ) { setRoomPacks(getRoomImagePacks(room)); } }, [room] ) ); return roomPacks; }; export const useRoomsImagePacks = (rooms: Room[]) => { const mx = useMatrixClient(); const [roomPacks, setRoomPacks] = useState(() => rooms.flatMap(getRoomImagePacks)); useStateEventCallback( mx, useCallback( (mEvent) => { if ( rooms.find((room) => room.roomId === mEvent.getRoomId()) && mEvent.getType() === StateEvent.PoniesRoomEmotes ) { setRoomPacks(rooms.flatMap(getRoomImagePacks)); } }, [rooms] ) ); return roomPacks; }; export const useRelevantImagePacks = (usage: ImageUsage, rooms: Room[]): ImagePack[] => { const userPack = useUserImagePack(); const globalPacks = useGlobalImagePacks(); const roomsPacks = useRoomsImagePacks(rooms); const relevantPacks = useMemo(() => { const packs = userPack ? [userPack] : []; const globalPackIds = new Set(globalPacks.map((pack) => pack.id)); const relPacks = packs.concat( globalPacks, roomsPacks.filter((pack) => !globalPackIds.has(pack.id)) ); return relPacks.filter((pack) => pack.getImages(usage).length > 0); }, [userPack, globalPacks, roomsPacks, usage]); return relevantPacks; };