Skip to content

Commit

Permalink
added custom ReactionMenu class, updated admins, mods, emojis, and ga…
Browse files Browse the repository at this point in the history
…llery to use ReactionMenu
  • Loading branch information
sabattle committed Aug 6, 2020
1 parent 1f67b56 commit 3a96030
Show file tree
Hide file tree
Showing 5 changed files with 281 additions and 47 deletions.
92 changes: 92 additions & 0 deletions src/commands/ReactionMenu.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/**
* Calypso's Reaction Menu class
*/
module.exports = class ReactionMenu {

/**
* Create new ReactionMenu
* @param {TextChannel} channel
* @param {GuildMember} member
* @param {MessageEmbed} embed
* @param {Object} reactions
* @param {int} timeout
*/
constructor(channel, member, embed, reactions, timeout = 120000) {

/**
* The text channel
* @type {TextChannel}
*/
this.channel = channel;

/**
* The member ID snowflake
* @type {string}
*/
this.memberId = member.id;

/**
* The message embed
* @type {MessageEmbed}
*/
this.embed = embed;

/**
* The reactions for menu
* @type {Object}
*/
this.reactions = reactions;

/**
* The emojis used as keys
* @type {Array<string>}
*/
this.emojis = Object.keys(this.reactions);

/**
* The collector timeout
* @type {int}
*/
this.timeout = timeout;

this.channel.send(this.embed).then(message => {
this.message = message;
this.addReactions();
this.createCollector();
});
}

/**
* Adds reactions to the message
*/
async addReactions() {
for (const emoji of this.emojis) {
await this.message.react(emoji);
}
}

/**
* Creates a reaction collector
*/
createCollector() {

// Create collector
const collector = this.message.createReactionCollector((reaction, user) => {
return (this.emojis.includes(reaction.emoji.name) || this.emojis.includes(reaction.emoji.id)) &&
user.id == this.memberId;
}, { time: this.timeout });

// On collect
collector.on('collect', async reaction => {
let newPage = this.reactions[reaction.emoji.name] || this.reactions[reaction.emoji.id];
if (typeof newPage === 'function') newPage = newPage();
await this.message.edit(newPage);
await reaction.users.remove(this.memberId);
});

// On end
collector.on('end', () => {
this.message.reactions.removeAll();
});
}
};
63 changes: 55 additions & 8 deletions src/commands/info/admins.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const Command = require('../Command.js');
const ReactionMenu = require('../ReactionMenu.js');
const { MessageEmbed } = require('discord.js');

module.exports = class AdminsCommand extends Command {
Expand All @@ -14,25 +15,71 @@ module.exports = class AdminsCommand extends Command {

// Get admin role
const adminRoleId = message.client.db.settings.selectAdminRoleId.pluck().get(message.guild.id);
let adminRole = '`None`';
if (adminRoleId) adminRole = message.guild.roles.cache.get(adminRoleId);
const adminRole = message.guild.roles.cache.get(adminRoleId) || '`None`';

const admins = message.guild.members.cache.filter(m => {
if (m.roles.cache.find(r => r === adminRole)) return true;
}).sort((a, b) => (a.joinedAt > b.joinedAt) ? 1 : -1).array();

let description = message.client.utils.trimStringFromArray(admins);
if (admins.length === 0) description = 'No admins found.';

const embed = new MessageEmbed()
.setTitle(`Admin List [${admins.length}]`)
.setThumbnail(message.guild.iconURL({ dynamic: true }))
.setDescription(description)
.addField('Admin Role', adminRole)
.addField('Admin Count', `**${admins.length}** out of **${message.guild.members.cache.size}** accounts`)
.addField('Admin Count', `**${admins.length}** out of **${message.guild.members.cache.size}** members`)
.setFooter(message.member.displayName, message.author.displayAvatarURL({ dynamic: true }))
.setTimestamp()
.setColor(message.guild.me.displayHexColor);
message.channel.send(embed);

let max = 25;
if (admins.length === 0) message.channel.send(embed.setDescription('No admins found.'));
else if (admins.length <= max) {
const range = (admins.length == 1) ? '[1]' : `[1 - ${admins.length}]`;
message.channel.send(embed
.setTitle(`Admin List ${range}`)
.setDescription(admins.join('\n'))
);

// Reaction Menu
} else {

let n = 0;
embed
.setTitle(`Admin List [${n + 1} - ${max}]`)
.setThumbnail(message.guild.iconURL({ dynamic: true }))
.setFooter(
'Expires after two minutes.\n' + message.member.displayName,
message.author.displayAvatarURL({ dynamic: true })
)
.setDescription(admins.slice(n, max).join('\n'));

const json = embed.toJSON();

const previous = () => {
if (n === 0) return;
n -= 25;
max -= 25;
if (max < 25) max = 25;
return new MessageEmbed(json)
.setTitle(`Admin List [${n + 1} - ${max}]`)
.setDescription(admins.slice(n, max).join('\n'));
};

const next = () => {
if (max === admins.length) return;
n += 25;
max += 25;
if (max >= admins.length) max = admins.length;
return new MessageEmbed(json)
.setTitle(`Admin List [${n + 1} - ${max}]`)
.setDescription(admins.slice(n, max).join('\n'));
};

const reactions = {
'◀️': previous,
'▶️': next,
};

new ReactionMenu(message.channel, message.member, embed, reactions);
}
}
};
57 changes: 52 additions & 5 deletions src/commands/info/emojis.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const Command = require('../Command.js');
const ReactionMenu = require('../ReactionMenu.js');
const { MessageEmbed } = require('discord.js');

