diff options
Diffstat (limited to 'src/lib/common/ButtonPaginator.ts')
-rw-r--r-- | src/lib/common/ButtonPaginator.ts | 219 |
1 files changed, 0 insertions, 219 deletions
diff --git a/src/lib/common/ButtonPaginator.ts b/src/lib/common/ButtonPaginator.ts deleted file mode 100644 index 02c78ea..0000000 --- a/src/lib/common/ButtonPaginator.ts +++ /dev/null @@ -1,219 +0,0 @@ -import { DeleteButton, type CommandMessage, type SlashMessage } from '#lib'; -import { CommandUtil } from 'discord-akairo'; -import { - ActionRowBuilder, - ButtonBuilder, - ButtonStyle, - EmbedBuilder, - type APIEmbed, - type Message, - type MessageComponentInteraction -} from 'discord.js'; - -/** - * Sends multiple embeds with controls to switch between them - */ -export class ButtonPaginator { - /** - * The current page of the paginator - */ - protected curPage: number; - - /** - * The paginator message - */ - protected sentMessage: Message | undefined; - - /** - * @param message The message that triggered the command - * @param embeds The embeds to switch between - * @param text The optional text to send with the paginator - * @param {} [deleteOnExit=true] Whether the paginator message gets deleted when the exit button is pressed - * @param startOn The page to start from (**not** the index) - */ - protected constructor( - protected message: CommandMessage | SlashMessage, - protected embeds: EmbedBuilder[] | APIEmbed[], - protected text: string | null, - protected deleteOnExit: boolean, - startOn: number - ) { - this.curPage = startOn - 1; - - // add footers - for (let i = 0; i < embeds.length; i++) { - if (embeds[i] instanceof EmbedBuilder) { - (embeds[i] as EmbedBuilder).setFooter({ text: `Page ${(i + 1).toLocaleString()}/${embeds.length.toLocaleString()}` }); - } else { - (embeds[i] as APIEmbed).footer = { - text: `Page ${(i + 1).toLocaleString()}/${embeds.length.toLocaleString()}` - }; - } - } - } - - /** - * The number of pages in the paginator - */ - protected get numPages(): number { - return this.embeds.length; - } - - /** - * Sends the paginator message - */ - protected async send() { - this.sentMessage = await this.message.util.reply({ - content: this.text, - embeds: [this.embeds[this.curPage]], - components: [this.getPaginationRow()] - }); - - const collector = this.sentMessage.createMessageComponentCollector({ - filter: (i) => i.customId.startsWith('paginate_'), - time: 300_000 - }); - collector.on('collect', (i) => void this.collect(i)); - collector.on('end', () => void this.end()); - } - - /** - * Handles interactions with the paginator - * @param interaction The interaction received - */ - protected async collect(interaction: MessageComponentInteraction) { - if (interaction.user.id !== this.message.author.id && !this.message.client.config.owners.includes(interaction.user.id)) - return await interaction?.deferUpdate().catch(() => null); - - switch (interaction.customId) { - case 'paginate_beginning': - this.curPage = 0; - await this.edit(interaction); - break; - case 'paginate_back': - this.curPage--; - await this.edit(interaction); - break; - case 'paginate_stop': - if (this.deleteOnExit) { - await interaction.deferUpdate().catch(() => null); - await this.sentMessage!.delete().catch(() => null); - break; - } else { - await interaction - ?.update({ - content: `${this.text ? `${this.text}\n` : ''}Command closed by user.`, - embeds: [], - components: [] - }) - .catch(() => null); - break; - } - case 'paginate_next': - this.curPage++; - await this.edit(interaction); - break; - case 'paginate_end': - this.curPage = this.embeds.length - 1; - await this.edit(interaction); - break; - } - } - - /** - * Ends the paginator - */ - protected async end() { - if (this.sentMessage && !CommandUtil.deletedMessages.has(this.sentMessage.id)) - await this.sentMessage - .edit({ - content: this.text, - embeds: [this.embeds[this.curPage]], - components: [this.getPaginationRow(true)] - }) - .catch(() => null); - } - - /** - * Edits the paginator message - * @param interaction The interaction received - */ - protected async edit(interaction: MessageComponentInteraction) { - await interaction - ?.update({ - content: this.text, - embeds: [this.embeds[this.curPage]], - components: [this.getPaginationRow()] - }) - .catch(() => null); - } - - /** - * Generates the pagination row based on the class properties - * @param disableAll Whether to disable all buttons - * @returns The generated {@link ActionRow} - */ - protected getPaginationRow(disableAll = false) { - return new ActionRowBuilder<ButtonBuilder>().addComponents( - new ButtonBuilder({ - style: ButtonStyle.Primary, - customId: 'paginate_beginning', - emoji: PaginateEmojis.BEGINNING, - disabled: disableAll || this.curPage === 0 - }), - new ButtonBuilder({ - style: ButtonStyle.Primary, - customId: 'paginate_back', - emoji: PaginateEmojis.BACK, - disabled: disableAll || this.curPage === 0 - }), - new ButtonBuilder({ - style: ButtonStyle.Primary, - customId: 'paginate_stop', - emoji: PaginateEmojis.STOP, - disabled: disableAll - }), - new ButtonBuilder({ - style: ButtonStyle.Primary, - customId: 'paginate_next', - emoji: PaginateEmojis.FORWARD, - disabled: disableAll || this.curPage === this.numPages - 1 - }), - new ButtonBuilder({ - style: ButtonStyle.Primary, - customId: 'paginate_end', - emoji: PaginateEmojis.END, - disabled: disableAll || this.curPage === this.numPages - 1 - }) - ); - } - - /** - * Sends multiple embeds with controls to switch between them - * @param message The message to respond to - * @param embeds The embeds to switch between - * @param text The text send with the embeds (optional) - * @param deleteOnExit Whether to delete the message when the exit button is clicked (defaults to true) - * @param startOn The page to start from (**not** the index) - */ - public static async send( - message: CommandMessage | SlashMessage, - embeds: EmbedBuilder[] | APIEmbed[], - text: string | null = null, - deleteOnExit = true, - startOn = 1 - ) { - // no need to paginate if there is only one page - if (embeds.length === 1) return DeleteButton.send(message, { embeds: embeds }); - - return await new ButtonPaginator(message, embeds, text, deleteOnExit, startOn).send(); - } -} - -export const PaginateEmojis = { - BEGINNING: { id: '853667381335162910', name: 'w_paginate_beginning', animated: false } as const, - BACK: { id: '853667410203770881', name: 'w_paginate_back', animated: false } as const, - STOP: { id: '853667471110570034', name: 'w_paginate_stop', animated: false } as const, - FORWARD: { id: '853667492680564747', name: 'w_paginate_next', animated: false } as const, - END: { id: '853667514915225640', name: 'w_paginate_end', animated: false } as const -} as const; |