jillo-bot/src/commands/color.ts

134 lines
4.2 KiB
TypeScript
Raw Normal View History

2023-11-16 11:33:11 +01:00
import { RoleCreateOptions, GuildMember, CommandInteraction, EmbedBuilder, TextChannel, ActionRowBuilder, ButtonBuilder, ButtonStyle, SlashCommandBuilder } from 'discord.js';
2022-07-16 21:24:13 +02:00
import { default as parseColor, Color } from 'parse-color';
import { getRoleSeperator, isColorRole } from '../lib/assignableRoles';
2023-11-11 01:54:11 +01:00
import * as log from '../lib/log';
2023-11-16 11:33:11 +01:00
import { Command } from '../types/index';
2022-07-16 17:33:30 +02:00
2022-07-16 21:24:13 +02:00
const PREVIEW_DURATION = 1000 * 60;
2022-07-16 17:33:30 +02:00
function removeAllColorRoles(member: GuildMember) {
return Promise.all(member.roles.cache.map(role => {
if (isColorRole(role.name)) {
return member.roles.remove(role);
}
}));
}
2022-07-16 21:24:13 +02:00
async function applyColor(member: GuildMember, color: Color) {
await removeAllColorRoles(member);
const seperator = await getRoleSeperator('color', member.guild);
if (!seperator) log.info('no color role seperator found');
2022-07-16 21:24:13 +02:00
const roleSettings: RoleCreateOptions = {
2022-07-16 21:24:13 +02:00
name: color.hex,
color: color.rgb,
hoist: false,
mentionable: false,
permissions: 0n,
};
if (seperator) {
roleSettings.position = seperator.position;
2022-07-16 21:24:13 +02:00
}
const role = member.guild.roles.cache.find(role => role.name === color.hex) || await member.guild.roles.create(roleSettings);
await member.roles.add(role);
2022-07-16 17:33:30 +02:00
}
2023-11-16 11:33:11 +01:00
export default {
2022-07-16 17:33:30 +02:00
data: new SlashCommandBuilder()
.setName('color')
.setDescription('Change your role color.')
2022-07-16 21:24:13 +02:00
.addStringOption((option) =>
option.setName('color')
.setDescription('Color to set. Must be a parsable HTML color. Examples include: #ff0000, rgb(50, 0, 0), red, etc.')
)
.addBooleanOption((option) =>
option.setName('preview').setDescription('Preview the color instead of applying it')
2023-11-27 13:12:37 +01:00
)
.setDefaultMemberPermissions(0)
.setDMPermission(false),
2023-11-16 11:33:11 +01:00
execute: async (interaction: CommandInteraction) => {
if (!interaction.isChatInputCommand()) return;
2023-11-16 11:33:11 +01:00
const member = interaction.member! as GuildMember;
2022-07-16 17:33:30 +02:00
const color = interaction.options.getString('color');
2022-07-16 21:24:13 +02:00
const preview = interaction.options.getBoolean('preview');
2022-07-16 17:33:30 +02:00
if (color) {
2022-07-16 21:24:13 +02:00
const parsed = parseColor(color.trim());
2022-07-16 17:33:30 +02:00
if (!parsed.hex) {
interaction.reply({
content: 'Invalid color. Try an HTML color like `#ff0000`, `rgb(50, 0, 0)`, `red`, etc.',
2022-07-16 21:24:13 +02:00
ephemeral: true
2022-07-16 17:33:30 +02:00
});
return;
}
2022-07-16 21:24:13 +02:00
if (preview) {
const embed = new EmbedBuilder();
2022-07-16 21:24:13 +02:00
embed.setImage(`https://dummyimage.com/200x200/${parsed.hex.slice(1)}/${parsed.hex.slice(1)}.png`);
embed.setTitle(`Previewing ${parsed.hex}`);
const apply = new ButtonBuilder()
.setLabel('Apply')
.setStyle(ButtonStyle.Primary)
.setCustomId(`apply-color-${parsed.hex}`);
const row = new ActionRowBuilder<ButtonBuilder>()
.addComponents(apply);
2022-07-16 21:24:13 +02:00
const message = await interaction.reply({
2022-07-16 21:24:13 +02:00
embeds: [embed],
components: [row],
fetchReply: true
});
2022-07-16 21:24:13 +02:00
const collector = (interaction.channel as TextChannel).createMessageComponentCollector({
filter: (i) => i.message.id === message.id,
time: PREVIEW_DURATION,
});
collector.on('collect', async (i) => {
if (i.customId !== `apply-color-${parsed.hex}`) return;
if (i.member === member) {
collector.stop();
await i.deferReply({ephemeral: false});
row.components[0].setDisabled(true);
await message.edit({
embeds: [embed],
components: [row]
});
await applyColor(member, parsed);
await i.followUp({
content: 'Color applied.'
});
} else {
i.reply({
content: 'You didn\'t run the command!',
ephemeral: true
});
}
});
} else {
await interaction.deferReply({
ephemeral: true
});
await applyColor(member, parsed);
interaction.followUp({
content: 'Your color has been set.'
});
}
2022-07-16 17:33:30 +02:00
} else {
await removeAllColorRoles(member);
interaction.reply({
content: 'Removed all colors.',
ephemeral: true
});
}
}
2023-11-16 11:33:11 +01:00
} satisfies Command;