mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Fix icon being the wrong colour on macos sometimes
Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
parent
c5edceca67
commit
a1a85856ad
@ -11,7 +11,7 @@ import type { Disposer } from "../../common/utils";
|
|||||||
import { getOrInsertWithAsync, HashMap } from "../../common/utils";
|
import { getOrInsertWithAsync, HashMap } from "../../common/utils";
|
||||||
import updateAvailableInjectable from "../app-updater/update-available.injectable";
|
import updateAvailableInjectable from "../app-updater/update-available.injectable";
|
||||||
import useDarkColorsInjectable from "../electron/use-dark-colors.injectable";
|
import useDarkColorsInjectable from "../electron/use-dark-colors.injectable";
|
||||||
import { createTrayIcon } from "./create-tray-icon";
|
import createTrayIconInjectable from "./create-tray-icon.injectable";
|
||||||
|
|
||||||
export interface ComputedTrayIcon {
|
export interface ComputedTrayIcon {
|
||||||
getCurrent(): Promise<NativeImage>;
|
getCurrent(): Promise<NativeImage>;
|
||||||
@ -29,15 +29,13 @@ const computedTrayIconInjectable = getInjectable({
|
|||||||
const useDarkColors = di.inject(useDarkColorsInjectable);
|
const useDarkColors = di.inject(useDarkColorsInjectable);
|
||||||
const updateAvailable = di.inject(updateAvailableInjectable);
|
const updateAvailable = di.inject(updateAvailableInjectable);
|
||||||
const logger = di.inject(loggerInjectable);
|
const logger = di.inject(loggerInjectable);
|
||||||
|
const createTrayIcon = di.inject(createTrayIconInjectable);
|
||||||
const lock = new AwaitLock();
|
const lock = new AwaitLock();
|
||||||
const cache = new HashMap<NativeImageCacheKey, NativeImage>(
|
const cache = new HashMap<NativeImageCacheKey, NativeImage>(
|
||||||
(key) => `${key.updateAvailable ? "updateAvailable" : ""}:${key.useDarkColors ? "shouldUseDarkColors" : ""}`,
|
(key) => `${key.updateAvailable ? "updateAvailable" : ""}:${key.useDarkColors ? "shouldUseDarkColors" : ""}`,
|
||||||
);
|
);
|
||||||
|
|
||||||
const computedCurrent = (key: NativeImageCacheKey) => getOrInsertWithAsync(cache, key, () => createTrayIcon({
|
const computedCurrent = (key: NativeImageCacheKey) => getOrInsertWithAsync(cache, key, () => createTrayIcon(key));
|
||||||
size: 16,
|
|
||||||
...key,
|
|
||||||
}));
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
getCurrent: () => computedCurrent({
|
getCurrent: () => computedCurrent({
|
||||||
|
|||||||
92
src/main/tray/create-tray-icon.injectable.ts
Normal file
92
src/main/tray/create-tray-icon.injectable.ts
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import { nativeImage } from "electron";
|
||||||
|
import type { NativeImage } from "electron";
|
||||||
|
import { base64 } 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";
|
||||||
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
|
import isMacInjectable from "../../common/vars/is-mac.injectable";
|
||||||
|
|
||||||
|
export interface CreateTrayIconArgs {
|
||||||
|
useDarkColors: boolean;
|
||||||
|
updateAvailable: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type CreateTrayIcon = (args: CreateTrayIconArgs) => Promise<NativeImage>;
|
||||||
|
|
||||||
|
const createTrayIconInjectable = getInjectable({
|
||||||
|
id: "create-tray-icon",
|
||||||
|
instantiate: (di): CreateTrayIcon => {
|
||||||
|
const produceTemplateImage = di.inject(isMacInjectable);
|
||||||
|
|
||||||
|
return async ({ useDarkColors, updateAvailable }) => {
|
||||||
|
const size = 32; // 2x zoom
|
||||||
|
const trayIconColor = useDarkColors ? "white" : "black"; // Invert to show contrast
|
||||||
|
const trayBackgroundColor = useDarkColors ? "black" : "white";
|
||||||
|
const styleTag = produceTemplateImage
|
||||||
|
? ""
|
||||||
|
: `
|
||||||
|
<style>
|
||||||
|
ellipse {
|
||||||
|
stroke: ${trayIconColor} !important;
|
||||||
|
fill: ${trayBackgroundColor} !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
path, rect {
|
||||||
|
fill: ${trayIconColor} !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
`;
|
||||||
|
|
||||||
|
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 (updateAvailable) {
|
||||||
|
// This adds some contrast between the notice icon and the logo
|
||||||
|
logoSvgRoot.innerHTML += `<ellipse ry="192" rx="192" cy="352" cx="352" />`;
|
||||||
|
|
||||||
|
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();
|
||||||
|
const image = nativeImage.createFromBuffer(iconBuffer, {
|
||||||
|
scaleFactor: 2,
|
||||||
|
});
|
||||||
|
|
||||||
|
image.setTemplateImage(produceTemplateImage);
|
||||||
|
|
||||||
|
return image;
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default createTrayIconInjectable;
|
||||||
|
|
||||||
@ -1,71 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
|
||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
|
||||||
*/
|
|
||||||
import { nativeImage } from "electron";
|
|
||||||
import type { NativeImage } from "electron";
|
|
||||||
import { base64 } 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 {
|
|
||||||
useDarkColors: boolean;
|
|
||||||
size: number;
|
|
||||||
updateAvailable: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function createTrayIcon({ useDarkColors, size, updateAvailable }: CreateTrayIconArgs): Promise<NativeImage> {
|
|
||||||
const trayIconColor = useDarkColors ? "white" : "black"; // Invert to show contrast
|
|
||||||
const trayBackgroundColor = useDarkColors ? "black" : "white";
|
|
||||||
const styleTag = `
|
|
||||||
<style>
|
|
||||||
ellipse {
|
|
||||||
stroke: ${trayIconColor} !important;
|
|
||||||
fill: ${trayBackgroundColor} !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
path, rect {
|
|
||||||
fill: ${trayIconColor} !important;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
`;
|
|
||||||
|
|
||||||
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 (updateAvailable) {
|
|
||||||
// This adds some contrast between the notice icon and the logo
|
|
||||||
logoSvgRoot.innerHTML += `<ellipse ry="192" rx="192" cy="352" cx="352" />`;
|
|
||||||
|
|
||||||
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();
|
|
||||||
|
|
||||||
return nativeImage.createFromBuffer(iconBuffer);
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue
Block a user