Skip to content

Commit

Permalink
update electron 2.0.9 => 3.0.0 and other dependencies
Browse files Browse the repository at this point in the history
  • Loading branch information
vladimiry committed Sep 24, 2018
1 parent 2821b17 commit f3a63da
Show file tree
Hide file tree
Showing 10 changed files with 562 additions and 596 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ is built with Electron unofficial desktop app for [ProtonMail](https://protonmai

## Build your own package

- Regardless of the platform you are working on, you will need to have Node.JS v8 installed. Version 8 is required to match the Node.JS version Electron comes with. If you already have Node.JS installed, but not the version 8, then you might want to use [Node Version Manager](https://github.com/creationix/nvm) to be able to switch between multiple Node.JS versions:
- Regardless of the platform you are working on, you will need to have Node.js v10 installed. v10 as it's recommended to go with the same Node.js version Electron comes with. If you already have Node.js installed, but not the version 10, then you might want to use [Node Version Manager](https://github.com/creationix/nvm) to be able to switch between multiple Node.js versions:
- Install [NVM](https://github.com/creationix/nvm).
- Run `nvm install 8`.
- Run `nvm use 8`.
- Run `nvm install 10`.
- Run `nvm use 10`.
- Some native modules require node prebuilds files compiling and for that Python and C++ compiler need to be installed on your system:
- **`On Windows`**: the simplest way to install all the needed stuff on Windows is to run `npm install --global --production windows-build-tools` CLI command.
- **`On Linux`**: `python v2.7`, `make` and a C/C++ compiler toolchain, like `GCC` are most likely already installed. Besides [keytar](https://github.com/atom/node-keytar) needs `libsecret` library to be installed.
Expand Down
65 changes: 33 additions & 32 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@
"fs-no-eperm-anymore": "2.0.2",
"html-to-text": "4.0.0",
"image-processing-js": "0.0.0",
"keepasshttp-client": "2.2.7",
"keepasshttp-client": "2.2.8",
"keytar": "4.2.1",
"memory-streams": "0.1.3",
"p-queue": "3.0.0",
Expand All @@ -103,33 +103,33 @@
"valid-url": "1.0.9"
},
"devDependencies": {
"@angular-devkit/build-optimizer": "0.8.1",
"@angular/animations": "6.1.7",
"@angular/common": "6.1.7",
"@angular/compiler": "6.1.7",
"@angular/compiler-cli": "6.1.7",
"@angular/core": "6.1.7",
"@angular/forms": "6.1.7",
"@angular/http": "6.1.7",
"@angular/language-service": "6.1.7",
"@angular/platform-browser": "6.1.7",
"@angular/platform-browser-dynamic": "6.1.7",
"@angular/router": "6.1.7",
"@angular-devkit/build-optimizer": "0.8.3",
"@angular/animations": "6.1.8",
"@angular/common": "6.1.8",
"@angular/compiler": "6.1.8",
"@angular/compiler-cli": "6.1.8",
"@angular/core": "6.1.8",
"@angular/forms": "6.1.8",
"@angular/http": "6.1.8",
"@angular/language-service": "6.1.8",
"@angular/platform-browser": "6.1.8",
"@angular/platform-browser-dynamic": "6.1.8",
"@angular/router": "6.1.8",
"@angularclass/hmr": "2.1.3",
"@email-securely-app/import-sort-style": "0.1.0",
"@ng-select/ng-select": "2.8.1",
"@ng-select/ng-select": "2.9.1",
"@ngrx/effects": "6.1.0",
"@ngrx/router-store": "6.1.0",
"@ngrx/store": "6.1.0",
"@ngtools/webpack": "6.2.1",
"@ngtools/webpack": "6.2.3",
"@types/html-to-text": "1.4.31",
"@types/html-webpack-plugin": "3.2.0",
"@types/jasmine": "2.8.8",
"@types/karma": "1.7.6",
"@types/keytar": "4.0.1",
"@types/mini-css-extract-plugin": "0.2.0",
"@types/mkdirp": "0.5.2",
"@types/node": "8.10.11",
"@types/node": "10.10.3",
"@types/node-fetch": "2.1.2",
"@types/p-queue": "2.3.1",
"@types/ramda": "0.25.38",
Expand All @@ -142,9 +142,9 @@
"@types/tapable": "1.0.4",
"@types/uglifyjs-webpack-plugin": "1.1.0",
"@types/valid-url": "1.0.2",
"@types/webdriverio": "4.10.3",
"@types/webpack": "4.4.11",
"@types/webpack-dev-server": "3.1.0",
"@types/webdriverio": "4.10.4",
"@types/webpack": "4.4.12",
"@types/webpack-dev-server": "3.1.1",
"@types/webpack-env": "1.13.6",
"@types/webpack-merge": "4.1.3",
"@types/webpack-node-externals": "1.6.3",
Expand All @@ -162,15 +162,15 @@
"css-loader": "1.0.0",
"cssnano": "4.1.0",
"devtron": "1.4.0",
"electron": "2.0.9",
"electron": "3.0.0",
"electron-builder": "20.28.4",
"exports-loader": "0.7.0",
"file-loader": "2.0.0",
"font-awesome": "4.7.0",
"html-loader": "0.5.5",
"html-webpack-plugin": "4.0.0-alpha",
"husky": "0.14.3",
"immer": "1.6.0",
"husky": "1.0.0-rc.15",
"immer": "1.7.2",
"import-sort-cli": "5.2.0",
"import-sort-parser-typescript": "5.0.0",
"jasmine": "3.2.0",
Expand All @@ -183,8 +183,8 @@
"karma-webpack": "4.0.0-rc.2",
"keysim": "2.1.0",
"less-loader": "4.1.0",
"lint-staged": "7.2.2",
"mini-css-extract-plugin": "0.4.2",
"lint-staged": "7.3.0",
"mini-css-extract-plugin": "0.4.3",
"mkdirp": "0.5.1",
"ng2-dragula": "2.1.0",
"ngx-bootstrap": "3.0.1",
Expand All @@ -196,20 +196,18 @@
"nsp-preprocessor-yarn": "1.1.2",
"null-loader": "0.1.1",
"otplib": "10.0.1",
"postcss-custom-properties": "7.0.0",
"postcss-custom-properties": "8.0.5",
"postcss-loader": "3.0.0",
"postcss-url": "8.0.0",
"ps-node": "0.1.6",
"ps-tree": "1.1.0",
"randomstring": "1.1.5",
"raw-loader": "0.5.1",
"resolve-url-loader": "2.3.1",
"resolve-url-loader": "3.0.0",
"rewiremock": "3.7.8",
"rxjs-compat": "6.3.2",
"sass-lint": "1.12.1",
"sass-loader": "7.1.0",
"script-loader": "0.7.2",
"sinon": "6.3.1",
"sinon": "6.3.4",
"source-map": "0.7.3",
"source-map-loader": "0.2.4",
"source-map-support": "0.5.9",
Expand All @@ -226,13 +224,16 @@
"tslint-eslint-rules": "5.4.0",
"tslint-rules-bunch": "0.0.5",
"typescript": "3.0.3",
"uglifyjs-webpack-plugin": "1.3.0",
"uglifyjs-webpack-plugin": "2.0.1",
"url-loader": "1.1.1",
"webpack": "4.18.1",
"webpack-cli": "3.1.0",
"webpack": "4.19.1",
"webpack-cli": "3.1.1",
"webpack-dev-server": "3.1.8",
"webpack-merge": "4.1.4",
"webpack-node-externals": "1.7.2",
"zone.js": "0.8.26"
},
"resolutions": {
"spectron/**/electron-chromedriver": "^3.0.0-beta.1"
}
}
1 change: 0 additions & 1 deletion src/@types/ps-node/index.d.ts

This file was deleted.

1 change: 0 additions & 1 deletion src/@types/ps-tree/index.d.ts

This file was deleted.

43 changes: 7 additions & 36 deletions src/e2e/workflow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ import electron from "electron";
import fs from "fs";
import mkdirp from "mkdirp";
import path from "path";
import psNode from "ps-node"; // see also https://www.npmjs.com/package/find-process
import psTree from "ps-tree";
import randomString from "randomstring";
import sinon from "sinon";
import ava, {ExecutionContext, TestInterface} from "ava";
Expand Down Expand Up @@ -145,40 +143,13 @@ function buildWorkflow(t: ExecutionContext<TestContext>) {
const workflow = {
async destroyApp() {
// TODO update to electron 2: app.isRunning() returns undefined, uncomment as soon as it's fixed
// if (!t.context.app || !t.context.app.isRunning()) {
// t.pass("app is not running");
// return;
// }
// await t.context.app.stop();
// t.is(t.context.app.isRunning(), false);
// delete t.context.app;

// TODO update to electron 2: remove as soon as app.isRunning() returns valid value
await (async () => {
const processes = await promisify(psNode.lookup)({
command: "electron",
// arguments: mainScriptFilePath.replace(/\\/g, "\\\\"),
arguments: "--enable-automation",
});
const pid = processes.length && processes.pop().pid;

if (!pid) {
throw new Error("Filed to lookup process Electron root process to kill");
}

const processesToKill = [
...(await promisify(psTree)(pid)),
{PID: pid},
];

for (const {PID} of processesToKill) {
try {
process.kill(Number(PID), "SIGKILL");
} catch {
// NOOP
}
}
})();
if (!t.context.app || !t.context.app.isRunning()) {
t.pass("app is not running");
return;
}
await t.context.app.stop();
t.is(t.context.app.isRunning(), false);
delete t.context.app;
},

async login(options: { setup: boolean, savePassword: boolean }) {
Expand Down
20 changes: 13 additions & 7 deletions src/electron-main/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,34 @@ import rewiremock from "rewiremock";
import ava, {TestInterface} from "ava";
import sinon, {SinonStub} from "sinon";

import {APP_NAME} from "src/shared/constants";
import {APP_NAME, ONE_SECOND_MS} from "src/shared/constants";
import {Endpoints} from "src/shared/api/main";
import {INITIAL_STORES} from "./constants";
import {asyncDelay} from "src/shared/util";

interface TestContext {
ctx: any;
endpoints: Record<keyof Pick<Endpoints, "readConfig" | "updateOverlayIcon">, SinonStub>;
endpoints: Record<keyof Pick<Endpoints, "readConfig" | "updateOverlayIcon" | "activateBrowserWindow">, SinonStub>;
mocks: ReturnType<typeof buildMocks>;
}

const test = ava as TestInterface<TestContext>;

// tslint:disable:max-line-length
test.serial("workflow", async (t) => {
await asyncDelay(ONE_SECOND_MS);

const m = t.context.mocks["~index"];
const {endpoints} = t.context;

t.true(m["electron-unhandled"].calledWithExactly(sinon.match.hasOwn("logger")), `"electronUnhandled" called`);
t.true(m["electron-unhandled"].calledBefore(m.electron.app.setAppUserModelId), `"electronUnhandled" called before "makeSingleInstance"`);
t.true(m["electron-unhandled"].calledBefore(m.electron.app.setAppUserModelId), `"electronUnhandled" called before "requestSingleInstanceLock"`);

t.true(m.electron.app.setAppUserModelId.calledWithExactly(`com.github.vladimiry.${APP_NAME}`));
t.true(m.electron.app.setAppUserModelId.calledBefore(m.electron.app.makeSingleInstance));
t.true(m.electron.app.setAppUserModelId.calledBefore(m.electron.app.requestSingleInstanceLock));

t.true(m.electron.app.makeSingleInstance.called, `"makeSingleInstance" called`);
t.true(m.electron.app.makeSingleInstance.calledBefore(m["./util"].initContext), `"makeSingleInstance" called before "initContext"`);
t.true(m.electron.app.requestSingleInstanceLock.called, `"requestSingleInstanceLock" called`);
t.true(m.electron.app.requestSingleInstanceLock.calledBefore(m["./util"].initContext), `"requestSingleInstanceLock" called before "initContext"`);

t.true(m["./util"].initContext.calledWithExactly(), `"initContext" called`);

Expand Down Expand Up @@ -59,6 +62,9 @@ test.beforeEach(async (t) => {
updateOverlayIcon: sinon.stub().returns({
toPromise: () => Promise.resolve(null),
}),
activateBrowserWindow: sinon.stub().returns({
toPromise: () => Promise.resolve(INITIAL_STORES.config()),
}),
};

t.context.ctx = {
Expand Down Expand Up @@ -118,7 +124,7 @@ function buildMocks(testContext: TestContext) {
"electron": {
app: {
setAppUserModelId: sinon.spy(),
makeSingleInstance: sinon.spy(),
requestSingleInstanceLock: sinon.stub().returns(true),
quit: sinon.spy(),
on: sinon.stub()
.callsArg(1)
Expand Down
26 changes: 10 additions & 16 deletions src/electron-main/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,13 @@ electronUnhandled({logger: logger.error});
// needed for desktop notifications properly working on Win 10, details https://www.electron.build/configuration/nsis
app.setAppUserModelId(`com.github.vladimiry.${APP_NAME}`);

const secondInstanceExecutedCallbacks = (() => {
const callbacks: Array<() => Promise<any>> = [];
if (app.makeSingleInstance(async () => {
for (const callback of callbacks) {
await callback();
}
})) {
// calling app.exit() instead of app.quit() in order to prevent "Error: Cannot find module ..." error happening
// https://github.com/electron/electron/issues/8862
app.exit();
}
return callbacks;
})();
const singleInstanceLock = app.requestSingleInstanceLock();

if (!singleInstanceLock) {
// calling app.exit() instead of app.quit() in order to prevent "Error: Cannot find module ..." error happening
// https://github.com/electron/electron/issues/8862
app.exit();
}

const ctx = initContext();

Expand All @@ -39,8 +33,6 @@ app.on("ready", async () => {
const endpoints = await initApi(ctx);
const {checkForUpdatesAndNotify} = await endpoints.readConfig().toPromise();

secondInstanceExecutedCallbacks.push(() => endpoints.activateBrowserWindow().toPromise());

initWebContentContextMenu(ctx);

const uiContext = ctx.uiContext = {
Expand All @@ -59,13 +51,15 @@ app.on("ready", async () => {
}
}

app.on("second-instance", async () => {
await endpoints.activateBrowserWindow().toPromise();
});
app.on("activate", async () => {
// on macOS it's common to re-create a window in the app when the dock icon is clicked and there are no other windows open
if (!uiContext.browserWindow || uiContext.browserWindow.isDestroyed()) {
uiContext.browserWindow = await initBrowserWindow(ctx, endpoints);
}
});

app.on("web-contents-created", (webContentsCreatedEvent, contents) => {
contents.on("will-attach-webview", (willAttachWebviewEvent, webPreferences, params) => {
webPreferences.nodeIntegration = false;
Expand Down
2 changes: 1 addition & 1 deletion src/web/src/app/_db-view/db-view-mails.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {reduceNodesMails} from "src/shared/util";
export class DbViewMailsComponent {
// TODO read "email-securely-app-db-view-mail" dynamically from the annotation
private static mailComponentTagName = "email-securely-app-db-view-mail";
conversationViewMode: boolean = true;
conversationViewMode: boolean = false;
inputState!: Pick<Unpacked<typeof DbViewMailTabComponent.prototype.state$>, "selectedMail" | "rootConversationNodes">
& { meta: Instance["foldersMeta"][string] };
@Output()
Expand Down
2 changes: 1 addition & 1 deletion src/web/src/variables.scss
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ $app-font-size-base-small: $font-size-base * 0.75;
display: inline-block;
align-self: center;
line-height: 1;
padding: 0.34em .5em;
padding: 0.34em 0.5em;
margin-bottom: -1px;
}

Expand Down
Loading

0 comments on commit f3a63da

Please sign in to comment.