95 lines
3.6 KiB
TypeScript
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;
|