Adds deployment for icons

This commit is contained in:
Michel Fedde 2025-05-23 21:41:04 +02:00
parent 154002f6f3
commit 0e10ea3cab
14 changed files with 1449 additions and 53 deletions

8
source/Icons/DiscordIcons.d.ts vendored Normal file
View file

@ -0,0 +1,8 @@
type DiscordIcon = {
id: string,
name: string,
}
type DiscordIconRequest = {
items: DiscordIcon[]
}

52
source/Icons/IconCache.ts Normal file
View file

@ -0,0 +1,52 @@
import {Routes} from "discord.js";
import {DiscordClient} from "../Discord/DiscordClient";
export class IconCache {
private existingIcons: Map<string, string>|null;
constructor(
private readonly client: DiscordClient
) {
}
public get(iconName: string): string | null {
if (!this.existingIcons?.has(iconName) ?? false) {
return null;
}
return this.existingIcons?.get(iconName) ?? null;
}
public async set(iconName: string, pngBuffer: Buffer) {
const pngBase64 = pngBuffer.toString("base64");
const iconDataUrl = `data:image/png;base64,${pngBase64}`;
await this.client.RESTClient.post(
Routes.applicationEmojis(this.client.ApplicationId),
{
body: {
name: iconName,
image: iconDataUrl
}
}
)
}
public async populate() {
if (this.existingIcons != null) {
return;
}
const existingEmojis: DiscordIconRequest = await this.client.RESTClient.get(
Routes.applicationEmojis(this.client.ApplicationId)
)
this.existingIcons = new Map<string, string>(
existingEmojis.items.map((item) => {
return [ item.name, item.id ]
})
)
}
}

View file

@ -0,0 +1,56 @@
import {REST, Routes} from "discord.js";
import path from "node:path";
import * as fs from "node:fs";
import svg2img from "svg2img";
import {IconCache} from "./IconCache";
export class IconDeployer {
static ICON_PATH = path.resolve('public/icons')
constructor(
private readonly iconCache: IconCache
) {}
public async ensureExistance() {
const directory = await fs.promises.opendir(IconDeployer.ICON_PATH);
const addIconPromises: Promise<void>[] = [];
for await (let dirname of directory) {
const iconName = path.basename(dirname.name, '.svg').replaceAll('-','_');
if (this.iconCache.get(iconName) !== null) {
continue;
}
addIconPromises.push(
this.addIcon(path.resolve(dirname.parentPath, dirname.name), iconName)
);
}
await Promise.all(addIconPromises);
}
private async addIcon(iconPath: string, iconName: string) {
const svgBuffer = await fs.promises.readFile(iconPath, 'utf-8');
const pngBuffer = await new Promise<Buffer>(resolve => {
svg2img(
svgBuffer,
{
format: "png",
resvg: {
fitTo: {
mode: "width",
value: 128
}
}
},
function (err, buffer) {
resolve(buffer);
}
)
}
)
await this.iconCache.set(iconName, pngBuffer);
}
}