discord-pagination-advanced
Version:
An module to create advanced pagination for your discord bots.
164 lines (137 loc) • 5.78 kB
JavaScript
const { CommandInteraction, Interaction, Message, MessageActionRow, MessageButton, MessageEmbed, MessageButtonStyle } = require("discord.js");
const { fixData, verify } = require("./utility");
const defaultConfig_1 = [
{
label: "",
style: "SECONDARY",
emoji: "⬅️"
},
{
label: "",
style: "SECONDARY",
emoji: "➡️"
},
{
label: "",
style: "SECONDARY",
emoji: "❌"
}
];
const defaultConfig_2 = [
{
label: "",
style: "SECONDARY",
emoji: "⬅️"
},
{
label: "",
style: "SECONDARY",
emoji: "➡️"
},
{
label: "",
style: "SECONDARY",
emoji: "❌"
},
{
label: "",
style: "SECONDARY",
emoji: "⏮️"
},
{
label: "",
style: "SECONDARY",
emoji: "⏭️"
}
];
/**
* Easily create pagination of embeds / text messages.
* @param { Interaction | Message } message The message/interaction
* @param {Array<MessageEmbed | String>} embeds The array or embeds or string.
* @param {Options} options The options of pagination.
*/
module.exports = async function pagination(message, embeds, options = {}) {
const defaultFilter = (i) => i.user.id === (message.author?.id || message.user?.id);
const { pageSkip = false } = options;
const defaultConfig = pageSkip ? defaultConfig_2 : defaultConfig_1;
const { buttonConfig = defaultConfig, timeout = 60000, deleteMessage = false, editReply = false, ephemeral = false, filter = defaultFilter, logs = true, removeComponent = false, close = true } = options;
verify(message, embeds, { buttonConfig, timeout, deleteMessage, editReply, ephemeral, filter, pageSkip, logs, removeComponent, close });
let index = 0, row = new MessageActionRow(), data = { components: [row], content: null, embeds: [], fetchReply: true };;
for (let i = 0; i < defaultConfig.length; i++) {
if (i !== 2 || close) data.components[0].addComponents(
new MessageButton({
customId: `${i + 1}_embed_button`,
style: buttonConfig[i]?.style || "SECONDARY",
emoji: buttonConfig[i]?.emoji || defaultConfig[i].emoji,
label: buttonConfig[i]?.label || defaultConfig[i].label,
})
);
}
try {
typeof (embeds[index]) === "string" ? data.content = embeds[index] : data.embeds = [embeds[index]];
if (ephemeral) data.ephemeral = true;
const msg = await message[message.replied || message.deferred ? editReply ? "editReply" : "followUp" : "reply"](data);
const collector = msg.createMessageComponentCollector({
filter: filter || defaultFilter,
time: timeout,
})
collector.on('collect', async (i) => {
if (!i.isButton() || i.message.id !== msg?.id) return;
const id = i.customId[0];
if (id === "1") index--;
else if (id === "2") index++;
else if (id === "4") index = 0;
else if (id === "5") index = embeds.length - 1;
else {
await i.update(fixData(data, embeds, 0));
return collector.stop("goodEnd");
}
index = index < 0 ? embeds.length - 1 : index >= embeds.length ? index = 0 : index;
i.update(fixData(data, embeds, index));
});
collector.on('end', async (s, r) => {
if (deleteMessage && !message.ephemeral) return await msg.delete().catch(e => {
if (logs) {
console.log("Unable to delete the message!");
console.log(e)
}
});
const msgData = {
components: removeComponent ? [] : data.components.map(x => {
x.components = x.components.map(v => {
v.disabled = true;
return v;
});
return x;
})
};
if (message.ephemeral) message.editReply(msgData).catch(e => {
if (logs) {
console.log("Unable to edit the message!");
console.log(e)
}
}); else msg.edit(msgData).catch(e => {
if (logs) {
console.log("Unable to edit the message!");
console.log(e)
}
})
});
} catch (e) {
if (logs) console.log(e);
throw new Error("I was unable to send/edit embed either the client do not have permission to send message or Invalid embed was provided");
}
}
/**
* @typedef Options The options to control the pagination
* @property {Number} timeout The time for which pagination stays active
* @property {Array<{label: string, style:MessageButtonStyle, emoji: string }>} buttonConfig
* @property {Boolean} pageSkip Do you want page skip buttons
* @property {Boolean} close Do you want the close buttons
* @property {Boolean} deleteMessage Do you want to delete the pagination message after it ends
* @property {Boolean} editReply Do you want to edit the interaction message for the pagination
* @property {Boolean} ephemeral Do you want to the reply to be ephemeral or not
* @property {Boolean} logs Do you want the bot to log errors, default is true
* @property {Boolean} removeComponent Do you to remove component after the collector ends
* @property {Function} filter The interaction listener filter
*/