finished settings/rolemenu

pull/11/head
TheCodedProf 3 years ago
parent 8c29523dc0
commit f4facde097

@ -3,6 +3,7 @@
"@discordjs/rest": "^0.2.0-canary.0", "@discordjs/rest": "^0.2.0-canary.0",
"@hokify/agenda": "^6.2.12", "@hokify/agenda": "^6.2.12",
"@tsconfig/node18-strictest-esm": "^1.0.0", "@tsconfig/node18-strictest-esm": "^1.0.0",
"@types/lodash": "^4.14.191",
"@types/node-cron": "^3.0.1", "@types/node-cron": "^3.0.1",
"@ungap/structured-clone": "^1.0.1", "@ungap/structured-clone": "^1.0.1",
"agenda": "^4.3.0", "agenda": "^4.3.0",
@ -17,6 +18,7 @@
"fuse.js": "^6.6.2", "fuse.js": "^6.6.2",
"humanize-duration": "^3.27.1", "humanize-duration": "^3.27.1",
"immutable": "^4.1.0", "immutable": "^4.1.0",
"lodash": "^4.17.21",
"mongodb": "^4.7.0", "mongodb": "^4.7.0",
"node-cron": "^3.0.0", "node-cron": "^3.0.0",
"node-fetch": "^3.3.0", "node-fetch": "^3.3.0",
@ -24,7 +26,7 @@
"pastebin-api": "^5.1.1", "pastebin-api": "^5.1.1",
"structured-clone": "^0.2.2", "structured-clone": "^0.2.2",
"systeminformation": "^5.17.3", "systeminformation": "^5.17.3",
"typescript": "^5.0.0-dev.20230102", "typescript": "^4.9.4",
"uuid": "^8.3.2" "uuid": "^8.3.2"
}, },
"name": "nucleus", "name": "nucleus",

