Development (#11)

We need this NOW.

---------

Co-authored-by: PineaFan <ash@pinea.dev>
Co-authored-by: pineafan <pineapplefanyt@gmail.com>
Co-authored-by: PineappleFan <PineaFan@users.noreply.github.com>
Co-authored-by: Skyler <skyler3665@gmail.com>
diff --git a/src/Unfinished/categorizationTest.ts b/src/Unfinished/categorizationTest.ts
new file mode 100644
index 0000000..ff2d66b
--- /dev/null
+++ b/src/Unfinished/categorizationTest.ts
@@ -0,0 +1,132 @@
+import { LoadingEmbed } from "../utils/defaults.js";
+import { CommandInteraction, GuildChannel, ActionRowBuilder, ButtonBuilder, ButtonStyle, ChannelType, StringSelectMenuBuilder, APIMessageComponentEmoji } from "discord.js";
+import { SlashCommandBuilder } from "discord.js";
+import EmojiEmbed from "../utils/generateEmojiEmbed.js";
+import client from "../utils/client.js";
+import addPlural from "../utils/plurals.js";
+import getEmojiByName from "../utils/getEmojiByName.js";
+
+const command = new SlashCommandBuilder().setName("categorize").setDescription("Categorizes your servers channels");
+
+const callback = async (interaction: CommandInteraction): Promise<unknown> => {
+    const channels = interaction.guild!.channels.cache.filter((c) => c.type !== ChannelType.GuildCategory);
+    const categorized = {};
+    await interaction.reply({ embeds: LoadingEmbed, ephemeral: true });
+    const predicted = {};
+    const types = {
+        important: ["rule", "announcement", "alert", "info"],
+        general: ["general", "main", "topic", "discuss"],
+        commands: ["bot", "command", "music"],
+        images: ["pic", "selfies", "image", "gallery", "meme", "media"],
+        nsfw: ["porn", "nsfw", "sex", "lewd", "fetish"],
+        links: ["link"],
+        advertising: ["ads", "advert", "partner", "bump"],
+        staff: ["staff", "mod", "admin", "helper", "train"],
+        spam: ["spam", "count"],
+        logs: ["log"],
+        other: ["random", "starboard"],
+    };
+    for (const c of channels.values()) {
+        for (const type in types) {
+            for (const word of types[type]) {
+                if (c.name.toLowerCase().includes(word)) {
+                    predicted[c.id] = predicted[c.id] ?? [];
+                    predicted[c.id].push(type);
+                }
+            }
+        }
+    }
+    let m;
+    for (const c of channels) {
+        // convert channel to a channel if its a string
+        let channel: string | GuildChannel;
+        if (typeof c === "string") channel = interaction.guild!.channels.cache.get(c as string)!.id;
+        else channel = (c[0] as unknown as GuildChannel).id;
+        console.log(channel);
+        if (!predicted[channel]) predicted[channel] = [];
+        m = await interaction.editReply({
+            embeds: [
+                new EmojiEmbed()
+                    .setTitle("Categorize")
+                    .setDescription(
+                        `Select all types that apply to <#${channel}>.\n\n` +
+                            `${addPlural(predicted[channel].length, "Suggestion")}: ${predicted[channel].join(", ")}`
+                    )
+                    .setEmoji("CHANNEL.CATEGORY.CREATE")
+                    .setStatus("Success")
+            ],
+            components: [
+                new ActionRowBuilder<StringSelectMenuBuilder>().addComponents([
+                    new StringSelectMenuBuilder()
+                        .setCustomId("selected")
+                        .setMaxValues(Object.keys(types).length)
+                        .setMinValues(1)
+                        .setPlaceholder("Select all types that apply to this channel")
+                        .setOptions(
+                            Object.keys(types).map((type) => ({
+                                label: type,
+                                value: type
+                            }))
+                        )
+                ]),
+                new ActionRowBuilder<ButtonBuilder>().addComponents([
+                    new ButtonBuilder()
+                        .setLabel("Accept Suggestion")
+                        .setCustomId("accept")
+                        .setStyle(ButtonStyle.Success)
+                        .setDisabled(predicted[channel].length === 0)
+                        .setEmoji(client.emojis.cache.get(getEmojiByName("ICONS.TICK", "id")) as APIMessageComponentEmoji),
+                    new ButtonBuilder()
+                        .setLabel('Use "Other"')
+                        .setCustomId("reject")
+                        .setStyle(ButtonStyle.Secondary)
+                        .setEmoji(client.emojis.cache.get(getEmojiByName("ICONS.CROSS", "id")) as APIMessageComponentEmoji)
+                ])
+            ]
+        });
+        let i;
+        try {
+            i = await m.awaitMessageComponent({
+                time: 300000,
+                filter: (i) => { return i.user.id === interaction.user.id && i.channel!.id === interaction.channel!.id && i.message.id === m.id}
+            });
+        } catch (e) {
+            return await interaction.editReply({
+                embeds: [
+                    new EmojiEmbed()
+                        .setTitle("Categorize")
+                        .setEmoji("CHANNEL.CATEGORY.DELETE")
+                        .setStatus("Danger")
+                        .setDescription(
+                            `Select all types that apply to <#${channel}>.\n\n` +
+                                `${addPlural(predicted[channel].length, "Suggestion")}: ${predicted[channel].join(
+                                    ", "
+                                )}`
+                        )
+                        .setFooter({ text: "Message timed out" })
+                ]
+            });
+        }
+        await i.deferUpdate();
+        let selected;
+        if (i.customId === "select") {
+            selected = i.values;
+        }
+        if (i.customId === "accept") {
+            selected = predicted[channel];
+        }
+        if (i.customId === "reject") {
+            selected = ["other"];
+        }
+        categorized[channel] = selected;
+    }
+    console.log(categorized);
+};
+
+const check = () => {
+    return true;
+};
+
+export { command };
+export { callback };
+export { check };