Fix icon generation
Signed-off-by: Sebastian Malton <sebastian@malton.name>
1
Makefile
@ -56,6 +56,7 @@ integration: build
|
||||
build: node_modules binaries/client
|
||||
yarn run npm:fix-build-version
|
||||
$(MAKE) build-extensions -B
|
||||
yarn run build:tray-icons
|
||||
yarn run compile
|
||||
ifeq "$(DETECTED_OS)" "Windows"
|
||||
# https://github.com/ukoloff/win-ca#clear-pem-folder-on-publish
|
||||
|
||||
@ -31,113 +31,70 @@ function getSvgStyling(colouring: "dark" | "light"): string {
|
||||
`;
|
||||
}
|
||||
|
||||
async function getBaseIconTemplates() {
|
||||
async function getBaseIconImage() {
|
||||
const svgData = await readFile(inputFile, { encoding: "utf-8" });
|
||||
const dom = new JSDOM(`<body>${svgData}</body>`);
|
||||
const root = dom.window.document.body.getElementsByTagName("svg")[0];
|
||||
|
||||
root.innerHTML += getSvgStyling("light");
|
||||
|
||||
return root.outerHTML;
|
||||
return Buffer.from(root.outerHTML);
|
||||
}
|
||||
|
||||
async function generateNormalImages(template: string, size: number, name: string) {
|
||||
async function generateImage(image: Buffer, size: number, namePrefix: string) {
|
||||
sharp(image)
|
||||
.resize({ width: size, height: size })
|
||||
.toFile(path.join(outputFolder, `${namePrefix}.png`));
|
||||
}
|
||||
|
||||
async function generateImages(image: Buffer, size: number, name: string) {
|
||||
await Promise.all([
|
||||
sharp(Buffer.from(template))
|
||||
.resize({ width: size, height: size })
|
||||
.png()
|
||||
.toFile(path.join(outputFolder, `${name}.png`)),
|
||||
sharp(Buffer.from(template))
|
||||
.resize({ width: size*2, height: size*2 })
|
||||
.png()
|
||||
.toFile(path.join(outputFolder, `${name}@2x.png`)),
|
||||
generateImage(image, size, name),
|
||||
generateImage(image, size*2, `${name}@2x`),
|
||||
generateImage(image, size*3, `${name}@3x`),
|
||||
generateImage(image, size*4, `${name}@4x`),
|
||||
]);
|
||||
}
|
||||
|
||||
async function generateUpdateAvailableImages(template: string, size: number, name: string, noticeSvg: string) {
|
||||
const circleSvg = new JSDOM(`
|
||||
<body>
|
||||
<svg viewBox="0 0 32 32">
|
||||
<circle cx="20" cy="20" r="6" />
|
||||
</svg>
|
||||
<style>
|
||||
circle {
|
||||
fill: "black" !important;
|
||||
}
|
||||
</style>
|
||||
</body>
|
||||
`).window.document.getElementsByTagName("svg")[0];
|
||||
|
||||
circleSvg.innerHTML += getSvgStyling("dark");
|
||||
|
||||
const circleBuffer = await sharp(Buffer.from(circleSvg.outerHTML))
|
||||
.resize({
|
||||
width: Math.floor(size/1.5),
|
||||
height: Math.floor(size/1.5),
|
||||
})
|
||||
async function generateUpdateAvailableImages(baseImage: Buffer) {
|
||||
const noticeIconImage = await getNoticeIconImage();
|
||||
const circleBuffer = await sharp(Buffer.from(`
|
||||
<svg viewBox="0 0 64 64">
|
||||
<circle cx="32" cy="32" r="32" fill="black" />
|
||||
</svg>
|
||||
`))
|
||||
.toBuffer();
|
||||
|
||||
await sharp(circleBuffer)
|
||||
.toFile(path.join(outputFolder, "circle.png"));
|
||||
|
||||
await Promise.all([
|
||||
sharp(Buffer.from(template))
|
||||
.resize({ width: size, height: size })
|
||||
.composite([
|
||||
{
|
||||
input: circleBuffer,
|
||||
gravity: "southeast",
|
||||
/**
|
||||
* The `clear` blend rule is buggy and currently doesn't work
|
||||
*
|
||||
* https://github.com/lovell/sharp/issues/3247
|
||||
*/
|
||||
blend: "clear",
|
||||
},
|
||||
{
|
||||
input: (
|
||||
await sharp(Buffer.from(noticeSvg))
|
||||
.resize({
|
||||
width: Math.floor(size/1.5),
|
||||
height: Math.floor(size/1.5),
|
||||
})
|
||||
.toBuffer()
|
||||
),
|
||||
gravity: "southeast",
|
||||
},
|
||||
])
|
||||
.png()
|
||||
.toFile(path.join(outputFolder, `${name}.png`)),
|
||||
sharp(Buffer.from(template))
|
||||
.composite([
|
||||
{
|
||||
input: circleBuffer,
|
||||
gravity: "southeast",
|
||||
blend: "clear",
|
||||
},
|
||||
{
|
||||
input: (
|
||||
await sharp(Buffer.from(noticeSvg))
|
||||
.resize({
|
||||
width: Math.floor((size * 2)/1.5),
|
||||
height: Math.floor((size * 2)/1.5),
|
||||
})
|
||||
.toBuffer()
|
||||
),
|
||||
gravity: "southeast",
|
||||
},
|
||||
])
|
||||
.resize({ width: size*2, height: size*2 })
|
||||
.png()
|
||||
.toFile(path.join(outputFolder, `${name}@2x.png`)),
|
||||
]);
|
||||
return sharp(baseImage)
|
||||
.resize({ width: 128, height: 128 })
|
||||
.composite([
|
||||
{
|
||||
input: circleBuffer,
|
||||
top: 64,
|
||||
left: 64,
|
||||
blend: "dest-out",
|
||||
},
|
||||
{
|
||||
input: (
|
||||
await sharp(noticeIconImage)
|
||||
.resize({
|
||||
width: 60,
|
||||
height: 60,
|
||||
})
|
||||
.toBuffer()
|
||||
),
|
||||
top: 66,
|
||||
left: 66,
|
||||
},
|
||||
])
|
||||
.toBuffer();
|
||||
}
|
||||
|
||||
async function getNoticeSvg(): Promise<string> {
|
||||
async function getNoticeIconImage() {
|
||||
const svgData = await readFile(noticeFile, { encoding: "utf-8" });
|
||||
const noticeSvgRoot = new JSDOM(svgData).window.document.getElementsByTagName("svg")[0];
|
||||
|
||||
return noticeSvgRoot.outerHTML;
|
||||
return Buffer.from(noticeSvgRoot.outerHTML);
|
||||
}
|
||||
|
||||
async function generateTrayIcons() {
|
||||
@ -145,21 +102,14 @@ async function generateTrayIcons() {
|
||||
console.log("Generating tray icon pngs");
|
||||
await ensureOutputFoler();
|
||||
|
||||
const baseTemplate = await getBaseIconTemplates();
|
||||
const noticeTemplate = await getNoticeSvg();
|
||||
|
||||
void noticeTemplate;
|
||||
void generateUpdateAvailableImages;
|
||||
const baseIconImage = await getBaseIconImage();
|
||||
const updateAvailableImage = await generateUpdateAvailableImages(baseIconImage);
|
||||
|
||||
await Promise.all([
|
||||
generateNormalImages(baseTemplate, size, "trayIconTemplate"),
|
||||
// generateUpdateAvailableImages(baseTemplate, size, "trayIconDarkUpdateAvailableTemplate", noticeTemplate),
|
||||
generateImages(baseIconImage, size, "trayIconTemplate"),
|
||||
generateImages(updateAvailableImage, size, "trayIconUpdateAvailableTemplate"),
|
||||
]);
|
||||
|
||||
console.warn("Did not update:", [
|
||||
"trayIconUpdateAvailableTemplate.png",
|
||||
"trayIconUpdateAvailableTemplate@2x.png",
|
||||
]);
|
||||
console.log("Generated all images");
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
|
||||
BIN
build/tray/trayIconTemplate@3x.png
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
BIN
build/tray/trayIconTemplate@4x.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 466 B |
|
Before Width: | Height: | Size: 5.9 KiB After Width: | Height: | Size: 1.0 KiB |
BIN
build/tray/trayIconUpdateAvailableTemplate@3x.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
build/tray/trayIconUpdateAvailableTemplate@4x.png
Normal file
|
After Width: | Height: | Size: 2.4 KiB |