UNPKG

discord-buttons-react

Version:

A package which allow you to use buttons as reactions

282 lines (213 loc) 11.3 kB
const { Structures, MessageEmbed } = require("discord.js"); const { resolveString } = require('discord.js').Util; const db = require('quick.db'); let createEnum = (keys) => { const obj = {}; for (const [index, key] of keys.entries()) { if (key === null) continue; obj[key] = index; obj[index] = key; } return obj; } let MessageButtonStyles = createEnum([null, 'blurple', 'grey', 'green', 'red', 'url']); let MessageButtonStylesAliases = createEnum([null, 'PRIMARY', 'SECONDARY', 'SUCCESS', 'DESTRUCTIVE', 'LINK']); let resolveStyle = (style) => { if (!style || style === undefined || style === null) throw new TypeError('NO_BUTTON_STYLE: Please provide button style'); if (style === 'gray') style = 'grey'; if ((!MessageButtonStyles[style] || MessageButtonStyles[style] === undefined || MessageButtonStyles[style] === null) && (!MessageButtonStylesAliases[style] || MessageButtonStylesAliases[style] === undefined || MessageButtonStylesAliases[style] === null)) throw new TypeError('INVALID_BUTTON_STYLE: An invalid button styles was provided'); return typeof style === 'string' ? MessageButtonStyles[style] : style; } let randomID = () => { let s4 = () => { return Math.floor((1 + Math.random()) * 0x10000) .toString(16) .substring(1); } return s4() + '-' + s4() + '-' + s4(); } let getButtonsFromComponents = (components) => { const buttonsArray = []; for (const ActionRow of components) { for (const btn of ActionRow.components) { buttonsArray.push(btn) }; }; return buttonsArray; } let isEmoji = (string) => { var regex = /(?:[\u2700-\u27bf]|(?:\ud83c[\udde6-\uddff]){2}|[\ud800-\udbff][\udc00-\udfff]|[\u0023-\u0039]\ufe0f?\u20e3|\u3299|\u3297|\u303d|\u3030|\u24c2|\ud83c[\udd70-\udd71]|\ud83c[\udd7e-\udd7f]|\ud83c\udd8e|\ud83c[\udd91-\udd9a]|\ud83c[\udde6-\uddff]|\ud83c[\ude01-\ude02]|\ud83c\ude1a|\ud83c\ude2f|\ud83c[\ude32-\ude3a]|\ud83c[\ude50-\ude51]|\u203c|\u2049|[\u25aa-\u25ab]|\u25b6|\u25c0|[\u25fb-\u25fe]|\u00a9|\u00ae|\u2122|\u2139|\ud83c\udc04|[\u2600-\u26FF]|\u2b05|\u2b06|\u2b07|\u2b1b|\u2b1c|\u2b50|\u2b55|\u231a|\u231b|\u2328|\u23cf|[\u23e9-\u23f3]|[\u23f8-\u23fa]|\ud83c\udccf|\u2934|\u2935|[\u2190-\u21ff])/g; return regex.test(string) } class ReactionButton { constructor(data = {}) { //super({ type: 'BUTTON' }); this.setup(data); } setup(data) { this.style = 'style' in data ? resolveStyle(data.style) : null; this.emoji = 'emoji' in data ? data.emoji : undefined; return this; } setStyle(style) { style = resolveStyle(style); if (style != "url") this.style = style else (style = "gray") return this; } setEmoji(emoji) { if (isEmoji(resolveString(emoji)) === true) this.emoji = { name: resolveString(emoji) } else if (emoji.id) this.emoji = { id: emoji.id } else if (resolveString(emoji).length > 0) this.emoji = { id: resolveString(emoji) } else this.emoji = { name: null, id: null }; return this; } toJSON() { return { style: this.style, emoji: this.emoji, } } } module.exports = (client) => { const { MessageButton, MessageActionRow } = require("discord-buttons"); client.on("clickButton", async button => { let user = await button.clicker.user; if (!db.get(`discord-buttons-react.${button.message.id}.${button.id}`)) return; button.defer(); if (db.get(`discord-buttons-react.${button.message.id}`)[button.id]["clickers"].includes(user.id)) { // editer le message avec le bouton -1 const buttonList = getButtonsFromComponents(button.message.components); let indexClickedButton = buttonList.findIndex(btn => btn.custom_id == button.id); let clickedButton = buttonList[indexClickedButton]; let newBtn = new MessageButton() .setStyle(clickedButton.style) .setLabel((parseInt(clickedButton.label, 10)-1).toString()) .setEmoji(clickedButton.emoji.id || clickedButton.emoji.name) .setID(clickedButton.custom_id) buttonList[indexClickedButton] = newBtn; const buttonsRoleRow1 = []; const buttonsRoleRow2 = []; const buttonsRoleRow3 = []; const buttonsRoleRow4 = []; const buttonsRoleRow5 = []; let i = 0; for(let btn of buttonList) { i++ if (i <=5) buttonsRoleRow1.push(btn) else if (i>5 && i<=10) buttonsRoleRow2.push(btn) else if (i>10 && i<=15) buttonsRoleRow3.push(btn) else if (i>15 && i<=20) buttonsRoleRow4.push(btn) else if (i>20 && i<=25) buttonsRoleRow5.push(btn) else return; }; const ListeRows = []; if (buttonsRoleRow1.length) ListeRows.push(new MessageActionRow().addComponents(buttonsRoleRow1)); if (buttonsRoleRow2.length) ListeRows.push(new MessageActionRow().addComponents(buttonsRoleRow2)); if (buttonsRoleRow3.length) ListeRows.push(new MessageActionRow().addComponents(buttonsRoleRow3)); if (buttonsRoleRow4.length) ListeRows.push(new MessageActionRow().addComponents(buttonsRoleRow4)); if (buttonsRoleRow5.length) ListeRows.push(new MessageActionRow().addComponents(buttonsRoleRow5)); button.message.edit(button.message.content, { components: ListeRows }); let clickerArray = db.get(`discord-buttons-react.${button.message.id}`)[button.id]["clickers"]; let index = clickerArray.indexOf(user.id); if (index > -1) { clickerArray.splice(index, 1); }; db.set(`discord-buttons-react.${button.message.id}.${button.id}.clickers`, clickerArray); client.emit('messageButtonReactionRemove', { clicker: button.clicker, message: button.message, reactionEmoji: clickedButton.emoji.name||clickedButton.emoji.id }); } else { db.push(`discord-buttons-react.${button.message.id}.${button.id}.clickers`, user.id); const buttonList = getButtonsFromComponents(button.message.components); let indexClickedButton = buttonList.findIndex(btn => btn.custom_id == button.id); let clickedButton = buttonList[indexClickedButton]; let newBtn = new MessageButton() .setStyle(clickedButton.style) .setLabel((parseInt(clickedButton.label, 10)+1).toString()) .setEmoji(clickedButton.emoji.id || clickedButton.emoji.name) .setID(clickedButton.custom_id) buttonList[indexClickedButton] = newBtn; const buttonsRoleRow1 = []; const buttonsRoleRow2 = []; const buttonsRoleRow3 = []; const buttonsRoleRow4 = []; const buttonsRoleRow5 = []; let i = 0; for(let btn of buttonList) { i++ if (i <=5) buttonsRoleRow1.push(btn) else if (i>5 && i<=10) buttonsRoleRow2.push(btn) else if (i>10 && i<=15) buttonsRoleRow3.push(btn) else if (i>15 && i<=20) buttonsRoleRow4.push(btn) else if (i>20 && i<=25) buttonsRoleRow5.push(btn) else return; }; const ListeRows = []; if (buttonsRoleRow1.length) ListeRows.push(new MessageActionRow().addComponents(buttonsRoleRow1)); if (buttonsRoleRow2.length) ListeRows.push(new MessageActionRow().addComponents(buttonsRoleRow2)); if (buttonsRoleRow3.length) ListeRows.push(new MessageActionRow().addComponents(buttonsRoleRow3)); if (buttonsRoleRow4.length) ListeRows.push(new MessageActionRow().addComponents(buttonsRoleRow4)); if (buttonsRoleRow5.length) ListeRows.push(new MessageActionRow().addComponents(buttonsRoleRow5)); button.message.edit(button.message.content, { components: ListeRows }); client.emit('messageButtonReactionAdd', { clicker: button.clicker, message: button.message, reactionEmoji: clickedButton.emoji.name||clickedButton.emoji.id }); } }); class TextChannel extends Structures.get("TextChannel") { async createMessageReactionButton(content, ReactionButtons) { const buttonsRoleRow1 = []; const buttonsRoleRow2 = []; const buttonsRoleRow3 = []; const buttonsRoleRow4 = []; const buttonsRoleRow5 = []; const listID = []; let i = 0; for(let btn of ReactionButtons) { i++ let ID = randomID(); listID.push(ID) let bouton = new MessageButton().setStyle(btn.style).setID(ID) if (btn.emoji) bouton.setEmoji(btn.emoji.name || btn.emoji.id); bouton.setLabel("0"); if (!btn.label && !btn.emoji) throw new TypeError('DISCORD-BUTTONS-REACT: You must provide emoji and/or label'); if (i <=5) buttonsRoleRow1.push(bouton) else if (i>5 && i<=10) buttonsRoleRow2.push(bouton) else if (i>10 && i<=15) buttonsRoleRow3.push(bouton) else if (i>15 && i<=20) buttonsRoleRow4.push(bouton) else if (i>20 && i<=25) buttonsRoleRow5.push(bouton) else return; }; const ListeRows = []; if (buttonsRoleRow1.length) ListeRows.push(new MessageActionRow().addComponents(buttonsRoleRow1)); if (buttonsRoleRow2.length) ListeRows.push(new MessageActionRow().addComponents(buttonsRoleRow2)); if (buttonsRoleRow3.length) ListeRows.push(new MessageActionRow().addComponents(buttonsRoleRow3)); if (buttonsRoleRow4.length) ListeRows.push(new MessageActionRow().addComponents(buttonsRoleRow4)); if (buttonsRoleRow5.length) ListeRows.push(new MessageActionRow().addComponents(buttonsRoleRow5)); let message; if (content instanceof MessageEmbed) message = await this.send({ embed: content, components: ListeRows }) else message = await this.send(content, { components: ListeRows }); let listIDObject = {}; for (const Id of listID) { listIDObject[Id] = { active: true, clickers: [] }; }; db.set(`discord-buttons-react.${message.id}`, listIDObject); }; }; Structures.extend("TextChannel", () => TextChannel); return { ReactionButton: ReactionButton }; }; module.exports.ReactionButton = ReactionButton;