diff --git a/src/commands/fun/poll.ts b/src/commands/fun/poll.ts index 40f9287..d595b4c 100644 --- a/src/commands/fun/poll.ts +++ b/src/commands/fun/poll.ts @@ -1,7 +1,24 @@ -import {MessageEmbed, Message, User} from "discord.js"; +import {MessageEmbed, Message, User, MessageActionRow, MessageButton} from "discord.js"; import {NamedCommand, RestCommand, poll, CHANNEL_TYPE, SendFunction, Command} from "onion-lasers"; +import {SlashCommandBuilder} from "@discordjs/builders"; +import {CommandInteraction} from "discord.js"; import {pluralise} from "../../lib"; +export const header = new SlashCommandBuilder() + .setDescription("Create a poll.") + .addStringOption((option) => option.setName("question").setDescription("Question for the poll").setRequired(true)) + .addIntegerOption((option) => + option.setName("duration").setDescription("Duration of the poll in seconds.").setRequired(false) + ); + +export async function handler(interaction: CommandInteraction) { + const {options} = interaction; + const question = options.getString("question", true); + const duration = options.getInteger("duration", false); + + execSlashPoll(interaction, question, duration || 60000); +} + export default new NamedCommand({ description: "Create a poll.", usage: "() ", @@ -27,6 +44,63 @@ export default new NamedCommand({ const AGREE = "✅"; const DISAGREE = "⛔"; +async function execSlashPoll(interaction: CommandInteraction, question: string, duration = 60000) { + const responseButtons = new MessageActionRow().addComponents( + new MessageButton().setCustomId("agree").setLabel(AGREE).setStyle("SUCCESS"), + new MessageButton().setCustomId("disagree").setLabel(DISAGREE).setStyle("DANGER") + ); + + const icon = + interaction.user.avatarURL({ + dynamic: true, + size: 2048 + }) || interaction.user.defaultAvatarURL; + const embed = new MessageEmbed() + .setAuthor(`Poll created by ${interaction.user.username}`, icon) + .setColor(0xffffff) + .setFooter("Click the buttons to vote.") + .setDescription(question) + .addField(`${AGREE} -`, `${pluralise(0, "", "people have voted")}\n`) + .addField(`${DISAGREE} -`, `${pluralise(0, "", "people have voted")}\n`); + const msg = await interaction.reply({ + embeds: [embed], + components: [responseButtons] + }); + var idsArray: string[] = []; + const collector = interaction.channel?.createMessageComponentCollector({time: duration}); + collector?.on("collect", async (i) => { + if (i.customId === "agree") { + if (idsArray.includes(i.user.id)) { + i.reply({content: "You have already voted!", ephemeral: true}); + } else { + idsArray.push(i.user.id); + var agree = +1; + embed.fields[0].value = `${pluralise(agree, "", "people who agree", "person who agrees")}\n`; + interaction.editReply({embeds: [embed]}); + i.reply({content: "You picked ✅!", ephemeral: true}); + } + } + if (i.customId === "disagree") { + if (idsArray.includes(i.user.id)) { + i.reply({content: "You have already voted!", ephemeral: true}); + } else { + idsArray.push(i.user.id); + var disagree = +1; + embed.fields[1].value = `${pluralise(disagree, "", "people who disagree", "person who disagrees")}\n`; + interaction.editReply({embeds: [embed]}); + i.reply({content: "You picked ⛔!", ephemeral: true}); + } + } + }); + //This solution looks messy but works really well and stops from stuff like vote fraud happening. + //I'm not sure if it's the best solution but if you have a better idea then please let me know. + + collector?.on("end", async (collected) => { + embed.setTitle(`The results of ${interaction.user.username}'s poll:`); + interaction.editReply({embeds: [embed]}); + }); +} + async function execPoll(send: SendFunction, message: Message, user: User, question: string, duration = 60000) { const icon = user.avatarURL({ diff --git a/src/commands/fun/thonk.ts b/src/commands/fun/thonk.ts index 001c51f..ee698de 100644 --- a/src/commands/fun/thonk.ts +++ b/src/commands/fun/thonk.ts @@ -42,7 +42,7 @@ export async function handler(interaction: CommandInteraction) { interaction.reply(transform(response)); // You might notice the remove message code is missing here. It's because reactions collectors are - //not a thing in interactions. The best alternative would buttons + //not a thing in interactions. The best alternative would be buttons } let phrase = "I have no currently set phrase!";