[nextgen/cardstack] rework timeout logic

This commit is contained in:
bignutty 2025-02-22 19:02:44 +01:00
parent 99c9af9a5d
commit ceb8eb097b

View file

@ -8,7 +8,7 @@ const {STATIC_ASSETS} = require("#utils/statics");
const {Context} = require("detritus-client/lib/command");
const {MessageComponentTypes, InteractionCallbackTypes, MessageFlags} = require("detritus-client/lib/constants");
const {Message} = require("detritus-client/lib/structures");
const {ComponentContext, Components, ComponentActionRow, ComponentButton} = require("detritus-client/lib/utils");
const {ComponentContext, ComponentActionRow, ComponentButton} = require("detritus-client/lib/utils");
const {
STACK_CACHE_KEYS,
@ -55,7 +55,7 @@ class DynamicCardStack {
this.interactive_components = options.interactive || {};
this.index = options.startingIndex || 0;
this.loopPages = options.loop || true;
this.expires = options.expires || 3 * 60 * 1000;
this.expires = options.expires || 60 * 1000;
this.pageNumbers = options.pageNumbers || true;
this.pageNumberGenerator = options.pageNumberGenerator || ((pg) => `Page ${pg.index + 1}/${pg.activeCardStack.length}`);
this.disableCloning = options.disableCloning || false;
@ -70,6 +70,9 @@ class DynamicCardStack {
this.currentComponentsBatch = {};
this.lastInteraction = Date.now();
this.spawned = 0;
return this._spawn();
}
@ -77,6 +80,7 @@ class DynamicCardStack {
* Kills the dynamic card stack.
*/
async kill(clearComponents) {
clearTimeout(this.timeout);
if (clearComponents && !this.killed) await this._edit(this.getCurrentCard(), false, true);
this.killed = true;
@ -85,6 +89,27 @@ class DynamicCardStack {
activeStacks.delete(this.context.message || this.context.interaction);
}
/**
* Creates a timeout for the paginator.
* @returns {number} Timeout
* @private
*/
_createTimeout() {
return setTimeout(async () => {
// If we have an interaction within the expiry window
// restart the expiry window with 30s
if((this.lastInteraction - this.spawned) >= 0){
clearTimeout(this.timeout)
this.spawned = Date.now();
// New expiry time is 30 seconds
this.expires = 30*1000;
this.timeout = this._createTimeout();
} else {
await this.kill(true);
}
}, this.expires)
}
/**
* Get a Stack from an attached reference (message/interaction).
* @param {Message} ref Attached message/interaction
@ -120,18 +145,9 @@ class DynamicCardStack {
this.updatePageState()
// Create internal component listener
this.listener = new Components({
timeout: this.expires,
run: this._handleInteraction.bind(this),
onError: (e) => {
console.error("Component Handler Exception:")
console.error(e)
},
onTimeout: async (_e)=> {
await this.kill(true);
}
})
this.timeout = this._createTimeout()
this.spawned = Date.now()
if (createMessage) return this._edit({
...this.getCurrentCard()
@ -241,22 +257,17 @@ class DynamicCardStack {
* Automatically applies and re-renders components.
* @param {Message} cardContent Card Content
* @param {boolean, Array} components Custom Components Array
* @param killComponents Remove components
*/
async _edit(cardContent, components = false, killComponents = false) {
let message = Object.assign({}, cardContent);
this._renderComponents(killComponents);
message.components = this.listener;
message.components = this._renderComponents(killComponents);
if (components) {
message.components = components;
}
// This should detatch the listener.
if(killComponents) {
message.components = this.listener.components;
}
if (message["_meta"]) delete message["_meta"];
try {
@ -414,7 +425,15 @@ class DynamicCardStack {
// Slot all components into their respective rows.
while (components.length > 0) {
row.addButton(components.shift());
let c = components.shift();
// Avoid adding listeners to disabled components
// for optimization's sake
if(c.disabled) row.addButton(c);
else row.addButton({
...c,
run: this._handleInteraction.bind(this)
})
// Create a new row for content to overflow in.
if (row.isFull) {
@ -429,9 +448,7 @@ class DynamicCardStack {
if (renderedSlots.length > 5) console.warn("Component Overflow - Limiting to 5.")
this.listener.components = renderedSlots.splice(0, 5);
return this.listener;
return renderedSlots.splice(0, 5);
}
/**
@ -530,7 +547,7 @@ class DynamicCardStack {
return;
}
//this.lastInteraction = Date.now();
this.lastInteraction = Date.now();
// Built-in Buttons
if (Object.values(BuiltInButtonTypes).includes(ctx.data.customId)) {