start working on "/roles show"
This commit is contained in:
parent
b5170b9c65
commit
6239e20f92
|
@ -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 //
|
builder //
|
||||||
.setName(this.name)
|
.setName(this.name)
|
||||||
.setDescription(this.description)
|
.setDescription(this.description)
|
||||||
.addSubcommand(builder => builder.setName('new').setDescription('Creates a new role message'))
|
.addSubcommand((builder) => builder.setName('new').setDescription('Creates a new role message'))
|
||||||
.addSubcommand(builder => builder.setName('edit').setDescription('Edit an existing role message'))
|
.addSubcommand((builder) =>
|
||||||
.addSubcommand(builder => builder.setName('show').setDescription('Re-send an existing role message'))
|
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 });
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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
|
||||||
|
}
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async showRolesButton(interaction: MessageComponentInteraction) {
|
let userRoles = (interaction.member as GuildMember).roles.cache;
|
||||||
interaction.reply({
|
|
||||||
content: 'This button lets you select pronoun roles. You can select multiple.',
|
let newRoles: RolesChecker[] = [];
|
||||||
allowedMentions: { parse: [] },
|
for (const role of roles) {
|
||||||
ephemeral: true,
|
if (userRoles.has(role.id)) {
|
||||||
components: [
|
newRoles.push({ role, has: true });
|
||||||
{
|
} else {
|
||||||
type: ComponentType.ActionRow,
|
newRoles.push({ role, has: false });
|
||||||
components: [
|
}
|
||||||
{
|
}
|
||||||
type: ComponentType.Button,
|
|
||||||
style: ButtonStyle.Danger,
|
console.log(roles);
|
||||||
label: 'she/her',
|
console.log(userRoles);
|
||||||
customId: 'giveRole.<roleId>'
|
console.log(newRoles);
|
||||||
},
|
|
||||||
{
|
if (data.dataValues.style == 'buttons') {
|
||||||
type: ComponentType.Button,
|
let size = 5;
|
||||||
style: ButtonStyle.Success,
|
let arrayOfArrays = [];
|
||||||
label: 'he/him',
|
for (let i = 0; i < newRoles.length; i += size) {
|
||||||
customId: 'giveRole.<roleId>1'
|
arrayOfArrays.push(newRoles.slice(i, i + size));
|
||||||
},
|
}
|
||||||
{
|
|
||||||
type: ComponentType.Button,
|
// 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:
|
||||||
style: ButtonStyle.Success,
|
}
|
||||||
label: 'they/them',
|
|
||||||
customId: 'giveRole.<roleId>2'
|
return;
|
||||||
},
|
}
|
||||||
{
|
}
|
||||||
type: ComponentType.Button,
|
}
|
||||||
style: ButtonStyle.Success,
|
return;
|
||||||
label: 'ask',
|
|
||||||
customId: 'giveRole.<roleId>3'
|
|
||||||
},
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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]}`;
|
||||||
|
|
Loading…
Reference in New Issue