The weeb for the next gen discord boat - Wamellow
wamellow.com
bot
discord
1import { type ApiV1GuildsChannelsGetResponse, type ApiV1GuildsEmojisGetResponse, type ApiV1GuildsRolesGetResponse, PermissionFlagsBits } from "@/typings";
2import { ChannelType } from "discord-api-types/v10";
3import Image from "next/image";
4import { HiAtSymbol, HiHashtag, HiMenuAlt2, HiNewspaper, HiVolumeUp } from "react-icons/hi";
5
6type Item = ApiV1GuildsChannelsGetResponse | ApiV1GuildsRolesGetResponse;
7type PermissionNames = keyof typeof PermissionFlagsBits | "RoleHirachy";
8
9function parsePermissions(permissions: number, required: PermissionNames[]) {
10 if (permissions === -1 && required.includes("RoleHirachy")) return ["Role is above Wamellow"];
11
12 return required
13 .filter((perm) => perm !== "RoleHirachy")
14 .map((perm) => (permissions & PermissionFlagsBits[perm]) === 0 ? perm : false)
15 .filter(Boolean);
16}
17
18export function createSelectableItems<T extends Item>(
19 items: T[] | undefined,
20 requiredPermissions?: (PermissionNames | null)[],
21 allowedTypes: ChannelType[] = [ChannelType.GuildText, ChannelType.GuildAnnouncement]
22) {
23 if (!items?.length) return [];
24
25 if (requiredPermissions === undefined && "type" in items[0]) {
26 requiredPermissions = ["ViewChannel", "SendMessages", "EmbedLinks"];
27 }
28
29 return items
30 .sort((a, b) => a.name.localeCompare(b.name))
31 .filter((item) => "type" in item ? allowedTypes.includes(item.type) : true)
32 .map((item) => ({
33 icon: getIconByType("type" in item ? item.type : -1),
34 name: item.name,
35 value: item.id,
36 color: "color" in item ? item.color : undefined,
37 error: "permissions" in item
38 ? parsePermissions(item.permissions, requiredPermissions?.filter((perm) => perm !== null) || []).join(", ")
39 : undefined
40 }));
41}
42
43export function createSelectableEmojiItems(emojis: ApiV1GuildsEmojisGetResponse[] = []) {
44 return [
45 { icon: "👋", name: "Wave", value: "👋" },
46 { icon: "☕", name: "Coffee", value: "☕" },
47 ...emojis
48 .sort((a, b) => a.name.localeCompare(b.name))
49 .map((c) => ({
50 icon: <Image
51 src={`https://cdn.discordapp.com/emojis/${c.id}.webp?size=64&quality=lossless`}
52 className="rounded-md h-6 w-6"
53 alt={c.name}
54 height={64}
55 width={64}
56 />,
57 name: c.name.replace(/-|_/g, " "),
58 value: c.id
59 }))
60 ];
61}
62
63function getIconByType(type: ChannelType | -1) {
64 switch (type) {
65 case ChannelType.GuildVoice: return <HiVolumeUp />;
66 case ChannelType.GuildCategory: return <HiMenuAlt2 />;
67 case ChannelType.GuildAnnouncement: return <HiNewspaper />;
68 case -1: return <HiAtSymbol />;
69 default: return <HiHashtag />;
70 }
71}