/[sudobot]/branches/8.x/src/commands/automation/BallotVoteListCommand.ts
ViewVC logotype

Contents of /branches/8.x/src/commands/automation/BallotVoteListCommand.ts

Parent Directory Parent Directory | Revision Log Revision Log


Revision 577 - (show annotations)
Mon Jul 29 18:52:37 2024 UTC (8 months ago) by rakinar2
File MIME type: application/typescript
File size: 6184 byte(s)
chore: add old version archive branches (2.x to 9.x-dev)
1 /**
2 * This file is part of SudoBot.
3 *
4 * Copyright (C) 2021-2023 OSN Developers.
5 *
6 * SudoBot is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU Affero General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * SudoBot is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Affero General Public License for more details.
15 *
16 * You should have received a copy of the GNU Affero General Public License
17 * along with SudoBot. If not, see <https://www.gnu.org/licenses/>.
18 */
19
20 import { ActionRowBuilder, ButtonBuilder, ButtonStyle, EmbedBuilder } from "discord.js";
21 import Command, { BasicCommandContext, CommandMessage, CommandReturn } from "../../core/Command";
22 import Pagination from "../../utils/Pagination";
23 import { safeUserFetch } from "../../utils/fetch";
24
25 export default class BallotVoteListCommand extends Command {
26 public readonly name = "ballot__votelist";
27 public readonly permissions = [];
28 public readonly description = "Shows a list of each vote in a poll/ballot.";
29 public readonly supportsInteractions: boolean = true;
30 public readonly supportsLegacy: boolean = true;
31
32 async execute(message: CommandMessage, context: BasicCommandContext): Promise<CommandReturn> {
33 if (context.isLegacy && context.args[0] === undefined) {
34 await this.error(message, "Please provide the ballot ID!");
35 return;
36 }
37
38 await this.deferIfInteraction(message);
39
40 type Mode = "all" | "upvotes" | "downvotes";
41 const id = context.isLegacy
42 ? parseInt(context.args[0])
43 : context.options.getInteger("id", true);
44 const mode = <Mode>((context.isLegacy ? null : context.options.getString("mode")) ?? "all");
45
46 if (isNaN(id)) {
47 await this.error(
48 message,
49 "Invalid ballot ID given! Ballot IDs must be numeric values."
50 );
51 return;
52 }
53
54 const ballot = await this.client.ballotManager.get({
55 id,
56 guildId: message.guildId!
57 });
58
59 if (!ballot) {
60 await this.error(message, "No such ballot exists with that ID!");
61 return;
62 }
63
64 const user = ballot.anonymous ? null : await safeUserFetch(this.client, ballot.userId);
65 const url = `https://discord.com/channels/${encodeURIComponent(
66 ballot.guildId
67 )}/${encodeURIComponent(ballot.channelId)}/${encodeURIComponent(ballot.messageId)}`;
68
69 const data = [
70 ...(mode === "all" || mode === "upvotes"
71 ? ballot.upvotes.map(userId => ({
72 userId,
73 type: "upvote" as const
74 }))
75 : []),
76 ...(mode === "all" || mode === "downvotes"
77 ? ballot.downvotes.map(userId => ({
78 userId,
79 type: "downvote" as const
80 }))
81 : [])
82 ];
83
84 const pagination = new Pagination(data, {
85 channelId: message.channelId!,
86 client: this.client,
87 guildId: message.guildId!,
88 limit: 10,
89 userId: message.member?.user.id,
90 timeout: 120_000,
91 messageOptions: {
92 files: ballot.files.map(url => ({ attachment: url })),
93 embeds: [
94 {
95 author: {
96 name: ballot.anonymous ? "Staff" : user?.username ?? "Unknown",
97 icon_url: ballot.anonymous
98 ? message.guild!.iconURL() ?? undefined
99 : user?.displayAvatarURL(),
100 url
101 },
102 description: ballot.content,
103 color: 0x007bff,
104 fields: [
105 {
106 name: "Total Votes",
107 value: `⚪ **${ballot.upvotes.length - ballot.downvotes.length}**`,
108 inline: true
109 },
110 {
111 name: "Upvotes",
112 value: `${this.emoji("ArrowTop")} ${ballot.upvotes.length}`,
113 inline: true
114 },
115 {
116 name: "Downvotes",
117 value: `${this.emoji("ArrowDown")} ${ballot.downvotes.length}`,
118 inline: true
119 }
120 ]
121 }
122 ],
123 components: [
124 new ActionRowBuilder<ButtonBuilder>().addComponents(
125 new ButtonBuilder()
126 .setURL(url)
127 .setStyle(ButtonStyle.Link)
128 .setLabel("Go to ballot message")
129 )
130 ]
131 },
132 embedBuilder({ currentPage, data, maxPages }) {
133 let description = "";
134
135 for (const vote of data) {
136 description += ` * **${vote.type[0].toUpperCase()}${vote.type.substring(
137 1
138 )}** - <@${vote.userId}> [${vote.userId}]\n`;
139 }
140
141 description = description === "" ? "*No vote was recorded*" : description;
142
143 return new EmbedBuilder({
144 color: 0x007bff,
145 description,
146 footer: {
147 text: `Page ${currentPage} of ${maxPages}`
148 }
149 }).setTimestamp();
150 }
151 });
152
153 const reply = await this.deferredReply(message, await pagination.getMessageOptions(1));
154 await pagination.start(reply);
155 }
156 }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26