mirror of
https://github.com/zulip/zulip-desktop.git
synced 2025-10-23 03:31:56 +00:00
Reformat all code with Prettier.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
This commit is contained in:
@@ -1,97 +1,102 @@
|
||||
import type {WebviewTag, NativeImage} from 'electron';
|
||||
import {ipcRenderer, remote} from 'electron';
|
||||
import path from 'path';
|
||||
import type {WebviewTag, NativeImage} from "electron";
|
||||
import {ipcRenderer, remote} from "electron";
|
||||
import path from "path";
|
||||
|
||||
import * as ConfigUtil from '../../common/config-util';
|
||||
import * as ConfigUtil from "../../common/config-util";
|
||||
|
||||
const {Tray, Menu, nativeImage, BrowserWindow} = remote;
|
||||
|
||||
let tray: Electron.Tray;
|
||||
|
||||
const ICON_DIR = '../../resources/tray';
|
||||
const ICON_DIR = "../../resources/tray";
|
||||
|
||||
const TRAY_SUFFIX = 'tray';
|
||||
const TRAY_SUFFIX = "tray";
|
||||
|
||||
const APP_ICON = path.join(__dirname, ICON_DIR, TRAY_SUFFIX);
|
||||
|
||||
const iconPath = (): string => {
|
||||
if (process.platform === 'linux') {
|
||||
return APP_ICON + 'linux.png';
|
||||
}
|
||||
if (process.platform === "linux") {
|
||||
return APP_ICON + "linux.png";
|
||||
}
|
||||
|
||||
return APP_ICON + (process.platform === 'win32' ? 'win.ico' : 'macOSTemplate.png');
|
||||
return (
|
||||
APP_ICON + (process.platform === "win32" ? "win.ico" : "macOSTemplate.png")
|
||||
);
|
||||
};
|
||||
|
||||
const winUnreadTrayIconPath = (): string => APP_ICON + 'unread.ico';
|
||||
const winUnreadTrayIconPath = (): string => APP_ICON + "unread.ico";
|
||||
|
||||
let unread = 0;
|
||||
|
||||
const trayIconSize = (): number => {
|
||||
switch (process.platform) {
|
||||
case 'darwin':
|
||||
return 20;
|
||||
case 'win32':
|
||||
return 100;
|
||||
case 'linux':
|
||||
return 100;
|
||||
default: return 80;
|
||||
}
|
||||
switch (process.platform) {
|
||||
case "darwin":
|
||||
return 20;
|
||||
case "win32":
|
||||
return 100;
|
||||
case "linux":
|
||||
return 100;
|
||||
default:
|
||||
return 80;
|
||||
}
|
||||
};
|
||||
|
||||
// Default config for Icon we might make it OS specific if needed like the size
|
||||
const config = {
|
||||
pixelRatio: window.devicePixelRatio,
|
||||
unreadCount: 0,
|
||||
showUnreadCount: true,
|
||||
unreadColor: '#000000',
|
||||
readColor: '#000000',
|
||||
unreadBackgroundColor: '#B9FEEA',
|
||||
readBackgroundColor: '#B9FEEA',
|
||||
size: trayIconSize(),
|
||||
thick: process.platform === 'win32'
|
||||
pixelRatio: window.devicePixelRatio,
|
||||
unreadCount: 0,
|
||||
showUnreadCount: true,
|
||||
unreadColor: "#000000",
|
||||
readColor: "#000000",
|
||||
unreadBackgroundColor: "#B9FEEA",
|
||||
readBackgroundColor: "#B9FEEA",
|
||||
size: trayIconSize(),
|
||||
thick: process.platform === "win32",
|
||||
};
|
||||
|
||||
const renderCanvas = function (arg: number): HTMLCanvasElement {
|
||||
config.unreadCount = arg;
|
||||
config.unreadCount = arg;
|
||||
|
||||
const SIZE = config.size * config.pixelRatio;
|
||||
const PADDING = SIZE * 0.05;
|
||||
const CENTER = SIZE / 2;
|
||||
const HAS_COUNT = config.showUnreadCount && config.unreadCount;
|
||||
const color = config.unreadCount ? config.unreadColor : config.readColor;
|
||||
const backgroundColor = config.unreadCount ? config.unreadBackgroundColor : config.readBackgroundColor;
|
||||
const SIZE = config.size * config.pixelRatio;
|
||||
const PADDING = SIZE * 0.05;
|
||||
const CENTER = SIZE / 2;
|
||||
const HAS_COUNT = config.showUnreadCount && config.unreadCount;
|
||||
const color = config.unreadCount ? config.unreadColor : config.readColor;
|
||||
const backgroundColor = config.unreadCount
|
||||
? config.unreadBackgroundColor
|
||||
: config.readBackgroundColor;
|
||||
|
||||
const canvas = document.createElement('canvas');
|
||||
canvas.width = SIZE;
|
||||
canvas.height = SIZE;
|
||||
const ctx = canvas.getContext('2d');
|
||||
const canvas = document.createElement("canvas");
|
||||
canvas.width = SIZE;
|
||||
canvas.height = SIZE;
|
||||
const ctx = canvas.getContext("2d");
|
||||
|
||||
// Circle
|
||||
// If (!config.thick || config.thick && HAS_COUNT) {
|
||||
ctx.beginPath();
|
||||
ctx.arc(CENTER, CENTER, (SIZE / 2) - PADDING, 0, 2 * Math.PI, false);
|
||||
ctx.fillStyle = backgroundColor;
|
||||
ctx.fill();
|
||||
ctx.lineWidth = SIZE / (config.thick ? 10 : 20);
|
||||
ctx.strokeStyle = backgroundColor;
|
||||
ctx.stroke();
|
||||
// Count or Icon
|
||||
if (HAS_COUNT) {
|
||||
ctx.fillStyle = color;
|
||||
ctx.textAlign = 'center';
|
||||
if (config.unreadCount > 99) {
|
||||
ctx.font = `${config.thick ? 'bold ' : ''}${SIZE * 0.4}px Helvetica`;
|
||||
ctx.fillText('99+', CENTER, CENTER + (SIZE * 0.15));
|
||||
} else if (config.unreadCount < 10) {
|
||||
ctx.font = `${config.thick ? 'bold ' : ''}${SIZE * 0.5}px Helvetica`;
|
||||
ctx.fillText(String(config.unreadCount), CENTER, CENTER + (SIZE * 0.2));
|
||||
} else {
|
||||
ctx.font = `${config.thick ? 'bold ' : ''}${SIZE * 0.5}px Helvetica`;
|
||||
ctx.fillText(String(config.unreadCount), CENTER, CENTER + (SIZE * 0.15));
|
||||
}
|
||||
}
|
||||
// Circle
|
||||
// If (!config.thick || config.thick && HAS_COUNT) {
|
||||
ctx.beginPath();
|
||||
ctx.arc(CENTER, CENTER, SIZE / 2 - PADDING, 0, 2 * Math.PI, false);
|
||||
ctx.fillStyle = backgroundColor;
|
||||
ctx.fill();
|
||||
ctx.lineWidth = SIZE / (config.thick ? 10 : 20);
|
||||
ctx.strokeStyle = backgroundColor;
|
||||
ctx.stroke();
|
||||
// Count or Icon
|
||||
if (HAS_COUNT) {
|
||||
ctx.fillStyle = color;
|
||||
ctx.textAlign = "center";
|
||||
if (config.unreadCount > 99) {
|
||||
ctx.font = `${config.thick ? "bold " : ""}${SIZE * 0.4}px Helvetica`;
|
||||
ctx.fillText("99+", CENTER, CENTER + SIZE * 0.15);
|
||||
} else if (config.unreadCount < 10) {
|
||||
ctx.font = `${config.thick ? "bold " : ""}${SIZE * 0.5}px Helvetica`;
|
||||
ctx.fillText(String(config.unreadCount), CENTER, CENTER + SIZE * 0.2);
|
||||
} else {
|
||||
ctx.font = `${config.thick ? "bold " : ""}${SIZE * 0.5}px Helvetica`;
|
||||
ctx.fillText(String(config.unreadCount), CENTER, CENTER + SIZE * 0.15);
|
||||
}
|
||||
}
|
||||
|
||||
return canvas;
|
||||
return canvas;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -100,128 +105,133 @@ const renderCanvas = function (arg: number): HTMLCanvasElement {
|
||||
* @return the native image
|
||||
*/
|
||||
const renderNativeImage = function (arg: number): NativeImage {
|
||||
if (process.platform === 'win32') {
|
||||
return nativeImage.createFromPath(winUnreadTrayIconPath());
|
||||
}
|
||||
if (process.platform === "win32") {
|
||||
return nativeImage.createFromPath(winUnreadTrayIconPath());
|
||||
}
|
||||
|
||||
const canvas = renderCanvas(arg);
|
||||
const pngData = nativeImage.createFromDataURL(canvas.toDataURL('image/png')).toPNG();
|
||||
return nativeImage.createFromBuffer(pngData, {
|
||||
scaleFactor: config.pixelRatio
|
||||
});
|
||||
const canvas = renderCanvas(arg);
|
||||
const pngData = nativeImage
|
||||
.createFromDataURL(canvas.toDataURL("image/png"))
|
||||
.toPNG();
|
||||
return nativeImage.createFromBuffer(pngData, {
|
||||
scaleFactor: config.pixelRatio,
|
||||
});
|
||||
};
|
||||
|
||||
function sendAction(action: string): void {
|
||||
const win = BrowserWindow.getAllWindows()[0];
|
||||
const win = BrowserWindow.getAllWindows()[0];
|
||||
|
||||
if (process.platform === 'darwin') {
|
||||
win.restore();
|
||||
}
|
||||
if (process.platform === "darwin") {
|
||||
win.restore();
|
||||
}
|
||||
|
||||
win.webContents.send(action);
|
||||
win.webContents.send(action);
|
||||
}
|
||||
|
||||
const createTray = function (): void {
|
||||
const contextMenu = Menu.buildFromTemplate([
|
||||
{
|
||||
label: 'Zulip',
|
||||
click() {
|
||||
ipcRenderer.send('focus-app');
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'Settings',
|
||||
click() {
|
||||
ipcRenderer.send('focus-app');
|
||||
sendAction('open-settings');
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'separator'
|
||||
},
|
||||
{
|
||||
label: 'Quit',
|
||||
click() {
|
||||
ipcRenderer.send('quit-app');
|
||||
}
|
||||
}
|
||||
]);
|
||||
tray = new Tray(iconPath());
|
||||
tray.setContextMenu(contextMenu);
|
||||
if (process.platform === 'linux' || process.platform === 'win32') {
|
||||
tray.on('click', () => {
|
||||
ipcRenderer.send('toggle-app');
|
||||
});
|
||||
}
|
||||
const contextMenu = Menu.buildFromTemplate([
|
||||
{
|
||||
label: "Zulip",
|
||||
click() {
|
||||
ipcRenderer.send("focus-app");
|
||||
},
|
||||
},
|
||||
{
|
||||
label: "Settings",
|
||||
click() {
|
||||
ipcRenderer.send("focus-app");
|
||||
sendAction("open-settings");
|
||||
},
|
||||
},
|
||||
{
|
||||
type: "separator",
|
||||
},
|
||||
{
|
||||
label: "Quit",
|
||||
click() {
|
||||
ipcRenderer.send("quit-app");
|
||||
},
|
||||
},
|
||||
]);
|
||||
tray = new Tray(iconPath());
|
||||
tray.setContextMenu(contextMenu);
|
||||
if (process.platform === "linux" || process.platform === "win32") {
|
||||
tray.on("click", () => {
|
||||
ipcRenderer.send("toggle-app");
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
ipcRenderer.on('destroytray', (event: Event): Event => {
|
||||
if (!tray) {
|
||||
return undefined;
|
||||
}
|
||||
ipcRenderer.on(
|
||||
"destroytray",
|
||||
(event: Event): Event => {
|
||||
if (!tray) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
tray.destroy();
|
||||
if (tray.isDestroyed()) {
|
||||
tray = null;
|
||||
} else {
|
||||
throw new Error('Tray icon not properly destroyed.');
|
||||
}
|
||||
tray.destroy();
|
||||
if (tray.isDestroyed()) {
|
||||
tray = null;
|
||||
} else {
|
||||
throw new Error("Tray icon not properly destroyed.");
|
||||
}
|
||||
|
||||
return event;
|
||||
});
|
||||
return event;
|
||||
},
|
||||
);
|
||||
|
||||
ipcRenderer.on('tray', (_event: Event, arg: number): void => {
|
||||
if (!tray) {
|
||||
return;
|
||||
}
|
||||
ipcRenderer.on("tray", (_event: Event, arg: number): void => {
|
||||
if (!tray) {
|
||||
return;
|
||||
}
|
||||
|
||||
// We don't want to create tray from unread messages on macOS since it already has dock badges.
|
||||
if (process.platform === 'linux' || process.platform === 'win32') {
|
||||
if (arg === 0) {
|
||||
unread = arg;
|
||||
tray.setImage(iconPath());
|
||||
tray.setToolTip('No unread messages');
|
||||
} else {
|
||||
unread = arg;
|
||||
const image = renderNativeImage(arg);
|
||||
tray.setImage(image);
|
||||
tray.setToolTip(`${arg} unread messages`);
|
||||
}
|
||||
}
|
||||
// We don't want to create tray from unread messages on macOS since it already has dock badges.
|
||||
if (process.platform === "linux" || process.platform === "win32") {
|
||||
if (arg === 0) {
|
||||
unread = arg;
|
||||
tray.setImage(iconPath());
|
||||
tray.setToolTip("No unread messages");
|
||||
} else {
|
||||
unread = arg;
|
||||
const image = renderNativeImage(arg);
|
||||
tray.setImage(image);
|
||||
tray.setToolTip(`${arg} unread messages`);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
function toggleTray(): void {
|
||||
let state;
|
||||
if (tray) {
|
||||
state = false;
|
||||
tray.destroy();
|
||||
if (tray.isDestroyed()) {
|
||||
tray = null;
|
||||
}
|
||||
let state;
|
||||
if (tray) {
|
||||
state = false;
|
||||
tray.destroy();
|
||||
if (tray.isDestroyed()) {
|
||||
tray = null;
|
||||
}
|
||||
|
||||
ConfigUtil.setConfigItem('trayIcon', false);
|
||||
} else {
|
||||
state = true;
|
||||
createTray();
|
||||
if (process.platform === 'linux' || process.platform === 'win32') {
|
||||
const image = renderNativeImage(unread);
|
||||
tray.setImage(image);
|
||||
tray.setToolTip(`${unread} unread messages`);
|
||||
}
|
||||
ConfigUtil.setConfigItem("trayIcon", false);
|
||||
} else {
|
||||
state = true;
|
||||
createTray();
|
||||
if (process.platform === "linux" || process.platform === "win32") {
|
||||
const image = renderNativeImage(unread);
|
||||
tray.setImage(image);
|
||||
tray.setToolTip(`${unread} unread messages`);
|
||||
}
|
||||
|
||||
ConfigUtil.setConfigItem('trayIcon', true);
|
||||
}
|
||||
ConfigUtil.setConfigItem("trayIcon", true);
|
||||
}
|
||||
|
||||
const selector = 'webview:not([class*=disabled])';
|
||||
const webview: WebviewTag = document.querySelector(selector);
|
||||
const webContents = remote.webContents.fromId(webview.getWebContentsId());
|
||||
webContents.send('toggletray', state);
|
||||
const selector = "webview:not([class*=disabled])";
|
||||
const webview: WebviewTag = document.querySelector(selector);
|
||||
const webContents = remote.webContents.fromId(webview.getWebContentsId());
|
||||
webContents.send("toggletray", state);
|
||||
}
|
||||
|
||||
ipcRenderer.on('toggletray', toggleTray);
|
||||
ipcRenderer.on("toggletray", toggleTray);
|
||||
|
||||
if (ConfigUtil.getConfigItem('trayIcon', true)) {
|
||||
createTray();
|
||||
if (ConfigUtil.getConfigItem("trayIcon", true)) {
|
||||
createTray();
|
||||
}
|
||||
|
||||
export {};
|
||||
|
Reference in New Issue
Block a user