Skip to content
This repository was archived by the owner on Dec 6, 2022. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { Message, EmbedOptions } from 'eris';

declare module 'eris-pagination' {

/**
* An optional options object for overwriting defaults
*/
interface PaginationOptions {
/** Whether or not to show the current page index over the embed. Defaults to: true */
showPageNumbers?: boolean;
/** Whether or not to show extended control buttons besides standard pagination (First & Last page, deleting) */
extendedButtons?: boolean;
/** Cycle through all embeds jumping from the first page to the last page on going back and from the last page to the first page going forth. Defaults to: false */
cycling?: boolean;
/** How often the reaction handler should listen for a reaction (How often the paginator can be used). Defaults to: 50. Maximum: 100 */
maxMatches?: number;
/** How long the paginator should work before the reaction listener times out. Defaults to: 300000ms (5 minutes). Maximum: 900000ms (15 minutes) */
timeout?: number;
/** Emoji which should be used as the delete button. This MUST be a unicode emoji! Defaults to: 🗑 */
deleteButton?: string;
/** Emoji which should be used as the first page button. This MUST be a unicode emoji! Defaults to: ⏮ */
firstButton?: string;
/** Emoji which should be used as the last page button. This MUST be a unicode emoji! Defaults to: ⏭ */
lastButton?: string;
/** Emoji which should be used as the back button. This MUST be a unicode emoji! Defaults to: ⬅ */
backButton?: string;
/** Emoji which should be used as the forth button. This MUST be a unicode emoji! Defaults to: ➡ */
forthButton?: string;
/** Which page of the submitted embed array should be shown first. Defaults to: 1 (The 1st page / element in the array) */
startPage?: number;
}

/**
* Create an Embed Paginator
* @param message A message object emitted from a messageCreate event coming from Eris, used as an invoker. If sent by the client, the message will be edited.
* @param pages An array containing all embed objects
* @param options An optional options object for overwriting defaults
*/
function createPaginationEmbed(message: Message, pages: EmbedOptions[], options?: PaginationOptions): Promise<Message>;

}
88 changes: 63 additions & 25 deletions lib/PaginationEmbed.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,22 @@

const ReactionHandler = require('eris-reactions');

/**
* @typedef {import('eris').EmbedBase} EmbedBase
* @typedef {import('eris').Message} Message
* @typedef {Object} PaginationOptions An optional options object for overwriting defaults
* @property {Boolean} [showPageNumbers] Whether or not to show the current page index over the embed. Defaults to: true
* @property {Boolean} [extendedButtons] Whether or not to show extended control buttons besides standard pagination (First & Last page, deleting)
* @property {Boolean} [cycling] Cycle through all embeds jumping from the first page to the last page on going back and from the last page to the first page going forth. Defaults to: false
* @property {Number} [maxMatches] How often the reaction handler should listen for a reaction (How often the paginator can be used). Defaults to: 50. Maximum: 100
* @property {Number} [timeout] How long the paginator should work before the reaction listener times out. Defaults to: 300000ms (5 minutes). Maximum: 900000ms (15 minutes)
* @property {String} [deleteButton] Emoji which should be used as the delete button. This MUST be a unicode emoji! Defaults to: 🗑
* @property {String} [firstButton] Emoji which should be used as the first page button. This MUST be a unicode emoji! Defaults to: ⏮
* @property {String} [lastButton] Emoji which should be used as the last page button. This MUST be a unicode emoji! Defaults to: ⏭
* @property {String} [backButton] Emoji which should be used as the back button. This MUST be a unicode emoji! Defaults to: ⬅
* @property {String} [forthButton] Emoji which should be used as the forth button. This MUST be a unicode emoji! Defaults to: ➡
* @property {Number} [startPage] Which page of the submitted embed array should be shown first. Defaults to: 1 (The 1st page / element in the array)
*/
/**
* Embed Pagination class
* @class PaginationEmbed
Expand All @@ -10,20 +26,9 @@ const ReactionHandler = require('eris-reactions');
class PaginationEmbed {
/**
* Constructor for the Embed Paginator
* @param {Eris#Message} message A message object emitted from a messageCreate event coming from Eris, used as an invoker.
* @param {Object[]} pages An array containing all embed objects
* @param {Object} options An optional options object for overwriting defaults
* @property {Boolean} options.showPageNumbers Whether or not to show the current page index over the embed. Defaults to: true
* @property {Boolean} options.extendedButtons Whether or not to show extended control buttons besides standard pagination (First & Last page, deleting)
* @property {Boolean} options.cycling Cycle through all embeds jumping from the first page to the last page on going back and from the last page to the first page going forth. Defaults to: false
* @property {Number} options.maxMatches How often the reaction handler should listen for a reaction (How often the paginator can be used). Defaults to: 50. Maximum: 100
* @property {Number} options.timeout How long the paginator should work before the reaction listener times out. Defaults to: 300000ms (5 minutes). Maximum: 900000ms (15 minutes)
* @property {String} options.deleteButton Emoji which should be used as the delete button. This MUST be a unicode emoji! Defaults to: 🗑
* @property {String} options.firstButton Emoji which should be used as the first page button. This MUST be a unicode emoji! Defaults to: ⏮
* @property {String} options.lastButton Emoji which should be used as the last page button. This MUST be a unicode emoji! Defaults to: ⏭
* @property {String} options.backButton Emoji which should be used as the back button. This MUST be a unicode emoji! Defaults to: ⬅
* @property {String} options.forthButton Emoji which should be used as the forth button. This MUST be a unicode emoji! Defaults to: ➡
* @property {Number} options.startPage Which page of the submitted embed array shoulb be shown first. Defaults to: 1 (The 1st page / element in the array)
* @param {Message} message A message object emitted from a messageCreate event coming from Eris, used as an invoker. If sent by the client, the message will be edited.
* @param {EmbedBase[]} pages An array containing all embed objects
* @param {PaginationOptions} [options] An optional options object for overwriting defaults
*/
constructor(message, pages = [], options = {}) {
this.pages = pages;
Expand Down Expand Up @@ -62,11 +67,17 @@ class PaginationEmbed {
if (this.timeout > 900000) {
return Promise.reject(new Error('Embed Timeout too high! Maximum pagination lifespan allowed is 15 minutes (900000 ms)!'));
}
this.message = await this.invoker.channel.createMessage({

const messageContent = {
content: (this.showPages) ? `Page **${this.page}** of **${this.pages.length}**` : undefined,
embed: this.pages[this.page - 1]
});
}

if (this.invoker.author.id === this.invoker._client.user.id) {
this.message = await this.invoker.edit(messageContent);
} else {
this.message = await this.invoker.channel.createMessage(messageContent)
}

this.handler = new ReactionHandler.continuousReactionStream(this.message, (userID) => userID === this.invoker.author.id, false, { maxMatches: this.maxMatches, time: this.timeout });

Expand All @@ -92,6 +103,14 @@ class PaginationEmbed {
});
}

