diff --git a/backend/src/plugins/ContextMenus/actions/ban.ts b/backend/src/plugins/ContextMenus/actions/ban.ts index bfc756d2..5227c793 100644 --- a/backend/src/plugins/ContextMenus/actions/ban.ts +++ b/backend/src/plugins/ContextMenus/actions/ban.ts @@ -11,10 +11,11 @@ import humanizeDuration from "humanize-duration"; import { GuildPluginData } from "knub"; import { canActOn } from "src/pluginUtils"; import { ModActionsPlugin } from "src/plugins/ModActions/ModActionsPlugin"; +import { logger } from "../../../logger"; import { convertDelayStringToMS, renderUserUsername } from "../../../utils"; import { CaseArgs } from "../../Cases/types"; import { MODAL_TIMEOUT } from "../commands/ModMenuUserCtxCmd"; -import { ContextMenuPluginType } from "../types"; +import { ContextMenuPluginType, ModMenuActionType } from "../types"; async function banAction( pluginData: GuildPluginData, @@ -24,7 +25,7 @@ async function banAction( interaction: ButtonInteraction | ContextMenuCommandInteraction, submitInteraction: ModalSubmitInteraction, ) { - const interactionToReply = interaction instanceof ButtonInteraction ? interaction : submitInteraction; + const interactionToReply = interaction.isButton() ? interaction : submitInteraction; const executingMember = await pluginData.guild.members.fetch(interaction.user.id); const userCfg = await pluginData.config.getMatchingConfig({ channelId: interaction.channelId, @@ -68,7 +69,8 @@ export async function launchBanActionModal( interaction: ButtonInteraction | ContextMenuCommandInteraction, target: string, ) { - const modal = new ModalBuilder().setCustomId("ban").setTitle("Ban"); + const modalId = `${ModMenuActionType.WARN}:${interaction.id}`; + const modal = new ModalBuilder().setCustomId(modalId).setTitle("Ban"); const durationIn = new TextInputBuilder() .setCustomId("duration") .setLabel("Duration (Optional)") @@ -84,17 +86,19 @@ export async function launchBanActionModal( modal.addComponents(durationRow, reasonRow); await interaction.showModal(modal); - const submitted: ModalSubmitInteraction = await interaction.awaitModalSubmit({ time: MODAL_TIMEOUT }); - if (submitted) { - if (interaction instanceof ButtonInteraction) { - await submitted.deferUpdate(); - } else { - await submitted.deferReply({ ephemeral: true }); - } + await interaction + .awaitModalSubmit({ time: MODAL_TIMEOUT, filter: (i) => i.customId == modalId }) + .then(async (submitted) => { + if (interaction.isButton()) { + await submitted.deferUpdate(); + } else if (interaction.isContextMenuCommand()) { + await submitted.deferReply({ ephemeral: true }); + } - const duration = submitted.fields.getTextInputValue("duration"); - const reason = submitted.fields.getTextInputValue("reason"); + const duration = submitted.fields.getTextInputValue("duration"); + const reason = submitted.fields.getTextInputValue("reason"); - await banAction(pluginData, duration, reason, target, interaction, submitted); - } + await banAction(pluginData, duration, reason, target, interaction, submitted); + }) + .catch((err) => logger.error(`Ban modal interaction failed: ${err}`)); } diff --git a/backend/src/plugins/ContextMenus/actions/clean.ts b/backend/src/plugins/ContextMenus/actions/clean.ts index 34ae2d14..13795f04 100644 --- a/backend/src/plugins/ContextMenus/actions/clean.ts +++ b/backend/src/plugins/ContextMenus/actions/clean.ts @@ -1,15 +1,9 @@ -import { - ActionRowBuilder, - ButtonInteraction, - ModalBuilder, - ModalSubmitInteraction, - TextInputBuilder, - TextInputStyle, -} from "discord.js"; +import { ActionRowBuilder, ButtonInteraction, ModalBuilder, TextInputBuilder, TextInputStyle } from "discord.js"; import { GuildPluginData } from "knub"; +import { logger } from "../../../logger"; import { UtilityPlugin } from "../../../plugins/Utility/UtilityPlugin"; import { MODAL_TIMEOUT } from "../commands/ModMenuUserCtxCmd"; -import { ContextMenuPluginType } from "../types"; +import { ContextMenuPluginType, ModMenuActionType } from "../types"; export async function cleanAction( pluginData: GuildPluginData, @@ -42,22 +36,25 @@ export async function launchCleanActionModal( interaction: ButtonInteraction, target: string, ) { - const modal = new ModalBuilder().setCustomId("clean").setTitle("Clean"); + const modalId = `${ModMenuActionType.CLEAN}:${interaction.id}`; + const modal = new ModalBuilder().setCustomId(modalId).setTitle("Clean"); const amountIn = new TextInputBuilder().setCustomId("amount").setLabel("Amount").setStyle(TextInputStyle.Short); const amountRow = new ActionRowBuilder().addComponents(amountIn); modal.addComponents(amountRow); await interaction.showModal(modal); - const submitted: ModalSubmitInteraction = await interaction.awaitModalSubmit({ time: MODAL_TIMEOUT }); - if (submitted) { - await submitted.deferUpdate(); + await interaction + .awaitModalSubmit({ time: MODAL_TIMEOUT, filter: (i) => i.customId == modalId }) + .then(async (submitted) => { + await submitted.deferUpdate(); - const amount = submitted.fields.getTextInputValue("amount"); - if (isNaN(Number(amount))) { - interaction.editReply({ content: `Error: Amount '${amount}' is invalid`, embeds: [], components: [] }); - return; - } + const amount = submitted.fields.getTextInputValue("amount"); + if (isNaN(Number(amount))) { + interaction.editReply({ content: `Error: Amount '${amount}' is invalid`, embeds: [], components: [] }); + return; + } - await cleanAction(pluginData, Number(amount), target, interaction); - } + await cleanAction(pluginData, Number(amount), target, interaction); + }) + .catch((err) => logger.error(`Clean modal interaction failed: ${err}`)); } diff --git a/backend/src/plugins/ContextMenus/actions/mute.ts b/backend/src/plugins/ContextMenus/actions/mute.ts index 28a988c8..ad98d544 100644 --- a/backend/src/plugins/ContextMenus/actions/mute.ts +++ b/backend/src/plugins/ContextMenus/actions/mute.ts @@ -12,12 +12,13 @@ import { GuildPluginData } from "knub"; import { canActOn } from "src/pluginUtils"; import { ModActionsPlugin } from "src/plugins/ModActions/ModActionsPlugin"; import { ERRORS, RecoverablePluginError } from "../../../RecoverablePluginError"; +import { logger } from "../../../logger"; import { convertDelayStringToMS } from "../../../utils"; import { CaseArgs } from "../../Cases/types"; import { LogsPlugin } from "../../Logs/LogsPlugin"; import { MutesPlugin } from "../../Mutes/MutesPlugin"; import { MODAL_TIMEOUT } from "../commands/ModMenuUserCtxCmd"; -import { ContextMenuPluginType } from "../types"; +import { ContextMenuPluginType, ModMenuActionType } from "../types"; async function muteAction( pluginData: GuildPluginData, @@ -27,7 +28,7 @@ async function muteAction( interaction: ButtonInteraction | ContextMenuCommandInteraction, submitInteraction: ModalSubmitInteraction, ) { - const interactionToReply = interaction instanceof ButtonInteraction ? interaction : submitInteraction; + const interactionToReply = interaction.isButton() ? interaction : submitInteraction; const executingMember = await pluginData.guild.members.fetch(interaction.user.id); const userCfg = await pluginData.config.getMatchingConfig({ channelId: interaction.channelId, @@ -91,7 +92,8 @@ export async function launchMuteActionModal( interaction: ButtonInteraction | ContextMenuCommandInteraction, target: string, ) { - const modal = new ModalBuilder().setCustomId("mute").setTitle("Mute"); + const modalId = `${ModMenuActionType.MUTE}:${interaction.id}`; + const modal = new ModalBuilder().setCustomId(modalId).setTitle("Mute"); const durationIn = new TextInputBuilder() .setCustomId("duration") .setLabel("Duration (Optional)") @@ -107,17 +109,19 @@ export async function launchMuteActionModal( modal.addComponents(durationRow, reasonRow); await interaction.showModal(modal); - const submitted: ModalSubmitInteraction = await interaction.awaitModalSubmit({ time: MODAL_TIMEOUT }); - if (submitted) { - if (interaction instanceof ButtonInteraction) { - await submitted.deferUpdate(); - } else { - await submitted.deferReply({ ephemeral: true }); - } + await interaction + .awaitModalSubmit({ time: MODAL_TIMEOUT, filter: (i) => i.customId == modalId }) + .then(async (submitted) => { + if (interaction.isButton()) { + await submitted.deferUpdate(); + } else if (interaction.isContextMenuCommand()) { + await submitted.deferReply({ ephemeral: true }); + } - const duration = submitted.fields.getTextInputValue("duration"); - const reason = submitted.fields.getTextInputValue("reason"); + const duration = submitted.fields.getTextInputValue("duration"); + const reason = submitted.fields.getTextInputValue("reason"); - await muteAction(pluginData, duration, reason, target, interaction, submitted); - } + await muteAction(pluginData, duration, reason, target, interaction, submitted); + }) + .catch((err) => logger.error(`Mute modal interaction failed: ${err}`)); } diff --git a/backend/src/plugins/ContextMenus/actions/note.ts b/backend/src/plugins/ContextMenus/actions/note.ts index 51a018ca..ecc48d6e 100644 --- a/backend/src/plugins/ContextMenus/actions/note.ts +++ b/backend/src/plugins/ContextMenus/actions/note.ts @@ -11,11 +11,12 @@ import { GuildPluginData } from "knub"; import { canActOn } from "src/pluginUtils"; import { ModActionsPlugin } from "src/plugins/ModActions/ModActionsPlugin"; import { CaseTypes } from "../../../data/CaseTypes"; +import { logger } from "../../../logger"; import { CasesPlugin } from "../../../plugins/Cases/CasesPlugin"; import { renderUserUsername } from "../../../utils"; import { LogsPlugin } from "../../Logs/LogsPlugin"; import { MODAL_TIMEOUT } from "../commands/ModMenuUserCtxCmd"; -import { ContextMenuPluginType } from "../types"; +import { ContextMenuPluginType, ModMenuActionType } from "../types"; async function noteAction( pluginData: GuildPluginData, @@ -24,7 +25,7 @@ async function noteAction( interaction: ButtonInteraction | ContextMenuCommandInteraction, submitInteraction: ModalSubmitInteraction, ) { - const interactionToReply = interaction instanceof ButtonInteraction ? interaction : submitInteraction; + const interactionToReply = interaction.isButton() ? interaction : submitInteraction; const executingMember = await pluginData.guild.members.fetch(interaction.user.id); const userCfg = await pluginData.config.getMatchingConfig({ channelId: interaction.channelId, @@ -79,22 +80,25 @@ export async function launchNoteActionModal( interaction: ButtonInteraction | ContextMenuCommandInteraction, target: string, ) { - const modal = new ModalBuilder().setCustomId("note").setTitle("Note"); + const modalId = `${ModMenuActionType.NOTE}:${interaction.id}`; + const modal = new ModalBuilder().setCustomId(modalId).setTitle("Note"); const reasonIn = new TextInputBuilder().setCustomId("reason").setLabel("Note").setStyle(TextInputStyle.Paragraph); const reasonRow = new ActionRowBuilder().addComponents(reasonIn); modal.addComponents(reasonRow); await interaction.showModal(modal); - const submitted: ModalSubmitInteraction = await interaction.awaitModalSubmit({ time: MODAL_TIMEOUT }); - if (submitted) { - if (interaction instanceof ButtonInteraction) { - await submitted.deferUpdate(); - } else { - await submitted.deferReply({ ephemeral: true }); - } + await interaction + .awaitModalSubmit({ time: MODAL_TIMEOUT, filter: (i) => i.customId == modalId }) + .then(async (submitted) => { + if (interaction.isButton()) { + await submitted.deferUpdate(); + } else if (interaction.isContextMenuCommand()) { + await submitted.deferReply({ ephemeral: true }); + } - const reason = submitted.fields.getTextInputValue("reason"); + const reason = submitted.fields.getTextInputValue("reason"); - await noteAction(pluginData, reason, target, interaction, submitted); - } + await noteAction(pluginData, reason, target, interaction, submitted); + }) + .catch((err) => logger.error(`Note modal interaction failed: ${err}`)); } diff --git a/backend/src/plugins/ContextMenus/actions/warn.ts b/backend/src/plugins/ContextMenus/actions/warn.ts index 4ec0cf43..9afbf44e 100644 --- a/backend/src/plugins/ContextMenus/actions/warn.ts +++ b/backend/src/plugins/ContextMenus/actions/warn.ts @@ -10,10 +10,11 @@ import { import { GuildPluginData } from "knub"; import { canActOn } from "src/pluginUtils"; import { ModActionsPlugin } from "src/plugins/ModActions/ModActionsPlugin"; +import { logger } from "../../../logger"; import { renderUserUsername } from "../../../utils"; import { CaseArgs } from "../../Cases/types"; import { MODAL_TIMEOUT } from "../commands/ModMenuUserCtxCmd"; -import { ContextMenuPluginType } from "../types"; +import { ContextMenuPluginType, ModMenuActionType } from "../types"; async function warnAction( pluginData: GuildPluginData, @@ -22,7 +23,7 @@ async function warnAction( interaction: ButtonInteraction | ContextMenuCommandInteraction, submitInteraction: ModalSubmitInteraction, ) { - const interactionToReply = interaction instanceof ButtonInteraction ? interaction : submitInteraction; + const interactionToReply = interaction.isButton() ? interaction : submitInteraction; const executingMember = await pluginData.guild.members.fetch(interaction.user.id); const userCfg = await pluginData.config.getMatchingConfig({ channelId: interaction.channelId, @@ -71,22 +72,25 @@ export async function launchWarnActionModal( interaction: ButtonInteraction | ContextMenuCommandInteraction, target: string, ) { - const modal = new ModalBuilder().setCustomId("warn").setTitle("Warn"); + const modalId = `${ModMenuActionType.WARN}:${interaction.id}`; + const modal = new ModalBuilder().setCustomId(modalId).setTitle("Warn"); const reasonIn = new TextInputBuilder().setCustomId("reason").setLabel("Reason").setStyle(TextInputStyle.Paragraph); const reasonRow = new ActionRowBuilder().addComponents(reasonIn); modal.addComponents(reasonRow); await interaction.showModal(modal); - const submitted: ModalSubmitInteraction = await interaction.awaitModalSubmit({ time: MODAL_TIMEOUT }); - if (submitted) { - if (interaction instanceof ButtonInteraction) { - await submitted.deferUpdate(); - } else { - await submitted.deferReply({ ephemeral: true }); - } + await interaction + .awaitModalSubmit({ time: MODAL_TIMEOUT, filter: (i) => i.customId == modalId }) + .then(async (submitted) => { + if (interaction.isButton()) { + await submitted.deferUpdate(); + } else if (interaction.isContextMenuCommand()) { + await submitted.deferReply({ ephemeral: true }); + } - const reason = submitted.fields.getTextInputValue("reason"); + const reason = submitted.fields.getTextInputValue("reason"); - await warnAction(pluginData, reason, target, interaction, submitted); - } + await warnAction(pluginData, reason, target, interaction, submitted); + }) + .catch((err) => logger.error(`Mute modal interaction failed: ${err}`)); }