mirror of
https://gitlab.com/bignutty/labscore.git
synced 2025-06-07 21:53:07 -04:00
[nextgen/cardstack] big improvements
- Implement return types - page numbers - better subpage resolve delay - error handling and system error cards - code cleanup
This commit is contained in:
parent
7e850e5b5d
commit
18bd28591c
6 changed files with 249 additions and 125 deletions
|
@ -2,6 +2,7 @@ const { createEmbed, page } = require("#utils/embed");
|
|||
const { acknowledge } = require("#utils/interactions");
|
||||
|
||||
const { DynamicCardStack } = require("../../../labscore/cardstack/DynamicCardStack");
|
||||
const {CARD_STACK_CONSTANTS} = require("#cardstack");
|
||||
|
||||
module.exports = {
|
||||
label: "text",
|
||||
|
@ -25,6 +26,9 @@ module.exports = {
|
|||
createEmbed("default", context, { description: "page 1"}),
|
||||
createEmbed("default", context, { description: "page 2. this has a conditional button."})
|
||||
].map((p, index)=>page(p, {}, { key: `t_${index}` })),
|
||||
pageNumberGenerator: (pg)=>{
|
||||
return `Test ${pg.index}`
|
||||
},
|
||||
interactive: {
|
||||
always_active_button: {
|
||||
label: "single sub page",
|
||||
|
@ -32,9 +36,12 @@ module.exports = {
|
|||
visible: true,
|
||||
disableCache: true,
|
||||
resolvePage: ()=>{
|
||||
return [
|
||||
createEmbed("success", context, "smiley")
|
||||
].map((p)=>page(p))
|
||||
return {
|
||||
type: CARD_STACK_CONSTANTS.RESOLVE_CALLBACK_TYPES.SUBSTACK,
|
||||
cards: [
|
||||
createEmbed("success", context, "smiley")
|
||||
].map((p)=>page(p))
|
||||
}
|
||||
}
|
||||
},
|
||||
conditional_button: {
|
||||
|
@ -46,16 +53,20 @@ module.exports = {
|
|||
return (page.getState("key") === "t_1")
|
||||
},
|
||||
resolvePage: (pg) => {
|
||||
return [
|
||||
createEmbed("default", context, { description: "this is a conditional sub page"}),
|
||||
createEmbed("default", context, { description: "this is a conditional sub page two"})
|
||||
].map((p)=>page(p));
|
||||
return {
|
||||
type: CARD_STACK_CONSTANTS.RESOLVE_CALLBACK_TYPES.SUBSTACK,
|
||||
cards: [
|
||||
createEmbed("default", context, { description: "this is a conditional sub page"}),
|
||||
createEmbed("default", context, { description: "this is a conditional sub page two"})
|
||||
].map((p)=>page(p))
|
||||
}
|
||||
}
|
||||
},
|
||||
dynamic_button: {
|
||||
// Button Label
|
||||
label: (page) => {
|
||||
return page.getState("key");
|
||||
console.log(page.getState("key"))
|
||||
return page.getState("key") || "test";
|
||||
},
|
||||
// Next to pagination or new row
|
||||
inline: false,
|
||||
|
@ -63,67 +74,19 @@ module.exports = {
|
|||
// Renders the loading state card
|
||||
renderLoadingState: (page) => {
|
||||
return createEmbed("default", context, {
|
||||
description: "-# Subpage Loading :)",
|
||||
description: "-# replacing papa card",
|
||||
})
|
||||
},
|
||||
resolvePage: async (pg) => {
|
||||
console.log("resolving page")
|
||||
return [
|
||||
createEmbed("default", context, { description: "this is a dynamic sub page " + Math.random()}),
|
||||
createEmbed("default", context, { description: "this is a dynamic sub page " + Math.random()}),
|
||||
createEmbed("default", context, { description: "this is a dynamic sub page " + Math.random()}),
|
||||
createEmbed("default", context, { description: "this is a dynamic sub page " + Math.random()})
|
||||
].map((p)=>page(p));
|
||||
return {
|
||||
type: CARD_STACK_CONSTANTS.RESOLVE_CALLBACK_TYPES.REPLACE_PARENT_CARD,
|
||||
card: page(createEmbed("default", context, { description: "this is the new over lord " + new Date()}), {}, {
|
||||
key: Date.now()
|
||||
})
|
||||
};
|
||||
}
|
||||
},
|
||||
conditional_button_2: {
|
||||
// Button Label
|
||||
label: "Conditional",
|
||||
// Next to pagination or new row
|
||||
inline: false,
|
||||
visible: true,
|
||||
resolvePage: (pg) => {throw "a"}
|
||||
},
|
||||
conditional_button_3: {
|
||||
// Button Label
|
||||
label: "Conditional",
|
||||
// Next to pagination or new row
|
||||
inline: false,
|
||||
visible: true,
|
||||
resolvePage: (pg) => {throw "a"}
|
||||
},
|
||||
conditional_button_4: {
|
||||
// Button Label
|
||||
label: "Conditional",
|
||||
// Next to pagination or new row
|
||||
inline: false,
|
||||
visible: true,
|
||||
resolvePage: (pg) => {throw "a"}
|
||||
},
|
||||
conditional_button_5: {
|
||||
// Button Label
|
||||
label: "Conditional",
|
||||
// Next to pagination or new row
|
||||
inline: false,
|
||||
visible: true,
|
||||
resolvePage: (pg) => {throw "a"}
|
||||
},
|
||||
conditional_button_6: {
|
||||
// Button Label
|
||||
label: "Conditional",
|
||||
// Next to pagination or new row
|
||||
inline: false,
|
||||
visible: true,
|
||||
resolvePage: (pg) => {throw "a"}
|
||||
},
|
||||
conditional_button_7: {
|
||||
// Button Label
|
||||
label: "Conditional",
|
||||
// Next to pagination or new row
|
||||
inline: false,
|
||||
visible: true,
|
||||
resolvePage: (pg) => {throw "a"}
|
||||
},
|
||||
}
|
||||
}
|
||||
})
|
||||
}catch(e){
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
const { anime, animeSupplemental} = require('#api');
|
||||
const { PERMISSION_GROUPS, OMNI_ANIME_FORMAT_TYPES, COLORS_HEX} = require('#constants');
|
||||
|
||||
const { createDynamicCardStack } = require("#cardstack");
|
||||
const { createDynamicCardStack, CARD_STACK_CONSTANTS } = require("#cardstack");
|
||||
|
||||
const { hexToDecimalColor } = require("#utils/color");
|
||||
const { createEmbed, formatPaginationEmbeds, page } = require('#utils/embed');
|
||||
const { createEmbed, page } = require('#utils/embed');
|
||||
const { acknowledge } = require('#utils/interactions');
|
||||
const { smallPill, link, pill, stringwrapPreserveWords, timestamp, TIMESTAMP_FLAGS} = require('#utils/markdown');
|
||||
const { editOrReply } = require('#utils/message');
|
||||
|
@ -106,7 +106,7 @@ module.exports = {
|
|||
if(!pages.length) return editOrReply(context, createEmbed("warning", context, `No results found.`))
|
||||
|
||||
createDynamicCardStack(context, {
|
||||
cards: formatPaginationEmbeds(pages),
|
||||
cards: pages,
|
||||
interactive: {
|
||||
episodes_button: {
|
||||
label: "Episodes",
|
||||
|
@ -152,7 +152,15 @@ module.exports = {
|
|||
return page(card)
|
||||
})
|
||||
|
||||
return formatPaginationEmbeds(cards);
|
||||
return {
|
||||
type: CARD_STACK_CONSTANTS.RESOLVE_CALLBACK_TYPES.SUBSTACK,
|
||||
cards: cards.length >= 1 ? cards : [
|
||||
// This happens if the episode metadata resolver fails.
|
||||
page(createEmbed("defaultNoFooter", context, {
|
||||
description: `-# ${pg.getState("name")} › **Episodes**\n## Episodes Unavailable\n\nWe're unable to display episode details for this content.`
|
||||
}))
|
||||
],
|
||||
};
|
||||
}
|
||||
},
|
||||
characters_button: {
|
||||
|
@ -190,7 +198,10 @@ module.exports = {
|
|||
return page(card)
|
||||
})
|
||||
|
||||
return formatPaginationEmbeds(cards);
|
||||
return {
|
||||
type: CARD_STACK_CONSTANTS.RESOLVE_CALLBACK_TYPES.SUBSTACK,
|
||||
cards: cards
|
||||
};
|
||||
}
|
||||
},
|
||||
related_button: {
|
||||
|
@ -214,9 +225,12 @@ module.exports = {
|
|||
|
||||
let cards = episodes.response.body.relations.map((e) => renderAnimeResultsPage(context, e, false))
|
||||
|
||||
return formatPaginationEmbeds(cards);
|
||||
return {
|
||||
type: CARD_STACK_CONSTANTS.RESOLVE_CALLBACK_TYPES.SUBSTACK,
|
||||
cards: cards
|
||||
};
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
});
|
||||
}catch(e){
|
||||
|
|
33
labscore/cardstack/Constants.js
Normal file
33
labscore/cardstack/Constants.js
Normal file
|
@ -0,0 +1,33 @@
|
|||
|
||||
module.exports.BUILT_IN_BUTTON_TYPES = Object.freeze({
|
||||
NEXT_PAGE: "next",
|
||||
PREVIOUS_PAGE: "previous"
|
||||
})
|
||||
|
||||
module.exports.DEFAULT_BUTTON_ICON_MAPPINGS = Object.freeze({
|
||||
[this.BUILT_IN_BUTTON_TYPES.NEXT_PAGE]: "button_chevron_right",
|
||||
[this.BUILT_IN_BUTTON_TYPES.PREVIOUS_PAGE]: "button_chevron_left"
|
||||
});
|
||||
|
||||
module.exports.STACK_CACHE_KEYS = Object.freeze({
|
||||
RESULT_CARDS: 0
|
||||
})
|
||||
|
||||
/**
|
||||
* Callback Types for a Dynamic Card Stack
|
||||
* Component resolve.
|
||||
*
|
||||
* - `SUBSTACK` - Creates a "submenu" with a brand new cardstack
|
||||
* - `REPLACE_PARENT` - Replaces the parent card in the root stack
|
||||
* - This callback type will also unselect the button
|
||||
* - `REPLACE_ROOT_STACK` - Replaces the root stack
|
||||
* - This callback type will also unselect the button
|
||||
*/
|
||||
module.exports.RESOLVE_CALLBACK_TYPES = Object.freeze({
|
||||
SUBSTACK: 0,
|
||||
REPLACE_PARENT_CARD: 1,
|
||||
REPLACE_STACK: 2,
|
||||
0: "SUBSTACK",
|
||||
1: "REPLACE_PARENT_CARD",
|
||||
2: "REPLACE_STACK",
|
||||
})
|
|
@ -1,5 +1,5 @@
|
|||
const { createEmbed, page } = require("#utils/embed");
|
||||
const { iconAsEmojiObject, icon, link} = require("#utils/markdown");
|
||||
const { iconAsEmojiObject, icon, link, codeblock } = require("#utils/markdown");
|
||||
const { editOrReply } = require("#utils/message");
|
||||
const { STATIC_ASSETS } = require("#utils/statics");
|
||||
|
||||
|
@ -8,6 +8,7 @@ const { MessageComponentTypes, InteractionCallbackTypes } = require("detritus-cl
|
|||
const { Message } = require("detritus-client/lib/structures");
|
||||
const { ComponentContext, Components, ComponentActionRow} = require("detritus-client/lib/utils");
|
||||
const {DISCORD_INVITES} = require("#constants");
|
||||
const {DEFAULT_BUTTON_ICON_MAPPINGS, STACK_CACHE_KEYS, BUILT_IN_BUTTON_TYPES, RESOLVE_CALLBACK_TYPES} = require("./Constants");
|
||||
|
||||
/**
|
||||
* Stores all active card stacks
|
||||
|
@ -15,20 +16,6 @@ const {DISCORD_INVITES} = require("#constants");
|
|||
*/
|
||||
const activeStacks = new WeakMap();
|
||||
|
||||
const BUILT_IN_BUTTON_TYPES = Object.freeze({
|
||||
NEXT_PAGE: "next",
|
||||
PREVIOUS_PAGE: "previous"
|
||||
})
|
||||
|
||||
const DEFAULT_BUTTON_ICON_MAPPINGS = Object.freeze({
|
||||
[BUILT_IN_BUTTON_TYPES.NEXT_PAGE]: "button_chevron_right",
|
||||
[BUILT_IN_BUTTON_TYPES.PREVIOUS_PAGE]: "button_chevron_left"
|
||||
});
|
||||
|
||||
const STACK_CACHE_KEYS = Object.freeze({
|
||||
RESULT_CARDS: 0
|
||||
})
|
||||
|
||||
/**
|
||||
* DynamicCardStack represents an interactive stacks
|
||||
* of cards (embeds) for the user to paginate through
|
||||
|
@ -39,13 +26,15 @@ class DynamicCardStack {
|
|||
* Creates a new DynamicCardStack
|
||||
* @param {Context} context Context
|
||||
* @param {Object} options DynamicCardStack Arguments
|
||||
* @param {Array<string>} options.buttons CardStack built-in navigation buttons
|
||||
* @param {Array} options.cards Baseline CardStack
|
||||
* @param {Array<string>} options.buttons Card Stack built-in navigation buttons
|
||||
* @param {Array} options.cards Root Card Stack
|
||||
* @param {Object} options.interactive Interactive Components
|
||||
* @param {Number} options.startingIndex Starting card index
|
||||
* @param {boolean} options.loop Wrap paging
|
||||
* @param {number} options.expires CardStack timeout
|
||||
* @param {number} options.expires Timeout for the Card Stack listener.
|
||||
* @param {boolean} options.disableStackCache Allows disabling the stack result cache, meaning that every trigger will reevaluate a stack
|
||||
* @param {boolean} options.pageNumbers Renders Page Numbers in the footer of all embeds in cards.
|
||||
* @param {Function} options.pageNumberGenerator Function that renders a page number. Default style is `Page <index>/<total>`
|
||||
*/
|
||||
constructor(context, options){
|
||||
this.context = context;
|
||||
|
@ -54,9 +43,12 @@ class DynamicCardStack {
|
|||
this.buttons = options.buttons || ["previous","next"]
|
||||
this.interactive_components = options.interactive || {};
|
||||
this.index = options.startingIndex || 0;
|
||||
this.rootIndex = this.index;
|
||||
this.loopPages = options.loop || true;
|
||||
this.expires = options.expires || 5*60*1000;
|
||||
this.pageNumbers = options.pageNumbers || true;
|
||||
this.pageNumberGenerator = options.pageNumberGenerator || ((pg)=>`Page ${pg.index + 1}/${pg.activeCardStack.length}`);
|
||||
|
||||
this.rootIndex = this.index;
|
||||
|
||||
this.stackCache = {};
|
||||
this.pageState = [];
|
||||
|
@ -138,15 +130,7 @@ class DynamicCardStack {
|
|||
|
||||
this.activeCardStack = [...this.cards];
|
||||
|
||||
// Resolve page state for all
|
||||
// root pages.
|
||||
let i = 0;
|
||||
for(const ac of this.cards){
|
||||
if(ac["_meta"]){
|
||||
this.pageState[i] = Object.assign({}, ac["_meta"]);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
this.updatePageState()
|
||||
|
||||
// Create internal component listener
|
||||
this.listener = new Components({
|
||||
|
@ -170,6 +154,20 @@ class DynamicCardStack {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves page state for all root stack cards.
|
||||
*/
|
||||
updatePageState(){
|
||||
let i = 0;
|
||||
this.pageState = [];
|
||||
for(const ac of this.cards){
|
||||
if(ac["_meta"]){
|
||||
this.pageState[i] = Object.assign({}, ac["_meta"]);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a card from the currently active
|
||||
* stack by its index
|
||||
|
@ -177,11 +175,46 @@ class DynamicCardStack {
|
|||
* @returns {*}
|
||||
*/
|
||||
getCardByIndex(index){
|
||||
// TODO: remove this some time after launch
|
||||
let card = Object.assign({}, this.activeCardStack[index])
|
||||
if(!card.content) card.content = "";
|
||||
card.content += `\n-# ${icon("flask_mini")} You are using the new page system • Leave feedback or report bugs in our ${link(DISCORD_INVITES.feedback_cardstack, "Discord Server", "labsCore Support", false)}!`
|
||||
return card;
|
||||
try{
|
||||
// TODO: remove this some time after launch
|
||||
let card = structuredClone(this.activeCardStack[index]);
|
||||
|
||||
// This creates an error card with debug information
|
||||
// in case that our activeCardStack gets corrupted
|
||||
// or lost somehow (bad implementation)
|
||||
if(!this.activeCardStack[index]) card = page(createEmbed("errordetail", this.context, {
|
||||
error: "Unable to resolve card.",
|
||||
content: `Index: \`${this.index}\`, Stack Size: \`${this.index}\`\n` +
|
||||
(Object.keys(this.getAllStateForPage(this.index)).length >= 1 ?
|
||||
codeblock("json", [JSON.stringify(this.getAllStateForPage(this.index), null, 2)]).substr(0, 5000) : "")
|
||||
}))
|
||||
|
||||
if(!card.content) card.content = "";
|
||||
card.content += `\n-# ${icon("flask_mini")} You are using the new page system • Leave feedback or report bugs in our ${link(DISCORD_INVITES.feedback_cardstack, "Discord Server", "labsCore Support", false)}!`
|
||||
|
||||
// Render Page Numbers.
|
||||
// Conditions:
|
||||
// - We have more than one card in the active stack
|
||||
// - We have embeds in the stack
|
||||
if(this.pageNumbers && card.embeds?.length && this.activeCardStack.length >= 2){
|
||||
card.embeds = card.embeds.map((e)=>{
|
||||
if(!e.footer) e.footer = { text: this.pageNumberGenerator(this) }
|
||||
else {
|
||||
if(e.footer.text) e.footer.text += ` • ${this.pageNumberGenerator(this)}`;
|
||||
else e.footer.text = this.pageNumberGenerator(this);
|
||||
}
|
||||
return e;
|
||||
})
|
||||
}
|
||||
|
||||
return card;
|
||||
}catch(e){
|
||||
console.log(e)
|
||||
return page(createEmbed("errordetail", this.context, {
|
||||
error: "Unable to render card:",
|
||||
content: codeblock("js",[(e ? e.stack || e.message : e).replaceAll(process.cwd(), '')])
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -270,6 +303,16 @@ class DynamicCardStack {
|
|||
return this.pageState;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all state for a specific page.
|
||||
* Only really intended for debugging purposes.
|
||||
* @returns {Object}
|
||||
*/
|
||||
getAllStateForPage(index){
|
||||
return this.pageState[index] || {};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Renders components and button states
|
||||
*/
|
||||
|
@ -433,8 +476,7 @@ class DynamicCardStack {
|
|||
}
|
||||
else this.currentSelectedSubcategory = ctx.data.customId;
|
||||
|
||||
// Reset page index so the new stack starts on page 0
|
||||
this.index = 0;
|
||||
let resolveTime = Date.now();
|
||||
|
||||
try{
|
||||
// If we have a cached result, retrieve it
|
||||
|
@ -472,28 +514,82 @@ class DynamicCardStack {
|
|||
}
|
||||
|
||||
// Compute the active cardstack.
|
||||
this.activeCardStack = await this.interactive_components[ctx.data.customId].resolvePage(this);
|
||||
let resolvedNewStack = await this.interactive_components[ctx.data.customId].resolvePage(this);
|
||||
|
||||
// TODO: this needs several modes/callback types.
|
||||
// SUBSTACK - Creates a "submenu" with a brand new cardstack
|
||||
// REPLACE_PARENT - Replaces the parent card in the root stack
|
||||
// REPLACE_ROOT_STACK - Replaces the root stack
|
||||
if(!Object.values(RESOLVE_CALLBACK_TYPES).includes(resolvedNewStack.type))
|
||||
throw new Error(`Invalid Stack Resolve Type (${resolvedNewStack.type})`);
|
||||
|
||||
// Cache the computed cardstack for future accessing.
|
||||
// The cache can be disabled/bypassed if we either
|
||||
// a) have really big/complex results
|
||||
// b) want to ensure data is always fresh
|
||||
if(!this.interactive_components[ctx.data.customId].disableCache){
|
||||
this._setCachedValue(this.rootIndex, ctx.data.customId, STACK_CACHE_KEYS.RESULT_CARDS, [...this.activeCardStack]);
|
||||
switch(resolvedNewStack.type){
|
||||
/**
|
||||
* SUBSTACK
|
||||
*
|
||||
* Replace the currently active paging
|
||||
* with a new, separate card stack to
|
||||
* page through.
|
||||
*/
|
||||
case RESOLVE_CALLBACK_TYPES.SUBSTACK:
|
||||
this.activeCardStack = resolvedNewStack.cards;
|
||||
this.index = resolvedNewStack.index || 0;
|
||||
|
||||
// Cache the computed cardstack for future accessing.
|
||||
// The cache can be disabled/bypassed if we either
|
||||
// a) have really big/complex results
|
||||
// b) want to ensure data is always fresh
|
||||
|
||||
// We currently only cache SUBSTACK responses, as the other
|
||||
// types probably need revalidating/refetching since the parent
|
||||
// has changed and might carry new data.
|
||||
if(!this.interactive_components[ctx.data.customId].disableCache){
|
||||
this._setCachedValue(this.rootIndex, ctx.data.customId, STACK_CACHE_KEYS.RESULT_CARDS, [...this.activeCardStack]);
|
||||
}
|
||||
break;
|
||||
/**
|
||||
* REPLACE_PARENT_CARD
|
||||
*
|
||||
* Replaces the parent card (the one this action
|
||||
* was initiated from) with a new one.
|
||||
*
|
||||
* Re-resolves all page state.
|
||||
* Unselects the button.
|
||||
*/
|
||||
case RESOLVE_CALLBACK_TYPES.REPLACE_PARENT_CARD:
|
||||
this.cards[this.rootIndex] = resolvedNewStack.card;
|
||||
this.activeCardStack = [...this.cards];
|
||||
this.updatePageState();
|
||||
this.index = resolvedNewStack.index || this.rootIndex;
|
||||
this.currentSelectedSubcategory = null;
|
||||
break;
|
||||
/**
|
||||
* REPLACE_STACK
|
||||
*
|
||||
* Replaces the entire parent
|
||||
* card stack with a new set.
|
||||
*
|
||||
* Re-resolves all page state.
|
||||
* Unselects the button.
|
||||
*/
|
||||
case RESOLVE_CALLBACK_TYPES.REPLACE_STACK:
|
||||
this.activeCardStack = resolvedNewStack.cards;
|
||||
this.updatePageState();
|
||||
this.index = resolvedNewStack.index || this.rootIndex;
|
||||
this.currentSelectedSubcategory = null;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
} catch(e){
|
||||
this.activeCardStack = [
|
||||
page(createEmbed("error", ctx, "Stack rendering failed."))
|
||||
]
|
||||
// Display an error if we're NOT
|
||||
// in the root stack (that would break
|
||||
// things badly).
|
||||
if(this.currentSelectedSubcategory != null)
|
||||
this.activeCardStack = [
|
||||
page(createEmbed("errordetail", ctx, {
|
||||
error: "Card stack rendering failed.",
|
||||
content: codeblock("js",[(e ? e.stack || e.message : e).replaceAll(process.cwd(), '')])
|
||||
}))
|
||||
]
|
||||
console.log("resolve failed:")
|
||||
console.log(e)
|
||||
// TODO: better errors maybe?
|
||||
}
|
||||
|
||||
// Update the card stack with a card from the new stack.
|
||||
|
@ -503,9 +599,20 @@ class DynamicCardStack {
|
|||
data: Object.assign(this.getCurrentCard(), { components: this._renderComponents()})
|
||||
})
|
||||
} else {
|
||||
setTimeout(()=>{
|
||||
return this._edit(Object.assign(this.getCurrentCard(), {components:this._renderComponents()}))
|
||||
}, 1500)
|
||||
// This timeout exists 1. for cosmetic reasons so people can
|
||||
// see the skeleton state and 2. in order to avoid a really
|
||||
// annoying race condition with the media proxy reverting our
|
||||
// embed to a prior state.
|
||||
|
||||
// If we've already waited at least 2 seconds during processing
|
||||
// it *should* be safe to just edit the message now.
|
||||
if((Date.now() - resolveTime) < 2000){
|
||||
setTimeout(()=>{
|
||||
return this._edit(Object.assign(this.getCurrentCard(), {components:this._renderComponents()}))
|
||||
}, 1500)
|
||||
} else {
|
||||
await this._edit(Object.assign(this.getCurrentCard(), {components:this._renderComponents()}))
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
|
|
|
@ -3,5 +3,6 @@ const { DynamicCardStack } = require("./DynamicCardStack");
|
|||
module.exports = {
|
||||
createDynamicCardStack: (context, options)=>{
|
||||
return new DynamicCardStack(context, options)
|
||||
}
|
||||
},
|
||||
CARD_STACK_CONSTANTS: require("./constants"),
|
||||
}
|
|
@ -148,6 +148,12 @@ module.exports.createEmbed = function(type, context, content){
|
|||
}
|
||||
|
||||
// Adds formatted page numbers to the embed footer
|
||||
/**
|
||||
* Formats embeds for pagination.
|
||||
* @deprecated No longer necessary in DynamicCardStack.
|
||||
* @param embeds Array of Messages
|
||||
* @returns {Embed[]}
|
||||
*/
|
||||
module.exports.formatPaginationEmbeds = function(embeds){
|
||||
// No formatting if we only have one page
|
||||
if(embeds.length == 1) return embeds;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue