Last active
January 22, 2023 06:15
-
-
Save peakh/128c7645be4f200c77fba5335fc63ee5 to your computer and use it in GitHub Desktop.
Pagination with first page, previous, next, and last page buttons; includes automatic splicing within the other file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { ActionRowBuilder, ButtonBuilder, ButtonInteraction, ButtonStyle, ChatInputCommandInteraction, EmbedBuilder } from 'discord.js'; | |
import colors from '../util/colors'; | |
/** | |
* | |
* @param {ChatInputCommandInteraction} interaction | |
* @param {EmbedBuilder} embeds | |
* @param {ButtonBuilder} buttons | |
* @returns | |
*/ | |
const pagination = async(interaction: ChatInputCommandInteraction, embeds: any, buttons: Array<any>, time: number = 15000, ephemeral: boolean = false, footerText?: string) => { | |
const row = new ActionRowBuilder<ButtonBuilder>().addComponents(buttons); | |
if(!embeds || embeds.length === 0) { | |
throw new Error(`No embeds were provided.`); | |
} | |
if(!buttons) { | |
throw new Error(`No buttons were provided.`); | |
} | |
if(buttons.length < 4 || buttons.length > 4) { | |
throw new Error(`The minimum and maximum amount of buttons are 4.`); | |
} | |
if(buttons[0].style === 'LINK' || buttons[1].style === 'LINK' || buttons[2].style === 'LINK' || buttons[3].style === 'LINK') { | |
throw new Error(`Buttons are not intended to be link-styled.`); | |
} | |
let page = 0; | |
if(interaction.deferred === false) { | |
await interaction.deferReply({ ephemeral: ephemeral || false }); | |
} | |
embeds.length === 1 ? buttons[0].setDisabled(true) && buttons[1].setDisabled(true) && buttons[2].setDisabled(true) && buttons[3].setDisabled(true) : buttons[0].setDisabled(true) && buttons[1].setDisabled(true) && buttons[2].setDisabled(false) && buttons[3].setDisabled(false); | |
const currentPage = await interaction.editReply({ | |
embeds: [ | |
embeds[page].setFooter({ text: `${footerText?.length > 0 ? `${footerText} ` + '|' : ''} Page ${page + 1} of ${embeds.length}`}) | |
], | |
components: [ | |
row | |
] | |
}); | |
// ? Maybe filter IDs. | |
const filter = (int: ButtonInteraction) => { | |
if(int.customId === buttons[0].data.custom_id || int.customId === buttons[1].data.custom_id || int.customId === buttons[2].data.custom_id ||int.customId === buttons[3].data.custom_id) { | |
return true; | |
} | |
int.reply({ | |
embeds: [ | |
new EmbedBuilder() | |
.setColor(colors.discord) | |
.setDescription(`Unknown interaction.`) | |
], | |
ephemeral: true | |
}); | |
}; | |
const collector = currentPage.createMessageComponentCollector({ filter: filter, time: time }); | |
collector.on('collect', async (int: ButtonInteraction) => { | |
switch(int.customId) { | |
case buttons[0].data.custom_id: | |
page = page + 1 < embeds.length ? page = embeds.length - embeds.length : 0; | |
page === 0 ? buttons[0].setDisabled(true) && buttons[1].setDisabled(true) && buttons[2].setDisabled(false) && buttons[3].setDisabled(false) : buttons[0].setDisabled(false) && buttons[1].setDisabled(false); | |
break; | |
case buttons[1].data.custom_id: | |
page = page > 0 ? --page : embeds.length - 1; | |
page === 0 ? buttons[0].setDisabled(true) && buttons[1].setDisabled(true) && buttons[2].setDisabled(false) && buttons[3].setDisabled(false) : buttons[0].setDisabled(false) && buttons[1].setDisabled(false) && buttons[2].setDisabled(false) && buttons[3].setDisabled(false); | |
break; | |
case buttons[2].data.custom_id: | |
page = page + 1 < embeds.length ? ++page : 0; | |
page === embeds.length - 1 ? buttons[2].setDisabled(true) && buttons[3].setDisabled(true) && buttons[0].setDisabled(false) && buttons[1].setDisabled(false) : buttons[2].setDisabled(false) && buttons[3].setDisabled(false) && buttons[0].setDisabled(false) && buttons[1].setDisabled(false); | |
break; | |
case buttons[3].data.custom_id: | |
page = page + 1 < embeds.length ? page = embeds.length - 1 : 0; | |
page === embeds.length - 1 ? buttons[2].setDisabled(true) && buttons[3].setDisabled(true) && buttons[0].setDisabled(false) && buttons[1].setDisabled(false) : buttons[2].setDisabled(false) && buttons[3].setDisabled(false); | |
default: | |
break; | |
} | |
await int.deferUpdate(); | |
await int.editReply({ | |
embeds: [ | |
embeds[page].setFooter({ text: `${footerText?.length > 0 ? `${footerText} ` + '|' : ''} Page ${page + 1} of ${embeds.length}`}) | |
], | |
components: [ | |
row | |
] | |
}); | |
collector.resetTimer(); | |
}); | |
collector.on('end', async (collected, reason) => { | |
if(reason === 'time' && interaction.ephemeral === true) { | |
if(!currentPage) { | |
return; | |
} | |
const row = new ActionRowBuilder<ButtonBuilder>().setComponents( | |
ButtonBuilder.from(buttons[0]) | |
.setStyle(ButtonStyle.Secondary) | |
.setDisabled(true), | |
ButtonBuilder.from(buttons[1]) | |
.setStyle(ButtonStyle.Secondary) | |
.setDisabled(true), | |
ButtonBuilder.from(buttons[2]) | |
.setStyle(ButtonStyle.Secondary) | |
.setDisabled(true), | |
ButtonBuilder.from(buttons[3]) | |
.setStyle(ButtonStyle.Secondary) | |
.setDisabled(true), | |
) | |
await interaction.editReply({ | |
embeds: [embeds[page].setFooter({ text: `${footerText?.length > 0 ? `${footerText} ` + '|' : ''} Page ${page + 1} of ${embeds.length}`})], | |
components: [row], | |
}); | |
} else if(reason === 'time' && interaction.ephemeral === false) { | |
if(!currentPage) { | |
return; | |
} | |
const row = new ActionRowBuilder<ButtonBuilder>().setComponents( | |
ButtonBuilder.from(buttons[0]) | |
.setStyle(ButtonStyle.Secondary) | |
.setDisabled(true), | |
ButtonBuilder.from(buttons[1]) | |
.setStyle(ButtonStyle.Secondary) | |
.setDisabled(true), | |
ButtonBuilder.from(buttons[2]) | |
.setStyle(ButtonStyle.Secondary) | |
.setDisabled(true), | |
ButtonBuilder.from(buttons[3]) | |
.setStyle(ButtonStyle.Secondary) | |
.setDisabled(true), | |
); | |
await interaction.editReply({ | |
embeds: [embeds[page].setFooter({ text: `${footerText?.length > 0 ? `${footerText} ` + '|' : ''} Page ${page + 1} of ${embeds.length}`})], | |
components: [row], | |
}); | |
} | |
}); | |
return currentPage; | |
} | |
export default pagination; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import pagination from './pagination'; | |
import { ButtonBuilder, ButtonStyle, ChatInputCommandInteraction, EmbedBuilder } from 'discord.js'; | |
import colors from '../util/colors'; | |
import emojis from '../util/emojis'; | |
const splitContent = async (interaction: ChatInputCommandInteraction, content: string[], displayAmount: number, title?: string, paginationTime: number = 15000, paginationEphemeral: boolean = false, footerText?: string) => { | |
let embed: Object = {}; | |
let embeds: Array<any> = []; | |
let i, j, temp, chunk = displayAmount; | |
for(i = 0, j = content.length; i < j; i += chunk) { | |
temp = content.slice(i, i + chunk); | |
embed[`${i / displayAmount}`] = new EmbedBuilder() | |
.setTitle(title || null) | |
.setColor(colors.discord) | |
.setDescription(`${temp.join('\n')}`); | |
} | |
for(let i = 0; i < (Object.keys(embed).length); i++) { | |
embeds.push(embed[i]); | |
} | |
const first = new ButtonBuilder() | |
.setCustomId('first') | |
.setEmoji(emojis.arrows.skipLeft) | |
.setStyle(ButtonStyle.Secondary) | |
const previous = new ButtonBuilder() | |
.setCustomId('previous') | |
.setEmoji(emojis.arrows.left) | |
.setStyle(ButtonStyle.Secondary) | |
const next = new ButtonBuilder() | |
.setCustomId('next') | |
.setEmoji(emojis.arrows.right) | |
.setStyle(ButtonStyle.Secondary) | |
const last = new ButtonBuilder() | |
.setCustomId('last') | |
.setEmoji(emojis.arrows.skipRight) | |
.setStyle(ButtonStyle.Secondary) | |
let buttons: Array<any> = []; | |
buttons.push( | |
first, | |
previous, | |
next, | |
last | |
); | |
pagination(interaction, embeds, buttons, paginationTime, paginationEphemeral, footerText); | |
} | |
export default splitContent; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment