57 lines
2.1 KiB
TypeScript
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 <></>;
|
|
};
|