forked from Galactic/galactic-bot
Refactor poll command
This commit is contained in:
parent
bc467e4dd9
commit
c5c304d5d9
@ -56,91 +56,76 @@ class PollCommand extends SlashCommand
|
|||||||
|
|
||||||
async execute (invoker: InvokerWrapper<true>, { choices, channel, duration, multichoice, message }: CommandParams)
|
async execute (invoker: InvokerWrapper<true>, { choices, channel, duration, multichoice, message }: CommandParams)
|
||||||
{
|
{
|
||||||
const { subcommand, author } = invoker;
|
const { subcommand } = invoker;
|
||||||
const guild = invoker.guild!;
|
|
||||||
const member = invoker.member!;
|
|
||||||
|
|
||||||
if (subcommand!.name === 'create')
|
if (subcommand!.name === 'create')
|
||||||
{
|
return this.#createPoll(invoker, { choices, channel, duration, multichoice });
|
||||||
const targetChannel = (channel?.asChannel || invoker.channel) as GuildTextBasedChannel;
|
|
||||||
if (!targetChannel?.isTextBased())
|
|
||||||
throw new CommandError(invoker, { index: 'ERR_INVALID_CHANNEL_TYPE' });
|
|
||||||
const botMissing = targetChannel.permissionsFor(this.client.user!)?.missing([ 'SendMessages', 'EmbedLinks' ]);
|
|
||||||
const userMissing = targetChannel.permissionsFor(member).missing([ 'SendMessages' ]);
|
|
||||||
if (!botMissing || botMissing.length)
|
|
||||||
return invoker.editReply({ index: 'COMMAND_POLL_BOT_PERMS', params: { missing: botMissing?.join(', ') ?? 'ALL', channel: targetChannel.id } });
|
|
||||||
if (userMissing.length)
|
|
||||||
return invoker.editReply({ index: 'COMMAND_POLL_USER_PERMS', params: { missing: userMissing.join(', '), channel: targetChannel.id } });
|
|
||||||
|
|
||||||
const questions = await this.#queryQuestions(invoker, choices?.asNumber ?? 1, targetChannel);
|
|
||||||
if (!questions)
|
|
||||||
return;
|
|
||||||
|
|
||||||
await invoker.editReply({ index: 'COMMAND_POLL_STARTING' });
|
|
||||||
|
|
||||||
const embed = {
|
|
||||||
title: guild.format('COMMAND_POLL_TITLE', { user: author.tag }),
|
|
||||||
description: guild.format('COMMAND_POLL_DESCRIPTION', {
|
|
||||||
multi: guild.format('COMMAND_POLL_MULTI', { multichoice: multichoice?.asBool && questions.length > 1 || false }, { code: true }),
|
|
||||||
duration: duration ? guild.format('COMMAND_POLL_DURATION', { time: Util.humanise(duration.asNumber), duration: Math.floor(Date.now() / 1000) + duration.asNumber }) : guild.format('COMMAND_POLL_INFINITE')
|
|
||||||
}),
|
|
||||||
fields: questions,
|
|
||||||
color: EmbedDefaultColor,
|
|
||||||
timestamp: new Date().toISOString()
|
|
||||||
};
|
|
||||||
|
|
||||||
let pollMsg = null;
|
|
||||||
if (questions.length === 1)
|
|
||||||
{
|
|
||||||
questions[0].name = guild.format('COMMAND_POLL_FIELD_QUESTION');
|
|
||||||
pollMsg = await targetChannel.send({ embeds: [ embed ] });
|
|
||||||
await pollMsg.react('👍');
|
|
||||||
await pollMsg.react('👎');
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pollMsg = await targetChannel.send({ embeds: [ embed ] });
|
|
||||||
for (const question of questions)
|
|
||||||
await pollMsg.react(PollReactions.Multi[question.index + 1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
const poll: PollData = {
|
|
||||||
questions: questions.map(q => q.value),
|
|
||||||
duration: (duration?.asNumber ?? 0),
|
|
||||||
multiChoice: multichoice?.asBool && questions.length > 1 || false,
|
|
||||||
user: author.id,
|
|
||||||
channel: targetChannel.id,
|
|
||||||
startedIn: invoker.channel!.id,
|
|
||||||
message: pollMsg.id
|
|
||||||
};
|
|
||||||
|
|
||||||
if (duration)
|
|
||||||
await this.client.polls.create(poll, guild.id);
|
|
||||||
await invoker.editReply({ emoji: 'success', index: 'COMMAND_POLL_START', params: { channel: targetChannel.id } });
|
|
||||||
}
|
|
||||||
else if (subcommand!.name === 'delete')
|
else if (subcommand!.name === 'delete')
|
||||||
{
|
return this.#deletePoll(invoker, { message });
|
||||||
const poll = await this.client.polls.delete(message!.asString);
|
|
||||||
if (!poll)
|
|
||||||
return { index: 'COMMAND_POLL_404', emoji: 'failure' };
|
|
||||||
const pollChannel = await guild.resolveChannel<TextChannel>(poll.payload.channel);
|
|
||||||
if (!pollChannel)
|
|
||||||
return { index: 'COMMAND_POLL_MISSING_CHANNEL', emoji: 'failure' };
|
|
||||||
const msg = await pollChannel.messages.fetch(poll.payload.message).catch(() => null);
|
|
||||||
if (msg)
|
|
||||||
await msg.delete();
|
|
||||||
return { index: 'COMMAND_POLL_DELETED', emoji: 'success' };
|
|
||||||
}
|
|
||||||
else if (subcommand!.name === 'end')
|
else if (subcommand!.name === 'end')
|
||||||
{
|
return this.#endPoll(invoker, { message });
|
||||||
const poll = await this.client.polls.find(message!.asString);
|
|
||||||
if (!poll)
|
|
||||||
return { index: 'COMMAND_POLL_404', emoji: 'failure' };
|
|
||||||
await this.client.polls.end(poll.payload);
|
|
||||||
// await guild._poll(poll.data as PollData & CallbackData);
|
|
||||||
return { index: 'COMMAND_POLL_ENDED', emoji: 'success' };
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async #createPoll (invoker: InvokerWrapper<true>, { choices, channel, duration, multichoice }: CommandParams)
|
||||||
|
{
|
||||||
|
const { guild, member, author } = invoker;
|
||||||
|
const targetChannel = (channel?.asChannel || invoker.channel) as GuildTextBasedChannel;
|
||||||
|
if (!targetChannel?.isTextBased())
|
||||||
|
throw new CommandError(invoker, { index: 'ERR_INVALID_CHANNEL_TYPE' });
|
||||||
|
const botMissing = targetChannel.permissionsFor(this.client.user!)?.missing([ 'SendMessages', 'EmbedLinks' ]);
|
||||||
|
const userMissing = targetChannel.permissionsFor(member).missing([ 'SendMessages' ]);
|
||||||
|
if (!botMissing || botMissing.length)
|
||||||
|
return invoker.editReply({ index: 'COMMAND_POLL_BOT_PERMS', params: { missing: botMissing?.join(', ') ?? 'ALL', channel: targetChannel.id } });
|
||||||
|
if (userMissing.length)
|
||||||
|
return invoker.editReply({ index: 'COMMAND_POLL_USER_PERMS', params: { missing: userMissing.join(', '), channel: targetChannel.id } });
|
||||||
|
|
||||||
|
const questions = await this.#queryQuestions(invoker, choices?.asNumber ?? 1, targetChannel);
|
||||||
|
if (!questions)
|
||||||
|
return;
|
||||||
|
|
||||||
|
await invoker.editReply({ index: 'COMMAND_POLL_STARTING' });
|
||||||
|
|
||||||
|
const embed = {
|
||||||
|
title: guild.format('COMMAND_POLL_TITLE', { user: author.tag }),
|
||||||
|
description: guild.format('COMMAND_POLL_DESCRIPTION', {
|
||||||
|
multi: guild.format('COMMAND_POLL_MULTI', { multichoice: multichoice?.asBool && questions.length > 1 || false }, { code: true }),
|
||||||
|
duration: duration ? guild.format('COMMAND_POLL_DURATION', { time: Util.humanise(duration.asNumber), duration: Math.floor(Date.now() / 1000) + duration.asNumber }) : guild.format('COMMAND_POLL_INFINITE')
|
||||||
|
}),
|
||||||
|
fields: questions,
|
||||||
|
color: EmbedDefaultColor,
|
||||||
|
timestamp: new Date().toISOString()
|
||||||
|
};
|
||||||
|
|
||||||
|
let pollMsg = null;
|
||||||
|
if (questions.length === 1)
|
||||||
|
{
|
||||||
|
questions[0].name = guild.format('COMMAND_POLL_FIELD_QUESTION');
|
||||||
|
pollMsg = await targetChannel.send({ embeds: [ embed ] });
|
||||||
|
await pollMsg.react('👍');
|
||||||
|
await pollMsg.react('👎');
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pollMsg = await targetChannel.send({ embeds: [ embed ] });
|
||||||
|
for (const question of questions)
|
||||||
|
await pollMsg.react(PollReactions.Multi[question.index + 1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
const poll: PollData = {
|
||||||
|
questions: questions.map(q => q.value),
|
||||||
|
duration: (duration?.asNumber ?? 0),
|
||||||
|
multiChoice: multichoice?.asBool && questions.length > 1 || false,
|
||||||
|
user: author.id,
|
||||||
|
channel: targetChannel.id,
|
||||||
|
startedIn: invoker.channel!.id,
|
||||||
|
message: pollMsg.id
|
||||||
|
};
|
||||||
|
|
||||||
|
if (duration)
|
||||||
|
await this.client.polls.create(poll, guild.id);
|
||||||
|
await invoker.editReply({ emoji: 'success', index: 'COMMAND_POLL_START', params: { channel: targetChannel.id } });
|
||||||
|
}
|
||||||
|
|
||||||
async #queryQuestions (invoker: InvokerWrapper<true>, choices: number, targetchannel: GuildTextBasedChannel)
|
async #queryQuestions (invoker: InvokerWrapper<true>, choices: number, targetchannel: GuildTextBasedChannel)
|
||||||
{
|
{
|
||||||
const { guild, member } = invoker;
|
const { guild, member } = invoker;
|
||||||
@ -166,6 +151,31 @@ class PollCommand extends SlashCommand
|
|||||||
}
|
}
|
||||||
return questions;
|
return questions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async #deletePoll (invoker: InvokerWrapper<true>, { message }: CommandParams)
|
||||||
|
{
|
||||||
|
const { guild } = invoker;
|
||||||
|
const poll = await this.client.polls.delete(message!.asString);
|
||||||
|
if (!poll)
|
||||||
|
return { index: 'COMMAND_POLL_404', emoji: 'failure' };
|
||||||
|
const pollChannel = await guild.resolveChannel<TextChannel>(poll.payload.channel);
|
||||||
|
if (!pollChannel)
|
||||||
|
return { index: 'COMMAND_POLL_MISSING_CHANNEL', emoji: 'failure' };
|
||||||
|
const msg = await pollChannel.messages.fetch(poll.payload.message).catch(() => null);
|
||||||
|
if (msg)
|
||||||
|
await msg.delete();
|
||||||
|
return { index: 'COMMAND_POLL_DELETED', emoji: 'success' };
|
||||||
|
}
|
||||||
|
|
||||||
|
async #endPoll (_invoker: InvokerWrapper<true>, { message }: CommandParams)
|
||||||
|
{
|
||||||
|
const poll = await this.client.polls.find(message!.asString);
|
||||||
|
if (!poll)
|
||||||
|
return { index: 'COMMAND_POLL_404', emoji: 'failure' };
|
||||||
|
await this.client.polls.end(poll._id, poll.payload);
|
||||||
|
// await guild._poll(poll.data as PollData & CallbackData);
|
||||||
|
return { index: 'COMMAND_POLL_ENDED', emoji: 'success' };
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default PollCommand;
|
export default PollCommand;
|
@ -47,12 +47,12 @@ class PollManager implements CallbackClient
|
|||||||
return poll;
|
return poll;
|
||||||
}
|
}
|
||||||
|
|
||||||
async handleCallback (_id: string, payload: PollData): Promise<void>
|
async handleCallback (id: string, payload: PollData): Promise<void>
|
||||||
{
|
{
|
||||||
await this.end(payload);
|
await this.end(id, payload);
|
||||||
}
|
}
|
||||||
|
|
||||||
async end ({ user, channel, startedIn, message, multiChoice }: PollData)
|
async end (id: string, { user, channel, startedIn, message, multiChoice }: PollData)
|
||||||
{
|
{
|
||||||
const startChannel = await this.#client.resolveChannel(startedIn);
|
const startChannel = await this.#client.resolveChannel(startedIn);
|
||||||
const pollChannel = await this.#client.resolveChannel(channel);
|
const pollChannel = await this.#client.resolveChannel(channel);
|
||||||
@ -89,6 +89,7 @@ class PollManager implements CallbackClient
|
|||||||
if (startChannel && startChannel.isTextBased())
|
if (startChannel && startChannel.isTextBased())
|
||||||
await startChannel.send(guild.format('COMMAND_POLL_NOTIFY_STARTER', { user, channel }));
|
await startChannel.send(guild.format('COMMAND_POLL_NOTIFY_STARTER', { user, channel }));
|
||||||
}
|
}
|
||||||
|
await this.callbacks.removeCallback(id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user