Development (#62)

- fixed /user tracks & /settings tracks. Added presets to /server
buttons
- prettiered
pull/67/head
PineappleFan 3 years ago committed by GitHub
commit b1dcfb8ac7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -20,6 +20,7 @@ import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
import lodash from "lodash";
import getEmojiByName from "../../utils/getEmojiByName.js";
import { modalInteractionCollector } from "../../utils/dualCollector.js";
import _ from "lodash";
export const command = new SlashCommandSubcommandBuilder()
.setName("buttons")
@ -50,6 +51,27 @@ const buttonNames: Record<string, string> = {
createticket: "Create Ticket"
};
const presetButtons = [
{
title: "Verify",
description: "Click the button below to get verified in the server.",
buttons: ["verifybutton"],
color: "GREEN"
},
{
title: "Get Roles",
description: "Click the button to choose which roles you would like in the server",
buttons: ["rolemenu"],
color: "BLUE"
},
{
title: "Create Ticket",
description: "Click the button below to create a ticket",
buttons: ["createticket"],
color: "RED"
}
];
export const callback = async (interaction: CommandInteraction): Promise<void> => {
const m = await interaction.reply({
embeds: LoadingEmbed,
@ -58,7 +80,7 @@ export const callback = async (interaction: CommandInteraction): Promise<void> =
});
let closed = false;
const data: Data = {
let data: Data = {
buttons: [],
title: null,
description: null,
@ -71,7 +93,7 @@ export const callback = async (interaction: CommandInteraction): Promise<void> =
.setCustomId("edit")
.setLabel("Edit Embed")
.setStyle(ButtonStyle.Secondary)
.setEmoji(getEmojiByName("ICONS.EDIT") as APIMessageComponentEmoji),
.setEmoji(getEmojiByName("ICONS.EDIT", "id") as APIMessageComponentEmoji),
new ButtonBuilder()
.setCustomId("send")
.setLabel("Send")
@ -95,6 +117,22 @@ export const callback = async (interaction: CommandInteraction): Promise<void> =
)
);
const presetSelect = new ActionRowBuilder<StringSelectMenuBuilder>().addComponents(
new StringSelectMenuBuilder()
.setCustomId("preset")
.setPlaceholder("Select a preset")
.setMaxValues(1)
.addOptions(
presetButtons.map((preset, i) => {
return new StringSelectMenuOptionBuilder()
.setLabel(preset.title)
.setValue(i.toString())
.setDescription(preset.description)
.setEmoji(getEmojiByName("COLORS." + preset.color, "id") as APIMessageComponentEmoji);
})
)
);
const buttonSelect = new ActionRowBuilder<StringSelectMenuBuilder>().addComponents(
new StringSelectMenuBuilder()
.setCustomId("button")
@ -141,7 +179,7 @@ export const callback = async (interaction: CommandInteraction): Promise<void> =
await interaction.editReply({
embeds: [embed],
components: [colorSelect, buttonSelect, channelMenu, buttons]
components: [presetSelect, colorSelect, buttonSelect, channelMenu, buttons]
});
let i: Discord.ButtonInteraction | Discord.ChannelSelectMenuInteraction | Discord.StringSelectMenuInteraction;
@ -257,6 +295,12 @@ export const callback = async (interaction: CommandInteraction): Promise<void> =
console.log(err);
}
switch (i.customId) {
case "preset": {
const chosen = presetButtons[parseInt(i.values[0]!)]!;
const newColor = colors[chosen.color!]!;
data = _.assign(data, chosen, { color: newColor });
break;
}
case "color": {
data.color = colors[i.values[0]!]!;
break;

@ -171,6 +171,7 @@ const editTrack = async (
const isAdmin = (interaction.member!.permissions as PermissionsBitField).has("Administrator");
if (!current) {
current = _.cloneDeep(defaultTrackData);
current.name = "Default";
}
const roleSelect = new ActionRowBuilder<RoleSelectMenuBuilder>().addComponents(
@ -348,16 +349,15 @@ const editTrack = async (
const callback = async (interaction: CommandInteraction) => {
const m = await interaction.reply({ embeds: LoadingEmbed, fetchReply: true, ephemeral: true });
const config = await client.database.guilds.read(interaction.guild!.id);
const tracks: ObjectSchema[] = config.tracks;
const tracks: ObjectSchema[] = _.cloneDeep(config.tracks);
const roles = await interaction.guild!.roles.fetch();
let page = 0;
let closed = false;
let modified = false;
do {
const embed = new EmojiEmbed().setTitle("Track Settings").setEmoji("TRACKS.ICON").setStatus("Success");
const noTracks = config.tracks.length === 0;
const noTracks = tracks.length === 0;
let current: ObjectSchema;
const pageSelect = new StringSelectMenuBuilder().setCustomId("page").setPlaceholder("Select a track to manage");
@ -398,7 +398,7 @@ const callback = async (interaction: CommandInteraction) => {
.setLabel("Save")
.setEmoji(getEmojiByName("ICONS.SAVE", "id") as APIMessageComponentEmoji)
.setStyle(ButtonStyle.Success)
.setDisabled(!modified)
.setDisabled(_.isEqual(tracks, config.tracks))
);
if (noTracks) {
embed.setDescription(
@ -471,13 +471,15 @@ const callback = async (interaction: CommandInteraction) => {
case "add": {
const newPage = await editTrack(i, m, roles);
if (_.isEqual(newPage, defaultTrackData)) break;
tracks.push();
if (!newPage) break;
console.log(newPage);
tracks.push(newPage);
console.log(tracks);
page = tracks.length - 1;
break;
}
case "save": {
await client.database.guilds.write(interaction.guild!.id, { tracks: tracks });
modified = false;
await client.memory.forceUpdate(interaction.guild!.id);
break;
}
@ -490,7 +492,6 @@ const callback = async (interaction: CommandInteraction) => {
const edited = await editTrack(i, m, roles, current!);
if (!edited) break;
tracks[page] = edited;
modified = true;
break;
}
case "delete": {

@ -97,7 +97,12 @@ const callback = async (interaction: CommandInteraction): Promise<unknown> => {
selected.length
} roles from this track. `;
conflictDropdown = [];
if (roles.get(selected[0]!)!.position < memberRoles.highest.position || managed) {
const yourRoles = guild.members.cache.get(interaction.user.id)!.roles;
if (
(roles.get(selected[0]!)!.position < yourRoles.highest.position &&
roles.get(selected[0]!)!.position < guild.members.me!.roles.highest.position!) ||
managed
) {
generated +=
"In order to promote or demote this user, you must select which role the member should keep.";
selected.forEach((role) => {
@ -115,8 +120,13 @@ const callback = async (interaction: CommandInteraction): Promise<unknown> => {
.setPlaceholder("Select a role to keep")
];
} else {
generated +=
"You don't have permission to manage one or more of the users roles, and therefore can't select one to keep.";
if (roles.get(selected[0]!)!.position >= yourRoles.highest.position) {
generated +=
"You don't have permission to manage one or more of the user's roles, and therefore can't select one to keep.";
} else {
generated +=
"I don't have permission to manage one or more of the user's roles, and therefore can't select one to keep.";
}
}
} else {
currentRoleIndex = selected.length === 0 ? -1 : data.track.indexOf(selected[0]!.toString());
@ -183,6 +193,7 @@ const callback = async (interaction: CommandInteraction): Promise<unknown> => {
const rolesToRemove = selected.filter(
(role) => role !== (component as StringSelectMenuInteraction).values[0]
);
await member.roles.remove(rolesToRemove);
} else if (component.customId === "promote") {
if (

@ -210,18 +210,14 @@ export async function TestImage(url: string): Promise<string | null> {
export async function doMemberChecks(member: Discord.GuildMember): Promise<void> {
if (member.user.bot) return;
console.log("Checking member " + member.user.tag);
const guild = member.guild;
const guildData = await client.database.guilds.read(guild.id);
if (!guildData.logging.staff.channel) return;
const [loose, strict] = [guildData.filters.wordFilter.words.loose, guildData.filters.wordFilter.words.strict];
console.log(1, loose, strict);
// Does the username contain filtered words
const usernameCheck = TestString(member.user.username, loose, strict, guildData.filters.wordFilter.enabled);
console.log(2, usernameCheck);
// Does the nickname contain filtered words
const nicknameCheck = TestString(member.nickname ?? "", loose, strict, guildData.filters.wordFilter.enabled);
console.log(3, nicknameCheck);
// Does the profile picture contain filtered words
const avatarTextCheck = TestString(
(await TestImage(member.displayAvatarURL({ forceStatic: true }))) ?? "",
@ -229,18 +225,14 @@ export async function doMemberChecks(member: Discord.GuildMember): Promise<void>
strict,
guildData.filters.wordFilter.enabled
);
console.log(4, avatarTextCheck);
// Is the profile picture NSFW
const avatar = member.displayAvatarURL({ extension: "png", size: 1024, forceStatic: true });
const avatarCheck = guildData.filters.images.NSFW && (await NSFWCheck(avatar));
console.log(5, avatarCheck);
// Does the username contain an invite
const inviteCheck = guildData.filters.invite.enabled && /discord\.gg\/[a-zA-Z0-9]+/gi.test(member.user.username);
console.log(6, inviteCheck);
// Does the nickname contain an invite
const nicknameInviteCheck =
guildData.filters.invite.enabled && /discord\.gg\/[a-zA-Z0-9]+/gi.test(member.nickname ?? "");
console.log(7, nicknameInviteCheck);
if (
usernameCheck !== null ||
nicknameCheck !== null ||
@ -282,39 +274,42 @@ export async function doMemberChecks(member: Discord.GuildMember): Promise<void>
`**Member:** ${member.user.username} (<@${member.user.id}>)\n\n` +
infractions.map((element) => `${filter} ${element}`).join("\n")
);
await channel.send({
embeds: [embed],
components: [
const buttons = [
new ButtonBuilder()
.setCustomId(`mod:warn:${member.user.id}`)
.setLabel("Warn")
.setStyle(ButtonStyle.Primary),
new ButtonBuilder()
.setCustomId(`mod:mute:${member.user.id}`)
.setLabel("Mute")
.setStyle(ButtonStyle.Primary),
new ButtonBuilder().setCustomId(`mod:kick:${member.user.id}`).setLabel("Kick").setStyle(ButtonStyle.Danger),
new ButtonBuilder().setCustomId(`mod:ban:${member.user.id}`).setLabel("Ban").setStyle(ButtonStyle.Danger)
];
if (usernameCheck !== null || nicknameCheck !== null)
buttons.concat([
new ButtonBuilder()
.setCustomId(`mod:nickname:${member.user.id}`)
.setLabel("Change Name")
.setStyle(ButtonStyle.Primary)
]);
if (avatarCheck || avatarTextCheck !== null)
buttons.concat([
new ButtonBuilder().setURL(member.displayAvatarURL()).setLabel("View Avatar").setStyle(ButtonStyle.Link)
]);
const components: ActionRowBuilder<ButtonBuilder>[] = [];
for (let i = 0; i < buttons.length; i += 5) {
components.push(
new ActionRowBuilder<ButtonBuilder>().addComponents(
...[
new ButtonBuilder()
.setCustomId(`mod:warn:${member.user.id}`)
.setLabel("Warn")
.setStyle(ButtonStyle.Primary),
new ButtonBuilder()
.setCustomId(`mod:mute:${member.user.id}`)
.setLabel("Mute")
.setStyle(ButtonStyle.Primary),
new ButtonBuilder()
.setCustomId(`mod:kick:${member.user.id}`)
.setLabel("Kick")
.setStyle(ButtonStyle.Danger),
new ButtonBuilder()
.setCustomId(`mod:ban:${member.user.id}`)
.setLabel("Ban")
.setStyle(ButtonStyle.Danger)
].concat(
usernameCheck !== null || nicknameCheck !== null
? [
new ButtonBuilder()
.setCustomId(`mod:nickname:${member.user.id}`)
.setLabel("Change Name")
.setStyle(ButtonStyle.Primary)
]
: []
)
buttons.slice(i, Math.min(buttons.length - 1, i + 5))
)
]
);
}
await channel.send({
embeds: [embed],
components: components
});
}
}

@ -1,7 +1,6 @@
import emojis from "../config/emojis.json" assert { type: "json" };
import lodash from "lodash";
import _ from "lodash";
const isArray = lodash.isArray;
interface EmojisIndex {
[key: string]: string | EmojisIndex | EmojisIndex[];
}
@ -14,7 +13,7 @@ function getEmojiByName(name: string | null, format?: string): string {
if (typeof id === "string" || id === undefined) {
throw new Error(`Emoji ${name} not found`);
}
if (isArray(id)) {
if (_.isArray(id)) {
id = id[parseInt(part)];
} else {
id = id[part];
@ -34,9 +33,9 @@ function getEmojiFromId(id: string | undefined, format?: string): string {
if (id === undefined) {
return "";
} else if (id.toString().startsWith("a")) {
return `<a:_:${id.toString().slice(1, id.toString().length)}>`;
return `<a:N:${id.toString().slice(1, id.toString().length)}>`;
}
return `<:_:${id}>`;
return `<:N:${id}>`;
}
export default getEmojiByName;

Loading…
Cancel
Save