Use process-specific electron/{main,renderer,common} imports.

Signed-off-by: Anders Kaseorg <anders@zulip.com>
This commit is contained in:
Anders Kaseorg
2022-03-14 21:29:09 -07:00
parent 343e0ed848
commit 5acc45cba4
22 changed files with 113 additions and 105 deletions

View File

@@ -1,7 +1,6 @@
import electron from "electron";
export const {app, dialog} = export const {app, dialog} =
process.type === "renderer" process.type === "renderer"
? // eslint-disable-next-line @typescript-eslint/no-require-imports, @typescript-eslint/no-var-requires ? // eslint-disable-next-line @typescript-eslint/no-require-imports, @typescript-eslint/no-var-requires
(require("@electron/remote") as typeof import("@electron/remote")) (require("@electron/remote") as typeof import("@electron/remote"))
: electron; : // eslint-disable-next-line @typescript-eslint/no-require-imports
require("electron/main");

View File

@@ -1,4 +1,5 @@
import {app, dialog, session, shell} from "electron"; import {shell} from "electron/common";
import {app, dialog, session} from "electron/main";
import util from "util"; import util from "util";
import log from "electron-log"; import log from "electron-log";

View File

@@ -1,13 +1,12 @@
import electron, {app} from "electron"; import {nativeImage} from "electron/common";
import type {BrowserWindow} from "electron/main";
import {app} from "electron/main";
import * as ConfigUtil from "../common/config-util"; import * as ConfigUtil from "../common/config-util";
import {send} from "./typed-ipc-main"; import {send} from "./typed-ipc-main";
function showBadgeCount( function showBadgeCount(messageCount: number, mainWindow: BrowserWindow): void {
messageCount: number,
mainWindow: electron.BrowserWindow,
): void {
if (process.platform === "win32") { if (process.platform === "win32") {
updateOverlayIcon(messageCount, mainWindow); updateOverlayIcon(messageCount, mainWindow);
} else { } else {
@@ -15,7 +14,7 @@ function showBadgeCount(
} }
} }
function hideBadgeCount(mainWindow: electron.BrowserWindow): void { function hideBadgeCount(mainWindow: BrowserWindow): void {
if (process.platform === "win32") { if (process.platform === "win32") {
mainWindow.setOverlayIcon(null, ""); mainWindow.setOverlayIcon(null, "");
} else { } else {
@@ -25,7 +24,7 @@ function hideBadgeCount(mainWindow: electron.BrowserWindow): void {
export function updateBadge( export function updateBadge(
badgeCount: number, badgeCount: number,
mainWindow: electron.BrowserWindow, mainWindow: BrowserWindow,
): void { ): void {
if (ConfigUtil.getConfigItem("badgeOption", true)) { if (ConfigUtil.getConfigItem("badgeOption", true)) {
showBadgeCount(badgeCount, mainWindow); showBadgeCount(badgeCount, mainWindow);
@@ -36,7 +35,7 @@ export function updateBadge(
function updateOverlayIcon( function updateOverlayIcon(
messageCount: number, messageCount: number,
mainWindow: electron.BrowserWindow, mainWindow: BrowserWindow,
): void { ): void {
if (!mainWindow.isFocused()) { if (!mainWindow.isFocused()) {
mainWindow.flashFrame( mainWindow.flashFrame(
@@ -54,8 +53,8 @@ function updateOverlayIcon(
export function updateTaskbarIcon( export function updateTaskbarIcon(
data: string, data: string,
text: string, text: string,
mainWindow: electron.BrowserWindow, mainWindow: BrowserWindow,
): void { ): void {
const img = electron.nativeImage.createFromDataURL(data); const img = nativeImage.createFromDataURL(data);
mainWindow.setOverlayIcon(img, text); mainWindow.setOverlayIcon(img, text);
} }

View File

@@ -1,4 +1,5 @@
import electron, {app, dialog, session} from "electron"; import type {IpcMainEvent, SaveDialogOptions, WebContents} from "electron/main";
import {BrowserWindow, app, dialog, powerMonitor, session} from "electron/main";
import fs from "fs"; import fs from "fs";
import path from "path"; import path from "path";
@@ -25,7 +26,7 @@ sentryInit();
let mainWindowState: windowStateKeeper.State; let mainWindowState: windowStateKeeper.State;
// Prevent window being garbage collected // Prevent window being garbage collected
let mainWindow: Electron.BrowserWindow; let mainWindow: BrowserWindow;
let badgeCount: number; let badgeCount: number;
let isQuitting = false; let isQuitting = false;
@@ -50,7 +51,7 @@ const toggleApp = (): void => {
} }
}; };
function createMainWindow(): Electron.BrowserWindow { function createMainWindow(): BrowserWindow {
// Load the previous state with fallback to defaults // Load the previous state with fallback to defaults
mainWindowState = windowStateKeeper({ mainWindowState = windowStateKeeper({
defaultWidth: 1100, defaultWidth: 1100,
@@ -58,7 +59,7 @@ function createMainWindow(): Electron.BrowserWindow {
path: `${app.getPath("userData")}/config`, path: `${app.getPath("userData")}/config`,
}); });
const win = new electron.BrowserWindow({ const win = new BrowserWindow({
// This settings needs to be saved in config // This settings needs to be saved in config
title: "Zulip", title: "Zulip",
icon: iconPath(), icon: iconPath(),
@@ -239,7 +240,7 @@ function createMainWindow(): Electron.BrowserWindow {
"certificate-error", "certificate-error",
( (
event: Event, event: Event,
webContents: Electron.WebContents, webContents: WebContents,
urlString: string, urlString: string,
error: string, error: string,
) => { ) => {
@@ -275,7 +276,7 @@ ${error}`,
); );
// Temporarily remove this event // Temporarily remove this event
// electron.powerMonitor.on('resume', () => { // powerMonitor.on('resume', () => {
// mainWindow.reload(); // mainWindow.reload();
// send(page, 'destroytray'); // send(page, 'destroytray');
// }); // });
@@ -308,27 +309,21 @@ ${error}`,
BadgeSettings.updateBadge(badgeCount, mainWindow); BadgeSettings.updateBadge(badgeCount, mainWindow);
}); });
ipcMain.on( ipcMain.on("toggle-menubar", (_event: IpcMainEvent, showMenubar: boolean) => {
"toggle-menubar", mainWindow.autoHideMenuBar = showMenubar;
(_event: Electron.IpcMainEvent, showMenubar: boolean) => { mainWindow.setMenuBarVisibility(!showMenubar);
mainWindow.autoHideMenuBar = showMenubar; send(page, "toggle-autohide-menubar", showMenubar, true);
mainWindow.setMenuBarVisibility(!showMenubar); });
send(page, "toggle-autohide-menubar", showMenubar, true);
},
);
ipcMain.on( ipcMain.on("update-badge", (_event: IpcMainEvent, messageCount: number) => {
"update-badge", badgeCount = messageCount;
(_event: Electron.IpcMainEvent, messageCount: number) => { BadgeSettings.updateBadge(badgeCount, mainWindow);
badgeCount = messageCount; send(page, "tray", messageCount);
BadgeSettings.updateBadge(badgeCount, mainWindow); });
send(page, "tray", messageCount);
},
);
ipcMain.on( ipcMain.on(
"update-taskbar-icon", "update-taskbar-icon",
(_event: Electron.IpcMainEvent, data: string, text: string) => { (_event: IpcMainEvent, data: string, text: string) => {
BadgeSettings.updateTaskbarIcon(data, text, mainWindow); BadgeSettings.updateTaskbarIcon(data, text, mainWindow);
}, },
); );
@@ -336,7 +331,7 @@ ${error}`,
ipcMain.on( ipcMain.on(
"forward-message", "forward-message",
<Channel extends keyof RendererMessage>( <Channel extends keyof RendererMessage>(
_event: Electron.IpcMainEvent, _event: IpcMainEvent,
listener: Channel, listener: Channel,
...parameters: Parameters<RendererMessage[Channel]> ...parameters: Parameters<RendererMessage[Channel]>
) => { ) => {
@@ -344,31 +339,28 @@ ${error}`,
}, },
); );
ipcMain.on( ipcMain.on("update-menu", (_event: IpcMainEvent, props: MenuProps) => {
"update-menu", AppMenu.setMenu(props);
(_event: Electron.IpcMainEvent, props: MenuProps) => { if (props.activeTabIndex !== undefined) {
AppMenu.setMenu(props); const activeTab = props.tabs[props.activeTabIndex];
if (props.activeTabIndex !== undefined) { mainWindow.setTitle(`Zulip - ${activeTab.name}`);
const activeTab = props.tabs[props.activeTabIndex]; }
mainWindow.setTitle(`Zulip - ${activeTab.name}`); });
}
},
);
ipcMain.on( ipcMain.on(
"toggleAutoLauncher", "toggleAutoLauncher",
async (_event: Electron.IpcMainEvent, AutoLaunchValue: boolean) => { async (_event: IpcMainEvent, AutoLaunchValue: boolean) => {
await setAutoLaunch(AutoLaunchValue); await setAutoLaunch(AutoLaunchValue);
}, },
); );
ipcMain.on( ipcMain.on(
"downloadFile", "downloadFile",
(_event: Electron.IpcMainEvent, url: string, downloadPath: string) => { (_event: IpcMainEvent, url: string, downloadPath: string) => {
page.downloadURL(url); page.downloadURL(url);
page.session.once("will-download", async (_event: Event, item) => { page.session.once("will-download", async (_event: Event, item) => {
if (ConfigUtil.getConfigItem("promptDownload", false)) { if (ConfigUtil.getConfigItem("promptDownload", false)) {
const showDialogOptions: electron.SaveDialogOptions = { const showDialogOptions: SaveDialogOptions = {
defaultPath: path.join(downloadPath, item.getFilename()), defaultPath: path.join(downloadPath, item.getFilename()),
}; };
item.setSaveDialogOptions(showDialogOptions); item.setSaveDialogOptions(showDialogOptions);
@@ -443,26 +435,23 @@ ${error}`,
ipcMain.on( ipcMain.on(
"realm-name-changed", "realm-name-changed",
(_event: Electron.IpcMainEvent, serverURL: string, realmName: string) => { (_event: IpcMainEvent, serverURL: string, realmName: string) => {
send(page, "update-realm-name", serverURL, realmName); send(page, "update-realm-name", serverURL, realmName);
}, },
); );
ipcMain.on( ipcMain.on(
"realm-icon-changed", "realm-icon-changed",
(_event: Electron.IpcMainEvent, serverURL: string, iconURL: string) => { (_event: IpcMainEvent, serverURL: string, iconURL: string) => {
send(page, "update-realm-icon", serverURL, iconURL); send(page, "update-realm-icon", serverURL, iconURL);
}, },
); );
ipcMain.on( ipcMain.on("save-last-tab", (_event: IpcMainEvent, index: number) => {
"save-last-tab", ConfigUtil.setConfigItem("lastActiveTab", index);
(_event: Electron.IpcMainEvent, index: number) => { });
ConfigUtil.setConfigItem("lastActiveTab", index);
},
);
ipcMain.on("focus-this-webview", (event: Electron.IpcMainEvent) => { ipcMain.on("focus-this-webview", (event: IpcMainEvent) => {
send(page, "focus-webview-with-id", event.sender.id); send(page, "focus-webview-with-id", event.sender.id);
mainWindow.show(); mainWindow.show();
}); });
@@ -472,8 +461,7 @@ ${error}`,
setInterval(() => { setInterval(() => {
// Set user idle if no activity in 1 second (idleThresholdSeconds) // Set user idle if no activity in 1 second (idleThresholdSeconds)
const idleThresholdSeconds = 1; // 1 second const idleThresholdSeconds = 1; // 1 second
const idleState = const idleState = powerMonitor.getSystemIdleState(idleThresholdSeconds);
electron.powerMonitor.getSystemIdleState(idleThresholdSeconds);
if (idleState === "active") { if (idleState === "active") {
send(page, "set-active"); send(page, "set-active");
} else { } else {

View File

@@ -1,4 +1,4 @@
import {app, dialog} from "electron"; import {app, dialog} from "electron/main";
import fs from "fs"; import fs from "fs";
import path from "path"; import path from "path";

View File

@@ -1,4 +1,5 @@
import {Notification, app, net} from "electron"; import type {Session} from "electron/main";
import {Notification, app, net} from "electron/main";
import getStream from "get-stream"; import getStream from "get-stream";
import * as semver from "semver"; import * as semver from "semver";
@@ -14,9 +15,7 @@ const logger = new Logger({
file: "linux-update-util.log", file: "linux-update-util.log",
}); });
export async function linuxUpdateNotification( export async function linuxUpdateNotification(session: Session): Promise<void> {
session: Electron.Session,
): Promise<void> {
let url = "https://api.github.com/repos/zulip/zulip-desktop/releases"; let url = "https://api.github.com/repos/zulip/zulip-desktop/releases";
url = ConfigUtil.getConfigItem("betaUpdate", false) ? url : url + "/latest"; url = ConfigUtil.getConfigItem("betaUpdate", false) ? url : url + "/latest";

View File

@@ -1,4 +1,6 @@
import {BrowserWindow, Menu, app, shell} from "electron"; import {shell} from "electron/common";
import type {MenuItemConstructorOptions} from "electron/main";
import {BrowserWindow, Menu, app} from "electron/main";
import AdmZip from "adm-zip"; import AdmZip from "adm-zip";
@@ -13,9 +15,7 @@ import {send} from "./typed-ipc-main";
const appName = app.name; const appName = app.name;
function getHistorySubmenu( function getHistorySubmenu(enableMenu: boolean): MenuItemConstructorOptions[] {
enableMenu: boolean,
): Electron.MenuItemConstructorOptions[] {
return [ return [
{ {
label: t.__("Back"), label: t.__("Back"),
@@ -41,7 +41,7 @@ function getHistorySubmenu(
]; ];
} }
function getToolsSubmenu(): Electron.MenuItemConstructorOptions[] { function getToolsSubmenu(): MenuItemConstructorOptions[] {
return [ return [
{ {
label: t.__("Check for Updates"), label: t.__("Check for Updates"),
@@ -107,7 +107,7 @@ function getToolsSubmenu(): Electron.MenuItemConstructorOptions[] {
]; ];
} }
function getViewSubmenu(): Electron.MenuItemConstructorOptions[] { function getViewSubmenu(): MenuItemConstructorOptions[] {
return [ return [
{ {
label: t.__("Reload"), label: t.__("Reload"),
@@ -256,7 +256,7 @@ function getViewSubmenu(): Electron.MenuItemConstructorOptions[] {
]; ];
} }
function getHelpSubmenu(): Electron.MenuItemConstructorOptions[] { function getHelpSubmenu(): MenuItemConstructorOptions[] {
return [ return [
{ {
label: `${appName + " Desktop"} v${app.getVersion()}`, label: `${appName + " Desktop"} v${app.getVersion()}`,
@@ -290,8 +290,8 @@ function getHelpSubmenu(): Electron.MenuItemConstructorOptions[] {
function getWindowSubmenu( function getWindowSubmenu(
tabs: TabData[], tabs: TabData[],
activeTabIndex?: number, activeTabIndex?: number,
): Electron.MenuItemConstructorOptions[] { ): MenuItemConstructorOptions[] {
const initialSubmenu: Electron.MenuItemConstructorOptions[] = [ const initialSubmenu: MenuItemConstructorOptions[] = [
{ {
label: t.__("Minimize"), label: t.__("Minimize"),
role: "minimize", role: "minimize",
@@ -367,7 +367,7 @@ function getWindowSubmenu(
return initialSubmenu; return initialSubmenu;
} }
function getDarwinTpl(props: MenuProps): Electron.MenuItemConstructorOptions[] { function getDarwinTpl(props: MenuProps): MenuItemConstructorOptions[] {
const {tabs, activeTabIndex, enableMenu = false} = props; const {tabs, activeTabIndex, enableMenu = false} = props;
return [ return [
@@ -532,7 +532,7 @@ function getDarwinTpl(props: MenuProps): Electron.MenuItemConstructorOptions[] {
]; ];
} }
function getOtherTpl(props: MenuProps): Electron.MenuItemConstructorOptions[] { function getOtherTpl(props: MenuProps): MenuItemConstructorOptions[] {
const {tabs, activeTabIndex, enableMenu = false} = props; const {tabs, activeTabIndex, enableMenu = false} = props;
return [ return [
{ {

View File

@@ -1,5 +1,5 @@
import type {ClientRequest, IncomingMessage} from "electron"; import type {ClientRequest, IncomingMessage, Session} from "electron/main";
import {app, net} from "electron"; import {app, net} from "electron/main";
import fs from "fs"; import fs from "fs";
import path from "path"; import path from "path";
import stream from "stream"; import stream from "stream";
@@ -57,7 +57,7 @@ const generateFilePath = (url: string): string => {
export const _getServerSettings = async ( export const _getServerSettings = async (
domain: string, domain: string,
session: Electron.Session, session: Session,
): Promise<ServerConf> => { ): Promise<ServerConf> => {
const response = await fetchResponse( const response = await fetchResponse(
net.request({ net.request({
@@ -89,7 +89,7 @@ export const _getServerSettings = async (
export const _saveServerIcon = async ( export const _saveServerIcon = async (
url: string, url: string,
session: Electron.Session, session: Session,
): Promise<string> => { ): Promise<string> => {
try { try {
const response = await fetchResponse(net.request({url, session})); const response = await fetchResponse(net.request({url, session}));
@@ -113,7 +113,7 @@ export const _saveServerIcon = async (
export const _isOnline = async ( export const _isOnline = async (
url: string, url: string,
session: Electron.Session, session: Session,
): Promise<boolean> => { ): Promise<boolean> => {
try { try {
const response = await fetchResponse( const response = await fetchResponse(

View File

@@ -1,4 +1,4 @@
import {app} from "electron"; import {app} from "electron/main";
import * as Sentry from "@sentry/electron"; import * as Sentry from "@sentry/electron";

View File

@@ -1,4 +1,4 @@
import {app} from "electron"; import {app} from "electron/main";
import AutoLaunch from "auto-launch"; import AutoLaunch from "auto-launch";

View File

@@ -1,7 +1,11 @@
import type {IpcMainEvent, IpcMainInvokeEvent, WebContents} from "electron"; import type {
IpcMainEvent,
IpcMainInvokeEvent,
WebContents,
} from "electron/main";
import { import {
ipcMain as untypedIpcMain, // eslint-disable-line no-restricted-imports ipcMain as untypedIpcMain, // eslint-disable-line no-restricted-imports
} from "electron"; } from "electron/main";
import type { import type {
MainCall, MainCall,

View File

@@ -1,5 +1,5 @@
import crypto from "crypto"; import crypto from "crypto";
import {clipboard} from "electron"; import {clipboard} from "electron/common";
// This helper is exposed via electron_bridge for use in the social // This helper is exposed via electron_bridge for use in the social
// login flow. // login flow.

View File

@@ -1,11 +1,15 @@
import type {ContextMenuParams} from "electron"; import type {WebContents} from "electron/main";
import type {
ContextMenuParams,
MenuItemConstructorOptions,
} from "electron/renderer";
import {Menu, clipboard} from "@electron/remote"; import {Menu, clipboard} from "@electron/remote";
import * as t from "../../../common/translation-util"; import * as t from "../../../common/translation-util";
export const contextMenu = ( export const contextMenu = (
webContents: Electron.WebContents, webContents: WebContents,
event: Event, event: Event,
props: ContextMenuParams, props: ContextMenuParams,
) => { ) => {
@@ -21,7 +25,7 @@ export const contextMenu = (
}, },
}); });
let menuTemplate: Electron.MenuItemConstructorOptions[] = [ let menuTemplate: MenuItemConstructorOptions[] = [
{ {
label: t.__("Add to Dictionary"), label: t.__("Add to Dictionary"),
visible: props.isEditable && isText && props.misspelledWord.length > 0, visible: props.isEditable && isText && props.misspelledWord.length > 0,
@@ -118,7 +122,7 @@ export const contextMenu = (
if (props.misspelledWord) { if (props.misspelledWord) {
if (props.dictionarySuggestions.length > 0) { if (props.dictionarySuggestions.length > 0) {
const suggestions: Electron.MenuItemConstructorOptions[] = const suggestions: MenuItemConstructorOptions[] =
props.dictionarySuggestions.map((suggestion: string) => props.dictionarySuggestions.map((suggestion: string) =>
makeSuggestion(suggestion), makeSuggestion(suggestion),
); );

View File

@@ -1,3 +1,5 @@
import type {HandlerDetails} from "electron/renderer";
import {app, shell} from "@electron/remote"; import {app, shell} from "@electron/remote";
import * as ConfigUtil from "../../../common/config-util"; import * as ConfigUtil from "../../../common/config-util";
@@ -10,7 +12,7 @@ const dingSound = new Audio("../resources/sounds/ding.ogg");
export default function handleExternalLink( export default function handleExternalLink(
this: WebView, this: WebView,
details: Electron.HandlerDetails, details: HandlerDetails,
): void { ): void {
const url = new URL(details.url); const url = new URL(details.url);
const downloadPath = ConfigUtil.getConfigItem( const downloadPath = ConfigUtil.getConfigItem(

View File

@@ -1,3 +1,4 @@
import type {WebContents} from "electron/main";
import fs from "fs"; import fs from "fs";
import path from "path"; import path from "path";
@@ -20,7 +21,7 @@ const shouldSilentWebview = ConfigUtil.getConfigItem("silent", false);
interface WebViewProps { interface WebViewProps {
$root: Element; $root: Element;
rootWebContents: Electron.WebContents; rootWebContents: WebContents;
index: number; index: number;
tabIndex: number; tabIndex: number;
url: string; url: string;
@@ -119,7 +120,7 @@ export default class WebView {
return new WebView(props, $element, webContentsId); return new WebView(props, $element, webContentsId);
} }
getWebContents(): Electron.WebContents { getWebContents(): WebContents {
return remote.webContents.fromId(this.webContentsId); return remote.webContents.fromId(this.webContentsId);
} }

View File

@@ -1,4 +1,4 @@
import {clipboard} from "electron"; import {clipboard} from "electron/common";
import path from "path"; import path from "path";
import {Menu, app, dialog, session} from "@electron/remote"; import {Menu, app, dialog, session} from "@electron/remote";

View File

@@ -1,4 +1,4 @@
import type {OpenDialogOptions} from "electron"; import type {OpenDialogOptions} from "electron/renderer";
import fs from "fs"; import fs from "fs";
import path from "path"; import path from "path";

View File

@@ -1,4 +1,4 @@
import {contextBridge, webFrame} from "electron"; import {contextBridge, webFrame} from "electron/renderer";
import fs from "fs"; import fs from "fs";
import electron_bridge, {bridgeEvents} from "./electron-bridge"; import electron_bridge, {bridgeEvents} from "./electron-bridge";

View File

@@ -1,4 +1,5 @@
import type {NativeImage} from "electron"; import type {NativeImage} from "electron/common";
import type {Tray as ElectronTray} from "electron/main";
import path from "path"; import path from "path";
import {BrowserWindow, Menu, Tray, nativeImage} from "@electron/remote"; import {BrowserWindow, Menu, Tray, nativeImage} from "@electron/remote";
@@ -9,7 +10,7 @@ import type {RendererMessage} from "../../common/typed-ipc";
import type {ServerManagerView} from "./main"; import type {ServerManagerView} from "./main";
import {ipcRenderer} from "./typed-ipc-renderer"; import {ipcRenderer} from "./typed-ipc-renderer";
let tray: Electron.Tray | null = null; let tray: ElectronTray | null = null;
const iconDir = "../../resources/tray"; const iconDir = "../../resources/tray";

View File

@@ -1,7 +1,7 @@
import type {IpcRendererEvent} from "electron"; import type {IpcRendererEvent} from "electron/renderer";
import { import {
ipcRenderer as untypedIpcRenderer, // eslint-disable-line no-restricted-imports ipcRenderer as untypedIpcRenderer, // eslint-disable-line no-restricted-imports
} from "electron"; } from "electron/renderer";
import type { import type {
MainCall, MainCall,

View File

@@ -1,4 +1,4 @@
import {shell} from "electron"; import {shell} from "electron/common";
import fs from "fs"; import fs from "fs";
import os from "os"; import os from "os";
import path from "path"; import path from "path";

View File

@@ -248,11 +248,21 @@
"paths": [ "paths": [
{ {
"name": "electron", "name": "electron",
"message": "Use electron/main, electron/renderer, or electron/common."
},
{
"name": "electron/main",
"importNames": [
"ipcMain"
],
"message": "Use typed-ipc-main."
},
{
"name": "electron/renderer",
"importNames": [ "importNames": [
"ipcMain",
"ipcRenderer" "ipcRenderer"
], ],
"message": "Use typed-ipc-main and typed-ipc-renderer." "message": "Use typed-ipc-renderer."
} }
] ]
} }