161 lines
4.4 KiB
TypeScript
161 lines
4.4 KiB
TypeScript
|
|
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 {
|
|||
|
|
getGlobalSoundboardPacks,
|
|||
|
|
getRoomSoundboardPack,
|
|||
|
|
getRoomSoundboardPacks,
|
|||
|
|
getUserSoundboardPack,
|
|||
|
|
SoundboardPack,
|
|||
|
|
} from '../plugins/soundboard';
|
|||
|
|
import { useMatrixClient } from './useMatrixClient';
|
|||
|
|
import { useAccountDataCallback } from './useAccountDataCallback';
|
|||
|
|
import { useStateEventCallback } from './useStateEventCallback';
|
|||
|
|
|
|||
|
|
// Parallels hooks/useImagePacks.ts (custom emoji). Same aggregation shape.
|
|||
|
|
|
|||
|
|
export const useUserSoundboardPack = (): SoundboardPack | undefined => {
|
|||
|
|
const mx = useMatrixClient();
|
|||
|
|
const [userPack, setUserPack] = useState(() => getUserSoundboardPack(mx));
|
|||
|
|
|
|||
|
|
useAccountDataCallback(
|
|||
|
|
mx,
|
|||
|
|
useCallback(
|
|||
|
|
(mEvent) => {
|
|||
|
|
if (mEvent.getType() === AccountDataEvent.LotusSoundboard) {
|
|||
|
|
setUserPack(getUserSoundboardPack(mx));
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
[mx],
|
|||
|
|
),
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
return userPack;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
export const useGlobalSoundboardPacks = (): SoundboardPack[] => {
|
|||
|
|
const mx = useMatrixClient();
|
|||
|
|
const [globalPacks, setGlobalPacks] = useState(() => getGlobalSoundboardPacks(mx));
|
|||
|
|
|
|||
|
|
useAccountDataCallback(
|
|||
|
|
mx,
|
|||
|
|
useCallback(
|
|||
|
|
(mEvent) => {
|
|||
|
|
if (mEvent.getType() === AccountDataEvent.LotusSoundboardRooms) {
|
|||
|
|
setGlobalPacks(getGlobalSoundboardPacks(mx));
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
[mx],
|
|||
|
|
),
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
useStateEventCallback(
|
|||
|
|
mx,
|
|||
|
|
useCallback(
|
|||
|
|
(mEvent) => {
|
|||
|
|
const roomId = mEvent.getRoomId();
|
|||
|
|
const stateKey = mEvent.getStateKey();
|
|||
|
|
if (
|
|||
|
|
mEvent.getType() === StateEvent.LotusSoundboardRoom &&
|
|||
|
|
roomId &&
|
|||
|
|
typeof stateKey === 'string'
|
|||
|
|
) {
|
|||
|
|
const isGlobal = !!globalPacks.find(
|
|||
|
|
(pack) =>
|
|||
|
|
pack.address && pack.address.roomId === roomId && pack.address.stateKey === stateKey,
|
|||
|
|
);
|
|||
|
|
if (isGlobal) setGlobalPacks(getGlobalSoundboardPacks(mx));
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
[mx, globalPacks],
|
|||
|
|
),
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
return globalPacks;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
export const useRoomSoundboardPack = (room: Room, stateKey: string): SoundboardPack | undefined => {
|
|||
|
|
const mx = useMatrixClient();
|
|||
|
|
const [roomPack, setRoomPack] = useState(() => getRoomSoundboardPack(room, stateKey));
|
|||
|
|
|
|||
|
|
useStateEventCallback(
|
|||
|
|
mx,
|
|||
|
|
useCallback(
|
|||
|
|
(mEvent) => {
|
|||
|
|
if (
|
|||
|
|
mEvent.getRoomId() === room.roomId &&
|
|||
|
|
mEvent.getType() === StateEvent.LotusSoundboardRoom &&
|
|||
|
|
mEvent.getStateKey() === stateKey
|
|||
|
|
) {
|
|||
|
|
setRoomPack(getRoomSoundboardPack(room, stateKey));
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
[room, stateKey],
|
|||
|
|
),
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
return roomPack;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
export const useRoomSoundboardPacks = (room: Room): SoundboardPack[] => {
|
|||
|
|
const mx = useMatrixClient();
|
|||
|
|
const [roomPacks, setRoomPacks] = useState(() => getRoomSoundboardPacks(room));
|
|||
|
|
|
|||
|
|
useStateEventCallback(
|
|||
|
|
mx,
|
|||
|
|
useCallback(
|
|||
|
|
(mEvent) => {
|
|||
|
|
if (
|
|||
|
|
mEvent.getRoomId() === room.roomId &&
|
|||
|
|
mEvent.getType() === StateEvent.LotusSoundboardRoom
|
|||
|
|
) {
|
|||
|
|
setRoomPacks(getRoomSoundboardPacks(room));
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
[room],
|
|||
|
|
),
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
return roomPacks;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
export const useRoomsSoundboardPacks = (rooms: Room[]): SoundboardPack[] => {
|
|||
|
|
const mx = useMatrixClient();
|
|||
|
|
const [roomPacks, setRoomPacks] = useState(() => rooms.flatMap(getRoomSoundboardPacks));
|
|||
|
|
|
|||
|
|
useStateEventCallback(
|
|||
|
|
mx,
|
|||
|
|
useCallback(
|
|||
|
|
(mEvent) => {
|
|||
|
|
if (
|
|||
|
|
rooms.find((room) => room.roomId === mEvent.getRoomId()) &&
|
|||
|
|
mEvent.getType() === StateEvent.LotusSoundboardRoom
|
|||
|
|
) {
|
|||
|
|
setRoomPacks(rooms.flatMap(getRoomSoundboardPacks));
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
[rooms],
|
|||
|
|
),
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
return roomPacks;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
/** User ∪ global ∪ room packs, deduped by id, keeping only packs with clips. */
|
|||
|
|
export const useRelevantSoundboardPacks = (rooms: Room[]): SoundboardPack[] => {
|
|||
|
|
const userPack = useUserSoundboardPack();
|
|||
|
|
const globalPacks = useGlobalSoundboardPacks();
|
|||
|
|
const roomsPacks = useRoomsSoundboardPacks(rooms);
|
|||
|
|
|
|||
|
|
return 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.getClips().length > 0);
|
|||
|
|
}, [userPack, globalPacks, roomsPacks]);
|
|||
|
|
};
|