Compare commits

...

4 Commits

Author SHA1 Message Date
3def31b0fb Moved all button handling to ButtonHandlers.js and cleaned up /save gifSearch
All checks were successful
NodBot Production Dockerization / build (pull_request) Successful in 18s
2024-09-26 19:30:41 -04:00
b536ebda5b Add ability to handle pages of different length, defaulting to 10 2024-09-26 19:30:01 -04:00
6175a30974 Add PR tag # 2024-09-26 14:28:11 -04:00
8d5f75e471 Add nested commands 2024-09-26 14:25:22 -04:00
7 changed files with 181 additions and 204 deletions

View File

@ -1,3 +1,7 @@
## v3.4.x
#### v3.4.0 (#25)
* Added nested commands, enclose a command in brackets, braces, or parenthesis inside a longer message: `You really don't get it do you? [that's the joke.gif] You're so dense` would return the results for just `that's the joke.gif`
## v3.3.x ## v3.3.x
#### v3.3.3 (#20) #### v3.3.3 (#20)
* Fixed content-list slash commands `/gifs`, `/pastas`, `/joints`, `/requests` (#19) * Fixed content-list slash commands `/gifs`, `/pastas`, `/joints`, `/requests` (#19)

View File

@ -3,6 +3,7 @@ const InteractionStorage = require('../CustomModules/InteractionStorage.js');
const indexer = require('../CustomModules/Indexer.js'); const indexer = require('../CustomModules/Indexer.js');
const fn = require('../functions.js'); const fn = require('../functions.js');
const requests = require('../slash-commands/requests.js'); const requests = require('../slash-commands/requests.js');
const { GifData } = require('./NodBot.js');
module.exports = { module.exports = {
baseEvent(interaction) { baseEvent(interaction) {
@ -40,6 +41,18 @@ module.exports = {
case 'nextJointsPage': case 'nextJointsPage':
module.exports.jointsPage(interaction); module.exports.jointsPage(interaction);
break; break;
case 'prevGif':
module.exports.gifSearchPage(interaction);
break;
case 'nextGif':
module.exports.gifSearchPage(interaction);
break;
case 'confirmGif':
module.exports.gifSearchPage(interaction);
break;
case 'cancelGif':
module.exports.gifSearchPage(interaction);
break;
default: default:
return; return;
} }
@ -147,5 +160,45 @@ module.exports = {
} }
interaction.update(fn.embeds.joints({command: "/joints", author: interaction.member.displayName}, indexedJoints)); interaction.update(fn.embeds.joints({command: "/joints", author: interaction.member.displayName}, indexedJoints));
},
gifSearchPage(interaction) {
const iStorage = interaction.client.iStorage.get(interaction.message.interaction.id);
switch (interaction.component.customId) {
case 'prevGif':
if (iStorage.page > 0) {
iStorage.page = iStorage.page - 1;
}
break;
case 'nextGif':
if (iStorage.page < interaction.client.gifs.size / 10) {
iStorage.page = iStorage.page + 1;
}
break;
case 'confirmGif':
const gif = indexer(iStorage.gifsCollection, iStorage.page, 1).thisPage[0];
const gifData = new GifData().setInfo(iStorage.gifName, gif.media_formats.gif.url, gif.id);
fn.upload.gif(gifData, interaction.client);
interaction.update({ content: `I've saved the GIF as ${gifData.name}.gif`, components: [] });
fn.download.gifs(interaction.client);
return;
break;
case 'cancelGif':
interaction.update({ content: 'The GIF has been discarded.', components: [], embeds: [] });
return;
break;
default:
break;
}
// Generate the action row
const gifSearchAR = customEmbeds.actionRows.gifSearchAR(iStorage.state);
// Update the index
const indexedGifs = indexer(iStorage.gifsCollection, iStorage.page, 1);
indexedGifs.query = iStorage.query;
indexedGifs.gifName = iStorage.gifName;
// Generate the embed
const gifEmbed = customEmbeds.core.gifSearch({ author: interaction.member.displayName }, indexedGifs);
// Update the interaction
interaction.update({ embeds: [gifEmbed], components: [gifSearchAR], ephemeral: true });
} }
} }

