Development (#91)

pull/95/head
Skyler 3 years ago committed by GitHub
commit 512483f1e4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -45,7 +45,8 @@ interface ObjectSchema {
export const configToDropdown = (
placeholder: string,
currentPageData: ObjectSchema,
selectedRoles?: string[]
selectedRoles?: string[],
disabled?: boolean
): ActionRowBuilder<StringSelectMenuBuilder> => {
return new ActionRowBuilder<StringSelectMenuBuilder>().addComponents(
new StringSelectMenuBuilder()
@ -53,6 +54,7 @@ export const configToDropdown = (
.setPlaceholder(placeholder)
.setMinValues(currentPageData.min)
.setMaxValues(currentPageData.max)
.setDisabled(disabled)
.addOptions(
currentPageData.options.map((option: { name: string; description: string | null; role: string }) => {
const builder = new StringSelectMenuOptionBuilder()

@ -6,7 +6,7 @@ const command = (builder: SlashCommandSubcommandBuilder) =>
builder.setName("guide").setDescription("Shows the welcome guide for the bot");
const callback = async (interaction: CommandInteraction) => {
await guide(interaction.guild!, interaction);
await guide(interaction.guild, interaction);
};
export { command };

@ -165,7 +165,10 @@ const callback = async (interaction: CommandInteraction): Promise<void> => {
const gaveUser = await client.users.fetch(hasPremium[1]);
premiumGuild = `**This server has premium! It was ${
hasPremium[2] === 3 && hasPremium[3]
? `automatically applied by ${gaveUser.username}#${gaveUser.discriminator}`
? `automatically applied by ` +
(gaveUser.discriminator !== "0"
? `${gaveUser.username}#${gaveUser.discriminator}`
: `@${gaveUser.username}`)
: `given by <@${hasPremium[1]}>`
}**\n\n`;
}

@ -19,7 +19,6 @@ const command = (builder: SlashCommandSubcommandBuilder) =>
builder.setName("suggest").setDescription("Sends a suggestion to the developers");
const callback = async (interaction: CommandInteraction): Promise<void> => {
await interaction.guild?.members.fetch(interaction.member!.user.id);
await interaction.reply({ embeds: LoadingEmbed, ephemeral: true });
let closed = false;
let suggestionTitle: string | null = null;
@ -90,18 +89,25 @@ const callback = async (interaction: CommandInteraction): Promise<void> => {
suggestionTitle = suggestionTitle ? suggestionTitle : `${suggestionDesc.substring(0, 70)}`;
const channel = client.channels.cache.get(config.suggestionChannel) as Discord.TextChannel;
const m = await channel.send({ embeds: LoadingEmbed });
const issue = await client.GitHub.rest.issues.create({
owner: "ClicksMinutePer",
repo: "Nucleus",
title: suggestionTitle,
body: `Linked Suggestion in Private Developer Channel: [Message](${
m.url
})\n\n**Suggestion:**\n> ${suggestionDesc
.replaceAll("@", "@<!-- -->")
.replaceAll("/issues", "/issues<!-- -->")
.replaceAll("/pull", "/pull<!-- -->")}\n\n`,
labels: ["🤖 Auto", "📝 Suggestion"]
});
let issueNumber: number | null = null;
try {
const issue = await client.GitHub.rest.issues.create({
owner: "ClicksMinutePer",
repo: "Nucleus",
title: suggestionTitle,
body: `Linked Suggestion in Private Developer Channel: [Message](${
m.url
})\n\n**Suggestion:**\n> ${suggestionDesc
.replaceAll("@", "@<!-- -->")
.replaceAll("/issues", "/issues<!-- -->")
.replaceAll("/pull", "/pull<!-- -->")}\n\n`,
labels: ["🤖 Auto", "📝 Suggestion"]
});
issueNumber = issue.data.number;
} catch (_e) {
console.log("Could not connect to GitHub");
}
const disabled = issueNumber ? false : true;
await m.edit({
embeds: [
new EmojiEmbed()
@ -109,25 +115,47 @@ const callback = async (interaction: CommandInteraction): Promise<void> => {
.setTitle(`Suggestion from ${interaction.user.tag} (${interaction.user.id})`)
.setDescription(`**Suggestion:**\n> ${suggestionDesc}\n\n`)
.setStatus("Success")
.setFooter({ text: `${issue.data.number}` })
.setFooter({ text: `${issueNumber ? issueNumber : "Could not connect to GitHub"}` })
],
components: [
new Discord.ActionRowBuilder<ButtonBuilder>().addComponents(
new ButtonBuilder().setCustomId("accept:Suggestion").setLabel("Accept").setStyle(ButtonStyle.Success),
new ButtonBuilder().setCustomId("deny:Suggestion").setLabel("Deny").setStyle(ButtonStyle.Danger),
new ButtonBuilder().setCustomId("close:Suggestion").setLabel("Close").setStyle(ButtonStyle.Secondary),
new ButtonBuilder()
.setCustomId("accept:Suggestion")
.setLabel("Accept")
.setStyle(ButtonStyle.Success)
.setDisabled(disabled),
new ButtonBuilder()
.setCustomId("deny:Suggestion")
.setLabel("Deny")
.setStyle(ButtonStyle.Danger)
.setDisabled(disabled),
new ButtonBuilder()
.setCustomId("close:Suggestion")
.setLabel("Close")
.setStyle(ButtonStyle.Secondary)
.setDisabled(disabled),
new ButtonBuilder()
.setCustomId("implemented:Suggestion")
.setLabel("Implemented")
.setStyle(ButtonStyle.Secondary),
.setStyle(ButtonStyle.Secondary)
.setDisabled(disabled),
new ButtonBuilder()
.setLabel(`Open Issue #${issue.data.number}`)
.setLabel(`Open Issue #${issueNumber ? issueNumber : "0"}`)
.setStyle(ButtonStyle.Link)
.setURL(`https://github.com/ClicksMinutePer/Nucleus/issues/${issue.data.number}`)
.setURL(`https://github.com/ClicksMinutePer/Nucleus/issues/${issueNumber}`)
.setDisabled(disabled)
),
new Discord.ActionRowBuilder<ButtonBuilder>().addComponents(
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("lock:Comment")
.setLabel("Lock")
.setStyle(ButtonStyle.Danger)
.setDisabled(disabled),
new ButtonBuilder()
.setCustomId("spam:Suggestion")
.setLabel("Mark as Spam")
.setStyle(ButtonStyle.Danger)
.setDisabled(disabled)
)
]
});

@ -120,6 +120,7 @@ const editNameDescription = async (
.setStyle(TextInputStyle.Short)
.setValue(name ?? "")
.setRequired(true)
.setMaxLength(100)
),
new ActionRowBuilder<TextInputBuilder>().addComponents(
new TextInputBuilder()
@ -128,6 +129,8 @@ const editNameDescription = async (
.setPlaceholder("A short description of the role (e.g. A role for people who code)")
.setStyle(TextInputStyle.Short)
.setValue(description ?? "")
.setRequired(false)
.setMaxLength(100)
)
);
const button = new ActionRowBuilder<ButtonBuilder>().addComponents(
@ -159,15 +162,15 @@ const editNameDescription = async (
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;
description = out.fields.fields.find((f) => f.customId === "description")?.value ?? "";
return [name, description];
};
const defaultRoleMenuData = {
name: "Role Menu Page",
description: "A new role menu page",
name: "New Page",
description: "",
min: 0,
max: 0,
max: 1,
options: []
};
@ -196,17 +199,20 @@ const editRoleMenuPage = async (
);
let back = false;
if (data.options.length === 0) {
data.options = [{ name: "Role 1", description: null, role: "No role set" }];
}
do {
const previewSelect = configToDropdown("Edit Roles", {
name: data.name,
description: data.description,
min: 1,
max: 1,
options: data.options
});
const noRoles = data.options.length === 0;
const previewSelect = configToDropdown(
"Edit Roles",
{
name: data.name,
description: data.description,
min: 1,
max: 1,
options: noRoles ? [{ name: "Role 1", description: null, role: "No role set" }] : data.options
},
undefined,
noRoles
);
const embed = new EmojiEmbed()
.setTitle(`${data.name}`)
.setStatus("Success")
@ -215,7 +221,8 @@ const editRoleMenuPage = async (
`**Min:** ${data.min}` +
(data.min === 0 ? " (Members will be given a skip button)" : "") +
"\n" +
`**Max:** ${data.max}\n`
`**Max:** ${data.max}\n` +
`\n**Roles:** ${data.options.length === 0 ? "*No roles set*" : data.options.length}`
);
await interaction.editReply({ embeds: [embed], components: [previewSelect, buttons] });
@ -237,7 +244,8 @@ const editRoleMenuPage = async (
await createRoleMenuOptionPage(
interaction,
m,
data.options.find((o) => o.role === (i as StringSelectMenuInteraction).values[0])
data.options.find((o) => o.role === (i as StringSelectMenuInteraction).values[0]),
false
);
}
} else if (i.isButton()) {
@ -255,7 +263,8 @@ const editRoleMenuPage = async (
}
case "addRole": {
await i.deferUpdate();
data.options.push(await createRoleMenuOptionPage(interaction, m));
const out = await createRoleMenuOptionPage(interaction, m, undefined, true);
if (out) data.options.push(out);
break;
}
}
@ -268,8 +277,10 @@ const editRoleMenuPage = async (
const createRoleMenuOptionPage = async (
interaction: StringSelectMenuInteraction | ButtonInteraction,
m: Message,
data?: { name: string; description: string | null; role: string }
data?: { name: string; description: string | null; role: string },
newRole: boolean = false
) => {
const initialData = _.cloneDeep(data);
const { renderRole } = client.logger;
if (!data)
data = {
@ -281,19 +292,29 @@ const createRoleMenuOptionPage = async (
const buttons = new ActionRowBuilder<ButtonBuilder>().addComponents(
new ButtonBuilder()
.setCustomId("back")
.setLabel("Back")
.setStyle(ButtonStyle.Secondary)
.setEmoji(getEmojiByName("CONTROL.LEFT", "id") as APIMessageComponentEmoji),
.setLabel(newRole ? "Add" : "Back")
.setStyle(newRole ? ButtonStyle.Success : ButtonStyle.Secondary)
.setEmoji(getEmojiByName("ICONS.SAVE", "id") as APIMessageComponentEmoji),
new ButtonBuilder()
.setCustomId("edit")
.setLabel("Edit Details")
.setStyle(ButtonStyle.Primary)
.setEmoji(getEmojiByName("ICONS.EDIT", "id") as APIMessageComponentEmoji)
.setEmoji(getEmojiByName("ICONS.EDIT", "id") as APIMessageComponentEmoji),
new ButtonBuilder()
.setCustomId("delete")
.setLabel("Delete")
.setStyle(ButtonStyle.Danger)
.setEmoji(getEmojiByName("TICKETS.ISSUE", "id") as APIMessageComponentEmoji),
new ButtonBuilder()
.setCustomId("cancel")
.setLabel("Cancel")
.setStyle(ButtonStyle.Secondary)
.setEmoji(getEmojiByName("CONTROL.LEFT", "id") as APIMessageComponentEmoji)
);
do {
const roleSelect = new RoleSelectMenuBuilder()
.setCustomId("role")
.setPlaceholder(data.role ? "Set role to" : "Set the role");
.setPlaceholder(data.role ? "Change role to" : "Select a role");
const embed = new EmojiEmbed()
.setTitle(`${data.name}`)
.setStatus("Success")
@ -325,6 +346,12 @@ const createRoleMenuOptionPage = async (
if (i.customId === "role") {
await i.deferUpdate();
data.role = (i as RoleSelectMenuInteraction).values[0]!;
await interaction.editReply({
embeds: [
new EmojiEmbed().setTitle(`Applying changes`).setStatus("Danger").setEmoji("NUCLEUS.LOADING")
],
components: []
});
}
} else if (i.isButton()) {
switch (i.customId) {
@ -334,7 +361,6 @@ const createRoleMenuOptionPage = async (
break;
}
case "edit": {
await i.deferUpdate();
const [name, description] = await editNameDescription(
i,
interaction,
@ -345,6 +371,15 @@ const createRoleMenuOptionPage = async (
data.description = description ? description : data.description;
break;
}
case "delete": {
await i.deferUpdate();
return null;
}
case "cancel": {
await i.deferUpdate();
if (newRole) return null;
else return initialData;
}
}
}
} while (!back);
@ -383,6 +418,7 @@ const callback = async (interaction: CommandInteraction): Promise<void> => {
.setValue("delete")
.setEmoji(getEmojiByName("TICKETS.ISSUE", "id") as APIMessageComponentEmoji)
);
console.log(page);
const buttonRow = new ActionRowBuilder<ButtonBuilder>().addComponents(
new ButtonBuilder()
.setCustomId("back")
@ -422,7 +458,7 @@ const callback = async (interaction: CommandInteraction): Promise<void> => {
actionSelect.setDisabled(true);
pageSelect.addOptions(new StringSelectMenuOptionBuilder().setLabel("No role menu pages").setValue("none"));
} else {
page = Math.min(page, Object.keys(currentObject).length - 1);
page = Math.max(Math.min(page, currentObject.length - 1), 0);
current = currentObject[page]!;
embed.setDescription(
`**Currently Editing:** ${current.name}\n\n` +

@ -32,9 +32,10 @@ export async function callback(_client: NucleusClient, message: Message) {
await message.crosspost();
} else {
await singleNotify(
`Nucleus does not have Manage Messages in <#${message.channel.id}>`,
"crosspost.noManageMessages",
message.guild.id,
true
`Nucleus does not have Manage Messages in <#${message.channel.id}>`,
"Warning"
);
}
}

@ -16,35 +16,49 @@ import getEmojiByName from "../utils/getEmojiByName.js";
import createPageIndicator from "../utils/createPageIndicator.js";
import { Embed } from "../utils/defaults.js";
export default async (guild: Guild, interaction?: CommandInteraction) => {
let c: GuildTextBasedChannel | null = guild.publicUpdatesChannel ? guild.publicUpdatesChannel : guild.systemChannel;
c = c
? c
: (guild.channels.cache.find(
(ch) =>
[
ChannelType.GuildText,
ChannelType.GuildAnnouncement,
ChannelType.PublicThread,
ChannelType.PrivateThread,
ChannelType.AnnouncementThread
].includes(ch.type) &&
ch.permissionsFor(guild.roles.everyone).has("SendMessages") &&
ch.permissionsFor(guild.members.me!).has("EmbedLinks")
) as GuildTextBasedChannel | undefined) ?? null;
if (interaction) c = interaction.channel as GuildTextBasedChannel;
if (!c) {
return;
}
export default async (guild: Guild | null, interaction?: CommandInteraction) => {
let m: Message;
if (interaction) {
m = (await interaction.reply({
embeds: LoadingEmbed,
fetchReply: true,
ephemeral: true
})) as Message;
if (guild) {
let c: GuildTextBasedChannel | null = guild.publicUpdatesChannel
? guild.publicUpdatesChannel
: guild.systemChannel;
c = c
? c
: (guild.channels.cache.find(
(ch) =>
[
ChannelType.GuildText,
ChannelType.GuildAnnouncement,
ChannelType.PublicThread,
ChannelType.PrivateThread,
ChannelType.AnnouncementThread
].includes(ch.type) &&
ch.permissionsFor(guild.roles.everyone).has("SendMessages") &&
ch.permissionsFor(guild.members.me!).has("EmbedLinks")
) as GuildTextBasedChannel | undefined) ?? null;
if (interaction) c = interaction.channel as GuildTextBasedChannel;
if (!c) {
return;
}
if (interaction) {
m = (await interaction.reply({
embeds: LoadingEmbed,
fetchReply: true,
ephemeral: true
})) as Message;
} else {
m = await c.send({ embeds: LoadingEmbed });
}
} else {
m = await c.send({ embeds: LoadingEmbed });
if (interaction) {
m = (await interaction.reply({
embeds: LoadingEmbed,
fetchReply: true,
ephemeral: true
})) as Message;
} else {
return;
}
}
let page = 0;
const pages = [

@ -226,7 +226,8 @@ class confirmationMessage {
try {
component = await m.awaitMessageComponent({
filter: (i) =>
i.user.id === this.interaction.user.id && i.channel!.id === this.interaction.channel!.id,
i.user.id === this.interaction.user.id &&
(i.channel ? i.channel!.id === this.interaction.channel!.id : true),
time: 300000
});
} catch (e) {

@ -192,7 +192,7 @@ interface TranscriptComponent {
interface TranscriptAuthor {
username: string;
discriminator: number;
discriminator: string | undefined;
nickname?: string;
id: string;
iconURL?: string;
@ -390,7 +390,7 @@ export class Transcript {
type: type,
for: {
username: member!.user.username,
discriminator: parseInt(member!.user.discriminator),
discriminator: member!.user.discriminator === "0" ? undefined : member!.user.discriminator,
id: member!.user.id,
topRole: {
color: member!.roles.highest.color
@ -404,7 +404,7 @@ export class Transcript {
createdTimestamp: Date.now(),
createdBy: {
username: interaction.user.username,
discriminator: parseInt(interaction.user.discriminator),
discriminator: interaction.user.discriminator === "0" ? undefined : interaction.user.discriminator,
id: interaction.user.id,
topRole: {
color: interactionMember?.roles.highest.color ?? 0x000000
@ -420,7 +420,7 @@ export class Transcript {
id: message.id,
author: {
username: message.author.username,
discriminator: parseInt(message.author.discriminator),
discriminator: message.author.discriminator === "0" ? undefined : message.author.discriminator,
id: message.author.id,
topRole: {
color: message.member ? message.member.roles.highest.color : 0x000000
@ -499,9 +499,7 @@ export class Transcript {
out += `> [Crosspost From] ${message.referencedMessage[0]} in ${message.referencedMessage[1]} in ${message.referencedMessage[2]}\n`;
} else out += `> [Reply To] ${message.referencedMessage}\n`;
}
out += `${message.author.nickname ?? message.author.username}#${message.author.discriminator} (${
message.author.id
}) (${message.id})`;
out += `${message.author.nickname ?? message.author.username} (${message.author.id}) (${message.id})`;
out += ` [${new Date(message.createdTimestamp).toISOString()}]`;
if (message.editedTimestamp) out += ` [Edited: ${new Date(message.editedTimestamp).toISOString()}]`;
out += "\n";

@ -54,7 +54,7 @@ function defaultInteractionFilter(i: MessageComponentInteraction, user: User, m:
return i.channel!.id === m.channel!.id && i.user.id === user.id;
}
function defaultModalFilter(i: ModalSubmitInteraction, user: User, m: Message) {
return i.channel!.id === m.channel!.id && i.user.id === user.id;
return (i.channel ? i.channel!.id === m.channel!.id : true) && i.user.id === user.id;
}
export async function modalInteractionCollector(

Loading…
Cancel
Save