add more custom emojis hooks

This commit is contained in:
Ajay Bura 2024-12-26 17:40:02 +05:30
parent 3bfc80c9fc
commit 15d72b68a0
4 changed files with 129 additions and 58 deletions

View file

@ -52,7 +52,7 @@ export function EmoticonAutocomplete({
const mx = useMatrixClient();
const useAuthentication = useMediaAuthentication();
const imagePacks = useRelevantImagePacks(mx, ImageUsage.Emoticon, imagePackRooms);
const imagePacks = useRelevantImagePacks(ImageUsage.Emoticon, imagePackRooms);
const recentEmoji = useRecentEmoji(mx, 20);
const searchList = useMemo(() => {

View file

@ -674,7 +674,7 @@ export function EmojiBoard({
const useAuthentication = useMediaAuthentication();
const emojiGroupLabels = useEmojiGroupLabels();
const emojiGroupIcons = useEmojiGroupIcons();
const imagePacks = useRelevantImagePacks(mx, usage, imagePackRooms);
const imagePacks = useRelevantImagePacks(usage, imagePackRooms);
const recentEmojis = useRecentEmoji(mx, 21);
const contentScrollRef = useRef<HTMLDivElement>(null);

View file

@ -1,48 +1,137 @@
import { ClientEvent, MatrixClient, MatrixEvent, Room, RoomStateEvent } from 'matrix-js-sdk';
import { useEffect, useMemo } from 'react';
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 { useForceUpdate } from './useForceUpdate';
import { getRelevantPacks, ImagePack, ImageUsage } from '../plugins/custom-emoji';
import {
getGlobalImagePacks,
getRoomImagePacks,
getUserImagePack,
ImagePack,
ImageUsage,
} from '../plugins/custom-emoji';
import { useMatrixClient } from './useMatrixClient';
import { useAccountDataCallback } from './useAccountDataCallback';
import { useStateEventCallback } from './useStateEventCallback';
export const useRelevantImagePacks = (
mx: MatrixClient,
usage: ImageUsage,
rooms: Room[]
): ImagePack[] => {
const [forceCount, forceUpdate] = useForceUpdate();
export const useUserImagePack = (): ImagePack | undefined => {
const mx = useMatrixClient();
const [userPack, setUserPack] = useState(() => getUserImagePack(mx));
const relevantPacks = useMemo(
() => getRelevantPacks(mx, rooms).filter((pack) => pack.getImages(usage).length > 0),
// eslint-disable-next-line react-hooks/exhaustive-deps
[mx, usage, rooms, forceCount]
useAccountDataCallback(
mx,
useCallback(
(mEvent) => {
if (mEvent.getType() === AccountDataEvent.PoniesUserEmotes) {
setUserPack(getUserImagePack(mx));
}
},
[mx]
)
);
useEffect(() => {
const handleUpdate = (event: MatrixEvent) => {
if (
event.getType() === AccountDataEvent.PoniesEmoteRooms ||
event.getType() === AccountDataEvent.PoniesUserEmotes
) {
forceUpdate();
}
const eventRoomId = event.getRoomId();
if (
eventRoomId &&
event.getType() === StateEvent.PoniesRoomEmotes &&
rooms.find((room) => room.roomId === eventRoomId)
) {
forceUpdate();
}
};
return userPack;
};
mx.on(ClientEvent.AccountData, handleUpdate);
mx.on(RoomStateEvent.Events, handleUpdate);
return () => {
mx.removeListener(ClientEvent.AccountData, handleUpdate);
mx.removeListener(RoomStateEvent.Events, handleUpdate);
};
}, [mx, rooms, forceUpdate]);
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 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;
};

View file

@ -57,21 +57,3 @@ export function getUserImagePack(mx: MatrixClient): ImagePack | undefined {
const userImagePack = ImagePack.fromMatrixEvent(userId, packEvent);
return userImagePack;
}
/**
* @param {MatrixClient} mx Provide if you want to include user personal/global pack
* @param {Room[]} rooms Provide rooms if you want to include rooms pack
* @returns {ImagePack[]} packs
*/
export function getRelevantPacks(mx?: MatrixClient, rooms?: Room[]): ImagePack[] {
const userPack = mx && getUserImagePack(mx);
const userPacks = userPack ? [userPack] : [];
const globalPacks = mx ? getGlobalImagePacks(mx) : [];
const globalPackIds = new Set(globalPacks.map((pack) => pack.id));
const roomsPack = rooms?.flatMap(getRoomImagePacks) ?? [];
return userPacks.concat(
globalPacks,
roomsPack.filter((pack) => !globalPackIds.has(pack.id))
);
}