57 lines
2.1 KiB
TypeScript

import { useEffect, useMemo } from "preact/hooks";
import { useQuery } from "react-query";
import { fetchGuildChannels, fetchGuildRoles, fetchGuildEmojis } from "../../api";
import Tribute from "tributejs";
import { useGuild } from "./useGuild";
export const Mentions = ({ input }) => {
const guild = useGuild();
return <>{guild && <_Mentions guild={guild} input={input} />}</>;
};
const _Mentions = ({ guild, input }) => {
const { data: roles } = useQuery(fetchGuildRoles(guild));
const { data: channels } = useQuery(fetchGuildChannels(guild));
const { data: emojis } = useQuery(fetchGuildEmojis(guild));
const tribute = useMemo(() => {
return new Tribute({
collection: [
{
trigger: "@",
values: (roles || [])
.filter((role) => role.name !== "@everyone")
.map(({ id, name }) => ({ key: name, value: id })),
allowSpaces: true,
selectTemplate: (item) => `<@&${item.original.value}>`,
menuItemTemplate: (item) => `@${item.original.key}`,
},
{
trigger: "#",
values: (channels || []).map(({ id, name }) => ({ key: name, value: id })),
allowSpaces: true,
selectTemplate: (item) => `<#${item.original.value}>`,
menuItemTemplate: (item) => `#${item.original.key}`,
},
{
trigger: ":",
values: (emojis || []).map(({ fmt, name }) => ({ key: name, value: fmt })),
allowSpaces: true,
selectTemplate: (item) => item.original.value,
menuItemTemplate: (item) => `:${item.original.key}:`,
},
],
});
}, [roles, channels, emojis]);
useEffect(() => {
tribute.detach(input.current);
if (input.current !== null) {
tribute.attach(input.current);
}
}, [tribute]);
return <></>;
};