diff --git a/commands/message/core/help.js b/commands/message/core/help.js index 4398769..5ed075a 100644 --- a/commands/message/core/help.js +++ b/commands/message/core/help.js @@ -22,11 +22,6 @@ const categories = { "dev": `${icon("analytics")} Development` } -const reactions = { - previousPage: "⬅️", - nextPage: "➡️" -}; - module.exports = { name: 'help', label: 'command', @@ -58,10 +53,9 @@ module.exports = { pages = formatPaginationEmbeds(pages) const message = context.message - const paging = await paginator.createReactionPaginator({ + const paging = await paginator.createPaginator({ message, - pages, - reactions + pages }); } }, diff --git a/commands/message/dev/debug/page.js b/commands/message/dev/debug/page.js index 6b576aa..bfce9ca 100644 --- a/commands/message/dev/debug/page.js +++ b/commands/message/dev/debug/page.js @@ -1,11 +1,6 @@ const { Constants } = require('detritus-client'); const { paginator } = require('../../../../labscore/client'); -const reactions = { - previousPage: "⬅️", - nextPage: "➡️" -}; - const createEmbedMessage = (title, description) => ({ embeds: [{ title, description }] }); @@ -25,13 +20,11 @@ module.exports = { createEmbedMessage("Page2", "eee"), createEmbedMessage("Page 3", "h") ] - const paging = await paginator.createReactionPaginator({ + const paging = await paginator.createPaginator({ // message is the message the user has sent message, // pages is an array of pages (will be passed as parameter in Message#edit) - pages, - // reactions is an object that includes `previousPage` and `nextPage` emojis (defined above) - reactions + pages }); }, }; \ No newline at end of file diff --git a/commands/message/search/bing-images.js b/commands/message/search/bing-images.js index 3ebf696..6aaa239 100644 --- a/commands/message/search/bing-images.js +++ b/commands/message/search/bing-images.js @@ -25,11 +25,6 @@ function createImageResultPage(context, result){ return res; } -const reactions = { - previousPage: "⬅️", - nextPage: "➡️" -}; - module.exports = { name: 'bingimage', label: 'query', @@ -54,10 +49,9 @@ module.exports = { pages = formatPaginationEmbeds(pages) const message = context.message - const paging = await paginator.createReactionPaginator({ + const paging = await paginator.createPaginator({ message, - pages, - reactions + pages }); }catch(e){ console.log(e) diff --git a/commands/message/search/bing.js b/commands/message/search/bing.js index 3ba8d77..dd60bc1 100644 --- a/commands/message/search/bing.js +++ b/commands/message/search/bing.js @@ -21,11 +21,6 @@ function createSearchResultPage(context, result){ return res; } -const reactions = { - previousPage: "⬅️", - nextPage: "➡️" -}; - module.exports = { name: 'bing', label: 'query', @@ -50,10 +45,9 @@ module.exports = { pages = formatPaginationEmbeds(pages) const message = context.message - const paging = await paginator.createReactionPaginator({ + const paging = await paginator.createPaginator({ message, - pages, - reactions + pages }); }catch(e){ console.log(e) diff --git a/commands/message/search/google-images.js b/commands/message/search/google-images.js index 2a329db..72d8370 100644 --- a/commands/message/search/google-images.js +++ b/commands/message/search/google-images.js @@ -25,11 +25,6 @@ function createImageResultPage(context, result){ return res; } -const reactions = { - previousPage: "⬅️", - nextPage: "➡️" -}; - module.exports = { name: 'image', label: 'query', @@ -54,10 +49,9 @@ module.exports = { pages = formatPaginationEmbeds(pages) const message = context.message - const paging = await paginator.createReactionPaginator({ + const paging = await paginator.createPaginator({ message, - pages, - reactions + pages }); }catch(e){ console.log(e) diff --git a/commands/message/search/google.js b/commands/message/search/google.js index 9203647..684d35b 100644 --- a/commands/message/search/google.js +++ b/commands/message/search/google.js @@ -22,11 +22,6 @@ function createSearchResultPage(context, result){ return res; } -const reactions = { - previousPage: "⬅️", - nextPage: "➡️" -}; - module.exports = { name: 'google', label: 'query', @@ -51,10 +46,9 @@ module.exports = { pages = formatPaginationEmbeds(pages) const message = context.message - const paging = await paginator.createReactionPaginator({ + const paging = await paginator.createPaginator({ message, - pages, - reactions + pages }); }catch(e){ console.log(e) diff --git a/commands/message/search/lyrics.js b/commands/message/search/lyrics.js index 22b1fb7..be57736 100644 --- a/commands/message/search/lyrics.js +++ b/commands/message/search/lyrics.js @@ -5,11 +5,6 @@ const { STATICS } = require('../../../labscore/utils/statics') const { lyrics } = require('../../../labscore/api'); const { paginator } = require('../../../labscore/client'); -const reactions = { - previousPage: "⬅️", - nextPage: "➡️" -}; - function createLyricsPage(context, search, fields){ let em= createEmbed("default", context, { description: `**${search.body.song.title}**\n*Released ${search.body.song.release}*\n\n`, @@ -70,10 +65,9 @@ module.exports = { const message = context.message pages = formatPaginationEmbeds(pages) - const paging = await paginator.createReactionPaginator({ + const paging = await paginator.createPaginator({ message, - pages, - reactions + pages }); return; } diff --git a/commands/message/search/wolfram-alpha.js b/commands/message/search/wolfram-alpha.js index 7540ba5..4bc7bf2 100644 --- a/commands/message/search/wolfram-alpha.js +++ b/commands/message/search/wolfram-alpha.js @@ -23,11 +23,6 @@ function createWolframPage(context, pod){ return res; } -const reactions = { - previousPage: "⬅️", - nextPage: "➡️" -}; - module.exports = { name: 'wolframalpha', label: 'query', @@ -52,10 +47,9 @@ module.exports = { pages = formatPaginationEmbeds(pages) const message = context.message - const paging = await paginator.createReactionPaginator({ + const paging = await paginator.createPaginator({ message, - pages, - reactions + pages }); }catch(e){ console.log(e) diff --git a/labscore/client.js b/labscore/client.js index 161ad8c..03367a9 100644 --- a/labscore/client.js +++ b/labscore/client.js @@ -21,7 +21,7 @@ const cluster = new ClusterClient("", { // Create this clusters paginator const paginator = new Paginator(cluster, { - maxTime: 120000, + maxTime: 300000, pageLoop: true, pageNumber: true }); diff --git a/labscore/paginator/structures/BasePaginator.js b/labscore/paginator/structures/BasePaginator.js index 6825d90..fe84f92 100644 --- a/labscore/paginator/structures/BasePaginator.js +++ b/labscore/paginator/structures/BasePaginator.js @@ -11,9 +11,7 @@ module.exports = class BasePaginator extends EventEmitter { this.index = 0; this.targetUser = data.targetUser || this.message.author.id; - // Reference to reply function - // Uses context.editOrReply if an instance of Context was passed - // Defaults to message.reply + // TODO: use editOrReply, kill old paginator if it exists this.editOrReply = (data.message.editOrReply || data.message.reply).bind(data.message); } diff --git a/labscore/paginator/structures/InteractionPaginator.js b/labscore/paginator/structures/InteractionPaginator.js new file mode 100644 index 0000000..956f656 --- /dev/null +++ b/labscore/paginator/structures/InteractionPaginator.js @@ -0,0 +1,8 @@ +const BasePaginator = require("./BasePaginator"); + +module.exports = class InteractionPaginator extends BasePaginator { + constructor(client, data) { + super(client, data); + this.waitingForPage = null; + } +}; diff --git a/labscore/paginator/structures/Paginator.js b/labscore/paginator/structures/Paginator.js index 74ca6d4..c0fba10 100644 --- a/labscore/paginator/structures/Paginator.js +++ b/labscore/paginator/structures/Paginator.js @@ -1,4 +1,4 @@ -const ReactionPaginator = require("./ReactionPaginator"); +const InteractionPaginator = require("./InteractionPaginator"); const assert = require("assert"); const { Constants, Utils } = require('detritus-client') @@ -6,18 +6,19 @@ const { Components, ComponentActionRow } = Utils const { InteractionCallbackTypes } = Constants const allowedEvents = new Set([ - "MESSAGE_REACTION_ADD", - "MESSAGE_CREATE" + "MESSAGE_CREATE" ]); function deprecate(message) { - console.warn(`[detritus-pagination] Deprecation warning: ${message}`); + console.warn(`[detritus-pagination] Deprecation warning: ${message}`); } const ButtonEmoji = Object.freeze({ - NEXT: '<:right:977871577758707782>', - PREVIOUS: '<:left:977871577532211200>', - STOP: '<:ico_trash:929498022386221096>' + NEXT: '<:right:977871577758707782>', + PREVIOUS: '<:left:977871577532211200>', + STOP: '<:ico_trash:929498022386221096>', + // NEXT: '<:next_page:977894273376727050>', + // PREVIOUS: '<:previous_page:977894273443844167>' }) const { hasOwnProperty } = Object.prototype; @@ -27,179 +28,143 @@ const { hasOwnProperty } = Object.prototype; const instances = new WeakSet(); module.exports = class Paginator { - constructor(client, data = {}) { - if (instances.has(client)) { - deprecate("Avoid attaching multiple Paginators to the same client, as it can lead to memory leaks"); - } else { - instances.add(client); - } - - assert.ok( - hasOwnProperty.call(client, "gateway"), - "Provided `client` has no `gateway` property. Consider using `require('detritus-pagination').PaginatorCluster` if you're using CommandClient." - ); - - this.client = client; - this.maxTime = data.maxTime || 300000; - this.pageLoop = typeof data.pageLoop !== "boolean" ? false : data.pageLoop; - this.pageNumber = typeof data.pageNumber !== "boolean" ? false : data.pageNumber; - this.activeListeners = []; - - this.client.gateway.on("packet", async packet => { - const { - d: data, - t: event - } = packet; - if (!data) return; - if (!allowedEvents.has(event)) return; - - for (const listener of this.activeListeners) { - if (!(listener instanceof ReactionPaginator)) continue; - if (!listener.commandMessage) continue; - - if (listener.isCommandMessage(data.message_id) && - listener.isTarget(data.user_id)) { - await this.handleReactionEvent(data, listener); - } else if (event === "MESSAGE_CREATE" && - listener.isInChannel(data.channel_id) && - listener.isTarget(data.user_id) && - listener.waitingForPage) { - await this.handleMessageEvent(data, listener); - } - } - }); + constructor(client, data = {}) { + if (instances.has(client)) { + deprecate("Avoid attaching multiple Paginators to the same client, as it can lead to memory leaks"); + } else { + instances.add(client); } - async handleButtonEvent(context) { - // Get listener - let listener; - for (const l of this.activeListeners) { - if (!(l instanceof ReactionPaginator)) continue; - if (!l.commandMessage) continue; + assert.ok( + hasOwnProperty.call(client, "gateway"), + "Provided `client` has no `gateway` property. Consider using `require('detritus-pagination').PaginatorCluster` if you're using CommandClient." + ); - if (l.isCommandMessage(context.message.id)) { - listener = l - } - } + this.client = client; + this.maxTime = data.maxTime || 300000; + this.pageLoop = typeof data.pageLoop !== "boolean" ? false : data.pageLoop; + this.pageNumber = typeof data.pageNumber !== "boolean" ? false : data.pageNumber; + this.activeListeners = []; - if(!listener.isTarget(context.user.id)) { - await context.respond(InteractionCallbackTypes.DEFERRED_UPDATE_MESSAGE) - return; - } + this.client.gateway.on("packet", async packet => { + const { + d: data, + t: event + } = packet; + if (!data) return; + if (!allowedEvents.has(event)) return; - switch (context.customId) { - case "next": - //await context.respond(InteractionCallbackTypes.DEFERRED_UPDATE_MESSAGE) - //listener.next(); - await context.respond(InteractionCallbackTypes.UPDATE_MESSAGE, await listener.getNext()) - break; - case "previous": - await context.respond(InteractionCallbackTypes.UPDATE_MESSAGE, await listener.getPrevious()) - break; - case "stop": - await context.respond(InteractionCallbackTypes.DEFERRED_UPDATE_MESSAGE) - listener.stop(); - break; + for (const listener of this.activeListeners) { + if (!(listener instanceof InteractionPaginator)) continue; + if (!listener.commandMessage) continue; + + if (event === "MESSAGE_CREATE" && + listener.isInChannel(data.channel_id) && + listener.isTarget(data.user_id) && + listener.waitingForPage) { + await this.handleMessageEvent(data, listener); } + } + }); + } + + async handleButtonEvent(context) { + // Get listener + let listener; + for (const l of this.activeListeners) { + if (!(l instanceof InteractionPaginator)) continue; + if (!l.commandMessage) continue; + + if (l.isCommandMessage(context.message.id)) { + listener = l + } } - // TODO: Clean up legacy code from ReactionPaginator - - // Legacy - async handleReactionEvent(data, listener) { - switch (data.emoji.name) { - case listener.reactions.nextPage: - listener.next(); - break; - case listener.reactions.previousPage: - listener.previous(); - break; - case listener.reactions.firstPage: - listener.jumpTo(0); - break; - case listener.reactions.lastPage: - listener.jumpTo(listener.pages.length - 1); - break; - case listener.reactions.stop: - listener.stop(); - break; - case listener.reactions.skipTo: - if (listener.waitingForPage) return; - listener.waitingForPage = await this.client.rest.createMessage(data.channel_id, "What page do you want to go to?"); - break; - default: - if (!Object.values(listener.reactions).includes(data.emoji.name)) return; - } - - listener.emit("raw", data); - listener.clearReaction(data.emoji.name); + if (!listener.isTarget(context.user.id)) { + await context.respond(InteractionCallbackTypes.DEFERRED_UPDATE_MESSAGE) + return; } - async handleMessageEvent(data, listener) { - const page = parseInt(data.content, 10); - if (isNaN(page)) { - return; - } + switch (context.customId) { + case "next": + //await context.respond(InteractionCallbackTypes.DEFERRED_UPDATE_MESSAGE) + //listener.next(); + await context.respond(InteractionCallbackTypes.UPDATE_MESSAGE, await listener.getNext()) + break; + case "previous": + await context.respond(InteractionCallbackTypes.UPDATE_MESSAGE, await listener.getPrevious()) + break; + case "stop": + await context.respond(InteractionCallbackTypes.DEFERRED_UPDATE_MESSAGE) + listener.stop(); + break; + } + } - listener.jumpTo(page - 1) - .then(async () => { - try { - await listener.waitingForPage.delete(); - await this.client.rest.deleteMessage(data.channel_id, data.id); - } catch (e) { } - - listener.waitingForPage = null; - }).catch(() => { }); + async handleMessageEvent(data, listener) { + const page = parseInt(data.content, 10); + if (isNaN(page)) { + return; } - async components(listener) { - const components = new Components({ - timeout: this.expires, - run: this.handleButtonEvent.bind(this), - }); + listener.jumpTo(page - 1) + .then(async () => { + try { + await listener.waitingForPage.delete(); + await this.client.rest.deleteMessage(data.channel_id, data.id); + } catch (e) { } - components.createButton({ - customId: "previous", - disabled: 0, - style: 2, - emoji: ButtonEmoji.PREVIOUS - }); - components.createButton({ - customId: "next", - disabled: 0, - style: 2, - emoji: ButtonEmoji.NEXT - }); + listener.waitingForPage = null; + }).catch(() => { }); + } - //components.createButton({ - // customId: "stop", - // disabled: 0, - // style: 2, - // emoji: ButtonEmoji.STOP - //}); - return components; + async components(listener) { + const components = new Components({ + timeout: this.expires, + run: this.handleButtonEvent.bind(this), + }); + + components.createButton({ + customId: "previous", + disabled: 0, + style: 2, + emoji: ButtonEmoji.PREVIOUS + }); + components.createButton({ + customId: "next", + disabled: 0, + style: 2, + emoji: ButtonEmoji.NEXT + }); + + //components.createButton({ + // customId: "stop", + // disabled: 0, + // style: 2, + // emoji: ButtonEmoji.STOP + //}); + return components; + } + + async createPaginator(data) { + if (this.pageNumber && Array.isArray(data.pages)) { + for (let i = 0; i < data.pages.length; ++i) { + const element = data.pages[i]; + + } } - async createReactionPaginator(data) { - if (this.pageNumber && Array.isArray(data.pages)) { - for (let i = 0; i < data.pages.length; ++i) { - const element = data.pages[i]; + const instance = new InteractionPaginator(this, data); + this.activeListeners.push(instance); - } - } + setTimeout(() => { + instance.stop(true); + }, data.maxTime || this.maxTime); - const instance = new ReactionPaginator(this, data); - this.activeListeners.push(instance); - - setTimeout(() => { - instance.stop(true); - }, data.maxTime || this.maxTime); - - if (instance.commandMessage === null && data.pages) { - await instance.init(); - } - - //await instance.addReactions(); - return instance; + if (instance.commandMessage === null && data.pages) { + await instance.init(); } + + return instance; + } }; diff --git a/labscore/paginator/structures/PaginatorCluster.js b/labscore/paginator/structures/PaginatorCluster.js index f11d6f7..05d9624 100644 --- a/labscore/paginator/structures/PaginatorCluster.js +++ b/labscore/paginator/structures/PaginatorCluster.js @@ -3,35 +3,35 @@ const Paginator = require("./Paginator"); const assert = require("assert"); module.exports = class PaginatorCluster { - constructor(clusterClient, data = {}) { - assert.ok( - clusterClient instanceof ClusterClient, - "clusterClient must be an instance of ClusterClient" - ); + constructor(clusterClient, data = {}) { + assert.ok( + clusterClient instanceof ClusterClient, + "clusterClient must be an instance of ClusterClient" + ); - const paginators = new WeakMap(); + const paginators = new WeakMap(); - for (const [, client] of clusterClient.shards) { - paginators.set(client, new Paginator(client, data)); - } - - this.data = data; - this.paginators = paginators; + for (const [, client] of clusterClient.shards) { + paginators.set(client, new Paginator(client, data)); } - findOrSetPaginator(client) { - const cachedPaginator = this.paginators.get(client); - if (cachedPaginator) return cachedPaginator; + this.data = data; + this.paginators = paginators; + } - const paginator = new Paginator(client, this.data); - this.paginators.set(client, paginator); + findOrSetPaginator(client) { + const cachedPaginator = this.paginators.get(client); + if (cachedPaginator) return cachedPaginator; - return paginator; - } + const paginator = new Paginator(client, this.data); + this.paginators.set(client, paginator); - createReactionPaginator(data) { - const targetPaginator = this.findOrSetPaginator(data.message.client); + return paginator; + } - return targetPaginator.createReactionPaginator(data); - } + createPaginator(data) { + const targetPaginator = this.findOrSetPaginator(data.message.client); + + return targetPaginator.createPaginator(data); + } } \ No newline at end of file diff --git a/labscore/paginator/structures/ReactionPaginator.js b/labscore/paginator/structures/ReactionPaginator.js deleted file mode 100644 index a8a987c..0000000 --- a/labscore/paginator/structures/ReactionPaginator.js +++ /dev/null @@ -1,48 +0,0 @@ -const BasePaginator = require("./BasePaginator"); - -module.exports = class ReactionPaginator extends BasePaginator { - constructor(client, data) { - super(client, data); - this.waitingForPage = null; - this.reactions = data.reactions || { - firstPage: "⏮️", - previousPage: "⬅️", - nextPage: "➡️", - lastPage: "⏭️", - skipTo: "🔢", - stop: "⏹️" - }; - } - - async addReactions() { - if (!this.commandMessage) return; - - for (const reactions of Object.values(this.reactions)) { - if (this.isShared) { - for (const msg of this.commandMessage.values()) { - await msg.react(reactions).catch(); - } - } else { - await this.commandMessage.react(reactions).catch(() => {}); - } - } - } - - // TODO: this only works if cache is enabled - // perhaps add option to use REST API to fetch all reactions? - async clearReactions() { - const reactions = this.isShared ? Array.from(this.commandMessage.values()).map(x => Array.from(x.reactions.values())).flat() : this.commandMessage.reactions.values(); - - for (const reaction of reactions) { - this.clearReaction(reaction.emoji.name); - } - } - - async clearReaction(emoji) { - const reaction = this.commandMessage.reactions.find(x => x.emoji.name === emoji); - - if (reaction) { - reaction.delete(this.message.author.id).catch(() => {}); - } - } -}; diff --git a/package.json b/package.json index f92192b..f65aea8 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,6 @@ "license": "ISC", "dependencies": { "detritus-client": "^0.17.0-beta.12", - "detritus-pagination": "^1.4.0", "dotenv": "^16.0.1", "express": "^4.17.1", "superagent": "^7.1.1"