diff --git a/CustomModules/ButtonHandlers.js b/CustomModules/ButtonHandlers.js new file mode 100644 index 0000000..a9cfa6c --- /dev/null +++ b/CustomModules/ButtonHandlers.js @@ -0,0 +1,22 @@ +const customEmbeds = require('../CustomModules/Embeds.js'); + +module.exports = { + baseEvent(interaction) { + console.log(interaction.component.customId); + switch (interaction.component.customId) { + // Any of the gifsPage Buttons + case 'prevGifsPage' || 'nextGifsPage' : + break; + default: + return; + } + }, + gifsPage(interaction, gifs, page) { + switch (buttonId) { + case 'prevGifsPage': + return 'previous'; + case 'nextGifsPage': + return 'next'; + } + } +} \ No newline at end of file diff --git a/CustomModules/Embeds.js b/CustomModules/Embeds.js index 6335690..cc057da 100644 --- a/CustomModules/Embeds.js +++ b/CustomModules/Embeds.js @@ -1,5 +1,7 @@ +const { MessageActionRow, MessageButton } = require('discord.js'); + module.exports = { - gifSearchAR() { + gifSearchAR(state) { // Setup the buttons const previousButton = new MessageButton() .setCustomId('prevGif') @@ -21,6 +23,83 @@ module.exports = { .setLabel('❌') .setStyle('DANGER'); + switch (state) { + case 'first': + previousButton.setDisabled(true); + break; + case 'last': + nextButton.setDisabled(true); + break; + } + + // Put the buttons into an ActionRow + return new MessageActionRow() + .addComponents(previousButton, confirmButton, nextButton, cancelButton); + }, + gifsPageAR() { + // Setup the buttons + const previousButton = new MessageButton() + .setCustomId('prevGifsPage') + .setLabel('⬅️') + .setStyle('SECONDARY'); + + const nextButton = new MessageButton() + .setCustomId('nextGifsPage') + .setLabel('➡️') + .setStyle('SECONDARY'); + + // Put the buttons into an ActionRow + return new MessageActionRow() + .addComponents(previousButton, nextButton); + }, + requestsPageAR() { + // Setup the buttons + const previousButton = new MessageButton() + .setCustomId('prevRequestsPage') + .setLabel('⬅️') + .setStyle('SECONDARY'); + + const confirmButton = new MessageButton() + .setCustomId('confirmRequestsPage') + .setLabel('✅') + .setStyle('PRIMARY'); + + const nextButton = new MessageButton() + .setCustomId('nextRequestsPage') + .setLabel('➡️') + .setStyle('SECONDARY'); + + const cancelButton = new MessageButton() + .setCustomId('cancelRequestsPage') + .setLabel('❌') + .setStyle('DANGER'); + + // Put the buttons into an ActionRow + return new MessageActionRow() + .addComponents(previousButton, confirmButton, nextButton, cancelButton); + }, + pastasPageAR() { + // Setup the buttons + const previousButton = new MessageButton() + .setCustomId('prevPastasPage') + .setLabel('⬅️') + .setStyle('SECONDARY'); + + const confirmButton = new MessageButton() + .setCustomId('confirmPastasPage') + .setLabel('✅') + .setStyle('PRIMARY'); + + const nextButton = new MessageButton() + .setCustomId('nextPastasPage') + .setLabel('➡️') + .setStyle('SECONDARY'); + + const cancelButton = new MessageButton() + .setCustomId('cancelPastasPage') + .setLabel('❌') + .setStyle('DANGER'); + // Put the buttons into an ActionRow return new MessageActionRow() .addComponents(previousButton, confirmButton, nextButton, cancelButton); diff --git a/CustomModules/Indexer.js b/CustomModules/Indexer.js new file mode 100644 index 0000000..8a3960f --- /dev/null +++ b/CustomModules/Indexer.js @@ -0,0 +1,31 @@ +module.exports = (collection, page) => { + const itemsPerPage = 10; + const index = page * itemsPerPage; + const totalPages = Math.ceil(collection.size / itemsPerPage); + let state = page === 0 ? 'first' : 'middle'; + + const thisPage = new Array(); + + // Map the Djs Collection to an Array + const collectionArray = collection.map((command) => command); + + for (let i = index; i < index + itemsPerPage; i++) { + if (collectionArray[i]) { + thisPage.push(collectionArray[i]); + } else { + state = 'last'; + break; + } + + if (i === collectionArray.size - 1) { + state = 'last'; + break; + } + } + + return { + state: state, + thisPage: thisPage, + pages: `Page ${page + 1}/${totalPages}` + }; +} \ No newline at end of file diff --git a/CustomModules/InteractionStorage.js b/CustomModules/InteractionStorage.js new file mode 100644 index 0000000..d5cf06a --- /dev/null +++ b/CustomModules/InteractionStorage.js @@ -0,0 +1,15 @@ +module.exports = class InteractionStorage { + constructor(idString, interaction) { + this.idString = idString; + + // Store in the client + interaction.client.iStorage.set(idString, this); + + // Delete this from the interactionStorage after 5 minutes + setTimeout(() => { + interaction.client.iStorage.delete(idString); + }, 300000); + + return this; + } +} \ No newline at end of file diff --git a/CustomModules/NodBot.js b/CustomModules/NodBot.js index 2d2ed16..d18c21b 100644 --- a/CustomModules/NodBot.js +++ b/CustomModules/NodBot.js @@ -26,8 +26,6 @@ module.exports = { return this; } } - - this.isValid = validCommands.includes(this.command); return this; } }, diff --git a/functions.js b/functions.js index 608848d..15a5e5a 100644 --- a/functions.js +++ b/functions.js @@ -1,7 +1,6 @@ /* eslint-disable comma-dangle */ // dotenv for handling environment variables -const dotenv = require('dotenv'); -dotenv.config(); +const dotenv = require('dotenv').config(); // Assignment of environment variables for database access const dbHost = process.env.dbHost; const dbUser = process.env.dbUser; @@ -9,7 +8,6 @@ const dbName = process.env.dbName; const dbPass = process.env.dbPass; const dbPort = process.env.dbPort; const isDev = process.env.isDev; - const ownerId = process.env.ownerId; // filesystem @@ -22,10 +20,6 @@ const Discord = require('discord.js'); // Fuzzy text matching for db lookups const FuzzySearch = require('fuzzy-search'); -// OpenAI -// const OpenAI = require("openai"); -// const openai = new OpenAI(); - // Axios for APIs const axios = require('axios'); @@ -34,7 +28,7 @@ const config = require('./config.json'); const strings = require('./strings.json'); const slashCommandFiles = fs.readdirSync('./slash-commands/').filter(file => file.endsWith('.js')); const dotCommandFiles = fs.readdirSync('./dot-commands/').filter(file => file.endsWith('.js')); -const { CommandData } = require('./CustomModules/NodBot.js'); +const customEmbeds = require('./CustomModules/Embeds.js'); // MySQL database connection const mysql = require('mysql'); @@ -51,6 +45,11 @@ const db = new mysql.createPool({ const functions = { // Functions for managing and creating Collections collections: { + interactionStorage(client) { + if (!client.iStorage) client.iStorage = new Discord.Collection(); + client.iStorage.clear(); + if (isDev) console.log('Interaction Storage Collection Built'); + } // Create the collection of slash commands slashCommands(client) { if (!client.slashCommands) client.slashCommands = new Discord.Collection(); @@ -268,14 +267,15 @@ const functions = { return { embeds: [pastasEmbed], ephemeral: true }; }, - gifs(commandData, gifList) { + gifs(commandData, gifsString, state) { const gifsEmbed = new Discord.MessageEmbed() .setAuthor({name: commandData.command}) .setTimestamp() .setFooter({text: commandData.author}) - .setDescription(gifList.join('\n')); + .setDescription(gifsString); - return { embeds: [gifsEmbed] }; + const gifsPageAR = customEmbeds.gifsPageAR(state); + return { embeds: [gifsEmbed], components: [gifsPageAR], ephemeral: true }; }, text(commandData) { return { embeds: [new Discord.MessageEmbed() diff --git a/main.js b/main.js index 2493676..304c7be 100644 --- a/main.js +++ b/main.js @@ -28,9 +28,12 @@ const fn = require('./functions.js'); const config = require('./config.json'); const strings = require('./strings.json'); const { GifData, CommandData } = require('./CustomModules/NodBot.js'); +const ButtonHandlers = require('./CustomModules/ButtonHandlers.js'); +const InteractionStorage = require('./CustomModules/InteractionStorage.js'); const isDev = process.env.isDev; client.once('ready', async () => { + fn.collections.interactionStorage(client); fn.collections.slashCommands(client); fn.collections.dotCommands(client); fn.collections.setvalidCommands(client); @@ -58,6 +61,12 @@ client.on('interactionCreate', async interaction => { } const { commandName } = interaction; + const idString = `${interaction.channelId}${interaction.member.id}`; + + if (!client.interactionStorage.has(idString)) { + new InteractionStorage(idString, interaction); + } + if (client.slashCommands.has(commandName)) { client.slashCommands.get(commandName).execute(interaction); } else { @@ -67,7 +76,7 @@ client.on('interactionCreate', async interaction => { } if (interaction.isButton()) { - if (interaction.user.id != strings.temp.gifUserId) return; + if (isDev) console.log(interaction.id); // Get some meta info from strings const index = strings.temp.gifIndex; const limit = strings.temp.gifLimit; @@ -176,6 +185,7 @@ client.on('interactionCreate', async interaction => { interaction.update({ content: 'Canceled.', components: [row] }); break; default: + ButtonHandlers.baseEvent(interaction); break; } } diff --git a/slash-commands/gifs.js b/slash-commands/gifs.js index 0409968..00a30f0 100644 --- a/slash-commands/gifs.js +++ b/slash-commands/gifs.js @@ -1,36 +1,29 @@ const { SlashCommandBuilder } = require('@discordjs/builders'); const { config } = require('dotenv'); const fn = require('../functions.js'); +const indexer = require('../CustomModules/Indexer.js'); module.exports = { data: new SlashCommandBuilder() .setName('gifs') .setDescription('Get a list of currently saved GIFs.'), - async execute(interaction) { - if (!interaction.client.gifs) { - interaction.reply('For some reason I don\'t have access to the collection of gifs. Sorry about that!'); - return; - } - // const gifsMap = interaction.client.gifs.map(e => {e.name, e.url}); - // const commandData = { - // gifs: [], - // command: 'gifs', - // author: interaction.user.tag, - // }; - // for (const row of gifsMap) { - // commandData.gifs.push({ - // id: row.id, - // name: row.name, - // }); - // } - let gifList = []; - interaction.client.gifs.forEach(element => { - gifList.push(`[${element.name}](${element.url})`); + execute(interaction) { + return new Promise((resolve, reject) => { + if (!interaction.client.gifs) { + interaction.reply('For some reason I don\'t have access to the collection of gifs. Sorry about that!'); + resolve(); + } + let gifList = indexer(interaction.client.gifs, 0); + let gifsString = new String(); + + for (const gif of gifList.thisPage) { + gifsString += `[${gif.name}.gif](${gif.url})\n`; + } + const commandData = { + command: "/gifs", + author: interaction.member.displayName + }; + interaction.reply(fn.embeds.gifs(commandData, gifsString, gifList.state)); }); - const commandData = { - command: "/gifs", - author: interaction.member.displayName - }; - interaction.reply(fn.embeds.gifs(commandData, gifList)); }, }; \ No newline at end of file