From aa412befca9f5fa7f81649cc9e0729f8608c7d2b Mon Sep 17 00:00:00 2001 From: Evorp <3vorpgaming@gmail.com> Date: Fri, 6 Oct 2023 22:36:48 -0700 Subject: [PATCH] readd magnification and more ephemeral translations --- lang/en-US/commands.json | 5 +++-- src/commands/images/animate.ts | 2 +- src/commands/images/magnify.ts | 23 ++++++++++++++++++++--- src/commands/images/tile.ts | 19 ++++++++++++++++--- src/components/buttons/image/magnify.ts | 8 +------- src/components/buttons/image/palette.ts | 2 +- src/components/buttons/image/tile.ts | 16 +++++++++++----- src/helpers/images/magnify.ts | 23 ++++++++++++++++++----- src/helpers/images/tile.ts | 6 ++++++ src/helpers/prefixCommandHandler.ts | 9 +++++++-- 10 files changed, 84 insertions(+), 29 deletions(-) diff --git a/lang/en-US/commands.json b/lang/en-US/commands.json index f637d0709..13ba4c9ab 100644 --- a/lang/en-US/commands.json +++ b/lang/en-US/commands.json @@ -9,8 +9,9 @@ "title": "You cannot run slash commands in a submission channel!", "description": "Please use the appropriate bot command channel instead." }, - "images": { - "too_big": "Output exceeds the maximum of 512px²!" + "tile": { + "too_big": "This image is too big to be tiled!", + "suggestion": "Try scaling your image down or using another program." }, "stats": { "footer": "Made with love", diff --git a/src/commands/images/animate.ts b/src/commands/images/animate.ts index 5203ae7b1..5e5593391 100644 --- a/src/commands/images/animate.ts +++ b/src/commands/images/animate.ts @@ -37,7 +37,7 @@ export const command: SlashCommand = { const mcmeta: MCMETA = mcmetaList[style]; // magnify beforehand since you can't magnify a gif currently - const { magnified } = await magnify(image, true); + const { magnified } = await magnify(image, { isAnimation: true }); const file = await animateToAttachment(await loadImage(magnified), mcmeta, `${style}.gif`); await interaction .editReply({ files: [file] }) diff --git a/src/commands/images/magnify.ts b/src/commands/images/magnify.ts index 7ad3082a3..b0202e601 100644 --- a/src/commands/images/magnify.ts +++ b/src/commands/images/magnify.ts @@ -1,7 +1,9 @@ import { SlashCommand } from "@interfaces"; -import { SlashCommandBuilder } from "discord.js"; -import { ChatInputCommandInteraction, EmbedBuilder } from "@client"; +import { ActionRowBuilder, ButtonBuilder, SlashCommandBuilder } from "discord.js"; +import { ChatInputCommandInteraction, Message } from "@client"; import { magnifyToAttachment } from "@images/magnify"; +import getImage from "@helpers/getImage"; +import { tile, palette } from "@helpers/buttons"; export const command: SlashCommand = { data: new SlashCommandBuilder() @@ -25,5 +27,20 @@ export const command: SlashCommand = { .setDescription("The scale factor the image should be enlarged by.") .setRequired(false); }), - async execute(interaction: ChatInputCommandInteraction) {}, + async execute(interaction: ChatInputCommandInteraction) { + await interaction.deferReply(); + const image = + interaction.options.getAttachment("image", false)?.url ?? (await getImage(interaction)); + + const file = await magnifyToAttachment(image, { + factor: interaction.options.getNumber("factor", false), + }); + + await interaction + .editReply({ + files: [file], + components: [new ActionRowBuilder().addComponents(palette)], + }) + .then((message: Message) => message.deleteButton()); + }, }; diff --git a/src/commands/images/tile.ts b/src/commands/images/tile.ts index c45c1387b..202439fda 100644 --- a/src/commands/images/tile.ts +++ b/src/commands/images/tile.ts @@ -1,9 +1,10 @@ import { SlashCommand } from "@interfaces"; import { SlashCommandBuilder } from "discord.js"; -import { ChatInputCommandInteraction, Message } from "@client"; +import { ChatInputCommandInteraction, EmbedBuilder, Message } from "@client"; import { tileToAttachment, TileShape, TileRandom } from "@images/tile"; import getImage from "@helpers/getImage"; import { imageButtons } from "@helpers/buttons"; +import { colors } from "@helpers/colors"; export const command: SlashCommand = { data: new SlashCommandBuilder() @@ -36,7 +37,6 @@ export const command: SlashCommand = { o.setName("image").setDescription("The image to tile").setRequired(false), ), async execute(interaction: ChatInputCommandInteraction) { - await interaction.deferReply(); const random = interaction.options.getString("random") as TileRandom; const shape = interaction.options.getString("type") as TileShape; @@ -44,10 +44,23 @@ export const command: SlashCommand = { interaction.options.getAttachment("image", false)?.url ?? (await getImage(interaction)); const file = await tileToAttachment(image, { random, shape }); + + if (!file) { + return await interaction.reply({ + embeds: [ + new EmbedBuilder() + .setTitle(interaction.strings().command.tile.too_big) + .setDescription(interaction.strings().command.tile.suggestion) + .setColor(colors.red), + ], + ephemeral: true + }); + } await interaction - .editReply({ + .reply({ files: [file], components: [imageButtons], + fetchReply: true, }) .then((message: Message) => message.deleteButton()); }, diff --git a/src/components/buttons/image/magnify.ts b/src/components/buttons/image/magnify.ts index 0f01ceec0..31329502d 100644 --- a/src/components/buttons/image/magnify.ts +++ b/src/components/buttons/image/magnify.ts @@ -14,13 +14,7 @@ export default { const message: Message = interaction.message as Message; const url = await getImage(message); - const attachment = await magnifyToAttachment(url, url.split("/").at(-1)); - - if (attachment == null) - return interaction.reply({ - content: interaction.strings().command.images.too_big, - ephemeral: true, - }); + const attachment = await magnifyToAttachment(url); return interaction .reply({ diff --git a/src/components/buttons/image/palette.ts b/src/components/buttons/image/palette.ts index 58e3b95c8..080794a41 100644 --- a/src/components/buttons/image/palette.ts +++ b/src/components/buttons/image/palette.ts @@ -11,7 +11,7 @@ export default { const message: Message = interaction.message as Message; const url = await getImage(message); - const [attachment, embed] = await paletteToAttachment(url, url.split("/").at(-1)); + const [attachment, embed] = await paletteToAttachment(url); return interaction .reply({ diff --git a/src/components/buttons/image/tile.ts b/src/components/buttons/image/tile.ts index 81b0ede1a..4620148c0 100644 --- a/src/components/buttons/image/tile.ts +++ b/src/components/buttons/image/tile.ts @@ -6,6 +6,7 @@ import { magnify, palette } from "@helpers/buttons"; import { ActionRowBuilder } from "discord.js"; import { ButtonBuilder } from "discord.js"; import getImage from "@helpers/getImage"; +import { colors } from "@helpers/colors"; export default { id: "tile", @@ -14,12 +15,17 @@ export default { const message: Message = interaction.message as Message; const url = await getImage(message); - const attachment = await tileToAttachment(url, {}, url.split("/").at(-1)); + const attachment = await tileToAttachment(url); - if (attachment == null) - return interaction.reply({ - content: interaction.strings().command.images.too_big, - ephemeral: true, + if (!attachment) + return await interaction.reply({ + embeds: [ + new EmbedBuilder() + .setTitle(interaction.strings().command.tile.too_big) + .setDescription(interaction.strings().command.tile.suggestion) + .setColor(colors.red), + ], + ephemeral: true }); return interaction diff --git a/src/helpers/images/magnify.ts b/src/helpers/images/magnify.ts index 396d7e0de..8aa8f12f8 100644 --- a/src/helpers/images/magnify.ts +++ b/src/helpers/images/magnify.ts @@ -11,19 +11,25 @@ export type ImageSource = | Image | import("stream").Readable; +export interface MagnifyOptions { + isAnimation?: boolean; + factor?: number; +} + /** * The actual magnification function * @author Juknum, Evorp * @param origin url, image, or buffer to magnify - * @param isAnimation whether to magnify the image as a tilesheet + * @param options * @returns buffer for magnified image */ -export async function magnify(origin: ImageSource, isAnimation = false) { +export async function magnify(origin: ImageSource, options: MagnifyOptions = {}) { const input = await loadImage(origin).catch((err) => Promise.reject(err)); // ignore height if tilesheet, otherwise it's not scaled as much - const surface = isAnimation ? input.width * 16 : input.width * input.height; + const surface = options.isAnimation ? input.width * 16 : input.width * input.height; + // no custom factor provided let factor = 64; if (surface <= 256) factor = 32; if (surface > 256) factor = 16; @@ -32,6 +38,9 @@ export async function magnify(origin: ImageSource, isAnimation = false) { if (surface > 65536) factor = 2; if (surface > 262144) factor = 1; + // custom factor provided + if (options.factor) factor = options.factor; + const width = input.width * factor; const height = input.height * factor; const output = createCanvas(width, height); @@ -49,7 +58,11 @@ export async function magnify(origin: ImageSource, isAnimation = false) { * @param name name, defaults to "magnified.png" * @returns magnified file */ -export async function magnifyToAttachment(origin: ImageSource, name = "magnified.png") { - const { magnified } = await magnify(origin); +export async function magnifyToAttachment( + origin: ImageSource, + options?: MagnifyOptions, + name = "magnified.png", +) { + const { magnified } = await magnify(origin, options); return new AttachmentBuilder(magnified, { name }); } diff --git a/src/helpers/images/tile.ts b/src/helpers/images/tile.ts index 17460df3c..29c1ae908 100644 --- a/src/helpers/images/tile.ts +++ b/src/helpers/images/tile.ts @@ -9,6 +9,12 @@ interface TileOptions { random?: TileRandom; } +/** + * @author Juknum + * @param origin what to tile + * @param options what shape and randomness + * @returns tiled image as buffer + */ export async function tile(origin: ImageSource, options: TileOptions = {}): Promise { const input = await loadImage(origin).catch((err) => Promise.reject(err)); diff --git a/src/helpers/prefixCommandHandler.ts b/src/helpers/prefixCommandHandler.ts index e001f764f..4a0bf0538 100644 --- a/src/helpers/prefixCommandHandler.ts +++ b/src/helpers/prefixCommandHandler.ts @@ -3,6 +3,8 @@ import { magnifyToAttachment } from "./images/magnify"; import getImage from "./getImage"; import { tileToAttachment } from "./images/tile"; import { paletteToAttachment } from "./images/palette"; +import { ActionRowBuilder, ButtonBuilder } from "discord.js"; +import { imageButtons, palette } from "./buttons"; export default async function prefixCommandHandler(message: Message) { const args = message.content.split(" "); @@ -15,11 +17,14 @@ export default async function prefixCommandHandler(message: Message) { case "m": case "z": return await message - .reply({ files: [await magnifyToAttachment(url)] }) + .reply({ + files: [await magnifyToAttachment(url)], + components: [new ActionRowBuilder().addComponents(palette)] + }) .then((message: Message) => message.deleteButton()); case "t": return await message - .reply({ files: [await tileToAttachment(url)] }) + .reply({ files: [await tileToAttachment(url)], components: [imageButtons] }) .then((message: Message) => message.deleteButton()); case "p": const [attachment, embed] = await paletteToAttachment(url);