diff --git a/src/bot/commands/checkin/handlers/checkin.ts b/src/bot/commands/checkin/handlers/index.ts similarity index 100% rename from src/bot/commands/checkin/handlers/checkin.ts rename to src/bot/commands/checkin/handlers/index.ts diff --git a/src/bot/events/interaction-create/checkin/validators/index.ts b/src/bot/events/interaction-create/checkin/validators/index.ts index bff1464..df8ad63 100644 --- a/src/bot/events/interaction-create/checkin/validators/index.ts +++ b/src/bot/events/interaction-create/checkin/validators/index.ts @@ -4,9 +4,9 @@ import type { Attachment as AttachmentType } from '@type/attachment' import type { CheckinAllowedEmojiType, CheckinColumn, CheckinStatusType, Checkin as CheckinType } from '@type/checkin' import type { CheckinStreak } from '@type/checkin-streak' import type { User } from '@type/user' -import type { Attachment, Client, EmbedBuilder, Guild, GuildMember, Interaction, Message, TextChannel } from 'discord.js' +import type { ActionRow, Attachment, ButtonComponent, Client, EmbedBuilder, Guild, GuildMember, Interaction, Message, TextChannel } from 'discord.js' import crypto from 'node:crypto' -import { CheckinError } from '@commands/checkin/handlers/checkin' +import { CheckinError } from '@commands/checkin/handlers' import { AURA_FARMING_CHANNEL, CHECKIN_CHANNEL, GRINDER_ROLE } from '@config/discord' import { SubmittedCheckinError } from '@events/message-reaction-add/checkin/handlers/submitted' import { createEmbed, decodeSnowflakes, encodeSnowflake, getCustomId } from '@utils/component' @@ -38,6 +38,12 @@ export class Checkin extends CheckinMessage { '🔥': 'APPROVED', } + static readonly CHECKIN_DELETED_BUTTONS = [ + CHECKIN_APPROVE_BUTTON_ID, + CHECKIN_REJECT_BUTTON_ID, + CHECKIN_CUSTOM_BUTTON_ID, + ] + static REVERSED_EMOJI_STATUS = Object.fromEntries( Object.entries(this.EMOJI_STATUS).map(([emoji, status]) => [status, emoji]), ) as Record @@ -169,13 +175,6 @@ export class Checkin extends CheckinMessage { allowedMentions: { users: [member.id], roles: [] }, }) } - else { - const checkinChannel = await getChannel(guild, CHECKIN_CHANNEL) as TextChannel - await sendAsBot(null, checkinChannel, { - content: `Hey, <@${member.id}>. You already have <@&${newRole.id}>`, - allowedMentions: { users: [member.id], roles: [] }, - }, true) - } } static assertCheckinToday(user: User) { @@ -439,7 +438,7 @@ export class Checkin extends CheckinMessage { const message = await checkinChannel.messages.fetch(messageId) await this.validateCheckinHandleToUser(guild, flamewarden, updatedCheckin.user!.discord_id, updatedCheckin) - await message.react(this.REVERSED_EMOJI_STATUS[checkinStatus]) + await this.editSubmittedCheckinMessage(message, checkinStatus) return updatedCheckin } @@ -457,6 +456,26 @@ export class Checkin extends CheckinMessage { await this.sendCheckinStatusToMember(flamewarden, member, updatedCheckin) } + static async editSubmittedCheckinMessage(message: Message, checkinStatus: CheckinStatusType) { + await message.react(this.REVERSED_EMOJI_STATUS[checkinStatus]) + + const newRows = this.getNewButtons(message.components as ActionRow[]) + await message.edit({ components: newRows }) + } + + static getNewButtons(components: readonly ActionRow[]): ActionRowBuilder[] { + return components + .map((row) => { + const buttons = row.components + .filter(btn => btn.customId && !this.CHECKIN_DELETED_BUTTONS.some(id => btn.customId!.startsWith(id))) + .map(btn => ButtonBuilder.from(btn)) + const newRow = new ActionRowBuilder().addComponents(...buttons) + + return buttons.length ? newRow : null + }) + .filter((row): row is ActionRowBuilder => row !== null) + } + static async updateCheckinMsgLink(interaction: Interaction, prisma: PrismaClient, checkin: CheckinType, msg: Message): Promise { const msgLink = messageLink(interaction.channelId!, msg.id, interaction.guildId!)