diff --git a/src/index.ts b/src/index.ts index 063563b..3b0f6ee 100644 --- a/src/index.ts +++ b/src/index.ts @@ -32,7 +32,7 @@ veluna.discord.on(Events.InteractionCreate, (interaction) => { return; } if (interaction.isButton()) { - void handleButton(interaction); + void handleButton(veluna, interaction); } if (interaction.isModalSubmit()) { void handleModalSubmit(veluna, interaction); diff --git a/src/modules/handleButton.ts b/src/modules/handleButton.ts index 407d591..afd1748 100644 --- a/src/modules/handleButton.ts +++ b/src/modules/handleButton.ts @@ -4,18 +4,26 @@ * @author Naomi Carrigan */ +import { + MessageFlags, + PermissionFlagsBits, + type ButtonInteraction, +} from "discord.js"; import { answer } from "../modals/answer.js"; import { ask } from "../modals/ask.js"; -import type { ButtonInteraction } from "discord.js"; +import type { Veluna } from "../interfaces/veluna.js"; /** * Displays the appropriate modal when a button is pressed. + * @param veluna - Veluna's instance. * @param interaction - The button interaction payload from Discord. */ +// eslint-disable-next-line max-lines-per-function , max-statements -- Big boi function. export const handleButton = async( + veluna: Veluna, interaction: ButtonInteraction, ): Promise => { - const { customId } = interaction; + const { customId, message } = interaction; if (customId === "ask") { await interaction.showModal(ask); @@ -24,4 +32,62 @@ export const handleButton = async( if (customId === "answer") { await interaction.showModal(answer); } + + if (customId.startsWith("block-")) { + await interaction.deferReply({ + flags: MessageFlags.Ephemeral, + }); + if (!interaction.inCachedGuild()) { + await interaction.editReply({ + content: "This interaction can only be used in a server.", + }); + return; + } + const { member, guild } = interaction; + if (!member.permissions.has(PermissionFlagsBits.ManageGuild)) { + await interaction.editReply({ + content: "You do not have permission to use this interaction.", + }); + return; + } + + const userId = customId.replace("block-", ""); + const record = await veluna.db.servers.findUnique({ + where: { + serverId: guild.id, + }, + }); + + if (!record) { + await interaction.editReply({ + content: + // eslint-disable-next-line stylistic/max-len -- Big boi string. + "This server is not registered in the database. Please configure your settings.", + }); + return; + } + + if (record.blockedUsers.includes(userId)) { + await interaction.editReply({ + content: "This user is already blocked.", + }); + await message.delete(); + return; + } + + await veluna.db.servers.update({ + data: { + blockedUsers: { + push: userId, + }, + }, + where: { + serverId: guild.id, + }, + }); + await interaction.editReply({ + content: "User blocked successfully.", + }); + await message.delete(); + } }; diff --git a/src/modules/handleModalSubmit.ts b/src/modules/handleModalSubmit.ts index b011627..7dd1b38 100644 --- a/src/modules/handleModalSubmit.ts +++ b/src/modules/handleModalSubmit.ts @@ -47,6 +47,12 @@ export const handleModalSubmit = async( }); return; } + if (record.blockedUsers.includes(interaction.user.id)) { + await interaction.editReply({ + content: "You are blocked from asking questions in this server.", + }); + return; + } const question = interaction.fields.getTextInputValue("textinput"); const channel = veluna.discord.channels.cache.get(record.questionChannelId) @@ -71,6 +77,13 @@ export const handleModalSubmit = async( style: 3, type: 2, }, + { + // eslint-disable-next-line @typescript-eslint/naming-convention -- Discord API. + custom_id: `block-${interaction.user.id}`, + label: "Block user", + style: 4, + type: 2, + }, ], type: 1, }, @@ -159,5 +172,6 @@ export const handleModalSubmit = async( }, ], }); + await message.delete(); } };