View File

@ -1,139 +1,154 @@
const { MessageActionRow, MessageButton } = require('discord.js'); const { MessageActionRow, MessageButton, MessageEmbed } = require('discord.js');
module.exports = { module.exports = {
gifSearchAR(state) { actionRows: {
// Setup the buttons gifSearchAR(state) {
const previousButton = new MessageButton() // Setup the buttons
const previousButton = new MessageButton()
.setCustomId('prevGif') .setCustomId('prevGif')
.setLabel('⬅️') .setLabel('⬅️')
.setStyle('SECONDARY'); .setStyle('SECONDARY');
const confirmButton = new MessageButton() const confirmButton = new MessageButton()
.setCustomId('confirmGif') .setCustomId('confirmGif')
.setLabel('') .setLabel('Select')
.setStyle('PRIMARY'); .setStyle('PRIMARY');
const nextButton = new MessageButton() const nextButton = new MessageButton()
.setCustomId('nextGif') .setCustomId('nextGif')
.setLabel('➡️') .setLabel('➡️')
.setStyle('SECONDARY'); .setStyle('SECONDARY');
const cancelButton = new MessageButton() const cancelButton = new MessageButton()
.setCustomId('cancelGif') .setCustomId('cancelGif')
.setLabel('') .setLabel('Cancel')
.setStyle('DANGER'); .setStyle('DANGER');
switch (state) { switch (state) {
case 'first': case 'first':
previousButton.setDisabled(true); previousButton.setDisabled(true);
break; break;
case 'last': case 'last':
nextButton.setDisabled(true); nextButton.setDisabled(true);
break; break;
} }
// Put the buttons into an ActionRow // Put the buttons into an ActionRow
return new MessageActionRow() return new MessageActionRow()
.addComponents(previousButton, confirmButton, nextButton, cancelButton); .addComponents(previousButton, confirmButton, nextButton, cancelButton);
}, },
gifsPageAR(state) { gifsPageAR(state) {
// Setup the buttons // Setup the buttons
const previousButton = new MessageButton() const previousButton = new MessageButton()
.setCustomId('prevGifsPage') .setCustomId('prevGifsPage')
.setLabel('⬅️') .setLabel('⬅️')
.setStyle('SECONDARY'); .setStyle('SECONDARY');
const nextButton = new MessageButton() const nextButton = new MessageButton()
.setCustomId('nextGifsPage') .setCustomId('nextGifsPage')
.setLabel('➡️') .setLabel('➡️')
.setStyle('SECONDARY'); .setStyle('SECONDARY');
switch (state) { switch (state) {
case 'first': case 'first':
previousButton.setDisabled(true); previousButton.setDisabled(true);
break; break;
case 'last': case 'last':
nextButton.setDisabled(true); nextButton.setDisabled(true);
break; break;
} }
// Put the buttons into an ActionRow // Put the buttons into an ActionRow
return new MessageActionRow() return new MessageActionRow()
.addComponents(previousButton, nextButton); .addComponents(previousButton, nextButton);
}, },
requestsPageAR(state) { requestsPageAR(state) {
// Setup the buttons // Setup the buttons
const previousButton = new MessageButton() const previousButton = new MessageButton()
.setCustomId('prevRequestsPage') .setCustomId('prevRequestsPage')
.setLabel('⬅️') .setLabel('⬅️')
.setStyle('SECONDARY'); .setStyle('SECONDARY');
const nextButton = new MessageButton() const nextButton = new MessageButton()
.setCustomId('nextRequestsPage') .setCustomId('nextRequestsPage')
.setLabel('➡️') .setLabel('➡️')
.setStyle('SECONDARY'); .setStyle('SECONDARY');
switch (state) { switch (state) {
case 'first': case 'first':
previousButton.setDisabled(true); previousButton.setDisabled(true);
break; break;
case 'last': case 'last':
nextButton.setDisabled(true); nextButton.setDisabled(true);
break; break;
} }
// Put the buttons into an ActionRow // Put the buttons into an ActionRow
return new MessageActionRow() return new MessageActionRow()
.addComponents(previousButton, nextButton); .addComponents(previousButton, nextButton);
}, },
pastasPageAR(state) { pastasPageAR(state) {
// Setup the buttons // Setup the buttons
const previousButton = new MessageButton() const previousButton = new MessageButton()
.setCustomId('prevPastasPage') .setCustomId('prevPastasPage')
.setLabel('⬅️') .setLabel('⬅️')
.setStyle('SECONDARY'); .setStyle('SECONDARY');
const nextButton = new MessageButton() const nextButton = new MessageButton()
.setCustomId('nextPastasPage') .setCustomId('nextPastasPage')
.setLabel('➡️') .setLabel('➡️')
.setStyle('SECONDARY'); .setStyle('SECONDARY');
switch (state) { switch (state) {
case 'first': case 'first':
previousButton.setDisabled(true); previousButton.setDisabled(true);
break; break;
case 'last': case 'last':
nextButton.setDisabled(true); nextButton.setDisabled(true);
break; break;
} }
// Put the buttons into an ActionRow // Put the buttons into an ActionRow
return new MessageActionRow() return new MessageActionRow()
.addComponents(previousButton, nextButton); .addComponents(previousButton, nextButton);
}, },
jointsPageAR(state) { jointsPageAR(state) {
// Setup the buttons // Setup the buttons
const previousButton = new MessageButton() const previousButton = new MessageButton()
.setCustomId('prevJointsPage') .setCustomId('prevJointsPage')
.setLabel('⬅️') .setLabel('⬅️')
.setStyle('SECONDARY'); .setStyle('SECONDARY');
const nextButton = new MessageButton() const nextButton = new MessageButton()
.setCustomId('nextJointsPage') .setCustomId('nextJointsPage')
.setLabel('➡️') .setLabel('➡️')
.setStyle('SECONDARY'); .setStyle('SECONDARY');
switch (state) { switch (state) {
case 'first': case 'first':
previousButton.setDisabled(true); previousButton.setDisabled(true);
break; break;
case 'last': case 'last':
nextButton.setDisabled(true); nextButton.setDisabled(true);
break; break;
} }
// Put the buttons into an ActionRow // Put the buttons into an ActionRow
return new MessageActionRow() return new MessageActionRow()
.addComponents(previousButton, nextButton); .addComponents(previousButton, nextButton);
}
},
core: {
gifSearch(commandData, indexedGifs) {
return new MessageEmbed()
.setColor('#0099ff')
.setTitle('GIF Search')
.setImage(indexedGifs.thisPage[0].media_formats.gif.url)
.setFooter({ text: `Page ${indexedGifs.pagesString}` })
.addFields(
{ name: 'Query', value: `"${indexedGifs.query}"`, inline: true },
{ name: 'Saving As', value: `${indexedGifs.gifName}.gif`, inline: true },
);
}
} }
} }

