Denim-Bot/src/modules/anketa.ts
2024-01-29 22:54:45 +01:00

95 lines
3.6 KiB
TypeScript

// Modul na komand "anketa"
import { ActionRowBuilder, APIEmbed, APIEmbedField, ButtonBuilder, ButtonStyle, CommandInteraction, ComponentType, Message, MessageComponentInteraction } from "discord.js";
import { Modul, SRecord } from "../utils/types";
import { formatter } from "../utils/utils";
function lookup<T>(opt: CommandInteraction["options"], item: string) {
return opt.get(item)?.value as T | undefined;
}
const exp: Modul = {
more_komandy: {
anketa: {
DMUnsafe: true,
slashRun: async int => {
const opt = int.options;
const settings = {
time: lookup<number>(opt, "cas") || 60,
immediateShow: !lookup<boolean>(opt, "neprubezny"),
listNames: lookup<boolean>(opt, "jmena")
};
const str = lookup<string>(opt, "moznosti")!;
const moznosti = str.split(str.includes("|") ? "|" : ",").reduce<string[]>((acc, c) => {
if (c.length) acc.push(c.trim());
return acc;
}, []);
if (moznosti.length < 2) return "zadej alespo%n dve moznosti";
if (moznosti.length > 25) return "toje moc";
const konec = new Date();
konec.setSeconds(konec.getSeconds() + settings.time);
const embed: APIEmbed = {
title: "Hlasování",
description: settings.immediateShow ? `Končí ${formatter(konec)}` : `Výsledky se zobrazí ${formatter(konec)}`
};
const fildy: APIEmbedField[] = [];
const radky: ActionRowBuilder<ButtonBuilder>[] = [];
const odpovedi: SRecord<number> = {};
function prepocitat(interaction?: MessageComponentInteraction) {
const celkem = Object.keys(odpovedi).length;
fildy.forEach((f, i) => {
const hovn = Object.values(odpovedi).filter(n => n == i);
const dylka = hovn.length;
const p = Math.floor(dylka / celkem * 10) || 0;
const people = Object.keys(odpovedi).reduce<string[]>((pr, cur) => {
if (odpovedi[cur] == i) pr.push(cur);
return pr;
}, []);
const kindo = people.map(w => int.guild?.members.cache.get(w)?.displayName);
f.value = `${"█".repeat(p)}${"░".repeat(10 - p)} ${Math.round(dylka / celkem * 100) || 0}% (${dylka}) ${settings.listNames ? " (" + kindo.join(", ") + ")" : ""}`;
});
interaction?.update({ embeds: [embed] });
}
moznosti.forEach((h, i) => {
const mnam = (i - (i % 5)) / 5;
if (i % 5 == 0) radky[mnam] = new ActionRowBuilder<ButtonBuilder>;
fildy.push({ name: h, value: "" });
radky[mnam].addComponents(new ButtonBuilder({ customId: `${i}`, label: h, style: ButtonStyle.Primary }));
});
prepocitat();
if (settings.immediateShow) embed.fields = fildy;
const zprava = await int.reply({ embeds: [embed], components: radky });
const collector = zprava.createMessageComponentCollector<ComponentType.Button>({ time: settings.time * 1000 });
collector.on("collect", d => {
if (!(d.message instanceof Message)) return;
const i = Number(d.customId);
const prev = odpovedi[d.user.id];
if (prev == i) return void d.deferUpdate();
odpovedi[d.user.id] = i;
if (!settings.immediateShow) return void d.deferUpdate();
prepocitat();
d.update({ embeds: [embed] });
});
collector.on("end", () => {
embed.description = `Skončilo ${formatter(konec)}`;
prepocitat();
embed.fields = fildy;
int.editReply({ components: [], embeds: [embed] });
});
}
}
}
};
module.exports = exp;