@necord/pagination
Version:
A lightweight Pagination module for Necord
181 lines (180 loc) • 6.69 kB
JavaScript
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.PaginationBuilder = void 0;
const discord_js_1 = require("discord.js");
const enums_1 = require("../enums");
const assert = require("assert");
class PaginationBuilder {
get maxPages() {
var _a;
if (this.pages.length) {
return this.pages.length;
}
return (_a = this._maxPages) !== null && _a !== void 0 ? _a : null;
}
set maxPages(value) {
this._maxPages = value;
}
constructor(options) {
this.filters = [];
this.pages = [];
this.options = Object.assign({}, options);
}
setCustomId(customId) {
this.customId = customId;
return this;
}
setMaxPages(maxPages) {
this.maxPages = maxPages;
return this;
}
setPages(pages) {
this.pages = pages;
return this;
}
addPage(page) {
this.pages.push(page);
return this;
}
clearPages() {
this.pages = [];
return this;
}
setPagesFactory(factory) {
this.pagesFactory = factory;
return this;
}
setButtonsAppearance(buttons) {
this.options.buttons = buttons;
return this;
}
setAllowSkip(allowSkip) {
this.options.allowSkip = allowSkip;
return this;
}
setAllowTraversal(allowTraversal) {
this.options.allowTraversal = allowTraversal;
return this;
}
setFilter(filter) {
this.filters = [filter];
return this;
}
setFilters(filters) {
this.filters = filters;
return this;
}
addFilter(filter) {
this.filters.push(filter);
return this;
}
clearFilters() {
this.filters = [];
return this;
}
filter(interaction) {
return __awaiter(this, void 0, void 0, function* () {
if (this.filters.length === 0) {
return true;
}
for (const filter of this.filters) {
if (!(yield filter(interaction))) {
return false;
}
}
return true;
});
}
build() {
return __awaiter(this, arguments, void 0, function* (page = 1) {
var _a;
page = Math.max(1, Math.min(page, this.maxPages)) || 1;
assert(!!this.customId, 'Custom id must be set');
assert(!!this.pagesFactory || this.pages.length >= 1, 'Pages factory must be set if no pages are provided');
assert(this.maxPages !== null, 'Max pages must be set if no pages are provided');
assert(this.maxPages >= page, `Page ${page} is out of range (max: ${this.maxPages})`);
const pageBuilder = (_a = this.pages[page - 1]) !== null && _a !== void 0 ? _a : (yield this.pagesFactory(page, this.maxPages));
const pageOptions = pageBuilder.build();
const buttons = this.generateButtons(page);
const row = new discord_js_1.ActionRowBuilder().addComponents(buttons);
return Object.assign(Object.assign({}, pageOptions), { components: this.options.buttonsPosition === 'end'
? [...pageOptions.components, row]
: [row, ...pageOptions.components] });
});
}
copy() {
const copy = new PaginationBuilder(this.options);
const customId = [this.customId, 'copy', crypto.randomUUID()].join('.');
copy.setCustomId(customId);
copy.setMaxPages(this.maxPages);
copy.setPages(this.pages);
copy.setPagesFactory(this.pagesFactory);
copy.setButtonsAppearance(this.options.buttons);
copy.setAllowSkip(this.options.allowSkip);
copy.setAllowTraversal(this.options.allowTraversal);
copy.setFilters(this.filters);
return copy;
}
generateButtons(page) {
const options = Object.assign({}, this.options);
if (!options.allowSkip) {
delete options.buttons[enums_1.PaginationAction.First];
delete options.buttons[enums_1.PaginationAction.Last];
}
if (!options.allowTraversal) {
delete options.buttons[enums_1.PaginationAction.Traverse];
}
return Object.entries(this.options.buttons).map(([action, button]) => {
let navigationPage = String(page);
let disabled = false;
switch (action) {
case enums_1.PaginationAction.First:
navigationPage = `-1`;
if (page === 1) {
disabled = true;
}
break;
case enums_1.PaginationAction.Next:
if (page === this.maxPages) {
disabled = true;
}
navigationPage = `${page + 1}`;
break;
case enums_1.PaginationAction.Back:
if (page === 1) {
disabled = true;
}
navigationPage = `${page - 1}`;
break;
case enums_1.PaginationAction.Last:
if (page === this.maxPages) {
disabled = true;
}
navigationPage = `${this.maxPages + 2}`;
break;
case enums_1.PaginationAction.Traverse:
navigationPage = 'traversal';
break;
}
const builder = new discord_js_1.ButtonBuilder()
.setStyle(button.style)
.setLabel(button.label)
.setDisabled(disabled)
.setCustomId(`necord-pagination/${this.customId}/${navigationPage}`);
if (button.emoji) {
builder.setEmoji(button.emoji);
}
return builder;
});
}
}
exports.PaginationBuilder = PaginationBuilder;