pull/59/head
TheCodedProf 3 years ago
parent 35e7371361
commit ca29ebb481

@ -22,7 +22,10 @@ import { capitalize } from "../utils/generateKeyValueList.js";
import { getCommandByName, getCommandMentionByName } from "../utils/getCommandDataByName.js"; import { getCommandByName, getCommandMentionByName } from "../utils/getCommandDataByName.js";
import getEmojiByName from "../utils/getEmojiByName.js"; import getEmojiByName from "../utils/getEmojiByName.js";
const command = new SlashCommandBuilder().setName("help").setDescription("Shows help for commands").setDMPermission(true); const command = new SlashCommandBuilder()
.setName("help")
.setDescription("Shows help for commands")
.setDMPermission(true);
const styles: Record<string, { emoji: string }> = { const styles: Record<string, { emoji: string }> = {
help: { emoji: "NUCLEUS.LOGO" }, help: { emoji: "NUCLEUS.LOGO" },
@ -127,9 +130,9 @@ const callback = async (interaction: CommandInteraction): Promise<void> => {
); );
} }
for (const option of options) { for (const option of options) {
optionString += ` - \`${option.name}\` (${ApplicationCommandOptionType[option.type].replace("Integer", "Number").replace("String", "Text")}) - ${ optionString += ` - \`${option.name}\` (${ApplicationCommandOptionType[option.type]
option.description .replace("Integer", "Number")
}\n`; .replace("String", "Text")}) - ${option.description}\n`;
} }
const APICommand = const APICommand =
client.commands[ client.commands[
@ -140,7 +143,9 @@ const callback = async (interaction: CommandInteraction): Promise<void> => {
allowedToRun = await APICommand.check(interaction as Interaction, true); allowedToRun = await APICommand.check(interaction as Interaction, true);
} }
embed.setDescription( embed.setDescription(
`${getEmojiByName(styles[currentPath[0]]!.emoji)} **${capitalize(currentData.name)}** | ${currentData.mention}\n\n` + `${getEmojiByName(styles[currentPath[0]]!.emoji)} **${capitalize(currentData.name)}** | ${
currentData.mention
}\n\n` +
`${currentData.description}\n\n` + `${currentData.description}\n\n` +
(APICommand (APICommand
? `${getEmojiByName(allowedToRun ? "CONTROL.TICK" : "CONTROL.CROSS")} You ${ ? `${getEmojiByName(allowedToRun ? "CONTROL.TICK" : "CONTROL.CROSS")} You ${

@ -81,7 +81,7 @@ const callback = async (
"Change nickname", "Change nickname",
"ICONS.EDIT", "ICONS.EDIT",
"modal", "modal",
{default: newNickname ?? ""}, { default: newNickname ?? "" },
new ModalBuilder().setTitle("Editing nickname").addComponents( new ModalBuilder().setTitle("Editing nickname").addComponents(
new ActionRowBuilder<TextInputBuilder>().addComponents( new ActionRowBuilder<TextInputBuilder>().addComponents(
new TextInputBuilder() new TextInputBuilder()

@ -21,7 +21,6 @@ import config from "../../config/main.js";
const command = (builder: SlashCommandSubcommandBuilder) => const command = (builder: SlashCommandSubcommandBuilder) =>
builder.setName("stats").setDescription("Gets the bot's stats"); builder.setName("stats").setDescription("Gets the bot's stats");
const confirm = async (interaction: CommandInteraction) => { const confirm = async (interaction: CommandInteraction) => {
const requiredTexts = [ const requiredTexts = [
"just do it", "just do it",
@ -36,23 +35,23 @@ const confirm = async (interaction: CommandInteraction) => {
"what's a java script", "what's a java script",
"it's a feature not a bug", "it's a feature not a bug",
"that never happened during testing" "that never happened during testing"
] ];
const chosen = requiredTexts[Math.floor(Math.random() * (requiredTexts.length - 1))]!; const chosen = requiredTexts[Math.floor(Math.random() * (requiredTexts.length - 1))]!;
const modal = new ModalBuilder() const modal = new ModalBuilder()
.addComponents( .addComponents(
new ActionRowBuilder<TextInputBuilder>().addComponents( new ActionRowBuilder<TextInputBuilder>().addComponents(
new TextInputBuilder() new TextInputBuilder()
.setStyle(TextInputStyle.Short) .setStyle(TextInputStyle.Short)
.setLabel(`Type "${chosen}" below`) .setLabel(`Type "${chosen}" below`)
.setCustomId("confirm") .setCustomId("confirm")
.setPlaceholder("Guild ID") .setPlaceholder("Guild ID")
.setMinLength(chosen.length) .setMinLength(chosen.length)
.setMaxLength(chosen.length) .setMaxLength(chosen.length)
)
) )
.setTitle("Admin Panel") )
.setCustomId("adminPanel"); .setTitle("Admin Panel")
.setCustomId("adminPanel");
await interaction.showModal(modal); await interaction.showModal(modal);
let out: ModalSubmitInteraction; let out: ModalSubmitInteraction;
try { try {
@ -65,9 +64,8 @@ const confirm = async (interaction: CommandInteraction) => {
} }
await out.deferUpdate(); await out.deferUpdate();
const typed = out.fields.getTextInputValue("confirm"); const typed = out.fields.getTextInputValue("confirm");
return typed.toLowerCase() === chosen.toLowerCase() return typed.toLowerCase() === chosen.toLowerCase();
} };
const callback = async (interaction: CommandInteraction): Promise<void> => { const callback = async (interaction: CommandInteraction): Promise<void> => {
const description = `**Servers:** ${client.guilds.cache.size}\n` + `**Ping:** \`${client.ws.ping * 2}ms\``; const description = `**Servers:** ${client.guilds.cache.size}\n` + `**Ping:** \`${client.ws.ping * 2}ms\``;
@ -159,7 +157,7 @@ const callback = async (interaction: CommandInteraction): Promise<void> => {
new ButtonBuilder().setCustomId("data").setLabel("Guild data").setStyle(ButtonStyle.Secondary), new ButtonBuilder().setCustomId("data").setLabel("Guild data").setStyle(ButtonStyle.Secondary),
new ButtonBuilder().setCustomId("cache").setLabel("Reset cache").setStyle(ButtonStyle.Success), new ButtonBuilder().setCustomId("cache").setLabel("Reset cache").setStyle(ButtonStyle.Success),
new ButtonBuilder().setCustomId("leave").setLabel("Leave").setStyle(ButtonStyle.Danger), new ButtonBuilder().setCustomId("leave").setLabel("Leave").setStyle(ButtonStyle.Danger),
new ButtonBuilder().setCustomId("purge").setLabel("Delete data").setStyle(ButtonStyle.Danger), new ButtonBuilder().setCustomId("purge").setLabel("Delete data").setStyle(ButtonStyle.Danger)
) )
] ]
}); });
@ -186,87 +184,79 @@ const callback = async (interaction: CommandInteraction): Promise<void> => {
await interaction.editReply({ await interaction.editReply({
embeds: [ embeds: [
new EmojiEmbed() new EmojiEmbed()
.setTitle("Stats") .setTitle("Stats")
.setDescription( .setDescription(
`**Name:** ${guild.name}\n` + `**Name:** ${guild.name}\n` +
`**ID:** \`${guild.id}\`\n` + `**ID:** \`${guild.id}\`\n` +
`**Owner:** ${client.users.cache.get(guild.ownerId)!.tag}\n` + `**Owner:** ${client.users.cache.get(guild.ownerId)!.tag}\n` +
`**Member Count:** ${guild.memberCount}\n` + `**Member Count:** ${guild.memberCount}\n` +
`**Created:** <t:${guild.createdTimestamp}:F>\n` + `**Created:** <t:${guild.createdTimestamp}:F>\n` +
`**Added Nucleus:** <t:${guild.members.me!.joinedTimestamp}:R>\n` + `**Added Nucleus:** <t:${guild.members.me!.joinedTimestamp}:R>\n` +
`**Nucleus' Perms:** https://discordapi.com/permissions.html#${guild.members.me!.permissions.valueOf()}\n` `**Nucleus' Perms:** https://discordapi.com/permissions.html#${guild.members.me!.permissions.valueOf()}\n`
) )
.setStatus("Success") .setStatus("Success")
.setEmoji("SETTINGS.STATS.GREEN") .setEmoji("SETTINGS.STATS.GREEN")
] ]
}); });
} else if (i.customId === "leave") { } else if (i.customId === "leave") {
if (!await confirm(interaction)) { if (!(await confirm(interaction))) {
await interaction.editReply({
embeds: [
new EmojiEmbed()
.setTitle("No changes were made")
.setStatus("Danger")
],
components: []
});
return;
}
await guild.leave();
await interaction.editReply({ await interaction.editReply({
embeds: [ embeds: [new EmojiEmbed().setTitle("No changes were made").setStatus("Danger")],
new EmojiEmbed() components: []
});
return;
}
await guild.leave();
await interaction.editReply({
embeds: [
new EmojiEmbed()
.setTitle("Left") .setTitle("Left")
.setDescription(`Left ${guild.name}`) .setDescription(`Left ${guild.name}`)
.setStatus("Success") .setStatus("Success")
.setEmoji("SETTINGS.STATS.GREEN") .setEmoji("SETTINGS.STATS.GREEN")
], ],
components: [] components: []
}); });
} else if (i.customId === "data") { } else if (i.customId === "data") {
await i.deferUpdate(); await i.deferUpdate();
// Get all the data and convert to a string // Get all the data and convert to a string
const data = await client.database.guilds.read(guild.id); const data = await client.database.guilds.read(guild.id);
const stringified = JSON.stringify(data, null, 2); const stringified = JSON.stringify(data, null, 2);
const buffer = Buffer.from(stringified); const buffer = Buffer.from(stringified);
const attachment = new AttachmentBuilder(buffer).setName("data.json"); const attachment = new AttachmentBuilder(buffer).setName("data.json");
await interaction.editReply({
embeds: [
new EmojiEmbed().setTitle("Data").setDescription(`Data for ${guild.name}`).setStatus("Success")
],
components: [],
files: [attachment]
});
} else if (i.customId === "purge") {
if (!(await confirm(interaction))) {
await interaction.editReply({ await interaction.editReply({
embeds: [ embeds: [new EmojiEmbed().setTitle("No changes were made").setStatus("Danger")],
new EmojiEmbed().setTitle("Data").setDescription(`Data for ${guild.name}`).setStatus("Success") components: []
],
components: [],
files: [attachment]
}); });
} else if (i.customId === "purge") { return;
if (!await confirm(interaction)) { }
await interaction.editReply({ await client.database.guilds.delete(GuildID);
embeds: [ await client.database.history.delete(GuildID);
new EmojiEmbed() await client.database.notes.delete(GuildID);
.setTitle("No changes were made") await client.database.transcripts.deleteAll(GuildID);
.setStatus("Danger") await interaction.editReply({
], embeds: [
components: [] new EmojiEmbed()
});
return;
}
await client.database.guilds.delete(GuildID);
await client.database.history.delete(GuildID);
await client.database.notes.delete(GuildID);
await client.database.transcripts.deleteAll(GuildID);
await interaction.editReply({
embeds: [
new EmojiEmbed()
.setTitle("Purge") .setTitle("Purge")
.setDescription(`Deleted data for ${guild.name}`) .setDescription(`Deleted data for ${guild.name}`)
.setStatus("Success") .setStatus("Success")
.setEmoji("SETTINGS.STATS.GREEN") .setEmoji("SETTINGS.STATS.GREEN")
], ],
components: [] components: []
}); });
} else if (i.customId === "cache") { } else if (i.customId === "cache") {
await i.deferUpdate(); await i.deferUpdate();
await client.memory.forceUpdate(guild.id); await client.memory.forceUpdate(guild.id);
await interaction.editReply({ await interaction.editReply({
embeds: [ embeds: [
new EmojiEmbed() new EmojiEmbed()
.setTitle("Cache") .setTitle("Cache")

@ -1,92 +1,107 @@
import { LoadingEmbed } from "../../utils/defaults.js"; import { LoadingEmbed } from "../../utils/defaults.js";
import Discord, { ActionRowBuilder, ButtonBuilder, ButtonStyle, CommandInteraction, ModalBuilder, TextInputBuilder, TextInputStyle } from "discord.js"; import Discord, {
ActionRowBuilder,
ButtonBuilder,
ButtonStyle,
CommandInteraction,
ModalBuilder,
TextInputBuilder,
TextInputStyle
} from "discord.js";
import type { SlashCommandSubcommandBuilder } from "discord.js"; import type { SlashCommandSubcommandBuilder } from "discord.js";
import confirmationMessage from "../../utils/confirmationMessage.js"; import confirmationMessage from "../../utils/confirmationMessage.js";
import EmojiEmbed from "../../utils/generateEmojiEmbed.js"; import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
import client from "../../utils/client.js"; import client from "../../utils/client.js";
import config from "../../config/main.js" import config from "../../config/main.js";
import _ from "lodash"; import _ from "lodash";
const command = (builder: SlashCommandSubcommandBuilder) => const command = (builder: SlashCommandSubcommandBuilder) =>
builder builder.setName("suggest").setDescription("Sends a suggestion to the developers");
.setName("suggest")
.setDescription("Sends a suggestion to the developers")
const callback = async (interaction: CommandInteraction): Promise<void> => { const callback = async (interaction: CommandInteraction): Promise<void> => {
await interaction.guild?.members.fetch(interaction.member!.user.id); await interaction.guild?.members.fetch(interaction.member!.user.id);
await interaction.reply({ embeds: LoadingEmbed, ephemeral: true }); await interaction.reply({ embeds: LoadingEmbed, ephemeral: true });
let closed = false; let closed = false;
let suggestionTitle: string | null = null let suggestionTitle: string | null = null;
let suggestionDesc: string | null = null; let suggestionDesc: string | null = null;
do { do {
const modal = new ModalBuilder() const modal = new ModalBuilder()
.setTitle("Suggestion") .setTitle("Suggestion")
.setComponents( .setComponents(
new ActionRowBuilder<TextInputBuilder>() new ActionRowBuilder<TextInputBuilder>().addComponents(
.addComponents( new TextInputBuilder()
new TextInputBuilder() .setLabel("Suggestion Title")
.setLabel("Suggestion Title") .setRequired(false)
.setRequired(false) .setStyle(TextInputStyle.Short)
.setStyle(TextInputStyle.Short) .setCustomId("suggestionTitle")
.setCustomId("suggestionTitle") .setPlaceholder("Summarize your suggestion in 1 sentence...")
.setPlaceholder("Summarize your suggestion in 1 sentence...") .setMaxLength(256)
.setMaxLength(256) ),
), new ActionRowBuilder<TextInputBuilder>().addComponents(
new ActionRowBuilder<TextInputBuilder>() new TextInputBuilder()
.addComponents( .setLabel("Suggestion Description")
new TextInputBuilder() .setCustomId("suggestionDesc")
.setLabel("Suggestion Description") .setStyle(TextInputStyle.Paragraph)
.setCustomId("suggestionDesc") .setRequired(true)
.setStyle(TextInputStyle.Paragraph) .setPlaceholder("Put the full details of your suggestion here...")
.setRequired(true) .setMinLength(50)
.setPlaceholder("Put the full details of your suggestion here...") )
.setMinLength(50) );
), const o: { suggestionDesc?: string; suggestionTitle?: string } = {};
) if (suggestionTitle) {
const o: {suggestionDesc?: string, suggestionTitle?: string} = {};
if(suggestionTitle) {
o.suggestionTitle = suggestionTitle; o.suggestionTitle = suggestionTitle;
modal.components[0]!.components[0]!.setValue(suggestionTitle); modal.components[0]!.components[0]!.setValue(suggestionTitle);
} }
if(suggestionDesc) { if (suggestionDesc) {
o.suggestionDesc = suggestionDesc o.suggestionDesc = suggestionDesc;
modal.components[1]!.components[0]!.setValue(suggestionDesc); modal.components[1]!.components[0]!.setValue(suggestionDesc);
}; }
const confirmation = await new confirmationMessage(interaction) const confirmation = await new confirmationMessage(interaction)
.setEmoji("ICONS.ADD") .setEmoji("ICONS.ADD")
.setTitle("Suggest") .setTitle("Suggest")
.setDescription(suggestionDesc ? (`Are you sure you want to send this suggestion?\n\n**Title ${suggestionTitle ? "" : "(*Placeholder*)"}:**\n> ${suggestionTitle ? suggestionTitle : `${suggestionDesc.substring(0, 70)}`}\n\n**Suggestion:**\n> ${suggestionDesc}`) : "Please enter your suggestion below.") .setDescription(
suggestionDesc
? `Are you sure you want to send this suggestion?\n\n**Title ${
suggestionTitle ? "" : "(*Placeholder*)"
}:**\n> ${
suggestionTitle ? suggestionTitle : `${suggestionDesc.substring(0, 70)}`
}\n\n**Suggestion:**\n> ${suggestionDesc}`
: "Please enter your suggestion below."
)
.addModal("Edit Suggestion", "ICONS.EDIT", "editSuggestion", _.cloneDeep(o), modal) .addModal("Edit Suggestion", "ICONS.EDIT", "editSuggestion", _.cloneDeep(o), modal)
.setColor("Success") .setColor("Success")
.setInverted(true) .setInverted(true)
.setFailedMessage("Your suggestion was deleted", "Success", "ICONS.ADD") .setFailedMessage("Your suggestion was deleted", "Success", "ICONS.ADD")
.send(true); .send(true);
if(confirmation.modals?.[0] && !_.isEqual(confirmation.modals[0].values, o)) { if (confirmation.modals?.[0] && !_.isEqual(confirmation.modals[0].values, o)) {
suggestionTitle = confirmation.modals[0].values["suggestionTitle"] as string | null; suggestionTitle = confirmation.modals[0].values["suggestionTitle"] as string | null;
suggestionDesc = confirmation.modals[0].values["suggestionDesc"] as string | null; suggestionDesc = confirmation.modals[0].values["suggestionDesc"] as string | null;
continue; continue;
} }
if(confirmation.cancelled || confirmation.success === false) { if (confirmation.cancelled || confirmation.success === false) {
closed = true; closed = true;
return; return;
} }
if (confirmation.success) { if (confirmation.success) {
closed = true; closed = true;
}; }
} while (!closed); } while (!closed);
if(!suggestionDesc) return; if (!suggestionDesc) return;
suggestionTitle = suggestionTitle ? suggestionTitle : `${suggestionDesc.substring(0, 70)}`; suggestionTitle = suggestionTitle ? suggestionTitle : `${suggestionDesc.substring(0, 70)}`;
const channel = client.channels.cache.get(config.suggestionChannel) as Discord.TextChannel; const channel = client.channels.cache.get(config.suggestionChannel) as Discord.TextChannel;
const m = await channel.send({ embeds: LoadingEmbed}); const m = await channel.send({ embeds: LoadingEmbed });
const issue = await client.GitHub.rest.issues.create({ const issue = await client.GitHub.rest.issues.create({
owner: "ClicksMinutePer", owner: "ClicksMinutePer",
repo: "Nucleus", repo: "Nucleus",
title: suggestionTitle, title: suggestionTitle,
body: `Linked Suggestion in Private Developer Channel: [Message](${m.url})\n\n**Suggestion:**\n> ${ body: `Linked Suggestion in Private Developer Channel: [Message](${
suggestionDesc.replaceAll("@", "@<!-- -->").replaceAll("/issues", "/issues<!-- -->").replaceAll("/pull", "/pull<!-- -->") m.url
}\n\n`, })\n\n**Suggestion:**\n> ${suggestionDesc
.replaceAll("@", "@<!-- -->")
.replaceAll("/issues", "/issues<!-- -->")
.replaceAll("/pull", "/pull<!-- -->")}\n\n`,
labels: ["🤖 Auto", "📝 Suggestion"] labels: ["🤖 Auto", "📝 Suggestion"]
}) });
await m.edit({ await m.edit({
embeds: [ embeds: [
new EmojiEmbed() new EmojiEmbed()
@ -94,22 +109,28 @@ const callback = async (interaction: CommandInteraction): Promise<void> => {
.setTitle(`Suggestion from ${interaction.user.tag} (${interaction.user.id})`) .setTitle(`Suggestion from ${interaction.user.tag} (${interaction.user.id})`)
.setDescription(`**Suggestion:**\n> ${suggestionDesc}\n\n`) .setDescription(`**Suggestion:**\n> ${suggestionDesc}\n\n`)
.setStatus("Success") .setStatus("Success")
.setFooter({text: `${issue.data.number}`}) .setFooter({ text: `${issue.data.number}` })
], ],
components: [ components: [
new Discord.ActionRowBuilder<ButtonBuilder>().addComponents( new Discord.ActionRowBuilder<ButtonBuilder>().addComponents(
new ButtonBuilder().setCustomId("accept:Suggestion").setLabel("Accept").setStyle(ButtonStyle.Success), new ButtonBuilder().setCustomId("accept:Suggestion").setLabel("Accept").setStyle(ButtonStyle.Success),
new ButtonBuilder().setCustomId("deny:Suggestion").setLabel("Deny").setStyle(ButtonStyle.Danger), new ButtonBuilder().setCustomId("deny:Suggestion").setLabel("Deny").setStyle(ButtonStyle.Danger),
new ButtonBuilder().setCustomId("close:Suggestion").setLabel("Close").setStyle(ButtonStyle.Secondary), new ButtonBuilder().setCustomId("close:Suggestion").setLabel("Close").setStyle(ButtonStyle.Secondary),
new ButtonBuilder().setCustomId("implemented:Suggestion").setLabel("Implemented").setStyle(ButtonStyle.Secondary), new ButtonBuilder()
new ButtonBuilder().setLabel(`Open Issue #${issue.data.number}`).setStyle(ButtonStyle.Link).setURL(`https://github.com/ClicksMinutePer/Nucleus/issues/${issue.data.number}`), .setCustomId("implemented:Suggestion")
.setLabel("Implemented")
.setStyle(ButtonStyle.Secondary),
new ButtonBuilder()
.setLabel(`Open Issue #${issue.data.number}`)
.setStyle(ButtonStyle.Link)
.setURL(`https://github.com/ClicksMinutePer/Nucleus/issues/${issue.data.number}`)
), ),
new Discord.ActionRowBuilder<ButtonBuilder>().addComponents( new Discord.ActionRowBuilder<ButtonBuilder>().addComponents(
new ButtonBuilder().setCustomId("lock:Suggestion").setLabel("Lock").setStyle(ButtonStyle.Danger), new ButtonBuilder().setCustomId("lock:Suggestion").setLabel("Lock").setStyle(ButtonStyle.Danger),
new ButtonBuilder().setCustomId("spam:Suggestion").setLabel("Mark as Spam").setStyle(ButtonStyle.Danger), new ButtonBuilder().setCustomId("spam:Suggestion").setLabel("Mark as Spam").setStyle(ButtonStyle.Danger)
) )
] ]
}) });
await interaction.editReply({ await interaction.editReply({
embeds: [ embeds: [
new EmojiEmbed() new EmojiEmbed()

@ -45,8 +45,8 @@ const callback = async (interaction: CommandInteraction): Promise<void> => {
.setDescription( .setDescription(
"Nucleus scans content sent by users for malware and NSFW content\n" + "Nucleus scans content sent by users for malware and NSFW content\n" +
'Malware is detected using [ClamAV](https://clamav.net/), and the standard ClamAV database."\n' + 'Malware is detected using [ClamAV](https://clamav.net/), and the standard ClamAV database."\n' +
'NSFW detection is provided by [NsfwJS](https://nsfwjs.com/), with a model provided by [GantMan](https://github.com/GantMan/nsfw_model/releases/tag/1.1.0)\n\n' + "NSFW detection is provided by [NsfwJS](https://nsfwjs.com/), with a model provided by [GantMan](https://github.com/GantMan/nsfw_model/releases/tag/1.1.0)\n\n" +
'All data is processed on our servers and is not processed by a 3rd party.' "All data is processed on our servers and is not processed by a 3rd party."
) )
.setEmoji("NUCLEUS.LOGO") .setEmoji("NUCLEUS.LOGO")
.setStatus("Danger") .setStatus("Danger")

@ -718,7 +718,7 @@ const mentionMenu = async (
.setEmoji("GUILD.SETTINGS.GREEN") .setEmoji("GUILD.SETTINGS.GREEN")
.setFooter({ .setFooter({
text: unsavedChanges ? "No changes made" : "Changes not saved" text: unsavedChanges ? "No changes made" : "Changes not saved"
});; });
await interaction.editReply({ embeds: [embed], components: [menu, allowedMenu, buttons] }); await interaction.editReply({ embeds: [embed], components: [menu, allowedMenu, buttons] });
@ -1047,11 +1047,14 @@ const callback = async (interaction: CommandInteraction): Promise<void> => {
let closed = false; let closed = false;
let current = _.cloneDeep(config); let current = _.cloneDeep(config);
do { do {
const button = new ActionRowBuilder<ButtonBuilder>().addComponents( const button = new ActionRowBuilder<ButtonBuilder>().addComponents(
new ButtonBuilder().setCustomId("save").setLabel("Save").setStyle(ButtonStyle.Success).setDisabled(_.isEqual(config, current)) new ButtonBuilder()
.setCustomId("save")
.setLabel("Save")
.setStyle(ButtonStyle.Success)
.setDisabled(_.isEqual(config, current))
); );
const selectMenu = new ActionRowBuilder<StringSelectMenuBuilder>().addComponents( const selectMenu = new ActionRowBuilder<StringSelectMenuBuilder>().addComponents(
new StringSelectMenuBuilder() new StringSelectMenuBuilder()
@ -1116,7 +1119,7 @@ const callback = async (interaction: CommandInteraction): Promise<void> => {
continue; continue;
} }
await i.deferUpdate(); await i.deferUpdate();
if(i.isButton()) { if (i.isButton()) {
await client.database.guilds.write(interaction.guild.id, { filters: current }); await client.database.guilds.write(interaction.guild.id, { filters: current });
await client.memory.forceUpdate(interaction.guild.id); await client.memory.forceUpdate(interaction.guild.id);
config = current; config = current;

@ -131,7 +131,7 @@ export default async function (walkthrough = false) {
} }
if (walkthrough && !(json["mongoUrl"] ?? false)) json["mongoUrl"] = "mongodb://127.0.0.1:27017"; if (walkthrough && !(json["mongoUrl"] ?? false)) json["mongoUrl"] = "mongodb://127.0.0.1:27017";
if (!((json["baseUrl"] as string | undefined) ?? "").endsWith("/")) (json["baseUrl"] as string) += "/"; if (!((json["baseUrl"] as string | undefined) ?? "").endsWith("/")) (json["baseUrl"] as string) += "/";
const localhost = "127.0.0.1" const localhost = "127.0.0.1";
json["mongoUrl"] = (json["mongoUrl"]! as string).replace("localhost", localhost); json["mongoUrl"] = (json["mongoUrl"]! as string).replace("localhost", localhost);
json["baseUrl"] = (json["baseUrl"]! as string).replace("localhost", localhost); json["baseUrl"] = (json["baseUrl"]! as string).replace("localhost", localhost);
json["mongoOptions"] = { json["mongoOptions"] = {
@ -145,7 +145,7 @@ export default async function (walkthrough = false) {
socket: json["clamAVSocket"] as string | undefined, socket: json["clamAVSocket"] as string | undefined,
host: json["clamAVHost"] as string | undefined, host: json["clamAVHost"] as string | undefined,
port: json["clamAVPort"] as number | undefined port: json["clamAVPort"] as number | undefined
} };
fs.writeFileSync("./src/config/main.ts", "export default " + JSON.stringify(json, null, 4) + ";"); fs.writeFileSync("./src/config/main.ts", "export default " + JSON.stringify(json, null, 4) + ";");

@ -4,7 +4,18 @@ import create from "../actions/tickets/create.js";
import close from "../actions/tickets/delete.js"; import close from "../actions/tickets/delete.js";
import createTranscript from "../premium/createTranscript.js"; import createTranscript from "../premium/createTranscript.js";
import { ActionRowBuilder, ButtonBuilder, ButtonInteraction, ButtonStyle, Interaction, InteractionEditReplyOptions, ModalBuilder, ModalSubmitInteraction, TextInputBuilder, TextInputStyle } from "discord.js"; import {
ActionRowBuilder,
ButtonBuilder,
ButtonInteraction,
ButtonStyle,
Interaction,
InteractionEditReplyOptions,
ModalBuilder,
ModalSubmitInteraction,
TextInputBuilder,
TextInputStyle
} from "discord.js";
import type { NucleusClient } from "../utils/client.js"; import type { NucleusClient } from "../utils/client.js";
import EmojiEmbed from "../utils/generateEmojiEmbed.js"; import EmojiEmbed from "../utils/generateEmojiEmbed.js";
@ -28,7 +39,10 @@ async function errorMessage(interaction: ButtonInteraction, message: string) {
async function interactionCreate(interaction: Interaction) { async function interactionCreate(interaction: Interaction) {
if (interaction.isButton()) { if (interaction.isButton()) {
if (interaction.customId.endsWith(":Suggestion")) { if (interaction.customId.endsWith(":Suggestion")) {
const value = interaction.customId.startsWith("accept") || interaction.customId.startsWith("implement") ? true : false const value =
interaction.customId.startsWith("accept") || interaction.customId.startsWith("implement")
? true
: false;
return await modifySuggestion(interaction, value); return await modifySuggestion(interaction, value);
} }
switch (interaction.customId) { switch (interaction.customId) {
@ -88,10 +102,7 @@ const getReason = async (buttonInteraction: ButtonInteraction, prompt: string) =
const modal = new ModalBuilder() const modal = new ModalBuilder()
.addComponents( .addComponents(
new ActionRowBuilder<TextInputBuilder>().addComponents( new ActionRowBuilder<TextInputBuilder>().addComponents(
new TextInputBuilder() new TextInputBuilder().setStyle(TextInputStyle.Paragraph).setLabel(prompt).setCustomId("typed")
.setStyle(TextInputStyle.Paragraph)
.setLabel(prompt)
.setCustomId("typed")
) )
) )
.setTitle("Reason") .setTitle("Reason")
@ -108,74 +119,95 @@ const getReason = async (buttonInteraction: ButtonInteraction, prompt: string) =
} }
await out.deferUpdate(); await out.deferUpdate();
return out.fields.getTextInputValue("typed"); return out.fields.getTextInputValue("typed");
} };
async function modifySuggestion(interaction: ButtonInteraction, accept: boolean) { async function modifySuggestion(interaction: ButtonInteraction, accept: boolean) {
const message = interaction.message; const message = interaction.message;
await message.fetch(); await message.fetch();
if (message.embeds.length === 0) return; if (message.embeds.length === 0) return;
const embed = message.embeds[0]!; const embed = message.embeds[0]!;
const issueNum = embed.footer!.text const issueNum = embed.footer!.text;
if(!issueNum) return; if (!issueNum) return;
const issue = { const issue = {
owner: "ClicksMinutePer", owner: "ClicksMinutePer",
repo: "Nucleus", repo: "Nucleus",
issue_number: parseInt(issueNum) issue_number: parseInt(issueNum)
} };
let name = "Unknown"; let name = "Unknown";
const components: InteractionEditReplyOptions["components"] = []; const components: InteractionEditReplyOptions["components"] = [];
switch(interaction.customId) { switch (interaction.customId) {
case "accept:Suggestion": { case "accept:Suggestion": {
name = "Accepted"; name = "Accepted";
await interaction.deferUpdate(); await interaction.deferUpdate();
await client.GitHub.rest.issues.createComment({...issue, body: "Suggestion accepted by " + interaction.user.tag}); await client.GitHub.rest.issues.createComment({
components.push(new ActionRowBuilder<ButtonBuilder>().addComponents( ...issue,
new ButtonBuilder().setCustomId("close:Suggestion").setLabel("Close").setStyle(ButtonStyle.Secondary), body: "Suggestion accepted by " + interaction.user.tag
new ButtonBuilder().setCustomId("implemented:Suggestion").setLabel("Implemented").setStyle(ButtonStyle.Secondary) });
)) components.push(
new ActionRowBuilder<ButtonBuilder>().addComponents(
new ButtonBuilder()
.setCustomId("close:Suggestion")
.setLabel("Close")
.setStyle(ButtonStyle.Secondary),
new ButtonBuilder()
.setCustomId("implemented:Suggestion")
.setLabel("Implemented")
.setStyle(ButtonStyle.Secondary)
)
);
break; break;
} }
case "deny:Suggestion": { case "deny:Suggestion": {
name = "Denied"; name = "Denied";
const reason = await getReason(interaction, "Reason for denial"); const reason = await getReason(interaction, "Reason for denial");
await client.GitHub.rest.issues.createComment({...issue, body: "Suggestion denied by " + interaction.user.tag + " for reason:\n>" + reason}); await client.GitHub.rest.issues.createComment({
await client.GitHub.rest.issues.update({...issue, state: "closed", state_reason: "not_planned"}); ...issue,
body: "Suggestion denied by " + interaction.user.tag + " for reason:\n>" + reason
});
await client.GitHub.rest.issues.update({ ...issue, state: "closed", state_reason: "not_planned" });
// await client.GitHub.rest.issues.lock({...issue, lock_reason: "resolved"}) // await client.GitHub.rest.issues.lock({...issue, lock_reason: "resolved"})
components.push(new ActionRowBuilder<ButtonBuilder>().addComponents( components.push(
new ButtonBuilder().setCustomId("lock:Suggestion").setLabel("Lock").setStyle(ButtonStyle.Danger) new ActionRowBuilder<ButtonBuilder>().addComponents(
)) new ButtonBuilder().setCustomId("lock:Suggestion").setLabel("Lock").setStyle(ButtonStyle.Danger)
)
);
break; break;
} }
case "close:Suggestion": { case "close:Suggestion": {
name = "Closed"; name = "Closed";
const reason = await getReason(interaction, "Reason for closing"); const reason = await getReason(interaction, "Reason for closing");
await client.GitHub.rest.issues.createComment({...issue, body: "Suggestion closed by " + interaction.user.tag + " for reason:\n>" + reason}); await client.GitHub.rest.issues.createComment({
await client.GitHub.rest.issues.update({...issue, state: "closed"}); ...issue,
body: "Suggestion closed by " + interaction.user.tag + " for reason:\n>" + reason
});
await client.GitHub.rest.issues.update({ ...issue, state: "closed" });
// await client.GitHub.rest.issues.lock({...issue}) // await client.GitHub.rest.issues.lock({...issue})
components.push(new ActionRowBuilder<ButtonBuilder>().addComponents( components.push(
new ButtonBuilder().setCustomId("lock:Suggestion").setLabel("Lock").setStyle(ButtonStyle.Danger) new ActionRowBuilder<ButtonBuilder>().addComponents(
)) new ButtonBuilder().setCustomId("lock:Suggestion").setLabel("Lock").setStyle(ButtonStyle.Danger)
)
);
break; break;
} }
case "implement:Suggestion": { case "implement:Suggestion": {
name = "Implemented"; name = "Implemented";
await interaction.deferUpdate(); await interaction.deferUpdate();
await client.GitHub.rest.issues.createComment({...issue, body: "Suggestion implemented"}); await client.GitHub.rest.issues.createComment({ ...issue, body: "Suggestion implemented" });
await client.GitHub.rest.issues.update({...issue, state: "closed", state_reason: "completed"}); await client.GitHub.rest.issues.update({ ...issue, state: "closed", state_reason: "completed" });
await client.GitHub.rest.issues.lock({...issue, lock_reason: "resolved"}) await client.GitHub.rest.issues.lock({ ...issue, lock_reason: "resolved" });
break; break;
} }
case "lock:Suggestion": { case "lock:Suggestion": {
name = "Locked"; name = "Locked";
await interaction.deferUpdate(); await interaction.deferUpdate();
await client.GitHub.rest.issues.lock({...issue}); await client.GitHub.rest.issues.lock({ ...issue });
break; break;
} }
case "spam:Suggestion": { case "spam:Suggestion": {
name = "Marked as Spam"; name = "Marked as Spam";
await interaction.deferUpdate(); await interaction.deferUpdate();
await client.GitHub.rest.issues.update({...issue, state: "closed", state_reason: "not_planned"}); await client.GitHub.rest.issues.update({ ...issue, state: "closed", state_reason: "not_planned" });
await client.GitHub.rest.issues.lock({...issue, lock_reason: "spam"}) await client.GitHub.rest.issues.lock({ ...issue, lock_reason: "spam" });
break; break;
} }
} }
@ -189,7 +221,7 @@ async function modifySuggestion(interaction: ButtonInteraction, accept: boolean)
.setDescription(embed!.description!) .setDescription(embed!.description!)
.setFields({ .setFields({
name: name + " by", name: name + " by",
value: interaction.user.tag, value: interaction.user.tag
}) })
.setStatus(newcolor) .setStatus(newcolor)
.setFooter(embed!.footer); .setFooter(embed!.footer);

@ -106,7 +106,13 @@ class confirmationMessage {
this.reason = reason; this.reason = reason;
return this; return this;
} }
addModal(buttonText: string, emoji: string, customId: string, current: Record<string, string>, modal: Discord.ModalBuilder) { addModal(
buttonText: string,
emoji: string,
customId: string,
current: Record<string, string>,
modal: Discord.ModalBuilder
) {
modal.setCustomId(customId); modal.setCustomId(customId);
this.modals.push({ buttonText, emoji, customId, modal, values: current }); this.modals.push({ buttonText, emoji, customId, modal, values: current });
return this; return this;

Loading…
Cancel
Save