start working on "/roles show"

This commit is contained in:
SadlyNotSappho 2023-02-28 15:14:38 -08:00
parent b5170b9c65
commit 6239e20f92
4 changed files with 147 additions and 77 deletions

View File

@ -1,21 +1,37 @@
import { ModalActionRowComponentBuilder, ModalBuilder } from '@discordjs/builders'; import { ModalActionRowComponentBuilder, ModalBuilder } from '@discordjs/builders';
import { ApplyOptions } from '@sapphire/decorators'; import { ApplyOptions } from '@sapphire/decorators';
import { Command } from '@sapphire/framework'; import { Command } from '@sapphire/framework';
import { ActionRowBuilder, TextInputBuilder, TextInputStyle } from 'discord.js'; import { ActionRowBuilder, ButtonStyle, ComponentType, TextInputBuilder, TextInputStyle } from 'discord.js';
import { RolesMessage } from '../lib/types';
@ApplyOptions<Command.Options>({ @ApplyOptions<Command.Options>({
description: 'Lets you configure a role message' description: 'Lets you configure a role message'
}) })
export class UserCommand extends Command { export class UserCommand extends Command {
public override registerApplicationCommands(registry: Command.Registry) { public override registerApplicationCommands(registry: Command.Registry) {
registry.registerChatInputCommand((builder) => registry.registerChatInputCommand(
builder // (builder) =>
.setName(this.name) builder //
.setDescription(this.description) .setName(this.name)
.addSubcommand(builder => builder.setName('new').setDescription('Creates a new role message')) .setDescription(this.description)
.addSubcommand(builder => builder.setName('edit').setDescription('Edit an existing role message')) .addSubcommand((builder) => builder.setName('new').setDescription('Creates a new role message'))
.addSubcommand(builder => builder.setName('show').setDescription('Re-send an existing role message')) .addSubcommand((builder) =>
, builder
.setName('edit')
.setDescription('Edit an existing role message')
.addStringOption((b) =>
b.setName('id').setDescription('The ID of the menu to edit. See all with /roles list').setRequired(true)
)
)
.addSubcommand((builder) =>
builder
.setName('show')
.setDescription('Re-send an existing role message')
.addStringOption((b) =>
b.setName('id').setDescription('The ID of the menu to edit. See all with /roles list').setRequired(true)
)
)
.addSubcommand((builder) => builder.setName('list').setDescription('Lists all available role menus.')),
{ {
guildIds: ['1030563119132594187'], guildIds: ['1030563119132594187'],
idHints: ['1074474624672350279'] idHints: ['1074474624672350279']
@ -27,45 +43,90 @@ export class UserCommand extends Command {
let subcommand = interaction.options.getSubcommand(true); let subcommand = interaction.options.getSubcommand(true);
switch (subcommand) { switch (subcommand) {
case 'new': await this.new(interaction); break; case 'new':
case 'edit': await this.edit(interaction); break; await this.new(interaction);
case 'show': await this.show(interaction); break; break;
case 'edit':
await this.edit(interaction);
break;
case 'show':
await this.show(interaction);
break;
case 'list':
await this.list(interaction);
break;
} }
} }
private async new(interaction: Command.ChatInputCommandInteraction) { private async new(interaction: Command.ChatInputCommandInteraction) {
const modal = new ModalBuilder() const modal = new ModalBuilder().setCustomId('newEmbedEditorModal').setTitle('Embed Editor');
.setCustomId('newEmbedEditorModal')
.setTitle('Embed Editor')
const embedTitle = new TextInputBuilder() const embedTitle = new TextInputBuilder().setCustomId('embedTitle').setLabel('Title').setStyle(TextInputStyle.Short);
.setCustomId('embedTitle') const embedDescription = new TextInputBuilder().setCustomId('embedDescription').setLabel('Description').setStyle(TextInputStyle.Paragraph);
.setLabel('Title')
.setStyle(TextInputStyle.Short);
const embedDescription = new TextInputBuilder()
.setCustomId('embedDescription')
.setLabel('Description')
.setStyle(TextInputStyle.Paragraph)
const embedColor = new TextInputBuilder() const embedColor = new TextInputBuilder()
.setCustomId('embedColor') .setCustomId('embedColor')
.setLabel('Color') .setLabel('Color')
.setPlaceholder('RGB color for the embed (e.g #FF0000)') .setPlaceholder('RGB color for the embed (e.g #FF0000)')
.setStyle(TextInputStyle.Short);
const buttonLabel = new TextInputBuilder()
.setCustomId('buttonLabel')
.setLabel('Button Label')
.setPlaceholder('The text to display on the "show roles" button')
.setStyle(TextInputStyle.Short) .setStyle(TextInputStyle.Short)
.setMaxLength(80);
let firstRow = new ActionRowBuilder<ModalActionRowComponentBuilder>().addComponents(embedTitle) let firstRow = new ActionRowBuilder<ModalActionRowComponentBuilder>().addComponents(embedTitle);
let secondRow = new ActionRowBuilder<ModalActionRowComponentBuilder>().addComponents(embedDescription) let secondRow = new ActionRowBuilder<ModalActionRowComponentBuilder>().addComponents(embedDescription);
let thirdRow = new ActionRowBuilder<ModalActionRowComponentBuilder>().addComponents(embedColor) let thirdRow = new ActionRowBuilder<ModalActionRowComponentBuilder>().addComponents(embedColor);
let fourthRow = new ActionRowBuilder<ModalActionRowComponentBuilder>().addComponents(buttonLabel);
modal.addComponents(firstRow, secondRow, thirdRow) modal.addComponents(firstRow, secondRow, thirdRow, fourthRow);
await interaction.showModal(modal) await interaction.showModal(modal);
}
private async edit(interaction: Command.ChatInputCommandInteraction) {
await interaction.reply({content: 'edit', ephemeral: true})
} }
private async show(interaction: Command.ChatInputCommandInteraction) { private async show(interaction: Command.ChatInputCommandInteraction) {
await interaction.reply({content: 'show', ephemeral: true}) let menuData = await RolesMessage.findByPk(Number(interaction.options.getString('id')));
if (!menuData) {
return await interaction.reply({ content: 'No role menu exists with that ID.', ephemeral: true });
}
if (menuData.dataValues.guildId != interaction.guild?.id) {
return await interaction.reply({ content: 'No role menu exists with that ID.', ephemeral: true });
}
let color = menuData.dataValues.embedColor ?? '0x36393E';
let regex = /[0-9A-F]{6}/gi;
let matches = color.match(regex);
if (matches == null) color = '0x36393E';
else color = `0x${matches[0]}`;
await interaction.reply({ content: 'Ok.', ephemeral: true });
await interaction.channel?.send({
embeds: [{ title: menuData.dataValues.embedTitle ?? 'Generic Title', description: menuData.dataValues.embedDescription ?? 'Generic Description', color: Number(color) }],
components: [
{
type: ComponentType.ActionRow,
components: [
{
type: ComponentType.Button,
label: menuData.dataValues.buttonLabel ?? 'Select Roles',
customId: `showRoleSelector-${interaction.options.getString('id')}`,
style: ButtonStyle.Primary
}
]
}
]
});
return;
} }
}
private async edit(interaction: Command.ChatInputCommandInteraction) {
await interaction.reply({ content: 'edit', ephemeral: true });
}
private async list(interaction: Command.ChatInputCommandInteraction) {
await interaction.reply({ content: 'list', ephemeral: true });
}
}

View File

@ -1,5 +1,5 @@
import { container, LogLevel, SapphireClient } from '@sapphire/framework'; import { container, LogLevel, SapphireClient } from '@sapphire/framework';
import { GatewayIntentBits, Partials } from 'discord.js'; import { GatewayIntentBits, Partials, Role } from 'discord.js';
import { Model, Sequelize } from 'sequelize'; import { Model, Sequelize } from 'sequelize';
export class SaplingClient extends SapphireClient { export class SaplingClient extends SapphireClient {
@ -61,3 +61,8 @@ declare module '@sapphire/pieces' {
} }
export class RolesMessage extends Model {} export class RolesMessage extends Model {}
export type RolesChecker = {
role: Role,
has: boolean
}

View File

@ -1,6 +1,7 @@
import { ApplyOptions } from '@sapphire/decorators'; import { ApplyOptions } from '@sapphire/decorators';
import { Listener, ListenerOptions } from '@sapphire/framework'; import { Listener, ListenerOptions } from '@sapphire/framework';
import { ButtonStyle, ComponentType, Interaction, InteractionType, MessageComponentInteraction } from 'discord.js'; import { ComponentType, GuildMember, Interaction, InteractionType } from 'discord.js';
import { RolesChecker, RolesMessage } from '../lib/types';
@ApplyOptions<ListenerOptions>({ @ApplyOptions<ListenerOptions>({
event: 'interactionCreate' event: 'interactionCreate'
@ -11,47 +12,50 @@ export class UserEvent extends Listener {
switch (interaction.componentType) { switch (interaction.componentType) {
case ComponentType.Button: { case ComponentType.Button: {
if (interaction.customId == 'showRolesButton') await this.showRolesButton(interaction); if (interaction.customId.startsWith('showRoleSelector-')) {
let id = interaction.customId.split('-')[1];
let data = await RolesMessage.findByPk(id);
if (!data) {
return await interaction.reply({ content: 'Someone messed up big time.', ephemeral: true });
}
let roleIds = data.dataValues.roles;
let roles = [];
for (const id of roleIds) {
let r = await interaction.guild?.roles.fetch(id);
if (r) {
roles.push(r);
}
}
let userRoles = (interaction.member as GuildMember).roles.cache;
let newRoles: RolesChecker[] = [];
for (const role of roles) {
if (userRoles.has(role.id)) {
newRoles.push({ role, has: true });
} else {
newRoles.push({ role, has: false });
}
}
console.log(roles);
console.log(userRoles);
console.log(newRoles);
if (data.dataValues.style == 'buttons') {
let size = 5;
let arrayOfArrays = [];
for (let i = 0; i < newRoles.length; i += size) {
arrayOfArrays.push(newRoles.slice(i, i + size));
}
// arrays with all the buttons and if the user has them are now in arrayOfArrays, figure out how to get that in a message later:tm:
}
return;
}
} }
} }
} return;
private async showRolesButton(interaction: MessageComponentInteraction) {
interaction.reply({
content: 'This button lets you select pronoun roles. You can select multiple.',
allowedMentions: { parse: [] },
ephemeral: true,
components: [
{
type: ComponentType.ActionRow,
components: [
{
type: ComponentType.Button,
style: ButtonStyle.Danger,
label: 'she/her',
customId: 'giveRole.<roleId>'
},
{
type: ComponentType.Button,
style: ButtonStyle.Success,
label: 'he/him',
customId: 'giveRole.<roleId>1'
},
{
type: ComponentType.Button,
style: ButtonStyle.Success,
label: 'they/them',
customId: 'giveRole.<roleId>2'
},
{
type: ComponentType.Button,
style: ButtonStyle.Success,
label: 'ask',
customId: 'giveRole.<roleId>3'
},
]
}
]
});
} }
} }

View File

@ -10,12 +10,12 @@ export class UserEvent extends Listener {
if (interaction.customId != 'newEmbedEditorModal') return; if (interaction.customId != 'newEmbedEditorModal') return;
await interaction.reply({ content: 'modal recieved', ephemeral: true }); await interaction.reply({ content: 'modal recieved', ephemeral: true });
let regex = /[0-9A-F]{6}/gi;
let title = interaction.fields.fields.get('embedTitle')?.value; let title = interaction.fields.fields.get('embedTitle')?.value;
let description = interaction.fields.fields.get('embedDescription')?.value; let description = interaction.fields.fields.get('embedDescription')?.value;
let color: string = interaction.fields.fields.get('embedColor')?.value as string; let color: string = interaction.fields.fields.get('embedColor')?.value as string;
let regex = /[0-9A-F]{6}/gi;
let matches = color.match(regex); let matches = color.match(regex);
if (matches == null) color = '0x36393E'; if (matches == null) color = '0x36393E';
else color = `0x${matches[0]}`; else color = `0x${matches[0]}`;