diff --git a/src/main/tray/create-current-tray-icon.injectable.ts b/src/main/tray/create-current-tray-icon.injectable.ts index 6a50b973c0..104ce3b8c6 100644 --- a/src/main/tray/create-current-tray-icon.injectable.ts +++ b/src/main/tray/create-current-tray-icon.injectable.ts @@ -5,7 +5,6 @@ import { getInjectable } from "@ogre-tools/injectable"; import nativeThemeInjectable from "../electron/native-theme.injectable"; import { createTrayIcon } from "./create-tray-icon"; -import LogoLens from "../../renderer/components/icon/logo-lens.svg"; const createCurrentTrayIconInjectable = getInjectable({ id: "create-current-tray-icon", @@ -15,7 +14,7 @@ const createCurrentTrayIconInjectable = getInjectable({ return () => createTrayIcon({ shouldUseDarkColors: nativeTheme.shouldUseDarkColors, size: 16, - sourceSvg: LogoLens, + updateIsAvailable: false, }); }, }); diff --git a/src/main/tray/create-tray-icon.ts b/src/main/tray/create-tray-icon.ts index e56871b2c4..2650c61c9a 100644 --- a/src/main/tray/create-tray-icon.ts +++ b/src/main/tray/create-tray-icon.ts @@ -7,25 +7,65 @@ import type { NativeImage } from "electron"; import { base64, getOrInsertWithAsync } from "../../common/utils"; import sharp from "sharp"; import { JSDOM } from "jsdom"; +import LogoLens from "../../renderer/components/icon/logo-lens.svg"; +import Notice from "../../renderer/components/icon/notice.svg"; export interface CreateTrayIconArgs { shouldUseDarkColors: boolean; size: number; - sourceSvg: string; + updateIsAvailable: boolean; } const trayIcons = new Map(); -export async function createTrayIcon({ shouldUseDarkColors, size, sourceSvg }: CreateTrayIconArgs): Promise { +export async function createTrayIcon({ shouldUseDarkColors, size, updateIsAvailable }: CreateTrayIconArgs): Promise { return getOrInsertWithAsync(trayIcons, shouldUseDarkColors, async () => { const trayIconColor = shouldUseDarkColors ? "white" : "black"; // Invert to show contrast - const parsedSvg = base64.decode(sourceSvg.split("base64,")[1]); - const svgDom = new JSDOM(`${parsedSvg}`); - const svgRoot = svgDom.window.document.body.getElementsByTagName("svg")[0]; + const trayBackgroundColor = shouldUseDarkColors ? "black" : "white"; + const styleTag = ` + `; + path, rect { + fill: ${trayIconColor} !important; + } + + `; - const iconBuffer = await sharp(Buffer.from(svgRoot.outerHTML)) + const overlayImages: sharp.OverlayOptions[] = []; + const parsedLogoSvg = base64.decode(LogoLens.split("base64,")[1]); + const logoSvgRoot = new JSDOM(parsedLogoSvg).window.document.getElementsByTagName("svg")[0]; + + logoSvgRoot.innerHTML += styleTag; + + if (updateIsAvailable) { + // This adds some contrast between the notice icon and the logo + logoSvgRoot.innerHTML += ``; + + const parsedNoticeSvg = base64.decode(Notice.split("base64,")[1]); + const noticeSvgRoot = new JSDOM(parsedNoticeSvg).window.document.getElementsByTagName("svg")[0]; + + noticeSvgRoot.innerHTML += styleTag; + + const noticeImage = await sharp(Buffer.from(noticeSvgRoot.outerHTML)) + .resize({ + width: Math.floor(size/1.5), + height: Math.floor(size/1.5), + }) + .toBuffer(); + + overlayImages.push({ + input: noticeImage, + top: Math.floor(size/2.5), + left: Math.floor(size/2.5), + }); + } + + const iconBuffer = await sharp(Buffer.from(logoSvgRoot.outerHTML)) + .composite(overlayImages) .resize({ width: size, height: size }) .png() .toBuffer(); diff --git a/src/renderer/components/icon/notice.svg b/src/renderer/components/icon/notice.svg new file mode 100644 index 0000000000..a17cb1896b --- /dev/null +++ b/src/renderer/components/icon/notice.svg @@ -0,0 +1,30 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/types/mocks.d.ts b/types/mocks.d.ts index 17dba848b7..4d3e378937 100644 --- a/types/mocks.d.ts +++ b/types/mocks.d.ts @@ -25,7 +25,11 @@ declare module "*.scss" { // Declare everything what's bundled as webpack's type="asset/resource" // Should be mocked for tests support in jestConfig.moduleNameMapper (currently in "/package.json") -declare module "*.svg"; +declare module "*.svg" { + const content: string; + export = content; +} + declare module "*.jpg"; declare module "*.png"; declare module "*.eot";