View File

@ -1,5 +1,5 @@
module.exports = (collection, page) => { module.exports = (collection, page, qty) => {
const itemsPerPage = 10; const itemsPerPage = qty ? qty : 10;
const index = page * itemsPerPage; const index = page * itemsPerPage;
const totalPages = Math.ceil(collection.size / itemsPerPage); const totalPages = Math.ceil(collection.size / itemsPerPage);
let state = page === 0 ? 'first' : 'middle'; let state = page === 0 ? 'first' : 'middle';

View File

@ -270,7 +270,7 @@ const functions = {
.setFooter({text: `Page: ${indexedPastas.pagesString}`}) .setFooter({text: `Page: ${indexedPastas.pagesString}`})
.setDescription(indexedPastas.pastasString); .setDescription(indexedPastas.pastasString);
const pastasPageAR = customEmbeds.pastasPageAR(indexedPastas.state); const pastasPageAR = customEmbeds.actionRows.pastasPageAR(indexedPastas.state);
return { embeds: [pastasEmbed], components: [pastasPageAR], ephemeral: true }; return { embeds: [pastasEmbed], components: [pastasPageAR], ephemeral: true };
}, },
gifs(commandData, indexedGifs) { gifs(commandData, indexedGifs) {
@ -280,7 +280,7 @@ const functions = {
.setFooter({text: `Page: ${indexedGifs.pagesString}`}) .setFooter({text: `Page: ${indexedGifs.pagesString}`})
.setDescription(indexedGifs.gifsString); .setDescription(indexedGifs.gifsString);
const gifsPageAR = customEmbeds.gifsPageAR(indexedGifs.state); const gifsPageAR = customEmbeds.actionRows.gifsPageAR(indexedGifs.state);
return { embeds: [gifsEmbed], components: [gifsPageAR], ephemeral: true }; return { embeds: [gifsEmbed], components: [gifsPageAR], ephemeral: true };
}, },
joints(commandData, indexedJoints) { joints(commandData, indexedJoints) {
@ -290,7 +290,7 @@ const functions = {
.setFooter({text: `Page: ${indexedJoints.pagesString}`}) .setFooter({text: `Page: ${indexedJoints.pagesString}`})
.setDescription(indexedJoints.jointsString); .setDescription(indexedJoints.jointsString);
const jointsPageAR = customEmbeds.jointsPageAR(indexedJoints.state); const jointsPageAR = customEmbeds.actionRows.jointsPageAR(indexedJoints.state);
return { embeds: [jointsEmbed], components: [jointsPageAR], ephemeral: true }; return { embeds: [jointsEmbed], components: [jointsPageAR], ephemeral: true };
}, },
text(commandData) { text(commandData) {
@ -307,7 +307,7 @@ const functions = {
.setFooter({text: `Page: ${indexedRequests.pagesString}`}) .setFooter({text: `Page: ${indexedRequests.pagesString}`})
.setDescription(indexedRequests.requestsString); .setDescription(indexedRequests.requestsString);
const requestsPageAR = customEmbeds.requestsPageAR(indexedRequests.state); const requestsPageAR = customEmbeds.actionRows.requestsPageAR(indexedRequests.state);
return { embeds: [requestsEmbed], components: [requestsPageAR], ephemeral: true }; return { embeds: [requestsEmbed], components: [requestsPageAR], ephemeral: true };
}, },
strain(strainInfo, interaction) { strain(strainInfo, interaction) {

112
main.js
View File

@ -76,117 +76,7 @@ client.on('interactionCreate', async interaction => {
if (interaction.isButton()) { if (interaction.isButton()) {
if (isDev) console.log('Origin Interaction ID: ' + interaction.message.interaction.id); if (isDev) console.log('Origin Interaction ID: ' + interaction.message.interaction.id);
if (isDev) console.log('Button ID: ' + interaction.component.customId); if (isDev) console.log('Button ID: ' + interaction.component.customId);
// Get some meta info from strings ButtonHandlers.baseEvent(interaction);
const index = strings.temp.gifIndex;
const limit = strings.temp.gifLimit;
let newIndex;
const buttonId = interaction.component.customId;
switch (buttonId) {
case 'prevGif':
newIndex = index - 1;
strings.temp.gifIndex = newIndex;
// If we're leaving the last GIF, enable the Next GIF button
if (index == limit) {
// Re-Send Previous GIF button
const prevButton = new MessageButton().setCustomId('prevGif').setLabel('Previous GIF').setStyle('SECONDARY');
// Re-Send Confirm GIF Button
const confirmButton = new MessageButton().setCustomId('confirmGif').setLabel('Confirm').setStyle('PRIMARY');
// Enable Next GIF Button
const nextButton = new MessageButton().setCustomId('nextGif').setLabel('Next GIF').setStyle('SECONDARY');
// Re-Send Cancel Button
const cancelButton = new MessageButton().setCustomId('cancelGif').setLabel('Cancel').setStyle('DANGER');
// Put all the above into an ActionRow to be sent as a component of the reply
const row = new MessageActionRow().addComponents(prevButton, confirmButton, nextButton, cancelButton);
interaction.update({ content: strings.temp.gifs[newIndex].embed_url, components: [row] });
break;
}
// If we're going into the first GIF, disable the Previous GIF button
if (newIndex == 0) {
// Disable Previous GIF button
const prevButton = new MessageButton().setCustomId('prevGif').setLabel('Previous GIF').setStyle('SECONDARY').setDisabled();
// Re-Send Confirm GIF Button
const confirmButton = new MessageButton().setCustomId('confirmGif').setLabel('Confirm').setStyle('PRIMARY');
// Re-Send Next GIF Button
const nextButton = new MessageButton().setCustomId('nextGif').setLabel('Next GIF').setStyle('SECONDARY');
// Re-Send Cancel Button
const cancelButton = new MessageButton().setCustomId('cancelGif').setLabel('Canceled').setStyle('DANGER');
// Put all the above into an ActionRow to be sent as a component of the reply
const row = new MessageActionRow().addComponents(prevButton, confirmButton, nextButton, cancelButton);
interaction.update({ content: strings.temp.gifs[newIndex].embed_url, components: [row] });
break;
}
interaction.update(strings.temp.gifs[newIndex].embed_url);
break;
case 'confirmGif':
// const gifData = {
// name: strings.temp.gifName,
// url: strings.temp.gifs[strings.temp.gifIndex].embed_url,
// };
const gifData = new GifData().setInfo(strings.temp.gifName, strings.temp.gifs[strings.temp.gifIndex].embed_url);
fn.upload.gif(gifData, client);
interaction.update({ content: `I've saved the GIF as ${gifData.name}.gif`, components: [] });
fn.download.gifs(interaction.client);
break;
case 'nextGif':
newIndex = index + 1;
strings.temp.gifIndex = newIndex;
// If we're leaving the first GIF, enable the Previous GIF button
if (index == 0) {
// Enable Previous GIF button
const prevButton = new MessageButton().setCustomId('prevGif').setLabel('Previous GIF').setStyle('SECONDARY').setDisabled(false);
// Re-Send Confirm GIF Button
const confirmButton = new MessageButton().setCustomId('confirmGif').setLabel('Confirm').setStyle('PRIMARY');
// Re-Send Next GIF Button
const nextButton = new MessageButton().setCustomId('nextGif').setLabel('Next GIF').setStyle('SECONDARY');
// Re-Send Cancel Button
const cancelButton = new MessageButton().setCustomId('cancelGif').setLabel('Cancel').setStyle('DANGER');
// Put all the above into an ActionRow to be sent as a component of the reply
const row = new MessageActionRow().addComponents(prevButton, confirmButton, nextButton, cancelButton);
interaction.update({ content: strings.temp.gifs[newIndex].embed_url, components: [row] });
break;
}
// If we're going into the last GIF, disable the Next GIF button
if (newIndex == strings.temp.gifLimit) {
// Re-Send Previous GIF button
const prevButton = new MessageButton().setCustomId('prevGif').setLabel('Previous GIF').setStyle('SECONDARY');
// Re-Send Confirm GIF Button
const confirmButton = new MessageButton().setCustomId('confirmGif').setLabel('Confirm').setStyle('PRIMARY');
// Disable Next GIF Button
const nextButton = new MessageButton().setCustomId('nextGif').setLabel('Next GIF').setStyle('SECONDARY').setDisabled();
// Re-Send Cancel Button
const cancelButton = new MessageButton().setCustomId('cancelGif').setLabel('Canceled').setStyle('DANGER');
// Put all the above into an ActionRow to be sent as a component of the reply
const row = new MessageActionRow().addComponents(prevButton, confirmButton, nextButton, cancelButton);
interaction.update({ content: strings.temp.gifs[newIndex].embed_url, components: [row] });
break;
}
interaction.update(strings.temp.gifs[newIndex].embed_url);
break;
case 'cancelGif':
// Previous GIF button
const prevButton = new MessageButton().setCustomId('prevGif').setLabel('Previous GIF').setStyle('SECONDARY').setDisabled();
// Confirm GIF Button
const confirmButton = new MessageButton().setCustomId('confirmGif').setLabel('Confirm').setStyle('PRIMARY').setDisabled();
// Next GIF Button
const nextButton = new MessageButton().setCustomId('nextGif').setLabel('Next GIF').setStyle('SECONDARY').setDisabled();
// Cancel Button
const cancelButton = new MessageButton().setCustomId('cancelGif').setLabel('Canceled').setStyle('DANGER');
// Put all the above into an ActionRow to be sent as a component of the reply
const row = new MessageActionRow().addComponents(prevButton, confirmButton, nextButton, cancelButton);
interaction.component.setDisabled(true);
interaction.update({ content: 'Canceled.', components: [row] });
break;
default:
ButtonHandlers.baseEvent(interaction);
break;
}
} }
// Handle autocomplete requests // Handle autocomplete requests

View File

@ -7,11 +7,13 @@ const tenor = require('tenorjs').client({
}); });
const { SlashCommandBuilder } = require('@discordjs/builders'); const { SlashCommandBuilder } = require('@discordjs/builders');
const { MessageActionRow, MessageButton } = require('discord.js'); const { Collection } = require('discord.js');
const fn = require('../functions.js'); const fn = require('../functions.js');
const strings = require('../strings.json'); const strings = require('../strings.json');
const { GifData } = require('../CustomModules/NodBot.js'); const { GifData } = require('../CustomModules/NodBot.js');
const customEmbeds = require('../CustomModules/Embeds.js'); const customEmbeds = require('../CustomModules/Embeds.js');
const Indexer = require('../CustomModules/Indexer.js');
const Embeds = require('../CustomModules/Embeds.js');
const { emoji } = strings; const { emoji } = strings;
module.exports = { module.exports = {
@ -142,15 +144,21 @@ module.exports = {
switch (subcommand) { switch (subcommand) {
// GIF Search // GIF Search
case "gifsearch": case "gifsearch":
// TODO Check on option names // Grab the inputs from the command
const actionRow = customEmbeds.gifSearchAR();
// Get the query
const query = interaction.options.getString('query'); const query = interaction.options.getString('query');
strings.temp.gifName = interaction.options.getString('name').toLowerCase(); const gifName = interaction.options.getString('name').toLowerCase();
const iStorage = interaction.client.iStorage.get(interaction.id);
iStorage.page = 0;
iStorage.gifsCollection = new Collection();
iStorage.gifName = gifName;
iStorage.query = query;
// Search Tenor for the GIF // Search Tenor for the GIF
tenor.Search.Query(query, '10').then(res => { tenor.Search.Query(query, '20').then(res => {
strings.temp.gifs = []; strings.temp.gifs = [];
strings.temp.gifIndex = 0; strings.temp.gifIndex = 0;
strings.temp.gifLimit = res.length - 1; strings.temp.gifLimit = res.length - 1;
@ -161,11 +169,18 @@ module.exports = {
return; return;
} }
for (const row of res) { for (const row of res) {
strings.temp.gifs.push({ iStorage.gifsCollection.set(row.id, row);
embed_url: row.media_formats.gif.url,
});
} }
interaction.editReply({ content: strings.temp.gifs[0].embed_url, components: [actionRow], ephemeral: true });
// Generate the initial action row
const actionRow = customEmbeds.actionRows.gifSearchAR('first');
// Get the index built
const gifPage = Indexer(iStorage.gifsCollection, 0, 1);
gifPage.query = query;
gifPage.gifName = gifName;
// Generate the embed
const gifEmbed = Embeds.core.gifSearch({ author: interaction.member.displayName }, gifPage);
interaction.editReply({ embeds: [gifEmbed], components: [actionRow], ephemeral: true });
}); });
break; break;
// GIF URL // GIF URL