From 0c2d0b15135a53d40e3c59ede5d499686c4b4f00 Mon Sep 17 00:00:00 2001 From: Larsundso Date: Tue, 21 Nov 2023 22:50:03 +0100 Subject: [PATCH] add sticker command --- .../ClientHelperModules/getLanguage.ts | 4 +- src/BaseClient/Other/constants.ts | 5 +- src/BaseClient/Other/language.ts | 1 + .../Other/language/slashCommands/info.ts | 2 + .../language/slashCommands/info/stickers.ts | 6 + src/Commands/ButtonCommands/info/emojis.ts | 2 +- src/Commands/ButtonCommands/info/servers.ts | 2 +- src/Commands/ButtonCommands/info/stickers.ts | 5 + .../ChannelSelect/embed-builder/send.ts | 2 +- src/Commands/SlashCommands/info/emoji.ts | 1 + src/Commands/SlashCommands/info/servers.ts | 1 + src/Commands/SlashCommands/info/sticker.ts | 234 ++++++++++++++++++ .../stickers/create/from-message.ts | 6 +- src/Commands/SlashCommands/stickers/delete.ts | 2 +- .../stickers/edit/description.ts | 2 +- .../SlashCommands/stickers/edit/emoji.ts | 4 +- .../SlashCommands/stickers/edit/name.ts | 2 +- src/Commands/SlashCommands/stickers/info.ts | 4 +- .../startupTasks/slashCommands/info.ts | 11 + 19 files changed, 281 insertions(+), 15 deletions(-) create mode 100644 src/BaseClient/Other/language/slashCommands/info/stickers.ts create mode 100644 src/Commands/ButtonCommands/info/stickers.ts create mode 100644 src/Commands/SlashCommands/info/sticker.ts diff --git a/src/BaseClient/ClientHelperModules/getLanguage.ts b/src/BaseClient/ClientHelperModules/getLanguage.ts index 455acd71d..e9bebe121 100644 --- a/src/BaseClient/ClientHelperModules/getLanguage.ts +++ b/src/BaseClient/ClientHelperModules/getLanguage.ts @@ -10,7 +10,7 @@ export default async (guildIDOrLocale: bigint | undefined | null | string) => { if (!guildIDOrLocale) { const { default: Lang } = await import('../Other/language.js'); - const lang = new Lang('en'); + const lang = new Lang('en-GB'); await lang.init(); return lang; @@ -30,7 +30,7 @@ export default async (guildIDOrLocale: bigint | undefined | null | string) => { .then((r) => r?.lan); const { default: Lang } = await import('../Other/language.js'); - const lang = new Lang(lan || 'en'); + const lang = new Lang((lan === 'en' ? 'en-GB' : lan) || 'en-GB'); await lang.init(); return lang; diff --git a/src/BaseClient/Other/constants.ts b/src/BaseClient/Other/constants.ts index e577a754f..67b35861b 100644 --- a/src/BaseClient/Other/constants.ts +++ b/src/BaseClient/Other/constants.ts @@ -244,7 +244,10 @@ export default { `https://cdn.discordapp.com/emojis/${emote.id}.${emote.animated ? 'gif' : 'png'}?size=4096`, getEmote: ( emoji: Discord.Emoji | { name: string; id?: string | null; animated?: boolean | null }, - ) => (emoji.id ? `<${emoji.animated ? 'a:' : ':'}${emoji.name}:${emoji.id}>` : `${emoji.name}`), + ) => + emoji.id + ? `<${emoji.animated ? 'a:' : ':'}${emoji.name}:${emoji.id}>` + : `${/\w/g.test(emoji.name ?? '') ? `:${emoji.name}:` : emoji.name}`, getTime: (time: number) => ` ()`, msgurl: (g: string | undefined | null, c: string, m: string) => diff --git a/src/BaseClient/Other/language.ts b/src/BaseClient/Other/language.ts index 4b7feb179..f9a0034ca 100644 --- a/src/BaseClient/Other/language.ts +++ b/src/BaseClient/Other/language.ts @@ -79,6 +79,7 @@ export default class Language { auditLogAction: { [key in Discord.GuildAuditLogsEntry['action']]: string } = auditLogAction(this); constructor(type: string | 'en-GB') { + if (type === 'en') throw new Error('EN given'); this.CURRENT_LANGUAGE = type; } diff --git a/src/BaseClient/Other/language/slashCommands/info.ts b/src/BaseClient/Other/language/slashCommands/info.ts index f9a7d14e7..aa2277f0d 100644 --- a/src/BaseClient/Other/language/slashCommands/info.ts +++ b/src/BaseClient/Other/language/slashCommands/info.ts @@ -7,6 +7,7 @@ import bot from './info/bot.js'; import user from './info/user.js'; import server from './info/server.js'; import channel from './info/channel.js'; +import stickers from './info/stickers.js'; export default (t: CT.Language) => ({ ...t.JSON.slashCommands.info, @@ -18,4 +19,5 @@ export default (t: CT.Language) => ({ user: user(t), server: server(t), channel: channel(t), + stickers: stickers(t), }); diff --git a/src/BaseClient/Other/language/slashCommands/info/stickers.ts b/src/BaseClient/Other/language/slashCommands/info/stickers.ts new file mode 100644 index 000000000..b73881fd2 --- /dev/null +++ b/src/BaseClient/Other/language/slashCommands/info/stickers.ts @@ -0,0 +1,6 @@ +import * as CT from '../../../../../Typings/CustomTypings.js'; + +export default (t: CT.Language) => ({ + ...t.JSON.slashCommands.info.stickers, + author: t.stp(t.JSON.slashCommands.info.stickers.author, { t }), +}); diff --git a/src/Commands/ButtonCommands/info/emojis.ts b/src/Commands/ButtonCommands/info/emojis.ts index bca2db13d..b68e88ca2 100644 --- a/src/Commands/ButtonCommands/info/emojis.ts +++ b/src/Commands/ButtonCommands/info/emojis.ts @@ -2,4 +2,4 @@ import * as Discord from 'discord.js'; import emojis from '../../SlashCommands/info/emoji.js'; export default async (cmd: Discord.ButtonInteraction, args: string[]) => - emojis(cmd, Number(args.shift())); + emojis(cmd, [], Number(args.shift())); diff --git a/src/Commands/ButtonCommands/info/servers.ts b/src/Commands/ButtonCommands/info/servers.ts index 2dd765b22..f1bf8ca6b 100644 --- a/src/Commands/ButtonCommands/info/servers.ts +++ b/src/Commands/ButtonCommands/info/servers.ts @@ -2,4 +2,4 @@ import * as Discord from 'discord.js'; import servers from '../../SlashCommands/info/servers.js'; export default async (cmd: Discord.ButtonInteraction, args: string[]) => - servers(cmd, Number(args.shift())); + servers(cmd, [], Number(args.shift())); diff --git a/src/Commands/ButtonCommands/info/stickers.ts b/src/Commands/ButtonCommands/info/stickers.ts new file mode 100644 index 000000000..37bf29c29 --- /dev/null +++ b/src/Commands/ButtonCommands/info/stickers.ts @@ -0,0 +1,5 @@ +import * as Discord from 'discord.js'; +import sticker from '../../SlashCommands/info/sticker.js'; + +export default async (cmd: Discord.ButtonInteraction, args: string[]) => + sticker(cmd, [], Number(args.shift())); diff --git a/src/Commands/SelectCommands/ChannelSelect/embed-builder/send.ts b/src/Commands/SelectCommands/ChannelSelect/embed-builder/send.ts index 833b0e059..842702da7 100644 --- a/src/Commands/SelectCommands/ChannelSelect/embed-builder/send.ts +++ b/src/Commands/SelectCommands/ChannelSelect/embed-builder/send.ts @@ -10,7 +10,7 @@ export default async (cmd: Discord.ChannelSelectMenuInteraction) => { const lan = language.slashCommands.embedbuilder.send; await ch.send(channels, { - embeds: [new Discord.EmbedBuilder(cmd.message.embeds[0].data).data], + embeds: [new Discord.EmbedBuilder(cmd.message.embeds[1].data).data], }); cmd.reply({ diff --git a/src/Commands/SlashCommands/info/emoji.ts b/src/Commands/SlashCommands/info/emoji.ts index d41ee0d2c..d82080077 100644 --- a/src/Commands/SlashCommands/info/emoji.ts +++ b/src/Commands/SlashCommands/info/emoji.ts @@ -5,6 +5,7 @@ import client from '../../../BaseClient/Client.js'; export default async ( cmd: Discord.ChatInputCommandInteraction | Discord.ButtonInteraction, + _args: string[], page?: number, ) => { if ( diff --git a/src/Commands/SlashCommands/info/servers.ts b/src/Commands/SlashCommands/info/servers.ts index 73ba51128..1c0901a13 100644 --- a/src/Commands/SlashCommands/info/servers.ts +++ b/src/Commands/SlashCommands/info/servers.ts @@ -5,6 +5,7 @@ import * as CT from '../../../Typings/CustomTypings.js'; export default async ( cmd: Discord.ChatInputCommandInteraction | Discord.ButtonInteraction, + _args: string[], page = 1, ) => { if (cmd.inGuild() && !cmd.inCachedGuild()) return; diff --git a/src/Commands/SlashCommands/info/sticker.ts b/src/Commands/SlashCommands/info/sticker.ts new file mode 100644 index 000000000..ff4291ea7 --- /dev/null +++ b/src/Commands/SlashCommands/info/sticker.ts @@ -0,0 +1,234 @@ +import * as Discord from 'discord.js'; +import * as ch from '../../../BaseClient/ClientHelper.js'; +import * as CT from '../../../Typings/CustomTypings.js'; + +export default async ( + cmd: Discord.ChatInputCommandInteraction | Discord.ButtonInteraction, + _args: string[], + page?: number, +) => { + if (!cmd.inCachedGuild()) return; + + const messageLinkOrStickerID = + cmd instanceof Discord.ChatInputCommandInteraction + ? cmd.options.getString('sticker', false) + : undefined; + const language = await ch.getLanguage(cmd.locale); + + if (messageLinkOrStickerID) single(cmd as Discord.ChatInputCommandInteraction<'cached'>, language); + else multiple(cmd, language, page); +}; + +const single = async ( + cmd: Discord.ChatInputCommandInteraction<'cached'>, + language: CT.Language, +) => { + let stickerIDs: string[] = []; + + const messageLinkOrStickerID = cmd.options.getString('sticker', true); + + if (messageLinkOrStickerID.includes('discord.com')) { + const message = await ch.getMessage(messageLinkOrStickerID); + if (!message) { + ch.errorCmd(cmd, language.errors.messageNotFound, language); + return; + } + + stickerIDs = message.stickers.map((s) => s.id); + } else { + stickerIDs = [messageLinkOrStickerID]; + } + + const stickers = ( + await Promise.all(stickerIDs.map((s) => cmd.client.fetchSticker(s).catch(() => undefined))) + ).filter((s): s is Discord.Sticker => !!s); + if (!stickers.length) { + ch.errorCmd(cmd, language.errors.stickerNotFound, language); + return; + } + + ch.replyCmd(cmd, { embeds: await getEmbeds(stickers, cmd, language) }); +}; + +export const multiple = async ( + cmd: Discord.ChatInputCommandInteraction<'cached'> | Discord.ButtonInteraction<'cached'>, + language: CT.Language, + page: number = 1, +) => { + const embeds = await getEmbeds( + cmd.guild.stickers.cache.map((s) => s).slice((page - 1) * 10, page * 10), + cmd, + language, + ); + + const components: Discord.APIActionRowComponent[] = [ + { + type: Discord.ComponentType.ActionRow, + components: [ + { + type: Discord.ComponentType.Button, + style: Discord.ButtonStyle.Secondary, + custom_id: `info/stickers_${page - 1}`, + emoji: ch.emotes.back, + disabled: page === 1, + }, + { + type: Discord.ComponentType.Button, + style: Discord.ButtonStyle.Secondary, + disabled: true, + custom_id: '-', + label: `${page}/${Math.ceil(cmd.guild.stickers.cache.size / 10)}`, + }, + { + type: Discord.ComponentType.Button, + style: Discord.ButtonStyle.Secondary, + custom_id: `info/stickers_${page + 1}`, + emoji: ch.emotes.forth, + disabled: page === Math.ceil(cmd.guild.stickers.cache.size / 10), + }, + ], + }, + ]; + + if (cmd instanceof Discord.ButtonInteraction) { + cmd.update({ embeds, components }); + return; + } + + ch.replyCmd(cmd, { embeds, components }); +}; + +const getEmbeds = async ( + stickers: Discord.Sticker[], + cmd: Discord.ChatInputCommandInteraction<'cached'> | Discord.ButtonInteraction<'cached'>, + language: CT.Language, +): Promise => { + const lan = language.slashCommands.info.stickers; + const packs = stickers.find((s) => s.packId) + ? await cmd.client.fetchPremiumStickerPacks() + : undefined; + const color = ch.getColor(cmd.guild ? await ch.getBotMemberFromGuild(cmd.guild) : undefined); + + return stickers.map((sticker) => { + const pack = packs?.find((p) => p.id === sticker.packId); + const partialEmoji = sticker.tags ? Discord.resolvePartialEmoji(sticker.tags) : undefined; + const emoji = partialEmoji?.id + ? sticker.guild?.emojis.cache.get(partialEmoji.id) + : (partialEmoji as { name: string; animated: false; id: undefined }); + + return { + color, + author: { + name: lan.author, + }, + thumbnail: { + url: sticker.url, + }, + description: [ + sticker.name + ? { + name: `${ch.util.makeBold(language.t.name)}:`, + value: `${ch.util.makeInlineCode(sticker.name)}`, + } + : undefined, + sticker.description + ? { + name: `${ch.util.makeBold(language.t.Description)}:`, + value: `${ch.util.makeInlineCode(sticker.description)}`, + } + : undefined, + sticker.id + ? { + name: `${ch.util.makeBold('ID')}:`, + value: `${ch.util.makeInlineCode(sticker.id)}`, + } + : undefined, + sticker.url + ? { + name: `${ch.util.makeBold('URL')}:`, + value: sticker.url, + } + : undefined, + sticker.createdTimestamp + ? { + name: `${ch.util.makeBold(language.t.createdAt)}:`, + value: `${ch.constants.standard.getTime(sticker.createdTimestamp)}`, + } + : undefined, + { + name: `${ch.util.makeBold(language.slashCommands.info.emojis.available)}:`, + value: `${ch.settingsHelpers.embedParsers.boolean(!!sticker.available, language)}`, + }, + sticker.guild + ? { + name: `\n${ch.util.makeBold(language.t.Server)}:\n`, + value: language.languageFunction.getGuild(sticker.guild), + } + : undefined, + sticker.user + ? { + name: `${ch.util.makeBold(language.slashCommands.info.emojis.uploader)}:\n`, + value: language.languageFunction.getUser(sticker.user), + } + : undefined, + sticker.format + ? { + name: `${ch.util.makeBold(lan.formatName)}: `, + value: `${ch.util.makeInlineCode(Discord.StickerFormatType[sticker.format])}`, + } + : undefined, + emoji + ? { + name: `${ch.util.makeBold(lan.tags)}: `, + value: `${ch.constants.standard.getEmote(emoji)}`, + } + : undefined, + ] + .filter((v): v is { name: string; value: string } => !!v) + .map((v) => `${v.name} ${v.value}`) + .join('\n'), + fields: pack + ? [ + { + name: lan.pack, + value: [ + pack.name + ? { + name: `${ch.util.makeBold(language.t.name)}:`, + value: `${ch.util.makeInlineCode(pack.name)}`, + } + : undefined, + pack.description + ? { + name: `${ch.util.makeBold(language.t.Description)}:`, + value: `${ch.util.makeInlineCode(pack.description)}`, + } + : undefined, + pack.id + ? { + name: `${ch.util.makeBold('ID')}:`, + value: `${ch.util.makeInlineCode(pack.id)}`, + } + : undefined, + pack.createdTimestamp + ? { + name: `${ch.util.makeBold(language.t.createdAt)}:`, + value: `${ch.constants.standard.getTime(pack.createdTimestamp)}`, + } + : undefined, + ] + .filter((v): v is { name: string; value: string } => !!v) + .map((v) => `${v.name} ${v.value}`) + .join('\n'), + }, + ] + : undefined, + image: + pack && pack.bannerId + ? { + url: pack.bannerURL({ size: 4096 }) as string, + } + : undefined, + }; + }); +}; diff --git a/src/Commands/SlashCommands/stickers/create/from-message.ts b/src/Commands/SlashCommands/stickers/create/from-message.ts index 4259f9641..145d76368 100644 --- a/src/Commands/SlashCommands/stickers/create/from-message.ts +++ b/src/Commands/SlashCommands/stickers/create/from-message.ts @@ -14,13 +14,13 @@ export default async (cmd: Discord.ChatInputCommandInteraction<'cached'>) => { const selectedEmoji = Emojis.find((e) => e === emoji.replace(/:/g, '')); if (!selectedEmoji) { - ch.errorCmd(cmd, language.t.errors.emoteNotFound, language); + ch.errorCmd(cmd, language.errors.emoteNotFound, language); return; } const message = await ch.getMessage(messageLink); if (!message) { - ch.errorCmd(cmd, language.t.errors.messageNotFound, language); + ch.errorCmd(cmd, language.errors.messageNotFound, language); return; } @@ -28,7 +28,7 @@ export default async (cmd: Discord.ChatInputCommandInteraction<'cached'>) => { ? message.stickers.find((s) => s.name === stickerName || s.id === stickerName) : message.stickers.first(); if (!sticker) { - ch.errorCmd(cmd, language.t.errors.stickerNotFound, language); + ch.errorCmd(cmd, language.errors.stickerNotFound, language); return; } diff --git a/src/Commands/SlashCommands/stickers/delete.ts b/src/Commands/SlashCommands/stickers/delete.ts index bbf83113f..d6c0e979b 100644 --- a/src/Commands/SlashCommands/stickers/delete.ts +++ b/src/Commands/SlashCommands/stickers/delete.ts @@ -10,7 +10,7 @@ export default async (cmd: Discord.ChatInputCommandInteraction<'cached'>) => { (s) => s.id === stickerIDorName || s.name === stickerIDorName, ); if (!sticker) { - ch.errorCmd(cmd, language.t.errors.stickerNotFound, language); + ch.errorCmd(cmd, language.errors.stickerNotFound, language); return; } diff --git a/src/Commands/SlashCommands/stickers/edit/description.ts b/src/Commands/SlashCommands/stickers/edit/description.ts index bdaf5afce..ecd380dca 100644 --- a/src/Commands/SlashCommands/stickers/edit/description.ts +++ b/src/Commands/SlashCommands/stickers/edit/description.ts @@ -16,7 +16,7 @@ export default async ( (s) => s.name === stickerIDorName || s.id === stickerIDorName, ); if (!sticker) { - ch.errorCmd(cmd, language.t.errors.stickerNotFound, language); + ch.errorCmd(cmd, language.errors.stickerNotFound, language); return; } diff --git a/src/Commands/SlashCommands/stickers/edit/emoji.ts b/src/Commands/SlashCommands/stickers/edit/emoji.ts index 4fece6012..783167c2c 100644 --- a/src/Commands/SlashCommands/stickers/edit/emoji.ts +++ b/src/Commands/SlashCommands/stickers/edit/emoji.ts @@ -11,7 +11,7 @@ export default async (cmd: Discord.ChatInputCommandInteraction<'cached'>) => { const selectedEmoji = Emojis.find((e) => e === emoji.replace(/:/g, '')); if (!selectedEmoji) { - ch.errorCmd(cmd, language.t.errors.emoteNotFound, language); + ch.errorCmd(cmd, language.errors.emoteNotFound, language); return; } @@ -19,7 +19,7 @@ export default async (cmd: Discord.ChatInputCommandInteraction<'cached'>) => { (s) => s.name === stickerIDorName || s.id === stickerIDorName, ); if (!sticker) { - ch.errorCmd(cmd, language.t.errors.stickerNotFound, language); + ch.errorCmd(cmd, language.errors.stickerNotFound, language); return; } diff --git a/src/Commands/SlashCommands/stickers/edit/name.ts b/src/Commands/SlashCommands/stickers/edit/name.ts index 8265df1a6..f3e0968c6 100644 --- a/src/Commands/SlashCommands/stickers/edit/name.ts +++ b/src/Commands/SlashCommands/stickers/edit/name.ts @@ -12,7 +12,7 @@ export default async (cmd: Discord.ChatInputCommandInteraction<'cached'>) => { (s) => s.name === stickerIDorName || s.id === stickerIDorName, ); if (!sticker) { - ch.errorCmd(cmd, language.t.errors.stickerNotFound, language); + ch.errorCmd(cmd, language.errors.stickerNotFound, language); return; } diff --git a/src/Commands/SlashCommands/stickers/info.ts b/src/Commands/SlashCommands/stickers/info.ts index 70b786d12..a50431b19 100644 --- a/src/Commands/SlashCommands/stickers/info.ts +++ b/src/Commands/SlashCommands/stickers/info.ts @@ -1 +1,3 @@ -// TODO +import sticker from '../info/sticker.js'; + +export default sticker; diff --git a/src/Events/readyEvents/startupTasks/slashCommands/info.ts b/src/Events/readyEvents/startupTasks/slashCommands/info.ts index 459f0ba62..5c0bf12b8 100644 --- a/src/Events/readyEvents/startupTasks/slashCommands/info.ts +++ b/src/Events/readyEvents/startupTasks/slashCommands/info.ts @@ -109,4 +109,15 @@ export default new Discord.SlashCommandBuilder() .setDescription('The Emoji you want to get Information about') .setRequired(false), ), + ) + .addSubcommand( + new Discord.SlashCommandSubcommandBuilder() + .setName('sticker') + .setDescription('Display Information about a Sticker') + .addStringOption( + new Discord.SlashCommandStringOption() + .setName('sticker') + .setDescription('A Message Link to the Sticker you want info about (can also be a Sticker ID)') + .setRequired(false), + ), );