mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Add computational support for a notice on the tray icon
Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
parent
60498bbd4a
commit
1fc2008b2f
@ -5,7 +5,6 @@
|
|||||||
import { getInjectable } from "@ogre-tools/injectable";
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
import nativeThemeInjectable from "../electron/native-theme.injectable";
|
import nativeThemeInjectable from "../electron/native-theme.injectable";
|
||||||
import { createTrayIcon } from "./create-tray-icon";
|
import { createTrayIcon } from "./create-tray-icon";
|
||||||
import LogoLens from "../../renderer/components/icon/logo-lens.svg";
|
|
||||||
|
|
||||||
const createCurrentTrayIconInjectable = getInjectable({
|
const createCurrentTrayIconInjectable = getInjectable({
|
||||||
id: "create-current-tray-icon",
|
id: "create-current-tray-icon",
|
||||||
@ -15,7 +14,7 @@ const createCurrentTrayIconInjectable = getInjectable({
|
|||||||
return () => createTrayIcon({
|
return () => createTrayIcon({
|
||||||
shouldUseDarkColors: nativeTheme.shouldUseDarkColors,
|
shouldUseDarkColors: nativeTheme.shouldUseDarkColors,
|
||||||
size: 16,
|
size: 16,
|
||||||
sourceSvg: LogoLens,
|
updateIsAvailable: false,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@ -7,25 +7,65 @@ import type { NativeImage } from "electron";
|
|||||||
import { base64, getOrInsertWithAsync } from "../../common/utils";
|
import { base64, getOrInsertWithAsync } from "../../common/utils";
|
||||||
import sharp from "sharp";
|
import sharp from "sharp";
|
||||||
import { JSDOM } from "jsdom";
|
import { JSDOM } from "jsdom";
|
||||||
|
import LogoLens from "../../renderer/components/icon/logo-lens.svg";
|
||||||
|
import Notice from "../../renderer/components/icon/notice.svg";
|
||||||
|
|
||||||
export interface CreateTrayIconArgs {
|
export interface CreateTrayIconArgs {
|
||||||
shouldUseDarkColors: boolean;
|
shouldUseDarkColors: boolean;
|
||||||
size: number;
|
size: number;
|
||||||
sourceSvg: string;
|
updateIsAvailable: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const trayIcons = new Map<boolean, NativeImage>();
|
const trayIcons = new Map<boolean, NativeImage>();
|
||||||
|
|
||||||
export async function createTrayIcon({ shouldUseDarkColors, size, sourceSvg }: CreateTrayIconArgs): Promise<NativeImage> {
|
export async function createTrayIcon({ shouldUseDarkColors, size, updateIsAvailable }: CreateTrayIconArgs): Promise<NativeImage> {
|
||||||
return getOrInsertWithAsync(trayIcons, shouldUseDarkColors, async () => {
|
return getOrInsertWithAsync(trayIcons, shouldUseDarkColors, async () => {
|
||||||
const trayIconColor = shouldUseDarkColors ? "white" : "black"; // Invert to show contrast
|
const trayIconColor = shouldUseDarkColors ? "white" : "black"; // Invert to show contrast
|
||||||
const parsedSvg = base64.decode(sourceSvg.split("base64,")[1]);
|
const trayBackgroundColor = shouldUseDarkColors ? "black" : "white";
|
||||||
const svgDom = new JSDOM(`<body>${parsedSvg}</body>`);
|
const styleTag = `
|
||||||
const svgRoot = svgDom.window.document.body.getElementsByTagName("svg")[0];
|
<style>
|
||||||
|
ellipse {
|
||||||
|
stroke: ${trayIconColor} !important;
|
||||||
|
fill: ${trayBackgroundColor} !important;
|
||||||
|
}
|
||||||
|
|
||||||
svgRoot.innerHTML += `<style>* {fill: ${trayIconColor} !important;}</style>`;
|
path, rect {
|
||||||
|
fill: ${trayIconColor} !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
`;
|
||||||
|
|
||||||
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 += `<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 })
|
.resize({ width: size, height: size })
|
||||||
.png()
|
.png()
|
||||||
.toBuffer();
|
.toBuffer();
|
||||||
|
|||||||
30
src/renderer/components/icon/notice.svg
Normal file
30
src/renderer/components/icon/notice.svg
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<svg xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" sodipodi:docname="notice.svg" inkscape:version="1.0 (4035a4f, 2020-05-01)" id="notice" version="1.1" viewBox="0 0 135.46666 135.46666" height="512" width="512">
|
||||||
|
<defs id="defs2">
|
||||||
|
<rect id="rect2785" height="134.1693" width="135.23837" y="0.26726951" x="-0.53453903" />
|
||||||
|
<linearGradient osb:paint="solid" id="linearGradient837">
|
||||||
|
<stop id="stop835" offset="0" style="stop-color:#000000;stop-opacity:1;" />
|
||||||
|
</linearGradient>
|
||||||
|
</defs>
|
||||||
|
<sodipodi:namedview inkscape:window-maximized="0" inkscape:window-y="0" inkscape:window-x="0" inkscape:window-height="1080" inkscape:window-width="1920" inkscape:pagecheckerboard="true" units="px" showgrid="false" inkscape:document-rotation="0" inkscape:current-layer="layer1" inkscape:document-units="px" inkscape:cy="263.00246" inkscape:cx="240.74335" inkscape:zoom="2.0359339" inkscape:pageshadow="2" inkscape:pageopacity="0.0" borderopacity="1.0" bordercolor="#666666" pagecolor="#ffffff" id="base" />
|
||||||
|
<metadata id="metadata5">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title></dc:title>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g id="layer1" inkscape:groupmode="layer" inkscape:label="Layer 1">
|
||||||
|
<ellipse ry="59.764721" rx="59.764713" cy="67.73333" cx="67.733345" id="path10" style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:15.9372;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||||
|
<path id="path2807" d="M 58.707956,29.522524 H 76.674473 L 76.739452,43.330427 73.23062,71.076192 62.054343,71.043701 58.740444,43.427894 Z" style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
|
||||||
|
<rect y="83.204803" x="59.292759" height="14.815064" width="16.861885" id="rect2809" style="fill:#000000;fill-opacity:1;stroke:none;" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 2.4 KiB |
6
types/mocks.d.ts
vendored
6
types/mocks.d.ts
vendored
@ -25,7 +25,11 @@ declare module "*.scss" {
|
|||||||
|
|
||||||
// Declare everything what's bundled as webpack's type="asset/resource"
|
// Declare everything what's bundled as webpack's type="asset/resource"
|
||||||
// Should be mocked for tests support in jestConfig.moduleNameMapper (currently in "/package.json")
|
// 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 "*.jpg";
|
||||||
declare module "*.png";
|
declare module "*.png";
|
||||||
declare module "*.eot";
|
declare module "*.eot";
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user