module.exports = class EmojisCommand extends Command {
Expand All @@ -22,11 +23,57 @@ module.exports = class EmojisCommand extends Command {
.setTimestamp()
.setColor(message.guild.me.displayHexColor);

// Trim array
let description = message.client.utils.trimStringFromArray(emojis);
if (description.length === 0) description = 'Sorry! No emojis found 😢';
else embed.setThumbnail(message.guild.iconURL({ dynamic: true }));
let max = 25;
if (emojis.length === 0) message.channel.send(embed.setDescription('Sorry! No emojis found 😢'));
else if (emojis.length <= max) {
const range = (emojis.length == 1) ? '[1]' : `[1 - ${emojis.length}]`;
message.channel.send(embed
.setTitle(`Emoji List ${range}`)
.setDescription(emojis.join('\n'))
.setThumbnail(message.guild.iconURL({ dynamic: true }))
);

// Reaction Menu
} else {

message.channel.send(embed.setDescription(description));
let n = 0;
embed
.setTitle(`Emoji List [1 - ${max}]`)
.setThumbnail(message.guild.iconURL({ dynamic: true }))
.setFooter(
'Expires after two minutes.\n' + message.member.displayName,
message.author.displayAvatarURL({ dynamic: true })
)
.setDescription(emojis.slice(n, max).join('\n'));

const json = embed.toJSON();

const previous = () => {
if (n === 0) return;
n -= 25;
max -= 25;
if (max < 25) max = 25;
return new MessageEmbed(json)
.setTitle(`Emoji List [${n + 1} - ${max}]`)
.setDescription(emojis.slice(n, max).join('\n'));
};

const next = () => {
if (max === emojis.length) return;
n += 25;
max += 25;
if (max >= emojis.length) max = emojis.length;
return new MessageEmbed(json)
.setTitle(`Emoji List [${n + 1} - ${max}]`)
.setDescription(emojis.slice(n, max).join('\n'));
};

const reactions = {
'◀️': previous,
'▶️': next,
};

new ReactionMenu(message.channel, message.member, embed, reactions);
}
}
};
53 changes: 27 additions & 26 deletions src/commands/info/gallery.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const Command = require('../Command.js');
const ReactionMenu = require('../ReactionMenu.js');
const { MessageEmbed } = require('discord.js');
const art = [
'https://raw.githubusercontent.com/sabattle/CalypsoBot/develop/data/images/Calypso_Full_Signature.png',
Expand All @@ -18,40 +19,40 @@ module.exports = class GalleryCommand extends Command {
type: client.types.INFO,
});
}
async run(message) {
run(message) {
let n = 0;
const back = '⬅';
const next = '➡';
const embed = new MessageEmbed()
.setTitle('Art Gallery')
.setDescription('All art courtesy of **CommradeFido#5286**.')
.setImage(art[n])
.setFooter('All art courtesy of CommradeFido#5286.\nGallery expires after 3 minutes.')
.setFooter(
'Expires after two minutes.\n' + message.member.displayName,
message.author.displayAvatarURL({ dynamic: true })
)
.setTimestamp()
.setColor(message.guild.me.displayHexColor);
const msg = await message.channel.send(embed);
await msg.react(back);
await msg.react(next);
const filter = (reaction, user) => user != message.client.user;
const collector = msg.createReactionCollector(filter, { time: 180000 }); // Three minute timer
collector.on('collect', async reaction => {
const reactionUsers = (await reaction.users.fetch()).filter(user=> user != message.client.user);
reactionUsers.forEach(async user => await reaction.users.remove(user));
if (reaction.emoji.name === back) {
n--;
if (n < 0) n = art.length - 1;
} else if (reaction.emoji.name === next) {
n++;
if (n > art.length - 1) n = 0;
}
embed.setImage(art[n]);
await msg.edit(embed);
});
collector.on('end', async () => {
await msg.edit(new MessageEmbed()
const json = embed.toJSON();
const goBack = () => {
(n <= 0) ? n = art.length - 1 : n--;
return new MessageEmbed(json).setImage(art[n]);
};
const goForward = () => {
(n >= art.length - 1) ? n = 0 : n++;
return new MessageEmbed(json).setImage(art[n]);
};

const reactions = {
'◀️': goBack,
'▶️': goForward,
};
const menu = new ReactionMenu(message.channel, message.member, embed, reactions);
setInterval(async () => {
await menu.message.edit(new MessageEmbed()
.setTitle('Art Gallery')
.setDescription('Sorry! The gallery has expired.')
.setColor(message.guild.me.displayHexColor)
);
await msg.reactions.removeAll();
});
}, menu.timeout);

}
};
Loading

0 comments on commit 3a96030

Please sign in to comment.