import { Client, CommandInteraction, GuildMember, EmbedBuilder, TextChannel, AutocompleteInteraction } from 'discord.js'; import { getSign } from './util'; import { Counter, db } from './db'; export async function getCounter(type: string) { const counter = await db('counters') .where('key', type) .first(); if (!counter) throw 'No such counter'; return counter.value; } export async function changeCounter(delta: number, type: string) { const value = await getCounter(type); const newValue = value + delta; await db('counters') .where('key', type) .update({ 'value': newValue }); return newValue; } export async function getCounterData(type: string) { const counter = await db('counters') .select('*') .where('key', type) .first(); if (!counter) throw 'No such counter'; return counter; } export async function updateCounter(bot: Client, counter: Counter, value: number) { const channel = await bot.channels.fetch(counter.channel) as TextChannel; const messageID = counter.message; const content = `[${counter.emoji}] x${value}`; // bit janky // yeah you don't say try { if (messageID) { const message = await channel.messages.fetch(messageID); if (!message) throw new Error(); await message.edit(content); } else { throw new Error(); } } catch(err) { const message = await channel.send(content); message.pin(); await db('counters') .where('key', counter.key) .update({ 'message': message.id }); } } export async function announceCounterUpdate(bot: Client, member: GuildMember, delta: number, counter: Counter, value: number) { const channel = await bot.channels.fetch(counter.channel) as TextChannel; const embed = new EmbedBuilder() .setAuthor({ name: `${member.user.username}#${member.user.discriminator}`, iconURL: member.user.displayAvatarURL() }) .setDescription(`**${member.toString()}** has ${delta > 0 ? 'increased' : 'decreased'} the counter by **${Math.abs(delta)}**.`) .setColor(member.displayColor) .setTimestamp() .setFooter({ text: `[${counter.emoji}] x${value}` }); await channel.send({ embeds: [embed] }); } export async function changeCounterInteraction(interaction: CommandInteraction, member: GuildMember, amount: number, type: string) { try { const counter = await getCounterData(type); const newCount = await changeCounter(amount, type); await updateCounter(interaction.client, counter, newCount); await announceCounterUpdate(interaction.client, member, amount, counter, newCount); interaction.followUp({ content: `${counter.emoji} **You have ${amount > 0 ? 'increased' : 'decreased'} the counter.**\n\`\`\`diff\n ${newCount - amount}\n${getSign(amount)}${Math.abs(amount)}\n ${newCount}\`\`\`` }); } catch(err) { interaction.followUp({ content: (err as Error).toString() }); } } export async function counterAutocomplete(interaction: AutocompleteInteraction) { const focusedValue = interaction.options.getFocused(); const guild = interaction.guildId; const query = db('counters') .select('name', 'key') .whereLike('name', `%${focusedValue.toLowerCase()}%`) .limit(25); if (guild) { query.where('guild', guild); } const foundCounters = await query; await interaction.respond( foundCounters.map(choice => ({ name: choice.name, value: choice.key })) ); }