Skip to content

Commit f3150fd

Browse files
authored
Use DB as source for poll embed creation (#544)
* Update deps * Add poll embed service * Rename * Move delayed poll embed creation * Add findPollOptions * Use embed poll service * Fetch old options from db * Add showAuthor * Resolve TODO * Add poll author check * Remove isPollField * Move letters * Remove import * Fix user name * Also return options * Remove import
1 parent f199d92 commit f3150fd

File tree

10 files changed

+384
-265
lines changed

10 files changed

+384
-265
lines changed

package-lock.json

Lines changed: 40 additions & 40 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,9 @@
5252
"@biomejs/biome": "^2.2.6",
5353
"@types/better-sqlite3": "^7.6.13",
5454
"@types/jsdom": "^27.0.0",
55-
"@types/node": "^24.8.1",
55+
"@types/node": "^24.9.1",
5656
"@types/node-cron": "^3.0.11",
57-
"@typescript/native-preview": "^7.0.0-dev.20251019.1",
57+
"@typescript/native-preview": "^7.0.0-dev.20251021.1",
5858
"expect": "^30.2.0",
5959
"lefthook": "^2.0.0"
6060
},

src/commands/extend.ts

Lines changed: 42 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
import {
22
ActionRowBuilder,
3-
type APIEmbedField,
43
ComponentType,
5-
EmbedBuilder,
64
type GuildTextBasedChannel,
75
type Message,
86
StringSelectMenuBuilder,
@@ -12,16 +10,12 @@ import type { MessageCommand } from "@/commands/command.js";
1210
import type { BotContext } from "@/context.js";
1311
import type { ProcessableMessage } from "@/service/command.js";
1412

13+
import * as pollEmbedService from "@/service/pollEmbed.js";
1514
import { parseLegacyMessageParts } from "@/service/command.js";
16-
import { LETTERS, EMOJI } from "@/service/poll.js";
1715
import * as pollService from "@/service/poll.js";
1816
import { defer } from "@/utils/interactionUtils.js";
19-
import * as poll from "./poll.js";
2017
import { truncateToLength } from "@/utils/stringUtils.js";
2118

22-
const isPollField = (field: APIEmbedField): boolean =>
23-
!field.inline && LETTERS.some(l => field.name.startsWith(l));
24-
2519
type ResolvedPoll = {
2620
message: Message;
2721
description: string;
@@ -60,7 +54,7 @@ async function fetchPollsFromChannel(
6054

6155
export default class ExtendCommand implements MessageCommand {
6256
name = "extend";
63-
description = `Nutzbar als Reply auf eine mit --extendable erstellte Umfrage, um eine/mehrere Antwortmöglichkeit/en hinzuzufügen. Die Anzahl der bestehenden und neuen Antwortmöglichkeiten darf ${poll.OPTION_LIMIT} nicht übersteigen.\nUsage: $COMMAND_PREFIX$extend [Antwort 1] ; [...]`;
57+
description = `Nutzbar als Reply auf eine mit --extendable erstellte Umfrage, um eine/mehrere Antwortmöglichkeit/en hinzuzufügen. Die Anzahl der bestehenden und neuen Antwortmöglichkeiten darf ${pollEmbedService.OPTION_LIMIT} nicht übersteigen.\nUsage: $COMMAND_PREFIX$extend [Antwort 1] ; [...]`;
6458

6559
async handleMessage(message: ProcessableMessage, context: BotContext): Promise<void> {
6660
const { args } = parseLegacyMessageParts(context, message);
@@ -146,15 +140,13 @@ export default class ExtendCommand implements MessageCommand {
146140
return "Bruder das ist keine Umfrage ಠ╭╮ಠ";
147141
}
148142

149-
if (!dbPoll.extendable) {
143+
const { poll, options: oldOptions } = dbPoll;
144+
145+
if (!poll.extendable) {
150146
return "Bruder die Umfrage ist nicht erweiterbar (ง'̀-'́)ง";
151147
}
152148

153-
const oldPollOptionFields = pollMessage.embeds[0].fields.filter(field =>
154-
isPollField(field),
155-
);
156-
157-
if (oldPollOptionFields.length === poll.OPTION_LIMIT) {
149+
if (oldOptions.length === pollEmbedService.OPTION_LIMIT) {
158150
return "Bruder die Umfrage ist leider schon voll (⚆ ͜ʖ⚆)";
159151
}
160152

@@ -163,36 +155,48 @@ export default class ExtendCommand implements MessageCommand {
163155
return "Bruder da sind keine Antwortmöglichkeiten :c";
164156
}
165157

166-
if (additionalPollOptions.length + oldPollOptionFields.length > poll.OPTION_LIMIT) {
167-
return `Bruder mit deinen Antwortmöglichkeiten wird das Limit von ${poll.OPTION_LIMIT} überschritten!`;
158+
if (additionalPollOptions.length + oldOptions.length > pollEmbedService.OPTION_LIMIT) {
159+
return `Bruder mit deinen Antwortmöglichkeiten wird das Limit von ${pollEmbedService.OPTION_LIMIT} überschritten!`;
168160
}
169161

170-
if (additionalPollOptions.some(value => value.length > poll.FIELD_VALUE_LIMIT)) {
171-
return `Bruder mindestens eine Antwortmöglichkeit ist länger als ${poll.FIELD_VALUE_LIMIT} Zeichen!`;
162+
if (
163+
additionalPollOptions.some(value => value.length > pollEmbedService.FIELD_VALUE_LIMIT)
164+
) {
165+
return `Bruder mindestens eine Antwortmöglichkeit ist länger als ${pollEmbedService.FIELD_VALUE_LIMIT} Zeichen!`;
172166
}
173167

174168
for (const option of additionalPollOptions) {
175-
await pollService.addPollOption(message.author, dbPoll, option);
176-
}
177-
178-
const replyEmbed = pollMessage.embeds[0];
179-
const originalAuthor = replyEmbed.author?.name.split(" ").slice(2).join(" ");
180-
const author = originalAuthor === message.author.username ? undefined : message.author;
181-
182-
const newFields = additionalPollOptions.map((value, i) =>
183-
poll.createOptionField(value, oldPollOptionFields.length + i, author),
169+
await pollService.addPollOption(message.author, poll, option);
170+
}
171+
172+
const newPoll = await pollService.findPoll(poll.id);
173+
if (newPoll === undefined) {
174+
throw new Error("Could not find poll that should have been there.");
175+
}
176+
177+
const pollAuthor = (await message.guild.members.fetch(newPoll.poll.authorId))?.user ?? {
178+
username: "<unbekannt>",
179+
iconURL: undefined,
180+
};
181+
182+
const embed = pollEmbedService.buildPollEmbed(
183+
message.channel,
184+
{
185+
question: newPoll.poll.question,
186+
anonymous: newPoll.poll.anonymous,
187+
extendable: newPoll.poll.extendable,
188+
ended: newPoll.poll.ended,
189+
endsAt: newPoll.poll.endsAt ? new Date(newPoll.poll.endsAt) : null,
190+
multipleChoices: newPoll.poll.multipleChoices,
191+
author: pollAuthor,
192+
},
193+
newPoll.options.map(o => ({
194+
index: o.index,
195+
option: o.option,
196+
author: message.guild.members.cache.get(o.authorId)?.user,
197+
})),
184198
);
185199

186-
let metaFields = pollMessage.embeds[0].fields.filter(field => !isPollField(field));
187-
const embed = EmbedBuilder.from(pollMessage.embeds[0]).data;
188-
189-
if (oldPollOptionFields.length + additionalPollOptions.length === poll.OPTION_LIMIT) {
190-
embed.color = 0xcd5c5c;
191-
metaFields = metaFields.filter(field => !field.name.endsWith("Erweiterbar"));
192-
}
193-
194-
embed.fields = [...oldPollOptionFields, ...newFields, ...metaFields];
195-
196200
const msg = await pollMessage.edit({
197201
embeds: [embed],
198202
// Re-Applying embed thumbnails from attachments will post a picture,
@@ -201,7 +205,7 @@ export default class ExtendCommand implements MessageCommand {
201205
});
202206

203207
for (const i in additionalPollOptions) {
204-
await msg.react(EMOJI[oldPollOptionFields.length + Number(i)]);
208+
await msg.react(pollEmbedService.EMOJI[oldOptions.length + Number(i)]);
205209
}
206210
await message.delete();
207211
}

0 commit comments

Comments
 (0)