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