@ -7,7 +7,9 @@ import client from "../../utils/client.js";
import getEmojiByName from "../../utils/getEmojiByName.js"; import getEmojiByName from "../../utils/getEmojiByName.js";
import createPageIndicator from "../../utils/createPageIndicator.js"; import createPageIndicator from "../../utils/createPageIndicator.js";
import { configToDropdown } from "../../actions/roleMenu.js"; import { configToDropdown } from "../../actions/roleMenu.js";
import { modalInteractionCollector } from "../../utils/dualCollector.js";
import lodash from 'lodash';
const isEqual = lodash.isEqual;
const command = (builder: SlashCommandSubcommandBuilder) => const command = (builder: SlashCommandSubcommandBuilder) =>
builder builder
.setName("rolemenu") .setName("rolemenu")
@ -25,7 +27,17 @@ interface ObjectSchema {
}[]; }[];
} }
const editNameDescription = async (interaction: StringSelectMenuInteraction | ButtonInteraction, m: Message, data: {name?: string, description?: string}) => { const defaultRolePageConfig = {
name: "Role Menu Page",
description: "A new role menu page",
min: 0,
max: 0,
options: [
{name: "Role 1", description: null, role: "No role set"}
]
}
const editNameDescription = async (i: ButtonInteraction, interaction: StringSelectMenuInteraction | ButtonInteraction, m: Message, data: {name?: string, description?: string}) => {
let {name, description} = data; let {name, description} = data;
const modal = new ModalBuilder() const modal = new ModalBuilder()
@ -35,14 +47,21 @@ const editNameDescription = async (interaction: StringSelectMenuInteraction | Bu
new ActionRowBuilder<TextInputBuilder>() new ActionRowBuilder<TextInputBuilder>()
.addComponents( .addComponents(
new TextInputBuilder() new TextInputBuilder()
.setLabel("Name")
.setCustomId("name") .setCustomId("name")
.setPlaceholder(name ?? "") .setPlaceholder("Name here...") // TODO: Make better placeholder
.setStyle(TextInputStyle.Short) .setStyle(TextInputStyle.Short)
.setRequired(true), .setValue(name ?? "")
.setRequired(true)
),
new ActionRowBuilder<TextInputBuilder>()
.addComponents(
new TextInputBuilder() new TextInputBuilder()
.setLabel("Description")
.setCustomId("description") .setCustomId("description")
.setPlaceholder(description ?? "") .setPlaceholder("Description here...") // TODO: Make better placeholder
.setStyle(TextInputStyle.Short) .setStyle(TextInputStyle.Short)
.setValue(description ?? "")
) )
) )
const button = new ActionRowBuilder<ButtonBuilder>() const button = new ActionRowBuilder<ButtonBuilder>()
@ -54,6 +73,33 @@ const editNameDescription = async (interaction: StringSelectMenuInteraction | Bu
.setEmoji(getEmojiByName("CONTROL.LEFT", "id") as APIMessageComponentEmoji) .setEmoji(getEmojiByName("CONTROL.LEFT", "id") as APIMessageComponentEmoji)
) )
await i.showModal(modal)
await interaction.editReply({
embeds: [
new EmojiEmbed()
.setTitle("Role Menu")
.setDescription("Modal opened. If you can't see it, click back and try again.")
.setStatus("Success")
],
components: [button]
});
let out: Discord.ModalSubmitInteraction | null;
try {
out = await modalInteractionCollector(
m,
(m) => m.channel!.id === interaction.channel!.id,
(_) => true
) as Discord.ModalSubmitInteraction | null;
} catch (e) {
console.error(e);
out = null;
}
if(!out) return [name, description];
if (out.isButton()) return [name, description];
if(!out.fields) return [name, description];
name = out.fields.fields.find((f) => f.customId === "name")?.value ?? name;
description = out.fields.fields.find((f) => f.customId === "description")?.value ?? description;
return [name, description] return [name, description]
} }
@ -63,7 +109,7 @@ const ellipsis = (str: string, max: number): string => {
return str.slice(0, max - 3) + "..."; return str.slice(0, max - 3) + "...";
} }
const createRoleMenuPage = async (interaction: StringSelectMenuInteraction | ButtonInteraction, m: Message, data?: ObjectSchema) => { const createRoleMenuPage = async (interaction: StringSelectMenuInteraction | ButtonInteraction, m: Message, data?: ObjectSchema): Promise<ObjectSchema | null> => {
if (!data) data = { if (!data) data = {
name: "Role Menu Page", name: "Role Menu Page",
description: "A new role menu page", description: "A new role menu page",
@ -91,6 +137,11 @@ const createRoleMenuPage = async (interaction: StringSelectMenuInteraction | But
); );
let back = false let back = false
if(data.options.length === 0) {
data.options = [
{name: "Role 1", description: null, role: "No role set"}
]
}
do { do {
const previewSelect = configToDropdown("Edit Roles", {name: data.name, description: data.description, min: 1, max: 1, options: data.options}); const previewSelect = configToDropdown("Edit Roles", {name: data.name, description: data.description, min: 1, max: 1, options: data.options});
const embed = new EmojiEmbed() const embed = new EmojiEmbed()
@ -117,23 +168,25 @@ const createRoleMenuPage = async (interaction: StringSelectMenuInteraction | But
await createRoleMenuOptionPage(interaction, m, data.options.find((o) => o.role === (i as StringSelectMenuInteraction).values[0])); await createRoleMenuOptionPage(interaction, m, data.options.find((o) => o.role === (i as StringSelectMenuInteraction).values[0]));
} }
} else if (i.isButton()) { } else if (i.isButton()) {
await i.deferUpdate();
switch (i.customId) { switch (i.customId) {
case "back": case "back":
await i.deferUpdate();
back = true; back = true;
break; break;
case "edit": case "edit":
let [name, description] = await editNameDescription(interaction, m, data); let [name, description] = await editNameDescription(i, interaction, m, data);
data.name = name ? name : data.name; data.name = name ? name : data.name;
data.description = description ? description : data.description; data.description = description ? description : data.description;
break; break;
case "addRole": case "addRole":
await i.deferUpdate();
data.options.push(await createRoleMenuOptionPage(interaction, m)); data.options.push(await createRoleMenuOptionPage(interaction, m));
break; break;
} }
} }
} while (!back); } while (!back);
if(isEqual(data, defaultRolePageConfig)) return null;
return data; return data;
} }
@ -184,14 +237,14 @@ const createRoleMenuOptionPage = async (interaction: StringSelectMenuInteraction
data.role = (i as RoleSelectMenuInteraction).values[0]!; data.role = (i as RoleSelectMenuInteraction).values[0]!;
} }
} else if (i.isButton()) { } else if (i.isButton()) {
await i.deferUpdate();
switch (i.customId) { switch (i.customId) {
case "back": case "back":
await i.deferUpdate();
back = true; back = true;
break; break;
case "edit": case "edit":
await i.deferUpdate(); await i.deferUpdate();
let [name, description] = await editNameDescription(interaction, m, data as {name: string; description: string}); let [name, description] = await editNameDescription(i, interaction, m, data as {name: string; description: string});
data.name = name ? name : data.name; data.name = name ? name : data.name;
data.description = description ? description : data.description; data.description = description ? description : data.description;
break; break;
@ -315,7 +368,9 @@ const callback = async (interaction: CommandInteraction): Promise<void> => {
page++; page++;
break; break;
case "add": case "add":
currentObject.push(await createRoleMenuPage(i, m)); let newPage = await createRoleMenuPage(i, m)
if(!newPage) break;
currentObject.push();
page = currentObject.length - 1; page = currentObject.length - 1;
break; break;
case "reorder": case "reorder":
@ -330,10 +385,14 @@ const callback = async (interaction: CommandInteraction): Promise<void> => {
case "action": case "action":
switch(i.values[0]) { switch(i.values[0]) {
case "edit": case "edit":
currentObject[page] = await createRoleMenuPage(i, m, current!); let edited = await createRoleMenuPage(i, m, current!);
if(!edited) break;
currentObject[page] = edited;
modified = true; modified = true;
break; break;
case "delete": case "delete":
if(page === 0 && currentObject.keys.length - 1 > 0) page++;
else page--;
currentObject.splice(page, 1); currentObject.splice(page, 1);
break; break;
} }

@ -1,5 +1,5 @@
import { LoadingEmbed } from "../../utils/defaults.js"; import { LoadingEmbed } from "../../utils/defaults.js";
import Discord, { CommandInteraction, Message, ActionRowBuilder, StringSelectMenuBuilder, ButtonBuilder, ButtonStyle, StringSelectMenuOptionBuilder, APIMessageComponentEmoji, TextInputBuilder, StringSelectMenuInteraction, ButtonInteraction, MessageComponentInteraction, ChannelSelectMenuBuilder, ChannelSelectMenuInteraction } from "discord.js"; import Discord, { CommandInteraction, Message, ActionRowBuilder, StringSelectMenuBuilder, ButtonBuilder, ButtonStyle, StringSelectMenuOptionBuilder, APIMessageComponentEmoji, TextInputBuilder, StringSelectMenuInteraction, ButtonInteraction, MessageComponentInteraction, ChannelSelectMenuBuilder, ChannelSelectMenuInteraction, ModalBuilder } from "discord.js";
import EmojiEmbed from "../../utils/generateEmojiEmbed.js"; import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
import type { SlashCommandSubcommandBuilder } from "discord.js"; import type { SlashCommandSubcommandBuilder } from "discord.js";
import client from "../../utils/client.js"; import client from "../../utils/client.js";
@ -18,7 +18,7 @@ const command = (builder: SlashCommandSubcommandBuilder) =>
const showModal = async (interaction: MessageComponentInteraction, current: { enabled: boolean; name: string; }) => { const showModal = async (interaction: MessageComponentInteraction, current: { enabled: boolean; name: string; }) => {
await interaction.showModal( await interaction.showModal(
new Discord.ModalBuilder() new ModalBuilder()
.setCustomId("modal") .setCustomId("modal")
.setTitle(`Stats channel name`) .setTitle(`Stats channel name`)
.addComponents( .addComponents(

Loading…
Cancel
Save