Development (#93)
diff --git a/src/actions/roleMenu.ts b/src/actions/roleMenu.ts
index 9c9430d..8b623a4 100644
--- a/src/actions/roleMenu.ts
+++ b/src/actions/roleMenu.ts
@@ -32,7 +32,7 @@
interface ObjectSchema {
name: string;
- description: string;
+ description: string | null;
min: number;
max: number;
options: {
@@ -72,6 +72,7 @@
if (!interaction.member) return;
if (!interaction.guild) return;
const config = await client.database.guilds.read(interaction.guild.id);
+ const options = config.roleMenu.options.filter((option) => option.options.length > 0);
if (!config.roleMenu.enabled) {
return await interaction.reply({
embeds: [
@@ -86,7 +87,7 @@
ephemeral: true
});
}
- if (config.roleMenu.options.length === 0)
+ if (options.length === 0) {
return await interaction.reply({
embeds: [
new EmojiEmbed()
@@ -99,6 +100,7 @@
],
ephemeral: true
});
+ }
const m = await interaction.reply({ embeds: LoadingEmbed, ephemeral: true, fetchReply: true });
if (config.roleMenu.allowWebUI) {
// TODO: Make rolemenu web ui
@@ -180,8 +182,6 @@
await component.deferUpdate();
}
}
-
- const options = config.roleMenu.options;
const selectedRoles: string[][] = [];
const maxPage = options.length;
const completedPages: boolean[] = options.map((option) => option.min === 0);
diff --git a/src/commands/nucleus/premium.ts b/src/commands/nucleus/premium.ts
index 5894850..a3f1368 100644
--- a/src/commands/nucleus/premium.ts
+++ b/src/commands/nucleus/premium.ts
@@ -56,11 +56,8 @@
})
)
);
- const cancel = new ActionRowBuilder<ButtonBuilder>().addComponents(
- new ButtonBuilder().setCustomId("cancel").setLabel("Close").setStyle(ButtonStyle.Danger)
- );
- const components: ActionRowBuilder<StringSelectMenuBuilder | ButtonBuilder>[] = [cancel];
+ const components: ActionRowBuilder<StringSelectMenuBuilder>[] = [];
if (options.length > 0) components.unshift(removeRow);
await interaction.editReply({
embeds: [
@@ -77,24 +74,20 @@
components: components
});
- let i: StringSelectMenuInteraction | ButtonInteraction;
+ let i: StringSelectMenuInteraction;
try {
- const filter = (i: StringSelectMenuInteraction | ButtonInteraction) => i.user.id === interaction.user.id;
- i = await msg.awaitMessageComponent<ComponentType.StringSelect | ComponentType.Button>({
+ const filter = (i: StringSelectMenuInteraction) => i.user.id === interaction.user.id;
+ i = await msg.awaitMessageComponent<ComponentType.StringSelect>({
time: 300000,
filter
});
} catch (e) {
await interaction.deleteReply();
closed = true;
- break;
+ continue;
}
await i.deferUpdate();
- if (i.isButton()) {
- closed = true;
- } else {
- await client.database.premium.removePremium(interaction.user.id, i.values[0]!);
- }
+ await client.database.premium.removePremium(interaction.user.id, i.values[0]!);
} while (!closed);
await interaction.deleteReply();
};
diff --git a/src/commands/settings/rolemenu.ts b/src/commands/settings/rolemenu.ts
index 9779126..dbdcb4c 100644
--- a/src/commands/settings/rolemenu.ts
+++ b/src/commands/settings/rolemenu.ts
@@ -29,11 +29,12 @@
const isEqual = _.isEqual;
-const command = (builder: SlashCommandSubcommandBuilder) => builder.setName("rolemenu").setDescription("rolemenu");
+const command = (builder: SlashCommandSubcommandBuilder) =>
+ builder.setName("rolemenu").setDescription("Allows you to change settings for the servers rolemenu");
interface ObjectSchema {
name: string;
- description: string;
+ description: string | null;
min: number;
max: number;
options: {
@@ -105,7 +106,7 @@
i: ButtonInteraction,
interaction: StringSelectMenuInteraction | ButtonInteraction,
m: Message,
- data: { name?: string; description?: string }
+ data: { name?: string; description?: string | null }
) => {
let { name, description } = data;
const modal = new ModalBuilder()
@@ -162,7 +163,7 @@
if (!out) return [name, description];
if (out.isButton()) 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 = out.fields.fields.find((f) => f.customId === "description")?.value ?? null;
return [name, description];
};
@@ -205,7 +206,7 @@
"Edit Roles",
{
name: data.name,
- description: data.description,
+ description: data.description ?? null,
min: 1,
max: 1,
options: noRoles ? [{ name: "Role 1", description: null, role: "No role set" }] : data.options
@@ -217,7 +218,7 @@
.setTitle(`${data.name}`)
.setStatus("Success")
.setDescription(
- `**Description:**\n> ${data.description}\n\n` +
+ `**Description:**\n> ${data.description ?? "*No description set*"}\n\n` +
`**Min:** ${data.min}` +
(data.min === 0 ? " (Members will be given a skip button)" : "") +
"\n" +
@@ -393,31 +394,47 @@
let page = 0;
let closed = false;
const config = await client.database.guilds.read(interaction.guild.id);
- let currentObject: ObjectSchema[] = _.cloneDeep(config.roleMenu.options);
+ const currentObject: typeof config.roleMenu = _.cloneDeep(config.roleMenu);
let modified = false;
do {
const embed = new EmojiEmbed().setTitle("Role Menu").setEmoji("GUILD.GREEN").setStatus("Success");
- const noRoleMenus = currentObject.length === 0;
+ const noRoleMenus = currentObject.options.length === 0;
let current: ObjectSchema;
const pageSelect = new StringSelectMenuBuilder()
.setCustomId("page")
.setPlaceholder("Select a Role Menu page to manage");
- const actionSelect = new StringSelectMenuBuilder()
- .setCustomId("action")
- .setPlaceholder("Perform an action")
- .addOptions(
- new StringSelectMenuOptionBuilder()
- .setLabel("Edit")
- .setDescription("Edit this page")
- .setValue("edit")
- .setEmoji(getEmojiByName("ICONS.EDIT", "id") as APIMessageComponentEmoji),
- new StringSelectMenuOptionBuilder()
- .setLabel("Delete")
- .setDescription("Delete this page")
- .setValue("delete")
- .setEmoji(getEmojiByName("TICKETS.ISSUE", "id") as APIMessageComponentEmoji)
+ let actionSelect;
+ if (page === 0) {
+ actionSelect = new ActionRowBuilder<ButtonBuilder>().addComponents(
+ new ButtonBuilder()
+ .setCustomId("switch")
+ .setLabel(currentObject.enabled ? "Enabled" : "Disabled")
+ .setStyle(currentObject.enabled ? ButtonStyle.Success : ButtonStyle.Danger)
+ .setEmoji(
+ getEmojiByName(
+ currentObject.enabled ? "CONTROL.TICK" : "CONTROL.CROSS",
+ "id"
+ ) as APIMessageComponentEmoji
+ )
);
+ } else {
+ actionSelect = new StringSelectMenuBuilder()
+ .setCustomId("action")
+ .setPlaceholder("Perform an action")
+ .addOptions(
+ new StringSelectMenuOptionBuilder()
+ .setLabel("Edit")
+ .setDescription("Edit this page")
+ .setValue("edit")
+ .setEmoji(getEmojiByName("ICONS.EDIT", "id") as APIMessageComponentEmoji),
+ new StringSelectMenuOptionBuilder()
+ .setLabel("Delete")
+ .setDescription("Delete this page")
+ .setValue("delete")
+ .setEmoji(getEmojiByName("TICKETS.ISSUE", "id") as APIMessageComponentEmoji)
+ );
+ }
const buttonRow = new ActionRowBuilder<ButtonBuilder>().addComponents(
new ButtonBuilder()
.setCustomId("back")
@@ -428,19 +445,19 @@
.setCustomId("next")
.setEmoji(getEmojiByName("CONTROL.RIGHT", "id") as APIMessageComponentEmoji)
.setStyle(ButtonStyle.Primary)
- .setDisabled(page === Object.keys(currentObject).length - 1 || noRoleMenus),
+ .setDisabled(page === Object.keys(currentObject.options).length || noRoleMenus),
new ButtonBuilder()
.setCustomId("add")
.setLabel("New Page")
.setEmoji(getEmojiByName("TICKETS.SUGGESTION", "id") as APIMessageComponentEmoji)
.setStyle(ButtonStyle.Secondary)
- .setDisabled(Object.keys(currentObject).length >= 24),
+ .setDisabled(Object.keys(currentObject.options).length >= 24),
new ButtonBuilder()
.setCustomId("reorder")
.setLabel("Reorder Pages")
.setEmoji(getEmojiByName("ICONS.REORDER", "id") as APIMessageComponentEmoji)
.setStyle(ButtonStyle.Secondary)
- .setDisabled(Object.keys(currentObject).length <= 1),
+ .setDisabled(Object.keys(currentObject.options).length <= 1),
new ButtonBuilder()
.setCustomId("save")
.setLabel("Save")
@@ -454,22 +471,69 @@
createPageIndicator(1, 1, undefined, true)
);
pageSelect.setDisabled(true);
- actionSelect.setDisabled(true);
+ if (page > 0) (actionSelect as StringSelectMenuBuilder).setDisabled(true);
pageSelect.addOptions(new StringSelectMenuOptionBuilder().setLabel("No role menu pages").setValue("none"));
+ } else if (page === 0) {
+ const cross = getEmojiByName("CONTROL.CROSS");
+ const tick = getEmojiByName("CONTROL.TICK");
+ embed.setDescription(
+ `**Enabled:** ${config.roleMenu.enabled ? `${tick} Yes` : `${cross} No`}\n\n` +
+ `**Pages:** ${currentObject.options.length}\n` +
+ (currentObject.options.length > 0
+ ? currentObject.options
+ .map((key: ObjectSchema) => {
+ return `> **${key.name}:** ${key.description ?? "*No description set*"}`;
+ })
+ .join("\n")
+ : "")
+ );
+ if (currentObject.options.length > 0) {
+ pageSelect.addOptions(
+ currentObject.options.map((key: ObjectSchema, index) => {
+ return new StringSelectMenuOptionBuilder()
+ .setLabel(ellipsis(key.name, 50))
+ .setDescription(
+ ellipsis(
+ key.description?.length
+ ? key.description.length > 0
+ ? key.description
+ : "No description set"
+ : "No description set",
+ 50
+ )
+ )
+ .setValue(index.toString());
+ })
+ );
+ } else {
+ pageSelect.setDisabled(true);
+ pageSelect.addOptions(
+ new StringSelectMenuOptionBuilder().setLabel("No role menu pages").setValue("none")
+ );
+ }
} else {
- page = Math.max(Math.min(page, currentObject.length - 1), 0);
- current = currentObject[page]!;
+ page = Math.max(Math.min(page, currentObject.options.length), 0);
+ current = currentObject.options[page - 1]!;
embed.setDescription(
`**Currently Editing:** ${current.name}\n\n` +
- `**Description:**\n> ${current.description || "*No description set*"}\n` +
+ `**Description:**\n> ${current.description ?? "*No description set*"}\n` +
`\n\n${createPageIndicator(Object.keys(config.roleMenu.options).length, page)}`
);
pageSelect.addOptions(
- currentObject.map((key: ObjectSchema, index) => {
+ currentObject.options.map((key: ObjectSchema, index) => {
return new StringSelectMenuOptionBuilder()
.setLabel(ellipsis(key.name, 50))
- .setDescription(ellipsis(key.description || "No description set", 50))
+ .setDescription(
+ ellipsis(
+ key.description?.length
+ ? key.description.length > 0
+ ? key.description
+ : "No description set"
+ : "No description set",
+ 50
+ )
+ )
.setValue(index.toString());
})
);
@@ -478,9 +542,13 @@
await interaction.editReply({
embeds: [embed],
components: [
- new ActionRowBuilder<StringSelectMenuBuilder>().addComponents(actionSelect),
+ page === 0
+ ? (actionSelect as ActionRowBuilder<ButtonBuilder>)
+ : new ActionRowBuilder<StringSelectMenuBuilder>().addComponents(
+ actionSelect as StringSelectMenuBuilder
+ ),
new ActionRowBuilder<StringSelectMenuBuilder>().addComponents(pageSelect),
- buttonRow
+ buttonRow as ActionRowBuilder<ButtonBuilder>
]
});
let i: StringSelectMenuInteraction | ButtonInteraction;
@@ -512,23 +580,32 @@
break;
}
if (newPage) {
- currentObject.push(newPage);
- page = currentObject.length - 1;
+ currentObject.options.push(newPage);
+ page = currentObject.options.length;
+ modified = true;
}
break;
}
case "reorder": {
- const reordered = await reorderRoleMenuPages(interaction, m, currentObject);
+ const reordered = await reorderRoleMenuPages(interaction, m, currentObject.options);
if (!reordered) break;
- currentObject = reordered;
+ currentObject.options = reordered;
+ modified = true;
break;
}
case "save": {
- await client.database.guilds.write(interaction.guild.id, { "roleMenu.options": currentObject });
+ await client.database.guilds.write(interaction.guild.id, {
+ "roleMenu.options": currentObject.options
+ });
modified = false;
await client.memory.forceUpdate(interaction.guild.id);
break;
}
+ case "switch": {
+ currentObject.enabled = !currentObject.enabled;
+ modified = true;
+ break;
+ }
}
} else if (i.isStringSelectMenu()) {
switch (i.customId) {
@@ -537,14 +614,15 @@
case "edit": {
const edited = await editRoleMenuPage(i, m, current!);
if (!edited) break;
- currentObject[page] = edited;
+ currentObject.options[page] = edited;
modified = true;
break;
}
case "delete": {
- if (page === 0 && currentObject.keys.length - 1 > 0) page++;
+ if (page === 0 && currentObject.options.keys.length - 1 > 0) page++;
else page--;
- currentObject.splice(page, 1);
+ currentObject.options.splice(page, 1);
+ modified = true;
break;
}
}
diff --git a/src/config/default.ts b/src/config/default.ts
index f0b931e..69de019 100644
--- a/src/config/default.ts
+++ b/src/config/default.ts
@@ -88,7 +88,7 @@
},
moderation: {
mute: {
- timeout: false,
+ timeout: true,
role: null,
text: null,
link: null
@@ -121,13 +121,13 @@
},
tracks: [],
roleMenu: {
- enabled: false,
+ enabled: true,
allowWebUI: false,
options: []
},
tags: {},
autoPublish: {
- enabled: false,
+ enabled: true,
channels: []
}
} as GuildConfig;
diff --git a/src/utils/database.ts b/src/utils/database.ts
index f24416a..a1d5f49 100644
--- a/src/utils/database.ts
+++ b/src/utils/database.ts
@@ -1016,7 +1016,7 @@
allowWebUI: boolean;
options: {
name: string;
- description: string;
+ description: string | null;
min: number;
max: number;
options: {