/**
* Check if the client can remove the reaction
* @returns {Boolean}
*/
checkPerms() {
return this.message.channel.guild && this.message.channel.permissionsOf(this.message._client.user.id).has('manageMessages');
}

/**
* Main method handling the reaction listening and content updating
*/
Expand All @@ -100,7 +119,9 @@ class PaginationEmbed {
switch (event.emoji.name) {
case this.firstPage: {
if (this.advanced) {
await this.message.removeReaction(this.firstPage, this.invoker.author.id);
if (this.checkPerms()) {
await this.message.removeReaction(this.firstPage, this.invoker.author.id);
}

if (this.page > 1) {
this.page = 1;
Expand All @@ -112,7 +133,9 @@ class PaginationEmbed {
}

case this.back: {
await this.message.removeReaction(this.back, this.invoker.author.id);
if (this.checkPerms()) {
await this.message.removeReaction(this.back, this.invoker.author.id);
}

if (this.page > 1) {
this.page--;
Expand All @@ -126,7 +149,9 @@ class PaginationEmbed {
}

case this.forth: {
await this.message.removeReaction(this.forth, this.invoker.author.id);
if (this.checkPerms()) {
await this.message.removeReaction(this.forth, this.invoker.author.id);
}

if (this.page < this.pages.length) {
this.page++;
Expand All @@ -141,7 +166,9 @@ class PaginationEmbed {

case this.lastPage: {
if (this.advanced) {
await this.message.removeReaction(this.lastPage, this.invoker.author.id);
if (this.checkPerms()) {
await this.message.removeReaction(this.lastPage, this.invoker.author.id);
}

if (this.page < this.pages.length) {
this.page = this.pages.length;
Expand All @@ -156,10 +183,14 @@ class PaginationEmbed {

case this.delete: {
if (this.advanced) {
return new Promise((resolve) => {
this.message.removeReactions().then(() => {
resolve();
});
return new Promise((resolve, reject) => {
if (this.checkPerms()) {
this.message.removeReactions().then(() => {
resolve();
});
} else {
reject(new Error('Insufficient permissions to remove reactions'))
}
});
}

Expand All @@ -171,6 +202,13 @@ class PaginationEmbed {
}

module.exports = {
/**
* Create an Embed Paginator
*
* @param {Message} message A message object emitted from a messageCreate event coming from Eris, used as an invoker. If sent by the client, the message will be edited.
* @param {EmbedBase[]} pages An array containing all embed objects
* @param {PaginationOptions} [options] An optional options object for overwriting defaults
*/
createPaginationEmbed: async (message, pages, options) => {
const paginationEmbed = new PaginationEmbed(message, pages, options);
await paginationEmbed.initialize();
Expand Down
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 5 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "eris-pagination",
"version": "0.4.0",
"version": "0.5.2",
"description": "An extremely easy to use Embed Paginator for the Eris Discord Library",
"main": "index.js",
"scripts": {
Expand All @@ -25,6 +25,9 @@
},
"homepage": "https://github.com/riyacchi/eris-pagination#readme",
"dependencies": {
"eris-reactions": "^0.1.2"
"eris-reactions": "^0.1.4"
},
"peerDependencies": {
"eris": "^0.13.1"
}
}