@ayanaware/bentocord
Version:
Bentocord is a Bento plugin designed to rapidly build fully functional Discord Bots.
188 lines • 7.25 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.PaginationPrompt = exports.PaginationEmojis = void 0;
const Button_1 = require("../components/helpers/Button");
const Select_1 = require("../components/helpers/Select");
const Prompt_1 = require("./Prompt");
var PaginationEmojis;
(function (PaginationEmojis) {
PaginationEmojis["FIRST"] = "\u23EE\uFE0F";
PaginationEmojis["PREV"] = "\u25C0\uFE0F";
PaginationEmojis["NEXT"] = "\u25B6\uFE0F";
PaginationEmojis["LAST"] = "\u23ED\uFE0F";
PaginationEmojis["CLOSE"] = "\u2716\uFE0F";
})(PaginationEmojis = exports.PaginationEmojis || (exports.PaginationEmojis = {}));
const TEXT_FIRST = ['<<', 'first', 'f'];
const TEXT_PREV = ['<', 'prev', 'previous'];
const TEXT_NEXT = ['>', 'next'];
const TEXT_LAST = ['>>', 'last', 'l'];
class PaginationPrompt extends Prompt_1.Prompt {
constructor(ctx, paginator, options) {
super(ctx, null, options);
this.paginator = paginator;
this.validator = this.handleText.bind(this);
this.btnFirst = new Button_1.Button(this.ctx, 'bc:page:first', this.handleButton.bind(this))
.secondary().emoji({ name: PaginationEmojis.FIRST });
this.btnPrev = new Button_1.Button(this.ctx, 'bc:page:prev', this.handleButton.bind(this))
.secondary().emoji({ name: PaginationEmojis.PREV });
this.btnNext = new Button_1.Button(this.ctx, 'bc:page:next', this.handleButton.bind(this))
.secondary().emoji({ name: PaginationEmojis.NEXT });
this.btnLast = new Button_1.Button(this.ctx, 'bc:page:last', this.handleButton.bind(this))
.secondary().emoji({ name: PaginationEmojis.LAST });
this.btnClose = new Button_1.Button(this.ctx, 'bc:page:close', this.handleButton.bind(this))
.danger().emoji({ name: PaginationEmojis.CLOSE });
this.sltPage = new Select_1.Select(this.ctx, 'bc:page:select', this.handleSelect.bind(this))
.max(1);
}
async start() {
await this.sltPage.placeholderTranslated('BENTOCORD_PAGINATION_SELECT', {}, 'Jump to Page');
return super.start();
}
async close() {
await this.cleanup();
// raw pagination doesn't return anything
return this.resolve();
}
async draw() {
// get pagination content
const paginator = this.paginator;
if (!paginator)
return;
// clear components
this.clearRows();
// render page
// merged by ComponentOperation.render()
this._merge = await paginator.render();
// less then 2 pages; no need to display pagination controls
if (this.paginator.pageCount < 2)
return;
// update state & add buttons
this.addRow([
this.btnFirst.enable(paginator.hasPrev),
this.btnPrev.enable(paginator.hasPrev),
this.btnNext.enable(paginator.hasNext),
this.btnLast.enable(paginator.hasNext),
this.btnClose,
]);
// Add page selector
const page = this.paginator.page;
const pageCount = this.paginator.pageCount;
if (!(this.options?.forcePageSelect ?? false) && pageCount < 5)
return;
const padding = Math.floor(this.sltPage.maxOptions / 2);
let start = page - padding;
let end = page + padding;
// went past 0, add leftover to end
if (start < 0) {
const pastStart = Math.abs(start);
start = 0;
end += pastStart;
}
// went past end, add leftover to start
if (end > pageCount - 1) {
const pastEnd = end - pageCount - 1;
start -= pastEnd;
}
// constrain start & end
if (start < 0)
start = 0;
if (end > pageCount - 1)
end = pageCount - 1;
// update select options
const options = [];
for (let i = start; i <= end; i++) {
const option = { value: i.toString(), label: (i + 1).toString(), default: i === page };
if (this.paginator.options.itemsPerPage === 1) {
const { item } = await this.paginator.getItem(i);
// label
let label = item.label ?? (i + 1).toString();
if (typeof label === 'object')
label = await this.ctx.formatTranslation(label);
option.label = label;
// description
let description = item.description;
if (typeof description === 'object')
description = await this.ctx.formatTranslation(description);
option.description = description;
// emoji
if (item.emoji)
option.emoji = item.emoji;
}
options.push(option);
}
this.sltPage.setOptions(options);
this.addRow([this.sltPage]);
}
async handleButton(btn) {
if (!this.paginator)
return;
const action = btn.parseCustomId();
switch (action.id) {
case 'first': {
this.paginator.page = 0;
break;
}
case 'prev': {
this.paginator.page--;
break;
}
case 'next': {
this.paginator.page++;
break;
}
case 'last': {
this.paginator.page = this.paginator.pageCount - 1;
break;
}
case 'close':
default: {
return this.close();
}
}
return btn.updateMessage(await this.build(), this._files);
}
async handleSelect(slt) {
if (slt.values.length !== 1)
return;
const page = Number(slt.values[0]);
if (isNaN(page))
return;
this.paginator.page = page;
return slt.updateMessage(await this.build(), this._files);
}
async handleText(response) {
if (!this.paginator)
return [null, null];
response = response.toLocaleLowerCase();
// Using arrays to allow localization in the future
if (TEXT_FIRST.includes(response)) {
this.paginator.page = 0;
}
else if (TEXT_PREV.includes(response)) {
this.paginator.page--;
}
else if (TEXT_NEXT.includes(response)) {
this.paginator.page++;
}
else if (TEXT_LAST.includes(response)) {
this.paginator.page = this.paginator.pageCount - 1;
}
else {
// check for p{num} syntax
const matches = /^p\s?(\d+)/.exec(response);
if (!matches)
return [null, null];
const page = Number(matches[1]);
if (isNaN(page))
return [null, null];
this.paginator.page = page - 1;
}
// refresh timeout, valid text page swap
this.refreshTimeout();
await this.render();
// validator; take no action
return [null, null];
}
}
exports.PaginationPrompt = PaginationPrompt;
//# sourceMappingURL=PaginationPrompt.js.map