diff --git a/src/commands/mod-ticket.ts b/src/commands/mod-ticket.ts index fb9c58b..9f82d29 100644 --- a/src/commands/mod-ticket.ts +++ b/src/commands/mod-ticket.ts @@ -1,4 +1,5 @@ -import { ApplicationIntegrationType, ChatInputCommandInteraction, Client, InteractionContextType, LabelBuilder, ModalBuilder, PermissionFlagsBits, SlashCommandBuilder, StringSelectMenuBuilder, StringSelectMenuOptionBuilder, TextInputBuilder, TextInputStyle } from 'discord.js'; +import { ApplicationIntegrationType, ChatInputCommandInteraction, Client, InteractionContextType, PermissionFlagsBits, SlashCommandBuilder } from 'discord.js'; +import { openModTicketModal } from '../utils'; export default { name: 'mod-ticket', @@ -22,53 +23,6 @@ export default { if (!member) return interaction.editReply('Could not find member.'); - const modal = new ModalBuilder() - .setCustomId(`open-mod-ticket_${user.id}`) - .setTitle(`Opening A Mod Ticket With ${member.displayName}`); - - const titleInput = new TextInputBuilder() - .setCustomId('title') - .setMaxLength(100) - .setStyle(TextInputStyle.Short) - .setRequired(false); - - const titleLabel = new LabelBuilder() - .setLabel('Title') - .setDescription(`The name of the thread. Defaults to "Mod Ticket For ${member.displayName}" if left empty`) - .setTextInputComponent(titleInput); - - const initialMessageInput = new TextInputBuilder() - .setCustomId('initial-message') - .setMaxLength(1800) - .setStyle(TextInputStyle.Paragraph) - .setRequired(false); - - const initialMessageLabel = new LabelBuilder() - .setLabel('Inital Message') - .setDescription('The inital message sent in the thread') - .setTextInputComponent(initialMessageInput); - - const yesNoMenu = new StringSelectMenuBuilder() - .setCustomId('auto-join-thread') - .setRequired(false) - .addOptions( - new StringSelectMenuOptionBuilder() - .setLabel('Yes') - .setDefault(true) - .setValue('yes'), - new StringSelectMenuOptionBuilder() - .setLabel('No') - .setDefault(false) - .setValue('no') - ); - - const autoJoinLabel = new LabelBuilder() - .setLabel('Auto Join Thread') - .setDescription('Whether or not to join you to the thread. Selecting no will not notify you of messages sent!') - .setStringSelectMenuComponent(yesNoMenu); - - modal.addLabelComponents(titleLabel, initialMessageLabel, autoJoinLabel); - - interaction.showModal(modal); + openModTicketModal(interaction, member); } }; \ No newline at end of file diff --git a/src/context-menus/open-mod-ticket.ts b/src/context-menus/open-mod-ticket.ts new file mode 100644 index 0000000..5a74054 --- /dev/null +++ b/src/context-menus/open-mod-ticket.ts @@ -0,0 +1,19 @@ +import { ApplicationIntegrationType, Client, InteractionContextType, PermissionFlagsBits, ContextMenuCommandBuilder, ApplicationCommandType, UserContextMenuCommandInteraction } from 'discord.js'; +import { openModTicketModal } from '../utils'; + +export default { + name: 'Open Mod Ticket', + data: new ContextMenuCommandBuilder() + .setName('Open Mod Ticket') + .setIntegrationTypes(ApplicationIntegrationType.GuildInstall) + .setContexts(InteractionContextType.Guild) + .setDefaultMemberPermissions(PermissionFlagsBits.KickMembers) + .setType(ApplicationCommandType.User), + handler: async function (client: Client, interaction: UserContextMenuCommandInteraction) { + const member = await interaction.guild?.members.fetch(interaction.targetUser.id); + + if (!member) return interaction.editReply('Could not find member.'); + + openModTicketModal(interaction, member); + } +}; \ No newline at end of file diff --git a/src/utils/private-help-utils.ts b/src/utils/private-help-utils.ts index 54b01e8..a41d148 100644 --- a/src/utils/private-help-utils.ts +++ b/src/utils/private-help-utils.ts @@ -1,4 +1,4 @@ -import { ActionRowBuilder, ButtonBuilder, ButtonStyle, ChannelType, Client, Guild, GuildMember, PrivateThreadChannel, TextChannel, ThreadAutoArchiveDuration, ThreadChannel } from 'discord.js'; +import { ActionRowBuilder, ButtonBuilder, ButtonStyle, ChannelType, ChatInputCommandInteraction, Client, Guild, GuildMember, LabelBuilder, ModalBuilder, PrivateThreadChannel, StringSelectMenuBuilder, StringSelectMenuOptionBuilder, TextChannel, TextInputBuilder, TextInputStyle, ThreadAutoArchiveDuration, ThreadChannel, UserContextMenuCommandInteraction } from 'discord.js'; import { Database } from '../shared/Database'; export async function closeOldTickets(client: Client) { @@ -82,4 +82,55 @@ export async function createPrivateHelpTicketThread(client: Client, guild: Guild } return thread; +} + +export async function openModTicketModal(interaction: UserContextMenuCommandInteraction | ChatInputCommandInteraction, member: GuildMember) { + const modal = new ModalBuilder() + .setCustomId(`open-mod-ticket_${member.id}`) + .setTitle(`Opening A Mod Ticket With ${member.displayName}`); + + const titleInput = new TextInputBuilder() + .setCustomId('title') + .setMaxLength(100) + .setStyle(TextInputStyle.Short) + .setRequired(false); + + const titleLabel = new LabelBuilder() + .setLabel('Title') + .setDescription(`The name of the thread. Defaults to "Mod Ticket For ${member.displayName}" if left empty`) + .setTextInputComponent(titleInput); + + const initialMessageInput = new TextInputBuilder() + .setCustomId('initial-message') + .setMaxLength(1800) + .setStyle(TextInputStyle.Paragraph) + .setRequired(false); + + const initialMessageLabel = new LabelBuilder() + .setLabel('Inital Message') + .setDescription('The inital message sent in the thread') + .setTextInputComponent(initialMessageInput); + + const yesNoMenu = new StringSelectMenuBuilder() + .setCustomId('auto-join-thread') + .setRequired(false) + .addOptions( + new StringSelectMenuOptionBuilder() + .setLabel('Yes') + .setDefault(true) + .setValue('yes'), + new StringSelectMenuOptionBuilder() + .setLabel('No') + .setDefault(false) + .setValue('no') + ); + + const autoJoinLabel = new LabelBuilder() + .setLabel('Auto Join Thread') + .setDescription('Whether or not to join you to the thread. Selecting no will not notify you of messages sent!') + .setStringSelectMenuComponent(yesNoMenu); + + modal.addLabelComponents(titleLabel, initialMessageLabel, autoJoinLabel); + + interaction.showModal(modal); } \ No newline at end of file