From 0fba9ea0e8deb632583cb1c965b90f9bec93770b Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Fri, 4 Jan 2019 13:36:08 +1100 Subject: [PATCH 001/153] WIP: Relates to #312. Initial setup using menubar library --- packages/fether-electron/mb.html | 6 ++++++ packages/fether-electron/mb.js | 24 ++++++++++++++++++++++++ packages/fether-electron/package.json | 2 +- 3 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 packages/fether-electron/mb.html create mode 100644 packages/fether-electron/mb.js diff --git a/packages/fether-electron/mb.html b/packages/fether-electron/mb.html new file mode 100644 index 000000000..82dae7135 --- /dev/null +++ b/packages/fether-electron/mb.html @@ -0,0 +1,6 @@ + + + + Hello World + + \ No newline at end of file diff --git a/packages/fether-electron/mb.js b/packages/fether-electron/mb.js new file mode 100644 index 000000000..a335c5222 --- /dev/null +++ b/packages/fether-electron/mb.js @@ -0,0 +1,24 @@ +const path = require('path'); +const menubar = require('menubar'); + +const indexDir = 'file://' + path.join(__dirname, '/static/build/index.html'); +// const indexDir = 'file://' + path.join(__dirname, '/mb.html'); // testing only +console.log(indexDir); + +const mb = menubar({ + dir: __dirname, + index: indexDir, + showDockIcon: true, + tooltip: 'Fether' +}); + +mb.on('ready', () => { + console.log('Fether is ready'); + // your app code here + + mb.showWindow(); +}); + +// mb.on('after-create-window', () => { +// mb.window.openDevTools(); +// }); diff --git a/packages/fether-electron/package.json b/packages/fether-electron/package.json index bb5f0444a..1af8d7afe 100644 --- a/packages/fether-electron/package.json +++ b/packages/fether-electron/package.json @@ -30,7 +30,7 @@ "scripts": { "prebuild": "copyfiles -u 2 \"../fether-react/build/**/*\" static/ && ./scripts/fixElectronBug.sh", "build": "electron-webpack", - "electron": "cross-env SKIP_PREFLIGHT_CHECK=true electron dist/main/main.js", + "electron": "cross-env SKIP_PREFLIGHT_CHECK=true electron mb.js", "prepackage": "./scripts/revertElectronBug.sh", "package": "electron-builder", "prerelease": "./scripts/revertElectronBug.sh", From 4cc3a6a8b1e12aa8e39d2254a2b4674802bb88bc Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Fri, 4 Jan 2019 15:07:23 +1100 Subject: [PATCH 002/153] feat: Update Readme. Add taskbar icon. Tweak taskbar window size. Change command to run taskbar app --- README.md | 16 +++++++++++++ package.json | 1 + packages/fether-electron/mb.js | 22 ++++++++++-------- packages/fether-electron/package.json | 3 ++- .../src/assets/img/logos/parity-icon.png | Bin 0 -> 2859 bytes .../src/assets/img/logos/parity-icon@2x.png | Bin 0 -> 5742 bytes 6 files changed, 31 insertions(+), 11 deletions(-) create mode 100644 packages/fether-react/src/assets/img/logos/parity-icon.png create mode 100644 packages/fether-react/src/assets/img/logos/parity-icon@2x.png diff --git a/README.md b/README.md index 10a4c85c2..b1036a98c 100644 --- a/README.md +++ b/README.md @@ -115,6 +115,22 @@ yarn start > Troubleshooting: If it hangs on a white screen in Electron even though it has compiled and has been syncing for a long time, then simply choose 'View > Reload' (CMD + R on macOS) from the Electron menu +### Run as a taskbar app + +Separately launch Parity Ethereum node with the following flags: + +```bash +$ parity --chain kovan --light --ws-origins=file://* +``` + +In another console launch Fether: + +```bash +# Fether will connect to the running node +$ cd /path/to/fether +$ yarn taskbar +``` + ## Join the chat! Get in touch with us on Gitter: diff --git a/package.json b/package.json index daad3b278..4b81c4f67 100644 --- a/package.json +++ b/package.json @@ -52,6 +52,7 @@ "start-electron": "cd packages/fether-electron && yarn start", "start-react": "cd packages/fether-react && yarn start", "start-ui": "cd packages/fether-ui && yarn start", + "taskbar": "cd packages/fether-electron && yarn taskbar", "test": "semistandard '**/*.{js,ts}' --parser babel-eslint && CI=true lerna run test --parallel" }, "husky": { diff --git a/packages/fether-electron/mb.js b/packages/fether-electron/mb.js index a335c5222..a03682b43 100644 --- a/packages/fether-electron/mb.js +++ b/packages/fether-electron/mb.js @@ -1,24 +1,26 @@ const path = require('path'); const menubar = require('menubar'); -const indexDir = 'file://' + path.join(__dirname, '/static/build/index.html'); -// const indexDir = 'file://' + path.join(__dirname, '/mb.html'); // testing only -console.log(indexDir); +const packagesDir = __dirname.substring(0, __dirname.lastIndexOf('/')); +const indexHtmlFile = + 'file://' + path.join(__dirname, '/static/build/index.html'); +const iconFile = path.join( + packagesDir, + '/fether-react/src/assets/img/logos/parity-icon.png' +); const mb = menubar({ dir: __dirname, - index: indexDir, + index: indexHtmlFile, showDockIcon: true, - tooltip: 'Fether' + icon: iconFile, + tooltip: 'Fether', + width: 352, + height: 464 }); mb.on('ready', () => { console.log('Fether is ready'); - // your app code here mb.showWindow(); }); - -// mb.on('after-create-window', () => { -// mb.window.openDevTools(); -// }); diff --git a/packages/fether-electron/package.json b/packages/fether-electron/package.json index 1af8d7afe..6f7f8450e 100644 --- a/packages/fether-electron/package.json +++ b/packages/fether-electron/package.json @@ -30,12 +30,13 @@ "scripts": { "prebuild": "copyfiles -u 2 \"../fether-react/build/**/*\" static/ && ./scripts/fixElectronBug.sh", "build": "electron-webpack", - "electron": "cross-env SKIP_PREFLIGHT_CHECK=true electron mb.js", + "electron": "cross-env SKIP_PREFLIGHT_CHECK=true electron dist/main/main.js", "prepackage": "./scripts/revertElectronBug.sh", "package": "electron-builder", "prerelease": "./scripts/revertElectronBug.sh", "release": "electron-builder", "start": "cross-env ELECTRON_START_URL=http://localhost:3000 electron-webpack dev --ws-origins all", + "taskbar": "cross-env SKIP_PREFLIGHT_CHECK=true electron mb.js", "test": "echo Skipped." }, "dependencies": { diff --git a/packages/fether-react/src/assets/img/logos/parity-icon.png b/packages/fether-react/src/assets/img/logos/parity-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..f6bcd0526a3594b9574d3ef24583dd602b914317 GIT binary patch literal 2859 zcmcgueNYtV9bRHI77@8>>cvoVELKt3yWRWV8_!d35ilMC-YF7^?(GL$kGs9z-oc^9 zQezx2P}>#-XGgF)F6i&m2#gaun9UyQp9#Z0ScD+?SO!am zARfCOUK$Q4$ugx&jGUX1sHAFy!jz~)gG(_rs#IZ#5;=-#WT;Apsu2{^p<10BlZ+fN zh~}nQT_&-7Bo=tm!+9Q$ODB^R78Xhi6;jTfE5mRcm!Wc*T#f()!WTI`qz`fO@uLg` z!&7dX%VXo5k}xA_<-8s}3^E;-;Bbx6I{A?@fr80=q)UcL(XgZ;AWeZV(8HiYQk#v|$>l7D%N1$_r&tZ5RH916N&(pljSAB;S}Trfl%w+rj`D_m z5S~B0BxsHT9REp=RB3RUr6`1?XbjP?N(>=2G=)&KN^4bGQH;Xnqin0(Hn1wm{Kr|t zSN*PS*cO|8jm_bX2hQMwgz8(9_fQPXU72^cOa)Zy% zk_B^Q5H#W2RAQ-FTV7sa;$o9xb~LmK^||bkuYB>4 zDNYF;CQ4_-V9T+4cEd;A-Bs7G1wQ}rD{(PL7q)dJ?^ zL(R>vrq!=z*muu9GVE(A=)wzkRn5%lI=R!I&Ytbe`{4J&yaTVcy~Fva zck>0XeCg52(A-)xY(<0TnjMCP9XCs{xxf4@ohUB3F6sv(n{Rxkvx7bz0(F0UjX-Rb3-6&}B_I*8ra9=DzESvm!O$QeA zC+z(A?pDQi*OrJT2qJDjuP~U;q!9Jc+i$;zUtfK=?V+=n!R?RkNr_Dhj>ztEM~gqN@6eUgCq<)RsMb z;9AS|3GMP=-sZNRlQ(=d4T8Mjy{y>1H8okpA1X2vcKT)T^uE6XrN{rg@n0Wx_5brl zYQG@N>lqAXZ(bA|y*JLE+gr{bYhw>bXPRLiHGZ_bIH^m_k?hYmg0arIPM{pr%X zk0Rlgic>;jhhyO3*Wxe!;nF@JEJ>E>qKh+r`+l=yI=lcDgv?OYPQUovr=J?nUAnYe z!}a7HxpXP{=zd{s(wrSJTYu)a$89%M;-b!dwzv02Y`jvl@c6;}8on|!JKmoFU#d>t zH9N<77^}-|Y_m6dEfy11b|G&23!?5of6$xr?K_z*(a=JuGRuCbcdv;FOqUw_$^P#JS17fIMu2^p-HXdI8Nq2Ym zYJ20R0mp^r7oZekryvA24QwbmHZ55B;1NF&dY5>1rZ*G;Z@arVDBh5``{fn$Gcsn_ zh2uG0uQdoq9=?84`k8pb%!$y4m4Dr`*zii@ngdc<+Pi&cXXr(5nRl`5WB9 Q@ZZ_gq%-_Vv7O;8u^FEi~`+F{% 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 literal 0 HcmV?d00001 From c5aa7d73af7476996b93096ab9e7231e303b1b47 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Fri, 4 Jan 2019 15:31:57 +1100 Subject: [PATCH 003/153] refactor: Remove temporary hello world file --- packages/fether-electron/mb.html | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 packages/fether-electron/mb.html diff --git a/packages/fether-electron/mb.html b/packages/fether-electron/mb.html deleted file mode 100644 index 82dae7135..000000000 --- a/packages/fether-electron/mb.html +++ /dev/null @@ -1,6 +0,0 @@ - - - - Hello World - - \ No newline at end of file From 730fd8744ee548a1708ad5270f114ea7a60664f4 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Fri, 4 Jan 2019 15:40:59 +1100 Subject: [PATCH 004/153] docs: Update Readme to include building before running --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b1036a98c..b983a29c7 100644 --- a/README.md +++ b/README.md @@ -128,7 +128,7 @@ In another console launch Fether: ```bash # Fether will connect to the running node $ cd /path/to/fether -$ yarn taskbar +$ yarn; yarn build; yarn taskbar ``` ## Join the chat! From 02b0d954944e6123b5cf42423afe2a1f29a8df73 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Fri, 4 Jan 2019 15:43:54 +1100 Subject: [PATCH 005/153] docs: Move onto separate line --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index b983a29c7..742fe2680 100644 --- a/README.md +++ b/README.md @@ -128,7 +128,8 @@ In another console launch Fether: ```bash # Fether will connect to the running node $ cd /path/to/fether -$ yarn; yarn build; yarn taskbar +$ yarn; yarn build +$ yarn taskbar ``` ## Join the chat! From b2a4092c5b9470209e9ee677482d90cc0269ad07 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Sat, 5 Jan 2019 17:08:38 +1100 Subject: [PATCH 006/153] fix: Update Onboarding component and make Terms & Conditions consistent on taskbar app * Note: To quickly see the changes force the Onboarding component (displaying Terms & Conditions screen) to appear by changing `if (isFirstRun) {` to `if (true) {` in `fether-react/src/App/App.js. The screen should be consistent when you run `yarn taskbar` and `yarn start` * Terms & Conditions updates for consistency and compatibility with taskbar app * Add extra side padding `-padded-extra` to Terms & Conditions so consistent with rest of site and in taskbar app * Wrap with `.terms-and-conditions-wrapper` to add box shadow around both the 'Please read carefully' label and associated Terms & Conditions * Adjust height of `.terms-and-conditions` down to 16rem otherwise with more side padding it causes overflow to occur with vertical scrollbar appearing (checked that it works on both taskbar app i.e. `yarn taskbar` and normal app `yarn electron` or `yarn start`) * Hide `overflow-x` in Terms and Conditions as caused horizontal scroll on taskbar app * Add top margin to Terms and Conditions so extra gap from its 'Please read carefully' label * Only left padding in Terms and Conditions --- .../fether-react/src/Onboarding/Onboarding.js | 18 ++++++++++-------- .../sass/components/_terms-and-conditions.scss | 12 ++++++++++-- .../src/assets/sass/shared/_box.scss | 4 ++++ 3 files changed, 24 insertions(+), 10 deletions(-) diff --git a/packages/fether-react/src/Onboarding/Onboarding.js b/packages/fether-react/src/Onboarding/Onboarding.js index e81800564..4ca715f03 100644 --- a/packages/fether-react/src/Onboarding/Onboarding.js +++ b/packages/fether-react/src/Onboarding/Onboarding.js @@ -53,14 +53,16 @@ class Onboarding extends Component {
Terms of Use} />
-
- +
+
+ +
diff --git a/packages/fether-react/src/assets/sass/components/_terms-and-conditions.scss b/packages/fether-react/src/assets/sass/components/_terms-and-conditions.scss index 058ef9d8d..ef3661ca1 100644 --- a/packages/fether-react/src/assets/sass/components/_terms-and-conditions.scss +++ b/packages/fether-react/src/assets/sass/components/_terms-and-conditions.scss @@ -1,7 +1,14 @@ +.terms-and-conditions-wrapper { + border-radius: 0.25rem; + box-shadow: 0 0.125rem 0.5rem rgba($black, 0.125); +} + .terms-and-conditions { - height: 20rem; + height: 16rem; /* Different impact on taskbar app */ + overflow-x: hidden; overflow-y: auto; - padding: 0.5rem; + margin-top: 0.75rem; + padding-left: 0.5rem; * { user-select: text; @@ -11,6 +18,7 @@ li { margin-bottom: 0.5rem; margin-top: 0.5rem; + padding-right: 0.5rem; } ul, diff --git a/packages/fether-react/src/assets/sass/shared/_box.scss b/packages/fether-react/src/assets/sass/shared/_box.scss index b069b4a5a..68ce14fc1 100644 --- a/packages/fether-react/src/assets/sass/shared/_box.scss +++ b/packages/fether-react/src/assets/sass/shared/_box.scss @@ -43,6 +43,10 @@ padding: 0.5rem; } + &.-padded-extra { + padding: 0.75rem; + } + &.-apart { margin-top: 1rem; margin-bottom: 1rem; From 64f65f47e6ee93e4cdbd43a485eab56a971f175b Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Sat, 5 Jan 2019 17:10:57 +1100 Subject: [PATCH 007/153] fix: Add white background body element so Onboarding background consistent in taskbar app * Note: To quickly see the changes force the Onboarding component (displaying Terms & Conditions screen) to appear by changing `if (isFirstRun) {` to `if (true) {` in `fether-react/src/App/App.js. The screen should be consistent when you run `yarn taskbar` and `yarn start` * Add eggshell background colour to `body` element otherwise `yarn taskbar` app has grey background (even though running as normal `yarn start` or `yarn electron` app has white background from manifest) --- packages/fether-react/src/assets/sass/shared/_basics.scss | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/fether-react/src/assets/sass/shared/_basics.scss b/packages/fether-react/src/assets/sass/shared/_basics.scss index e70205079..d036949f3 100644 --- a/packages/fether-react/src/assets/sass/shared/_basics.scss +++ b/packages/fether-react/src/assets/sass/shared/_basics.scss @@ -3,6 +3,10 @@ html { } body { + /* Running taskbar app requires $eggshell background colour otherwise + * Onboarding component screen is shown with grey background + */ + background-color: $eggshell; user-select: none; color: $black; font-family: $sans; From c204424065f0b403e604d75beed657d5b9714df1 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Sun, 6 Jan 2019 15:09:45 +1100 Subject: [PATCH 008/153] feat: Change mainWindow file extension to TypeScript file --- packages/fether-electron/src/main/{index.js => index.ts} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename packages/fether-electron/src/main/{index.js => index.ts} (100%) diff --git a/packages/fether-electron/src/main/index.js b/packages/fether-electron/src/main/index.ts similarity index 100% rename from packages/fether-electron/src/main/index.js rename to packages/fether-electron/src/main/index.ts From ff1a7e53db816c35f74d8f2ae8b1cfeee3eb5387 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Sun, 6 Jan 2019 15:14:07 +1100 Subject: [PATCH 009/153] feat: Create FetherWindow class --- packages/fether-electron/src/main/index.ts | 279 ++++++++++--------- packages/fether-electron/src/main/types.d.ts | 8 + 2 files changed, 158 insertions(+), 129 deletions(-) create mode 100644 packages/fether-electron/src/main/types.d.ts diff --git a/packages/fether-electron/src/main/index.ts b/packages/fether-electron/src/main/index.ts index dd9768115..4a59cec21 100644 --- a/packages/fether-electron/src/main/index.ts +++ b/packages/fether-electron/src/main/index.ts @@ -3,166 +3,187 @@ // // SPDX-License-Identifier: BSD-3-Clause +import { FetherWindowInstance } from "./types"; + import parityElectron, { getParityPath, fetchParity, isParityRunning, runParity, killParity -} from '@parity/electron'; -import electron from 'electron'; -import getRemainingArgs from 'commander-remaining-args'; -import path from 'path'; -import url from 'url'; - -import addMenu from './menu'; -import cli from './cli'; -import handleError from './utils/handleError'; -import messages from './messages'; -import { parity } from '../../package.json'; -import Pino from './utils/pino'; -import { productName } from '../../electron-builder.json'; -import staticPath from './utils/staticPath'; +} from "@parity/electron"; +import electron from "electron"; +import getRemainingArgs from "commander-remaining-args"; +import path from "path"; +import url from "url"; + +import addMenu from "./menu"; +import cli from "./cli"; +import handleError from "./utils/handleError"; +import messages from "./messages"; +import { parity } from "../../package.json"; +import Pino from "./utils/pino"; +import { productName } from "../../electron-builder.json"; +import staticPath from "./utils/staticPath"; const { app, BrowserWindow, ipcMain, session } = electron; -let mainWindow; const pino = Pino(); // Disable gpu acceleration on linux // https://github.com/parity-js/fether/issues/85 -if (!['darwin', 'win32'].includes(process.platform)) { +if (!["darwin", "win32"].includes(process.platform)) { app.disableHardwareAcceleration(); } -function createWindow () { - pino.info(`Starting ${productName}...`); - mainWindow = new BrowserWindow({ - height: 640, - resizable: false, - width: 360 - }); - - // Set options for @parity/electron - parityElectron({ - logger: namespace => log => Pino({ name: namespace }).info(log) - }); - - // Look if Parity is installed - getParityPath() - .catch(() => - // Install parity if not present - fetchParity(mainWindow, { - onProgress: progress => - // Notify the renderers on download progress - mainWindow.webContents.send('parity-download-progress', progress), - parityChannel: parity.channel - }) - ) - .then(async () => { - // Run parity when installed +let hasCalledInitFetherWindow = false; - // Don't run parity if the user ran fether with --no-run-parity - if (!cli.runParity) { - return; - } +class FetherWindow implements FetherWindowInstance { + private fetherWindow; - if ( - await isParityRunning({ - wsInterface: cli.wsInterface, - wsPort: cli.wsPort - }) - ) { - return; - } + create(): void { + if (hasCalledInitFetherWindow) { + throw new Error("Unable to initialise Fether window more than once"); + } - return runParity({ - flags: [ - ...getRemainingArgs(cli), - '--light', - '--chain', - cli.chain, - '--ws-interface', - cli.wsInterface, - '--ws-port', - cli.wsPort - ], - onParityError: err => handleError(err, 'An error occured with Parity.') - }); - }) - .then(() => { - // Notify the renderers - mainWindow.webContents.send('parity-running', true); - global.isParityRunning = true; // Send this variable to renderes via IPC - }) - .catch(handleError); - - // Globals for fether-react parityStore - global.wsInterface = cli.wsInterface; - global.wsPort = cli.wsPort; - - // Opens file:///path/to/build/index.html in prod mode, or whatever is - // passed to ELECTRON_START_URL - mainWindow.loadURL( - process.env.ELECTRON_START_URL || - url.format({ - pathname: path.join(staticPath, 'build', 'index.html'), - protocol: 'file:', - slashes: true + pino.info(`Starting ${productName}...`); + this.fetherWindow = new BrowserWindow({ + height: 640, + resizable: false, + width: 360 + }); + + // Set options for @parity/electron + parityElectron({ + logger: namespace => log => Pino({ name: namespace }).info(log) + }); + + // Look if Parity is installed + getParityPath() + .catch(() => + // Install parity if not present + fetchParity(this.fetherWindow, { + onProgress: progress => + // Notify the renderers on download progress + this.fetherWindow.webContents.send( + "parity-download-progress", + progress + ), + parityChannel: parity.channel + }) + ) + .then(async () => { + // Run parity when installed + + // Don't run parity if the user ran fether with --no-run-parity + if (!cli.runParity) { + return; + } + + if ( + await isParityRunning({ + wsInterface: cli.wsInterface, + wsPort: cli.wsPort + }) + ) { + return; + } + + return runParity({ + flags: [ + ...getRemainingArgs(cli), + "--light", + "--chain", + cli.chain, + "--ws-interface", + cli.wsInterface, + "--ws-port", + cli.wsPort + ], + onParityError: err => + handleError(err, "An error occured with Parity.") + }); }) - ); - - // Listen to messages from renderer process - ipcMain.on('asynchronous-message', (...args) => - messages(mainWindow, ...args) - ); - - // Add application menu - addMenu(mainWindow); - - // WS calls have Origin `file://` by default, which is not trusted. - // We override Origin header on all WS connections with an authorized one. - session.defaultSession.webRequest.onBeforeSendHeaders( - { - urls: ['ws://*/*', 'wss://*/*'] - }, - (details, callback) => { - if (!mainWindow) { - // There might be a split second where the user closes the app, so - // mainWindow is null, but there is still a network request done. - return; + .then(() => { + // Notify the renderers + this.fetherWindow.webContents.send("parity-running", true); + global.isParityRunning = true; // Send this variable to renderes via IPC + }) + .catch(handleError); + + // Globals for fether-react parityStore + global.wsInterface = cli.wsInterface; + global.wsPort = cli.wsPort; + + // Opens file:///path/to/build/index.html in prod mode, or whatever is + // passed to ELECTRON_START_URL + this.fetherWindow.loadURL( + process.env.ELECTRON_START_URL || + url.format({ + pathname: path.join(staticPath, "build", "index.html"), + protocol: "file:", + slashes: true + }) + ); + + // Listen to messages from renderer process + ipcMain.on("asynchronous-message", (...args) => + messages(this.fetherWindow, ...args) + ); + + // Add application menu + addMenu(this.fetherWindow); + + // WS calls have Origin `file://` by default, which is not trusted. + // We override Origin header on all WS connections with an authorized one. + session.defaultSession.webRequest.onBeforeSendHeaders( + { + urls: ["ws://*/*", "wss://*/*"] + }, + (details, callback) => { + if (!this.fetherWindow) { + // There might be a split second where the user closes the app, so + // this.fetherWindow is null, but there is still a network request done. + return; + } + details.requestHeaders.Origin = `parity://${ + this.fetherWindow.id + }.ui.parity`; + callback({ requestHeaders: details.requestHeaders }); // eslint-disable-line } - details.requestHeaders.Origin = `parity://${mainWindow.id}.ui.parity`; - callback({ requestHeaders: details.requestHeaders }); // eslint-disable-line - } - ); + ); - // Open external links in browser - mainWindow.webContents.on('new-window', function (event, url) { - event.preventDefault(); - electron.shell.openExternal(url); - }); + // Open external links in browser + this.fetherWindow.webContents.on("new-window", function(event, url) { + event.preventDefault(); + electron.shell.openExternal(url); + }); - mainWindow.on('closed', () => { - mainWindow = null; - }); + this.fetherWindow.on("closed", () => { + this.fetherWindow = null; + }); + } } -app.on('ready', createWindow); +const fetherWindowInstance = new FetherWindow(); + +fetherWindowInstance.create(); + +app.on("ready", fetherWindowInstance.create); -app.on('window-all-closed', () => { - if (process.platform !== 'darwin') { +app.on("window-all-closed", () => { + if (process.platform !== "darwin") { killParity(); app.quit(); } }); // Make sure parity stops when UI stops -app.on('before-quit', killParity); -app.on('will-quit', killParity); -app.on('quit', killParity); +app.on("before-quit", killParity); +app.on("will-quit", killParity); +app.on("quit", killParity); -app.on('activate', () => { - if (mainWindow === null) { - createWindow(); +app.on("activate", () => { + if (this.fetherWindow === null) { + fetherWindowInstance.create(); } }); diff --git a/packages/fether-electron/src/main/types.d.ts b/packages/fether-electron/src/main/types.d.ts new file mode 100644 index 000000000..8a31cdd98 --- /dev/null +++ b/packages/fether-electron/src/main/types.d.ts @@ -0,0 +1,8 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. +// +// SPDX-License-Identifier: BSD-3-Clause + +export interface FetherWindowInstance { + create: (fetherWindow) => void; +} From 3a1c9d75c173517b74b8cb7cca17a50555410e05 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Sun, 6 Jan 2019 16:18:41 +1100 Subject: [PATCH 010/153] refactor: Move FetherWindow component into module folder. Fix its type --- .../src/main/fetherWindow/index.ts | 160 ++++++++++++++++ .../src/main/{ => fetherWindow}/types.d.ts | 2 +- packages/fether-electron/src/main/index.ts | 172 ++---------------- 3 files changed, 173 insertions(+), 161 deletions(-) create mode 100644 packages/fether-electron/src/main/fetherWindow/index.ts rename packages/fether-electron/src/main/{ => fetherWindow}/types.d.ts (83%) diff --git a/packages/fether-electron/src/main/fetherWindow/index.ts b/packages/fether-electron/src/main/fetherWindow/index.ts new file mode 100644 index 000000000..97b7f7a16 --- /dev/null +++ b/packages/fether-electron/src/main/fetherWindow/index.ts @@ -0,0 +1,160 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. +// +// SPDX-License-Identifier: BSD-3-Clause + +import { FetherWindowInstance } from "./types"; + +import parityElectron, { + getParityPath, + fetchParity, + isParityRunning, + runParity +} from "@parity/electron"; +import electron from "electron"; +import getRemainingArgs from "commander-remaining-args"; +import path from "path"; +import url from "url"; + +import { parity } from "../../../package.json"; +import { productName } from "../../../electron-builder.json"; +import handleError from "../utils/handleError"; +import staticPath from "../utils/staticPath"; +import Pino from "../utils/pino"; +import addMenu from "../menu"; +import cli from "../cli"; +import messages from "../messages"; + +const { BrowserWindow, ipcMain, session } = electron; +const pino = Pino(); + +let hasCalledInitFetherWindow = false; + +class FetherWindow implements FetherWindowInstance { + private fetherWindow; + + create(): void { + if (hasCalledInitFetherWindow) { + throw new Error("Unable to initialise Fether window more than once"); + } + + pino.info(`Starting ${productName}...`); + this.fetherWindow = new BrowserWindow({ + height: 640, + resizable: false, + width: 360 + }); + + // Set options for @parity/electron + parityElectron({ + logger: namespace => log => Pino({ name: namespace }).info(log) + }); + + // Look if Parity is installed + getParityPath() + .catch(() => + // Install parity if not present + fetchParity(this.fetherWindow, { + onProgress: progress => + // Notify the renderers on download progress + this.fetherWindow.webContents.send( + "parity-download-progress", + progress + ), + parityChannel: parity.channel + }) + ) + .then(async () => { + // Run parity when installed + + // Don't run parity if the user ran fether with --no-run-parity + if (!cli.runParity) { + return; + } + + if ( + await isParityRunning({ + wsInterface: cli.wsInterface, + wsPort: cli.wsPort + }) + ) { + return; + } + + return runParity({ + flags: [ + ...getRemainingArgs(cli), + "--light", + "--chain", + cli.chain, + "--ws-interface", + cli.wsInterface, + "--ws-port", + cli.wsPort + ], + onParityError: err => + handleError(err, "An error occured with Parity.") + }); + }) + .then(() => { + // Notify the renderers + this.fetherWindow.webContents.send("parity-running", true); + global.isParityRunning = true; // Send this variable to renderes via IPC + }) + .catch(handleError); + + // Globals for fether-react parityStore + global.wsInterface = cli.wsInterface; + global.wsPort = cli.wsPort; + + // Opens file:///path/to/build/index.html in prod mode, or whatever is + // passed to ELECTRON_START_URL + this.fetherWindow.loadURL( + process.env.ELECTRON_START_URL || + url.format({ + pathname: path.join(staticPath, "build", "index.html"), + protocol: "file:", + slashes: true + }) + ); + + // Listen to messages from renderer process + ipcMain.on("asynchronous-message", (...args) => + messages(this.fetherWindow, ...args) + ); + + // Add application menu + addMenu(this.fetherWindow); + + // WS calls have Origin `file://` by default, which is not trusted. + // We override Origin header on all WS connections with an authorized one. + session.defaultSession.webRequest.onBeforeSendHeaders( + { + urls: ["ws://*/*", "wss://*/*"] + }, + (details, callback) => { + if (!this.fetherWindow) { + // There might be a split second where the user closes the app, so + // this.fetherWindow is null, but there is still a network request done. + return; + } + details.requestHeaders.Origin = `parity://${ + this.fetherWindow.id + }.ui.parity`; + callback({ requestHeaders: details.requestHeaders }); // eslint-disable-line + } + ); + + // Open external links in browser + this.fetherWindow.webContents.on("new-window", function(event, url) { + event.preventDefault(); + electron.shell.openExternal(url); + }); + + this.fetherWindow.on("closed", () => { + this.fetherWindow = null; + }); + } +} + +export default FetherWindow; diff --git a/packages/fether-electron/src/main/types.d.ts b/packages/fether-electron/src/main/fetherWindow/types.d.ts similarity index 83% rename from packages/fether-electron/src/main/types.d.ts rename to packages/fether-electron/src/main/fetherWindow/types.d.ts index 8a31cdd98..81708f818 100644 --- a/packages/fether-electron/src/main/types.d.ts +++ b/packages/fether-electron/src/main/fetherWindow/types.d.ts @@ -4,5 +4,5 @@ // SPDX-License-Identifier: BSD-3-Clause export interface FetherWindowInstance { - create: (fetherWindow) => void; + create: () => void; } diff --git a/packages/fether-electron/src/main/index.ts b/packages/fether-electron/src/main/index.ts index 4a59cec21..09c141d9c 100644 --- a/packages/fether-electron/src/main/index.ts +++ b/packages/fether-electron/src/main/index.ts @@ -3,186 +3,38 @@ // // SPDX-License-Identifier: BSD-3-Clause -import { FetherWindowInstance } from "./types"; +import { killParity } from '@parity/electron'; +import electron from 'electron'; -import parityElectron, { - getParityPath, - fetchParity, - isParityRunning, - runParity, - killParity -} from "@parity/electron"; -import electron from "electron"; -import getRemainingArgs from "commander-remaining-args"; -import path from "path"; -import url from "url"; +import FetherWindow from './fetherWindow'; -import addMenu from "./menu"; -import cli from "./cli"; -import handleError from "./utils/handleError"; -import messages from "./messages"; -import { parity } from "../../package.json"; -import Pino from "./utils/pino"; -import { productName } from "../../electron-builder.json"; -import staticPath from "./utils/staticPath"; - -const { app, BrowserWindow, ipcMain, session } = electron; -const pino = Pino(); +const { app } = electron; // Disable gpu acceleration on linux // https://github.com/parity-js/fether/issues/85 -if (!["darwin", "win32"].includes(process.platform)) { +if (!['darwin', 'win32'].includes(process.platform)) { app.disableHardwareAcceleration(); } -let hasCalledInitFetherWindow = false; - -class FetherWindow implements FetherWindowInstance { - private fetherWindow; - - create(): void { - if (hasCalledInitFetherWindow) { - throw new Error("Unable to initialise Fether window more than once"); - } - - pino.info(`Starting ${productName}...`); - this.fetherWindow = new BrowserWindow({ - height: 640, - resizable: false, - width: 360 - }); - - // Set options for @parity/electron - parityElectron({ - logger: namespace => log => Pino({ name: namespace }).info(log) - }); - - // Look if Parity is installed - getParityPath() - .catch(() => - // Install parity if not present - fetchParity(this.fetherWindow, { - onProgress: progress => - // Notify the renderers on download progress - this.fetherWindow.webContents.send( - "parity-download-progress", - progress - ), - parityChannel: parity.channel - }) - ) - .then(async () => { - // Run parity when installed - - // Don't run parity if the user ran fether with --no-run-parity - if (!cli.runParity) { - return; - } - - if ( - await isParityRunning({ - wsInterface: cli.wsInterface, - wsPort: cli.wsPort - }) - ) { - return; - } - - return runParity({ - flags: [ - ...getRemainingArgs(cli), - "--light", - "--chain", - cli.chain, - "--ws-interface", - cli.wsInterface, - "--ws-port", - cli.wsPort - ], - onParityError: err => - handleError(err, "An error occured with Parity.") - }); - }) - .then(() => { - // Notify the renderers - this.fetherWindow.webContents.send("parity-running", true); - global.isParityRunning = true; // Send this variable to renderes via IPC - }) - .catch(handleError); - - // Globals for fether-react parityStore - global.wsInterface = cli.wsInterface; - global.wsPort = cli.wsPort; - - // Opens file:///path/to/build/index.html in prod mode, or whatever is - // passed to ELECTRON_START_URL - this.fetherWindow.loadURL( - process.env.ELECTRON_START_URL || - url.format({ - pathname: path.join(staticPath, "build", "index.html"), - protocol: "file:", - slashes: true - }) - ); - - // Listen to messages from renderer process - ipcMain.on("asynchronous-message", (...args) => - messages(this.fetherWindow, ...args) - ); - - // Add application menu - addMenu(this.fetherWindow); - - // WS calls have Origin `file://` by default, which is not trusted. - // We override Origin header on all WS connections with an authorized one. - session.defaultSession.webRequest.onBeforeSendHeaders( - { - urls: ["ws://*/*", "wss://*/*"] - }, - (details, callback) => { - if (!this.fetherWindow) { - // There might be a split second where the user closes the app, so - // this.fetherWindow is null, but there is still a network request done. - return; - } - details.requestHeaders.Origin = `parity://${ - this.fetherWindow.id - }.ui.parity`; - callback({ requestHeaders: details.requestHeaders }); // eslint-disable-line - } - ); - - // Open external links in browser - this.fetherWindow.webContents.on("new-window", function(event, url) { - event.preventDefault(); - electron.shell.openExternal(url); - }); - - this.fetherWindow.on("closed", () => { - this.fetherWindow = null; - }); - } -} - const fetherWindowInstance = new FetherWindow(); fetherWindowInstance.create(); -app.on("ready", fetherWindowInstance.create); +app.on('ready', fetherWindowInstance.create); -app.on("window-all-closed", () => { - if (process.platform !== "darwin") { +app.on('window-all-closed', () => { + if (process.platform !== 'darwin') { killParity(); app.quit(); } }); // Make sure parity stops when UI stops -app.on("before-quit", killParity); -app.on("will-quit", killParity); -app.on("quit", killParity); +app.on('before-quit', killParity); +app.on('will-quit', killParity); +app.on('quit', killParity); -app.on("activate", () => { +app.on('activate', () => { if (this.fetherWindow === null) { fetherWindowInstance.create(); } From c703da0551aa712cbb1828ecde6f9c3837ce9714 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Sun, 6 Jan 2019 16:22:40 +1100 Subject: [PATCH 011/153] refactor: Rename fetherWindow to app --- .../fether-electron/src/main/{fetherWindow => app}/index.ts | 0 .../fether-electron/src/main/{fetherWindow => app}/types.d.ts | 0 packages/fether-electron/src/main/index.ts | 2 +- 3 files changed, 1 insertion(+), 1 deletion(-) rename packages/fether-electron/src/main/{fetherWindow => app}/index.ts (100%) rename packages/fether-electron/src/main/{fetherWindow => app}/types.d.ts (100%) diff --git a/packages/fether-electron/src/main/fetherWindow/index.ts b/packages/fether-electron/src/main/app/index.ts similarity index 100% rename from packages/fether-electron/src/main/fetherWindow/index.ts rename to packages/fether-electron/src/main/app/index.ts diff --git a/packages/fether-electron/src/main/fetherWindow/types.d.ts b/packages/fether-electron/src/main/app/types.d.ts similarity index 100% rename from packages/fether-electron/src/main/fetherWindow/types.d.ts rename to packages/fether-electron/src/main/app/types.d.ts diff --git a/packages/fether-electron/src/main/index.ts b/packages/fether-electron/src/main/index.ts index 09c141d9c..607c4eb6b 100644 --- a/packages/fether-electron/src/main/index.ts +++ b/packages/fether-electron/src/main/index.ts @@ -6,7 +6,7 @@ import { killParity } from '@parity/electron'; import electron from 'electron'; -import FetherWindow from './fetherWindow'; +import FetherWindow from './app'; const { app } = electron; From 7e91f7082c10f1e40d0174c0f279019dd12c40dd Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Sun, 6 Jan 2019 16:48:29 +1100 Subject: [PATCH 012/153] refactor: Rename FetherWindow to FetherApp. fetherApp var stores window --- .../fether-electron/src/main/app/index.ts | 90 +++++++++---------- .../fether-electron/src/main/app/types.d.ts | 2 +- packages/fether-electron/src/main/index.ts | 14 +-- 3 files changed, 53 insertions(+), 53 deletions(-) diff --git a/packages/fether-electron/src/main/app/index.ts b/packages/fether-electron/src/main/app/index.ts index 97b7f7a16..69b3848ca 100644 --- a/packages/fether-electron/src/main/app/index.ts +++ b/packages/fether-electron/src/main/app/index.ts @@ -3,43 +3,43 @@ // // SPDX-License-Identifier: BSD-3-Clause -import { FetherWindowInstance } from "./types"; +import { FetherAppInstance } from './types'; import parityElectron, { getParityPath, fetchParity, isParityRunning, runParity -} from "@parity/electron"; -import electron from "electron"; -import getRemainingArgs from "commander-remaining-args"; -import path from "path"; -import url from "url"; - -import { parity } from "../../../package.json"; -import { productName } from "../../../electron-builder.json"; -import handleError from "../utils/handleError"; -import staticPath from "../utils/staticPath"; -import Pino from "../utils/pino"; -import addMenu from "../menu"; -import cli from "../cli"; -import messages from "../messages"; +} from '@parity/electron'; +import electron from 'electron'; +import getRemainingArgs from 'commander-remaining-args'; +import path from 'path'; +import url from 'url'; + +import { parity } from '../../../package.json'; +import { productName } from '../../../electron-builder.json'; +import handleError from '../utils/handleError'; +import staticPath from '../utils/staticPath'; +import Pino from '../utils/pino'; +import addMenu from '../menu'; +import cli from '../cli'; +import messages from '../messages'; const { BrowserWindow, ipcMain, session } = electron; const pino = Pino(); -let hasCalledInitFetherWindow = false; +let hasCalledInitFetherApp = false; -class FetherWindow implements FetherWindowInstance { - private fetherWindow; +class FetherApp implements FetherAppInstance { + fetherApp; - create(): void { - if (hasCalledInitFetherWindow) { - throw new Error("Unable to initialise Fether window more than once"); + create (): void { + if (hasCalledInitFetherApp) { + throw new Error('Unable to initialise Fether window more than once'); } pino.info(`Starting ${productName}...`); - this.fetherWindow = new BrowserWindow({ + this.fetherApp.window = new BrowserWindow({ height: 640, resizable: false, width: 360 @@ -54,11 +54,11 @@ class FetherWindow implements FetherWindowInstance { getParityPath() .catch(() => // Install parity if not present - fetchParity(this.fetherWindow, { + fetchParity(this.fetherApp.window, { onProgress: progress => // Notify the renderers on download progress - this.fetherWindow.webContents.send( - "parity-download-progress", + this.fetherApp.window.webContents.send( + 'parity-download-progress', progress ), parityChannel: parity.channel @@ -84,21 +84,21 @@ class FetherWindow implements FetherWindowInstance { return runParity({ flags: [ ...getRemainingArgs(cli), - "--light", - "--chain", + '--light', + '--chain', cli.chain, - "--ws-interface", + '--ws-interface', cli.wsInterface, - "--ws-port", + '--ws-port', cli.wsPort ], onParityError: err => - handleError(err, "An error occured with Parity.") + handleError(err, 'An error occured with Parity.') }); }) .then(() => { // Notify the renderers - this.fetherWindow.webContents.send("parity-running", true); + this.fetherApp.window.webContents.send('parity-running', true); global.isParityRunning = true; // Send this variable to renderes via IPC }) .catch(handleError); @@ -109,52 +109,52 @@ class FetherWindow implements FetherWindowInstance { // Opens file:///path/to/build/index.html in prod mode, or whatever is // passed to ELECTRON_START_URL - this.fetherWindow.loadURL( + this.fetherApp.window.loadURL( process.env.ELECTRON_START_URL || url.format({ - pathname: path.join(staticPath, "build", "index.html"), - protocol: "file:", + pathname: path.join(staticPath, 'build', 'index.html'), + protocol: 'file:', slashes: true }) ); // Listen to messages from renderer process - ipcMain.on("asynchronous-message", (...args) => - messages(this.fetherWindow, ...args) + ipcMain.on('asynchronous-message', (...args) => + messages(this.fetherApp.window, ...args) ); // Add application menu - addMenu(this.fetherWindow); + addMenu(this.fetherApp.window); // WS calls have Origin `file://` by default, which is not trusted. // We override Origin header on all WS connections with an authorized one. session.defaultSession.webRequest.onBeforeSendHeaders( { - urls: ["ws://*/*", "wss://*/*"] + urls: ['ws://*/*', 'wss://*/*'] }, (details, callback) => { - if (!this.fetherWindow) { + if (!this.fetherApp.window) { // There might be a split second where the user closes the app, so - // this.fetherWindow is null, but there is still a network request done. + // this.fetherApp.window is null, but there is still a network request done. return; } details.requestHeaders.Origin = `parity://${ - this.fetherWindow.id + this.fetherApp.window.id }.ui.parity`; callback({ requestHeaders: details.requestHeaders }); // eslint-disable-line } ); // Open external links in browser - this.fetherWindow.webContents.on("new-window", function(event, url) { + this.fetherApp.window.webContents.on('new-window', function (event, url) { event.preventDefault(); electron.shell.openExternal(url); }); - this.fetherWindow.on("closed", () => { - this.fetherWindow = null; + this.fetherApp.window.on('closed', () => { + this.fetherApp.window = null; }); } } -export default FetherWindow; +export default FetherApp; diff --git a/packages/fether-electron/src/main/app/types.d.ts b/packages/fether-electron/src/main/app/types.d.ts index 81708f818..dd991c75e 100644 --- a/packages/fether-electron/src/main/app/types.d.ts +++ b/packages/fether-electron/src/main/app/types.d.ts @@ -3,6 +3,6 @@ // // SPDX-License-Identifier: BSD-3-Clause -export interface FetherWindowInstance { +export interface FetherAppInstance { create: () => void; } diff --git a/packages/fether-electron/src/main/index.ts b/packages/fether-electron/src/main/index.ts index 607c4eb6b..9413ea945 100644 --- a/packages/fether-electron/src/main/index.ts +++ b/packages/fether-electron/src/main/index.ts @@ -6,7 +6,7 @@ import { killParity } from '@parity/electron'; import electron from 'electron'; -import FetherWindow from './app'; +import FetherApp from './app'; const { app } = electron; @@ -16,11 +16,11 @@ if (!['darwin', 'win32'].includes(process.platform)) { app.disableHardwareAcceleration(); } -const fetherWindowInstance = new FetherWindow(); +const fetherAppInstance = new FetherApp(); -fetherWindowInstance.create(); +fetherAppInstance.create(); -app.on('ready', fetherWindowInstance.create); +app.on('ready', fetherAppInstance.create); app.on('window-all-closed', () => { if (process.platform !== 'darwin') { @@ -29,13 +29,13 @@ app.on('window-all-closed', () => { } }); -// Make sure parity stops when UI stops +// Make sure Parity Ethereum stops when UI stops app.on('before-quit', killParity); app.on('will-quit', killParity); app.on('quit', killParity); app.on('activate', () => { - if (this.fetherWindow === null) { - fetherWindowInstance.create(); + if (fetherAppInstance.app.window === null) { + fetherAppInstance.create(); } }); From 60027ca3e17e21d4d84ce087dd88d7f4290879ff Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Sun, 6 Jan 2019 17:37:02 +1100 Subject: [PATCH 013/153] fix: Change back to JS from TS --- .../fether-electron/src/main/app/{index.ts => index.js} | 0 packages/fether-electron/src/main/app/types.d.ts | 8 -------- packages/fether-electron/src/main/{index.ts => index.js} | 0 3 files changed, 8 deletions(-) rename packages/fether-electron/src/main/app/{index.ts => index.js} (100%) delete mode 100644 packages/fether-electron/src/main/app/types.d.ts rename packages/fether-electron/src/main/{index.ts => index.js} (100%) diff --git a/packages/fether-electron/src/main/app/index.ts b/packages/fether-electron/src/main/app/index.js similarity index 100% rename from packages/fether-electron/src/main/app/index.ts rename to packages/fether-electron/src/main/app/index.js diff --git a/packages/fether-electron/src/main/app/types.d.ts b/packages/fether-electron/src/main/app/types.d.ts deleted file mode 100644 index dd991c75e..000000000 --- a/packages/fether-electron/src/main/app/types.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright 2015-2018 Parity Technologies (UK) Ltd. -// This file is part of Parity. -// -// SPDX-License-Identifier: BSD-3-Clause - -export interface FetherAppInstance { - create: () => void; -} diff --git a/packages/fether-electron/src/main/index.ts b/packages/fether-electron/src/main/index.js similarity index 100% rename from packages/fether-electron/src/main/index.ts rename to packages/fether-electron/src/main/index.js From 5abd34a8176e59cf4c4d1c03783cb100633f5ab6 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Sun, 6 Jan 2019 18:42:09 +1100 Subject: [PATCH 014/153] fix: Replace TS with Babel.js in fether-electron * Remove TypeScript types (we're not using TypeScript here!) * Add Babel.js to fether-electron package similar to fether-ui * Change to block `onProgress: progress => {` otherwise it doesn't compile * Use https://babeljs.io/docs/en/next/babel-plugin-proposal-class-properties.html --- packages/fether-electron/babel.config.js | 4 ++++ packages/fether-electron/package.json | 3 +++ .../fether-electron/src/main/app/index.js | 20 +++++++++---------- packages/fether-electron/src/main/index.js | 10 +++++----- 4 files changed, 22 insertions(+), 15 deletions(-) create mode 100644 packages/fether-electron/babel.config.js diff --git a/packages/fether-electron/babel.config.js b/packages/fether-electron/babel.config.js new file mode 100644 index 000000000..f3a623b23 --- /dev/null +++ b/packages/fether-electron/babel.config.js @@ -0,0 +1,4 @@ +module.exports = { + plugins: ['@babel/plugin-proposal-class-properties'], + presets: ['@babel/preset-env'] +}; diff --git a/packages/fether-electron/package.json b/packages/fether-electron/package.json index 6f7f8450e..ea6b2a8a4 100644 --- a/packages/fether-electron/package.json +++ b/packages/fether-electron/package.json @@ -50,6 +50,9 @@ "source-map-support": "^0.5.6" }, "devDependencies": { + "@babel/cli": "^7.0.0-beta.49", + "@babel/core": "^7.0.0-beta.49", + "@babel/preset-env": "^7.0.0-beta.49", "copyfiles": "^2.0.0", "cross-env": "^5.2.0", "electron": "^2.0.2", diff --git a/packages/fether-electron/src/main/app/index.js b/packages/fether-electron/src/main/app/index.js index 69b3848ca..59c9dfcc0 100644 --- a/packages/fether-electron/src/main/app/index.js +++ b/packages/fether-electron/src/main/app/index.js @@ -3,8 +3,6 @@ // // SPDX-License-Identifier: BSD-3-Clause -import { FetherAppInstance } from './types'; - import parityElectron, { getParityPath, fetchParity, @@ -30,12 +28,13 @@ const pino = Pino(); let hasCalledInitFetherApp = false; -class FetherApp implements FetherAppInstance { - fetherApp; +class FetherApp { + fetherApp = {}; - create (): void { + // Bound function that is bound to class instance + create = () => { if (hasCalledInitFetherApp) { - throw new Error('Unable to initialise Fether window more than once'); + throw new Error('Unable to initialise Fether app more than once'); } pino.info(`Starting ${productName}...`); @@ -55,12 +54,13 @@ class FetherApp implements FetherAppInstance { .catch(() => // Install parity if not present fetchParity(this.fetherApp.window, { - onProgress: progress => + onProgress: progress => { // Notify the renderers on download progress - this.fetherApp.window.webContents.send( + return this.fetherApp.window.webContents.send( 'parity-download-progress', progress - ), + ); + }, parityChannel: parity.channel }) ) @@ -154,7 +154,7 @@ class FetherApp implements FetherAppInstance { this.fetherApp.window.on('closed', () => { this.fetherApp.window = null; }); - } + }; } export default FetherApp; diff --git a/packages/fether-electron/src/main/index.js b/packages/fether-electron/src/main/index.js index 9413ea945..3ac895be5 100644 --- a/packages/fether-electron/src/main/index.js +++ b/packages/fether-electron/src/main/index.js @@ -18,9 +18,9 @@ if (!['darwin', 'win32'].includes(process.platform)) { const fetherAppInstance = new FetherApp(); -fetherAppInstance.create(); - -app.on('ready', fetherAppInstance.create); +app.on('ready', () => { + fetherAppInstance.create.call(undefined); +}); app.on('window-all-closed', () => { if (process.platform !== 'darwin') { @@ -35,7 +35,7 @@ app.on('will-quit', killParity); app.on('quit', killParity); app.on('activate', () => { - if (fetherAppInstance.app.window === null) { - fetherAppInstance.create(); + if (fetherAppInstance.fetherApp.window === null) { + fetherAppInstance.create.call(undefined); } }); From a17aaf006da325eaa4057f3d3c6b0be9c2f38c76 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Sun, 6 Jan 2019 19:30:12 +1100 Subject: [PATCH 015/153] refactor: Move FetherApp options into FetherAppOptions class --- packages/fether-electron/package.json | 1 + .../fether-electron/src/main/app/index.js | 9 ++--- .../src/main/app/options/index.js | 34 +++++++++++++++++++ packages/fether-electron/src/main/index.js | 8 +++-- yarn.lock | 2 +- 5 files changed, 44 insertions(+), 10 deletions(-) create mode 100644 packages/fether-electron/src/main/app/options/index.js diff --git a/packages/fether-electron/package.json b/packages/fether-electron/package.json index ea6b2a8a4..a9d996719 100644 --- a/packages/fether-electron/package.json +++ b/packages/fether-electron/package.json @@ -43,6 +43,7 @@ "@parity/electron": "^3.0.1", "commander": "^2.15.1", "commander-remaining-args": "^1.2.0", + "extend": "^3.0.2", "fether-react": "^0.1.2", "menubar": "^5.2.3", "pino": "^4.16.1", diff --git a/packages/fether-electron/src/main/app/index.js b/packages/fether-electron/src/main/app/index.js index 59c9dfcc0..751993c7d 100644 --- a/packages/fether-electron/src/main/app/index.js +++ b/packages/fether-electron/src/main/app/index.js @@ -31,18 +31,13 @@ let hasCalledInitFetherApp = false; class FetherApp { fetherApp = {}; - // Bound function that is bound to class instance - create = () => { + create = options => { if (hasCalledInitFetherApp) { throw new Error('Unable to initialise Fether app more than once'); } pino.info(`Starting ${productName}...`); - this.fetherApp.window = new BrowserWindow({ - height: 640, - resizable: false, - width: 360 - }); + this.fetherApp.window = new BrowserWindow(options); // Set options for @parity/electron parityElectron({ diff --git a/packages/fether-electron/src/main/app/options/index.js b/packages/fether-electron/src/main/app/options/index.js new file mode 100644 index 000000000..bf99e6577 --- /dev/null +++ b/packages/fether-electron/src/main/app/options/index.js @@ -0,0 +1,34 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. +// +// SPDX-License-Identifier: BSD-3-Clause + +import extend from 'extend'; + +const DEFAULT_OPTIONS = { + height: 640, + resizable: false, + width: 360 +}; + +const TASKBAR_OPTIONS = {}; + +let hasCalledInitFetherAppOptions = false; + +class FetherAppOptions { + options = {}; + + create = withTaskbar => { + if (hasCalledInitFetherAppOptions) { + throw new Error('Unable to initialise Fether app options more than once'); + } + + this.options = withTaskbar + ? extend(DEFAULT_OPTIONS, TASKBAR_OPTIONS) + : DEFAULT_OPTIONS; + + return this.options; + }; +} + +export default FetherAppOptions; diff --git a/packages/fether-electron/src/main/index.js b/packages/fether-electron/src/main/index.js index 3ac895be5..433eda3d0 100644 --- a/packages/fether-electron/src/main/index.js +++ b/packages/fether-electron/src/main/index.js @@ -7,6 +7,7 @@ import { killParity } from '@parity/electron'; import electron from 'electron'; import FetherApp from './app'; +import FetherAppOptions from './app/options'; const { app } = electron; @@ -18,8 +19,11 @@ if (!['darwin', 'win32'].includes(process.platform)) { const fetherAppInstance = new FetherApp(); +const fetherAppOptionsInstance = new FetherAppOptions(); +const options = fetherAppOptionsInstance.create(); + app.on('ready', () => { - fetherAppInstance.create.call(undefined); + fetherAppInstance.create(options); }); app.on('window-all-closed', () => { @@ -36,6 +40,6 @@ app.on('quit', killParity); app.on('activate', () => { if (fetherAppInstance.fetherApp.window === null) { - fetherAppInstance.create.call(undefined); + fetherAppInstance.create(options); } }); diff --git a/yarn.lock b/yarn.lock index 839dc7e55..d85fbfcbe 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7172,7 +7172,7 @@ extend@^3.0.0, extend@~3.0.0, extend@~3.0.1: resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" integrity sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ= -extend@~3.0.2: +extend@^3.0.2, extend@~3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== From 7a9a81bfb74b603e1291158112d8b52e24b83cad Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Sun, 6 Jan 2019 21:04:56 +1100 Subject: [PATCH 016/153] refactor: Move download, installation, and running of Parity Ethereum into ParityEthereum class --- .../fether-electron/src/main/app/index.js | 67 +------------ .../src/main/app/parityEthereum/index.js | 98 +++++++++++++++++++ 2 files changed, 103 insertions(+), 62 deletions(-) create mode 100644 packages/fether-electron/src/main/app/parityEthereum/index.js diff --git a/packages/fether-electron/src/main/app/index.js b/packages/fether-electron/src/main/app/index.js index 751993c7d..d1f5b09fb 100644 --- a/packages/fether-electron/src/main/app/index.js +++ b/packages/fether-electron/src/main/app/index.js @@ -3,25 +3,18 @@ // // SPDX-License-Identifier: BSD-3-Clause -import parityElectron, { - getParityPath, - fetchParity, - isParityRunning, - runParity -} from '@parity/electron'; +import parityElectron from '@parity/electron'; import electron from 'electron'; -import getRemainingArgs from 'commander-remaining-args'; import path from 'path'; import url from 'url'; -import { parity } from '../../../package.json'; import { productName } from '../../../electron-builder.json'; -import handleError from '../utils/handleError'; import staticPath from '../utils/staticPath'; import Pino from '../utils/pino'; import addMenu from '../menu'; import cli from '../cli'; import messages from '../messages'; +import ParityEthereum from './parityEthereum'; const { BrowserWindow, ipcMain, session } = electron; const pino = Pino(); @@ -44,59 +37,9 @@ class FetherApp { logger: namespace => log => Pino({ name: namespace }).info(log) }); - // Look if Parity is installed - getParityPath() - .catch(() => - // Install parity if not present - fetchParity(this.fetherApp.window, { - onProgress: progress => { - // Notify the renderers on download progress - return this.fetherApp.window.webContents.send( - 'parity-download-progress', - progress - ); - }, - parityChannel: parity.channel - }) - ) - .then(async () => { - // Run parity when installed - - // Don't run parity if the user ran fether with --no-run-parity - if (!cli.runParity) { - return; - } - - if ( - await isParityRunning({ - wsInterface: cli.wsInterface, - wsPort: cli.wsPort - }) - ) { - return; - } - - return runParity({ - flags: [ - ...getRemainingArgs(cli), - '--light', - '--chain', - cli.chain, - '--ws-interface', - cli.wsInterface, - '--ws-port', - cli.wsPort - ], - onParityError: err => - handleError(err, 'An error occured with Parity.') - }); - }) - .then(() => { - // Notify the renderers - this.fetherApp.window.webContents.send('parity-running', true); - global.isParityRunning = true; // Send this variable to renderes via IPC - }) - .catch(handleError); + // Download, install, and run Parity Ethereum if not running and requested + const parityEthereumInstance = new ParityEthereum(); + parityEthereumInstance.setup(this.fetherApp.window); // Globals for fether-react parityStore global.wsInterface = cli.wsInterface; diff --git a/packages/fether-electron/src/main/app/parityEthereum/index.js b/packages/fether-electron/src/main/app/parityEthereum/index.js new file mode 100644 index 000000000..5921d2597 --- /dev/null +++ b/packages/fether-electron/src/main/app/parityEthereum/index.js @@ -0,0 +1,98 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. +// +// SPDX-License-Identifier: BSD-3-Clause + +import { + getParityPath, + fetchParity, + isParityRunning, + runParity +} from '@parity/electron'; +import getRemainingArgs from 'commander-remaining-args'; + +import { parity } from '../../../../package.json'; +import handleError from '../../utils/handleError'; +import cli from '../../cli'; +import Pino from '../../utils/pino'; + +const pino = Pino(); + +let hasCalledInitParityEthereum = false; + +class ParityEthereum { + setup = fetherAppWindow => { + if (hasCalledInitParityEthereum) { + throw new Error('Unable to initialise Parity Ethereum more than once'); + } + + // Check if Parity Ethereum is installed + getParityPath() + // Download and install Parity Ethereum if not present + .catch(() => { + pino.info('Downloading and Installing Parity Ethereum'); + return this.install(fetherAppWindow); + }) + .then(async () => { + // Do not run Parity Ethereum if the user ran Fether with --no-run-parity + if (!cli.runParity) { + return; + } + + // Do not run Parity Ethereum if it is already running + if (await this.isRunning()) { + return; + } + + // Run Parity Ethereum when installed + const parityEthereum = await this.run(); + pino.info('Running Parity Ethereum'); + return parityEthereum; + }) + .then(() => { + // Notify the renderers + fetherAppWindow.webContents.send('parity-running', true); + global.isParityRunning = true; // Send this variable to renderers via IPC + }) + .catch(handleError); + }; + + install = fetherAppWindow => { + return fetchParity(fetherAppWindow, { + onProgress: progress => { + // Notify the renderers on download progress + return fetherAppWindow.webContents.send( + 'parity-download-progress', + progress + ); + }, + parityChannel: parity.channel + }); + }; + + isRunning = async () => { + return isParityRunning({ + wsInterface: cli.wsInterface, + wsPort: cli.wsPort + }); + }; + + run = async () => { + return runParity({ + flags: [ + ...getRemainingArgs(cli), + '--light', + '--chain', + cli.chain, + '--ws-interface', + cli.wsInterface, + '--ws-port', + cli.wsPort + ], + onParityError: err => + handleError(err, 'An error occured with Parity Ethereum.') + }); + }; +} + +export default ParityEthereum; From 56104646ebf3834748e40170f846858377d6833f Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Sun, 6 Jan 2019 21:34:34 +1100 Subject: [PATCH 017/153] refactor: Move into default options.index the Electron start url --- packages/fether-electron/src/main/app/index.js | 12 +----------- .../fether-electron/src/main/app/options/index.js | 13 ++++++++++++- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/packages/fether-electron/src/main/app/index.js b/packages/fether-electron/src/main/app/index.js index d1f5b09fb..2eeeebf0e 100644 --- a/packages/fether-electron/src/main/app/index.js +++ b/packages/fether-electron/src/main/app/index.js @@ -5,11 +5,8 @@ import parityElectron from '@parity/electron'; import electron from 'electron'; -import path from 'path'; -import url from 'url'; import { productName } from '../../../electron-builder.json'; -import staticPath from '../utils/staticPath'; import Pino from '../utils/pino'; import addMenu from '../menu'; import cli from '../cli'; @@ -47,14 +44,7 @@ class FetherApp { // Opens file:///path/to/build/index.html in prod mode, or whatever is // passed to ELECTRON_START_URL - this.fetherApp.window.loadURL( - process.env.ELECTRON_START_URL || - url.format({ - pathname: path.join(staticPath, 'build', 'index.html'), - protocol: 'file:', - slashes: true - }) - ); + this.fetherApp.window.loadURL(options.index); // Listen to messages from renderer process ipcMain.on('asynchronous-message', (...args) => diff --git a/packages/fether-electron/src/main/app/options/index.js b/packages/fether-electron/src/main/app/options/index.js index bf99e6577..dab0e9285 100644 --- a/packages/fether-electron/src/main/app/options/index.js +++ b/packages/fether-electron/src/main/app/options/index.js @@ -3,12 +3,23 @@ // // SPDX-License-Identifier: BSD-3-Clause +import path from 'path'; +import url from 'url'; import extend from 'extend'; +import staticPath from '../../utils/staticPath'; + const DEFAULT_OPTIONS = { height: 640, resizable: false, - width: 360 + width: 360, + index: + process.env.ELECTRON_START_URL || + url.format({ + pathname: path.join(staticPath, 'build', 'index.html'), + protocol: 'file:', + slashes: true + }) }; const TASKBAR_OPTIONS = {}; From 9ed899c393ffcaa61afb492d18ca9f4a93541e4e Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Sun, 6 Jan 2019 22:32:49 +1100 Subject: [PATCH 018/153] refactor: Move all FetherApp dependencies into subfolders within app folder. Fix imports --- packages/fether-electron/src/main/{ => app}/cli/index.js | 4 ++-- packages/fether-electron/src/main/app/index.js | 8 ++++---- packages/fether-electron/src/main/{ => app}/menu/index.js | 0 .../fether-electron/src/main/{ => app}/messages/index.js | 0 packages/fether-electron/src/main/app/options/index.js | 2 +- .../fether-electron/src/main/app/parityEthereum/index.js | 6 +++--- .../src/main/{ => app}/utils/handleError.js | 2 +- packages/fether-electron/src/main/{ => app}/utils/pino.js | 2 +- .../src/main/{ => app}/utils/staticPath.js | 0 9 files changed, 12 insertions(+), 12 deletions(-) rename packages/fether-electron/src/main/{ => app}/cli/index.js (92%) rename packages/fether-electron/src/main/{ => app}/menu/index.js (100%) rename packages/fether-electron/src/main/{ => app}/messages/index.js (100%) rename packages/fether-electron/src/main/{ => app}/utils/handleError.js (94%) rename packages/fether-electron/src/main/{ => app}/utils/pino.js (94%) rename packages/fether-electron/src/main/{ => app}/utils/staticPath.js (100%) diff --git a/packages/fether-electron/src/main/cli/index.js b/packages/fether-electron/src/main/app/cli/index.js similarity index 92% rename from packages/fether-electron/src/main/cli/index.js rename to packages/fether-electron/src/main/app/cli/index.js index 16d365973..3c17141d4 100644 --- a/packages/fether-electron/src/main/cli/index.js +++ b/packages/fether-electron/src/main/app/cli/index.js @@ -5,8 +5,8 @@ import cli from 'commander'; -const { productName } = require('../../../electron-builder.json'); -const { version } = require('../../../package.json'); +const { productName } = require('../../../../electron-builder.json'); +const { version } = require('../../../../package.json'); /** * Process.argv arguments length is different in electron mode and in packaged diff --git a/packages/fether-electron/src/main/app/index.js b/packages/fether-electron/src/main/app/index.js index 2eeeebf0e..cad475466 100644 --- a/packages/fether-electron/src/main/app/index.js +++ b/packages/fether-electron/src/main/app/index.js @@ -7,10 +7,10 @@ import parityElectron from '@parity/electron'; import electron from 'electron'; import { productName } from '../../../electron-builder.json'; -import Pino from '../utils/pino'; -import addMenu from '../menu'; -import cli from '../cli'; -import messages from '../messages'; +import Pino from './utils/pino'; +import addMenu from './menu'; +import cli from './cli'; +import messages from './messages'; import ParityEthereum from './parityEthereum'; const { BrowserWindow, ipcMain, session } = electron; diff --git a/packages/fether-electron/src/main/menu/index.js b/packages/fether-electron/src/main/app/menu/index.js similarity index 100% rename from packages/fether-electron/src/main/menu/index.js rename to packages/fether-electron/src/main/app/menu/index.js diff --git a/packages/fether-electron/src/main/messages/index.js b/packages/fether-electron/src/main/app/messages/index.js similarity index 100% rename from packages/fether-electron/src/main/messages/index.js rename to packages/fether-electron/src/main/app/messages/index.js diff --git a/packages/fether-electron/src/main/app/options/index.js b/packages/fether-electron/src/main/app/options/index.js index dab0e9285..759bf9645 100644 --- a/packages/fether-electron/src/main/app/options/index.js +++ b/packages/fether-electron/src/main/app/options/index.js @@ -7,7 +7,7 @@ import path from 'path'; import url from 'url'; import extend from 'extend'; -import staticPath from '../../utils/staticPath'; +import staticPath from '../utils/staticPath'; const DEFAULT_OPTIONS = { height: 640, diff --git a/packages/fether-electron/src/main/app/parityEthereum/index.js b/packages/fether-electron/src/main/app/parityEthereum/index.js index 5921d2597..c9510eddd 100644 --- a/packages/fether-electron/src/main/app/parityEthereum/index.js +++ b/packages/fether-electron/src/main/app/parityEthereum/index.js @@ -12,9 +12,9 @@ import { import getRemainingArgs from 'commander-remaining-args'; import { parity } from '../../../../package.json'; -import handleError from '../../utils/handleError'; -import cli from '../../cli'; -import Pino from '../../utils/pino'; +import handleError from '../utils/handleError'; +import cli from '../cli'; +import Pino from '../utils/pino'; const pino = Pino(); diff --git a/packages/fether-electron/src/main/utils/handleError.js b/packages/fether-electron/src/main/app/utils/handleError.js similarity index 94% rename from packages/fether-electron/src/main/utils/handleError.js rename to packages/fether-electron/src/main/app/utils/handleError.js index 8159dfede..16bfc24f0 100644 --- a/packages/fether-electron/src/main/utils/handleError.js +++ b/packages/fether-electron/src/main/app/utils/handleError.js @@ -5,7 +5,7 @@ import { app, dialog, shell } from 'electron'; -import { bugs, name, parity } from '../../../package.json'; +import { bugs, name, parity } from '../../../../package.json'; import Pino from './pino'; const logFile = `${app.getPath('userData')}/${name}.log`; diff --git a/packages/fether-electron/src/main/utils/pino.js b/packages/fether-electron/src/main/app/utils/pino.js similarity index 94% rename from packages/fether-electron/src/main/utils/pino.js rename to packages/fether-electron/src/main/app/utils/pino.js index 620844917..cb4ea31d3 100644 --- a/packages/fether-electron/src/main/utils/pino.js +++ b/packages/fether-electron/src/main/app/utils/pino.js @@ -8,7 +8,7 @@ import fs from 'fs'; import { multistream } from 'pino-multi-stream'; import Pino from 'pino'; -import { name } from '../../../package.json'; +import { name } from '../../../../package.json'; // Pino by default outputs JSON. We prettify that. const pretty = Pino.pretty(); diff --git a/packages/fether-electron/src/main/utils/staticPath.js b/packages/fether-electron/src/main/app/utils/staticPath.js similarity index 100% rename from packages/fether-electron/src/main/utils/staticPath.js rename to packages/fether-electron/src/main/app/utils/staticPath.js From d101121ced0ff4e725559c4c7e72981d4a46853f Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Sun, 6 Jan 2019 23:27:31 +1100 Subject: [PATCH 019/153] fix: isRunning boolean returned to .then --- .../src/main/app/parityEthereum/index.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/fether-electron/src/main/app/parityEthereum/index.js b/packages/fether-electron/src/main/app/parityEthereum/index.js index c9510eddd..0269c91e5 100644 --- a/packages/fether-electron/src/main/app/parityEthereum/index.js +++ b/packages/fether-electron/src/main/app/parityEthereum/index.js @@ -36,23 +36,23 @@ class ParityEthereum { .then(async () => { // Do not run Parity Ethereum if the user ran Fether with --no-run-parity if (!cli.runParity) { - return; + return false; } // Do not run Parity Ethereum if it is already running if (await this.isRunning()) { - return; + return true; } // Run Parity Ethereum when installed - const parityEthereum = await this.run(); + await this.run(); pino.info('Running Parity Ethereum'); - return parityEthereum; + return true; }) - .then(() => { + .then(isRunning => { // Notify the renderers - fetherAppWindow.webContents.send('parity-running', true); - global.isParityRunning = true; // Send this variable to renderers via IPC + fetherAppWindow.webContents.send('parity-running', isRunning); + global.isParityRunning = isRunning; // Send this variable to renderers via IPC }) .catch(handleError); }; From 30abe60f83d7d572c07102d9b132c89da574c6da Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Mon, 7 Jan 2019 04:10:47 +1100 Subject: [PATCH 020/153] fix: Add hasVisibleWindows and event to activate Electron listener https://electronjs.org/docs/api/app#event-activate-macos --- packages/fether-electron/src/main/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/fether-electron/src/main/index.js b/packages/fether-electron/src/main/index.js index 433eda3d0..acc60551a 100644 --- a/packages/fether-electron/src/main/index.js +++ b/packages/fether-electron/src/main/index.js @@ -38,8 +38,8 @@ app.on('before-quit', killParity); app.on('will-quit', killParity); app.on('quit', killParity); -app.on('activate', () => { - if (fetherAppInstance.fetherApp.window === null) { +app.on('activate', (event, hasVisibleWindows) => { + if (!hasVisibleWindows || fetherAppInstance.fetherApp.window === null) { fetherAppInstance.create(options); } }); From 70ebf9415e8516dfe3a0a762507d19688f30a013 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Mon, 7 Jan 2019 06:48:20 +1100 Subject: [PATCH 021/153] docs: Add Fixme --- packages/fether-electron/src/main/index.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/fether-electron/src/main/index.js b/packages/fether-electron/src/main/index.js index acc60551a..5d6109c3d 100644 --- a/packages/fether-electron/src/main/index.js +++ b/packages/fether-electron/src/main/index.js @@ -38,6 +38,9 @@ app.on('before-quit', killParity); app.on('will-quit', killParity); app.on('quit', killParity); +// FIXME - determine how to trigger this to check that it works and doesn't create duplicate! +// perhaps it should be `!hasVisibleWindows && !fetherAppInstance` instead +// See https://electronjs.org/docs/api/app#event-activate-macos app.on('activate', (event, hasVisibleWindows) => { if (!hasVisibleWindows || fetherAppInstance.fetherApp.window === null) { fetherAppInstance.create(options); From 4763ac0591d3926475c1982232912294ed78b92b Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Mon, 7 Jan 2019 19:12:08 +1100 Subject: [PATCH 022/153] refactor: Integrate menubar. Separate logic for taskbar app. See commit details * Readme updated with environment variable prefix `TASKBAR=false` to disable taskbar. Use existing "electron" and "start" scripts in package.json. Configure taskbar to be enabled by default (i.e. `withTaskbar = true`) * Integrate menubar functionality including for taskbar including: * electron dependencies: `Tray` * electron-positioner: `Positioner` * Separate logic in `FetherApp` component dependending on whether `withTaskbar` is enabled, but shared functionality in `finalise()` function * Incorporate relevant Pino logs throughout to improve developer experience * Move options into FetherAppOptions class and move configuration config for options into a config subfolder within the module. * Use `extends` library to overwrite `DEFAULT_OPTIONS` options properties with those in `TASKBAR_OPTIONS` if `withTaskbar` is enabled * Add ability to pass `customOptions` to further overwrite the values in the config directory, and add option setter and getters * Move taskbar icons into app/options/config subdirectory. Use different logic to set the path of the icons directory depending on whether it was run using the "electron" or the "start" script in package.json. Leverage the fact that when "electron" is run the environment variable `SKIP_PREFLIGHT_CHECK=true` is set * Set the Electron option `webPreferences.devTools` depending on whether we are in production or not particularly for security reasons * Fix `activate` event listener to cater for `withTaskbar` enabled or disabled usage * BUG: When running with `withTaskbar` enabled we are setting the option `show: false` because it opens the window in the center of the screen instead of positioned right under the taskbar icon at the top of the screen. When you click the icon in the taskbar it toggles the window open/close correctly positioned since it takes into consideration the `bounds` value in `FetherApp.clickedTray`. To fix the bug we need to reuse the same approach. * BUG: Additional `EventEmitter` does not appear to be working correctly or is not required. Investigate if can remove --- README.md | 15 +- package.json | 1 - packages/fether-electron/package.json | 2 +- .../fether-electron/src/main/app/index.js | 192 ++++++++++++++++-- .../src/main/app/menu/index.js | 4 +- .../src/main/app/messages/index.js | 6 +- .../app/options/config/icons}/parity-icon.png | Bin .../options/config/icons}/parity-icon@2x.png | Bin .../src/main/app/options/config/index.js | 56 +++++ .../src/main/app/options/index.js | 39 ++-- packages/fether-electron/src/main/index.js | 39 +++- yarn.lock | 5 + 12 files changed, 294 insertions(+), 65 deletions(-) rename packages/{fether-react/src/assets/img/logos => fether-electron/src/main/app/options/config/icons}/parity-icon.png (100%) rename packages/{fether-react/src/assets/img/logos => fether-electron/src/main/app/options/config/icons}/parity-icon@2x.png (100%) create mode 100644 packages/fether-electron/src/main/app/options/config/index.js diff --git a/README.md b/README.md index 742fe2680..6f215ecd3 100644 --- a/README.md +++ b/README.md @@ -115,21 +115,10 @@ yarn start > Troubleshooting: If it hangs on a white screen in Electron even though it has compiled and has been syncing for a long time, then simply choose 'View > Reload' (CMD + R on macOS) from the Electron menu -### Run as a taskbar app - -Separately launch Parity Ethereum node with the following flags: +# Run without taskbar ```bash -$ parity --chain kovan --light --ws-origins=file://* -``` - -In another console launch Fether: - -```bash -# Fether will connect to the running node -$ cd /path/to/fether -$ yarn; yarn build -$ yarn taskbar +TASKBAR=false yarn start ``` ## Join the chat! diff --git a/package.json b/package.json index 4b81c4f67..daad3b278 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,6 @@ "start-electron": "cd packages/fether-electron && yarn start", "start-react": "cd packages/fether-react && yarn start", "start-ui": "cd packages/fether-ui && yarn start", - "taskbar": "cd packages/fether-electron && yarn taskbar", "test": "semistandard '**/*.{js,ts}' --parser babel-eslint && CI=true lerna run test --parallel" }, "husky": { diff --git a/packages/fether-electron/package.json b/packages/fether-electron/package.json index a9d996719..f23d0dc19 100644 --- a/packages/fether-electron/package.json +++ b/packages/fether-electron/package.json @@ -36,13 +36,13 @@ "prerelease": "./scripts/revertElectronBug.sh", "release": "electron-builder", "start": "cross-env ELECTRON_START_URL=http://localhost:3000 electron-webpack dev --ws-origins all", - "taskbar": "cross-env SKIP_PREFLIGHT_CHECK=true electron mb.js", "test": "echo Skipped." }, "dependencies": { "@parity/electron": "^3.0.1", "commander": "^2.15.1", "commander-remaining-args": "^1.2.0", + "electron-positioner": "^4.1.0", "extend": "^3.0.2", "fether-react": "^0.1.2", "menubar": "^5.2.3", diff --git a/packages/fether-electron/src/main/app/index.js b/packages/fether-electron/src/main/app/index.js index cad475466..371ef1247 100644 --- a/packages/fether-electron/src/main/app/index.js +++ b/packages/fether-electron/src/main/app/index.js @@ -4,7 +4,9 @@ // SPDX-License-Identifier: BSD-3-Clause import parityElectron from '@parity/electron'; -import electron from 'electron'; +import electron, { Tray } from 'electron'; +import Positioner from 'electron-positioner'; +import events from 'events'; import { productName } from '../../../electron-builder.json'; import Pino from './utils/pino'; @@ -19,16 +21,39 @@ const pino = Pino(); let hasCalledInitFetherApp = false; class FetherApp { - fetherApp = {}; + fetherApp = new events.EventEmitter(); - create = options => { + create = (electronApp, options) => { if (hasCalledInitFetherApp) { throw new Error('Unable to initialise Fether app more than once'); } - pino.info(`Starting ${productName}...`); - this.fetherApp.window = new BrowserWindow(options); + pino.info( + `Starting ${productName} (${ + options.withTaskbar ? 'with' : 'without' + } taskbar)...` + ); + + this.fetherApp.app = electronApp; + this.fetherApp.options = options; + + if (this.fetherApp.options.withTaskbar) { + this.createWindow(); + this.loadTaskbar(); + this.finalise(); + } else { + this.fetherApp.window = new BrowserWindow(this.fetherApp.options); + + // Opens file:///path/to/build/index.html in prod mode, or whatever is + // passed to ELECTRON_START_URL + this.fetherApp.window.loadURL(this.fetherApp.options.index); + this.finalise(); + } + + this.fetherApp.emit('ready'); + }; + finalise = () => { // Set options for @parity/electron parityElectron({ logger: namespace => log => Pino({ name: namespace }).info(log) @@ -42,17 +67,14 @@ class FetherApp { global.wsInterface = cli.wsInterface; global.wsPort = cli.wsPort; - // Opens file:///path/to/build/index.html in prod mode, or whatever is - // passed to ELECTRON_START_URL - this.fetherApp.window.loadURL(options.index); - // Listen to messages from renderer process - ipcMain.on('asynchronous-message', (...args) => - messages(this.fetherApp.window, ...args) - ); + ipcMain.on('asynchronous-message', (...args) => { + return messages(this.fetherApp.window, ...args); + }); // Add application menu addMenu(this.fetherApp.window); + pino.info('Finished configuring Electron menu'); // WS calls have Origin `file://` by default, which is not trusted. // We override Origin header on all WS connections with an authorized one. @@ -74,7 +96,7 @@ class FetherApp { ); // Open external links in browser - this.fetherApp.window.webContents.on('new-window', function (event, url) { + this.fetherApp.window.webContents.on('new-window', (event, url) => { event.preventDefault(); electron.shell.openExternal(url); }); @@ -83,6 +105,150 @@ class FetherApp { this.fetherApp.window = null; }); }; + + loadTaskbar = () => { + pino.info('Configuring Fether taskbar...'); + + if (this.fetherApp.app.dock && !this.fetherApp.options.showDockIcon) { + this.fetherApp.app.dock.hide(); + } + + const defaultClickEvent = this.fetherApp.options.showOnRightClick + ? 'right-click' + : 'click'; + + this.fetherApp.tray = new Tray(this.fetherApp.options.icon); + this.fetherApp.tray.on(defaultClickEvent, this.clickedTray); + this.fetherApp.tray.on('double-click', this.clickedTray); + this.fetherApp.tray.setToolTip(this.fetherApp.options.tooltip); + + this.fetherApp.supportsTrayHighlightState = false; + + try { + this.fetherApp.tray.setHighlightMode('never'); + this.fetherApp.supportsTrayHighlightState = true; + } catch (e) { + console.error('Unable to set highlight mode: ', e); + } + }; + + createWindow = () => { + pino.info('Creating Fether window'); + + this.fetherApp.emit('create-window'); + + this.fetherApp.window = new BrowserWindow(this.fetherApp.options); + this.fetherApp.positioner = new Positioner(this.fetherApp.window); + + this.fetherApp.window.on('blur', () => { + this.fetherApp.options.alwaysOnTop ? this.emitBlur() : this.hideWindow(); + }); + + if (this.fetherApp.options.showOnAllWorkspaces !== false) { + this.fetherApp.window.setVisibleOnAllWorkspaces(true); + } + + this.fetherApp.window.on('close', this.windowClear); + + this.fetherApp.window.loadURL(this.fetherApp.options.index); + + this.fetherApp.emit('after-create-window'); + }; + + showWindow = trayPos => { + pino.info('Showing Fether window'); + + if (this.fetherApp.supportsTrayHighlightState) { + this.fetherApp.tray.setHighlightMode('always'); + } + + if (!this.fetherApp.window) { + this.createWindow(); + } + + this.fetherApp.emit('show'); + + if (trayPos && trayPos.x !== 0) { + // Cache the bounds + this.fetherApp.cachedBounds = trayPos; + } else if (this.fetherApp.cachedBounds) { + // Cached value will be used if showWindow is called without bounds data + trayPos = this.fetherApp.cachedBounds; + } else if (this.fetherApp.tray.getBounds) { + // Get the current tray bounds + trayPos = this.fetherApp.tray.getBounds(); + } + + // Default the window to the right if `trayPos` bounds are undefined or null. + let noBoundsPosition = null; + + if ( + (trayPos === undefined || (trayPos && trayPos.x === 0)) && + this.fetherApp.options.windowPosition && + this.fetherApp.options.windowPosition.substr(0, 4) === 'tray' + ) { + noBoundsPosition = + process.platform === 'win32' ? 'bottomRight' : 'topRight'; + } + + const position = this.fetherApp.positioner.calculate( + noBoundsPosition || this.fetherApp.options.windowPosition, + trayPos + ); + + const x = + this.fetherApp.options.x !== undefined + ? this.fetherApp.options.x + : position.x; + const y = + this.fetherApp.options.y !== undefined + ? this.fetherApp.options.y + : position.y; + + this.fetherApp.window.setPosition(x, y); + this.fetherApp.window.show(); + + this.fetherApp.emit('after-show'); + }; + + hideWindow = () => { + if (this.fetherApp.supportsTrayHighlightState) { + this.fetherApp.tray.setHighlightMode('never'); + } + + if (!this.fetherApp.window) { + return; + } + + this.fetherApp.emit('hide'); + this.fetherApp.window.hide(); + this.fetherApp.emit('after-hide'); + }; + + windowClear = () => { + delete this.fetherApp.window; + this.fetherApp.emit('after-close'); + }; + + emitBlur = () => { + this.fetherApp.emit('focus-lost'); + }; + + clickedTray = (e, bounds) => { + if ( + e.altKey || + e.shiftKey || + e.ctrlKey || + e.metaKey || + (this.fetherApp.window && this.fetherApp.window.isVisible()) + ) { + return this.hideWindow(); + } + + // cachedBounds are needed for double-clicked event + this.fetherApp.cachedBounds = bounds || this.fetherApp.cachedBounds; + this.showWindow(this.fetherApp.cachedBounds); + }; } export default FetherApp; diff --git a/packages/fether-electron/src/main/app/menu/index.js b/packages/fether-electron/src/main/app/menu/index.js index b41c6006f..e5746a75e 100644 --- a/packages/fether-electron/src/main/app/menu/index.js +++ b/packages/fether-electron/src/main/app/menu/index.js @@ -7,7 +7,7 @@ import electron from 'electron'; const { app, Menu, shell } = electron; -export default mainWindow => { +export default fetherAppWindow => { // Create the Application's main menu // https://github.com/electron/electron/blob/master/docs/api/menu.md#examples const template = [ @@ -90,5 +90,5 @@ export default mainWindow => { const menu = Menu.buildFromTemplate(template); Menu.setApplicationMenu(menu); - mainWindow.setAutoHideMenuBar(true); + fetherAppWindow.setAutoHideMenuBar(true); }; diff --git a/packages/fether-electron/src/main/app/messages/index.js b/packages/fether-electron/src/main/app/messages/index.js index a2a1125cf..8c0007ee0 100644 --- a/packages/fether-electron/src/main/app/messages/index.js +++ b/packages/fether-electron/src/main/app/messages/index.js @@ -12,16 +12,16 @@ const pino = Pino(); /** * Handle all asynchronous messages from renderer to main. */ -export default async (mainWindow, event, action, ...args) => { +export default async (fetherAppWindow, event, action, ...args) => { try { if (!action) { return; } switch (action) { case 'app-resize': { - const [width] = mainWindow.getContentSize(); + const [width] = fetherAppWindow.getContentSize(); const newHeight = args[0]; - mainWindow.setContentSize(width, Math.round(newHeight) + 2); + fetherAppWindow.setContentSize(width, Math.round(newHeight) + 2); break; } case 'check-clock-sync': { diff --git a/packages/fether-react/src/assets/img/logos/parity-icon.png b/packages/fether-electron/src/main/app/options/config/icons/parity-icon.png similarity index 100% rename from packages/fether-react/src/assets/img/logos/parity-icon.png rename to packages/fether-electron/src/main/app/options/config/icons/parity-icon.png diff --git a/packages/fether-react/src/assets/img/logos/parity-icon@2x.png b/packages/fether-electron/src/main/app/options/config/icons/parity-icon@2x.png similarity index 100% rename from packages/fether-react/src/assets/img/logos/parity-icon@2x.png rename to packages/fether-electron/src/main/app/options/config/icons/parity-icon@2x.png diff --git a/packages/fether-electron/src/main/app/options/config/index.js b/packages/fether-electron/src/main/app/options/config/index.js new file mode 100644 index 000000000..3946914c1 --- /dev/null +++ b/packages/fether-electron/src/main/app/options/config/index.js @@ -0,0 +1,56 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. +// +// SPDX-License-Identifier: BSD-3-Clause + +import path from 'path'; +import url from 'url'; + +import staticPath from '../../utils/staticPath'; + +const INDEX_HTML_PATH = + process.env.ELECTRON_START_URL || + url.format({ + pathname: path.join(staticPath, 'build', 'index.html'), + protocol: 'file:', + slashes: true + }); + +// Icon path differs when started with `yarn electron` or `yarn start` +const ICON_PATH = + process.env.ELECTRON_START_ICON || process.env.SKIP_PREFLIGHT_CHECK + ? 'src/main/app/options/config/icons/parity-icon.png' + : path.join(__dirname, 'icons', 'parity-icon.png'); + +const shouldUseDevTools = process.env.NODE_ENV !== 'production'; + +const DEFAULT_OPTIONS = { + frame: true, + height: 640, + index: INDEX_HTML_PATH, + resizable: false, + show: true, + webPreferences: { + devTools: shouldUseDevTools // Security + }, + width: 360, + withTaskbar: false +}; + +const windowPosition = + process.platform === 'win32' ? 'trayBottomCenter' : 'trayCenter'; + +const TASKBAR_OPTIONS = { + dir: staticPath, + frame: false, + height: 464, + icon: ICON_PATH, + show: false, // Run showWindow later when taskbar has loaded in FetherApp + showDockIcon: true, + tooltip: 'Parity Fether', + windowPosition: windowPosition, // Required + width: 352, + withTaskbar: true +}; + +export { DEFAULT_OPTIONS, TASKBAR_OPTIONS }; diff --git a/packages/fether-electron/src/main/app/options/index.js b/packages/fether-electron/src/main/app/options/index.js index 759bf9645..35742514e 100644 --- a/packages/fether-electron/src/main/app/options/index.js +++ b/packages/fether-electron/src/main/app/options/index.js @@ -3,43 +3,40 @@ // // SPDX-License-Identifier: BSD-3-Clause -import path from 'path'; -import url from 'url'; import extend from 'extend'; -import staticPath from '../utils/staticPath'; - -const DEFAULT_OPTIONS = { - height: 640, - resizable: false, - width: 360, - index: - process.env.ELECTRON_START_URL || - url.format({ - pathname: path.join(staticPath, 'build', 'index.html'), - protocol: 'file:', - slashes: true - }) -}; - -const TASKBAR_OPTIONS = {}; +import { DEFAULT_OPTIONS, TASKBAR_OPTIONS } from './config'; let hasCalledInitFetherAppOptions = false; class FetherAppOptions { options = {}; - create = withTaskbar => { + create = (withTaskbar, customOptions) => { if (hasCalledInitFetherAppOptions) { throw new Error('Unable to initialise Fether app options more than once'); } + // Allow user to get/set options prior or to pass custom options this.options = withTaskbar - ? extend(DEFAULT_OPTIONS, TASKBAR_OPTIONS) - : DEFAULT_OPTIONS; + ? extend( + this.options, + DEFAULT_OPTIONS, + TASKBAR_OPTIONS, + customOptions || {} + ) + : extend(this.options, DEFAULT_OPTIONS, customOptions || {}); return this.options; }; + + get = opt => { + return this.options[opt]; + }; + + set = (opt, val) => { + this.options[opt] = val; + }; } export default FetherAppOptions; diff --git a/packages/fether-electron/src/main/index.js b/packages/fether-electron/src/main/index.js index 5d6109c3d..eca994a4c 100644 --- a/packages/fether-electron/src/main/index.js +++ b/packages/fether-electron/src/main/index.js @@ -6,10 +6,12 @@ import { killParity } from '@parity/electron'; import electron from 'electron'; +import Pino from './app/utils/pino'; import FetherApp from './app'; import FetherAppOptions from './app/options'; const { app } = electron; +const pino = Pino(); // Disable gpu acceleration on linux // https://github.com/parity-js/fether/issues/85 @@ -17,13 +19,32 @@ if (!['darwin', 'win32'].includes(process.platform)) { app.disableHardwareAcceleration(); } -const fetherAppInstance = new FetherApp(); +const withTaskbar = process.env.TASKBAR !== 'false'; +const fetherAppInstance = new FetherApp(); const fetherAppOptionsInstance = new FetherAppOptions(); -const options = fetherAppOptionsInstance.create(); +const options = fetherAppOptionsInstance.create(withTaskbar, {}); app.on('ready', () => { - fetherAppInstance.create(options); + fetherAppInstance.create(app, options); +}); + +// Event triggered by clicking the Electron icon in the menu Dock +// Reference: https://electronjs.org/docs/api/app#event-activate-macos +app.on('activate', (event, hasVisibleWindows) => { + if (withTaskbar) { + pino.info( + 'Detected Fether taskbar mode. Launching from application dock is not permitted.' + ); + return; + } + + if (hasVisibleWindows) { + pino.info('Existing Fether window detected.'); + return; + } + + fetherAppInstance.create(app, options); }); app.on('window-all-closed', () => { @@ -35,14 +56,10 @@ app.on('window-all-closed', () => { // Make sure Parity Ethereum stops when UI stops app.on('before-quit', killParity); + app.on('will-quit', killParity); -app.on('quit', killParity); -// FIXME - determine how to trigger this to check that it works and doesn't create duplicate! -// perhaps it should be `!hasVisibleWindows && !fetherAppInstance` instead -// See https://electronjs.org/docs/api/app#event-activate-macos -app.on('activate', (event, hasVisibleWindows) => { - if (!hasVisibleWindows || fetherAppInstance.fetherApp.window === null) { - fetherAppInstance.create(options); - } +app.on('quit', () => { + pino.info('Leaving Fether'); + killParity(); }); diff --git a/yarn.lock b/yarn.lock index d85fbfcbe..cdfb968a3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6323,6 +6323,11 @@ electron-positioner@^3.0.0: resolved "https://registry.yarnpkg.com/electron-positioner/-/electron-positioner-3.0.1.tgz#e699400c2d634ad19352cf20202e92b92b96accb" integrity sha512-zQsnNzJB2PY6KEcGFXAoW6iIKtZ+3nbpVozKN7jhdRdRHMFpEpGufwcfrKhnEBBwrfHpyFQgU+p5jkteLIV+Jg== +electron-positioner@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/electron-positioner/-/electron-positioner-4.1.0.tgz#e158f8f6aabd6725a8a9b4f2279b9504bcbea1b0" + integrity sha512-726DfbI9ZNoCg+Fcu6XLuTKTnzf+6nFqv7h+K/V6Ug7IbaPMI7s9S8URnGtWFCy5N5PL4HSzRFF2mXuinftDdg== + electron-publish@20.29.0: version "20.29.0" resolved "https://registry.yarnpkg.com/electron-publish/-/electron-publish-20.29.0.tgz#ab61e95bc4d466b4aff360c12bf1ee3d673967a4" From 7b0873bdc0ca4fbe6bc0f3be600d9efd6e65326e Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Mon, 7 Jan 2019 19:39:30 +1100 Subject: [PATCH 023/153] refactor: Remove menubar demo and dependency --- packages/fether-electron/mb.js | 26 -------------------------- packages/fether-electron/package.json | 1 - yarn.lock | 18 ------------------ 3 files changed, 45 deletions(-) delete mode 100644 packages/fether-electron/mb.js diff --git a/packages/fether-electron/mb.js b/packages/fether-electron/mb.js deleted file mode 100644 index a03682b43..000000000 --- a/packages/fether-electron/mb.js +++ /dev/null @@ -1,26 +0,0 @@ -const path = require('path'); -const menubar = require('menubar'); - -const packagesDir = __dirname.substring(0, __dirname.lastIndexOf('/')); -const indexHtmlFile = - 'file://' + path.join(__dirname, '/static/build/index.html'); -const iconFile = path.join( - packagesDir, - '/fether-react/src/assets/img/logos/parity-icon.png' -); - -const mb = menubar({ - dir: __dirname, - index: indexHtmlFile, - showDockIcon: true, - icon: iconFile, - tooltip: 'Fether', - width: 352, - height: 464 -}); - -mb.on('ready', () => { - console.log('Fether is ready'); - - mb.showWindow(); -}); diff --git a/packages/fether-electron/package.json b/packages/fether-electron/package.json index f23d0dc19..bc9935ded 100644 --- a/packages/fether-electron/package.json +++ b/packages/fether-electron/package.json @@ -45,7 +45,6 @@ "electron-positioner": "^4.1.0", "extend": "^3.0.2", "fether-react": "^0.1.2", - "menubar": "^5.2.3", "pino": "^4.16.1", "pino-multi-stream": "^3.1.2", "source-map-support": "^0.5.6" diff --git a/yarn.lock b/yarn.lock index cdfb968a3..3ee8d0e1e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6318,11 +6318,6 @@ electron-osx-sign@0.4.11: minimist "^1.2.0" plist "^3.0.1" -electron-positioner@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/electron-positioner/-/electron-positioner-3.0.1.tgz#e699400c2d634ad19352cf20202e92b92b96accb" - integrity sha512-zQsnNzJB2PY6KEcGFXAoW6iIKtZ+3nbpVozKN7jhdRdRHMFpEpGufwcfrKhnEBBwrfHpyFQgU+p5jkteLIV+Jg== - electron-positioner@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/electron-positioner/-/electron-positioner-4.1.0.tgz#e158f8f6aabd6725a8a9b4f2279b9504bcbea1b0" @@ -7167,11 +7162,6 @@ extend-shallow@^3.0.0, extend-shallow@^3.0.2: assign-symbols "^1.0.0" is-extendable "^1.0.1" -extend@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/extend/-/extend-2.0.1.tgz#1ee8010689e7395ff9448241c98652bc759a8260" - integrity sha1-HugBBonnOV/5RIJByYZSvHWagmA= - extend@^3.0.0, extend@~3.0.0, extend@~3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" @@ -10907,14 +10897,6 @@ memorystream@^0.3.1: resolved "https://registry.yarnpkg.com/memorystream/-/memorystream-0.3.1.tgz#86d7090b30ce455d63fbae12dda51a47ddcaf9b2" integrity sha1-htcJCzDORV1j+64S3aUaR93K+bI= -menubar@^5.2.3: - version "5.2.3" - resolved "https://registry.yarnpkg.com/menubar/-/menubar-5.2.3.tgz#8f2761597b4a0ee87edf04a87d8aab1aac2c44e9" - integrity sha1-jydhWXtKDuh+3wSofYqrGqwsROk= - dependencies: - electron-positioner "^3.0.0" - extend "^2.0.0" - meow@^3.1.0, meow@^3.3.0, meow@^3.7.0: version "3.7.0" resolved "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb" From ae917cceb62b61534dc608e0496771965ab64457 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Mon, 7 Jan 2019 21:37:46 +1100 Subject: [PATCH 024/153] refactor: Destructuring of fetherApp properties --- .../fether-electron/src/main/app/index.js | 88 +++++++++++-------- 1 file changed, 50 insertions(+), 38 deletions(-) diff --git a/packages/fether-electron/src/main/app/index.js b/packages/fether-electron/src/main/app/index.js index 371ef1247..4c2f8cbcc 100644 --- a/packages/fether-electron/src/main/app/index.js +++ b/packages/fether-electron/src/main/app/index.js @@ -37,16 +37,16 @@ class FetherApp { this.fetherApp.app = electronApp; this.fetherApp.options = options; - if (this.fetherApp.options.withTaskbar) { + if (options.withTaskbar) { this.createWindow(); this.loadTaskbar(); this.finalise(); } else { - this.fetherApp.window = new BrowserWindow(this.fetherApp.options); + this.fetherApp.window = new BrowserWindow(options); // Opens file:///path/to/build/index.html in prod mode, or whatever is // passed to ELECTRON_START_URL - this.fetherApp.window.loadURL(this.fetherApp.options.index); + this.fetherApp.window.loadURL(options.index); this.finalise(); } @@ -85,7 +85,7 @@ class FetherApp { (details, callback) => { if (!this.fetherApp.window) { // There might be a split second where the user closes the app, so - // this.fetherApp.window is null, but there is still a network request done. + // this.fether.window is null, but there is still a network request done. return; } details.requestHeaders.Origin = `parity://${ @@ -107,25 +107,29 @@ class FetherApp { }; loadTaskbar = () => { + const { app, options } = this.fetherApp; + pino.info('Configuring Fether taskbar...'); - if (this.fetherApp.app.dock && !this.fetherApp.options.showDockIcon) { - this.fetherApp.app.dock.hide(); + if (app.dock && !options.showDockIcon) { + app.dock.hide(); } - const defaultClickEvent = this.fetherApp.options.showOnRightClick + const defaultClickEvent = options.showOnRightClick ? 'right-click' : 'click'; - this.fetherApp.tray = new Tray(this.fetherApp.options.icon); - this.fetherApp.tray.on(defaultClickEvent, this.clickedTray); - this.fetherApp.tray.on('double-click', this.clickedTray); - this.fetherApp.tray.setToolTip(this.fetherApp.options.tooltip); + this.fetherApp.tray = new Tray(options.icon); + let { tray } = this.fetherApp; + + tray.on(defaultClickEvent, this.clickedTray); + tray.on('double-click', this.clickedTray); + tray.setToolTip(options.tooltip); this.fetherApp.supportsTrayHighlightState = false; try { - this.fetherApp.tray.setHighlightMode('never'); + tray.setHighlightMode('never'); this.fetherApp.supportsTrayHighlightState = true; } catch (e) { console.error('Unable to set highlight mode: ', e); @@ -133,33 +137,43 @@ class FetherApp { }; createWindow = () => { + const { options } = this.fetherApp; + pino.info('Creating Fether window'); this.fetherApp.emit('create-window'); - this.fetherApp.window = new BrowserWindow(this.fetherApp.options); + this.fetherApp.window = new BrowserWindow(options); this.fetherApp.positioner = new Positioner(this.fetherApp.window); this.fetherApp.window.on('blur', () => { - this.fetherApp.options.alwaysOnTop ? this.emitBlur() : this.hideWindow(); + options.alwaysOnTop ? this.emitBlur() : this.hideWindow(); }); - if (this.fetherApp.options.showOnAllWorkspaces !== false) { + if (options.showOnAllWorkspaces !== false) { this.fetherApp.window.setVisibleOnAllWorkspaces(true); } this.fetherApp.window.on('close', this.windowClear); - this.fetherApp.window.loadURL(this.fetherApp.options.index); + this.fetherApp.window.loadURL(options.index); this.fetherApp.emit('after-create-window'); }; showWindow = trayPos => { + const { + cachedBounds, + options, + positioner, + supportsTrayHighlightState, + tray + } = this.fetherApp; + pino.info('Showing Fether window'); - if (this.fetherApp.supportsTrayHighlightState) { - this.fetherApp.tray.setHighlightMode('always'); + if (supportsTrayHighlightState) { + tray.setHighlightMode('always'); } if (!this.fetherApp.window) { @@ -171,12 +185,12 @@ class FetherApp { if (trayPos && trayPos.x !== 0) { // Cache the bounds this.fetherApp.cachedBounds = trayPos; - } else if (this.fetherApp.cachedBounds) { + } else if (cachedBounds) { // Cached value will be used if showWindow is called without bounds data - trayPos = this.fetherApp.cachedBounds; - } else if (this.fetherApp.tray.getBounds) { + trayPos = cachedBounds; + } else if (tray.getBounds) { // Get the current tray bounds - trayPos = this.fetherApp.tray.getBounds(); + trayPos = tray.getBounds(); } // Default the window to the right if `trayPos` bounds are undefined or null. @@ -184,26 +198,20 @@ class FetherApp { if ( (trayPos === undefined || (trayPos && trayPos.x === 0)) && - this.fetherApp.options.windowPosition && - this.fetherApp.options.windowPosition.substr(0, 4) === 'tray' + options.windowPosition && + options.windowPosition.substr(0, 4) === 'tray' ) { noBoundsPosition = process.platform === 'win32' ? 'bottomRight' : 'topRight'; } - const position = this.fetherApp.positioner.calculate( - noBoundsPosition || this.fetherApp.options.windowPosition, + const position = positioner.calculate( + noBoundsPosition || options.windowPosition, trayPos ); - const x = - this.fetherApp.options.x !== undefined - ? this.fetherApp.options.x - : position.x; - const y = - this.fetherApp.options.y !== undefined - ? this.fetherApp.options.y - : position.y; + const x = options.x ? options.x : position.x; + const y = options.y ? options.y : position.y; this.fetherApp.window.setPosition(x, y); this.fetherApp.window.show(); @@ -212,8 +220,10 @@ class FetherApp { }; hideWindow = () => { - if (this.fetherApp.supportsTrayHighlightState) { - this.fetherApp.tray.setHighlightMode('never'); + const { supportsTrayHighlightState, tray } = this.fetherApp; + + if (supportsTrayHighlightState) { + tray.setHighlightMode('never'); } if (!this.fetherApp.window) { @@ -235,18 +245,20 @@ class FetherApp { }; clickedTray = (e, bounds) => { + const { cachedBounds, window } = this.fetherApp; + if ( e.altKey || e.shiftKey || e.ctrlKey || e.metaKey || - (this.fetherApp.window && this.fetherApp.window.isVisible()) + (window && window.isVisible()) ) { return this.hideWindow(); } // cachedBounds are needed for double-clicked event - this.fetherApp.cachedBounds = bounds || this.fetherApp.cachedBounds; + this.fetherApp.cachedBounds = bounds || cachedBounds; this.showWindow(this.fetherApp.cachedBounds); }; } From b63313b091e2efa7c776fa5714178913a607e89a Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Tue, 8 Jan 2019 01:19:38 +1100 Subject: [PATCH 025/153] feat: Replace taskbar icon with Parity Ethereum Fether instead of Parity icon --- .../config/icons/parity-ethereum-fether-icon.png | Bin 0 -> 590 bytes .../icons/parity-ethereum-fether-icon@2.png | Bin 0 -> 1417 bytes .../icons/parity-ethereum-fether-icon@3.png | Bin 0 -> 2292 bytes .../app/options/config/icons/parity-icon.png | Bin 2859 -> 0 bytes .../app/options/config/icons/parity-icon@2x.png | Bin 5742 -> 0 bytes .../src/main/app/options/config/index.js | 4 ++-- 6 files changed, 2 insertions(+), 2 deletions(-) create mode 100644 packages/fether-electron/src/main/app/options/config/icons/parity-ethereum-fether-icon.png create mode 100644 packages/fether-electron/src/main/app/options/config/icons/parity-ethereum-fether-icon@2.png create mode 100644 packages/fether-electron/src/main/app/options/config/icons/parity-ethereum-fether-icon@3.png delete mode 100644 packages/fether-electron/src/main/app/options/config/icons/parity-icon.png delete mode 100644 packages/fether-electron/src/main/app/options/config/icons/parity-icon@2x.png diff --git a/packages/fether-electron/src/main/app/options/config/icons/parity-ethereum-fether-icon.png b/packages/fether-electron/src/main/app/options/config/icons/parity-ethereum-fether-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..00dc72e2299b80e8f7319f946c351336d64e20fe GIT binary patch literal 590 zcmV-U06$Q5YMaTdE0ozGL zK~y-)jZ;Bu6JZd2-)wOWnEg#||7sN1UuAwcpqfK+%Y$8n$z zs4z_vN471GeU0S05CVeaD1bU7eA?MT+iSzN>!|Ek@b=9LB5+dy@JP;n*xp7mnS|f= zp$G->cpRJWHlqk0DgbWD+1Nk~KN=03o&7|qR6;tPhOX;T1XBut>)punJQy1rP*oLA zi$x?g4Rzaw`O(B!Duu^|IRrrvCKy-3Q6iDR?THDjuB{?_Hw&{|Ms|7{)q^kietL>a zu^28ce)o)^0H}6@U+3rWJRdXnW-xqt7>&*vxm*rQuU_KH$Owjp2E+XpNInZ6xY=y7 zY?}0ZpCq}sxJ2vlkas30={U!-9(0f#m9u|?fQDi4_~eB5^Laj*pQr1(QG&`SLWpkw zmV5S6RouvAP_2H&gV{WG_x7M^ntTC62yxI?%9drZP?+m0<-TSj$*ryT{mt~BcK%HA cMU6coi!RC@pb1r|v} zK~z}7y_aiDm317)zmIklMaocfh__S}(#(}2#%ilgMRd0EmNu`i)LeMQA+2eGptIa? z_QEx{*pi8OSq5GZ^R96<5O1J34`N(A2wu+N96g_22xO+`d3aI(H_!8IzvuV={=UDv zAs+{jVHg4oNkNhZN*XC?f}~-RdP*`R)kwM|>4>CrlCDdtG7Q7pqNB|RXn6(#SwIce zPaTj01V5{*trzw0^vSEJY#tn z@X(6Zrluw$-jC#$0|%^#JArqf2Vp#Kxugq{I-9XnQc|K_>AU50KGJuaH_PR6$^GOBj}5~(_b=<4eQrwolP6Euv113b=gtMdURgH(<*<*Pn;lb%^I$il>v~vaT6W={1_iKfjf8Z;P!a%TBG4O z&|W|gP;DmN*w{!?ax#mTECJxrqeq-MdzKCzJCeRT1Gn4F%2lff2nc9(hsn7M^l2w) zfTSL#QGfBGX3d?Tzow7 z@m~W_bm0O)!MzFY)0f}#^4OEHhc2(ahKzQE3<>3y-A;OXI+8eh?!0Me$yWg8<>#{@ zDT$hzr;Tvx^cmP}Hd0bjaJpP1Zb(8BlE}L?9~} zaN^`ix&#Ce_SR4e3yZMZ?L<$UL{M-rW5!2xsax(xwrKYkoEe(Kq^A{kAWy_xy&QYUB)5*UJlE^xEkcErCB(QrA_U+$~%jvS@ zf(&0SC@d;!{hl^`25$}+$REYU)YjG#J#i9}7#Ti_-5D9YH*yqX$BpOl&gXMMqA zkH-waN0v+RiIXRZS-O;pn}2ugd-eBP>q1$1Im3p(L#NLE96NT*jQZA6Y`GcL)z!7O z<5QpepWBv^pDxF zEhAY&LjwyJEh4|55U;>bvrHR<%@laJ&g(T+9Utra8 zCotyOJB=5tVPTT;%_ifVoE&*P9`)XRx}N_9 XQzc~FSC;b#00000NkvXXu0mjf^Sq!t literal 0 HcmV?d00001 diff --git a/packages/fether-electron/src/main/app/options/config/icons/parity-ethereum-fether-icon@3.png b/packages/fether-electron/src/main/app/options/config/icons/parity-ethereum-fether-icon@3.png new file mode 100644 index 0000000000000000000000000000000000000000..1d7435a64de4c028a1d5e9073dd1e141d54f7950 GIT binary patch literal 2292 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 Q@ZZ_gq%-_Vv7O;8u^FEi~`+F{% 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 diff --git a/packages/fether-electron/src/main/app/options/config/index.js b/packages/fether-electron/src/main/app/options/config/index.js index 3946914c1..519de3828 100644 --- a/packages/fether-electron/src/main/app/options/config/index.js +++ b/packages/fether-electron/src/main/app/options/config/index.js @@ -19,8 +19,8 @@ const INDEX_HTML_PATH = // Icon path differs when started with `yarn electron` or `yarn start` const ICON_PATH = process.env.ELECTRON_START_ICON || process.env.SKIP_PREFLIGHT_CHECK - ? 'src/main/app/options/config/icons/parity-icon.png' - : path.join(__dirname, 'icons', 'parity-icon.png'); + ? 'src/main/app/options/config/icons/parity-ethereum-fether-icon.png' + : path.join(__dirname, 'icons', 'parity-ethereum-fether-icon.png'); const shouldUseDevTools = process.env.NODE_ENV !== 'production'; From 666bbb54c17d06935d2123d28d4645448b443b93 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Tue, 8 Jan 2019 09:08:32 +1100 Subject: [PATCH 026/153] feat: Add method for fetherApp event listener handlers setup and move pino logs into them --- .../fether-electron/src/main/app/index.js | 86 +++++++++++++++---- 1 file changed, 68 insertions(+), 18 deletions(-) diff --git a/packages/fether-electron/src/main/app/index.js b/packages/fether-electron/src/main/app/index.js index 4c2f8cbcc..02590a15b 100644 --- a/packages/fether-electron/src/main/app/index.js +++ b/packages/fether-electron/src/main/app/index.js @@ -28,15 +28,13 @@ class FetherApp { throw new Error('Unable to initialise Fether app more than once'); } - pino.info( - `Starting ${productName} (${ - options.withTaskbar ? 'with' : 'without' - } taskbar)...` - ); - this.fetherApp.app = electronApp; this.fetherApp.options = options; + this.addListeners(); + + this.fetherApp.emit('create-app'); + if (options.withTaskbar) { this.createWindow(); this.loadTaskbar(); @@ -50,7 +48,7 @@ class FetherApp { this.finalise(); } - this.fetherApp.emit('ready'); + this.fetherApp.emit('after-create-app'); }; finalise = () => { @@ -103,13 +101,15 @@ class FetherApp { this.fetherApp.window.on('closed', () => { this.fetherApp.window = null; + + this.fetherApp.emit('closed-window'); }); }; loadTaskbar = () => { const { app, options } = this.fetherApp; - pino.info('Configuring Fether taskbar...'); + this.fetherApp.emit('load-taskbar'); if (app.dock && !options.showDockIcon) { app.dock.hide(); @@ -139,8 +139,6 @@ class FetherApp { createWindow = () => { const { options } = this.fetherApp; - pino.info('Creating Fether window'); - this.fetherApp.emit('create-window'); this.fetherApp.window = new BrowserWindow(options); @@ -170,8 +168,6 @@ class FetherApp { tray } = this.fetherApp; - pino.info('Showing Fether window'); - if (supportsTrayHighlightState) { tray.setHighlightMode('always'); } @@ -180,7 +176,7 @@ class FetherApp { this.createWindow(); } - this.fetherApp.emit('show'); + this.fetherApp.emit('show-window'); if (trayPos && trayPos.x !== 0) { // Cache the bounds @@ -216,7 +212,7 @@ class FetherApp { this.fetherApp.window.setPosition(x, y); this.fetherApp.window.show(); - this.fetherApp.emit('after-show'); + this.fetherApp.emit('after-show-window'); }; hideWindow = () => { @@ -230,18 +226,18 @@ class FetherApp { return; } - this.fetherApp.emit('hide'); + this.fetherApp.emit('hide-window'); this.fetherApp.window.hide(); - this.fetherApp.emit('after-hide'); + this.fetherApp.emit('after-hide-window'); }; windowClear = () => { delete this.fetherApp.window; - this.fetherApp.emit('after-close'); + this.fetherApp.emit('after-window-close'); }; emitBlur = () => { - this.fetherApp.emit('focus-lost'); + this.fetherApp.emit('blur-window'); }; clickedTray = (e, bounds) => { @@ -261,6 +257,60 @@ class FetherApp { this.fetherApp.cachedBounds = bounds || cachedBounds; this.showWindow(this.fetherApp.cachedBounds); }; + + addListeners = () => { + this.fetherApp.on('create-app', () => { + pino.info( + `Starting ${productName} (${ + this.fetherApp.options.withTaskbar ? 'with' : 'without' + } taskbar)...` + ); + }); + + this.fetherApp.on('after-create-app', () => { + pino.info(`Ready to use ${productName}`); + }); + + this.fetherApp.on('create-window', () => { + pino.info('Creating window'); + }); + + this.fetherApp.on('after-create-window', () => { + pino.info('Finished creating window'); + }); + + this.fetherApp.on('show-window', () => { + pino.info('Showing window'); + }); + + this.fetherApp.on('after-show-window', () => { + pino.info('Finished showing window'); + }); + + this.fetherApp.on('hide-window', () => { + pino.info('Hiding window on blur since not on top'); + }); + + this.fetherApp.on('after-hide-window', () => { + pino.info('Finished hiding window'); + }); + + this.fetherApp.on('blur-window', () => { + pino.info('Blur window since lost focus when on top'); + }); + + this.fetherApp.on('after-closed-window', () => { + pino.info('Reset window since it was closed'); + }); + + this.fetherApp.on('after-close-window', () => { + pino.info('Deleted window upon close'); + }); + + this.fetherApp.on('load-taskbar', () => { + pino.info('Configuring taskbar for the window'); + }); + }; } export default FetherApp; From 57e3c7ee3db0db61eff49e2b7598ba4eb70bf442 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Tue, 8 Jan 2019 09:34:31 +1100 Subject: [PATCH 027/153] feat: Add EventListener error listener --- packages/fether-electron/src/main/app/index.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/packages/fether-electron/src/main/app/index.js b/packages/fether-electron/src/main/app/index.js index 02590a15b..ea8a99ef5 100644 --- a/packages/fether-electron/src/main/app/index.js +++ b/packages/fether-electron/src/main/app/index.js @@ -25,7 +25,10 @@ class FetherApp { create = (electronApp, options) => { if (hasCalledInitFetherApp) { - throw new Error('Unable to initialise Fether app more than once'); + this.fetherApp.emit( + 'error', + new Error('Unable to initialise Fether app more than once') + ); } this.fetherApp.app = electronApp; @@ -310,6 +313,10 @@ class FetherApp { this.fetherApp.on('load-taskbar', () => { pino.info('Configuring taskbar for the window'); }); + + this.fetherApp.on('error', error => { + console.error(error); + }); }; } From f29672ad1e48b7915be9ebddc8eb9db55a2ec987 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Tue, 8 Jan 2019 10:03:33 +1100 Subject: [PATCH 028/153] fix: Fix so that it shows the window automatically when loaded in taskbar mode --- packages/fether-electron/src/main/app/index.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/fether-electron/src/main/app/index.js b/packages/fether-electron/src/main/app/index.js index ea8a99ef5..11765943a 100644 --- a/packages/fether-electron/src/main/app/index.js +++ b/packages/fether-electron/src/main/app/index.js @@ -42,6 +42,7 @@ class FetherApp { this.createWindow(); this.loadTaskbar(); this.finalise(); + this.showWindow(); } else { this.fetherApp.window = new BrowserWindow(options); From c8e7b90c1d1bcc17e399b2b04cce99bde6b9cac3 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Tue, 8 Jan 2019 11:42:04 +1100 Subject: [PATCH 029/153] fix: Fix naming of event listeners so they match. Reorder in order they are used --- .../fether-electron/src/main/app/index.js | 24 ++++++++----------- yarn.lock | 5 ++++ 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/packages/fether-electron/src/main/app/index.js b/packages/fether-electron/src/main/app/index.js index 11765943a..e1842eccc 100644 --- a/packages/fether-electron/src/main/app/index.js +++ b/packages/fether-electron/src/main/app/index.js @@ -106,7 +106,7 @@ class FetherApp { this.fetherApp.window.on('closed', () => { this.fetherApp.window = null; - this.fetherApp.emit('closed-window'); + this.fetherApp.emit('after-closed-window'); }); }; @@ -237,7 +237,7 @@ class FetherApp { windowClear = () => { delete this.fetherApp.window; - this.fetherApp.emit('after-window-close'); + this.fetherApp.emit('after-close-window'); }; emitBlur = () => { @@ -271,10 +271,6 @@ class FetherApp { ); }); - this.fetherApp.on('after-create-app', () => { - pino.info(`Ready to use ${productName}`); - }); - this.fetherApp.on('create-window', () => { pino.info('Creating window'); }); @@ -283,6 +279,10 @@ class FetherApp { pino.info('Finished creating window'); }); + this.fetherApp.on('load-taskbar', () => { + pino.info('Configuring taskbar for the window'); + }); + this.fetherApp.on('show-window', () => { pino.info('Showing window'); }); @@ -291,6 +291,10 @@ class FetherApp { pino.info('Finished showing window'); }); + this.fetherApp.on('after-create-app', () => { + pino.info(`Ready to use ${productName}`); + }); + this.fetherApp.on('hide-window', () => { pino.info('Hiding window on blur since not on top'); }); @@ -303,18 +307,10 @@ class FetherApp { pino.info('Blur window since lost focus when on top'); }); - this.fetherApp.on('after-closed-window', () => { - pino.info('Reset window since it was closed'); - }); - this.fetherApp.on('after-close-window', () => { pino.info('Deleted window upon close'); }); - this.fetherApp.on('load-taskbar', () => { - pino.info('Configuring taskbar for the window'); - }); - this.fetherApp.on('error', error => { console.error(error); }); diff --git a/yarn.lock b/yarn.lock index 3ee8d0e1e..529eb62e9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12326,6 +12326,11 @@ pkg-up@2.0.0: dependencies: find-up "^2.1.0" +pkill@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/pkill/-/pkill-2.0.0.tgz#7745bbbfe7c439353f48591d4165090d10b10370" + integrity sha1-d0W7v+fEOTU/SFkdQWUJDRCxA3A= + please-upgrade-node@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/please-upgrade-node/-/please-upgrade-node-3.1.1.tgz#ed320051dfcc5024fae696712c8288993595e8ac" From 794ae5c60bf9ecd21a61770ee2ba07b617ba77ec Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Tue, 8 Jan 2019 13:12:04 +1100 Subject: [PATCH 030/153] feat: Add security configuration options to Electron. Add progress bar. Add tabbing id. * Developer experience - Add progress bar that appears on the Docker icon (particularly useful for those with slow connection or local machine) * Add tabbing identifier set to 'parity' so it groups projects with same identifier * Security - Electron window setContentProtection to true to prevent other apps being able to access it * Security - webPreferences.enableRemoteModule to false to prevent unsolicited access * Add shadow to taskbar app --- packages/fether-electron/src/main/app/index.js | 11 +++++++++++ .../src/main/app/options/config/index.js | 6 +++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/packages/fether-electron/src/main/app/index.js b/packages/fether-electron/src/main/app/index.js index e1842eccc..15d833828 100644 --- a/packages/fether-electron/src/main/app/index.js +++ b/packages/fether-electron/src/main/app/index.js @@ -40,22 +40,33 @@ class FetherApp { if (options.withTaskbar) { this.createWindow(); + this.fetherApp.window.setProgressBar(0.4); this.loadTaskbar(); + this.fetherApp.window.setProgressBar(0.6); this.finalise(); + this.fetherApp.window.setProgressBar(0.8); this.showWindow(); + this.fetherApp.window.setProgressBar(1.0); } else { this.fetherApp.window = new BrowserWindow(options); + this.fetherApp.window.setProgressBar(0.4); // Opens file:///path/to/build/index.html in prod mode, or whatever is // passed to ELECTRON_START_URL this.fetherApp.window.loadURL(options.index); this.finalise(); + this.fetherApp.window.setProgressBar(1.0); } + this.fetherApp.window.setProgressBar(-1); + this.fetherApp.emit('after-create-app'); }; finalise = () => { + // Security to prevent window contents from being captured by other apps + this.fetherApp.window.setContentProtection(true); + // Set options for @parity/electron parityElectron({ logger: namespace => log => Pino({ name: namespace }).info(log) diff --git a/packages/fether-electron/src/main/app/options/config/index.js b/packages/fether-electron/src/main/app/options/config/index.js index 519de3828..c6414ee8b 100644 --- a/packages/fether-electron/src/main/app/options/config/index.js +++ b/packages/fether-electron/src/main/app/options/config/index.js @@ -24,14 +24,17 @@ const ICON_PATH = const shouldUseDevTools = process.env.NODE_ENV !== 'production'; +// API docs: https://electronjs.org/docs/api/browser-window const DEFAULT_OPTIONS = { frame: true, height: 640, index: INDEX_HTML_PATH, resizable: false, show: true, + tabbingIdentifier: 'parity', webPreferences: { - devTools: shouldUseDevTools // Security + devTools: shouldUseDevTools, // Security + enableRemoteModule: false }, width: 360, withTaskbar: false @@ -43,6 +46,7 @@ const windowPosition = const TASKBAR_OPTIONS = { dir: staticPath, frame: false, + hasShadow: true, height: 464, icon: ICON_PATH, show: false, // Run showWindow later when taskbar has loaded in FetherApp From 34e52b11334f52f461ac53cd061d5d6a7b504491 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Tue, 8 Jan 2019 14:09:56 +1100 Subject: [PATCH 031/153] refactor: Add newlines so steps are readable --- packages/fether-electron/src/main/app/index.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/fether-electron/src/main/app/index.js b/packages/fether-electron/src/main/app/index.js index 15d833828..e2b2a4a3a 100644 --- a/packages/fether-electron/src/main/app/index.js +++ b/packages/fether-electron/src/main/app/index.js @@ -41,10 +41,13 @@ class FetherApp { if (options.withTaskbar) { this.createWindow(); this.fetherApp.window.setProgressBar(0.4); + this.loadTaskbar(); this.fetherApp.window.setProgressBar(0.6); + this.finalise(); this.fetherApp.window.setProgressBar(0.8); + this.showWindow(); this.fetherApp.window.setProgressBar(1.0); } else { @@ -54,12 +57,12 @@ class FetherApp { // Opens file:///path/to/build/index.html in prod mode, or whatever is // passed to ELECTRON_START_URL this.fetherApp.window.loadURL(options.index); + this.finalise(); this.fetherApp.window.setProgressBar(1.0); } this.fetherApp.window.setProgressBar(-1); - this.fetherApp.emit('after-create-app'); }; From 41e1b03e884dd31cb82a12c81e3f7692cfa5501e Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Wed, 9 Jan 2019 12:42:56 +1100 Subject: [PATCH 032/153] feat: Makde body element draggable See https://electronjs.org/docs/api/frameless-window#draggable-region --- packages/fether-react/src/assets/sass/shared/_basics.scss | 2 ++ yarn.lock | 5 ----- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/packages/fether-react/src/assets/sass/shared/_basics.scss b/packages/fether-react/src/assets/sass/shared/_basics.scss index 0b694663a..2600ff390 100644 --- a/packages/fether-react/src/assets/sass/shared/_basics.scss +++ b/packages/fether-react/src/assets/sass/shared/_basics.scss @@ -14,6 +14,8 @@ body { font-size: ms(0); line-height: ms(0) * 1.3; overflow-y: hidden; + /* https://electronjs.org/docs/api/frameless-window#draggable-region */ + -webkit-app-region: drag; } .hidden { diff --git a/yarn.lock b/yarn.lock index 529eb62e9..3ee8d0e1e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12326,11 +12326,6 @@ pkg-up@2.0.0: dependencies: find-up "^2.1.0" -pkill@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/pkill/-/pkill-2.0.0.tgz#7745bbbfe7c439353f48591d4165090d10b10370" - integrity sha1-d0W7v+fEOTU/SFkdQWUJDRCxA3A= - please-upgrade-node@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/please-upgrade-node/-/please-upgrade-node-3.1.1.tgz#ed320051dfcc5024fae696712c8288993595e8ac" From aa232aeafcff32d087e33315396c0247d821c8a9 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Wed, 9 Jan 2019 13:47:45 +1100 Subject: [PATCH 033/153] feat: Configure window to be alwaysOnTop --- packages/fether-electron/src/main/app/options/config/index.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/fether-electron/src/main/app/options/config/index.js b/packages/fether-electron/src/main/app/options/config/index.js index c6414ee8b..552e3ed56 100644 --- a/packages/fether-electron/src/main/app/options/config/index.js +++ b/packages/fether-electron/src/main/app/options/config/index.js @@ -26,6 +26,7 @@ const shouldUseDevTools = process.env.NODE_ENV !== 'production'; // API docs: https://electronjs.org/docs/api/browser-window const DEFAULT_OPTIONS = { + alwaysOnTop: true, frame: true, height: 640, index: INDEX_HTML_PATH, From 17c4a2bc4e4bd4c6767be9dd9d24df3f597f43a4 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Wed, 9 Jan 2019 18:27:18 +1100 Subject: [PATCH 034/153] fix: Save window and restore within bounds of tray when restored --- packages/fether-electron/package.json | 1 + .../fether-electron/src/main/app/index.js | 159 ++++++++++++++---- yarn.lock | 8 + 3 files changed, 138 insertions(+), 30 deletions(-) diff --git a/packages/fether-electron/package.json b/packages/fether-electron/package.json index bc9935ded..5c46c1385 100644 --- a/packages/fether-electron/package.json +++ b/packages/fether-electron/package.json @@ -43,6 +43,7 @@ "commander": "^2.15.1", "commander-remaining-args": "^1.2.0", "electron-positioner": "^4.1.0", + "electron-settings": "^3.2.0", "extend": "^3.0.2", "fether-react": "^0.1.2", "pino": "^4.16.1", diff --git a/packages/fether-electron/src/main/app/index.js b/packages/fether-electron/src/main/app/index.js index e2b2a4a3a..b7d9e7605 100644 --- a/packages/fether-electron/src/main/app/index.js +++ b/packages/fether-electron/src/main/app/index.js @@ -6,6 +6,7 @@ import parityElectron from '@parity/electron'; import electron, { Tray } from 'electron'; import Positioner from 'electron-positioner'; +import settings from 'electron-settings'; import events from 'events'; import { productName } from '../../../electron-builder.json'; @@ -64,6 +65,12 @@ class FetherApp { this.fetherApp.window.setProgressBar(-1); this.fetherApp.emit('after-create-app'); + + this.fetherApp.window.on('moved', () => { + this.saveWindowPosition(); + + this.fetherApp.emit('after-moved-window-position-saved'); + }); }; finalise = () => { @@ -178,13 +185,7 @@ class FetherApp { }; showWindow = trayPos => { - const { - cachedBounds, - options, - positioner, - supportsTrayHighlightState, - tray - } = this.fetherApp; + const { supportsTrayHighlightState, tray } = this.fetherApp; if (supportsTrayHighlightState) { tray.setHighlightMode('always'); @@ -196,6 +197,106 @@ class FetherApp { this.fetherApp.emit('show-window'); + const calculatedWindowPosition = this.calculateWindowPosition(trayPos); + const trayHeight = Math.min( + calculatedWindowPosition.x, + calculatedWindowPosition.y + ); + const loadedWindowPosition = this.loadWindowPosition(); + const fixedWindowPosition = this.fixWindowPosition( + trayHeight, + loadedWindowPosition + ); + + /** + * Since the user may change the taskbar tray to be on any side of the screen. + * If the user moved the window out of where the tray would be in the screen resolution bounds. + * Restore the window so it is fully visible adjacent to where the tray would be. + */ + const x = + (fixedWindowPosition && fixedWindowPosition.x) || + (loadedWindowPosition && loadedWindowPosition.x) || + calculatedWindowPosition.x; + const y = + (fixedWindowPosition && fixedWindowPosition.y) || + (loadedWindowPosition && loadedWindowPosition.y) || + calculatedWindowPosition.y; + + this.fetherApp.window.setPosition(x, y); + this.fetherApp.window.show(); + + this.fetherApp.emit('after-show-window'); + }; + + hideWindow = () => { + const { supportsTrayHighlightState, tray } = this.fetherApp; + + if (supportsTrayHighlightState) { + tray.setHighlightMode('never'); + } + + if (!this.fetherApp.window) { + return; + } + + this.fetherApp.emit('hide-window'); + this.fetherApp.window.hide(); + this.fetherApp.emit('after-hide-window'); + }; + + fixWindowPosition = (trayHeight, loadedWindowPosition) => { + if (!loadedWindowPosition) { + return; + } + + const newPosition = { + x: undefined, + y: undefined + }; + + const windowResolution = { + x: this.fetherApp.positioner.calculate('bottomRight').x, + y: this.fetherApp.positioner.calculate('bottomRight').y + }; + + /** + * Assume that the taskbar tray could have been on the any side of the screen with + * the tray hidden when they last moved the window and its position was saved. + * Restore the window so it would be fully visible and not obstructed by the tray + */ + if (loadedWindowPosition.x < trayHeight) { + newPosition.x = trayHeight; + } + + if (loadedWindowPosition.y < trayHeight) { + newPosition.y = trayHeight; + } + + if (loadedWindowPosition.y >= windowResolution.x - trayHeight) { + newPosition.x = windowResolution.x - trayHeight; + } + + if (loadedWindowPosition.y >= windowResolution.y - trayHeight) { + newPosition.y = windowResolution.y - trayHeight; + } + + return newPosition; + }; + + loadWindowPosition = () => { + if (!settings.has('position.x') && !settings.has('position.y')) { + return; + } + + return { + x: settings.get('position.x'), + y: settings.get('position.y') + }; + }; + + calculateWindowPosition = trayPos => { + const { cachedBounds, options, positioner, tray } = this.fetherApp; + if (trayPos && trayPos.x !== 0) { // Cache the bounds this.fetherApp.cachedBounds = trayPos; @@ -224,29 +325,10 @@ class FetherApp { trayPos ); - const x = options.x ? options.x : position.x; - const y = options.y ? options.y : position.y; - - this.fetherApp.window.setPosition(x, y); - this.fetherApp.window.show(); - - this.fetherApp.emit('after-show-window'); - }; - - hideWindow = () => { - const { supportsTrayHighlightState, tray } = this.fetherApp; - - if (supportsTrayHighlightState) { - tray.setHighlightMode('never'); - } - - if (!this.fetherApp.window) { - return; - } - - this.fetherApp.emit('hide-window'); - this.fetherApp.window.hide(); - this.fetherApp.emit('after-hide-window'); + return { + x: options.x ? options.x : position.x, + y: options.y ? options.y : position.y + }; }; windowClear = () => { @@ -276,6 +358,15 @@ class FetherApp { this.showWindow(this.fetherApp.cachedBounds); }; + saveWindowPosition = () => { + const position = this.fetherApp.window.getPosition(); + + settings.set('position', { + x: position[0], + y: position[1] + }); + }; + addListeners = () => { this.fetherApp.on('create-app', () => { pino.info( @@ -321,6 +412,14 @@ class FetherApp { pino.info('Blur window since lost focus when on top'); }); + this.fetherApp.on('after-moved-window-position-saved', () => { + pino.info( + `Saved position of window to (x: ${settings.get( + 'position.x' + )}, y: ${settings.get('position.y')}) after move` + ); + }); + this.fetherApp.on('after-close-window', () => { pino.info('Deleted window upon close'); }); diff --git a/yarn.lock b/yarn.lock index 3ee8d0e1e..2447d6966 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6336,6 +6336,14 @@ electron-publish@20.29.0: lazy-val "^1.0.3" mime "^2.3.1" +electron-settings@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/electron-settings/-/electron-settings-3.2.0.tgz#01461e153f95b6f18adbe0c360c70898eb0f43c3" + integrity sha512-7U+vDKd5Gch4Z9K6FjGq80eB3Anwz2GuPc2h/6hOiuvZrS1w+UNPcAA0oAU8G1s9sWAVEadCsr4ZJR6J4iTdzA== + dependencies: + clone "^2.1.1" + jsonfile "^4.0.0" + electron-to-chromium@^1.2.7, electron-to-chromium@^1.3.47: version "1.3.50" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.50.tgz#7438b76f92b41b919f3fbdd350fbd0757dacddf7" From 0bf4455b8ce790b12a69c7fee6118db96e9163d9 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Thu, 10 Jan 2019 07:52:42 +1100 Subject: [PATCH 035/153] WIP: Fixes window position when screen resolution reduced. Restores to saved position after hide --- .../fether-electron/src/main/app/index.js | 135 ++++++++++++++---- 1 file changed, 105 insertions(+), 30 deletions(-) diff --git a/packages/fether-electron/src/main/app/index.js b/packages/fether-electron/src/main/app/index.js index b7d9e7605..18a0f33ac 100644 --- a/packages/fether-electron/src/main/app/index.js +++ b/packages/fether-electron/src/main/app/index.js @@ -67,7 +67,76 @@ class FetherApp { this.fetherApp.emit('after-create-app'); this.fetherApp.window.on('moved', () => { - this.saveWindowPosition(); + const { previousWindowResolution } = this.fetherApp; + const currentWindowResolution = this.getWindowResolution(); + console.log('previousWindowResolution: ', previousWindowResolution); + console.log('currentWindowResolution: ', currentWindowResolution); + + // Update window resolution + if ( + !previousWindowResolution || + (previousWindowResolution && + previousWindowResolution.x !== currentWindowResolution.x) || + (previousWindowResolution && + previousWindowResolution.y !== currentWindowResolution.y) + ) { + this.fetherApp.previousWindowResolution = currentWindowResolution; + } + // Get the latest position. The window may have been moved to a different + // screen with smaller resolution. We must move it to prevent cropping. + const position = this.fetherApp.window.getPosition(); + console.log('position', this.fetherApp.window.getPosition()); + const positionStruct = { + x: position[0], + y: position[1] + }; + + const fixedWindowPosition = this.fixWindowPosition(positionStruct); + console.log('fixedWindowPosition: ', fixedWindowPosition); + + const newFixedPosition = { + x: fixedWindowPosition.x || positionStruct.x, + y: fixedWindowPosition.y || positionStruct.y + }; + + /** + * Only move it immediately back into the threshold of screen tray bounds + * if the window resolution reduced due to the Fether window changing onto a + * different screen. This will prevent it from being moved to a position + * where it is cropped. + * Do not do this all the time otherwise it will crash with + * a call stack exceeded if the user keeps trying to move it outside the window bounds + * and it would also prevent the user from moving it to a different screen at all. + */ + if ( + !previousWindowResolution || + (previousWindowResolution && + previousWindowResolution.x > currentWindowResolution.x) || + (previousWindowResolution && + previousWindowResolution.y > currentWindowResolution.y) + ) { + console.log('Different resolution detected'); + // Move it to the fixed window x-coordinate position if that was fixed + if (fixedWindowPosition.x) { + this.fetherApp.window.setPosition( + fixedWindowPosition.x, + positionStruct.y, + true + ); + } + + // Move it to the fixed window x-coordinate position if that was fixed + if (fixedWindowPosition.y) { + this.fetherApp.window.setPosition( + positionStruct.x, + fixedWindowPosition.y, + true + ); + } + } + + console.log('setPosition', this.fetherApp.window.getPosition()); + this.saveWindowPosition(newFixedPosition || positionStruct); this.fetherApp.emit('after-moved-window-position-saved'); }); @@ -198,15 +267,12 @@ class FetherApp { this.fetherApp.emit('show-window'); const calculatedWindowPosition = this.calculateWindowPosition(trayPos); - const trayHeight = Math.min( + this.fetherApp.trayDepth = Math.min( calculatedWindowPosition.x, calculatedWindowPosition.y ); const loadedWindowPosition = this.loadWindowPosition(); - const fixedWindowPosition = this.fixWindowPosition( - trayHeight, - loadedWindowPosition - ); + const fixedWindowPosition = this.fixWindowPosition(loadedWindowPosition); /** * Since the user may change the taskbar tray to be on any side of the screen. @@ -244,40 +310,44 @@ class FetherApp { this.fetherApp.emit('after-hide-window'); }; - fixWindowPosition = (trayHeight, loadedWindowPosition) => { - if (!loadedWindowPosition) { + // Changes the window position if its is moved out of a screen bounds threshold + fixWindowPosition = proposedWindowPosition => { + const { trayDepth } = this.fetherApp; + const { width: windowWidth, height: windowHeight } = this.fetherApp.options; + + if (!proposedWindowPosition) { return; } + console.log('proposedWindowPosition: ', proposedWindowPosition); + const newPosition = { x: undefined, y: undefined }; - const windowResolution = { - x: this.fetherApp.positioner.calculate('bottomRight').x, - y: this.fetherApp.positioner.calculate('bottomRight').y - }; + console.log('XX width, height: ', windowWidth, windowHeight); + console.log('trayDepth: ', trayDepth); + const offsetX = windowWidth + trayDepth; + const offsetY = windowHeight + trayDepth; + console.log('offsetX, offsetY', offsetX, offsetY); - /** - * Assume that the taskbar tray could have been on the any side of the screen with - * the tray hidden when they last moved the window and its position was saved. - * Restore the window so it would be fully visible and not obstructed by the tray - */ - if (loadedWindowPosition.x < trayHeight) { - newPosition.x = trayHeight; + const currentWindowResolution = this.getWindowResolution(); + + if (proposedWindowPosition.x < trayDepth) { + newPosition.x = trayDepth; } - if (loadedWindowPosition.y < trayHeight) { - newPosition.y = trayHeight; + if (proposedWindowPosition.y < trayDepth) { + newPosition.y = trayDepth; } - if (loadedWindowPosition.y >= windowResolution.x - trayHeight) { - newPosition.x = windowResolution.x - trayHeight; + if (proposedWindowPosition.x >= currentWindowResolution.x - trayDepth) { + newPosition.x = currentWindowResolution.x - trayDepth; } - if (loadedWindowPosition.y >= windowResolution.y - trayHeight) { - newPosition.y = windowResolution.y - trayHeight; + if (proposedWindowPosition.y >= currentWindowResolution.y - trayDepth) { + newPosition.y = currentWindowResolution.y - trayDepth; } return newPosition; @@ -331,6 +401,13 @@ class FetherApp { }; }; + getWindowResolution = () => { + return { + x: this.fetherApp.positioner.calculate('bottomRight').x, + y: this.fetherApp.positioner.calculate('bottomRight').y + }; + }; + windowClear = () => { delete this.fetherApp.window; this.fetherApp.emit('after-close-window'); @@ -358,12 +435,10 @@ class FetherApp { this.showWindow(this.fetherApp.cachedBounds); }; - saveWindowPosition = () => { - const position = this.fetherApp.window.getPosition(); - + saveWindowPosition = position => { settings.set('position', { - x: position[0], - y: position[1] + x: position.x, + y: position.y }); }; From 9fe0756381e00d71b47757a5cec8407278a20ff9 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Thu, 10 Jan 2019 09:52:15 +1100 Subject: [PATCH 036/153] WIP: Refactor by moving some code into settings and utils/window --- .../fether-electron/src/main/app/index.js | 114 ++++++++---------- .../src/main/app/settings/index.js | 30 +++++ .../src/main/app/utils/window.js | 53 ++++++++ 3 files changed, 131 insertions(+), 66 deletions(-) create mode 100644 packages/fether-electron/src/main/app/settings/index.js create mode 100644 packages/fether-electron/src/main/app/utils/window.js diff --git a/packages/fether-electron/src/main/app/index.js b/packages/fether-electron/src/main/app/index.js index 18a0f33ac..8bae170de 100644 --- a/packages/fether-electron/src/main/app/index.js +++ b/packages/fether-electron/src/main/app/index.js @@ -6,11 +6,16 @@ import parityElectron from '@parity/electron'; import electron, { Tray } from 'electron'; import Positioner from 'electron-positioner'; -import settings from 'electron-settings'; import events from 'events'; import { productName } from '../../../electron-builder.json'; import Pino from './utils/pino'; +import { getScreenResolution, shouldFixWindowPosition } from './utils/window'; +import { + getSavedWindowPosition, + hasSavedWindowPosition, + saveWindowPosition +} from './settings'; import addMenu from './menu'; import cli from './cli'; import messages from './messages'; @@ -67,21 +72,14 @@ class FetherApp { this.fetherApp.emit('after-create-app'); this.fetherApp.window.on('moved', () => { - const { previousWindowResolution } = this.fetherApp; - const currentWindowResolution = this.getWindowResolution(); - console.log('previousWindowResolution: ', previousWindowResolution); - console.log('currentWindowResolution: ', currentWindowResolution); + const { previousScreenResolution } = this.fetherApp; + const currentScreenResolution = this.calculateScreenResolution(); + + this.fetherApp.previousScreenResolution = getScreenResolution( + previousScreenResolution, + currentScreenResolution + ); - // Update window resolution - if ( - !previousWindowResolution || - (previousWindowResolution && - previousWindowResolution.x !== currentWindowResolution.x) || - (previousWindowResolution && - previousWindowResolution.y !== currentWindowResolution.y) - ) { - this.fetherApp.previousWindowResolution = currentWindowResolution; - } // Get the latest position. The window may have been moved to a different // screen with smaller resolution. We must move it to prevent cropping. const position = this.fetherApp.window.getPosition(); @@ -101,22 +99,19 @@ class FetherApp { /** * Only move it immediately back into the threshold of screen tray bounds - * if the window resolution reduced due to the Fether window changing onto a - * different screen. This will prevent it from being moved to a position - * where it is cropped. - * Do not do this all the time otherwise it will crash with - * a call stack exceeded if the user keeps trying to move it outside the window bounds + * if the screen resolution reduced to prevent it from being cropped. + * Do not call this all the time otherwise it will crash with + * a call stack exceeded if the user keeps trying to move it outside the screen bounds * and it would also prevent the user from moving it to a different screen at all. */ if ( - !previousWindowResolution || - (previousWindowResolution && - previousWindowResolution.x > currentWindowResolution.x) || - (previousWindowResolution && - previousWindowResolution.y > currentWindowResolution.y) + shouldFixWindowPosition( + previousScreenResolution, + currentScreenResolution + ) ) { console.log('Different resolution detected'); - // Move it to the fixed window x-coordinate position if that was fixed + // Move window to the fixed x-coordinate position if that required fixing if (fixedWindowPosition.x) { this.fetherApp.window.setPosition( fixedWindowPosition.x, @@ -125,7 +120,7 @@ class FetherApp { ); } - // Move it to the fixed window x-coordinate position if that was fixed + // Move window to the fixed y-coordinate position if that required fixing if (fixedWindowPosition.y) { this.fetherApp.window.setPosition( positionStruct.x, @@ -136,7 +131,7 @@ class FetherApp { } console.log('setPosition', this.fetherApp.window.getPosition()); - this.saveWindowPosition(newFixedPosition || positionStruct); + saveWindowPosition(newFixedPosition || positionStruct); this.fetherApp.emit('after-moved-window-position-saved'); }); @@ -267,11 +262,16 @@ class FetherApp { this.fetherApp.emit('show-window'); const calculatedWindowPosition = this.calculateWindowPosition(trayPos); + this.fetherApp.trayDepth = Math.min( calculatedWindowPosition.x, calculatedWindowPosition.y ); - const loadedWindowPosition = this.loadWindowPosition(); + + const loadedWindowPosition = hasSavedWindowPosition() + ? getSavedWindowPosition() + : undefined; + const fixedWindowPosition = this.fixWindowPosition(loadedWindowPosition); /** @@ -283,6 +283,7 @@ class FetherApp { (fixedWindowPosition && fixedWindowPosition.x) || (loadedWindowPosition && loadedWindowPosition.x) || calculatedWindowPosition.x; + const y = (fixedWindowPosition && fixedWindowPosition.y) || (loadedWindowPosition && loadedWindowPosition.y) || @@ -310,29 +311,27 @@ class FetherApp { this.fetherApp.emit('after-hide-window'); }; - // Changes the window position if its is moved out of a screen bounds threshold + /** + * Proposes a fixed window position that may be used if the window is moved + * out of the screen bounds threshold. If the window is moved across to a + * second monitor (without screen mirroring) then if the screen is hidden + * and then shown again (by pressing the Fether tray icon), since the + * coordinates of the window are outside the screen bounds the window + * will be restored into the users primary screen. + */ fixWindowPosition = proposedWindowPosition => { const { trayDepth } = this.fetherApp; - const { width: windowWidth, height: windowHeight } = this.fetherApp.options; if (!proposedWindowPosition) { return; } - console.log('proposedWindowPosition: ', proposedWindowPosition); - const newPosition = { x: undefined, y: undefined }; - console.log('XX width, height: ', windowWidth, windowHeight); - console.log('trayDepth: ', trayDepth); - const offsetX = windowWidth + trayDepth; - const offsetY = windowHeight + trayDepth; - console.log('offsetX, offsetY', offsetX, offsetY); - - const currentWindowResolution = this.getWindowResolution(); + const currentScreenResolution = this.calculateScreenResolution(); if (proposedWindowPosition.x < trayDepth) { newPosition.x = trayDepth; @@ -342,28 +341,17 @@ class FetherApp { newPosition.y = trayDepth; } - if (proposedWindowPosition.x >= currentWindowResolution.x - trayDepth) { - newPosition.x = currentWindowResolution.x - trayDepth; + if (proposedWindowPosition.x >= currentScreenResolution.x - trayDepth) { + newPosition.x = currentScreenResolution.x - trayDepth; } - if (proposedWindowPosition.y >= currentWindowResolution.y - trayDepth) { - newPosition.y = currentWindowResolution.y - trayDepth; + if (proposedWindowPosition.y >= currentScreenResolution.y - trayDepth) { + newPosition.y = currentScreenResolution.y - trayDepth; } return newPosition; }; - loadWindowPosition = () => { - if (!settings.has('position.x') && !settings.has('position.y')) { - return; - } - - return { - x: settings.get('position.x'), - y: settings.get('position.y') - }; - }; - calculateWindowPosition = trayPos => { const { cachedBounds, options, positioner, tray } = this.fetherApp; @@ -401,7 +389,7 @@ class FetherApp { }; }; - getWindowResolution = () => { + calculateScreenResolution = () => { return { x: this.fetherApp.positioner.calculate('bottomRight').x, y: this.fetherApp.positioner.calculate('bottomRight').y @@ -435,13 +423,6 @@ class FetherApp { this.showWindow(this.fetherApp.cachedBounds); }; - saveWindowPosition = position => { - settings.set('position', { - x: position.x, - y: position.y - }); - }; - addListeners = () => { this.fetherApp.on('create-app', () => { pino.info( @@ -488,10 +469,11 @@ class FetherApp { }); this.fetherApp.on('after-moved-window-position-saved', () => { + const position = getSavedWindowPosition(); pino.info( - `Saved position of window to (x: ${settings.get( - 'position.x' - )}, y: ${settings.get('position.y')}) after move` + `Saved window position to (x: ${position.x}, y: ${ + position.y + }) after move` ); }); diff --git a/packages/fether-electron/src/main/app/settings/index.js b/packages/fether-electron/src/main/app/settings/index.js new file mode 100644 index 000000000..5ca03557f --- /dev/null +++ b/packages/fether-electron/src/main/app/settings/index.js @@ -0,0 +1,30 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. +// +// SPDX-License-Identifier: BSD-3-Clause + +import settings from 'electron-settings'; + +const hasSavedWindowPosition = () => { + return settings.has('position.x') && settings.has('position.y'); +}; + +const getSavedWindowPosition = () => { + return { + x: settings.get('position.x'), + y: settings.get('position.y') + }; +}; + +/** + * Returns the latest window resolution if it differs from the previous resolution. + * Note that the previous window resolution may be undefined if being changed in settings. + */ +const saveWindowPosition = position => { + settings.set('position', { + x: position.x, + y: position.y + }); +}; + +export { getSavedWindowPosition, hasSavedWindowPosition, saveWindowPosition }; diff --git a/packages/fether-electron/src/main/app/utils/window.js b/packages/fether-electron/src/main/app/utils/window.js new file mode 100644 index 000000000..14f09c67b --- /dev/null +++ b/packages/fether-electron/src/main/app/utils/window.js @@ -0,0 +1,53 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. +// +// SPDX-License-Identifier: BSD-3-Clause + +/** + * Returns the latest window resolution if it differs from the previous resolution. + * Note that the previous window resolution may be undefined if being changed in settings. + */ +const getScreenResolution = ( + previousScreenResolution, + currentScreenResolution +) => { + if ( + !previousScreenResolution || + (previousScreenResolution && + previousScreenResolution.x !== currentScreenResolution.x) || + (previousScreenResolution && + previousScreenResolution.y !== currentScreenResolution.y) + ) { + return currentScreenResolution; + } + return previousScreenResolution; +}; + +/** + * Determine if we need to fix the window position. We will fix the window position if + * the user is changing display resolution since the previousScreenResolution may be undefined, + * or if the new previousScreenResolution was larger than the currentScreenResolution + * to prevent the window moved to a position where it is cropped or not visible at all. + */ +const shouldFixWindowPosition = ( + previousScreenResolution, + currentScreenResolution +) => { + console.log( + 'previous, current: ', + previousScreenResolution, + currentScreenResolution + ); + if ( + !previousScreenResolution || + (previousScreenResolution && + previousScreenResolution.x > currentScreenResolution.x) || + (previousScreenResolution && + previousScreenResolution.y > currentScreenResolution.y) + ) { + return true; + } + return false; +}; + +export { getScreenResolution, shouldFixWindowPosition }; From eb673a8a292f504ed7ada3738a0d9dbfd248e2eb Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Thu, 10 Jan 2019 10:57:55 +1100 Subject: [PATCH 037/153] test: Setup fether-electron tests. Add tests for Fether window --- packages/fether-electron/craco.config.js | 1 + packages/fether-electron/package.json | 3 +- .../src/main/app/utils/window.spec.js | 84 +++++++++++++++++++ 3 files changed, 87 insertions(+), 1 deletion(-) create mode 100644 packages/fether-electron/craco.config.js create mode 100644 packages/fether-electron/src/main/app/utils/window.spec.js diff --git a/packages/fether-electron/craco.config.js b/packages/fether-electron/craco.config.js new file mode 100644 index 000000000..f053ebf79 --- /dev/null +++ b/packages/fether-electron/craco.config.js @@ -0,0 +1 @@ +module.exports = {}; diff --git a/packages/fether-electron/package.json b/packages/fether-electron/package.json index 5c46c1385..ebb2e6544 100644 --- a/packages/fether-electron/package.json +++ b/packages/fether-electron/package.json @@ -36,9 +36,10 @@ "prerelease": "./scripts/revertElectronBug.sh", "release": "electron-builder", "start": "cross-env ELECTRON_START_URL=http://localhost:3000 electron-webpack dev --ws-origins all", - "test": "echo Skipped." + "test": "ln -s ../../../node_modules/react-scripts node_modules/ && cross-env SKIP_PREFLIGHT_CHECK=true craco test; rm node_modules/react-scripts" }, "dependencies": { + "@craco/craco": "^3.2.3", "@parity/electron": "^3.0.1", "commander": "^2.15.1", "commander-remaining-args": "^1.2.0", diff --git a/packages/fether-electron/src/main/app/utils/window.spec.js b/packages/fether-electron/src/main/app/utils/window.spec.js new file mode 100644 index 000000000..39a9a14b7 --- /dev/null +++ b/packages/fether-electron/src/main/app/utils/window.spec.js @@ -0,0 +1,84 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. +// +// SPDX-License-Identifier: BSD-3-Clause + +/* eslint-env jest */ + +import { getScreenResolution, shouldFixWindowPosition } from './window'; + +let smallScreenResolution, largeScreenResolution; + +describe('window resolution', () => { + beforeEach(() => { + smallScreenResolution = { + x: 1024, + y: 768 + }; + + largeScreenResolution = { + x: 1366, + y: 768 + }; + }); + + test('should return previous resolution if it was defined and current resolution is the same', () => { + const previousScreenResolution = largeScreenResolution; + const currentScreenResolution = largeScreenResolution; + const screenResolution = getScreenResolution( + previousScreenResolution, + currentScreenResolution + ); + expect(screenResolution).toEqual(previousScreenResolution); + }); + + test('should return current resolution if either its x or y coordinate differs in the previous resolution', () => { + const previousScreenResolution = largeScreenResolution; + const currentScreenResolution = smallScreenResolution; + const screenResolution = getScreenResolution( + previousScreenResolution, + currentScreenResolution + ); + expect(screenResolution).toEqual(currentScreenResolution); + }); + + test('should return true to change resolution if previousScreenResolution is undefined', () => { + const previousScreenResolution = undefined; + const currentScreenResolution = smallScreenResolution; + const recommendation = shouldFixWindowPosition( + previousScreenResolution, + currentScreenResolution + ); + expect(recommendation).toEqual(true); + }); + + test('should return true to change resolution if either the x or y coordinate of the previousScreenResolution is greater than in the current resolution', () => { + const previousScreenResolution = largeScreenResolution; + const currentScreenResolution = smallScreenResolution; + const recommendation = shouldFixWindowPosition( + previousScreenResolution, + currentScreenResolution + ); + expect(recommendation).toEqual(true); + }); + + test('should return false to not change resolution if current resolution is larger than previous resolution', () => { + const previousScreenResolution = smallScreenResolution; + const currentScreenResolution = largeScreenResolution; + const recommendation = shouldFixWindowPosition( + previousScreenResolution, + currentScreenResolution + ); + expect(recommendation).toEqual(false); + }); + + test('should return false to not change resolution if current resolution is equal to the previous resolution', () => { + const previousScreenResolution = smallScreenResolution; + const currentScreenResolution = smallScreenResolution; + const recommendation = shouldFixWindowPosition( + previousScreenResolution, + currentScreenResolution + ); + expect(recommendation).toEqual(false); + }); +}); From d64bb0982b8e0b3f26f01f7dbd65e90bc9259324 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Fri, 11 Jan 2019 01:47:39 +1100 Subject: [PATCH 038/153] fix: Fix semicolon wrong place --- .../fether-react/src/assets/sass/components/_search-form.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/fether-react/src/assets/sass/components/_search-form.scss b/packages/fether-react/src/assets/sass/components/_search-form.scss index e82467546..e40be708a 100644 --- a/packages/fether-react/src/assets/sass/components/_search-form.scss +++ b/packages/fether-react/src/assets/sass/components/_search-form.scss @@ -15,7 +15,7 @@ font-weight: 400; font-family: $mono; line-height: ms(0) * 1.3; - width: calc(100% - 2rem;); + width: calc(100% - 2rem); opacity: 0.75; padding: 0.6rem 0.5rem 0.5rem; &:focus { From 4ea5ae0264df0853bb2f56482d9e44a8a384e287 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Fri, 11 Jan 2019 01:48:44 +1100 Subject: [PATCH 039/153] WIP: Add classes and elements for no-drag, or no user selection --- .../icons/_parity-ethereum-fether-icon.png | Bin 0 -> 590 bytes .../src/assets/sass/shared/_basics.scss | 24 ++++++++++++++++++ .../src/assets/sass/shared/_form.scss | 1 + 3 files changed, 25 insertions(+) create mode 100644 packages/fether-electron/src/main/app/options/config/icons/_parity-ethereum-fether-icon.png diff --git a/packages/fether-electron/src/main/app/options/config/icons/_parity-ethereum-fether-icon.png b/packages/fether-electron/src/main/app/options/config/icons/_parity-ethereum-fether-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..00dc72e2299b80e8f7319f946c351336d64e20fe GIT binary patch literal 590 zcmV-U06$Q5YMaTdE0ozGL zK~y-)jZ;Bu6JZd2-)wOWnEg#||7sN1UuAwcpqfK+%Y$8n$z zs4z_vN471GeU0S05CVeaD1bU7eA?MT+iSzN>!|Ek@b=9LB5+dy@JP;n*xp7mnS|f= zp$G->cpRJWHlqk0DgbWD+1Nk~KN=03o&7|qR6;tPhOX;T1XBut>)punJQy1rP*oLA zi$x?g4Rzaw`O(B!Duu^|IRrrvCKy-3Q6iDR?THDjuB{?_Hw&{|Ms|7{)q^kietL>a zu^28ce)o)^0H}6@U+3rWJRdXnW-xqt7>&*vxm*rQuU_KH$Owjp2E+XpNInZ6xY=y7 zY?}0ZpCq}sxJ2vlkas30={U!-9(0f#m9u|?fQDi4_~eB5^Laj*pQr1(QG&`SLWpkw zmV5S6RouvAP_2H&gV{WG_x7M^ntTC62yxI?%9drZP?+m0<-TSj$*ryT{mt~BcK%HA cMU Date: Fri, 11 Jan 2019 12:07:28 +1100 Subject: [PATCH 040/153] review-fix: Try to make token cards clickable on account page. Try further drag fixes --- .../src/assets/sass/shared/_basics.scss | 18 +++++++++++------- .../src/assets/sass/shared/_form.scss | 1 - 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/packages/fether-react/src/assets/sass/shared/_basics.scss b/packages/fether-react/src/assets/sass/shared/_basics.scss index 597121295..46711d596 100644 --- a/packages/fether-react/src/assets/sass/shared/_basics.scss +++ b/packages/fether-react/src/assets/sass/shared/_basics.scss @@ -33,24 +33,28 @@ a:visited { } button, -p, input[type='text'], input[type='number'], input[type='tel'], input[type='email'], input[type='password'], input[type='range'], +p, textarea, -.account, -.account_avatar, -.header-nav_left, -.header-nav_right, +.account.-header, /* i.e. account name/address in header that is clickable */ +.account_avatar, /* i.e. on create a new account page */ +.box.-card, /* i.e. account button */ +.form-details-buttons, /* i.e. show/hide transaction details button */ +.feedback, +.footer-feedback, /* i.e. feedback button in header */ +.header-nav_left, /* i.e. back button in header */ +.header-nav_right, /* i.e. menu */ .text { -webkit-app-region: no-drag; } -.footer-feedback, -.header-nav_title, +h1, /* i.e. Send Ether title */ +.account.-header, .status, .text { -webkit-user-select: none; diff --git a/packages/fether-react/src/assets/sass/shared/_form.scss b/packages/fether-react/src/assets/sass/shared/_form.scss index ca4f5ffd1..b179d98ac 100644 --- a/packages/fether-react/src/assets/sass/shared/_form.scss +++ b/packages/fether-react/src/assets/sass/shared/_form.scss @@ -67,7 +67,6 @@ color: transparent; } } - -webkit-app-region: no-drag; } input[type='range'] { From 70ff7eb05166e4bdd3cfb37ebd46bf53750cd596 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Mon, 14 Jan 2019 09:14:10 +1100 Subject: [PATCH 041/153] remove console.logs --- packages/fether-electron/src/main/app/index.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/packages/fether-electron/src/main/app/index.js b/packages/fether-electron/src/main/app/index.js index 8bae170de..87cf85ad2 100644 --- a/packages/fether-electron/src/main/app/index.js +++ b/packages/fether-electron/src/main/app/index.js @@ -83,14 +83,13 @@ class FetherApp { // Get the latest position. The window may have been moved to a different // screen with smaller resolution. We must move it to prevent cropping. const position = this.fetherApp.window.getPosition(); - console.log('position', this.fetherApp.window.getPosition()); + const positionStruct = { x: position[0], y: position[1] }; const fixedWindowPosition = this.fixWindowPosition(positionStruct); - console.log('fixedWindowPosition: ', fixedWindowPosition); const newFixedPosition = { x: fixedWindowPosition.x || positionStruct.x, @@ -110,7 +109,6 @@ class FetherApp { currentScreenResolution ) ) { - console.log('Different resolution detected'); // Move window to the fixed x-coordinate position if that required fixing if (fixedWindowPosition.x) { this.fetherApp.window.setPosition( @@ -130,7 +128,6 @@ class FetherApp { } } - console.log('setPosition', this.fetherApp.window.getPosition()); saveWindowPosition(newFixedPosition || positionStruct); this.fetherApp.emit('after-moved-window-position-saved'); From e38bff0ba4cf274fa9ee7fab929db0c2f7d44ac2 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Mon, 14 Jan 2019 10:19:05 +1100 Subject: [PATCH 042/153] feat: Add automatic opening of DevTools when flag provided --- README.md | 2 ++ .../fether-electron/src/main/app/index.js | 13 ++++++++++ yarn.lock | 24 +++++++++++++++++++ 3 files changed, 39 insertions(+) diff --git a/README.md b/README.md index 6f215ecd3..846c0424e 100644 --- a/README.md +++ b/README.md @@ -115,6 +115,8 @@ yarn start > Troubleshooting: If it hangs on a white screen in Electron even though it has compiled and has been syncing for a long time, then simply choose 'View > Reload' (CMD + R on macOS) from the Electron menu +> Developer Tools: Open developer tools automatically by running `DEBUG=true yarn start` when not in the production environment + # Run without taskbar ```bash diff --git a/packages/fether-electron/src/main/app/index.js b/packages/fether-electron/src/main/app/index.js index 87cf85ad2..89cf200a7 100644 --- a/packages/fether-electron/src/main/app/index.js +++ b/packages/fether-electron/src/main/app/index.js @@ -24,6 +24,8 @@ import ParityEthereum from './parityEthereum'; const { BrowserWindow, ipcMain, session } = electron; const pino = Pino(); +const withDebug = process.env.DEBUG === 'true'; + let hasCalledInitFetherApp = false; class FetherApp { @@ -64,6 +66,8 @@ class FetherApp { // passed to ELECTRON_START_URL this.fetherApp.window.loadURL(options.index); + this.debugSetup(); + this.finalise(); this.fetherApp.window.setProgressBar(1.0); } @@ -134,6 +138,13 @@ class FetherApp { }); }; + // Enable with `DEBUG=true yarn start` and access Developer Tools + debugSetup = () => { + if (withDebug && this.fetherApp.options.webPreferences.devTools) { + this.fetherApp.window.webContents.openDevTools(); + } + }; + finalise = () => { // Security to prevent window contents from being captured by other apps this.fetherApp.window.setContentProtection(true); @@ -242,6 +253,8 @@ class FetherApp { this.fetherApp.window.loadURL(options.index); + this.debugSetup(); + this.fetherApp.emit('after-create-window'); }; diff --git a/yarn.lock b/yarn.lock index 2447d6966..d27b61e2e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2324,6 +2324,11 @@ accepts@~1.3.4, accepts@~1.3.5: mime-types "~2.1.18" negotiator "0.6.1" +accessibility-developer-tools@^2.11.0: + version "2.12.0" + resolved "https://registry.yarnpkg.com/accessibility-developer-tools/-/accessibility-developer-tools-2.12.0.tgz#3da0cce9d6ec6373964b84f35db7cfc3df7ab514" + integrity sha1-PaDM6dbsY3OWS4TzXbfPw996tRQ= + acorn-dynamic-import@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/acorn-dynamic-import/-/acorn-dynamic-import-3.0.0.tgz#901ceee4c7faaef7e07ad2a47e890675da50a278" @@ -6033,6 +6038,15 @@ detect-port-alt@1.1.6: address "^1.0.1" debug "^2.6.0" +devtron@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/devtron/-/devtron-1.4.0.tgz#b5e748bd6e95bbe70bfcc68aae6fe696119441e1" + integrity sha1-tedIvW6Vu+cL/MaKrm/mlhGUQeE= + dependencies: + accessibility-developer-tools "^2.11.0" + highlight.js "^9.3.0" + humanize-plus "^1.8.1" + diff@^3.2.0, diff@^3.3.1, diff@^3.5.0: version "3.5.0" resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" @@ -8355,6 +8369,11 @@ hex-color-regex@^1.1.0: resolved "https://registry.yarnpkg.com/hex-color-regex/-/hex-color-regex-1.1.0.tgz#4c06fccb4602fe2602b3c93df82d7e7dbf1a8a8e" integrity sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ== +highlight.js@^9.3.0: + version "9.13.1" + resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-9.13.1.tgz#054586d53a6863311168488a0f58d6c505ce641e" + integrity sha512-Sc28JNQNDzaH6PORtRLMvif9RSn1mYuOoX3omVjnb0+HbpPygU2ALBI0R/wsiqCb4/fcp07Gdo8g+fhtFrQl6A== + history@^4.7.2: version "4.7.2" resolved "https://registry.yarnpkg.com/history/-/history-4.7.2.tgz#22b5c7f31633c5b8021c7f4a8a954ac139ee8d5b" @@ -8628,6 +8647,11 @@ https-browserify@^1.0.0: resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM= +humanize-plus@^1.8.1: + version "1.8.2" + resolved "https://registry.yarnpkg.com/humanize-plus/-/humanize-plus-1.8.2.tgz#a65b34459ad6367adbb3707a82a3c9f916167030" + integrity sha1-pls0RZrWNnrbs3B6gqPJ+RYWcDA= + husky@^1.0.0-rc.13: version "1.0.0-rc.13" resolved "https://registry.yarnpkg.com/husky/-/husky-1.0.0-rc.13.tgz#49c3cc210bfeac24d4ad272f770b7505c9091828" From 5f4f205f5b0df207254595fc9191506feff9512f Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Tue, 22 Jan 2019 08:45:27 +1100 Subject: [PATCH 043/153] WIP: Saves position windows. Incorrect screen dims being used. Debugging --- .../fether-electron/src/main/app/index.js | 244 +++++++++++++----- 1 file changed, 182 insertions(+), 62 deletions(-) diff --git a/packages/fether-electron/src/main/app/index.js b/packages/fether-electron/src/main/app/index.js index 89cf200a7..837df7c5e 100644 --- a/packages/fether-electron/src/main/app/index.js +++ b/packages/fether-electron/src/main/app/index.js @@ -4,7 +4,7 @@ // SPDX-License-Identifier: BSD-3-Clause import parityElectron from '@parity/electron'; -import electron, { Tray } from 'electron'; +import electron, { screen, Tray } from 'electron'; import Positioner from 'electron-positioner'; import events from 'events'; @@ -76,65 +76,7 @@ class FetherApp { this.fetherApp.emit('after-create-app'); this.fetherApp.window.on('moved', () => { - const { previousScreenResolution } = this.fetherApp; - const currentScreenResolution = this.calculateScreenResolution(); - - this.fetherApp.previousScreenResolution = getScreenResolution( - previousScreenResolution, - currentScreenResolution - ); - - // Get the latest position. The window may have been moved to a different - // screen with smaller resolution. We must move it to prevent cropping. - const position = this.fetherApp.window.getPosition(); - - const positionStruct = { - x: position[0], - y: position[1] - }; - - const fixedWindowPosition = this.fixWindowPosition(positionStruct); - - const newFixedPosition = { - x: fixedWindowPosition.x || positionStruct.x, - y: fixedWindowPosition.y || positionStruct.y - }; - - /** - * Only move it immediately back into the threshold of screen tray bounds - * if the screen resolution reduced to prevent it from being cropped. - * Do not call this all the time otherwise it will crash with - * a call stack exceeded if the user keeps trying to move it outside the screen bounds - * and it would also prevent the user from moving it to a different screen at all. - */ - if ( - shouldFixWindowPosition( - previousScreenResolution, - currentScreenResolution - ) - ) { - // Move window to the fixed x-coordinate position if that required fixing - if (fixedWindowPosition.x) { - this.fetherApp.window.setPosition( - fixedWindowPosition.x, - positionStruct.y, - true - ); - } - - // Move window to the fixed y-coordinate position if that required fixing - if (fixedWindowPosition.y) { - this.fetherApp.window.setPosition( - positionStruct.x, - fixedWindowPosition.y, - true - ); - } - } - - saveWindowPosition(newFixedPosition || positionStruct); - - this.fetherApp.emit('after-moved-window-position-saved'); + this.processMoved(); }); }; @@ -201,6 +143,105 @@ class FetherApp { this.fetherApp.emit('after-closed-window'); }); + + // Reference: http://robmayhew.com/listening-for-events-from-windows-in-electron-tutorial/ + + // Hook WM_SYSCOMMAND + this.fetherApp.window.hookWindowMessage( + Number.parseInt('0x0112'), + (wParam, lParam) => { + let eventName = null; + + if (wParam.readUInt32LE(0) == 0xf060) { + // SC_CLOSE + eventName = 'close'; + } else if (wParam.readUInt32LE(0) == 0xf030) { + // SC_MAXIMIZE + eventName = 'maximize'; + } else if (wParam.readUInt32LE(0) == 0xf020) { + // SC_MINIMIZE + eventName = 'minimize'; + } else if (wParam.readUInt32LE(0) == 0xf120) { + // SC_RESTORE + eventName = 'restored'; + } + + if (eventName !== null) { + console.log('WINDOWS ' + eventName); + } + } + ); + + // WM_EXITSIZEMOVE + this.fetherApp.window.hookWindowMessage( + Number.parseInt('0x0232'), + (wParam, lParam) => { + console.log('Winodws move or resize complete'); + this.processMoved(); + } + ); + }; + + processMoved = () => { + const { previousScreenResolution } = this.fetherApp; + const currentScreenResolution = this.calculateScreenResolution(); + + this.fetherApp.previousScreenResolution = getScreenResolution( + previousScreenResolution, + currentScreenResolution + ); + + // Get the latest position. The window may have been moved to a different + // screen with smaller resolution. We must move it to prevent cropping. + const position = this.fetherApp.window.getPosition(); + + const positionStruct = { + x: position[0], + y: position[1] + }; + + const fixedWindowPosition = this.fixWindowPosition(positionStruct); + + const newFixedPosition = { + x: fixedWindowPosition.x || positionStruct.x, + y: fixedWindowPosition.y || positionStruct.y + }; + + /** + * Only move it immediately back into the threshold of screen tray bounds + * if the screen resolution reduced to prevent it from being cropped. + * Do not call this all the time otherwise it will crash with + * a call stack exceeded if the user keeps trying to move it outside the screen bounds + * and it would also prevent the user from moving it to a different screen at all. + */ + if ( + shouldFixWindowPosition(previousScreenResolution, currentScreenResolution) + ) { + // Move window to the fixed x-coordinate position if that required fixing + if (fixedWindowPosition.x) { + this.fetherApp.window.setPosition( + fixedWindowPosition.x, + positionStruct.y, + true + ); + } + + // Move window to the fixed y-coordinate position if that required fixing + if (fixedWindowPosition.y) { + this.fetherApp.window.setPosition( + positionStruct.x, + fixedWindowPosition.y, + true + ); + } + } + + console.log('newFixedPosition - ', newFixedPosition); + console.log('positionStruct - ', positionStruct); + + saveWindowPosition(newFixedPosition || positionStruct); + + this.fetherApp.emit('after-moved-window-position-saved'); }; loadTaskbar = () => { @@ -273,10 +314,82 @@ class FetherApp { const calculatedWindowPosition = this.calculateWindowPosition(trayPos); + console.log('calculatedWindowPosition: ', calculatedWindowPosition); + + const currentScreenResolution = this.calculateScreenResolution(); + + // https://ourcodeworld.com/articles/read/285/how-to-get-the-screen-width-and-height-in-electron-framework + // + // workAreaSize - dimensions (width and height) of screen without taskbar height + // scaleFactor - float value scale factor of screen (1 is default without zoom) + // rotation - if screen orientation is different to 0 (normal) + + const mainScreen = screen.getPrimaryDisplay(); + const allScreens = screen.getAllDisplays(); + + console.log('screen mainScreen, allScreens', mainScreen, allScreens); + + const mainScreenDimensions = mainScreen.size; + + console.log( + 'mainScreen dimensions: ', + mainScreenDimensions.width, + mainScreenDimensions.height + ); + + const mainScreenScaleFactor = mainScreen.scaleFactor; + const mainScreenWorkAreaSize = mainScreen.workAreaSize; + const mainScreenRotation = mainScreen.rotation; + + console.log('mainScreen scaleFactor: ', mainScreenScaleFactor); + console.log('mainScreen workAreaSize: ', mainScreenWorkAreaSize); + console.log('mainScreen rotation: ', mainScreenRotation); + + // console.log('getMaximumSize', this.fetherApp.window.getMaximumSize()); + // console.log('getContentSize', this.fetherApp.window.getContentSize()); + // console.log('getContentBounds', this.fetherApp.window.getContentBounds()); + // console.log('getBounds', this.fetherApp.window.getBounds()); + + console.log('1aa', calculatedWindowPosition.x); + console.log('2aa', calculatedWindowPosition.y); + console.log('3aa', currentScreenResolution.x); + console.log('4aa', currentScreenResolution.y); + console.log('5aa', this.fetherApp.window.getSize()[0]); + console.log('6aa', this.fetherApp.window.getSize()[1]); + + // Depth depends on resolution. Add minimum incase calculations are + // wrong, for example on a VM with a scaled or resized virtual screen + // where the VM window screen resolution calculated is actually + // the width/height of the VM window relative to the host machine screen, + // rather than the resolution being used in the VM screen. + let platformDepth = 40; // 'win32' + if (process.platform === 'darwin') { + platformDepth = 23; + } + + // Tray could be on top, bottom, left, or right side of screen this.fetherApp.trayDepth = Math.min( - calculatedWindowPosition.x, - calculatedWindowPosition.y + platformDepth, + calculatedWindowPosition.x, // Left tray + calculatedWindowPosition.y, // Top tray + currentScreenResolution.x - + calculatedWindowPosition.x + + this.fetherApp.window.getSize()[0], // Right tray + currentScreenResolution.y - + calculatedWindowPosition.y + + this.fetherApp.window.getSize()[1] // Bottom tray ); + // Note: It is calculating the trayDeth incorrectly based + // on the most recent position, instead of the initial position! + // Consider storing smallest value in electron-settings. + // Consider doing Math.min(this.fetherApp.trayDepth, ...) to + // see if trayDepth already defined upon initial load adjacent + // to the tray (not subsequent position) + // this.fetherApp.trayDepth = Math.min( + // calculatedWindowPosition.x, + // calculatedWindowPosition.y + // ); + console.log('trayDepth setup: ', this.fetherApp.trayDepth); const loadedWindowPosition = hasSavedWindowPosition() ? getSavedWindowPosition() @@ -343,6 +456,9 @@ class FetherApp { const currentScreenResolution = this.calculateScreenResolution(); + console.log('currentScreenResolution: ', currentScreenResolution); + console.log('trayDepth: ', trayDepth); + if (proposedWindowPosition.x < trayDepth) { newPosition.x = trayDepth; } @@ -375,10 +491,13 @@ class FetherApp { // Get the current tray bounds trayPos = tray.getBounds(); } + console.log('tray.getBounds()', tray.getBounds()); // Default the window to the right if `trayPos` bounds are undefined or null. let noBoundsPosition = null; + console.log('platform: ', process.platform); + if ( (trayPos === undefined || (trayPos && trayPos.x === 0)) && options.windowPosition && @@ -480,6 +599,7 @@ class FetherApp { this.fetherApp.on('after-moved-window-position-saved', () => { const position = getSavedWindowPosition(); + pino.info( `Saved window position to (x: ${position.x}, y: ${ position.y From 893cd5ea267ba01589f5240a81171beb33c31cfe Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Tue, 22 Jan 2019 11:46:20 +1100 Subject: [PATCH 044/153] WIP - move window up into view when window bottom of screen and navigate to tall page --- .../fether-electron/src/main/app/index.js | 222 +++++++++--------- 1 file changed, 116 insertions(+), 106 deletions(-) diff --git a/packages/fether-electron/src/main/app/index.js b/packages/fether-electron/src/main/app/index.js index 837df7c5e..66eeec82f 100644 --- a/packages/fether-electron/src/main/app/index.js +++ b/packages/fether-electron/src/main/app/index.js @@ -75,9 +75,20 @@ class FetherApp { this.fetherApp.window.setProgressBar(-1); this.fetherApp.emit('after-create-app'); + // macOS (not Windows) this.fetherApp.window.on('moved', () => { this.processMoved(); }); + + // macOS (not Windows) + this.fetherApp.window.on('resize', () => { + console.log('resize event'); + this.moveWindowUp(); + setTimeout(() => { + console.log('resize general DELAYED'); + this.moveWindowUp(); + }, 5000); + }); }; // Enable with `DEBUG=true yarn start` and access Developer Tools @@ -146,45 +157,90 @@ class FetherApp { // Reference: http://robmayhew.com/listening-for-events-from-windows-in-electron-tutorial/ - // Hook WM_SYSCOMMAND - this.fetherApp.window.hookWindowMessage( - Number.parseInt('0x0112'), - (wParam, lParam) => { - let eventName = null; - - if (wParam.readUInt32LE(0) == 0xf060) { - // SC_CLOSE - eventName = 'close'; - } else if (wParam.readUInt32LE(0) == 0xf030) { - // SC_MAXIMIZE - eventName = 'maximize'; - } else if (wParam.readUInt32LE(0) == 0xf020) { - // SC_MINIMIZE - eventName = 'minimize'; - } else if (wParam.readUInt32LE(0) == 0xf120) { - // SC_RESTORE - eventName = 'restored'; + if (process.platform !== 'darwin') { + // Hook WM_SYSCOMMAND + this.fetherApp.window.hookWindowMessage( + Number.parseInt('0x0112'), + (wParam, lParam) => { + let eventName = null; + + if (wParam.readUInt32LE(0) === 0xf060) { + // SC_CLOSE + eventName = 'close'; + } else if (wParam.readUInt32LE(0) === 0xf030) { + // SC_MAXIMIZE + eventName = 'maximize'; + } else if (wParam.readUInt32LE(0) === 0xf020) { + // SC_MINIMIZE + eventName = 'minimize'; + } else if (wParam.readUInt32LE(0) === 0xf120) { + // SC_RESTORE + eventName = 'restored'; + } + + if (eventName !== null) { + console.log('WINDOWS ' + eventName); + } } + ); - if (eventName !== null) { - console.log('WINDOWS ' + eventName); + // WM_EXITSIZEMOVE + this.fetherApp.window.hookWindowMessage( + Number.parseInt('0x0232'), + (wParam, lParam) => { + console.log('Windows move or resize complete'); + + console.log('resize event (Windows)'); + this.moveWindowUp(); + setTimeout(() => { + console.log('resize Windows DELAYED'); + this.moveWindowUp(); + }, 5000); + + this.processMoved(); // save position } - } - ); + ); + } + }; - // WM_EXITSIZEMOVE - this.fetherApp.window.hookWindowMessage( - Number.parseInt('0x0232'), - (wParam, lParam) => { - console.log('Winodws move or resize complete'); - this.processMoved(); - } - ); + /** + * If the Fether window is restored on a page with a small window height + * and the window is positioned close to the bottom of the screen, then + * we do not want it to crop the bottom of the window when the user navigates + * to a page with a larger window height. So if the user navigates to a page + * with a larger window height that causes it to be cropped, then we will + * automatically move the window upward so it is viewable to the user + */ + moveWindowUp = () => { + console.log('window resized moving back up into view'); + const position = this.fetherApp.window.getPosition(); + + const positionStruct = { + x: position[0], + y: position[1] + }; + + const taskbarDepth = this.taskbarDepth || 40; // Default incase resizes on load + + const currentScreenResolution = this.getScreenResolution(); + const windowHeight = this.fetherApp.window.getSize()[1]; + const maxWindowY = currentScreenResolution.y - windowHeight - taskbarDepth; + const adjustY = positionStruct.y - maxWindowY; + console.log('positionStruct: ', positionStruct); + console.log('currentScreenResolution: ', currentScreenResolution); + console.log('windowHeight: ', windowHeight); + console.log('maxWindowY: ', maxWindowY); + console.log('adjustY: ', adjustY); + + if (adjustY > 0) { + console.log('moved window up'); + this.fetherApp.window.setPosition(positionStruct.x, maxWindowY); + } }; processMoved = () => { const { previousScreenResolution } = this.fetherApp; - const currentScreenResolution = this.calculateScreenResolution(); + const currentScreenResolution = this.getScreenResolution(); this.fetherApp.previousScreenResolution = getScreenResolution( previousScreenResolution, @@ -316,79 +372,18 @@ class FetherApp { console.log('calculatedWindowPosition: ', calculatedWindowPosition); - const currentScreenResolution = this.calculateScreenResolution(); - - // https://ourcodeworld.com/articles/read/285/how-to-get-the-screen-width-and-height-in-electron-framework - // - // workAreaSize - dimensions (width and height) of screen without taskbar height - // scaleFactor - float value scale factor of screen (1 is default without zoom) - // rotation - if screen orientation is different to 0 (normal) - const mainScreen = screen.getPrimaryDisplay(); - const allScreens = screen.getAllDisplays(); - - console.log('screen mainScreen, allScreens', mainScreen, allScreens); + // const allScreens = screen.getAllDisplays(); const mainScreenDimensions = mainScreen.size; - - console.log( - 'mainScreen dimensions: ', - mainScreenDimensions.width, - mainScreenDimensions.height - ); - - const mainScreenScaleFactor = mainScreen.scaleFactor; const mainScreenWorkAreaSize = mainScreen.workAreaSize; - const mainScreenRotation = mainScreen.rotation; - - console.log('mainScreen scaleFactor: ', mainScreenScaleFactor); - console.log('mainScreen workAreaSize: ', mainScreenWorkAreaSize); - console.log('mainScreen rotation: ', mainScreenRotation); - - // console.log('getMaximumSize', this.fetherApp.window.getMaximumSize()); - // console.log('getContentSize', this.fetherApp.window.getContentSize()); - // console.log('getContentBounds', this.fetherApp.window.getContentBounds()); - // console.log('getBounds', this.fetherApp.window.getBounds()); - - console.log('1aa', calculatedWindowPosition.x); - console.log('2aa', calculatedWindowPosition.y); - console.log('3aa', currentScreenResolution.x); - console.log('4aa', currentScreenResolution.y); - console.log('5aa', this.fetherApp.window.getSize()[0]); - console.log('6aa', this.fetherApp.window.getSize()[1]); - - // Depth depends on resolution. Add minimum incase calculations are - // wrong, for example on a VM with a scaled or resized virtual screen - // where the VM window screen resolution calculated is actually - // the width/height of the VM window relative to the host machine screen, - // rather than the resolution being used in the VM screen. - let platformDepth = 40; // 'win32' - if (process.platform === 'darwin') { - platformDepth = 23; - } - // Tray could be on top, bottom, left, or right side of screen - this.fetherApp.trayDepth = Math.min( - platformDepth, - calculatedWindowPosition.x, // Left tray - calculatedWindowPosition.y, // Top tray - currentScreenResolution.x - - calculatedWindowPosition.x + - this.fetherApp.window.getSize()[0], // Right tray - currentScreenResolution.y - - calculatedWindowPosition.y + - this.fetherApp.window.getSize()[1] // Bottom tray + // workAreaSize does not include the taskbar depth + this.fetherApp.trayDepth = Math.max( + mainScreenDimensions.width - mainScreenWorkAreaSize.width, + mainScreenDimensions.height - mainScreenWorkAreaSize.height ); - // Note: It is calculating the trayDeth incorrectly based - // on the most recent position, instead of the initial position! - // Consider storing smallest value in electron-settings. - // Consider doing Math.min(this.fetherApp.trayDepth, ...) to - // see if trayDepth already defined upon initial load adjacent - // to the tray (not subsequent position) - // this.fetherApp.trayDepth = Math.min( - // calculatedWindowPosition.x, - // calculatedWindowPosition.y - // ); + console.log('trayDepth setup: ', this.fetherApp.trayDepth); const loadedWindowPosition = hasSavedWindowPosition() @@ -454,11 +449,16 @@ class FetherApp { y: undefined }; - const currentScreenResolution = this.calculateScreenResolution(); + const currentScreenResolution = this.getScreenResolution(); console.log('currentScreenResolution: ', currentScreenResolution); console.log('trayDepth: ', trayDepth); + const windowWidth = this.fetherApp.window.getSize()[0]; + const windowHeight = this.fetherApp.window.getSize()[1]; + + console.log('window dimensions: ', windowWidth, windowHeight); + if (proposedWindowPosition.x < trayDepth) { newPosition.x = trayDepth; } @@ -467,12 +467,18 @@ class FetherApp { newPosition.y = trayDepth; } - if (proposedWindowPosition.x >= currentScreenResolution.x - trayDepth) { - newPosition.x = currentScreenResolution.x - trayDepth; + if ( + proposedWindowPosition.x >= + currentScreenResolution.x - windowWidth - trayDepth + ) { + newPosition.x = currentScreenResolution.x - windowWidth - trayDepth; } - if (proposedWindowPosition.y >= currentScreenResolution.y - trayDepth) { - newPosition.y = currentScreenResolution.y - trayDepth; + if ( + proposedWindowPosition.y >= + currentScreenResolution.y - windowHeight - trayDepth + ) { + newPosition.y = currentScreenResolution.y - windowHeight - trayDepth; } return newPosition; @@ -518,10 +524,14 @@ class FetherApp { }; }; - calculateScreenResolution = () => { + // https://ourcodeworld.com/articles/read/285/how-to-get-the-screen-width-and-height-in-electron-framework + getScreenResolution = () => { + const mainScreen = screen.getPrimaryDisplay(); + const mainScreenDimensions = mainScreen.size; + return { - x: this.fetherApp.positioner.calculate('bottomRight').x, - y: this.fetherApp.positioner.calculate('bottomRight').y + x: mainScreenDimensions.width, + y: mainScreenDimensions.height }; }; From 4fbd36f0271bd83fb575b0959b45c6f1669f167b Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Tue, 22 Jan 2019 12:08:08 +1100 Subject: [PATCH 045/153] refactor: Move Electron menu template into separate file. Create event for move window up into view --- .../fether-electron/src/main/app/index.js | 11 ++- .../src/main/app/menu/index.js | 86 ++---------------- .../src/main/app/menu/template/index.js | 87 +++++++++++++++++++ yarn.lock | 24 ----- 4 files changed, 101 insertions(+), 107 deletions(-) create mode 100644 packages/fether-electron/src/main/app/menu/template/index.js diff --git a/packages/fether-electron/src/main/app/index.js b/packages/fether-electron/src/main/app/index.js index 66eeec82f..2496a8b7a 100644 --- a/packages/fether-electron/src/main/app/index.js +++ b/packages/fether-electron/src/main/app/index.js @@ -16,7 +16,7 @@ import { hasSavedWindowPosition, saveWindowPosition } from './settings'; -import addMenu from './menu'; +import { addMenu } from './menu'; import cli from './cli'; import messages from './messages'; import ParityEthereum from './parityEthereum'; @@ -233,7 +233,7 @@ class FetherApp { console.log('adjustY: ', adjustY); if (adjustY > 0) { - console.log('moved window up'); + this.fetherApp.emit('moved-window-up-into-view'); this.fetherApp.window.setPosition(positionStruct.x, maxWindowY); } }; @@ -545,6 +545,7 @@ class FetherApp { }; clickedTray = (e, bounds) => { + console.log('clickedTray', window.isVisible()); const { cachedBounds, window } = this.fetherApp; if ( @@ -554,11 +555,13 @@ class FetherApp { e.metaKey || (window && window.isVisible()) ) { + console.log('called this.hideWindow()'); return this.hideWindow(); } // cachedBounds are needed for double-clicked event this.fetherApp.cachedBounds = bounds || cachedBounds; + console.log('this.fetherApp.cachedBounds: ', this.fetherApp.cachedBounds); this.showWindow(this.fetherApp.cachedBounds); }; @@ -617,6 +620,10 @@ class FetherApp { ); }); + this.fetherApp.on('moved-window-up-into-view', () => { + pino.info('Moved window up into view'); + }); + this.fetherApp.on('after-close-window', () => { pino.info('Deleted window upon close'); }); diff --git a/packages/fether-electron/src/main/app/menu/index.js b/packages/fether-electron/src/main/app/menu/index.js index e5746a75e..560e7f436 100644 --- a/packages/fether-electron/src/main/app/menu/index.js +++ b/packages/fether-electron/src/main/app/menu/index.js @@ -4,91 +4,15 @@ // SPDX-License-Identifier: BSD-3-Clause import electron from 'electron'; +import { template } from './template'; -const { app, Menu, shell } = electron; - -export default fetherAppWindow => { - // Create the Application's main menu - // https://github.com/electron/electron/blob/master/docs/api/menu.md#examples - const template = [ - { - label: 'Edit', - submenu: [ - { role: 'cut' }, - { role: 'copy' }, - { role: 'paste' }, - { role: 'delete' }, - { role: 'selectall' } - ] - }, - { - label: 'View', - submenu: [ - { role: 'reload' }, - { role: 'forcereload' }, - { role: 'toggledevtools' }, - { type: 'separator' }, - { role: 'resetzoom' }, - { role: 'zoomin' }, - { role: 'zoomout' }, - { type: 'separator' }, - { role: 'togglefullscreen' } - ] - }, - { - role: 'window', - submenu: [{ role: 'minimize' }, { role: 'close' }] - }, - { - role: 'help', - submenu: [ - { - label: 'Learn More', - click () { - shell.openExternal('https://parity.io'); - } - } - ] - } - ]; - - if (process.platform === 'darwin') { - template.unshift({ - label: app.getName(), - submenu: [ - { role: 'about' }, - { type: 'separator' }, - { role: 'services', submenu: [] }, - { type: 'separator' }, - { role: 'hide' }, - { role: 'hideothers' }, - { role: 'unhide' }, - { type: 'separator' }, - { role: 'quit' } - ] - }); - - // Edit menu - template[1].submenu.push( - { type: 'separator' }, - { - label: 'Speech', - submenu: [{ role: 'startspeaking' }, { role: 'stopspeaking' }] - } - ); - - // Window menu - template[3].submenu = [ - { role: 'close' }, - { role: 'minimize' }, - { role: 'zoom' }, - { type: 'separator' }, - { role: 'front' } - ]; - } +const { Menu } = electron; +const addMenu = fetherAppWindow => { const menu = Menu.buildFromTemplate(template); Menu.setApplicationMenu(menu); fetherAppWindow.setAutoHideMenuBar(true); }; + +export { addMenu }; diff --git a/packages/fether-electron/src/main/app/menu/template/index.js b/packages/fether-electron/src/main/app/menu/template/index.js new file mode 100644 index 000000000..7018731c9 --- /dev/null +++ b/packages/fether-electron/src/main/app/menu/template/index.js @@ -0,0 +1,87 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. +// +// SPDX-License-Identifier: BSD-3-Clause + +import electron from 'electron'; + +const { app, shell } = electron; + +// Create the Application's main menu +// https://github.com/electron/electron/blob/master/docs/api/menu.md#examples +export const template = [ + { + label: 'Edit', + submenu: [ + { role: 'cut' }, + { role: 'copy' }, + { role: 'paste' }, + { role: 'delete' }, + { role: 'selectall' } + ] + }, + { + label: 'View', + submenu: [ + { role: 'reload' }, + { role: 'forcereload' }, + { role: 'toggledevtools' }, + { type: 'separator' }, + { role: 'resetzoom' }, + { role: 'zoomin' }, + { role: 'zoomout' }, + { type: 'separator' }, + { role: 'togglefullscreen' } + ] + }, + { + role: 'window', + submenu: [{ role: 'minimize' }, { role: 'close' }] + }, + { + role: 'help', + submenu: [ + { + label: 'Learn More', + click () { + shell.openExternal('https://parity.io'); + } + } + ] + } +]; + +if (process.platform === 'darwin') { + template.unshift({ + label: app.getName(), + submenu: [ + { role: 'about' }, + { type: 'separator' }, + { role: 'services', submenu: [] }, + { type: 'separator' }, + { role: 'hide' }, + { role: 'hideothers' }, + { role: 'unhide' }, + { type: 'separator' }, + { role: 'quit' } + ] + }); + + // Edit menu + template[1].submenu.push( + { type: 'separator' }, + { + label: 'Speech', + submenu: [{ role: 'startspeaking' }, { role: 'stopspeaking' }] + } + ); + + // Window menu + template[3].submenu = [ + { role: 'close' }, + { role: 'minimize' }, + { role: 'zoom' }, + { type: 'separator' }, + { role: 'front' } + ]; +} diff --git a/yarn.lock b/yarn.lock index 8a692524c..27a2498c3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2364,11 +2364,6 @@ accepts@~1.3.4, accepts@~1.3.5: mime-types "~2.1.18" negotiator "0.6.1" -accessibility-developer-tools@^2.11.0: - version "2.12.0" - resolved "https://registry.yarnpkg.com/accessibility-developer-tools/-/accessibility-developer-tools-2.12.0.tgz#3da0cce9d6ec6373964b84f35db7cfc3df7ab514" - integrity sha1-PaDM6dbsY3OWS4TzXbfPw996tRQ= - acorn-dynamic-import@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/acorn-dynamic-import/-/acorn-dynamic-import-3.0.0.tgz#901ceee4c7faaef7e07ad2a47e890675da50a278" @@ -6086,15 +6081,6 @@ detect-port-alt@1.1.6: address "^1.0.1" debug "^2.6.0" -devtron@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/devtron/-/devtron-1.4.0.tgz#b5e748bd6e95bbe70bfcc68aae6fe696119441e1" - integrity sha1-tedIvW6Vu+cL/MaKrm/mlhGUQeE= - dependencies: - accessibility-developer-tools "^2.11.0" - highlight.js "^9.3.0" - humanize-plus "^1.8.1" - diff@^3.2.0, diff@^3.3.1, diff@^3.5.0: version "3.5.0" resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" @@ -8443,11 +8429,6 @@ hex-color-regex@^1.1.0: resolved "https://registry.yarnpkg.com/hex-color-regex/-/hex-color-regex-1.1.0.tgz#4c06fccb4602fe2602b3c93df82d7e7dbf1a8a8e" integrity sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ== -highlight.js@^9.3.0: - version "9.13.1" - resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-9.13.1.tgz#054586d53a6863311168488a0f58d6c505ce641e" - integrity sha512-Sc28JNQNDzaH6PORtRLMvif9RSn1mYuOoX3omVjnb0+HbpPygU2ALBI0R/wsiqCb4/fcp07Gdo8g+fhtFrQl6A== - history@^4.7.2: version "4.7.2" resolved "https://registry.yarnpkg.com/history/-/history-4.7.2.tgz#22b5c7f31633c5b8021c7f4a8a954ac139ee8d5b" @@ -8721,11 +8702,6 @@ https-browserify@^1.0.0: resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM= -humanize-plus@^1.8.1: - version "1.8.2" - resolved "https://registry.yarnpkg.com/humanize-plus/-/humanize-plus-1.8.2.tgz#a65b34459ad6367adbb3707a82a3c9f916167030" - integrity sha1-pls0RZrWNnrbs3B6gqPJ+RYWcDA= - husky@^1.0.0-rc.13: version "1.0.0-rc.13" resolved "https://registry.yarnpkg.com/husky/-/husky-1.0.0-rc.13.tgz#49c3cc210bfeac24d4ad272f770b7505c9091828" From 32d1bc52eb8a06b59ac8cac043b3bb4bd9643403 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Tue, 22 Jan 2019 12:09:15 +1100 Subject: [PATCH 046/153] fix: Use window after defined --- packages/fether-electron/src/main/app/index.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/fether-electron/src/main/app/index.js b/packages/fether-electron/src/main/app/index.js index 2496a8b7a..f5ee92f43 100644 --- a/packages/fether-electron/src/main/app/index.js +++ b/packages/fether-electron/src/main/app/index.js @@ -545,9 +545,10 @@ class FetherApp { }; clickedTray = (e, bounds) => { - console.log('clickedTray', window.isVisible()); const { cachedBounds, window } = this.fetherApp; + console.log('clickedTray', window.isVisible()); + if ( e.altKey || e.shiftKey || From 8ce7addb3b4c8b7b5f2eeca5460b381ef1bc6168 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Tue, 22 Jan 2019 12:45:39 +1100 Subject: [PATCH 047/153] feat: Add context menu on right click for Windows --- packages/fether-electron/src/main/app/index.js | 10 +++++++++- packages/fether-electron/src/main/app/menu/index.js | 10 +++++++--- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/packages/fether-electron/src/main/app/index.js b/packages/fether-electron/src/main/app/index.js index f5ee92f43..deb3d7891 100644 --- a/packages/fether-electron/src/main/app/index.js +++ b/packages/fether-electron/src/main/app/index.js @@ -16,7 +16,7 @@ import { hasSavedWindowPosition, saveWindowPosition } from './settings'; -import { addMenu } from './menu'; +import { addMenu, getMenu } from './menu'; import cli from './cli'; import messages from './messages'; import ParityEthereum from './parityEthereum'; @@ -316,6 +316,14 @@ class FetherApp { this.fetherApp.tray = new Tray(options.icon); let { tray } = this.fetherApp; + // Note: See https://github.com/RocketChat/Rocket.Chat.Electron/issues/44 + if (process.platform === 'win32') { + // Set context menu for tray icon + tray.setContextMenu(getMenu()); + tray.displayBalloon({ title: 'Right-click to view menu' }); + tray.popUpContextMenu(); + } + tray.on(defaultClickEvent, this.clickedTray); tray.on('double-click', this.clickedTray); tray.setToolTip(options.tooltip); diff --git a/packages/fether-electron/src/main/app/menu/index.js b/packages/fether-electron/src/main/app/menu/index.js index 560e7f436..72c6f1062 100644 --- a/packages/fether-electron/src/main/app/menu/index.js +++ b/packages/fether-electron/src/main/app/menu/index.js @@ -8,11 +8,15 @@ import { template } from './template'; const { Menu } = electron; -const addMenu = fetherAppWindow => { - const menu = Menu.buildFromTemplate(template); +const menu = Menu.buildFromTemplate(template); + +const getMenu = () => { + return menu; +}; +const addMenu = fetherAppWindow => { Menu.setApplicationMenu(menu); fetherAppWindow.setAutoHideMenuBar(true); }; -export { addMenu }; +export { addMenu, getMenu }; From ffffaa90ce01839256e620b2828588e3ea3f2f9b Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Tue, 22 Jan 2019 19:30:57 +1100 Subject: [PATCH 048/153] feat: Toggle Fether menu with ALT-M in Windows but menu items do not work --- .../fether-electron/src/main/app/index.js | 89 ++++++++++++++----- 1 file changed, 69 insertions(+), 20 deletions(-) diff --git a/packages/fether-electron/src/main/app/index.js b/packages/fether-electron/src/main/app/index.js index deb3d7891..be3262865 100644 --- a/packages/fether-electron/src/main/app/index.js +++ b/packages/fether-electron/src/main/app/index.js @@ -124,6 +124,13 @@ class FetherApp { addMenu(this.fetherApp.window); pino.info('Finished configuring Electron menu'); + this.fetherApp.window.webContents.debugger.on( + 'message', + (event, method, params) => { + console.log('MESSAGE: ', event, method, params); + } + ); + // WS calls have Origin `file://` by default, which is not trusted. // We override Origin header on all WS connections with an authorized one. session.defaultSession.webRequest.onBeforeSendHeaders( @@ -155,10 +162,38 @@ class FetherApp { this.fetherApp.emit('after-closed-window'); }); - // Reference: http://robmayhew.com/listening-for-events-from-windows-in-electron-tutorial/ - if (process.platform !== 'darwin') { - // Hook WM_SYSCOMMAND + /** + * Hook WM_SYSKEYUP + * + * Open the Fether Electron menu when the Fether window is active + * and the user enters a keyboard combination of both the ALT and 'm' keys + * + * Reference: https://docs.microsoft.com/en-gb/windows/desktop/inputdev/wm-syskeyup + */ + this.fetherApp.window.hookWindowMessage( + Number.parseInt('0x0105'), + (wParam, lParam) => { + // Reference: https://nodejs.org/api/buffer.html + if (wParam && wParam.readUInt32LE(0) === 77) { + let { tray } = this.fetherApp; + tray.setContextMenu(getMenu()); + tray.displayBalloon({ + title: 'Fether Menu', + content: 'Press ALT-M in the Fether window to open the menu' + }); + tray.popUpContextMenu(); + } + } + ); + + /** + * Hook WM_SYSCOMMAND + * + * Detect events on Windows + * + * Credit: http://robmayhew.com/listening-for-events-from-windows-in-electron-tutorial/ + */ this.fetherApp.window.hookWindowMessage( Number.parseInt('0x0112'), (wParam, lParam) => { @@ -179,25 +214,33 @@ class FetherApp { } if (eventName !== null) { - console.log('WINDOWS ' + eventName); + console.log('Detected event ' + eventName); } } ); - // WM_EXITSIZEMOVE + /** + * Hook WM_EXITSIZEMOVE + * + * Detect event on Windows when Fether window was moved + * or resized + */ this.fetherApp.window.hookWindowMessage( Number.parseInt('0x0232'), (wParam, lParam) => { - console.log('Windows move or resize complete'); + console.log('Detected completion of move or resize event'); - console.log('resize event (Windows)'); + // Move Fether window back up into view if it was a resize event + // that causes the bottom to be cropped this.moveWindowUp(); + // Try again after a delay incase Fether window resize occurs + // x seconds after navigating to a new page. setTimeout(() => { - console.log('resize Windows DELAYED'); this.moveWindowUp(); }, 5000); - this.processMoved(); // save position + // Save Fether window position to Electron settings + this.processMoved(); } ); } @@ -212,7 +255,7 @@ class FetherApp { * automatically move the window upward so it is viewable to the user */ moveWindowUp = () => { - console.log('window resized moving back up into view'); + console.log('Fether window resized. Moving it back up into view'); const position = this.fetherApp.window.getPosition(); const positionStruct = { @@ -226,11 +269,6 @@ class FetherApp { const windowHeight = this.fetherApp.window.getSize()[1]; const maxWindowY = currentScreenResolution.y - windowHeight - taskbarDepth; const adjustY = positionStruct.y - maxWindowY; - console.log('positionStruct: ', positionStruct); - console.log('currentScreenResolution: ', currentScreenResolution); - console.log('windowHeight: ', windowHeight); - console.log('maxWindowY: ', maxWindowY); - console.log('adjustY: ', adjustY); if (adjustY > 0) { this.fetherApp.emit('moved-window-up-into-view'); @@ -292,9 +330,6 @@ class FetherApp { } } - console.log('newFixedPosition - ', newFixedPosition); - console.log('positionStruct - ', positionStruct); - saveWindowPosition(newFixedPosition || positionStruct); this.fetherApp.emit('after-moved-window-position-saved'); @@ -320,12 +355,26 @@ class FetherApp { if (process.platform === 'win32') { // Set context menu for tray icon tray.setContextMenu(getMenu()); - tray.displayBalloon({ title: 'Right-click to view menu' }); - tray.popUpContextMenu(); + tray.displayBalloon({ + title: 'Fether Menu', + content: 'Press ALT-M in the Fether window to open the menu' + }); } tray.on(defaultClickEvent, this.clickedTray); tray.on('double-click', this.clickedTray); + tray.on('right-click', () => { + // Below does not work on Windows as intended + if (process.platform === 'win32') { + console.log('Detected right click on Windows'); + tray.setContextMenu(getMenu()); + tray.displayBalloon({ + title: 'Fether Menu', + content: 'Press ALT-M in the Fether window to open the menu' + }); + tray.popUpContextMenu(); + } + }); tray.setToolTip(options.tooltip); this.fetherApp.supportsTrayHighlightState = false; From 61ab4efaf5f8f8f6c2cad9ab7c8f8ae73029d1d9 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Tue, 22 Jan 2019 19:39:42 +1100 Subject: [PATCH 049/153] refactor: Remove useless debugger --- packages/fether-electron/src/main/app/index.js | 7 ------- 1 file changed, 7 deletions(-) diff --git a/packages/fether-electron/src/main/app/index.js b/packages/fether-electron/src/main/app/index.js index be3262865..51a9042ed 100644 --- a/packages/fether-electron/src/main/app/index.js +++ b/packages/fether-electron/src/main/app/index.js @@ -124,13 +124,6 @@ class FetherApp { addMenu(this.fetherApp.window); pino.info('Finished configuring Electron menu'); - this.fetherApp.window.webContents.debugger.on( - 'message', - (event, method, params) => { - console.log('MESSAGE: ', event, method, params); - } - ); - // WS calls have Origin `file://` by default, which is not trusted. // We override Origin header on all WS connections with an authorized one. session.defaultSession.webRequest.onBeforeSendHeaders( From 85197a7bfe52b5a1f7ec7541b6c0d78e1685116d Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Tue, 22 Jan 2019 20:22:06 +1100 Subject: [PATCH 050/153] fix: Fix missing code --- packages/fether-electron/src/main/app/index.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/fether-electron/src/main/app/index.js b/packages/fether-electron/src/main/app/index.js index 51a9042ed..d32d8de68 100644 --- a/packages/fether-electron/src/main/app/index.js +++ b/packages/fether-electron/src/main/app/index.js @@ -155,6 +155,10 @@ class FetherApp { this.fetherApp.emit('after-closed-window'); }); + this.addWindowsListeners(); + }; + + addWindowsListeners = () => { if (process.platform !== 'darwin') { /** * Hook WM_SYSKEYUP From d20f255da0e527a1faa49d59d7b6ff3ec782856b Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Tue, 22 Jan 2019 20:27:11 +1100 Subject: [PATCH 051/153] refactor: Remove console.logs --- .../fether-electron/src/main/app/index.js | 21 ++----------------- 1 file changed, 2 insertions(+), 19 deletions(-) diff --git a/packages/fether-electron/src/main/app/index.js b/packages/fether-electron/src/main/app/index.js index d32d8de68..3dd6c9687 100644 --- a/packages/fether-electron/src/main/app/index.js +++ b/packages/fether-electron/src/main/app/index.js @@ -82,10 +82,9 @@ class FetherApp { // macOS (not Windows) this.fetherApp.window.on('resize', () => { - console.log('resize event'); + console.log('Detected resize event'); this.moveWindowUp(); setTimeout(() => { - console.log('resize general DELAYED'); this.moveWindowUp(); }, 5000); }); @@ -360,8 +359,8 @@ class FetherApp { tray.on(defaultClickEvent, this.clickedTray); tray.on('double-click', this.clickedTray); + // Right click event handler does not work on Windows as intended tray.on('right-click', () => { - // Below does not work on Windows as intended if (process.platform === 'win32') { console.log('Detected right click on Windows'); tray.setContextMenu(getMenu()); @@ -424,8 +423,6 @@ class FetherApp { const calculatedWindowPosition = this.calculateWindowPosition(trayPos); - console.log('calculatedWindowPosition: ', calculatedWindowPosition); - const mainScreen = screen.getPrimaryDisplay(); // const allScreens = screen.getAllDisplays(); @@ -438,8 +435,6 @@ class FetherApp { mainScreenDimensions.height - mainScreenWorkAreaSize.height ); - console.log('trayDepth setup: ', this.fetherApp.trayDepth); - const loadedWindowPosition = hasSavedWindowPosition() ? getSavedWindowPosition() : undefined; @@ -505,14 +500,9 @@ class FetherApp { const currentScreenResolution = this.getScreenResolution(); - console.log('currentScreenResolution: ', currentScreenResolution); - console.log('trayDepth: ', trayDepth); - const windowWidth = this.fetherApp.window.getSize()[0]; const windowHeight = this.fetherApp.window.getSize()[1]; - console.log('window dimensions: ', windowWidth, windowHeight); - if (proposedWindowPosition.x < trayDepth) { newPosition.x = trayDepth; } @@ -551,13 +541,10 @@ class FetherApp { // Get the current tray bounds trayPos = tray.getBounds(); } - console.log('tray.getBounds()', tray.getBounds()); // Default the window to the right if `trayPos` bounds are undefined or null. let noBoundsPosition = null; - console.log('platform: ', process.platform); - if ( (trayPos === undefined || (trayPos && trayPos.x === 0)) && options.windowPosition && @@ -601,8 +588,6 @@ class FetherApp { clickedTray = (e, bounds) => { const { cachedBounds, window } = this.fetherApp; - console.log('clickedTray', window.isVisible()); - if ( e.altKey || e.shiftKey || @@ -610,13 +595,11 @@ class FetherApp { e.metaKey || (window && window.isVisible()) ) { - console.log('called this.hideWindow()'); return this.hideWindow(); } // cachedBounds are needed for double-clicked event this.fetherApp.cachedBounds = bounds || cachedBounds; - console.log('this.fetherApp.cachedBounds: ', this.fetherApp.cachedBounds); this.showWindow(this.fetherApp.cachedBounds); }; From 84ee0452144589ddae6baa1fb88ae51a00c05406 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Tue, 22 Jan 2019 20:31:11 +1100 Subject: [PATCH 052/153] refactor: Cleanup console.log --- packages/fether-electron/src/main/app/utils/window.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/fether-electron/src/main/app/utils/window.js b/packages/fether-electron/src/main/app/utils/window.js index 14f09c67b..c9507e359 100644 --- a/packages/fether-electron/src/main/app/utils/window.js +++ b/packages/fether-electron/src/main/app/utils/window.js @@ -34,7 +34,7 @@ const shouldFixWindowPosition = ( currentScreenResolution ) => { console.log( - 'previous, current: ', + 'Window position (previous, current): ', previousScreenResolution, currentScreenResolution ); From f6e811e69e2fba7f0c90f2ea8a659492e3f986a5 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Wed, 23 Jan 2019 12:33:46 +1100 Subject: [PATCH 053/153] fix: Only run hookWindowMessage on Windows --- packages/fether-electron/src/main/app/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/fether-electron/src/main/app/index.js b/packages/fether-electron/src/main/app/index.js index 3dd6c9687..971db4fb6 100644 --- a/packages/fether-electron/src/main/app/index.js +++ b/packages/fether-electron/src/main/app/index.js @@ -158,7 +158,7 @@ class FetherApp { }; addWindowsListeners = () => { - if (process.platform !== 'darwin') { + if (process.platform === 'win32') { /** * Hook WM_SYSKEYUP * From 9bb328da50e79da313a9b333913af3204f1a1a00 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Wed, 23 Jan 2019 21:19:31 +1100 Subject: [PATCH 054/153] Disable taskbar app mode on linux --- packages/fether-electron/src/main/index.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/fether-electron/src/main/index.js b/packages/fether-electron/src/main/index.js index eca994a4c..28e29cf76 100644 --- a/packages/fether-electron/src/main/index.js +++ b/packages/fether-electron/src/main/index.js @@ -13,13 +13,16 @@ import FetherAppOptions from './app/options'; const { app } = electron; const pino = Pino(); +let withTaskbar = process.env.TASKBAR !== 'false'; + // Disable gpu acceleration on linux // https://github.com/parity-js/fether/issues/85 if (!['darwin', 'win32'].includes(process.platform)) { app.disableHardwareAcceleration(); -} -const withTaskbar = process.env.TASKBAR !== 'false'; + // Disable taskbar on Linux (since not supported by Gnome 3) + withTaskbar = false; +} const fetherAppInstance = new FetherApp(); const fetherAppOptionsInstance = new FetherAppOptions(); From ab04406552c54fa8a15682a072fa0ee6863751d1 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Wed, 23 Jan 2019 23:46:55 +1100 Subject: [PATCH 055/153] WIP - Fether menu window frame on Windows and Feedback adjust --- .../fether-electron/src/main/app/index.js | 29 +++++++++++++++++++ packages/fether-electron/src/main/index.js | 4 ++- .../AccountsList/Feedback/Feedback.js | 14 +++++++-- .../assets/sass/components/_footer-nav.scss | 4 +++ 4 files changed, 48 insertions(+), 3 deletions(-) diff --git a/packages/fether-electron/src/main/app/index.js b/packages/fether-electron/src/main/app/index.js index 971db4fb6..1288ab242 100644 --- a/packages/fether-electron/src/main/app/index.js +++ b/packages/fether-electron/src/main/app/index.js @@ -3,6 +3,7 @@ // // SPDX-License-Identifier: BSD-3-Clause +import path from 'path'; import parityElectron from '@parity/electron'; import electron, { screen, Tray } from 'electron'; import Positioner from 'electron-positioner'; @@ -62,6 +63,34 @@ class FetherApp { this.fetherApp.window = new BrowserWindow(options); this.fetherApp.window.setProgressBar(0.4); + if (process.platform === 'win32') { + this.fetherApp.window.setThumbnailToolTip( + 'Press ALT to open Fether menu' + ); + + const ICON_PATH = + process.env.ELECTRON_START_ICON || process.env.SKIP_PREFLIGHT_CHECK + ? 'src/main/app/options/config/icons/parity-ethereum-fether-icon.png' + : path.join( + __dirname, + 'options', + 'config', + 'icons', + 'parity-ethereum-fether-icon.png' + ); + + this.fetherApp.window.setAppDetails({ + appId: '1234', + appIconPath: ICON_PATH + }); + } + + if (process.platform !== 'darwin') { + // Showing the Fether menu bar in the frame causes Feedback button to be cropped + this.fetherApp.window.setAutoHideMenuBar(true); // ALT shows menu bar + this.fetherApp.window.setMenuBarVisibility(false); + } + // Opens file:///path/to/build/index.html in prod mode, or whatever is // passed to ELECTRON_START_URL this.fetherApp.window.loadURL(options.index); diff --git a/packages/fether-electron/src/main/index.js b/packages/fether-electron/src/main/index.js index 28e29cf76..2dd1a5aa5 100644 --- a/packages/fether-electron/src/main/index.js +++ b/packages/fether-electron/src/main/index.js @@ -19,8 +19,10 @@ let withTaskbar = process.env.TASKBAR !== 'false'; // https://github.com/parity-js/fether/issues/85 if (!['darwin', 'win32'].includes(process.platform)) { app.disableHardwareAcceleration(); +} - // Disable taskbar on Linux (since not supported by Gnome 3) +if (process.platform !== 'darwin') { + // Disable taskbar on Windows or Linux (since not supported by Gnome 3) withTaskbar = false; } diff --git a/packages/fether-react/src/Accounts/AccountsList/Feedback/Feedback.js b/packages/fether-react/src/Accounts/AccountsList/Feedback/Feedback.js index 969f2bca7..01f5516c7 100644 --- a/packages/fether-react/src/Accounts/AccountsList/Feedback/Feedback.js +++ b/packages/fether-react/src/Accounts/AccountsList/Feedback/Feedback.js @@ -7,11 +7,21 @@ import React from 'react'; export const Feedback = ({ accountsListLength }) => ( 1 ? '-2px' : '-10px' }} + // On Windows when Fether menu is show the Feedback button is pushed down out of view + style={{ + marginBottom: + accountsListLength > 1 + ? process.platform === 'win32' + ? '18px' + : '-2px' + : process.platform === 'win32' + ? '15px' + : '-10px' + }} > Feedback diff --git a/packages/fether-react/src/assets/sass/components/_footer-nav.scss b/packages/fether-react/src/assets/sass/components/_footer-nav.scss index ddcf808c0..9ac3cbbee 100644 --- a/packages/fether-react/src/assets/sass/components/_footer-nav.scss +++ b/packages/fether-react/src/assets/sass/components/_footer-nav.scss @@ -26,6 +26,10 @@ background: $grey; box-shadow: 0.125rem 0.275rem 0.3rem 0 rgba($black, 0.4); } + + &.-windows { + border-radius: 5px 5px 5px 5px; + } } } From bc8a6dd5fe21919c76f176e610ef598d635038ff Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Thu, 24 Jan 2019 00:03:10 +1100 Subject: [PATCH 056/153] Show Fether menu in frame always on Windows --- packages/fether-electron/src/main/app/index.js | 4 ++-- .../src/Accounts/AccountsList/Feedback/Feedback.js | 14 ++------------ .../src/assets/sass/components/_footer-nav.scss | 4 ---- 3 files changed, 4 insertions(+), 18 deletions(-) diff --git a/packages/fether-electron/src/main/app/index.js b/packages/fether-electron/src/main/app/index.js index 1288ab242..ce93a1b9b 100644 --- a/packages/fether-electron/src/main/app/index.js +++ b/packages/fether-electron/src/main/app/index.js @@ -87,8 +87,8 @@ class FetherApp { if (process.platform !== 'darwin') { // Showing the Fether menu bar in the frame causes Feedback button to be cropped - this.fetherApp.window.setAutoHideMenuBar(true); // ALT shows menu bar - this.fetherApp.window.setMenuBarVisibility(false); + this.fetherApp.window.setAutoHideMenuBar(false); // ALT shows menu bar + this.fetherApp.window.setMenuBarVisibility(true); } // Opens file:///path/to/build/index.html in prod mode, or whatever is diff --git a/packages/fether-react/src/Accounts/AccountsList/Feedback/Feedback.js b/packages/fether-react/src/Accounts/AccountsList/Feedback/Feedback.js index 01f5516c7..969f2bca7 100644 --- a/packages/fether-react/src/Accounts/AccountsList/Feedback/Feedback.js +++ b/packages/fether-react/src/Accounts/AccountsList/Feedback/Feedback.js @@ -7,21 +7,11 @@ import React from 'react'; export const Feedback = ({ accountsListLength }) => ( 1 - ? process.platform === 'win32' - ? '18px' - : '-2px' - : process.platform === 'win32' - ? '15px' - : '-10px' - }} + style={{ marginBottom: accountsListLength > 1 ? '-2px' : '-10px' }} > Feedback diff --git a/packages/fether-react/src/assets/sass/components/_footer-nav.scss b/packages/fether-react/src/assets/sass/components/_footer-nav.scss index 9ac3cbbee..ddcf808c0 100644 --- a/packages/fether-react/src/assets/sass/components/_footer-nav.scss +++ b/packages/fether-react/src/assets/sass/components/_footer-nav.scss @@ -26,10 +26,6 @@ background: $grey; box-shadow: 0.125rem 0.275rem 0.3rem 0 rgba($black, 0.4); } - - &.-windows { - border-radius: 5px 5px 5px 5px; - } } } From 21e20b1a4fa2670e03af193e3b033db08c7d342d Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Thu, 24 Jan 2019 00:18:43 +1100 Subject: [PATCH 057/153] Hide menu bar by default. Comment out code that not working --- .../fether-electron/src/main/app/index.js | 53 ++++++++++--------- 1 file changed, 29 insertions(+), 24 deletions(-) diff --git a/packages/fether-electron/src/main/app/index.js b/packages/fether-electron/src/main/app/index.js index ce93a1b9b..0f7182554 100644 --- a/packages/fether-electron/src/main/app/index.js +++ b/packages/fether-electron/src/main/app/index.js @@ -63,32 +63,37 @@ class FetherApp { this.fetherApp.window = new BrowserWindow(options); this.fetherApp.window.setProgressBar(0.4); - if (process.platform === 'win32') { - this.fetherApp.window.setThumbnailToolTip( - 'Press ALT to open Fether menu' - ); - - const ICON_PATH = - process.env.ELECTRON_START_ICON || process.env.SKIP_PREFLIGHT_CHECK - ? 'src/main/app/options/config/icons/parity-ethereum-fether-icon.png' - : path.join( - __dirname, - 'options', - 'config', - 'icons', - 'parity-ethereum-fether-icon.png' - ); - - this.fetherApp.window.setAppDetails({ - appId: '1234', - appIconPath: ICON_PATH - }); - } + // // FIXME - Note that this block does not appear to work + // if (process.platform === 'win32') { + // this.fetherApp.window.setThumbnailToolTip( + // 'Press ALT to open Fether menu' + // ); + + // const ICON_PATH = + // process.env.ELECTRON_START_ICON || process.env.SKIP_PREFLIGHT_CHECK + // ? 'src/main/app/options/config/icons/parity-ethereum-fether-icon.png' + // : path.join( + // __dirname, + // 'options', + // 'config', + // 'icons', + // 'parity-ethereum-fether-icon.png' + // ); + + // this.fetherApp.window.setAppDetails({ + // appId: '1234', + // appIconPath: ICON_PATH + // }); + // } if (process.platform !== 'darwin') { - // Showing the Fether menu bar in the frame causes Feedback button to be cropped - this.fetherApp.window.setAutoHideMenuBar(false); // ALT shows menu bar - this.fetherApp.window.setMenuBarVisibility(true); + /** + * Showing the Fether menu bar in the frame on Windows causes the + * Feedback button to be cropped, so do not show it by default. The + * user will need to be informed that pressing ALT displays the Fether menu + */ + this.fetherApp.window.setAutoHideMenuBar(true); // ALT shows menu bar + this.fetherApp.window.setMenuBarVisibility(false); } // Opens file:///path/to/build/index.html in prod mode, or whatever is From 7460b19ac9acdd781a0f9703b60034cdb3fe9952 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Thu, 24 Jan 2019 00:36:37 +1100 Subject: [PATCH 058/153] fix comment --- packages/fether-electron/src/main/app/index.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/fether-electron/src/main/app/index.js b/packages/fether-electron/src/main/app/index.js index 0f7182554..a6cde82d6 100644 --- a/packages/fether-electron/src/main/app/index.js +++ b/packages/fether-electron/src/main/app/index.js @@ -285,7 +285,9 @@ class FetherApp { * automatically move the window upward so it is viewable to the user */ moveWindowUp = () => { - console.log('Fether window resized. Moving it back up into view'); + console.log( + 'Fether window resized. Moving it back up into view if required' + ); const position = this.fetherApp.window.getPosition(); const positionStruct = { From 0f373a1274d8ccebb302e1d3c6aaf80d0f07f492 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Thu, 24 Jan 2019 20:36:50 +1100 Subject: [PATCH 059/153] fix: Recover save position and show icon on Windows --- .../fether-electron/src/main/app/index.js | 74 ++++++++++--------- .../src/main/app/options/config/index.js | 10 +-- 2 files changed, 43 insertions(+), 41 deletions(-) diff --git a/packages/fether-electron/src/main/app/index.js b/packages/fether-electron/src/main/app/index.js index a6cde82d6..9e15268dc 100644 --- a/packages/fether-electron/src/main/app/index.js +++ b/packages/fether-electron/src/main/app/index.js @@ -3,7 +3,6 @@ // // SPDX-License-Identifier: BSD-3-Clause -import path from 'path'; import parityElectron from '@parity/electron'; import electron, { screen, Tray } from 'electron'; import Positioner from 'electron-positioner'; @@ -51,41 +50,17 @@ class FetherApp { this.createWindow(); this.fetherApp.window.setProgressBar(0.4); + this.createPositioner(); + this.createTray(); this.loadTaskbar(); this.fetherApp.window.setProgressBar(0.6); this.finalise(); this.fetherApp.window.setProgressBar(0.8); - - this.showWindow(); - this.fetherApp.window.setProgressBar(1.0); } else { this.fetherApp.window = new BrowserWindow(options); this.fetherApp.window.setProgressBar(0.4); - // // FIXME - Note that this block does not appear to work - // if (process.platform === 'win32') { - // this.fetherApp.window.setThumbnailToolTip( - // 'Press ALT to open Fether menu' - // ); - - // const ICON_PATH = - // process.env.ELECTRON_START_ICON || process.env.SKIP_PREFLIGHT_CHECK - // ? 'src/main/app/options/config/icons/parity-ethereum-fether-icon.png' - // : path.join( - // __dirname, - // 'options', - // 'config', - // 'icons', - // 'parity-ethereum-fether-icon.png' - // ); - - // this.fetherApp.window.setAppDetails({ - // appId: '1234', - // appIconPath: ICON_PATH - // }); - // } - if (process.platform !== 'darwin') { /** * Showing the Fether menu bar in the frame on Windows causes the @@ -100,12 +75,18 @@ class FetherApp { // passed to ELECTRON_START_URL this.fetherApp.window.loadURL(options.index); + this.createPositioner(); + this.createTray(); + this.debugSetup(); this.finalise(); - this.fetherApp.window.setProgressBar(1.0); + this.fetherApp.window.setProgressBar(0.8); } + this.showWindow(undefined); + this.fetherApp.window.setProgressBar(1.0); + this.fetherApp.window.setProgressBar(-1); this.fetherApp.emit('after-create-app'); @@ -131,6 +112,16 @@ class FetherApp { } }; + createPositioner = () => { + this.fetherApp.positioner = new Positioner(this.fetherApp.window); + }; + + createTray = () => { + let { options } = this.fetherApp; + + this.fetherApp.tray = new Tray(options.icon); + }; + finalise = () => { // Security to prevent window contents from being captured by other apps this.fetherApp.window.setContentProtection(true); @@ -192,6 +183,8 @@ class FetherApp { }; addWindowsListeners = () => { + const { options } = this.fetherApp; + if (process.platform === 'win32') { /** * Hook WM_SYSKEYUP @@ -210,7 +203,9 @@ class FetherApp { tray.setContextMenu(getMenu()); tray.displayBalloon({ title: 'Fether Menu', - content: 'Press ALT-M in the Fether window to open the menu' + content: `Press ALT ${ + options.withTaskbar ? '-M' : '' + } in the Fether window to toggle the menu` }); tray.popUpContextMenu(); } @@ -295,11 +290,11 @@ class FetherApp { y: position[1] }; - const taskbarDepth = this.taskbarDepth || 40; // Default incase resizes on load + const trayDepth = this.fetherApp.trayDepth || 40; // Default incase resizes on load const currentScreenResolution = this.getScreenResolution(); const windowHeight = this.fetherApp.window.getSize()[1]; - const maxWindowY = currentScreenResolution.y - windowHeight - taskbarDepth; + const maxWindowY = currentScreenResolution.y - windowHeight - trayDepth; const adjustY = positionStruct.y - maxWindowY; if (adjustY > 0) { @@ -368,7 +363,7 @@ class FetherApp { }; loadTaskbar = () => { - const { app, options } = this.fetherApp; + const { app, options, tray } = this.fetherApp; this.fetherApp.emit('load-taskbar'); @@ -380,9 +375,6 @@ class FetherApp { ? 'right-click' : 'click'; - this.fetherApp.tray = new Tray(options.icon); - let { tray } = this.fetherApp; - // Note: See https://github.com/RocketChat/Rocket.Chat.Electron/issues/44 if (process.platform === 'win32') { // Set context menu for tray icon @@ -425,7 +417,6 @@ class FetherApp { this.fetherApp.emit('create-window'); this.fetherApp.window = new BrowserWindow(options); - this.fetherApp.positioner = new Positioner(this.fetherApp.window); this.fetherApp.window.on('blur', () => { options.alwaysOnTop ? this.emitBlur() : this.hideWindow(); @@ -459,6 +450,8 @@ class FetherApp { const calculatedWindowPosition = this.calculateWindowPosition(trayPos); + console.log('Calculated window position: ', calculatedWindowPosition); + const mainScreen = screen.getPrimaryDisplay(); // const allScreens = screen.getAllDisplays(); @@ -471,12 +464,21 @@ class FetherApp { mainScreenDimensions.height - mainScreenWorkAreaSize.height ); + console.log( + 'Previously saved window position exists: ', + hasSavedWindowPosition() + ); + const loadedWindowPosition = hasSavedWindowPosition() ? getSavedWindowPosition() : undefined; + console.log('Loaded window position: ', loadedWindowPosition); + const fixedWindowPosition = this.fixWindowPosition(loadedWindowPosition); + console.log('Fixed window position: ', fixedWindowPosition); + /** * Since the user may change the taskbar tray to be on any side of the screen. * If the user moved the window out of where the tray would be in the screen resolution bounds. diff --git a/packages/fether-electron/src/main/app/options/config/index.js b/packages/fether-electron/src/main/app/options/config/index.js index 552e3ed56..03b4d5a17 100644 --- a/packages/fether-electron/src/main/app/options/config/index.js +++ b/packages/fether-electron/src/main/app/options/config/index.js @@ -24,11 +24,15 @@ const ICON_PATH = const shouldUseDevTools = process.env.NODE_ENV !== 'production'; +const windowPosition = + process.platform === 'win32' ? 'trayBottomCenter' : 'trayCenter'; + // API docs: https://electronjs.org/docs/api/browser-window const DEFAULT_OPTIONS = { alwaysOnTop: true, frame: true, height: 640, + icon: ICON_PATH, index: INDEX_HTML_PATH, resizable: false, show: true, @@ -38,22 +42,18 @@ const DEFAULT_OPTIONS = { enableRemoteModule: false }, width: 360, + windowPosition: windowPosition, // Required withTaskbar: false }; -const windowPosition = - process.platform === 'win32' ? 'trayBottomCenter' : 'trayCenter'; - const TASKBAR_OPTIONS = { dir: staticPath, frame: false, hasShadow: true, height: 464, - icon: ICON_PATH, show: false, // Run showWindow later when taskbar has loaded in FetherApp showDockIcon: true, tooltip: 'Parity Fether', - windowPosition: windowPosition, // Required width: 352, withTaskbar: true }; From a81b1a9274b1aa7292c433dec846a2faf0927b11 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Thu, 24 Jan 2019 20:57:53 +1100 Subject: [PATCH 060/153] refactor: Move showTrayBalloon into own method --- .../fether-electron/src/main/app/index.js | 30 +++++++++---------- packages/fether-electron/src/main/index.js | 3 +- 2 files changed, 16 insertions(+), 17 deletions(-) diff --git a/packages/fether-electron/src/main/app/index.js b/packages/fether-electron/src/main/app/index.js index 9e15268dc..d4a49c7d3 100644 --- a/packages/fether-electron/src/main/app/index.js +++ b/packages/fether-electron/src/main/app/index.js @@ -122,6 +122,17 @@ class FetherApp { this.fetherApp.tray = new Tray(options.icon); }; + showTrayBalloon = () => { + let { tray } = this.fetherApp; + + tray.displayBalloon({ + title: 'Fether Menu', + content: `Press ALT ${ + options.withTaskbar ? '-M' : '' + } in the Fether window to toggle the menu` + }); + }; + finalise = () => { // Security to prevent window contents from being captured by other apps this.fetherApp.window.setContentProtection(true); @@ -183,8 +194,6 @@ class FetherApp { }; addWindowsListeners = () => { - const { options } = this.fetherApp; - if (process.platform === 'win32') { /** * Hook WM_SYSKEYUP @@ -201,12 +210,7 @@ class FetherApp { if (wParam && wParam.readUInt32LE(0) === 77) { let { tray } = this.fetherApp; tray.setContextMenu(getMenu()); - tray.displayBalloon({ - title: 'Fether Menu', - content: `Press ALT ${ - options.withTaskbar ? '-M' : '' - } in the Fether window to toggle the menu` - }); + this.showTrayBalloon(); tray.popUpContextMenu(); } } @@ -379,10 +383,7 @@ class FetherApp { if (process.platform === 'win32') { // Set context menu for tray icon tray.setContextMenu(getMenu()); - tray.displayBalloon({ - title: 'Fether Menu', - content: 'Press ALT-M in the Fether window to open the menu' - }); + this.showTrayBalloon(); } tray.on(defaultClickEvent, this.clickedTray); @@ -392,10 +393,7 @@ class FetherApp { if (process.platform === 'win32') { console.log('Detected right click on Windows'); tray.setContextMenu(getMenu()); - tray.displayBalloon({ - title: 'Fether Menu', - content: 'Press ALT-M in the Fether window to open the menu' - }); + this.showTrayBalloon(); tray.popUpContextMenu(); } }); diff --git a/packages/fether-electron/src/main/index.js b/packages/fether-electron/src/main/index.js index 2dd1a5aa5..1138fe177 100644 --- a/packages/fether-electron/src/main/index.js +++ b/packages/fether-electron/src/main/index.js @@ -22,7 +22,8 @@ if (!['darwin', 'win32'].includes(process.platform)) { } if (process.platform !== 'darwin') { - // Disable taskbar on Windows or Linux (since not supported by Gnome 3) + // Disable taskbar mode on Windows since ALT-M menu items do not trigger + // Disable taskbar mode on Linux since not supported by Gnome 3 withTaskbar = false; } From ff88225a8e4759e84746c116047c672902c10830 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Thu, 24 Jan 2019 20:58:37 +1100 Subject: [PATCH 061/153] fix: Add missing options prop --- packages/fether-electron/src/main/app/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/fether-electron/src/main/app/index.js b/packages/fether-electron/src/main/app/index.js index d4a49c7d3..3ee476610 100644 --- a/packages/fether-electron/src/main/app/index.js +++ b/packages/fether-electron/src/main/app/index.js @@ -123,7 +123,7 @@ class FetherApp { }; showTrayBalloon = () => { - let { tray } = this.fetherApp; + let { options, tray } = this.fetherApp; tray.displayBalloon({ title: 'Fether Menu', From 6e8aafc7590d16eb598db21dea5425a395c5cdf6 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Thu, 24 Jan 2019 21:15:21 +1100 Subject: [PATCH 062/153] feat: Run showTrayBalloon when Fether window is maximised or restored --- packages/fether-electron/src/main/app/index.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/fether-electron/src/main/app/index.js b/packages/fether-electron/src/main/app/index.js index 3ee476610..9b6be4151 100644 --- a/packages/fether-electron/src/main/app/index.js +++ b/packages/fether-electron/src/main/app/index.js @@ -234,12 +234,14 @@ class FetherApp { } else if (wParam.readUInt32LE(0) === 0xf030) { // SC_MAXIMIZE eventName = 'maximize'; + this.showTrayBalloon(); } else if (wParam.readUInt32LE(0) === 0xf020) { // SC_MINIMIZE eventName = 'minimize'; } else if (wParam.readUInt32LE(0) === 0xf120) { // SC_RESTORE eventName = 'restored'; + this.showTrayBalloon(); } if (eventName !== null) { From 710a582ed4bc9c6df2db9d72e4f63f0631098b7e Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Thu, 24 Jan 2019 21:15:37 +1100 Subject: [PATCH 063/153] docs: Update Readme --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 846c0424e..7a11728a3 100644 --- a/README.md +++ b/README.md @@ -123,6 +123,10 @@ yarn start TASKBAR=false yarn start ``` +> macOS: Taskbar mode is enabled by default +> Windows: Taskbar mode is disabled by default and not supported +> Linux: Taskbar mode is disabled by default due to lack of support from Gnome 3 + ## Join the chat! Get in touch with us on Gitter: From c0b3fa16d8291c9e1b12fa110e6648ddacc44fb6 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Sat, 26 Jan 2019 09:42:50 +1100 Subject: [PATCH 064/153] feat: Save window position on Linux. Refactor events * Save Fether window position on Linux using debounce with 'move' event, and 'close' event * Save Fether window position on macOS and Windows also using 'close' event instead of just 'moved' event * Refactor `create` method to prevent duplication * Refactor to organise event listeners into `setupWindowListeners` and `setupRequestListeners` --- .../fether-electron/src/main/app/index.js | 152 ++++++++++-------- .../src/main/app/options/config/index.js | 2 +- 2 files changed, 90 insertions(+), 64 deletions(-) diff --git a/packages/fether-electron/src/main/app/index.js b/packages/fether-electron/src/main/app/index.js index 9b6be4151..ddec0e0c6 100644 --- a/packages/fether-electron/src/main/app/index.js +++ b/packages/fether-electron/src/main/app/index.js @@ -7,6 +7,7 @@ import parityElectron from '@parity/electron'; import electron, { screen, Tray } from 'electron'; import Positioner from 'electron-positioner'; import events from 'events'; +import debounce from 'lodash/debounce'; import { productName } from '../../../electron-builder.json'; import Pino from './utils/pino'; @@ -42,67 +43,32 @@ class FetherApp { this.fetherApp.app = electronApp; this.fetherApp.options = options; - this.addListeners(); + this.setupAppListeners(); this.fetherApp.emit('create-app'); - if (options.withTaskbar) { - this.createWindow(); - this.fetherApp.window.setProgressBar(0.4); - - this.createPositioner(); - this.createTray(); - this.loadTaskbar(); - this.fetherApp.window.setProgressBar(0.6); - - this.finalise(); - this.fetherApp.window.setProgressBar(0.8); - } else { - this.fetherApp.window = new BrowserWindow(options); - this.fetherApp.window.setProgressBar(0.4); - - if (process.platform !== 'darwin') { - /** - * Showing the Fether menu bar in the frame on Windows causes the - * Feedback button to be cropped, so do not show it by default. The - * user will need to be informed that pressing ALT displays the Fether menu - */ - this.fetherApp.window.setAutoHideMenuBar(true); // ALT shows menu bar - this.fetherApp.window.setMenuBarVisibility(false); - } + this.createWindow(); + this.fetherApp.window.setProgressBar(0.4); - // Opens file:///path/to/build/index.html in prod mode, or whatever is - // passed to ELECTRON_START_URL - this.fetherApp.window.loadURL(options.index); + this.createPositioner(); + this.createTray(); + this.setupRequestListeners(); + this.setupWindowListeners(); - this.createPositioner(); - this.createTray(); - - this.debugSetup(); - - this.finalise(); - this.fetherApp.window.setProgressBar(0.8); + if (options.withTaskbar) { + this.loadTaskbar(); } + this.fetherApp.window.setProgressBar(0.6); + + this.debugSetup(); + this.finalise(); + this.fetherApp.window.setProgressBar(0.8); this.showWindow(undefined); this.fetherApp.window.setProgressBar(1.0); this.fetherApp.window.setProgressBar(-1); this.fetherApp.emit('after-create-app'); - - // macOS (not Windows) - this.fetherApp.window.on('moved', () => { - this.processMoved(); - }); - - // macOS (not Windows) - this.fetherApp.window.on('resize', () => { - console.log('Detected resize event'); - this.moveWindowUp(); - setTimeout(() => { - this.moveWindowUp(); - }, 5000); - }); }; // Enable with `DEBUG=true yarn start` and access Developer Tools @@ -150,15 +116,17 @@ class FetherApp { global.wsInterface = cli.wsInterface; global.wsPort = cli.wsPort; + // Add application menu + addMenu(this.fetherApp.window); + pino.info('Finished configuring Electron menu'); + }; + + setupRequestListeners = () => { // Listen to messages from renderer process ipcMain.on('asynchronous-message', (...args) => { return messages(this.fetherApp.window, ...args); }); - // Add application menu - addMenu(this.fetherApp.window); - pino.info('Finished configuring Electron menu'); - // WS calls have Origin `file://` by default, which is not trusted. // We override Origin header on all WS connections with an authorized one. session.defaultSession.webRequest.onBeforeSendHeaders( @@ -177,23 +145,70 @@ class FetherApp { callback({ requestHeaders: details.requestHeaders }); // eslint-disable-line } ); + }; + setupWindowListeners = () => { // Open external links in browser this.fetherApp.window.webContents.on('new-window', (event, url) => { event.preventDefault(); electron.shell.openExternal(url); }); + // Linux (unchecked on others) + this.fetherApp.window.on('move', () => { + /** + * On Linux using this with debouncing is the closest equivalent + * to using 'moved' (not supported on Linux) with debouncing + */ + debounce(() => { + this.processMoved(); + }, 5000); + }); + + // macOS (not Windows or Linux) + this.fetherApp.window.on('moved', () => { + /** + * On macOS save the position in the 'moved' event since if + * we run it just in 'close' instead, then if the Fether app + * crashes after they've moved the Fether window then it won't run + * 'close' and it won't save the window position. + * + * On Windows we use the equivalent WM_EXITSIZEMOVE that detects + * the equivalent of 'moved' + * + * On Linux the closest equivalent to achieving 'moved' is debouncing + * on the 'move' event. It also works in 'close' even when app crashes + */ + this.processMoved(); + }); + + // macOS and Linux (not Windows) + this.fetherApp.window.on('resize', () => { + console.log('Detected resize event'); + this.moveWindowUp(); + setTimeout(() => { + this.moveWindowUp(); + }, 5000); + }); + + this.fetherApp.window.on('blur', () => { + this.fetherApp.options.alwaysOnTop ? this.emitBlur() : this.hideWindow(); + }); + + this.fetherApp.window.on('close', () => { + this.onClose(); + }); + this.fetherApp.window.on('closed', () => { this.fetherApp.window = null; this.fetherApp.emit('after-closed-window'); }); - this.addWindowsListeners(); + this.addWin32Listeners(); }; - addWindowsListeners = () => { + addWin32Listeners = () => { if (process.platform === 'win32') { /** * Hook WM_SYSKEYUP @@ -231,6 +246,7 @@ class FetherApp { if (wParam.readUInt32LE(0) === 0xf060) { // SC_CLOSE eventName = 'close'; + this.onClose(); } else if (wParam.readUInt32LE(0) === 0xf030) { // SC_MAXIMIZE eventName = 'maximize'; @@ -418,20 +434,25 @@ class FetherApp { this.fetherApp.window = new BrowserWindow(options); - this.fetherApp.window.on('blur', () => { - options.alwaysOnTop ? this.emitBlur() : this.hideWindow(); - }); - if (options.showOnAllWorkspaces !== false) { this.fetherApp.window.setVisibleOnAllWorkspaces(true); } - this.fetherApp.window.on('close', this.windowClear); + if (process.platform !== 'darwin') { + /** + * Toggle the Fether menu bar in the frame on Windows. Note that + * if not shown by default then when it is shown it causes cropping of the bottom + * of the window when menu open/close toggled. The user will need to be informed + * that pressing ALT displays the Fether menu + */ + this.fetherApp.window.setAutoHideMenuBar(true); // ALT shows menu bar + this.fetherApp.window.setMenuBarVisibility(false); + } + // Opens file:///path/to/build/index.html in prod mode, or whatever is + // passed to ELECTRON_START_URL this.fetherApp.window.loadURL(options.index); - this.debugSetup(); - this.fetherApp.emit('after-create-window'); }; @@ -623,6 +644,11 @@ class FetherApp { this.fetherApp.emit('blur-window'); }; + onClose = () => { + this.processMoved(); + this.windowClear(); + }; + clickedTray = (e, bounds) => { const { cachedBounds, window } = this.fetherApp; @@ -641,7 +667,7 @@ class FetherApp { this.showWindow(this.fetherApp.cachedBounds); }; - addListeners = () => { + setupAppListeners = () => { this.fetherApp.on('create-app', () => { pino.info( `Starting ${productName} (${ diff --git a/packages/fether-electron/src/main/app/options/config/index.js b/packages/fether-electron/src/main/app/options/config/index.js index 03b4d5a17..34024d934 100644 --- a/packages/fether-electron/src/main/app/options/config/index.js +++ b/packages/fether-electron/src/main/app/options/config/index.js @@ -35,7 +35,7 @@ const DEFAULT_OPTIONS = { icon: ICON_PATH, index: INDEX_HTML_PATH, resizable: false, - show: true, + show: false, tabbingIdentifier: 'parity', webPreferences: { devTools: shouldUseDevTools, // Security From 3e606c2ef282b85810b10b3e997445218434be2a Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Sat, 26 Jan 2019 11:37:02 +1100 Subject: [PATCH 065/153] fix: Fix save windows position on minimise on Linux. Add taskbar usage to Readme * Update Readme with Usage of taskbar mode on macOS and Linux * Remvoe custom context menu since was not working and we will use ALT version instead * Rename processMoved to saveWindowPosition * Fix by savingWindowPosition when user minimises Fether window so it restores to same position * Change tooltip message to 'Click to toggle Fether window' since it is important on Linux as use must click the tooltip to open/close the Fether window * Only disable taskbar mode on Windows --- README.md | 36 +++++++++++++++-- .../fether-electron/src/main/app/index.js | 40 +++++++++---------- .../src/main/app/options/config/index.js | 4 +- packages/fether-electron/src/main/index.js | 4 +- 4 files changed, 55 insertions(+), 29 deletions(-) diff --git a/README.md b/README.md index 7a11728a3..e94667240 100644 --- a/README.md +++ b/README.md @@ -113,7 +113,7 @@ yarn package yarn start ``` -> Troubleshooting: If it hangs on a white screen in Electron even though it has compiled and has been syncing for a long time, then simply choose 'View > Reload' (CMD + R on macOS) from the Electron menu +> Troubleshooting: If it hangs on a white screen in Electron even though it has compiled and has been syncing for a long time, then simply choose 'View > Reload' (CMD + R on macOS) from the Fether/Electron menu. If the Fether menu is not shown in the tray, then by clicking the Fether window and then holding down the ALT key to reveal it. > Developer Tools: Open developer tools automatically by running `DEBUG=true yarn start` when not in the production environment @@ -123,9 +123,37 @@ yarn start TASKBAR=false yarn start ``` -> macOS: Taskbar mode is enabled by default -> Windows: Taskbar mode is disabled by default and not supported -> Linux: Taskbar mode is disabled by default due to lack of support from Gnome 3 +# Usage of taskbar mode + +### macOS + +Taskbar mode is `true` by default. + +* Enabled `true` + * Fether window may be toggled open/closed by clicking the Fether tray icon, but not the Fether dock icon + * Fether window does not have a frame (i.e. no close/minimise icons) +* Disabled `false` + * Fether window may be toggled opened by clicking the Fether dock icon + * Fether window has a frame (with close/minimise icons) +* Always + * Fether menu shown in the tray by default + * Fether window position is saved upon move, minimising, and close so it is restored in the same position. + +### Linux + +Taskbar mode is `true` by default. + +* Enabled `true` + * Fether window may be toggled minimise/restore by clicking the Fether tray icon to reveal a tooltip + that says "Click to toggle Fether window" and then clicking the tooltip. + * Fether window does not have a frame (i.e. no close/minimise icons) +* Disabled `false` + * Fether window may be toggled opened by clicking the Fether dock icon + * Fether window has a frame (with close/minimise icons) +* Always + * Fether menu is not shown in the tray by default. Show the Fether menu in the tray by clicking + the Fether window and then holding down the ALT key to reveal it. + * Fether window position is saved upon move, minimising, and close so it is restored in the same position. ## Join the chat! diff --git a/packages/fether-electron/src/main/app/index.js b/packages/fether-electron/src/main/app/index.js index ddec0e0c6..bf2db1ddf 100644 --- a/packages/fether-electron/src/main/app/index.js +++ b/packages/fether-electron/src/main/app/index.js @@ -17,7 +17,7 @@ import { hasSavedWindowPosition, saveWindowPosition } from './settings'; -import { addMenu, getMenu } from './menu'; +import { addMenu } from './menu'; import cli from './cli'; import messages from './messages'; import ParityEthereum from './parityEthereum'; @@ -89,13 +89,11 @@ class FetherApp { }; showTrayBalloon = () => { - let { options, tray } = this.fetherApp; + let { tray } = this.fetherApp; tray.displayBalloon({ title: 'Fether Menu', - content: `Press ALT ${ - options.withTaskbar ? '-M' : '' - } in the Fether window to toggle the menu` + content: `Press ALT in the Fether window to toggle the menu` }); }; @@ -161,7 +159,7 @@ class FetherApp { * to using 'moved' (not supported on Linux) with debouncing */ debounce(() => { - this.processMoved(); + this.saveWindowPosition(); }, 5000); }); @@ -179,7 +177,7 @@ class FetherApp { * On Linux the closest equivalent to achieving 'moved' is debouncing * on the 'move' event. It also works in 'close' even when app crashes */ - this.processMoved(); + this.saveWindowPosition(); }); // macOS and Linux (not Windows) @@ -222,11 +220,12 @@ class FetherApp { Number.parseInt('0x0105'), (wParam, lParam) => { // Reference: https://nodejs.org/api/buffer.html - if (wParam && wParam.readUInt32LE(0) === 77) { - let { tray } = this.fetherApp; - tray.setContextMenu(getMenu()); + /** + * Detect when user presses ALT+keyCode. + * i.e. Use `wParam && wParam.readUInt32LE(0) === 77` to detect ALT+m + */ + if (wParam) { this.showTrayBalloon(); - tray.popUpContextMenu(); } } ); @@ -254,6 +253,7 @@ class FetherApp { } else if (wParam.readUInt32LE(0) === 0xf020) { // SC_MINIMIZE eventName = 'minimize'; + this.onClose(); } else if (wParam.readUInt32LE(0) === 0xf120) { // SC_RESTORE eventName = 'restored'; @@ -287,7 +287,7 @@ class FetherApp { }, 5000); // Save Fether window position to Electron settings - this.processMoved(); + this.saveWindowPosition(); } ); } @@ -325,7 +325,7 @@ class FetherApp { } }; - processMoved = () => { + saveWindowPosition = () => { const { previousScreenResolution } = this.fetherApp; const currentScreenResolution = this.getScreenResolution(); @@ -399,8 +399,6 @@ class FetherApp { // Note: See https://github.com/RocketChat/Rocket.Chat.Electron/issues/44 if (process.platform === 'win32') { - // Set context menu for tray icon - tray.setContextMenu(getMenu()); this.showTrayBalloon(); } @@ -410,9 +408,7 @@ class FetherApp { tray.on('right-click', () => { if (process.platform === 'win32') { console.log('Detected right click on Windows'); - tray.setContextMenu(getMenu()); this.showTrayBalloon(); - tray.popUpContextMenu(); } }); tray.setToolTip(options.tooltip); @@ -524,13 +520,15 @@ class FetherApp { hideWindow = () => { const { supportsTrayHighlightState, tray } = this.fetherApp; + if (!this.fetherApp.window) { + return; + } + if (supportsTrayHighlightState) { tray.setHighlightMode('never'); } - if (!this.fetherApp.window) { - return; - } + this.saveWindowPosition(); // Save window position when hide, particularly necessary on Linux this.fetherApp.emit('hide-window'); this.fetherApp.window.hide(); @@ -645,7 +643,7 @@ class FetherApp { }; onClose = () => { - this.processMoved(); + this.saveWindowPosition(); this.windowClear(); }; diff --git a/packages/fether-electron/src/main/app/options/config/index.js b/packages/fether-electron/src/main/app/options/config/index.js index 34024d934..7b6b5702f 100644 --- a/packages/fether-electron/src/main/app/options/config/index.js +++ b/packages/fether-electron/src/main/app/options/config/index.js @@ -53,7 +53,9 @@ const TASKBAR_OPTIONS = { height: 464, show: false, // Run showWindow later when taskbar has loaded in FetherApp showDockIcon: true, - tooltip: 'Parity Fether', + // On Linux the user must click the tray icon and then click the tooltip + // to toggle the Fether window open/close + tooltip: 'Click to toggle Fether window', width: 352, withTaskbar: true }; diff --git a/packages/fether-electron/src/main/index.js b/packages/fether-electron/src/main/index.js index 1138fe177..908097db5 100644 --- a/packages/fether-electron/src/main/index.js +++ b/packages/fether-electron/src/main/index.js @@ -21,9 +21,7 @@ if (!['darwin', 'win32'].includes(process.platform)) { app.disableHardwareAcceleration(); } -if (process.platform !== 'darwin') { - // Disable taskbar mode on Windows since ALT-M menu items do not trigger - // Disable taskbar mode on Linux since not supported by Gnome 3 +if (process.platform === 'win32') { withTaskbar = false; } From aad638b74e770359bc60c21d23cbdacc67abeba5 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Sat, 26 Jan 2019 11:48:36 +1100 Subject: [PATCH 066/153] fix: Reduce debounce to 1s so on Linux if crash 1s after move it saves position --- packages/fether-electron/src/main/app/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/fether-electron/src/main/app/index.js b/packages/fether-electron/src/main/app/index.js index bf2db1ddf..16c384756 100644 --- a/packages/fether-electron/src/main/app/index.js +++ b/packages/fether-electron/src/main/app/index.js @@ -160,7 +160,7 @@ class FetherApp { */ debounce(() => { this.saveWindowPosition(); - }, 5000); + }, 1000); }); // macOS (not Windows or Linux) From e68c7634b6fa0da84c17e40893f42af54049a458 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Sat, 26 Jan 2019 12:49:58 +1100 Subject: [PATCH 067/153] fix: Minimise should only save position, not kill window object too --- packages/fether-electron/src/main/app/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/fether-electron/src/main/app/index.js b/packages/fether-electron/src/main/app/index.js index 16c384756..cf6e5890c 100644 --- a/packages/fether-electron/src/main/app/index.js +++ b/packages/fether-electron/src/main/app/index.js @@ -253,7 +253,7 @@ class FetherApp { } else if (wParam.readUInt32LE(0) === 0xf020) { // SC_MINIMIZE eventName = 'minimize'; - this.onClose(); + this.saveWindowPosition(); } else if (wParam.readUInt32LE(0) === 0xf120) { // SC_RESTORE eventName = 'restored'; From 2068b6054c376f771a16101fc0e9b1439e6283be Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Sat, 26 Jan 2019 14:10:03 +1100 Subject: [PATCH 068/153] fix: Fix so unregisters relevant listeners when click close button instead of crashing --- packages/fether-electron/src/main/app/index.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/packages/fether-electron/src/main/app/index.js b/packages/fether-electron/src/main/app/index.js index cf6e5890c..8355bcfb4 100644 --- a/packages/fether-electron/src/main/app/index.js +++ b/packages/fether-electron/src/main/app/index.js @@ -302,6 +302,10 @@ class FetherApp { * automatically move the window upward so it is viewable to the user */ moveWindowUp = () => { + if (!this.fetherApp.window) { + return; + } + console.log( 'Fether window resized. Moving it back up into view if required' ); @@ -326,6 +330,10 @@ class FetherApp { }; saveWindowPosition = () => { + if (!this.fetherApp.window) { + return; + } + const { previousScreenResolution } = this.fetherApp; const currentScreenResolution = this.getScreenResolution(); @@ -634,6 +642,11 @@ class FetherApp { }; windowClear = () => { + // Remove relevant events when window object deleted + const events = ['close', 'move', 'moved', 'resize']; + for (let event in events) { + this.fetherApp.window.removeAllListeners(event); + } delete this.fetherApp.window; this.fetherApp.emit('after-close-window'); }; From 3ae04f8f97e1879339ab2f318761b8f70b528e04 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Sat, 26 Jan 2019 14:10:53 +1100 Subject: [PATCH 069/153] docs: Update Readme with Windows non-taskbar info --- README.md | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e94667240..234b956cf 100644 --- a/README.md +++ b/README.md @@ -133,7 +133,7 @@ Taskbar mode is `true` by default. * Fether window may be toggled open/closed by clicking the Fether tray icon, but not the Fether dock icon * Fether window does not have a frame (i.e. no close/minimise icons) * Disabled `false` - * Fether window may be toggled opened by clicking the Fether dock icon + * Fether window may be toggled open by clicking the Fether dock icon * Fether window has a frame (with close/minimise icons) * Always * Fether menu shown in the tray by default @@ -148,13 +148,25 @@ Taskbar mode is `true` by default. that says "Click to toggle Fether window" and then clicking the tooltip. * Fether window does not have a frame (i.e. no close/minimise icons) * Disabled `false` - * Fether window may be toggled opened by clicking the Fether dock icon + * Fether window may be toggled open by clicking the Fether dock icon * Fether window has a frame (with close/minimise icons) * Always * Fether menu is not shown in the tray by default. Show the Fether menu in the tray by clicking the Fether window and then holding down the ALT key to reveal it. * Fether window position is saved upon move, minimising, and close so it is restored in the same position. +### Windows + +Taskbar mode is always `false` since the Fether menu does not appear without a frame on the Fether window. + +* Disabled `false` + * Fether window may be toggled open/minimise by clicking the Fether dock icon + * Fether window has a frame (with close/minimise icons). +* Always + * Fether menu is shown in the Fether window by clicking the Fether window and then holding down the ALT key to reveal it. + * Fether tray icon does nothing + * Fether window position is saved upon move, minimising, and close so it is restored in the same position. + ## Join the chat! Get in touch with us on Gitter: From 93598904817a4bf61ea92f8d5b56d2b12d579ba0 Mon Sep 17 00:00:00 2001 From: Amaury Martiny Date: Wed, 30 Jan 2019 10:24:11 +0100 Subject: [PATCH 070/153] Move icons to static folder --- .../src/main/app/options/config/index.js | 10 ++++++---- .../assets}/icons/_parity-ethereum-fether-icon.png | Bin .../assets}/icons/parity-ethereum-fether-icon.png | Bin .../assets}/icons/parity-ethereum-fether-icon@2.png | Bin .../assets}/icons/parity-ethereum-fether-icon@3.png | Bin 5 files changed, 6 insertions(+), 4 deletions(-) rename packages/fether-electron/{src/main/app/options/config => static/assets}/icons/_parity-ethereum-fether-icon.png (100%) rename packages/fether-electron/{src/main/app/options/config => static/assets}/icons/parity-ethereum-fether-icon.png (100%) rename packages/fether-electron/{src/main/app/options/config => static/assets}/icons/parity-ethereum-fether-icon@2.png (100%) rename packages/fether-electron/{src/main/app/options/config => static/assets}/icons/parity-ethereum-fether-icon@3.png (100%) diff --git a/packages/fether-electron/src/main/app/options/config/index.js b/packages/fether-electron/src/main/app/options/config/index.js index 7b6b5702f..981df7155 100644 --- a/packages/fether-electron/src/main/app/options/config/index.js +++ b/packages/fether-electron/src/main/app/options/config/index.js @@ -17,10 +17,12 @@ const INDEX_HTML_PATH = }); // Icon path differs when started with `yarn electron` or `yarn start` -const ICON_PATH = - process.env.ELECTRON_START_ICON || process.env.SKIP_PREFLIGHT_CHECK - ? 'src/main/app/options/config/icons/parity-ethereum-fether-icon.png' - : path.join(__dirname, 'icons', 'parity-ethereum-fether-icon.png'); +const ICON_PATH = path.join( + staticPath, + 'assets', + 'icons', + 'parity-ethereum-fether-icon.png' +); const shouldUseDevTools = process.env.NODE_ENV !== 'production'; diff --git a/packages/fether-electron/src/main/app/options/config/icons/_parity-ethereum-fether-icon.png b/packages/fether-electron/static/assets/icons/_parity-ethereum-fether-icon.png similarity index 100% rename from packages/fether-electron/src/main/app/options/config/icons/_parity-ethereum-fether-icon.png rename to packages/fether-electron/static/assets/icons/_parity-ethereum-fether-icon.png diff --git a/packages/fether-electron/src/main/app/options/config/icons/parity-ethereum-fether-icon.png b/packages/fether-electron/static/assets/icons/parity-ethereum-fether-icon.png similarity index 100% rename from packages/fether-electron/src/main/app/options/config/icons/parity-ethereum-fether-icon.png rename to packages/fether-electron/static/assets/icons/parity-ethereum-fether-icon.png diff --git a/packages/fether-electron/src/main/app/options/config/icons/parity-ethereum-fether-icon@2.png b/packages/fether-electron/static/assets/icons/parity-ethereum-fether-icon@2.png similarity index 100% rename from packages/fether-electron/src/main/app/options/config/icons/parity-ethereum-fether-icon@2.png rename to packages/fether-electron/static/assets/icons/parity-ethereum-fether-icon@2.png diff --git a/packages/fether-electron/src/main/app/options/config/icons/parity-ethereum-fether-icon@3.png b/packages/fether-electron/static/assets/icons/parity-ethereum-fether-icon@3.png similarity index 100% rename from packages/fether-electron/src/main/app/options/config/icons/parity-ethereum-fether-icon@3.png rename to packages/fether-electron/static/assets/icons/parity-ethereum-fether-icon@3.png From 83114f1d31db50299bf98bcb84a0585f30cf31c2 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Thu, 31 Jan 2019 10:14:52 +1100 Subject: [PATCH 071/153] fix: Remove unused image --- .../assets/icons/_parity-ethereum-fether-icon.png | Bin 590 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 packages/fether-electron/static/assets/icons/_parity-ethereum-fether-icon.png diff --git a/packages/fether-electron/static/assets/icons/_parity-ethereum-fether-icon.png b/packages/fether-electron/static/assets/icons/_parity-ethereum-fether-icon.png deleted file mode 100644 index 00dc72e2299b80e8f7319f946c351336d64e20fe..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 590 zcmV-U06$Q5YMaTdE0ozGL zK~y-)jZ;Bu6JZd2-)wOWnEg#||7sN1UuAwcpqfK+%Y$8n$z zs4z_vN471GeU0S05CVeaD1bU7eA?MT+iSzN>!|Ek@b=9LB5+dy@JP;n*xp7mnS|f= zp$G->cpRJWHlqk0DgbWD+1Nk~KN=03o&7|qR6;tPhOX;T1XBut>)punJQy1rP*oLA zi$x?g4Rzaw`O(B!Duu^|IRrrvCKy-3Q6iDR?THDjuB{?_Hw&{|Ms|7{)q^kietL>a zu^28ce)o)^0H}6@U+3rWJRdXnW-xqt7>&*vxm*rQuU_KH$Owjp2E+XpNInZ6xY=y7 zY?}0ZpCq}sxJ2vlkas30={U!-9(0f#m9u|?fQDi4_~eB5^Laj*pQr1(QG&`SLWpkw zmV5S6RouvAP_2H&gV{WG_x7M^ntTC62yxI?%9drZP?+m0<-TSj$*ryT{mt~BcK%HA cMU Date: Thu, 31 Jan 2019 13:11:53 +1100 Subject: [PATCH 072/153] chore: Add copyright to electron-builder config --- packages/fether-electron/electron-builder.json | 1 + .../assets/icons/parity-ethereum-fether-icon.png | Bin 590 -> 0 bytes .../icons/parity-ethereum-fether-icon@2.png | Bin 1417 -> 0 bytes .../icons/parity-ethereum-fether-icon@3.png | Bin 2292 -> 0 bytes 4 files changed, 1 insertion(+) delete mode 100644 packages/fether-electron/static/assets/icons/parity-ethereum-fether-icon.png delete mode 100644 packages/fether-electron/static/assets/icons/parity-ethereum-fether-icon@2.png delete mode 100644 packages/fether-electron/static/assets/icons/parity-ethereum-fether-icon@3.png diff --git a/packages/fether-electron/electron-builder.json b/packages/fether-electron/electron-builder.json index cfad34938..95ccbd415 100644 --- a/packages/fether-electron/electron-builder.json +++ b/packages/fether-electron/electron-builder.json @@ -1,5 +1,6 @@ { "appId": "io.parity.fether", + "copyright": "Copyright 2015-2018 Parity Technologies (UK) Ltd.", "linux": { "category": "Utility", "target": ["AppImage", "snap", "deb", "tar.xz"] diff --git a/packages/fether-electron/static/assets/icons/parity-ethereum-fether-icon.png b/packages/fether-electron/static/assets/icons/parity-ethereum-fether-icon.png deleted file mode 100644 index 00dc72e2299b80e8f7319f946c351336d64e20fe..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 590 zcmV-U06$Q5YMaTdE0ozGL zK~y-)jZ;Bu6JZd2-)wOWnEg#||7sN1UuAwcpqfK+%Y$8n$z zs4z_vN471GeU0S05CVeaD1bU7eA?MT+iSzN>!|Ek@b=9LB5+dy@JP;n*xp7mnS|f= zp$G->cpRJWHlqk0DgbWD+1Nk~KN=03o&7|qR6;tPhOX;T1XBut>)punJQy1rP*oLA zi$x?g4Rzaw`O(B!Duu^|IRrrvCKy-3Q6iDR?THDjuB{?_Hw&{|Ms|7{)q^kietL>a zu^28ce)o)^0H}6@U+3rWJRdXnW-xqt7>&*vxm*rQuU_KH$Owjp2E+XpNInZ6xY=y7 zY?}0ZpCq}sxJ2vlkas30={U!-9(0f#m9u|?fQDi4_~eB5^Laj*pQr1(QG&`SLWpkw zmV5S6RouvAP_2H&gV{WG_x7M^ntTC62yxI?%9drZP?+m0<-TSj$*ryT{mt~BcK%HA cMU6coi!RC@pb1r|v} zK~z}7y_aiDm317)zmIklMaocfh__S}(#(}2#%ilgMRd0EmNu`i)LeMQA+2eGptIa? z_QEx{*pi8OSq5GZ^R96<5O1J34`N(A2wu+N96g_22xO+`d3aI(H_!8IzvuV={=UDv zAs+{jVHg4oNkNhZN*XC?f}~-RdP*`R)kwM|>4>CrlCDdtG7Q7pqNB|RXn6(#SwIce zPaTj01V5{*trzw0^vSEJY#tn z@X(6Zrluw$-jC#$0|%^#JArqf2Vp#Kxugq{I-9XnQc|K_>AU50KGJuaH_PR6$^GOBj}5~(_b=<4eQrwolP6Euv113b=gtMdURgH(<*<*Pn;lb%^I$il>v~vaT6W={1_iKfjf8Z;P!a%TBG4O z&|W|gP;DmN*w{!?ax#mTECJxrqeq-MdzKCzJCeRT1Gn4F%2lff2nc9(hsn7M^l2w) zfTSL#QGfBGX3d?Tzow7 z@m~W_bm0O)!MzFY)0f}#^4OEHhc2(ahKzQE3<>3y-A;OXI+8eh?!0Me$yWg8<>#{@ zDT$hzr;Tvx^cmP}Hd0bjaJpP1Zb(8BlE}L?9~} zaN^`ix&#Ce_SR4e3yZMZ?L<$UL{M-rW5!2xsax(xwrKYkoEe(Kq^A{kAWy_xy&QYUB)5*UJlE^xEkcErCB(QrA_U+$~%jvS@ zf(&0SC@d;!{hl^`25$}+$REYU)YjG#J#i9}7#Ti_-5D9YH*yqX$BpOl&gXMMqA zkH-waN0v+RiIXRZS-O;pn}2ugd-eBP>q1$1Im3p(L#NLE96NT*jQZA6Y`GcL)z!7O z<5QpepWBv^pDxF zEhAY&LjwyJEh4|55U;>bvrHR<%@laJ&g(T+9Utra8 zCotyOJB=5tVPTT;%_ifVoE&*P9`)XRx}N_9 XQzc~FSC;b#00000NkvXXu0mjf^Sq!t diff --git a/packages/fether-electron/static/assets/icons/parity-ethereum-fether-icon@3.png b/packages/fether-electron/static/assets/icons/parity-ethereum-fether-icon@3.png deleted file mode 100644 index 1d7435a64de4c028a1d5e9073dd1e141d54f7950..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2292 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 Date: Thu, 31 Jan 2019 13:14:09 +1100 Subject: [PATCH 073/153] fix: Add new taskbar icons with higher DPI --- .../src/main/app/options/config/index.js | 7 +------ .../static/assets/icons/icon.png | Bin 0 -> 2199 bytes .../static/assets/icons/icon@2x.png | Bin 0 -> 3181 bytes .../static/assets/icons/icon@3x.png | Bin 0 -> 4899 bytes .../static/assets/icons/icon@4x.png | Bin 0 -> 9430 bytes .../static/assets/icons/icon@5x.png | Bin 0 -> 20607 bytes 6 files changed, 1 insertion(+), 6 deletions(-) create mode 100644 packages/fether-electron/static/assets/icons/icon.png create mode 100644 packages/fether-electron/static/assets/icons/icon@2x.png create mode 100644 packages/fether-electron/static/assets/icons/icon@3x.png create mode 100644 packages/fether-electron/static/assets/icons/icon@4x.png create mode 100644 packages/fether-electron/static/assets/icons/icon@5x.png diff --git a/packages/fether-electron/src/main/app/options/config/index.js b/packages/fether-electron/src/main/app/options/config/index.js index 981df7155..df140570b 100644 --- a/packages/fether-electron/src/main/app/options/config/index.js +++ b/packages/fether-electron/src/main/app/options/config/index.js @@ -17,12 +17,7 @@ const INDEX_HTML_PATH = }); // Icon path differs when started with `yarn electron` or `yarn start` -const ICON_PATH = path.join( - staticPath, - 'assets', - 'icons', - 'parity-ethereum-fether-icon.png' -); +const ICON_PATH = path.join(staticPath, 'assets', 'icons', 'icon.png'); const shouldUseDevTools = process.env.NODE_ENV !== 'production'; diff --git a/packages/fether-electron/static/assets/icons/icon.png b/packages/fether-electron/static/assets/icons/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..0e3e52463bb3264288b2ff4a1682bbe7672e603c GIT binary patch literal 2199 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 A7XSbN literal 0 HcmV?d00001 diff --git a/packages/fether-electron/static/assets/icons/icon@5x.png b/packages/fether-electron/static/assets/icons/icon@5x.png new file mode 100644 index 0000000000000000000000000000000000000000..7d90fe6210006212de371179f21868e28cb7a75c GIT binary patch literal 20607 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 E3uT4g^8f$< literal 0 HcmV?d00001 From d2acf13592abaa241cef461e1eef0a0427dfa92b Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Thu, 31 Jan 2019 15:15:55 +1100 Subject: [PATCH 074/153] temp: Try adding more icons to see how to increase windows taskbar icon quality --- .../fether-electron/build/icons/1024x1024.png | Bin 0 -> 40762 bytes .../fether-electron/build/icons/128x128.png | Bin 0 -> 9430 bytes packages/fether-electron/build/icons/16x16.png | Bin 0 -> 2199 bytes .../fether-electron/build/icons/256x256.png | Bin 0 -> 20607 bytes packages/fether-electron/build/icons/32x32.png | Bin 0 -> 3181 bytes packages/fether-electron/build/icons/48x48.png | Bin 0 -> 4179 bytes .../fether-electron/build/icons/512x512.png | Bin 0 -> 48459 bytes packages/fether-electron/build/icons/64x64.png | Bin 0 -> 4899 bytes packages/fether-electron/build/icons/icon.ico | Bin 0 -> 40762 bytes .../static/assets/icons/1024x1024.png | Bin 0 -> 40762 bytes .../static/assets/icons/128x128.png | Bin 0 -> 9430 bytes .../static/assets/icons/16x16.png | Bin 0 -> 2199 bytes .../static/assets/icons/256x256.png | Bin 0 -> 20607 bytes .../static/assets/icons/32x32.png | Bin 0 -> 3181 bytes .../static/assets/icons/48x48.png | Bin 0 -> 4179 bytes .../static/assets/icons/512x512.png | Bin 0 -> 48459 bytes .../static/assets/icons/64x64.png | Bin 0 -> 4899 bytes .../static/assets/icons/icon.ico | Bin 0 -> 40762 bytes 18 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 packages/fether-electron/build/icons/1024x1024.png create mode 100644 packages/fether-electron/build/icons/128x128.png create mode 100644 packages/fether-electron/build/icons/16x16.png create mode 100644 packages/fether-electron/build/icons/256x256.png create mode 100644 packages/fether-electron/build/icons/32x32.png create mode 100644 packages/fether-electron/build/icons/48x48.png create mode 100644 packages/fether-electron/build/icons/512x512.png create mode 100644 packages/fether-electron/build/icons/64x64.png create mode 100644 packages/fether-electron/build/icons/icon.ico create mode 100644 packages/fether-electron/static/assets/icons/1024x1024.png create mode 100644 packages/fether-electron/static/assets/icons/128x128.png create mode 100644 packages/fether-electron/static/assets/icons/16x16.png create mode 100644 packages/fether-electron/static/assets/icons/256x256.png create mode 100644 packages/fether-electron/static/assets/icons/32x32.png create mode 100644 packages/fether-electron/static/assets/icons/48x48.png create mode 100644 packages/fether-electron/static/assets/icons/512x512.png create mode 100644 packages/fether-electron/static/assets/icons/64x64.png create mode 100644 packages/fether-electron/static/assets/icons/icon.ico diff --git a/packages/fether-electron/build/icons/1024x1024.png b/packages/fether-electron/build/icons/1024x1024.png new file mode 100644 index 0000000000000000000000000000000000000000..bd61e1bfc4fdbe921b43161c08a98fa23157b45c GIT binary patch literal 40762 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%0DLwMw>G%3}T=EK)ViW7Cm)?4G;^%lR4q@J2>r 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 A7XSbN literal 0 HcmV?d00001 diff --git a/packages/fether-electron/build/icons/16x16.png b/packages/fether-electron/build/icons/16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..0e3e52463bb3264288b2ff4a1682bbe7672e603c GIT binary patch literal 2199 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 E3uT4g^8f$< literal 0 HcmV?d00001 diff --git a/packages/fether-electron/build/icons/32x32.png b/packages/fether-electron/build/icons/32x32.png new file mode 100644 index 0000000000000000000000000000000000000000..f33a32c8f0b35ee1ca8b154962727236fe00b387 GIT binary patch literal 3181 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 literal 0 HcmV?d00001 diff --git a/packages/fether-electron/build/icons/512x512.png b/packages/fether-electron/build/icons/512x512.png new file mode 100644 index 0000000000000000000000000000000000000000..8dfc0a6a2e12f4910cdb8d5912777d5d698a34b4 GIT binary patch literal 48459 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 z ztL~cL4uCTSKoOiW`I&nFbFsyoy3p?XzmnD~O@RR5=@f*9eaNblxw%i>Q$TAE=#5j6 z!DnF=DXg1|fY$E1MpT~$JU{9K(1_3RcOg~qRIM*_&49%8%)a8?P>#e`Xt-c^;wxwP zxqNNO+w%_F2Y1e`M%RFMtE(N+Gj$HPAM%3zmA+g=Q(P{){Q0E*=fy8l%-hbuCkuH} zA9*%g@ira>_{i6q(X49mf^2OMXo0swQh=gN_ag5F zP!5?@CGAqN|I7h`5g{-`SL^1^MyHE$7Q#ECe=IaO7fOU6eLd!N^2fEG3$Tvliou2p z#jp;39YQMTzFJD-lNvop|3ak1b`}IWL2?Pv3uB_RooV6`D>EYI_ye3rjL>&pAj0Ly zAN^N(AWH8Ov5$_Oit$E5dB}`xC;8UxdhWc}7i*UHAZ%$C40qfYjNd3PED>oeZ~fAl;Kkz*#raCZ`aL}l=VgF* zZOdL!W$R&PKu$QKxfMpO2YTwqFq%NAT~*(=KQ{stPDF)OVG=|jJUEnYEaYX5eTU?33M=fr}gf69lH z;mhHKEU1%;G62y&Q3cNJH`G-#Cd5H0vch$)n~HqgO~@dUDJvbgA}7;KEw2}Db<9SE zA1y?k2=>DP%$l>VL<94Kt(3iFDg6ciki2u~4lX%Q51#~8rykiXB+h|>wnzeISo?ju zmT7%YHT~dMB-o%7#_Ee4k@?A7{PEW;6pDfaH)s>MO%Cw0UujBjFb{|CgSZE^Ex~r6 zq6{r~A`pgRAW>4lTY@4?65>BiRPE&LPOJ2lq&Gh_Pl3Kw>I%$jf~086fawDznH{K~RUh2& zO`vw8dX0@Jti7~dvEA+?R6Xe%63BiRB^tz9ql;O3gW^r3>rh4F^N|R|sR%xyXOCva zB5(xbrXf6#j=V1J2LU~&?8KmL*w44<2^PbMN8$qD&mV|D!)pku7~D*)l0e0yfFmA4w<$Tm1PYP~M>a9?xFd0Cd^mo?vbLaIH-Qr}JN6N7+!5_N(o)0$=(J+G zp!2uZQ1YDl2{eTHTR6SD3QEKzq&N}`7~6#ZA^z{a3UPv@H8noFt;s$C8?F&gpbBiI z0^-dTDgE0}A}#_$L`5cy3!e2@A}MWO<@_(A-ZCJ{Hrg7#>F$z{6zPx>q(M3bq!mzF zKte(sVTb|g8tHCC1d&E*q`OPHkr+@y;=6dxdC&J3rtT~EUVE*zr5kx}H^vhU_|^%g zOtmR4BIiWmm`^tt%#7-6_T@N_3E$(IY;1^#qk=^Ir=vV2EekY`PHf8eVS4mfdR2<`H5JAPF)|O8b@JDyfn43P`i`MH^{nLKhlxOAB^iFSo!s0b z)JWG@{Yp3wNK#8XvTf2eGtWua=Ac8aRD|pSnZnYWcccosrG|W7`_nGfsxxg0D9#wg zCSJ6_XsJ)f7&OnvDT?NT7B>~ur~m8{`^|ozar|0|a9JA}6=V{DBkbM&P{M~c+gFbu z!B>+UC%@mhZCfrq)d&dZ#TW!zL%5{>Nq~-m2f@?e+MaRl}H znPVx|gVf$S%;Gl>t*Mm&+GWmP+Sx72{W07iB@!;Ln5Dq+>9{EPv4*iJS1~U}OKCC1 zyYT)a2~*1A^dcc%v}?%GlrNZ7;3$3-&)oez)a|fL^${Cq7A-HG%_s?Sev)AkCrz1$ zVC|D|cZ2F^&Oosb74Wgt@ax}D_4+GkY>W7y&~SHWyhAa;;oE=xz5D2J;L}s6S5Z*H z7A*;!1JB*nFwTf4&b2lNYJUNa#w?Rx2PngNH~8!wJu!^;gmdjGn4szEd!C0dv0+U zAv;b}P^D>Iubd#i94koZoA>9{u6+LpF+VL}d$kby?Jd-8+R9A<0=`>p-#{Z^yr);5 z*(?d#;p-F22clB9&1c>wd}?3fKOVdhBZf?7bU((u|Mz$IUoI(#dcNHCA-cJqYS#Q% z5})9C;8oL!(cOUk>GR3KViv8i?a~_>((;)rB_(DJjdnjYEwAO5&&Pg zEN5?i*%iFH*}7|n9K0xRx(MI7{JC0d3TK|lMRQ`s`K#%X@lz}H@VLfVd?B+gWA@;9 zv`~xQu-wpORI@E$V@_|*QNB_hBbhiI6w5!R;8Ad}23rEWPLcX%iI6Gm@64yyO;0iw zVbO|`vX)$iBv1@=#haKj>b}&17ECH70((6Dx!e==oaWgFq#iw{I!@55FHQJd?7s)a z+Z{)a5&SJaJXjT@BufkiluTnEY}a^*F=IQgKQL#va<({Tyyl|8_*Pat%}vx2y>nSe zI?zpHaM~p;fz4%8e9R=_9;`Mb1Red19{o0ys;80}chnT; zKqSY$DH4l;L#&&pOcdN6*6t#3Ww3NgHCk>VTd0%eqW)t@>X;Yc7NLFmq^aiJG_rw2OV#lV$-+shB)GWoaQy|>uBc-U|pTiX*W&8$xcA0;AcQD?KL zYha@Aw4S!tWWp56K{MX}Z9rQw+MU$xDISajq3QKiTSQ@ZLMZH|7nUsvWEY!vH2N*f zZI#2)TRhJfl>uZUAycRQ!b4y(|3zE;!6Lv@oZg%F+_Y@B>D3>E8d6OHW;CDz0y;TC zM;$k}2SU0|QE@tcRE84rOjhW1ur@&0*crufJs zHVX!@8Tg9|b3ic-A7M-7Gzkq8Q1v`?260R0MwZyfVeo}2SN%a#Gwt)PT!E%xDkf$+ zdC3mIO6|`H!XZr3B5T8#w^VMmPx-y+e#o_m&D&4L38q87*K( z2rhT7+!tqhEs=0$Ni9y{1LG?DCx$LXYFu3WsLHo})Y^`t9gc3OC`CC@HUbe}ykTtJ zfK{Rv!d<^dm=jm;_L~T}3U)3hb*X~9Cn6^ygF7h5R+bvoYh3 z9Jna>bd~kGUP;bRL&VE|@^r3Y|^UE$`Ix(jY3)^kBrQ*$CTJZ@8j(o<`tw_2hwzRKeefz^xq2O9hj2+CzZEu433M=h(l|*Ap>Fa%c4X)zp`~mqsk) zjqR;b50h7BGt2YS&F^KPwTwpI$B*(+Zrc5F_X9G%#(DP6^VcG5S7O{3UX~aZ3r71W%Y3VuYm0*Q^k3*w3oilk-rKXBP|Y}jn771r4`(9us?mz8 zn-P!AJa8nZkPnMouRJ$Cm*o+O`yT!KE@D3&`@8w_MYt0_GnSbgw+8&3UY)WP>4?-h z*cN4`nIXtg(C2;>3*{mT?suaK0 z75tyT&r($aq+m-jjTU?Q9sTn)8<{Th#FpEL);Vudt5jeDAOZsKpc)5or z3gDK(@S{*`^#6nA3TXqCi>Dv!rJpPklam_|f8G@GX=GC96R3{YKi$*` zAfgwuj*1h24cxsamEj#%D|nJJqTE#bE0b=bna@E>#@z86L;m$z z{|j>hP7wUk>(5SPFSC6#Y|WV>wGtjxd#rB?Gf2A!bG`na_*7X&_)&A5vdqM}u=2Rf-B)V`&_L=u5EG{mJh-cE7qLU1 zUb)|Upe9f8l6b57%u?qJXCx7du~ts(RV;kuFQOyE#SZSjv|6VJWyeK3Jv1ji-* zV)Y6a&OtTdZ7}KOb(akPT|wruN)+)F(x5jGv=MBN;G5b!bsTi&%QU2F!^)C_s2vaB4l%}zb%;omhTQ-@VFkcLna4r zsO4KCxq_?8SWWtKbAB2H+)swGVtj0iqDB_~ZF(jV)K%sCMi-)vWp|H1q8MYJ9uC#9 zT_&OE;B@MIAXZvLa_LvhB#<=Q)Bu|!z;MI}kQ=QhL?y>&=u{_nRyn^5DNt^*mh=a| z$M^6bOx#IqAWzrx8j1V5+Ji3vFeyQ$8JESl)+$H{RgfIH7DOVuv_-c5EfGBl>xM#R z?bD$JU_YX@QP*q?e&(?Fl;OWy;|#bA9aT1X4^iwzO7_3s?ALErTKB|Pt#`k?#)M(U ziNUX0zD{;0FwOgnX=%P)jbeE8#Y}nl{>bOI9%7#@vh-+&q;I7Bf1Lh8deH^`uCiKH zP8D@d)w>EO^=rY3(||x?vjPh1O8*I5o_DxC1CX4w_afr^I#~}ut4|Z3R(YgA#5}Ts zk+1H$;cvO6dtW;__T&!+e{*_Fp;iQL|Bn{l;(|p%ls9L=GhFx!6Wz zT)7nZkU(_jpW5T+Mc>cw2LTxTq)`ZEBVC={k3CGH>tIaCYQ5GMx7x6dH+UgzJGd6# z6c(gdKhJonqy(6AmrV+EqAqO$b2Wv6xLj-&*!7G)JjH0{mIe1dA^@M9i;_Z+BYM|R zF755m?>Az4y}=p&hf9*xt%J7h+g=#tMRV<-E)c(e+3Gc0;g-je(LCu^UB7=pKgM4~ zK6bY^5qic;d2h2vi7hKJ`!Vn=K$ipBbFh;DIAzlsh~-xPtkzFj0rz>Pl!P;V5I7k@ zZHhH`se2^v`_&|}s`t}cI*E-2M1{eu#2N*olLy$_?xp>gc3-?tr{&t2{b2b|+PV%q zuL0eOQ`5DtiMsL+6lN4m`SY>&RZYYN5DIuVC_E1U=e-xb3NeqQ0^ws_3_t}_b06uZ z8Aup|H*x_cPi}P3R8S^16UraAh~n{wq@pl1xQM2>Pn|` zRMl?rXG~G3dMF;V-fk_z&-@`Nu4U~U#q(z%gy4r%bSWI(Uu=V_G;2YHBVb76=w!*@ z%{{(L8y%+0!5PoI841IS-o3wbNfibAc|7EQEnF~Y0a!N|C);_YT7XqKwUA91I8u?5 z9zYK8Ihp2KQZDw_->-f3rsy2kO5u|(KlmHKpEkXJr;bm^vn{qNhI$GF1(SZiDip$1 z&S@YLpK;`>OacB0qfO5m@iSo`Mekb_Y1?_2Mo^0{V1>|!fYJb%`@aW^Lnqru3))S9 zzi4)YN*X?B^qWJF26A*o>6lXB(>-FMf6Bt?(lpkFEmCV5?v!77=ltYFRh&S&WnUM8`2elv!F7}uxhLk~P17&SDDC%<} z>s~` zM(8yM^lAxs-J>Lh~mB3#s5JEJ~~7;T!XZRBTzbvGgwAA8dR2nUEDIYXwEY zT8Zmimlc3(*k#=!AL^f5qq(KWowWhuTMMPLlQ9VgWCD#y6Mz{R)b( z@Zj+ZG@{RmZR)*`{8PR<{_IcLyICax9NffY7)YfRa0B}EV+|!@8$iaI7Sz7IlG%7r z2=2bUg~q8^p=0<<)GS#saFo%IeBoZSq{m`f$aH0oD!bSKu)_0<8r~uiXZ2c_1;TAO zI4yj;rj*osDsmK8{Z0`y767P8EGuE4n(WH({-ySNwpxp;k$luxmCHLJl&cjc!^9Ya z(>V4~g3Y3m@iq3H^R~AeDR#6%Ych&2vF|yrX?SEX5j78K^cj{J|GPR>vuJdh5gL57 z%L~$4GU6G?BV>iQYjwnBPLs`I*i-x|n}u845GmW@a(gJ5g6qw2PDm$VMO(L#eEeuZ zSLHenxz{z20C~(g`-h$Num5!g>?3+^{V#Dz8t^2Gw}_Xo#)m!e`Kfa2iFeu0^mI~C zkJt+W#K&^L5E}qQub_i|U2QT!2e&mc}``NT!$XSA# z&-C%_D1NQPnYcQlxPQ-lGst$$ta)F>gCXM5j}woSldJXqiX_iaRx_MYn!k9-xC&H^ zhg*09-uqv+lE_}G_Kj%^8%&zZsdAB^PXJ_e>h`7soGRVk-B;i`sVy}ctI~a4$T$bsk)u}2;e^;(b;IU_xJisDN*35#GefBNOF)}0V7dEfG|fq_P9G4L7hON_^1!eT8Uv9U7Jff zk8`u%75SHAd12K1!|Q(`!MLT&YTKWiLE#Q8^;;EJsjZe1anYdI@cuWI7)BVF$e(x_ zX1G)&%vjtJaYF~kWQ;`oQ&BK&?|?73Dt;DZ;8F-BzT3MwNK(;-uQa~Y5uKfWPItDhFpES5e1UC0zSwZ0M7%;dO^liwkw@~PQ;UG1MqJsv=jlQYhVZrz zs$lM%gh3om8WCVX?^YH7qD>tbc zt!w-{eWut&&SV;b+Yxf6i#_B6wL#pOI@y(j5&@7;Nse}IRozXL6U1b9_| z8{H&#H?vLp`~dz44T@p6rTWRmXi-_y;hAz%8##tFSO^5%nuK2XjF>mY|_h*PKO{}56A!7pj* zf$^F?sBI$acqE5~!#|7p#w5K{{g-L#M2Xn7^FkktEHcu)ByflsvVlVmZm2N07jzez zfk_e4ozmR%&&2ne{l-Ec6gx$k&(N-B9MmZ1x-7^D)t>+oz|y=lqK;kiPLt3jvg14fFPlN;4X3jN6&Y_pB^q;i^kXVY zO5Mi&BiOeMNdO%`u#GJFb9LRt1O}v_?U0O(RKaztn+(Ii|0)yq?(aSbeOL1`Rp+q_ zPGOx?No)l`t$X$>JRE6EXrmHv>2_(Qrk2^AMz9n5tGR;k>PFG5s^} zu`|I0s~JL6&H&DW2tR0K!6afbhw>DX5TF9P2E9n#<>zb8=tTfkply{A57a8Q0)sUP>K$Y4N|ty<4J>m3hKR%nO1yb?;I?qVkuC>xyA+@Pk(aH$uRrUHd~*%b z$;U+229Ja9w%!y6jX9v;(FP{Ay0;7MnY&u=1B?dG-=;gywnRG<1jMuF z|8APa>Wu>C+C6K{sKS9%kLOAJPv-KM!#Ds8>sQzp>w(EPTp*jJj^G!2J;RE&{f0(W zE}Bl1o9&N`6s!(2AD9(oxajD~iiK*RyPsxC=b)haowV2FlZ_zO!c$Fa|5(8&mpPoB z6IMprBb)h--zCkyygnCMZeyH9Qi}$iU?4M*aFCIpfaE06%))WRu0ZXTX4X(>*J|s& zI|pIPv&`(HUEsrZ=X@)V%%;H;vv2&>T0((YN?#)1X1}oHefF2!Aj;P(P^SuBAR9{? z0|Xwx_#3XUQXE_FA^U>!3;!B;wg|F)t6ZaI(#eV@4J=P8$1M|3e6`tAp6Y1n-ngL3 zRkGryLZn6wXd58jFy%fu9Ax4ZW(0?UB5rG&K+}g;FL7&H7rcokh0d+Bk4gR~-6wy@ z7LSZaOR~s$?+~2iJ2W z_|+STe`LZyXb0*_6`p;G`MatJFoCXM@bSDE#}h3yS;xEVm0M2oObuBS6R}=AvB8n z0a>ZDu}4;qmQ9P4N^Ly|p?_Uvnvbh(Kb$=-xB1y}Z7kwBTUKcm5u@)G3&sAuM`4k$ zb^kr$(DbwMG1>%y&^p7!-2(uuWGAAL^{4*9OEMp&vHC_Ezt>JkEnw2$Py6l8Ll>vf zshwMt_5ZPX$6^g+eZdC-P_SZ7-2JSgXLS7@)#olpXt?Je6RhQ zPT+q#0CI6Oq{Rk=Nw}^@kR@j^$>Q->6dJ} z@hij3XS4s|)xgdSz^|A3yH|bAwGNW>R)&AFJ^lNW9~4gB9RzlK?97OTxGFObSCx&- zcl!g$-zECpY4ftWOwr+q9G1057;)&?t0{L)>VYJC6+r(+o5KO)!dLfLw^a3QO{T^- z#hm9VFXmormDWm?(4EV9H1ZegA@Wp^1r{7d==8Z)EWaFDq&K?b7d78+-VG*&onDbp z&4>N>n;VdEZW};2Am^6I_451Rj7ca&uPZ-8 z)VA&Z#GIjp7GK52iFDYB;~Cpx{bpugJUh4hv-nGr545LJPo&_ov^*Mq{?N%|a6SX6)@Id5I4S!5O9DGbDYA zn)l!~u%YXami)3=5{bhoqMUfiQW!UsttmSbO{OgKkx<0>I&F)iOqcMU=GEtioc6ZI_M4m(_hk?Z zUqnl&l$+W^Nj!jyjcxuHS7e+3&q&gdNMfiik_kZ^Em8OhbM3uih;`L3;D3ntj*nIk z@};p|gG`u7)EB=pZ#)PPKDZHaoCmS@1b@(V=PE@2qOn;=+^;3=c7F@su;zK+Qm#MT zI!&K9B$mp3o09t>$WcSERQ!KZ27QD$0_fE2fG=*UUeT{)*a$AM=Ks?^hQsig!_GNo zI+%AVJgE==uNtYCA!{$6CF%XeAwxDL85U<>>FKoiU!h_H^=zda8TT0*QYWa01P`VU zG-&S8qN!Lv?1rAhF18u;ci!)xZ=Ub|I4u;}?He^mqZf0@HyJA|>@NDiTry!7zi$Hf zQZ3fTpW+(L23ZYPRF9N82rO zjbc>-DOWIQAc*%3Tfc4{urbN2JE(6?CHSyW12sVCKnPOL^SVF&&7!6am>|sJ_+AA5 z6(?I3D;|1&_DE6cU1L5p&3lVcFdPy_&D{&Bg6G^c1)tC$pMZ`OcB+OjyS3f_SLFF) zn-Hgio73i7q^$mhqXfhnDX7J zg+FurJ5!}3ZG-uCnOcqCrPfGVl6E?`0STp;MN;Vn?Kxn-b^o>S>-j)9a*W<_{UuJh zi9q0c?2zmYLsAjG7d-&Y@BJ1!j;;DW2n3Xv54!&4lMCAorUUo_RJXvvQqJ@efFJ*E z+E4x;L~6h-Hk>q#D)!*!A8azo$TLbw0pX1F0HQbXW=S;8rdxf>-eDiyv0W~ z2oO<9%#vi@Uj#c518=~Hi3dvtBi?HdiIoW<$or0g_Aii9b(`5Y00>gjYY!Nn1c&K# zKDiHJhv}XI38$8h zME#rh2c1rA7H^&Nz)jIS?bVwBCyb4Ay=BnN0h{+Q~b(y*_IZqy#!-VtT7(eg3q=XeOJSRnks6SS;6@fD& zia8b3UV4jj;bFQq^yQY@0M>=06_O5D@;T@ zqHt!~nF9mlSD@>{Wl6sLNk6^!6$h?q%`)i0dm8c86ayOA&Oxhaca%p3MB8~;uZMqp zgdT()1>3>QQcG8-qkSLAN-qKpzeq2*yJ}9BR&ww?h%^w0kXZJ~p4+VT;nJYff2KyS zw1XhNz8+CSf+w_Y4d&+WetS}BlVpySP_PHAjJ^g}Uq~JG*}Nl5p!FCaL;KqkdPdiSA*mVfr-r(!zA0o<>P<)c{2%447lKl!400wEtR+F|hLSRwT;X|6)@;iG zAiRb;S)d2!*?cwV=!_hc-5k@A@Y#x8UN_Xklo&l{sRd+Zbk0iPW|6a+VpsY0*!GiA zscki9z1*OdZoN1J)dh5daZJH$AilZm^V(;Sns#)n%=oxwxfwcNiS~FE%`$gF!9XmX zpQf`DEtb7khxtJaMhsv?ep>s4O}fUlL|KX`<_&HnX43$DHXfBK^?GS@gi6Xg1mX$1A7*+_rG35<^d*4M5t9 zGx%Bbol;AB4rjc=5ILWFk8~+cMdj0=MI38YMv=OT%{bIXt3b`v(TyEQ2f!&gw+Eem z>o1-}s|0X-rf%cq2Gr_%0xm+d{|llj;K^Odl$)L!1QSlYs`l=?HvSkVwi;%|q~S^P!du6`IhfW1#X* zoTrSsjT`kI!mUKJ2j;BdkthOJFeAoVfJ&M>!e9>;PI#mnH=u<&Lb!nI+jmfJNRTTS z_1u0)oTn0H4gOr*ZDcQ?R&aD`=*m7ToB?b@WgCdW8tYObf-W2| zU|Q7qZwx!wp>#ah%WCF&xGDOU9g!~F3$Bh}>yt6m{R=bLoC>3Z;yIx7(3(O9tFOHH zccT9C4nB@xC{snR#uN(?eXec@m^CkG3|2+$%*i@g9`ayZR4+FKk0@sq!x1HG8PgPvdSG zOF`2#iQ!pYD{??oW+=~IkECc(Yk8HZp788@*hVxT+_WWPGCV<+lg-j=7^{xrj(s&V z?aKQlrsCfQeSi(_<<5}Wy89@*tg|w|@6i&`61!#j|B|rhTZ5>(*U+;CQhU?2oX~C2 zvp!y*0XBFJjwob6%wTW!vIv83X1uh65;TNqKfj>g#{6hBI$s#%rqSpgIz`4a;*lx1EKyVil?o3t&{Bn`t8hW#=Ii$? zq1o_jn1M09(gt3(GeG2{(rPiYZ+-n#h5)h7i6v)6r3HT#kk;K)5rVH&I2{h` zT8WT)+1-M-??ab##W=L9>c_!Hu!`{v2X2BwoJW};8Ti)zY$8`2L0mrWOobfP3@G*E zl0=m_Ha>#o_A@c1fn4di?Nlj4OK*D%T>V*Hzoe=IldOlSqtEO z*9YlAl)mCPK9qdE;Iq2@kO;XrQt%DAZmhGx{-qOvoRs*AJ{Wf}oGMI7mHuXfA&Y$# z&;_@p?#t2T>|dv`q&%zyullTn&>67MeoUaws^R}jLF@W$=lt6&Hz1$b19DNvCzL4# zWU~+2Ef@Wn?5#>3<7?3> zbSVqzOeJMoB7)!kgc{!4{<3AUj9MWswP931FK!6$Vv1oCiq#lNh zFDyzATr5JQ(I~(xj=^J#ZzBtlNTe}W4Qu0Dc;#1>lqh$~0%(oVAN_BR=l3GMM5Va( zap@+;Ax+;@|K`IN_M=(iRtj4OxhEDNegi%NsQnu)P-9HY60`bNvMiqyF=D?OM?xie zugKMy53WFy0XKptf@8Fs2v8hNYMdk*{pYBTB|(;!KT|RQNY;e!FHQ!t--N4&6a4mB z)@Y#?v9W9_Am>`ig#oe0PK))DdnwivPRekRWP*9jj!9*z#B3+nOqZpI$1K|TTDdN# zdsb$Pc9q+2d7!Td24gVO+S77_24qK%!AcQoIc;ef^{1i+|Cl5{$-lw_gF_j9nImdC zE>C6AqJYF=J|4&Th0$Ql_dy{?*P4tc0L{K9oRU_~1QP19vG20>%DwN8P{`rb!CA5s zDQ)=!lqWQtSS_%hc|V57hNF8pDJ6!ANAk!N04ryu3DD!Cb5ReloabS!z%@+Rk)VY^ zs>LZgt<#;8GNi)p;CToU{m)kk92k}!brq6(5O53@ahwl!HuF=!tuE9}ZgbBj0o9N| zgZoHyOWuKip<$FW52eHaaKpSK_T~<7K*5KPfrq_&N5U4D1$4H1@lA5N!IL10POSfX zML2BPyQ*pf_;BS5WsiHl6er=tp3J-NuS6{T`j^zK_ZGOZg=cGQmT4@2HbR}lpHuc6 zLzN4V9-yAED7ptA>JjGt##$~;d`8VTR}!8Oe_tII*u*8mY{wc}@$Nz>l0 zAWri*z#dQE-j*Wme?`uGvjbh<4lQD`3q>p8n*l-OSa zXIv>%cOG!Egtx4#{p=~1LWi1l%(hRrMuNh0q?HQ@_o%aI$*ESvR5it ziK)QmYjtuUIDZPxVH#CIpl?WTuw0OEoHh0XL!O6-=91IwGo^66MUtg(@>Rs-%xxlCllmDhMNsWIl9t*gcVpa(6e9yD}mOc zV;SIq*0TKxxmJ2*(u!_{M!Gv5C-iDZ%uI3ALfbxi4+DjnKi^y1=>L7-pCX;>yq1X_o~^dVb_ z+q;C7WB8zhBUUy1{c{ME(QeDPx8~?>eW$)Zrtf;C6Bp60a42Qx2kUIYdOK-OznW4a zRy49pLD~=qn?bK*9O%E@Q--%abbziPhBS~))bS8x^Ep?r(1qt>=LGU@%({*>0&A1< zLDN9rqo)ok!I`cooI@X}MD6QP5~dB{YZgw59=f2t*hDi{`DZ(^Cr=mY&NvHuFzqPc zUs!1dMWczK|G7QJK6C8J2tHbONh3Q6+jn_UL=HhJ+r){nT&{czbb=MI0i3 zx5H@dc%y%<`F85P_ajLIK@$q4Og&N?70Lo6*lTB3od97->x`f=q7qr-z=l< zAmq-&%4V#<7b2+91soBx<;!#p?@^4t&_ytJfELtTd z<0}avA->_yy&nU6ZP9$Fr^8Y&sZ3gc5zQT`Gi~56#^PgthFdYCZgjCE8aLq z6`$S|%9-L#Y!~E?z{)1Bpe=T+X2$RQ;eSOxBzsE2tbI?0g_ECOnff1E-D-4eB>lt0 zmod^}?W2W*fciiy1H-(9-yo3YF25;cbQH%1MVHB<+T}*kQX)R19Mzx~OZP0nF`chy zqYE*j{{+d30-CG(n61;b1H~;-IIN;l@+d`VSYmkJwZe9Q4)h;Pb@1e(R1*qg(3VW^ zGlS5l!~c8!!Do%G4fD6}`%=*(o0WbRd4Jjqh(WX+CL>8?&tk!Zr0OLp#IY*E7vLbi z&|@*8frj5E?9Lci&XdL6^I%;ZiX_qV_+ulx#(Fg(>R?w_+vdr9b;wiO8X$(n` z)+(}4OR9kv*m-eitUXazwhM$Li=;4_od=(8pk#XH9x6hQNkY+9}m z$MRi{&9ZzV@E)rXFC-0D0P#RKy5HH6isMv?1}G9JI=E-O+h>w^c#hGZoWmtZr9ecl zS?930{sy%toS@+RaC^IGVy(Pb(+4iy0)Yn(Zg)g`BZyZA3_B^qnfY`iqkg>eGUHR8 zq&WG7^ZQN5n2u~`!PP%A-j51#4`eV4Arty;);T_?6hwInR&>8c2?KwUc7?rO#Rf+q zDvo~m#ke*5%qM94@$n}okO$%`+2nQ~*lkr<UxhdRyM^Uj)dHK>d zK)L}jSQUxvTK;{l{(7>zNYx%bz%+c;u<^5pK%Vw)~Wv* z0(c*Qn&$neG{Kh}pFgO{&UjqT>~+)vbqerA2VAs0F?#)9un2YwKl!p%$JIY{^_@Ao z`2!3~R;38sc&#qz25a7-niOB@ix4osX7sV-+?~3@?HFvK*-sB0h#sSruG1EiJmRzX z8gHe@WVzgikUM{ z9^_G|m#mvr%-l`)yV%xzd#tsKX~fCx&R5X^Y*^*dj4@7tbQ8f!!+Fr*z4`1^*LW*R zXqzCL_nuqrmuKf*e;o6XfCd)tQZRxCpnmedKNK#WjXo?*KYI?mYXHVfq30?Frmkcw z*ef*A@a!kO%hH#|gC2MXKEh=XtHziMK4AvU!70ip<#M{cZYL15*n8iQCRJ%wOUTwy95C%V+KvA0 zBgLrLXT&+09b372K-(V92j{l`8V|OKZtw#z&A=y-oCR|;(?h#odjIhKg{kN(L7U!P zRW5+qy4#{|J#4m+3IIbrcb!#n$j}=OLXsQFQ~kX?hgww2yD;*ct2^ zmXCb1H{2S0K^a~(t%Us%uIYltfU&2nk4_o>Js<3@jt^u~qHei=0|o;6)*~ys_#ohH ze=zfn2AomZ&S~@b(dVeX^21?8lB0hIrZ1|DRVbpAnBypuYMud$7u%KKFhJ%TUGt^F zSHy+>bjyjgYH~qdOAigiWR)0SBvM$2y(pxxFb`(dHP=-8$^>t|To?PPa|Z}HMElE( zas)$JtDI46wubRsSe6fUIVh;OC}-gAE5g6R%B7Z_H(ejmiaJsPd;HiEPi{)uHPY0V zmMx$0g>s-v+$zCFazvY>URZ|_&?o?AO|0<0GkJ2Q72$}(npeXWEEF8t)=Q#O$)-gL zRxFM13tK9e8j7VPaF;&`d!h}a^;&tg5I-b4m3~%pgNgvx%f}2~`&N`@t0tBu_i$$i ziYh$vrNO?m!auLQu}q}J zN-Kb*@Hr>UpKyIh(w^FWgVYLEAjL%n-~R#>U)`Xz7pr&MCB?lhs2LPmfI2RiGX1vP z5*p3$z<-n`P>z|@u~GivuWrCl0%0C7(Lv%gvo6-(ISU;@q~<{8c#%Rm<_Ol8TUtdt z!7UaB!GMif*WIc0BDq` z92;+4JrjKo59XS){s*G&GAPw{YY~y;rglP@9qNHXJ*yQya7Px|10>n=YhG;6P*NhL(Y{^{4*WU&S)89 zm>@a9g#{lGx2Atj=Evvf-$JYuLxJ~a5d`!Dff6`+ENN^wo6NNAO=`e!s19azjr?D*u&q%;NX;sBknr?oWFdgTv(e z;k98I`l!y&gaK`sGLQHX?(0xz+1INb${cjhLltr`@EBsmNI0|_%pj)Q^c%6(NMRxJ z3%0AZljVvIhUf2I5710$t}^(0NgjcgD=|Q%4)X8F8fTNUPMVx|6N0i+YDxUhW`1xK z9D#6+1`UP;zlIa4Mf=!Jp&lnpd45Is?ofWc!zlVtdY|50C@0i*9%L#7*H%($Y z|2`5kyzgToxM6;Bi~EK-HF`*941h`*Sn9_$W#eUe?ipOXtLB!ExoHX;uyk>z!xA@) za=LNts$LE4ylyTT-+uEa*FVOL*#-~j>7ZLrVYP(&Zh8s#p(>dlM4*EiF;HEVj%`QN zNvC!(z9TfzLvIV|`zxm3b!Y%B-W6t{Q|*r1=FrMVNj7QIC1-r+)`# zx6wPxtpNJR1&8a}VNQkgUZpDRe6M2@sMhs@t&QI(fRL%75)dFse@Y!;g0q*Z7s);= z+Nufzm;9z{z2d38?VGmTTvpBz)*IvoM8g4WaSjEx_(0p`+ zp!nt0b=N4(ZS|+yZkfMWwKk&d-aba=#J_cGDmc2x>-LxN32Hg2nE+a1^=k9w--E0tCS#pj`uM(h zuN#3X?1A5<5C8Vu)CoAb6S$NmsSZOk1vqvw&qP2>VGZAPsf%meXCRczp4O@TvdP8K zHoywd)X(E@CTXuCg8t11{ITpZu)EdaSD9=Muz$-&; zUkN&K(h6DQ0#*|?yzjTw?j+xMxzW&z9?G{Zo-K1nP1#d8mTxX9IVsNreu3LqdRv)@ z9#~>90qr0_Q6z-V&8WfzzW+8AdHr*5<{Jp~K_$75I2RMfZn(> zQM$d*SgQs~^Q+rq4zr&n6mSQ3M-hM~SDgI9xOX@#5wPPe=g;sGdp{SSh+w&donlFw zK|H$na0Rje_mw_4MHVR%vp4#B?Rl7#X8c zi$jS|F^wq_@u%xCzMQOO!w49$`VZjgdv`kQ3?41`1gm&q`kaiYfLj(>;<-~$Q4vcP zBh@CHa376%k2qc1ZYMmJ^cHn{?MAl?*!ps6RN=T^R3gZY10LhI6v^ob-_zrC59r z>Bs+N-jai{?o{D|iD-5z{}iRLve_!;dBZ5fo!GNjk1~E05-s|lKHKuC%BlJJB0`9vS%+vQRQ(5m}b}A`>c3r@(Z!pzM*MQp>{kYfv&JfgK>@D9-Zq405UB&TKgceWiEV;{OM5#L7hoMsp$ ze(5wIri2i^iv@a2G)@i~{o)R7SP8|s%pYLgR>Yx|3#dK!K~OeKI!$&h&r8t44AQG& zYuNGc+S|t5xGcA}vIm!o?`F@PYH=DDsL8_0>+0&>RGW4Kv0NvhsKx0C{cb1mc!633 zF4RFT^;j%bPd5Os806}&N==jcPQnHcjuq7K+L?SwO&UJEU;Q)1mvKozKtK!nWafyS z16ds>>fb=EAM#xm_96%;i0>+>_kh-&AQc>EfpkjsXtlHti%O?e=2p zz3+a#zizeTQ~jN%oGXGAmpCIekSW@t-D3s-_}y>*O9w(>;KwH|xBmZC_0<7Uz1!LY zNF$AalynGE(w)*}&>$^JgAyVk9n!*&ZcqV1Kthq0MoQ`KZei$ealUiTz1M#kXJ+qt z_xrB(tS4U0S8${|FjQ9kC4N)}@P8n$rX@?(v$k}k3bt>ihU5|{6nq^^Xc*VkT`ZHa zA9Iswjy~e^uQX1aAl`rZn~whg>4)oX|6HBZe76x(eQRL#ma=*Z^ly>2Cax^()PuB8O1zJ9(Fnj%d(%%m2gwdqflFo#nr zA8)I{WU^2QWUugGlbd?W0K<>#2f>e3vHTcY2G+*we>eK^ni~m-)IM|&FdIBu zzzoK>0*JIG?N?>DN#!#l0!iUWaG%AHpD88qtx|k2AE8h~ASd(Q;u>SPHj`E>dC1*h zH}h*0{0UZ@Ft44?N^U)feJ!qNThO?F%MX|TUbw7wRA=cA#q@74iDdf=HR*=!M?Va% z-B$as6&_9~+j{xEPgTZ0#P@3Bq~GVV6`N!*1s<6liQ7W9ZwcQ5s=e2{zB9i)qRKAk zJ7Osy_0y>ZgLStlgzirM;%aP5qUPn?a489u!2D0>h~XgRH2nPbD@R;`>aNrrjvtz^ z&;jiJa2tnWkzPhlC`BX1*G#$SNg-SI;dY_4sL^)+G1N8E4%6j7pYO#l1J^pQY^?H(P;f2Ws}$qP11E24 z4d?6BO`&Nv_w8{?`Vq>l@sP{u5<{VrhSGYzMW5rH8Sb4L3#Siub53m@^~qN-6OeU* z4M@{rv}PdYwcuM_R?S4%X|X$#Rwb~H-n}SoXnHi@## zB!5o~)W6JVLRC|<)<#te_Mu!*LW{UCLMc*XqE|y7$i%ojn zUpz_W`kdq9#ImbgLo!QRS=WRUWX8r?-<7VR8x6f8u{gVq&L(Eol@*%Di!Lh4uzp=h zf}m^bkLbh@S*a%XtS;X6GK;fU&wqa~i>VA(>3Y!U=S1h1cndq{gC)EXp6K4m{~AUB zCSIU<*(thbg*!LrX{C&9kx5N5j(XuS9#Wuj=@ng85S~C>Sm@W>Ec<-8_+uIxS=cIK z^es-Kv-AtxAnirruCP*G2enX^!Slb#*8}@GvmVgia$+BUF_dIs|`ol-4H=LgLW6rY7 z3aI|nwv-r1L*8e=tlIat;D{i}oQj>6ETN5ap65?_rs2(ii%P_-2%Y^|9pVrUHINex zg5}oGJx}n=t+~3yM9y9u`ww1trKaoohnI~xTQTV565a?$OCTjjaf0+!wSRd0AwMG3 zur!Cy*?pH(+CufGmL(T_X3myl2*KO-;o{DUJ~frIO^<>wXymZDk8m`+xzEKcG`t~P z*nG7=yO?c?e>lT&RKjLs(R96)RW%*CU1Pzs(DrU=)FN8_`|7`enhFrE-f>Rt7?f6+ zYeoyS*nD%g^6+PCZn-q7IGHsX_RhC8B?JZzZ}2FRaHTsS zpE>|AQMNT+Y1@L_TTq{Ak8Xq1-Ev6gaHA8eh}+$*gM<`k%_v?wx@$Lc@!dwP;nFjr z(2HL-DZ9scCKsn_X~O;+r4K{Ck_Kx@t)gko=TcP{MR*!Q#QQ2x`ocpqhDKR?rn7j@U3`loA!&%DhYwr;=sZ(|haR`x!Dou(te z-o53W5T9AI$2yH^U)pJ$H>KR28`+O{#%wZwBKJt}lq(DukD-dZ z&a%}$Yg}$zasZKRnI+BKT&0 zlnzAM*!{7vKB`uWjn?oE6ZS^(w1h;@!fA$f?Shi_i!-#}rUV}F9A*h(pxmPNSL*Xy z_ogX>^rM7KO*?s%bP|=V>Jgqoo9ER9!84dI!5}{^-}-4qd4p9rc#QNH={g1yf)Fj_ z+9Cv}%DlRe&W`!kob~$ppHKViMWun`zt%f_7Yfwj6r`iS0ePVdL09Ljzgh4@TE2Cf zVuh>rP6DB^8vl0d<;59PTQEznWVwPBl@I=;SoF^ZYp_AB7LNBV{%gGN*q1&Kk^o~h zVQT`2%$5tmH=!@0Q2&vI>J$eHi?1u@jBXa5$=10eEn>E|9j^Q0XNCp;@Y_T!#Uh)J zZTX49xQVX)zCeruZ$4d2nfdFC^FB&SvW5`RTr84}-ONajsh->f>25%KevQliwB-Wn z@3zRwZbQE5iUzc#Qh8W6sZJ4~-^@!;dvj)g`~I`12G{%W3aDGa?nx-$8IRO62#*7S za{Z`9y8hbg;g8S2$m$kJcNq*T_5Lu|BeM5iUm4U$T_B=`>wrXYBewwsmOuY9=9u%; zg)zrnmPT*4c~yCj)JI~=6xVE8+3@~&i?*jE3`^yOV66k;ET0HJuu}ghO#pRp0~y+$gX;(AhkG zuti1WA0C?{P29k*}8g;D;NaJiK*vFW`$ihI76M=2oud_FHP zceFS1`NALeX1=p{O$2}QecU|G?3xbD#y=xQEn*;Ud{o7tDnfdQvTMK*%;4DR(N?Kr zF0yAOS4OtfT9}4JKqQoOJHHqMxCCrG@s{+J8GDV$n_!W}0z(S=v7P!CJa9_Lt9)d+ z5~rs?u_VxHSCJt-37FPuY0FVhyVT)-3A+7%c$`t~Cn|YA)-NI6h(EL$#QwP9R)x}@QUlp-#9QCck+j4(gf7oGY)_$FuO zd8XI8?I-GoV0Er*<|PndZsQiUGgCYxha|d`n2!8rq+o0V}D` z5S1NB2(AYio=0@_{8dA19rMakeC{ovV6+BSJix-B`M34_54}{ z@SbnzvY-A~d-YGo9xEg^04=k!OZU<3s2kOYDt(UN938@5C{fqkDtf~lp{mED60PhB z>w8Pu0)}Wd^MQMlulpp(>Z@Udjks>~G$loX|K(QZUJm~UgTz%x-gTaTUjoZ_T0K=@ zrIS~aqUv$(hssR?4#amZGP&4_o@D+IOgisSffrBEmWI|+g!)4WJitNT=Dfx^5px0i zn%O|>?L=Yf`vb3I@&?5;3pgdT{d=6(e(s~KO#~(jLV4SE>V>IT{H{VhpzJpzz_$Ws zwco&w%wkvosCf2}3(-Y?elSq_;Bz1v^kCJqo@`e1dBW&YHol>E?!IdmYic@j8tQvm z3ekkjYTLF-H4(w!OaZB#x&sfFO+A={7H_PFpIvooQ>GzdOxY4herd0VwB}DoHZN6) zP>b`K-(Y+Y)#~u@vr%}$D6O~aHH9t(mwU5`HPf4T+=5Q(NZAPg^|P5rc|?Px9bT;0 zD(QI+iIn3)DdS#PGd81Pr7;m_ht>y)TuSUG^AX%`nwKB7^wW_4hJkK&Pd&{bG0l@( zW@pX3_5_Sfi1VB2TZon@0N6{^4i5wMIeu}q9)$w4IeJI*sAp0{j@!ms61hyo{MtU_>Ec0bCZ`J(|+KByGEz>Bf6?693_UrG4YZ6c1bT zS>tx&5@*C*#tT4W6`w|Ec(T^>T4aO*;)5YV6~^5HAo35)xxVqGqut}!Xg+V`Ze=&L z<4!k(>7Pk)VANM@!Nn9bVYBY8-{lUe!ZGpMLw`=Ed$)*j@8!DND>e%Qc_zs_Bm>wG zgi678Oe^Zqc-Sdb$he1|JLZW?dD$P3eZ2W@#8mUez7RLDX`XGv&yT%w&gkCLvM}i7 zYdUU}A*y=t_dZXns3-6oLzi1^E;C+v!Pn{swm3`^Q9FK16l$Vh|5$jg^RL18j8fE% z;`^)Z8+djk^jJV9)JYMWEAPH%agM~k51||v2>;Nq4KVlL=_?E1@p>6Gp2@%SD*7~?|i_8(DH)LY& zTL4->d}8A8VgrOFd;ML1NBH*J%k|yiiHCAK{!wrakXWjx ze7rpcJv+#KCDV?yKdARewowqkbGY1_`rr(o28sa)ui!kNk0^UI6tn(XYr0a(XLB^B z=St`$2Wz^UP8Z)@Qp%^=yHZPJekYW-k?XqTAJR;% zV9+uB1w~nRmIowa?1F?k!CJ|v3!U6eQ`NdCS@I1Aeqn^+rT5*hTs<)#JA{3nzS<=x z$`7c+pZrG|fXE7u%gn3!9p5Xlvr8n6(w3eskOtl>but2K3%ab|lF*qY|Kp%9mHcwP zLTvDO1xw0A4;%%=FOdtAuE)l<-Kku4yYmrvbi8jbe9!%-wx70_iV4>{7#IE2u}su& zyvEVc<1&&(^ht4CYge|vBNvW;z}5(J_Ov(F?foi`7{9%|qnm~V!UKpq$;SKKgBA38 zghf_b$sg%-RXM#axRCOhNj-@74Vt{^KK=7j>hdY13TPW`>cWw|uifg{B*V4Y&XqsO zO%|@w^LfT6-nahm@T_7@t924s@2ws`Oc9KydvpHfk9ja890fs8lA)4h5@0A(=!0uV zdZ!ShrWDA6%b} zllngN_%t%`#v(azv$%4aMZ@zF+B?fmB*$+d8XNp44>2CH>CBG#o(J?vokhaXtz-Yq z`5mas=bJF;7DK+i@ZSvko%8}~`=yeH)%UK)Kh+mY+_v2*Tufb4*D-0i#;@!3^EEtI zL>~ITXpsudN2K9$b_UAh1m#2~nfe5U(0YZ=_>PEIR5%Yh4i(&7Xpa`!j68$A$#e5d zdki!4cqeJK*w+1T#LCWVf_)I*(!M&7drfe-87o9}y~GK`c@iLX@kUM^t1P4lv1%Fh zNL~GP-2V2kWQ7zjYx0&fCpx0CztJXzGe$OcL=V`0SU19nWLuSXQVlh{WwFA;!?TzW zjo@h1Nunt()0-kNlqh8A0oj|L9!Mwr%?ZrbC-?zf27fK0tu_+5-haAD%3gskTzeie zkcJ4TbI9PtQMfdJPh#rPPZKiLwyK@`Z057^v$#G1)_SK0z2ohF=D(JCpkAGhG`RT8 z-{s`A?6^2i64{%2Ne~n?UGsoiRYe6zxGo#^)y_|^F4G**g3RP4W@t1~Jg~_~q|F$> zIN%q%dTJ0x&E3+vI55W0<4R<2jcB#080(OCYyK~NLd0v42LjNrGW#%N7~wau;PDWt z9vbtmMXKf{Y>w8ar#gINx6-c&;xeq}o89k*-4=`sGOkt{niJ$6s4ejz)6gy%o)qhK zs$QLF1~cng^7>Ss)G?ILv-|C44iua*bL@xviXW#H8yEht|tI`sJXe5BB=9apcBbQUQiYF58o}+Dl?Ci=mrtziM58>KZ(C0FJC3UVk^J zUiB?$Ql4+sH*|ujHYJOr;O^4=&wVgnRNV-~ywkVs7WJn(r$Zwno_E>f0crZ3v=u+1 z4|x8-{($=ktG&%bC#dzF-tb z_I}bv@R3erffiZqA7Ov+m~H*>36Od3zYT|P-sFnx<;R=xPR^A%$FoFIi6vfF_4Xna zVb>|`m(bQ0s#BqCT_}C)4a{oYVbwaVzj@oOLV1wGC2cf$#@rUeOe&tQp9~k1zi^KAFj3 zIJ4y#dW4A4iR!Hx4Nsec&Q2vaN+cKGY3}tPK&-Lgv1j+SL%#)-x{RcS`y?+s-~&ue zH9TEa+AR4+iA|9|AV3Qz@Dl}Vg#uVF z3VlgrClH8-X$y3Q5PaI!rGfcH%wy*X$g+VJoZ^;nL3z33jHIIYKCHvDne0AMx6O{g zJrcgeH@`-eyx$V*%VsHw+4ir@M^FM9U-@F>*B#r60GM3zoX>>-frr~aJQf+*3^3DI zL-$);TKW@Y*z73lD6i+=D3_ulb`de;04(+nLhaN|uqlY#LP3S{i}{Y2_!TtEHI z+oEXNXRa>Y(1*>_2S&uB?0rCZO z)bKXbhr|y+k-+>F*hrW0zvXXH@|KM#knc|&&%k^a_V2sBi>8vqGayixjh&$rBF?10 z!6@j3OL^2UcmD0occ=h6cXi#=E@SFYd2o?Dw$7yC)N>1zL$zB~6Ue>xmro+hMZr#i zaC}2k-b21gy0I^Gj^H6R)}4GyuqUi^_|s)+%P&`_>ON~XpZX_F6B6gMjGimK^vsu#g^-0JN;$ajF4e94Av%@``2)LFyY&W zhLy8Gwy!XdZ@Ffz()4YH6266#@XOV#OxpHawi!~QcptDTTh5J^QdCiH+*yHak`@P5 zD`bZxc!tQ1d^Uzc3gV0RIyXhKl})j@I^rk;s~!J6F$rwGKXY8&kgQXfGsw@D45NQE z!bL%8^wcMdoEGixEEYQe3BLG3GZWazas#415pI&DcljkR*;a^)y?5tAj68pmWzQIA za46~P>_q^<=?2>#;J{F6UNZ|)gd8*2wfPkb(vS>che^W6ldhioove2srfdtAyImoeYa5x{$n`28L$sQJsdEsLzeUMuF-==LqZQ*?Ypo6X>67Chw7a%-HYlNI!1FpEa)-E}-Qx(7* zTc!(NZ`UTVW>U)mAlX}@8{3zLYNv6O<3@@AQCamMyL2{B+{pns&t_9L_+k==(j+j8 z&#C<{t_YrL5l_nXF=p98D48O76LCE_U(PqgC#Jp1f^kTs=REfI_Z`QA;g3Lxr`xpy zicJv$QFjwht(q{1;qkRCHUxKBwI6LsZ(dC9DqkfO^m+hpTvO?L71{NPCqoT}f11cM zw|(|P9_M-advsbNQPLbP!J2*vz3z%^2*iXxh9YU6)~ZYriK$3o(RD;0YkO3_>dLQV zay>J)t}xB)S%eljo61*2E~(!`|1MuA12f9&AGOJhV1H2c3cYdJ$=qEy=SCTklD@37 z?fD6u8czX^PWzpwY>obeLZgjw4`pel@ESHa%u~MqV*EEy3c~}_ZgQ#?B66vb!)QX3 zj}m238iB}^JS!R`qryz_mw^E$NH%4zCy3%ANWfLv_8>4 zWHhrSD^p1H;|%yPRKj1v@U|x3-o{Nn?hfi8J_8d@=oXvU%^^+>p4|E7O1rm$s8gH0 zp8}c9tBbMobS5^W9P*2wV$py6bY}AB#7EM5pMKYKhsj^Ga9d)>sLsT(Z0J<#@`C+W zhD4FrSQ2OK;*J&z>t4|1YcD?5khr+G*?val%Vvy>?5Iw<=4w=}IrUkgxw@=S%_f_X z$EfVKwx?MsgoCZ*sd-_Vp|}P&Ch4MZgU*QR3;noTyw!<9I5LbIO1kZ9&;mSUGxZxd z`1ysCKQA7B{73at6_9I%?!+edhLX?UB@0-HgUgqgB;nICUJ(~862y82H{k9X-}nq} z9peHo^vay*GhE2+E6S1HTLzrn<}=e0ydzCgwu6@UKDx83umdm21fPx_|DHRYxLc^{ zl)G=)9Z(vWRoRW1i!K_RH5|_rS`}?*sSJEoB_DPi_4qaD!xZPU)bxPH;ae;eLT386 z&W^X@@qNtPZT#@(>YmnABRKA(hWqC!85xD@X&D%Fg%WY^woyGqNPJ*n7pd)PQ|upF zM4TRNbtAD!kospw12=1;u5W}W95N)oa1}ox5YKS!-u?a=}YSYKihk^2~%3& z^`y$&!RhYnza)|b1eCHeGAQr(_;RS7w>m+o&|H99c5jmW-6F+|z4Q#0i7D0ty&qlz z)l;viRMu4MnurWpXb8` zhn{f}sa+DL!-wShCFQ*2r)MasQul@tMSfP9-w_0C3C)Veu}ISASmT^d`N}I)AP^L2 zbrii+I7AwQt*q+avht%;^0t4(ZyO@A+p>}b0-f+|=OcDl>Y+y4Z7uax*Vc~xLLomH zYOo)&N{+~i@bgAHCd+A)W! z@bH_xAhmh1_T^r~)v517D(ozp89kNNGce066}%lE>WMC2YkF@SKH9~vT7AkW)Kxv@ zelodYRNm$$rSuv<);*`z-Ci1pf~T_d5U3mKRX5kqlS|Yd{f4`J4K>qyAN%Cw#BS=e z1sP{QQ9Zy?^secHd>RFM9xXO zCix)rrlC29oiW&q-Jj~;q7t%mv)jk)=;^r;`gC7cFOlqg`tR0Mgv9G(bNyQ&bl}f8 zx9Llk%WZq7tug>1DzCQ2aHXp^Y4sABJ5A+V7ATZ1pH?9d9+<13WFdNRv^~)d^!s-@ z;obMXM^+bTlvK9UY|iT9WcHD(8OdSXoJWR{=q3Jq(483j{?GU(IWdc}GSNT7_6G}Y zP{-16p3-_QYHK7V#Kk3Q$eJ@a=u+<7GwE4>e>bv?ZN4qN5$~apP%S#)`t4@%1-($$ zt?3`BQRxoZ@RV~T)xFoL>F#dYk55SJQRV*8de9O=6)spVXg4Wuvd#0PRA0_q$K`2h z!_lU9+V;RsR9sS0UtO&$ijtZJJw5Lioi8iS?*|sUtV!P-2(YuWW8{)KFDgE*=tQWM zA|44Nj8JRv+Udg?iDemCj!+b@M#Kl;oPL-hJwm$05 zeOZ~2x0qnS>MJI+cVTs44VY7qPI!TOO1aa(_onw5fq{Wf_m9smJdCXHe0^@r(28)v zEe*izXaqUeSurAT9NoxK6pLsgJRIMpS3q~DP64+-Gj)6Q&G|ZzP2xdK;`mIzzSW%C;%%;y_VS<>!f%=Bsfp8cNF2YZtu~ZF{K5z)h6#)~X{jM74Qxfd3 zyu7?e$yj$KbuV!Iez5NKX7Gp9)rr?%oz3{CkO{+*ewlR82S?1_13CppHF|_3npZMD zLxOP?;@3;MU8*4&thpNxqNwNmQP8whV*iPemYFMRTH5Z4KT9y#$LE}oy6<$ye%x~I zZ_QoPet&iE$LY0B_wq?4qcKarrx8dQvB1R+DcL2SH`Svf8V#ji!#kQi0OzM1SO{$S zup})z2d_%%+G#{TbSz-A9MnykA)u z*1BR7i2}{^+iJ@TCO*l5G0ay$heH*v3fpNWy=+`ayAn9E3a>v&X>Dx{ZM!Eg%^rha zEI`w7GWr!Wi^J7F1a7YU{Xdmq+@rrSDt~pE19xw7tiku|2n61l_6UJEM3>|RL$p|(1D5(Onv=1yF;dcc zm3Dlg2e6~1NW8}PJRu)x)g>W&=hINPVv@+|Q~GO!WS#*JbvYS7hb8R^0+ELj;vZaq zM#MlJMJ>`?HfeP0o*v=`#vdl8{RKG>QlAC_(=6MaOHA6?Kh3f!0xxb&`EAUaXXt!* z*KekgS)wP?NBiZ(qp*ybJO-PZpGHZ2><3)ry+cBD5hW$zC&DSnTRoXOp^K&mg{14h zwm5QMK6$~}9k9?kV66>msiQf2?1zl%qhS5DF`va`Ok0?33b=kkahI=9Vp!@!wQw>=LS~8@-2Zc&GOb0d zjz>rqv9J)^aNa^7E)dBF>)^UMOj(pABT*&3F0^=oiZFc_>jNjo2{J z8ItVzWrD0n(5u6uz#Cu=+X5&NgO?`#Ctif!Q_)bT@IRdZZna#T90k#QPjkWuI9M;hv_A}c zp?wJap+aYLLvODJJMcv-?`c8E62W3BB*%y)i@DQ6rTk;|ANrln%eqapqc%|SDUk{lE+8ff$#6{VcW1Nmfp_f zqfxrw+GXJL`)>p zl}a8$xZ&~Y*Iy{X3xxA^0M;poMA1O~S)hIko@z?9Q_+$TT3(~5!bt@kSyac1<5ayw zh2u@yCVFwHa|zpd65a*M!wsY?e34jE1bGz#h$S&_p?+QJ-qkbH@%9t$8Lp_N&jv?2 z#Vf|%bDES>be9XiE=WiNDdlWy7zqL{#=Mv3aN~#+-Xr-CVN_S>Hw2oY*QN%)qZ+C=Hk|f8P={~uN1EqyXP;CXOb4V=R1MBRmOB>5JTp-yB3LF}_*bZ6byxuCNl^rL5wQYv zQ+MykPqMjxS5{Z%r3ntD>Gt!Lp<8BYR(gV9C^Gk5r@UUC$|o%$xe4Y!yWYp0E7U~F zHuy}3FB&A>9ZtaX0-;>8zfy5R_oulh6UmcUfcor@yg5##p zU=k%jt=bdMg>bb-M5o}(hNg^vv0$zBto1%0cyLOh;&1ik`QPW?+&8QRh3DLMP>vaQ z4s%t&r}Q+3j=k7Xl#u?{SM#4L`}?kAmChsxcH1>QzxKz96Hob&K5p)Tv*TEJjAS7}W)IiK#xy{;%r?#3M$<^aQ~VuCiuiSS^K=abeG;o!kSfY4Cya!(+@_EA z$DyeV`?-HWaDhhVui(GFeB@bW-%I^|t&U{VHfmJNg+?$-AigX;c}g8)FN_ZgD14fN z-9NgX7F`>N53Njbaq)N4`Bt6ZJD-sK74b$ACJh(a@EDjqr1BF#6!V#LDn}(Wte4lF z$9WcEM-oaX=Dv-`7qK_z*!a{9 zz0@zekv*3P+hX{$e($8`!L$ANwr>NaLtNMOzf`^F$=ohY5N-F}PN}v|9KQ|>6Zun& zd5zkM-fiRW&sf8xOx^@(oR&YPD9l3;X2%V5`*`}YX zqA8*sr{K$DY2S_TAL+l@Ec=K7-LHn?jo%6?T@c~X0W%MV{xG?~9dy4Bxa?SgJTJI- zC@(ZjLnGj2ScQiEg#$FLvZ1?%c<1<@w@d^5Nf8WjDJTSJ(WoOSHx;nj*%j#!f+U_y zn(}_|r}1+C_Wq(9Vb*d)&4QeVyXm!!?ZFmA&ayZNGt6TI0cwME@WZfC8x%U!1Aq5{ z=oM_DmpU*`_(p@&ot^OuhS%m)X`reOgk6%j?UOg(f~(VTVczX-EVZ-5l^G2o&_m;t zV?7J7ZXud)hChDE5^*B$r~2U%V=YKc)H1n>f37*OvzafVDVzx3Covyj%dEo6nx!XCP87akInqiyZj+4RM7~b+ZYy zo>L*~?1TcN36Qj-*mjush*W>BMqUeT?763KtwhFu{WEh|83iAZj15&!@I literal 0 HcmV?d00001 diff --git a/packages/fether-electron/build/icons/64x64.png b/packages/fether-electron/build/icons/64x64.png new file mode 100644 index 0000000000000000000000000000000000000000..c930c704dbd2298ef13411533e90c9543e8acf58 GIT binary patch literal 4899 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%0DLwMw>G%3}T=EK)ViW7Cm)?4G;^%lR4q@J2>r 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%0DLwMw>G%3}T=EK)ViW7Cm)?4G;^%lR4q@J2>r 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 A7XSbN literal 0 HcmV?d00001 diff --git a/packages/fether-electron/static/assets/icons/16x16.png b/packages/fether-electron/static/assets/icons/16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..0e3e52463bb3264288b2ff4a1682bbe7672e603c GIT binary patch literal 2199 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 E3uT4g^8f$< literal 0 HcmV?d00001 diff --git a/packages/fether-electron/static/assets/icons/32x32.png b/packages/fether-electron/static/assets/icons/32x32.png new file mode 100644 index 0000000000000000000000000000000000000000..f33a32c8f0b35ee1ca8b154962727236fe00b387 GIT binary patch literal 3181 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 literal 0 HcmV?d00001 diff --git a/packages/fether-electron/static/assets/icons/512x512.png b/packages/fether-electron/static/assets/icons/512x512.png new file mode 100644 index 0000000000000000000000000000000000000000..8dfc0a6a2e12f4910cdb8d5912777d5d698a34b4 GIT binary patch literal 48459 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 z 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 literal 0 HcmV?d00001 diff --git a/packages/fether-electron/static/assets/icons/64x64.png b/packages/fether-electron/static/assets/icons/64x64.png new file mode 100644 index 0000000000000000000000000000000000000000..c930c704dbd2298ef13411533e90c9543e8acf58 GIT binary patch literal 4899 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%0DLwMw>G%3}T=EK)ViW7Cm)?4G;^%lR4q@J2>r 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 Date: Thu, 31 Jan 2019 15:31:46 +1100 Subject: [PATCH 075/153] chore: Remove all useless icons that do not chagne poor quality icon on windows --- .../fether-electron/build/icons/128x128.png | Bin 9430 -> 0 bytes packages/fether-electron/build/icons/16x16.png | Bin 2199 -> 0 bytes .../fether-electron/build/icons/256x256.png | Bin 20607 -> 0 bytes packages/fether-electron/build/icons/32x32.png | Bin 3181 -> 0 bytes packages/fether-electron/build/icons/48x48.png | Bin 4179 -> 0 bytes .../fether-electron/build/icons/512x512.png | Bin 48459 -> 0 bytes packages/fether-electron/build/icons/64x64.png | Bin 4899 -> 0 bytes packages/fether-electron/build/icons/icon.ico | Bin 40762 -> 0 bytes .../static/assets/icons/1024x1024.png | Bin 40762 -> 0 bytes .../static/assets/icons/128x128.png | Bin 9430 -> 0 bytes .../static/assets/icons/16x16.png | Bin 2199 -> 0 bytes .../static/assets/icons/256x256.png | Bin 20607 -> 0 bytes .../static/assets/icons/32x32.png | Bin 3181 -> 0 bytes .../static/assets/icons/48x48.png | Bin 4179 -> 0 bytes .../static/assets/icons/512x512.png | Bin 48459 -> 0 bytes .../static/assets/icons/64x64.png | Bin 4899 -> 0 bytes .../static/assets/icons/icon.ico | Bin 40762 -> 0 bytes 17 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 packages/fether-electron/build/icons/128x128.png delete mode 100644 packages/fether-electron/build/icons/16x16.png delete mode 100644 packages/fether-electron/build/icons/256x256.png delete mode 100644 packages/fether-electron/build/icons/32x32.png delete mode 100644 packages/fether-electron/build/icons/48x48.png delete mode 100644 packages/fether-electron/build/icons/512x512.png delete mode 100644 packages/fether-electron/build/icons/64x64.png delete mode 100644 packages/fether-electron/build/icons/icon.ico delete mode 100644 packages/fether-electron/static/assets/icons/1024x1024.png delete mode 100644 packages/fether-electron/static/assets/icons/128x128.png delete mode 100644 packages/fether-electron/static/assets/icons/16x16.png delete mode 100644 packages/fether-electron/static/assets/icons/256x256.png delete mode 100644 packages/fether-electron/static/assets/icons/32x32.png delete mode 100644 packages/fether-electron/static/assets/icons/48x48.png delete mode 100644 packages/fether-electron/static/assets/icons/512x512.png delete mode 100644 packages/fether-electron/static/assets/icons/64x64.png delete mode 100644 packages/fether-electron/static/assets/icons/icon.ico diff --git a/packages/fether-electron/build/icons/128x128.png b/packages/fether-electron/build/icons/128x128.png deleted file mode 100644 index 5831c576b2c749c6884495662f49ec7bca57c48e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9430 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 A7XSbN diff --git a/packages/fether-electron/build/icons/16x16.png b/packages/fether-electron/build/icons/16x16.png deleted file mode 100644 index 0e3e52463bb3264288b2ff4a1682bbe7672e603c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2199 zcmbVO3rrJd96zQKM8(A*+Z6RY(W&!#k6ufAvlA$2n^{HZB0l5w?n+PE-g$S>!e(?j z<3!yQwrSiWx=k~aiI4eWjYci`8JOo8U zf-^_WaZIOK(WhfL(Z%b6J_(>9X!4Yx#ISk13cL7R!EZrYLdOtT;4H{&g9CR+R^B7n ziex^!Xoiz5%45wOGUW|;a*zfDK3-+upwH`9=%5AZ;-$e@TgDK$3!>&(kW|eeoa4xZ zt)k4s2AvUQ2?~dk%{sz}QwCxZOyWc`h8r;4h~fl|n`n}N!w&+i$()Y``j~M`=bvPn6o~Xs=i^m>$H2@W;8DHp0YGbV#OS#QvrfT6Cm(dizd^f@kZ0zI=8Ii|Bt^>Hcs1 z;Q+B7#-GcBhKnJZN0`={y3>RGJ9Axoz1mn09P~zQ7-`C25^3waA5hDnX|r`_mP61B z7JGWC)3km;=@i?iv*N3kb!>@Va<(;f#Cyeg!&hG%|6A>@dEaKoR_~2Z+?Ok@FU?s| z9hY$XlkMLpt=(~RQ7CEXu$|))rW1~Vo4>TP11ry0y>#?i#mc~=&y<$Xrsk5$%a<4Q zw^x;yn@0;-L&}^Jx1T#VYXddT-YDgia8YxXr!@|Ql15KJg^VG#>brM8D6Vp?KHk)n z+tl3rdi?gIUpsZ1#@;w`&SuNno;8aa_Hmz_ia22T!s$% z+U0_TmIipRW#og04;^VQ*xxL<;GyEzR_#B0_@cqyUd-ET>*{XB-aWmo)RQ@>^IT`= z(V{&!uN_W`niRz(p1dwsUR^Tx(4ol#`o=`BywlL9^~6}AU+~ttq|*L!dE&bjeNS;E z?(f!IX?Zn1wy_}e`OZ-bN{TD+l=AuGHrk}32Wz)&o0d3gRC~ofPknvs?uE^5Cu26+ z`qmv>U$JWVH!nx+uKDTyeN%RJHb=hVts7T*s&!)gaXHj6Z&!6qP4n+tZ`L4r$ghY(1R1Pks2*WeahgZth2 z?VbD9IrrW5STn3WGcDEK)zwvBeI2QxCXbClfdK#jwxWWpCICRdM+kt10{&rlYg zi*oS_@dya=a?tVd@CtMD2y*iXaq{qr@ra1=@zVY4j~?vJ)xuItQ&#R@eSx1O=&jw| zoyEAhy}Z1*y!g4CT&=iyMMXuqdHA^b_&C85oNhjj?oe+|N4KZ{Zb262X6|a^>~7=a zNcXozsF{<8y97Nb=|6|y;QXIv9o_ylP2hxadqbVMdAWH04(T5SEzJK@&e_A&{vVxN zm~+GIVGb}ycQ>#s?|;fVTRXWsxmi2?4^98)=l`t(aB5Xm|I^2RD~p4}f4XpUf9VMh z<6jf<-4td_;(zv|D_g87U~X@p#NKfla~*CY4h=k@d}Cw2(t5nYsmA@qN+|7HkLmB zDJlxCFDE~*HZPx;fT$P`-~Uz=)Ef(^JM{mvu!XsprIV`z6dbjU1Jnw}?d)hpPxqg> z6q9kXcX9%yDkQ|o$Hn^(aaC2t6dm2% zp^oM-MOg`YaE7>SY%Ih?EcirWP)kuxArU?vP5}`?OHS}@&MC+*U?C!CA<6?4w)}T} zStoOkzk2Yu{y(>bg_Akh#{VOpnFvgPN7#&qQ`8bB%4s1g0ON#O2=Q?WLM;S^1%xck zd0?XdZcW|Q2HcfU`~TYNU#Tp>7A;|ByrROQ=A8V(P%};e3qDXPsGu;XfTfTS4^+@h z#Ef6$ukQatox~Ju+`xtQ`PXjJg1P+b$=-(U9~vYEHUGOaBU&wkz()TMTJq1{-JC4ly`ZkJ=T_j{{okn~_y05kH>l_TS^odK_57z`|B?TH zQr-XG^8ags%&no0Rxr@ua?}4E5%*uy^v~tt{(rCBKYsf!X6)a^LEHHE@jpfx{O}*M z4s!&Xb_I?0U`~w(04Omk%0Acj&OFHSNh6w?dTgCq)LE3^;o#$^`-nN%M#lq3lYJ>i zge2&QMpi(^K=7)a5e45w7|-RY6vNoc`?NGNgorBoU>2MYU)a#t=XXvWY**%aC$Ochy@p|E}AD-%kxmGNOdBdjWo(6lZoQVswJm4N`#@AK)MX}E&}XgeTM(-ry!tP*)B zlQDUru{}Ik0E+A@0N7#$Isu5u=eavYEo=q;!0X?s=J!k(@1Siy%~uce5^wlWHH7iY z9K}huo{MagJ`VXb1Mu8s=G!Cp(#oLsT#aZz*Uv02Qjs{)7|g4St!89Ul7+W}*1T>l zk>k>`BgNF*3B1Po`id3vGHNA>5fO8>Hp<{L__CX+d_qs~_!)&1PQw<8q%qT9$Y`-h zBir#rwgdY02J#@xG1$@WiZ+@3N@X5m>MsVN5VS=aUhiHyY9)S_Uio093Fsncic zSat1WE#&v0mL<;ic4%alN-6R?DBkf@)PWisGvg59tI?zPdnXn1A-T)pv@N$JnZ4|4 zd%$QlOxX?TYI{8{@!=>znF~M6#TWBS;NwGmUawEHh~Jg-T&B72BSxBND&cEdQY~(2dDz<8TIf$q9=9HM-qTN& zjY=Myz!^J3zB=Oii0>8~+iWT!l#-a8?@mpAddcWW-H)Z{*vC7K)HVp}MrNg{i&rmfI*HuY7LS^Kn%E?+&;nh^i~ zg_GEueMJ1yKwlc9QMn=9DKt}ef$eX&_2V$fzz07;ghCaWGL(um#9_cX^D4(xFqhS> zj6UO?oU08p#&P7_q+up1yx6O?O?5nwK`3ame5M?N9)}(nKMk+^8Pxd3+vmc*E-uQa zEDJr+dn?OJwp+F|%v^qgJuh-wFVhtbHDs+-G>$Y6E~Q3>o%qocF-+hzA%OttUJ?)g z=JE&^T(;S-a~$8e0B$?tj(*pO&|neQ4N!YX7^GR+E|J40!mJr8n99^Lw7;n9e$JPs z(3M!_QcP|NU|U3TsjojV&r%JvchoTZ;0;obAm*O=iG z$fSeij>Ab=Ja|}9Sc||TyVD!}WtZ4K z_ysHS^M$40M#hZg5(iK1dDMuAZ}z_uCi_FbnbdlJy>jB*<{KfHiUCRnU&=Q3PY=1c zwC+rQ{>TP#RKI=tE}j@3v0Ztxo~Sg0Sz?>c#8y<^uolJM)tV#j!?)uba|(Y8X+}nN zc|6q4s2BMy@V!+VP_3imT;2aw6Y1ewT3V{$w%Le`rw8hTOLk+%m`JI`407XVhTwkV zgY^y*0;`TQ&pNUfn}=yJdg`052vm?S$_`3g!y%}LIi-xJ;fW9Oz2|3<0-4OI zuN%9~-+<=HSWt?;R^&58qx4%Wp&s_iA8o18YB5R5yYkoAIHil><8*LiA%M(u<@zNc zm(HL}V5ut&xk7d>*06#og&c2Os0e zIqN7N5=S}*SN#gY{`JK(ppk=fN8y>uCxBQt%GOfH^iL`V*!lWzBKI4sPHOirNm!E1!Z<-%#a5S@hc4FeZD zXpiiFZbDzJLTp4C7okRVD+9!>jI5VQS~k5=R}M%*e1gWmpbn6bRt~X3H--pM-X<7H;Vax3WL2 z>-i|H5yw;t+Dr{iO@!RaRP^I%zkr`JH}|FhR>L2RC2U@*9@@v{N5ZT>pjgqJth*RY zBs72s-k534P2xm1Tgw0)`3TprjE;_u%d&D)%QzmHup^ZVO%>B+y*oVO0mcG>2e;?0 zd6o5?PJcGgB6)Mue7q`d{1&v;V1X2t6RN_;y zS`Y%SR#Cf;#60(9E9RA>JJZh=TkdcBlk-Q_UK^>usj-YPqZup3-{BmEXbz!&U-WFU zAUM@*4Y=Q~9^`uOD`Yf-gM_f*?qa!vW-?a|B#eJEdSI>`W>J9{OXK`e4 z#Uemjb@D5Uh%NxFbU`~3QNxP0%a;i$DSNyfn>CU4OvEVh*OpruXaL*6g1+ZtgL10o zClVR|{{0`Ub(xa>8JQf)n50}u_majso)cwSB|m>=_q8p}(n1!TmTsQXK#Q#Yu&FC~ z0nd_Jv}-8*fM#@?5`6+*tdO-eGr$kG)-)Lvzzs?@_<9U~_{^(SB>3eS!^g}N+Pykd zp06WlStB!y7HX^S8To8FN}pRqGMJ;Z(R@bV=D1r6^^4n4MB*`qL?+Q2^Q@l651&2c zeOOZHOz7zg4V0$mge>5glEDd%W4_?FJzH5Pwtkjmi}#7$6b+t?GQkoSn^#1_9-aSG z<9nWM?J@AhAi=l{eWx30i7SGho30;O1jUA9@DuPApzb3siw&tLD07CG`8+IIzmQ|g zg{eebyd~TouVZhy+hs?jUzy=4O@f6nSrZ5X8Mgik>c|%6t3`U{7zUbG5BIkp(=(aK zryBbOQJr5jaqPG>8ag-X)sV^}B}+V4#dYq?@4%%NBT^&9q|YrcAK2f}nJUh}I4*gN z^vvW4Zx2CzN`do)=r|8lFkOqp7J?*|mlpBKWUS)d-y9c}BnAgL`*n8`ZE<)!I_AGS z(Tcfqb?;;piW%@czt_>(9xbbxmFJ`(h|11S z`QmkCT)#kbr>Dbc!14|{%By>&AYw5k8N~6<481gn+mJaFF`(9QQEbO|6&v8$p7=zC zPfpvOgG0?{P(j<(8vjyhB<TT7I!dW9BAVOguVzZuN8w4e* zUv$(EV7tA4szno&_*+``YP*xT+6k^7n2AmQa88De44dFZ=4&|534BslfDTXy`PJ`x z(Wo~|<&LXWD_*f^wR8Y0=Wkap2S@g&rlwffY*<@ve=h-yjEo|0&q{wK7F<}F2EC3EH#9Qh%(2c0AsE-n@95p*{NQiw zp5^9iz5H;$=0v4NDw?U*c=u;8hN#_;bM#cO|$!pBd#b_ zY~hw@Tq+wI8`hxx8)P1v*rqIxX?>SB$?i5|d86VL!cF`=7Ft$+hoGd};8S2s`a~f8RMKhdcfDFy<~CdJiHT}e)FHEp z)?gP_ERajOn zcoY^T3VP}x9-8{en{X1#i-!6K(k5|@`c8GRPUWnpEELb52kpK`(uQ$f<|t*XpaYUX zv0_^_N5`tO(iR%?V6SZL3ifg1IO$Gik!s?awufMbpsMF)N_j(vktIoPX>74CcE)BI z!|SVz42m()d@rAoXi^%DEsmi!1ms94nMfv%?9)GzGM2E!L)15i_q?h~?V=rKDyJkf zNx2mCd^EJQm6N{TG)bnaZR=3eB&lrGW^!#3i!IO5hI%c}Dv-&50uOO!<@fmnH5evH z)K>4#xZaU;gg)VQ8NXjUAV+}$R5Rzfigivi&)GU-Os8GbAc3_^TH8^?bm8e2aJpTj zc{8&{1gDO!U`&g(tGhZNW!F0vID>o{GIUw{`ZNHZe1^h<(ss_{Tquk@-zHymg$hi> zHT-(c*lv*|qKBd=SKti#;WWzpqf3jd~3y z^_b9C`||eO_JIx831aAoo9(@(*z{7Vkej1ii{A`$+#1*1Uwn;hv-mC;V(4~0 z<^6bHVLWV=%$fE<=C5w(@?asR&W9YeK0>fMo6Mpc4rZE7-UwtI#Neh0KJD|tw7HV~ z>1k9Qm1^u44}9qC?x9xpz5H=GF6q1Zlbrn}e@I~bu+ZfE@pp@2!yYm|i-`K^lqHkG zclr7BCj+#=*}?baHw;B(B8uh)yFSQx@IZ>}w;ZzdBVUhRl13sgeu2siSOvEOk8eyD z!8k@c=Rx0H(`u2%eSa4Jb_mzaS_lf*)rseJvu<*1yFcqAl8>YAL>)}A`NPY~#wIs3 zB84cu5OidY-}q~Lu2-uX9i2>#hE zUQ8%4W#Cx;OFvl-CrBj~p8)00URx2YmByr2g#re@bkX~6ilv(^DRe+oUsuRNk*z28 zMyE+SdZB8Cy6A$rvo=#I@Nazi%W&Bn5fI(UpP7|5hOR0T7LgcPqU zX7*n45Cu=b?t>f&Beje-lG-X9?ta{^CD+q_D#yb?mX^(+Sl&C2nhTt;9Ku5nUvcNT zlQ{Y+mt=RhyK8$QO}TYK{{oNF#QMU?Go5OF%x}%tx+Cd}Nxc=(!|Lwm|M{oD-h@ZD1hC(Z1(shDJc!T7-E}xY4kljgd); zPyhMt)=)=L*0U1T^_mgM0#akYS2YXd3}uL+`^mi`FFHYY*gmaN`)qH9yZGLhur|;b zKMBP}%j{zR*VkArx=Jc8N&y8Ymx@i|1a}~AsAId>X}M+XU7Y6V8^#4k;fDH+(V~t7 z^`V2M&Ud(}S)8G<{9s7&_I(O^7tV3)VuE%1!Dio%8M?IQUB9-1M^GW7NrynI?G#(L zd(`{)-B~XhV)^Z+IryW}(NU}z_@Z8^Wr{=733>yshKaCH*0Uvyw4UzbtED_Gd9St4 zmCgK}?`~8t%j=Sb@j1s=* zf-@{F#*=ec4;Pys1^jQ^Z|nzCYOC-*LGXV#eL}Lqa}Uy1G86+Nnksb`7MJn(7SDr> z!YySbB~8z?u5_#Y*=LF4^|yyjFfp9R+is^;2PLB&h-_g1nkCwE(hncsKuYJ<76~Yg zss}#4CzPjIcOKuF5Of(q32E00S8QpQIq|4rx%QYi2*ymX0K>s99;~nzzo1@-`1b>j zPYCdd*hsfX*!6};s#b0|XI#j_`HRe0H_|KHuV=8A@r&9YkPW#=MH$|-(mfKtHiVX{ zRUpVtb~!$YrmGKN*IyggNBt=5RH=09)oAFFN`*!x;w-Jpt!Sk(Kw>Y5G~|2lfgtUB zVcmoVkycX9q}a=?Zc42lk~USe|4r{dz3NWT>yk0>T-N>W%4KLItzV7? zm5U2{S&vxh#$mFEUEeRPLkcO$%CWHJCGYi^jNc^2!bhA&<=6U&Hk^yt6{&@8mttGZ zr$i1YFc{2*x`+59@$~13LoU`sqPLj#CO3)^^Ekt7xTZ^3KkfG3>yWts5a0L{rAjiAko;rDh2d^1y_9}*RXA)+r#p9jx7^&PV&!U_MzUk!#m@>Rw^)`kh9b|S4X z?pNwndT@1z3mUyJhUmr?*~j`URCs6E)|3i|qJAR*27KMO~I6BbL{Q z<*t)hcSnw<9PY@p*2LWRt!4c_y|OnKJb|FRFrSQ6S@rbAdqPKmVG7z&G6Cxkn*t)= zQ9n?fPv>_v7;?$d1r{EK7q?}e?VM1Nnz2hG2B8HD1HrnW5aOZx^ zTr2WPG?qpp<4*%^;2r+KTwTcf^|<0Ngp?(B8x)%mvRPLb?c!f1I^8)t?*$ideJ|;$ zu!19;bIUQt6!gBHka7nYU}3og^s0d_plkuYO2Ac~z2hCH#=LRa5-vtg=4dbpmmwKH zb4|v`Q4uCq{O<@k8bMkKYC1ayWCV@lZsjmnQ?!;bW+}d3^fs#NSUcA81$k!j!L72K zR-&yksCV8g%w1(7SRo&l!v_YGw6(QonLeUWjg}Rp6SI2@!k=3*B(Z{UBOG)=x{1UB zn6OY0|C;TLfrayoqC1K<133a7c3o#=@1k|z#PJ#=r{_UrWM&(E@pSY_M5Ir)FC)h! zTnkT1f~%ZlVsQ1mOxl_hNV7RQ#jjRm>VLofo_iEVI>#A>F9+zESqAHxkd2YHmFQZU zGR3K7MO`lW;+h=ILcg;_>U~F=DG=SgW4Hx@xfzqdka{QQt7H78?s&fUe4|`%xJQLv zJnLT$0qh$pl?TptMphQR9&v%{?oz_m*Ex{t)ulEMfa@FkDKTw81oX8L?DYk3Oa`~w z9}uS$gC`*X@~>LC-K z3U!qI4**RvKmw8!e1t{az8o-)<#BO}2Db%z0YB^q*DVR);UiR^U(J6Ppn{LB9IU^7 z^C5r}e%b!fq~<|Qv~I%{^%%h$p)KUgNU<}}h6Pm3CbdFcKO?#$Ng;4H$j=}xAvu%6 z;fukgjHJ2{Dmd}V^33DQ3n58h0jCYuczVk|bP%_>oUor}Ja!cv3Z#IJt!gIn z(yRrg=P=-ST+sfl=V-ZA3ISq3d_f3Y%(KFc_}kckkb^!wIx3tHm_C3Nk?$ErfBXz^ zmvmv3n22gm*C@-2@DE0g2Ep#yz3deuz-BzEQcbeWDm z|EYYe1_OcO^+H}}I6qw$)cw2p4=e&kSVt)O8nw*9d``j6uWSk5%@^7{LD8P@imlN+ znL8uk>tM;{{?g~0U$DWHsYRi+lZ4*&uNs;YvvOi{nsGQ^#zvnpBc5&lBK-WO4grX+ z-$B8{7xOr**wv3+KOWqx+)90ShZeL<+ZIk6U|rN_sexk}y;&k~kp?B-9coOM3Tz=e zd3s`drM=*FR7iww}m!g~vX7d&UwK6;**Z!=`;iXX}Hky@SV4VCdIhL`Odrb98z=TCT(X#ZldG zoj)2e4^B&XNP|m1P}hSBFPVJMIKbjTYExQVvtSK2$(7(X@QdqH`Q~lYvayRjdmoJg= z@gcbd@^Quf-@bg&XjTT30;8PY7tHGFEunpQh4)O|92Sd>9$%Xfy$e1pA2HMC&&|!% zj;MWdZcQg!ZUOzp8p@QC5|#u&OEG`Si|T(I|(-Vw>}nEar{!s=t|{dR5wgH+ZBEjnbb z&M8$WX6n=Hi4mzs`$DvIIwdv_`0^ZM9?cn>kF2bfSyXmH!gnxLT5D5lw;W3r9`dHv zI`2DLdY2-bn6#RyY(L>_vyYo0>S+GPkpDqleL5oW+4#qsR4VcfYNZ0CMj({K7c(7> z&!`@C#)Fn?-2Yyd-nro~nk$kyTz^!3rx7Wg$(N=#E=o=$%P*HC9yDX@i;dN}QX&&R zRt-b%h>x&kJlg!|^ltDs!q!QTU`sBGuC`%im1%mB{6Z^>eDR|ssd1@tKOtIpr%Tk@ zpWp0#Tc@u;_-8`0$!$wb-zdn#x9e*Q`u~^WwO+g$6g`)bQv| z#jvojMvDOgC52){Bzs~-h{S{hzLYC@$$Mb5OOa4Vin)c&u;ORZNZidi+Xavz=v1kE zh{YRjAtwDpnydkbRGF&e;4@P*Thax9g5AjBKrxtFwQ`Q^1c{-QGPYvnd$GXxMFQ@x z`zc44o@+!8bl-p!Zj&Hr=j0;F#gOoFZbb#hY7&pSfKvGgcH<&d2Y&EG_w6r>>*^1X z-ISo>Oo2K~s1FLT*pwU;p)L3TE-)6DBLWjRn(LU#&jhznm=~oYz1Tdyn5`oMU~ZDL zJ`+ak07O*5Gev;ZzF6vKDjI(hMj&9q%NER<&k2D3)Ig5pnuQ;V86UN1g3kANC7)mh zG3nv4Mh`p8B=MG2$NJTGwL3|vmkD*)&e;eE(wB?AIq_?-V56k>)GMHwC8iwZVB{W~ z`qccIyIVk(QJo1Jgd;gV)@>4r0`zRv1{i{&FY*|av)^dy{~;*ZH}8$@mY|H3D=REy z#K(7`>J@ffJN>HDQ4JeZ;dDa*BDO7?iWGXWg%?=t`n6=ll(U<1!Ciez>rJ=wYpg*2 zwDp9fP+WMn#%iS2)qbHqoh${ zwT0|La+%m-)sF=0&IABB_QYL23%D9xz6Tf_h6^guNbL$c&ML?DbwM5dt>kmJuyxAXm{jA4 z8$%)SMyr9t!gAVO{!^0p6N#J==39FKiWmWT!Qc-7H zVOfyTnU~VR6YZ^WI{Ve!dMrPze9PGPKrotCiUwpOGz3r&Rn0gb>Wzv-V=uvJvY!*~rgohg!wQP^Y6G zRtOOaI_vWE_&iu4=$8wa(+7&S&7f7r-kV;XEYo70VCCkPFHy^~5Qf7Wf57pDjdAm@ z$YgNEuS|bl97WaK58~q>e+4&f6L*Pbe){Jsz~+}qt&Yga$EbQVQ;OtfP$gLB z9+GvbTw4&S#oWPD_M5}}*b!}jo)&f5PnUVIwp)q{%U}s<J6F zB2*lzw4|O>?q)oG4ncxv)zi;S`9Qa_4$PgrdEU>ialo9$hLGmT$ld)%qy72h(Pgi$ zh@oaSBd0-zj?UY@B^L9k*k79;G1fW5ctcIRJp zJ&1mC5Dg9~C*Z7=)l>Q6yH9D(MeBc_FX8U>@%&iJLK<4kci*Y2x7 zNHx_-n?oPpuUhPiamjq1ujSR2B01)bVDYH8r`%p{Z545_ef7ssNy)eZv8bBMR_D*g z&w=0s<}6X9AAj>^3dwri;&?~o2_9GXl2c0Ac=(1F5ndUb77|Lv`TF{5{e;E0CE0Js zosIPRWbwubnuli`bpsT-GbZtzF~xvJbzbi z-u)o3O=@-*f4EvlDqOnJ(flLCNX3~tj2DheJ#JKqr3KJ8_Ej!GG+xCE#npa)xK>|O z%9buiGX-mbsqSv@pc2a7h>)fCbi(_!NA&i1<+;(w=So9rsT*w;9|R@*wn-KrPzKOQ zT`ha=mr5kv^(QjdtO`P%PC z=Qz0}HfgU5l(LWKL1g854OK@JA`rHJiLED_fRnpFo6^Y=<^x-7rf%5}#zcdQF>+5I z!xkHN62jKKDZ@H<@^>b3c=hSGzGO_P39_f3?#m?KELJ)AMCj`%;`E930@>dm{~!`PPXz9veZoTpFZswD>5T zFVjLNM5UrePq`*?T_<|&k(7-Spse46Wugm1FH)Y7yL+H$ivqmywT8yefCLu+Z`&4@nK-o#D6zg@v-GHB`M%l%yG` zI@G1^Ls4n{G^X5oW2t3aTzCyLpLrs2vIWR@nXvh9^x+eclG>&8Gm#8DIISh&-5SCM zkzn*4P`sXNL_^NmZ36rN|>uac6IB1o0?7a9nSnml#R_oIku&9082 zrV_?1eX#(X^mAD@P+jQWSvnPAZQYndNf&9JLd z71_l;(cCFI`tk8o3@(d+B+&g@dYT)(2#q-)OedH`swpy&i4{DYCtm^v)fSQE6G}o~ z6E$mH8gZNpuo3KnVfrqJR!hx38QGt88U^*|+ly@y zK>?d_B&nI{j^AdG($|0P0;HOatH@G}U*7+U-1qpZIT;#pP1Cm31LMs(-32w^G2Zpqk9LYUsKgc$k4fFd|@UXZO|f;LVBeyH^1(F{&_3=+H<9 zqaJB7uD+W0;_QVA4JT#6!dFr&TN+pLbVPFnt^>VaOH1Ue~eXCqc?OQ%2;Ey#BJne~j+YtbWh$2H@p z*67V)9JCM-5N$MPp<58_V+wtbjT~YyZtAZ7GG2Y9%nSBz*_(3Ri z9dUXGh;&E(!cRzU69y&wvV=e+XcrZNiaW;{n-twF$3F!@@&h)icB&x=D-qX77GsmG z7;VYv0~`}GJwA|ytW|MX+4=R#`SB&O<3jzIrH$;|(~uZkivW}lt{BoP6d>DDnES(CqFu0OSo(R>WU5sHpR2RTlzW>g?`OJ zki-yXqp7|!4Sb=wix`=6`~B+=hQ^w~@w6<8v@XRCOa$2!%{!g@If=03hkI)20gmJ3 z0U!;a`}pm`Gp};&BjVMpvCCxQK@}jF1k}^EIYEeEEF)Fzdn{EQJ&c*;li@gY@~Fp0 zOL;3X&wbQ_ zFSSI-ZcpcDt+?TfrQsn(k_kCLbqE1)4`2bKsM1arYFYh6NJ~#mDd90+M@aizh}mZP z)q(T^i7S?$uOVbexsjj8Ets2tiU|K{`aw>X^PoE;n4ux5}6M~Zt)A9FG zBl}MRLMOwI_p}3pgS_6yrs85A<%?^x$f(Ba@8L(dM+FbpCWVE0DnKiu6C)Gg)VW#H z=Xtt4SysQ(LkR(v{3x8sSXshg+F<6tafX^ zn==!L&`vijaU{M!*Ps=RKhllBkm|Ab4)mkADhsl(fIv>1AgRTP4zOlk3pu0-;R>zU z$uAozg5}V$P=Nsp9e!JgCnl8S9ENaZQu>3ESDnVK6yhx5>gUUw$_#H= ziL=?1IQ}ymQv~t*%s}b@#D$oo`bXWZd`~LVqV4W`Rj^O;l#~p!Mg0Noq0e*pgEB>1 z6Hr-W5OJfzK+rzfTfEkgJ^}#@D=1er0Pu|Lj;(4XS!daL)s1%S*srhpO&u6&qrGCO z(T{zr?BOAJNF|J;yc9qQtgJ0Ki%=z)?qI!u(2|8CK5MzbfWfYdNBd+}*3)5(zr;W- zlsX>yZt&qI8idRmwz9%I!vhfZF6gIN=QViHG>8K4_e^*#f2RFJ*AGm?Fnzc9f+4{{ z2)+rlK#mFjgexPNu7=3se4n*1J078?9qLm>FCQ4ic2>KuA1H_PJk zG^0D**~Yi4o~Gbr2{pS(II0>+AMG1BTLgJJ0SY=&T}2*{5pIbJ_8yGW3

t4njUIXkS(gt$Ism0Pt1%b(LO1tSw2ynJHkJ{9_I&yk6 z|D6;O)!6clF|FS*1WZPQa52}uFTUsD65{j$WbcASvXci#wxhWUpnvi+TY@qihxUb{ zVx*0$psDzZlh)ggYATKleaA1RLiWxaMvY0psOnR>(UB5$gM{8ex6Ka|{dPn+CGSPl zpWl4{(aUc8q`SMj*6$ia*y7*`-|gJ<>d1Puv+j-KOj1#vMX z@P>Z^oUpfN`!<#?6nv+^PeDdT!fAX&PJ{Ce-k%1Kcg%ve3wmqpZBCRzcGJGq*X- zXYup1i7pYU{DRod-vp@l35?2J%OH-B)_A$C==5-Z^zL-wd!Q6HmB^Rj*KG%ie~3Xu z=;Ss|>S5M7+b1Hzn*WyoWFaMT{I}vr`rI1|kS*d8D`rZDAPuI2Yi&*~mH!yELJ^Za z4>?YV6=;qXTM!bcLrby)<_H=n=$^5561Js96S2q9OWhqK8ok{qs&08CCMI@YX@h_@ zK@vVO2?+sUMy2-ad-FoBSJyWR31e=Mi!?&;i$bJ{MTW3#TP2xAT^v-|g4isvlaM%< z4_dARN8lBJ{-aBSgrnM>iM}UXtcK+%5_=~EWDn_{2lHdQQ=d5FIn}95K6Ded>7=tO z)6m17W>5UiPv^IKlTeb0&wZbJnV?+#k8Bc{EgdAd{!?hdsV@LI>$6~`;IobKwybtq zmei4JmYp(gJR<{%Iyy7j2J|L0s(0^IvH=Rhv9V~9JP0%uKQ3Zhvp@H>RTn#*mHi6@ zX)T(p7x4;RAF$#TLjRK9RZc-5P_WD$JHy6e4e5(eXUB~1KHr*RB*Ck#@$uS_WsIlB zAQ>ixN|dki4g{xY*lFB)$vS;D^5QKzkd9yUbXS(l!n%|hsBk7W)cFNI8OJqzrXZ8MHPRl;`7h}Bub%PoKnxRo()UO`$xb%@=22tFc_>AbdQ)?zMeNauUY%kEE?KybK!{iG|F?9(MN9#tq91=y^1gfUG@XOlh3 zh%v#X=IL!?PuJdaMT-OWZ1J4Wnih2DG-kk1izXG-OF+Q5pfwXs^m|yT1)8I zF`K%^sQL?kJeWdTU%S}@%zh(RFi=8_`8Iq`U(T8 zGhMlDMMF(Ar<2+}pGXou&;2ZI13M1MishpcXAyhNG76&a2~p@Pp7ULU1rZ7OxIl91 zWj@HS)=#K<1*+0cAvu3GFNZuGUM?74M!_7X%9B@%lo1(rn&AsbAJS*^vTFy!=~kG`ib{&B=vY5htBAz5nVz=*v3MMJSa04 z?JZYUR+bmYr6(;POI1{o6EODyzY65s&ecN;py?n0DEIsK4}ui(KeSy;nZnC{6QOg~ zJbsF-Oz=2+qKbC2IQ%1qMZeRbxfpN5#d)vM+(DHFE$8b$#M*|2DjoRd9)r;ct|EJe z38^iQE$DUQruDHFOz=Bs4i-K}*!F68U=E?2_=y9i#(Kw#w`(WNDkplG623w%RFnpm z*0}P<+S;;%DV+Ryx)coW6)X|Fr*-3ZMVZyIb15C`d6}cVU7ZX{-V?^Wr4+J#eNGtT ztwvhnII28-E8%-l_}Sq58x3XbSOCASI23)w&fsNv`2OtIkeiDG_GjBQLlLP;-J2q@ zn?KVNg_gSp6|~4tG`abAcWt&uKW+ELKTVm`LbO6qWP-o9Cn;V!?l0GwZ1mWRCObho z^Ic>8Gz${2&sGPLZBC7wJhAJX0@X4v&A~iTKk+=uWH}Vby*>O9hX64jj0Tw!@hvyD z;duhPqDS!-2;QTXP}hvtCjQ9_j%rkX!}b?liDW00O%HF`I1lI_nm__A$d10K^%==| zMDa0)w)_^va%e%|7z8g?^c;OSzxERV1E2bS>$NV$cN3pWsGjB{;JqTGA6P(7ek;vI zenKE|(i1}|FPRe;5rIQ3Ci{I+lIftV)mlJFi`G{qA6hCfSEN5<;`2M12qO$@N>N9L z7@NX9-GaX2y#)gmJB_&t)Z-VkY7iO5U5fy7`#zBNYQwV~0>BaqEcA@SCIfuY1s z|4Gfy()awM*-HVp4nz21LLhVx9v~f98VOlnD^{RF{=KYHf|q z5OQF6lS0)a_bjMW z5zIM(xi!uM-8|?9NKxmOmc`sp>EOBx0zCF-gOErKIp#eyF(hi{GqK6PjTDMKZoW57HaY-$2{B? zNyuysrdn#j+YUdbGWMuY@%>G|6QytBCNgV<$5L~i@+96MZ}YCD6F)l!wO#s$ zXUR2-x@|@bvQ4!-*rNE`o4Jcn2{_!;*1A%Odw-~`UyBl1hS$8QrHh-PybLt>X3uN5 zEZXOS7uf4fgUE1=T(372aA?_$v(V_le!l-};zN`}3jRpN^D05T?UEdSrA4lKx|h`6 z;7z&2h1k~tlPfr#G^i&tXuroIGELyRQeHJ&fc`goa_|VZ(fVqRIEY_UIq%S=OqKg0 z!!{%g^tqZQn|)4eJwA9xU&Z$)vRbzftHnA~$(}VXYHnae20%QV65X99#QxEe&rUaK zfA_AG+I*f2DoDPHD^<^t`~~e=uSLc5e+VP(;zx~5T8cDAxcW5x=9}%y!BlQx!^iW` zqd&cHExbrs>-J#e$zoN?MLBU$E_9?j0cZzOq!mrcjRU)Q;`Uc>5Na&1Fw7D7>oS1%YHkbNZdlbA@VOn^z$4>cN_HvH%rI4195w+AY(UO2J*~#AxD)SDD zxAy1g-dF27eD%-oUGwqP%Ww+Ie{}8?_RiwUe>HO>Vj7rMvC(^is<7Yb) z*vX>mR9T=2wrpbT7br5ik|ui_JFxo%4{cO}@Q`;Zq9pa4Qb@yQYnWiKA^QXLCfXaM z|K=3qtgS!f_%8Wq>t9E%@@*-uxh2RVvC-3;Ukd)FYi&H&MUYk(zb<5bI9IAL_#O)e z^^DXe`cp!K5vhG0VVGqg`#}4v2kzS#xn@LE9F3PRUkLwxO?0o z5dZ&uZNbX@>V?Lr*M4%zDv#Tyifhy2nyI@lCArXAKd-}$fU5`<0kOey?u>2MJV+t{ zEk}{SnhOm#FYnaSf#=6+o$_~ocZ;k4?SU70Kff}$3OZpMnL)QrZiQh(0_d`v5hJ2g~Z4 z=bYzz&Uv2C`}24uI-Bbg-{VULQ^a)AZSwW~qViWskb{6gq^*(+qDrOCN3B{wHErd{ezh!|Tk za$E;YmLv6#M9hDyTQPZvVI{ZRje4v(E{pm;MQ_pz#D_%ExIYgo$e)+k>et%M=8FnV zaFp*_9p&j$E;D7wJ;2j!m_(gc?QymyXTIo~(dEs(!>*7!1nq83Ny_Y|(5_1K`3W>{ z^_HKxke5Yi@SoqmpT6~TsJ28v&c@TULab1rI19K4RQ@rMbSPjzJt_HVa(?Vljn_#3 zD2s8k{^q#2udgnbOdk0xvM5v5)IVG7xXbk6I+>o*r^kBjPUb$tTg|iP*LCiy(}kt~ z;8GmnvtZ(%GmRR^EA#K zo*8(8i>)8rNHTv>dT3lWR%R^`S|(gz>A8KPTyAAA9Z05#1bpz+D6M$%_%_a>J+O!) zu6D_$CBXP^KD8iGwKZ#4IPrrSTDXv`V-&?cWidTI5OX>?Ki$q_uQ~mRRi%hLP|lR z9pdwck{kKde1t7TXw~$+fp}f#>@BdYZ_B)roTeMSZ@pCNTuP){%p&XA3fDlJha!T_ zvf|$d-l2eWM=tt=f%&|k+t@ESRVA?8=bRA%VdX%r@y%GndI+U)fTqpKoImcCwS?$R zi?y1|0gT=5Q8sb7zpBos8B7;Q{x3mw@_2iPU$(HjxVTD-c%$V~JYQv5*$s%>SSw$K z%229Mse7on@WEzpYk)1ReX8me>j7DckfHGZa#k5!lw3RSnZq+#fp3TE+;LZ??G+z) zzMT`^EH@fnkt2KbKZOH3GC2OGPY-@N=DnI(9FK1A*SmG#PnM-~Q4Ye3f-0`okl;;C z)}TghlEk~RwThay*Rt^SY&1S;MJa*y@~pl2queX*E=sK%h)+2#wgP;iqjCSj_IDe$ zY(|n6ET@IGb7zK*y+eG2Hcs`22|Ve&p5ym5ufjOaGc%n&-Z5E)nr6i|RvLZqqm32# zeJN?%S%W!Jp`+VQ@|gB@c)y0%Y@yoAQbKl?8^kO0j>^oEcN2^LZ76KaQg}Q!Uj%~v z+z%zZlanR1CfCUHJd$NC5qoro@+o3bHq%Mk3OV*?H6hnU2SK7-ceX#klWU60Prj0j zFgvLi@px6xjL|EQCdNzbge2wiL)ozE3}vw*2V3w)Zm0KflzpM+Tci;@5Fjf93lx?4 zdaT9&-E0$=CE}xnj|<-HvOWbD;M|Auoa-%+&%o+U(bAf}RO_*a4J-JXXfNqY4_UU^ zxoQ|@<$?s;-3p)7fZ_Uk5Jr=TnUb>l+#gXwU~1BLwpPC!NYl6F*Ro@y71=ul|2@q! zsv&P7+kFSY+y&h_>tbR$F$Yy^(Y)8D8d%^SD3S`XZvf0w4#vaHbKF7cs zi;sUlV2Y6hsJNqy2WZe)|FN_H0IHF~%2BefjP!LnajIpTk2lfS)TuEtgt#DD!fAAI zKz#$TJwok45CF5&TSsJnW%I6XBdcrOdDS!G+U(umSu5W!Lp{+_I{|i0L9^+hTCjI zt*zFOj91@-9>)s>omLlVSm})z!*5smFT8y3YWqrvnS3d=E7Y?K1>2Y{yo`s{%WCJ0 z+>*&K9`jTY*q;Q-U5js$pTGU3DnEPUf?hKl-@^+~W8I3KxDgn$Q+x9C{7L_V@MXICj{w08JfvB6n~O;{Tj+zqfPX zel8g22Ky#_{pwQV-`gP=C5kzX`0(r;yH529q~(MRsRD3zp$E$Z_lW2EON=D596@6^?Cu zSr(4mKI<{@ZWJAQi3PKvw2@RGOH!LVP)w}y?h>gvR$>65Wmd1@XHj3gm1BPyG_-Yi z?}FEAt|;PQ_UVZkxI!o+oej2)yr#kl)kZfX1pNJ|QeuIB+<}VbdEJCJQem?W-nEf~ z?;Jomb-h6-AfpZQ${UF%b5UnO5L6rjN?yJc4E$Qt_T;o&OB5GoWfNfNald2FU+&Tj zPtFYdhqUhK98`<-PM?KicLyH$T2rUMO6|c;XmN+ZhXBTIDzI>w=6iRE+?>W9S)_q1 zP?#AUMbG>|VHxbC&K50#5_mA6WE1|(zgG@M5EK;O2tSYn3vk%x-(~RpTT7 zaA0q{kNRw_!5NnGU?Qoe69o*q^~^TEk%|(;^j&{0gGd&m@^XI0p`24dm2IS*n>6&1 z3YW4U{DTJs{*4{F_u7qg3*<$h&qj#N9?|q&5+E5?pwxw_1gNATfi{B3p@pVO<#@eU zfRA*70g+?W1{}ZT=HmR`cwu&Z6NC>bTXo-g0G<}(NI8h}`{-wn+>EvXPHdxrKr;TO z&~2J0eA6Hjah{WI;f^J7A)dWF>A4S0t^Cx_;>1e0*))Dce@Vb7{0*WGyEct9R5eiu z^~tFgY>a-5X1bS)gO}uyOFehYCgez42xI|@Iyj0`xJP=R>_Xe6ql|D1y!e2*Ur9W_ zz%SMxNDL~jVi-;Qdk#z5sXAuMqRqMcGjBw(D`fYW;`k{`E0gZUy%vEd%xp|6ObCDd E3uT4g^8f$< diff --git a/packages/fether-electron/build/icons/32x32.png b/packages/fether-electron/build/icons/32x32.png deleted file mode 100644 index f33a32c8f0b35ee1ca8b154962727236fe00b387..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3181 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 diff --git a/packages/fether-electron/build/icons/512x512.png b/packages/fether-electron/build/icons/512x512.png deleted file mode 100644 index 8dfc0a6a2e12f4910cdb8d5912777d5d698a34b4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 48459 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 z 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 diff --git a/packages/fether-electron/build/icons/64x64.png b/packages/fether-electron/build/icons/64x64.png deleted file mode 100644 index c930c704dbd2298ef13411533e90c9543e8acf58..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4899 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%0DLwMw>G%3}T=EK)ViW7Cm)?4G;^%lR4q@J2>r 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%0DLwMw>G%3}T=EK)ViW7Cm)?4G;^%lR4q@J2>r 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 A7XSbN diff --git a/packages/fether-electron/static/assets/icons/16x16.png b/packages/fether-electron/static/assets/icons/16x16.png deleted file mode 100644 index 0e3e52463bb3264288b2ff4a1682bbe7672e603c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2199 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 E3uT4g^8f$< diff --git a/packages/fether-electron/static/assets/icons/32x32.png b/packages/fether-electron/static/assets/icons/32x32.png deleted file mode 100644 index f33a32c8f0b35ee1ca8b154962727236fe00b387..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3181 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 diff --git a/packages/fether-electron/static/assets/icons/512x512.png b/packages/fether-electron/static/assets/icons/512x512.png deleted file mode 100644 index 8dfc0a6a2e12f4910cdb8d5912777d5d698a34b4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 48459 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 z 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 diff --git a/packages/fether-electron/static/assets/icons/64x64.png b/packages/fether-electron/static/assets/icons/64x64.png deleted file mode 100644 index c930c704dbd2298ef13411533e90c9543e8acf58..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4899 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%0DLwMw>G%3}T=EK)ViW7Cm)?4G;^%lR4q@J2>r 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 Date: Thu, 31 Jan 2019 15:35:20 +1100 Subject: [PATCH 076/153] fix: Prevent removalAllListeners of undefined error when close window on Windows --- packages/fether-electron/src/main/app/index.js | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/packages/fether-electron/src/main/app/index.js b/packages/fether-electron/src/main/app/index.js index 8355bcfb4..6133ebbec 100644 --- a/packages/fether-electron/src/main/app/index.js +++ b/packages/fether-electron/src/main/app/index.js @@ -642,12 +642,15 @@ class FetherApp { }; windowClear = () => { - // Remove relevant events when window object deleted - const events = ['close', 'move', 'moved', 'resize']; - for (let event in events) { - this.fetherApp.window.removeAllListeners(event); + if (this.fetherApp.window) { + // Remove relevant events when window object deleted + const events = ['close', 'move', 'moved', 'resize']; + for (let event in events) { + this.fetherApp.window.removeAllListeners(event); + } + delete this.fetherApp.window; } - delete this.fetherApp.window; + this.fetherApp.emit('after-close-window'); }; From aa5abc11cfd8d5c378b761999520a65634ea04b9 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Thu, 31 Jan 2019 19:31:44 +1100 Subject: [PATCH 077/153] feat: Add Windows icon Reference: https://www.electron.build/icons#windows-nsis --- .../fether-electron/build/icons/1024x1024.png | Bin 40762 -> 0 bytes packages/fether-electron/build/icons/icon.ico | Bin 0 -> 33536 bytes packages/fether-electron/electron-builder.json | 1 + 3 files changed, 1 insertion(+) delete mode 100644 packages/fether-electron/build/icons/1024x1024.png create mode 100644 packages/fether-electron/build/icons/icon.ico diff --git a/packages/fether-electron/build/icons/1024x1024.png b/packages/fether-electron/build/icons/1024x1024.png deleted file mode 100644 index bd61e1bfc4fdbe921b43161c08a98fa23157b45c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 40762 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%0DLwMw>G%3}T=EK)ViW7Cm)?4G;^%lR4q@J2>r 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

!0K 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 R+noRa002ovPDHLkV1k4f*O~wT literal 0 HcmV?d00001 diff --git a/packages/fether-electron/electron-builder.json b/packages/fether-electron/electron-builder.json index 95ccbd415..02dcdff79 100644 --- a/packages/fether-electron/electron-builder.json +++ b/packages/fether-electron/electron-builder.json @@ -11,6 +11,7 @@ "productName": "Parity Fether", "publish": "github", "win": { + "icon": "icons/icon.ico", "publisherName": "Parity Technologies (UK) Ltd.", "target": "nsis" } From 0c0788c2c309a21e74f3019d4929b35b6c0e9402 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Thu, 31 Jan 2019 22:32:27 +1100 Subject: [PATCH 078/153] review-fix: Remove blue background highlight from tray icon on macOS --- .../fether-electron/src/main/app/index.js | 22 +------------------ 1 file changed, 1 insertion(+), 21 deletions(-) diff --git a/packages/fether-electron/src/main/app/index.js b/packages/fether-electron/src/main/app/index.js index 6133ebbec..2d796fb43 100644 --- a/packages/fether-electron/src/main/app/index.js +++ b/packages/fether-electron/src/main/app/index.js @@ -420,15 +420,7 @@ class FetherApp { } }); tray.setToolTip(options.tooltip); - - this.fetherApp.supportsTrayHighlightState = false; - - try { - tray.setHighlightMode('never'); - this.fetherApp.supportsTrayHighlightState = true; - } catch (e) { - console.error('Unable to set highlight mode: ', e); - } + tray.setHighlightMode('never'); }; createWindow = () => { @@ -461,12 +453,6 @@ class FetherApp { }; showWindow = trayPos => { - const { supportsTrayHighlightState, tray } = this.fetherApp; - - if (supportsTrayHighlightState) { - tray.setHighlightMode('always'); - } - if (!this.fetherApp.window) { this.createWindow(); } @@ -526,16 +512,10 @@ class FetherApp { }; hideWindow = () => { - const { supportsTrayHighlightState, tray } = this.fetherApp; - if (!this.fetherApp.window) { return; } - if (supportsTrayHighlightState) { - tray.setHighlightMode('never'); - } - this.saveWindowPosition(); // Save window position when hide, particularly necessary on Linux this.fetherApp.emit('hide-window'); From b4d3a3b69b6fa946140c08cfec35b35e45ead020 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Thu, 31 Jan 2019 22:37:58 +1100 Subject: [PATCH 079/153] refactor: State that downloading Parity Ethereum precisely --- .../src/RequireHealthOverlay/RequireHealthOverlay.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/fether-react/src/RequireHealthOverlay/RequireHealthOverlay.js b/packages/fether-react/src/RequireHealthOverlay/RequireHealthOverlay.js index f69a79053..c699b2d34 100644 --- a/packages/fether-react/src/RequireHealthOverlay/RequireHealthOverlay.js +++ b/packages/fether-react/src/RequireHealthOverlay/RequireHealthOverlay.js @@ -87,7 +87,7 @@ class RequireHealthOverlay extends Component { case STATUS.CLOCKNOTSYNC: return 'Your clock is not sync'; case STATUS.DOWNLOADING: - return 'Downloading Parity...'; + return 'Downloading Parity Ethereum...'; case STATUS.NOINTERNET: return 'No Internet connection'; case STATUS.NOPEERS: From 955bcad9c0dd3e325b63891c9894f618d3ec2b82 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Thu, 31 Jan 2019 22:57:51 +1100 Subject: [PATCH 080/153] review-fix: Remove craco and extend dependencies --- packages/fether-electron/package.json | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/fether-electron/package.json b/packages/fether-electron/package.json index 4aa3ecf6e..48c3ccf17 100644 --- a/packages/fether-electron/package.json +++ b/packages/fether-electron/package.json @@ -39,13 +39,11 @@ "test": "ln -s ../../../node_modules/react-scripts node_modules/ && cross-env SKIP_PREFLIGHT_CHECK=true craco test; rm node_modules/react-scripts" }, "dependencies": { - "@craco/craco": "^3.2.3", "@parity/electron": "^3.0.1", "commander": "^2.15.1", "commander-remaining-args": "^1.2.0", "electron-positioner": "^4.1.0", "electron-settings": "^3.2.0", - "extend": "^3.0.2", "fether-react": "^0.3.0", "pino": "^4.16.1", "pino-multi-stream": "^3.1.2", From 7aa59ce4b834c498f8b63a7eae9a45b84760806a Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Thu, 31 Jan 2019 23:14:56 +1100 Subject: [PATCH 081/153] review-fix: Replace console.logs with pino --- .../fether-electron/src/main/app/index.js | 26 ++++++++----------- .../src/main/app/utils/window.js | 5 +++- 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/packages/fether-electron/src/main/app/index.js b/packages/fether-electron/src/main/app/index.js index 2d796fb43..ec87d5ccc 100644 --- a/packages/fether-electron/src/main/app/index.js +++ b/packages/fether-electron/src/main/app/index.js @@ -182,7 +182,7 @@ class FetherApp { // macOS and Linux (not Windows) this.fetherApp.window.on('resize', () => { - console.log('Detected resize event'); + pino.info('Detected resize event'); this.moveWindowUp(); setTimeout(() => { this.moveWindowUp(); @@ -261,7 +261,7 @@ class FetherApp { } if (eventName !== null) { - console.log('Detected event ' + eventName); + pino.info('Detected event:', eventName); } } ); @@ -275,11 +275,12 @@ class FetherApp { this.fetherApp.window.hookWindowMessage( Number.parseInt('0x0232'), (wParam, lParam) => { - console.log('Detected completion of move or resize event'); + pino.info('Detected completion of move or resize event'); // Move Fether window back up into view if it was a resize event // that causes the bottom to be cropped this.moveWindowUp(); + // Try again after a delay incase Fether window resize occurs // x seconds after navigating to a new page. setTimeout(() => { @@ -306,18 +307,14 @@ class FetherApp { return; } - console.log( - 'Fether window resized. Moving it back up into view if required' - ); - const position = this.fetherApp.window.getPosition(); + pino.info('Fether window resized. Moving it back up into view if required'); + const position = this.fetherApp.window.getPosition(); const positionStruct = { x: position[0], y: position[1] }; - const trayDepth = this.fetherApp.trayDepth || 40; // Default incase resizes on load - const currentScreenResolution = this.getScreenResolution(); const windowHeight = this.fetherApp.window.getSize()[1]; const maxWindowY = currentScreenResolution.y - windowHeight - trayDepth; @@ -415,7 +412,7 @@ class FetherApp { // Right click event handler does not work on Windows as intended tray.on('right-click', () => { if (process.platform === 'win32') { - console.log('Detected right click on Windows'); + pino.info('Detected right click on Windows'); this.showTrayBalloon(); } }); @@ -461,11 +458,10 @@ class FetherApp { const calculatedWindowPosition = this.calculateWindowPosition(trayPos); - console.log('Calculated window position: ', calculatedWindowPosition); + pino.info('Calculated window position: ', calculatedWindowPosition); const mainScreen = screen.getPrimaryDisplay(); // const allScreens = screen.getAllDisplays(); - const mainScreenDimensions = mainScreen.size; const mainScreenWorkAreaSize = mainScreen.workAreaSize; @@ -475,7 +471,7 @@ class FetherApp { mainScreenDimensions.height - mainScreenWorkAreaSize.height ); - console.log( + pino.info( 'Previously saved window position exists: ', hasSavedWindowPosition() ); @@ -484,11 +480,11 @@ class FetherApp { ? getSavedWindowPosition() : undefined; - console.log('Loaded window position: ', loadedWindowPosition); + pino.info('Loaded window position: ', loadedWindowPosition); const fixedWindowPosition = this.fixWindowPosition(loadedWindowPosition); - console.log('Fixed window position: ', fixedWindowPosition); + pino.info('Fixed window position: ', fixedWindowPosition); /** * Since the user may change the taskbar tray to be on any side of the screen. diff --git a/packages/fether-electron/src/main/app/utils/window.js b/packages/fether-electron/src/main/app/utils/window.js index c9507e359..7dbbf005c 100644 --- a/packages/fether-electron/src/main/app/utils/window.js +++ b/packages/fether-electron/src/main/app/utils/window.js @@ -3,6 +3,9 @@ // // SPDX-License-Identifier: BSD-3-Clause +import Pino from './pino'; +const pino = Pino(); + /** * Returns the latest window resolution if it differs from the previous resolution. * Note that the previous window resolution may be undefined if being changed in settings. @@ -33,7 +36,7 @@ const shouldFixWindowPosition = ( previousScreenResolution, currentScreenResolution ) => { - console.log( + pino.info( 'Window position (previous, current): ', previousScreenResolution, currentScreenResolution From dfb3f7bc613398e524bafc198ec1f946fad10fe5 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Fri, 1 Feb 2019 08:12:01 +1100 Subject: [PATCH 082/153] test: Update package.json to use Jest with colours --- packages/fether-electron/package.json | 4 +++- packages/fether-react/package.json | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/fether-electron/package.json b/packages/fether-electron/package.json index 48c3ccf17..15d2a5972 100644 --- a/packages/fether-electron/package.json +++ b/packages/fether-electron/package.json @@ -36,7 +36,7 @@ "prerelease": "./scripts/revertElectronBug.sh", "release": "electron-builder", "start": "cross-env ELECTRON_START_URL=http://localhost:3000 electron-webpack dev --ws-origins all", - "test": "ln -s ../../../node_modules/react-scripts node_modules/ && cross-env SKIP_PREFLIGHT_CHECK=true craco test; rm node_modules/react-scripts" + "test": "jest --all --color --coverage" }, "dependencies": { "@parity/electron": "^3.0.1", @@ -53,11 +53,13 @@ "@babel/cli": "^7.0.0-beta.49", "@babel/core": "^7.0.0-beta.49", "@babel/preset-env": "^7.0.0-beta.49", + "babel-jest": "^24.0.0", "copyfiles": "^2.0.0", "cross-env": "^5.2.0", "electron": "^2.0.2", "electron-builder": "^20.29.0", "electron-webpack": "^2.1.2", + "jest": "^24.0.0", "webpack": "^4.7.0" } } \ No newline at end of file diff --git a/packages/fether-react/package.json b/packages/fether-react/package.json index dd7472c07..0e01a48f6 100644 --- a/packages/fether-react/package.json +++ b/packages/fether-react/package.json @@ -31,7 +31,7 @@ "start": "npm-run-all -p start-*", "start-css": "npm run build-css -- --watch --recursive", "start-js": "cross-env SKIP_PREFLIGHT_CHECK=true BROWSER=none craco start --react-scripts ../../node_modules/react-scripts", - "test": "ln -s ../../../node_modules/react-scripts node_modules/ && cross-env SKIP_PREFLIGHT_CHECK=true craco test; rm node_modules/react-scripts" + "test": "jest --all --color --coverage" }, "dependencies": { "@craco/craco": "^3.2.3", @@ -72,7 +72,9 @@ }, "devDependencies": { "@babel/plugin-proposal-decorators": "^7.2.0", + "babel-jest": "^24.0.0", "capitalize": "^1.0.0", + "jest": "^24.0.0", "node-sass": "^4.9.0", "node-sass-chokidar": "^1.2.2", "npm-run-all": "^4.1.2" From 7c9eb5f9d703bbe1184b4570eadcc83b5f139bdc Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Fri, 1 Feb 2019 10:36:07 +1100 Subject: [PATCH 083/153] test: Setup Jest --- packages/fether-electron/babel.config.js | 5 ++++- packages/fether-electron/package.json | 1 + packages/fether-react/babel.config.js | 11 +++++++++++ packages/fether-react/package.json | 4 ++++ 4 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 packages/fether-react/babel.config.js diff --git a/packages/fether-electron/babel.config.js b/packages/fether-electron/babel.config.js index f3a623b23..41b44e8d6 100644 --- a/packages/fether-electron/babel.config.js +++ b/packages/fether-electron/babel.config.js @@ -1,4 +1,7 @@ module.exports = { - plugins: ['@babel/plugin-proposal-class-properties'], + plugins: [ + '@babel/plugin-proposal-class-properties', + '@babel/plugin-transform-modules-commonjs' + ], presets: ['@babel/preset-env'] }; diff --git a/packages/fether-electron/package.json b/packages/fether-electron/package.json index 15d2a5972..ce70af7d5 100644 --- a/packages/fether-electron/package.json +++ b/packages/fether-electron/package.json @@ -52,6 +52,7 @@ "devDependencies": { "@babel/cli": "^7.0.0-beta.49", "@babel/core": "^7.0.0-beta.49", + "@babel/plugin-transform-modules-commonjs": "^7.2.0", "@babel/preset-env": "^7.0.0-beta.49", "babel-jest": "^24.0.0", "copyfiles": "^2.0.0", diff --git a/packages/fether-react/babel.config.js b/packages/fether-react/babel.config.js new file mode 100644 index 000000000..4eca21b9b --- /dev/null +++ b/packages/fether-react/babel.config.js @@ -0,0 +1,11 @@ +module.exports = { + plugins: [ + '@babel/plugin-proposal-class-properties', + '@babel/plugin-transform-modules-commonjs' + ], + presets: [ + '@babel/preset-env', + '@babel/preset-react', + ['@babel/preset-stage-0', { decoratorsLegacy: true }] + ] +}; diff --git a/packages/fether-react/package.json b/packages/fether-react/package.json index 0e01a48f6..e6708cd13 100644 --- a/packages/fether-react/package.json +++ b/packages/fether-react/package.json @@ -71,7 +71,11 @@ "rxjs": "^6.2.0" }, "devDependencies": { + "@babel/cli": "^7.0.0-beta.49", + "@babel/core": "^7.0.0-beta.49", + "@babel/plugin-transform-modules-commonjs": "^7.2.0", "@babel/plugin-proposal-decorators": "^7.2.0", + "@babel/preset-env": "^7.0.0-beta.49", "babel-jest": "^24.0.0", "capitalize": "^1.0.0", "jest": "^24.0.0", From 1807ca24b080d975ec21a39118f559c153f17096 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Fri, 1 Feb 2019 10:36:52 +1100 Subject: [PATCH 084/153] test: Mock pino.info to pass Fether window tests in Fether Electron --- packages/fether-electron/src/main/app/utils/window.spec.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/fether-electron/src/main/app/utils/window.spec.js b/packages/fether-electron/src/main/app/utils/window.spec.js index 39a9a14b7..660163b78 100644 --- a/packages/fether-electron/src/main/app/utils/window.spec.js +++ b/packages/fether-electron/src/main/app/utils/window.spec.js @@ -7,6 +7,10 @@ import { getScreenResolution, shouldFixWindowPosition } from './window'; +jest.mock('./pino', () => () => ({ + info: () => {} +})); + let smallScreenResolution, largeScreenResolution; describe('window resolution', () => { From 22ed464d5565df15da8144f9db323f74face0add Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Fri, 1 Feb 2019 10:45:21 +1100 Subject: [PATCH 085/153] test: Fix pipelineOperator error that was failing tests Fixes error: 'pipelineOperator' requires 'proposal' option whose value should be one of: 'minimal', 'smart' --- packages/fether-react/babel.config.js | 1 + packages/fether-react/package.json | 1 + 2 files changed, 2 insertions(+) diff --git a/packages/fether-react/babel.config.js b/packages/fether-react/babel.config.js index 4eca21b9b..46c4634ae 100644 --- a/packages/fether-react/babel.config.js +++ b/packages/fether-react/babel.config.js @@ -1,6 +1,7 @@ module.exports = { plugins: [ '@babel/plugin-proposal-class-properties', + ['@babel/plugin-proposal-pipeline-operator', { proposal: 'minimal' }], '@babel/plugin-transform-modules-commonjs' ], presets: [ diff --git a/packages/fether-react/package.json b/packages/fether-react/package.json index e6708cd13..dfd01326c 100644 --- a/packages/fether-react/package.json +++ b/packages/fether-react/package.json @@ -74,6 +74,7 @@ "@babel/cli": "^7.0.0-beta.49", "@babel/core": "^7.0.0-beta.49", "@babel/plugin-transform-modules-commonjs": "^7.2.0", + "@babel/plugin-proposal-pipeline-operator": "^7.3.0", "@babel/plugin-proposal-decorators": "^7.2.0", "@babel/preset-env": "^7.0.0-beta.49", "babel-jest": "^24.0.0", From d293a7df7f92a9fb2641e7d95e0d67fbd66459c6 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Fri, 1 Feb 2019 10:59:08 +1100 Subject: [PATCH 086/153] test: Fix Babel decorators plugin errors * Fixes `SyntaxError ... Decorators transform is necessary.` (regarding use of `@observable`) * Fixes `Decorating class property failed. Please ensure that proposal-class-properties is enabled and set to use loose mode. To use proposal-class-properties in spec mode with decorators, wait for the next major version of decorators in stage 2.` --- packages/fether-react/babel.config.js | 3 ++- packages/fether-react/src/utils/transaction.spec.js | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/fether-react/babel.config.js b/packages/fether-react/babel.config.js index 46c4634ae..890790ea3 100644 --- a/packages/fether-react/babel.config.js +++ b/packages/fether-react/babel.config.js @@ -1,6 +1,7 @@ module.exports = { plugins: [ - '@babel/plugin-proposal-class-properties', + ['@babel/plugin-proposal-decorators', { legacy: true }], // should be first plugin listed + ['@babel/plugin-proposal-class-properties', { loose: true }], ['@babel/plugin-proposal-pipeline-operator', { proposal: 'minimal' }], '@babel/plugin-transform-modules-commonjs' ], diff --git a/packages/fether-react/src/utils/transaction.spec.js b/packages/fether-react/src/utils/transaction.spec.js index faf5f6816..f580b36fa 100644 --- a/packages/fether-react/src/utils/transaction.spec.js +++ b/packages/fether-react/src/utils/transaction.spec.js @@ -40,7 +40,7 @@ describe('estimateGas', () => { test('should call estimateGasForErc20 with token', () => { expect(estimateGas(mock.tx, mock.erc20, mock.api)).resolves.toEqual( - new BigNumber(153.75) + new BigNumber(154) ); }); From d2c41d0d7067890041a8f80d9a3f8b81d19cf375 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Fri, 1 Feb 2019 12:20:42 +1100 Subject: [PATCH 087/153] test: Fix all failing tests * Update tests to include missing `token` property to a Tx of Ether or Token * Update tests to include missing `address` property to a Tx of Ether to fixes `TypeError: Cannot read property 'address' of undefined` error * Update tests to include missing `options` and `args` properties to the Tx so the second argument passed to `transfer$` in `contractForToken(token.address).transfer$(..., ...)` is not NaN * Fix error `ReferenceError: regeneratorRuntime is not defined` --- packages/fether-react/babel.config.js | 3 +- packages/fether-react/package.json | 2 + .../fether-react/src/stores/sendStore.spec.js | 32 +++++++---- .../src/utils/testHelpers/mock.js | 53 +++++++++++++++---- .../src/utils/transaction.spec.js | 4 +- 5 files changed, 70 insertions(+), 24 deletions(-) diff --git a/packages/fether-react/babel.config.js b/packages/fether-react/babel.config.js index 890790ea3..496fdd838 100644 --- a/packages/fether-react/babel.config.js +++ b/packages/fether-react/babel.config.js @@ -3,7 +3,8 @@ module.exports = { ['@babel/plugin-proposal-decorators', { legacy: true }], // should be first plugin listed ['@babel/plugin-proposal-class-properties', { loose: true }], ['@babel/plugin-proposal-pipeline-operator', { proposal: 'minimal' }], - '@babel/plugin-transform-modules-commonjs' + '@babel/plugin-transform-modules-commonjs', + '@babel/plugin-transform-runtime' ], presets: [ '@babel/preset-env', diff --git a/packages/fether-react/package.json b/packages/fether-react/package.json index dfd01326c..dcea21951 100644 --- a/packages/fether-react/package.json +++ b/packages/fether-react/package.json @@ -34,6 +34,7 @@ "test": "jest --all --color --coverage" }, "dependencies": { + "@babel/runtime": "^7.3.1", "@craco/craco": "^3.2.3", "@parity/abi": "^3.0.25", "@parity/api": "^3.0.25", @@ -74,6 +75,7 @@ "@babel/cli": "^7.0.0-beta.49", "@babel/core": "^7.0.0-beta.49", "@babel/plugin-transform-modules-commonjs": "^7.2.0", + "@babel/plugin-transform-runtime": "^7.2.0", "@babel/plugin-proposal-pipeline-operator": "^7.3.0", "@babel/plugin-proposal-decorators": "^7.2.0", "@babel/preset-env": "^7.0.0-beta.49", diff --git a/packages/fether-react/src/stores/sendStore.spec.js b/packages/fether-react/src/stores/sendStore.spec.js index 67071257c..8fe68f89e 100644 --- a/packages/fether-react/src/stores/sendStore.spec.js +++ b/packages/fether-react/src/stores/sendStore.spec.js @@ -50,8 +50,14 @@ describe('method acceptRequest', () => { }); describe('method clear', () => { - test('should clear tx', () => { - sendStore.setTx(mock.tx); + test('should clear txEth', () => { + sendStore.setTx(mock.txEth); + sendStore.clear(); + expect(sendStore.tx).toEqual({}); + }); + + test('should clear txErc20', () => { + sendStore.setTx(mock.txErc20); sendStore.clear(); expect(sendStore.tx).toEqual({}); }); @@ -82,12 +88,10 @@ describe('@computed confirmations', () => { }); describe('method send', () => { - beforeEach(() => { - sendStore.setTx(mock.tx); - }); - test('should call transfer$ if the token is Erc20', () => { - sendStore.send(mock.erc20); + sendStore.setTx(mock.txErc20); + sendStore.send('password'); + expect(mock.txErc20.token.address).toEqual('THIBCoin'); expect(mock.makeContract.transfer$).toHaveBeenCalledWith( '0x123', new BigNumber('10000000000000000'), @@ -96,7 +100,9 @@ describe('method send', () => { }); test('should call post$ if the token is ETH', () => { - sendStore.send(mock.eth); + sendStore.setTx(mock.txEth); + sendStore.send('password'); + expect(mock.txEth.token.address).toEqual('ETH'); expect(lightJs.post$).toHaveBeenCalledWith({ from: '0x456', gasPrice: new BigNumber('4000000000'), @@ -107,14 +113,18 @@ describe('method send', () => { test('should update txStatus', () => { sendStore.setTxStatus = jest.fn(); - sendStore.send(mock.eth); + sendStore.setTx(mock.txEth); + sendStore.send('password'); + expect(mock.txEth.token.address).toEqual('ETH'); expect(sendStore.setTxStatus).toHaveBeenCalledWith({ estimating: true }); }); test('should call acceptRequest when txStatus is requested', () => { sendStore.acceptRequest = jest.fn(() => Promise.resolve(true)); - sendStore.send(mock.eth, 'foo'); - expect(sendStore.acceptRequest).toHaveBeenCalledWith(1, 'foo'); + sendStore.setTx(mock.txEth); + sendStore.send('password'); + expect(mock.txEth.token.address).toEqual('ETH'); + expect(sendStore.acceptRequest).toHaveBeenCalledWith(1, 'password'); }); }); diff --git a/packages/fether-react/src/utils/testHelpers/mock.js b/packages/fether-react/src/utils/testHelpers/mock.js index d1dc0f952..09c97e169 100644 --- a/packages/fether-react/src/utils/testHelpers/mock.js +++ b/packages/fether-react/src/utils/testHelpers/mock.js @@ -6,15 +6,24 @@ /* eslint-env jest */ import BigNumber from 'bignumber.js'; +import { toWei } from '@parity/api/lib/util/wei'; + +const SECRET_PHRASE = 'foo'; +const ADDRESS_FROM = '0x456'; +const ADDRESS_TO = '0x123'; +const GAS_PRICE = 4; // in Gwei +const GAS_ESTIMATE = 456; +const GAS_ESTIMATE_CONTRACT_TX = 123; +const AMOUNT = 0.01; export const api = { eth: { - estimateGas: jest.fn(() => Promise.resolve(new BigNumber(456))) + estimateGas: jest.fn(() => Promise.resolve(new BigNumber(GAS_ESTIMATE))) }, parity: { - generateSecretPhrase: jest.fn(() => Promise.resolve('foo')), + generateSecretPhrase: jest.fn(() => Promise.resolve(SECRET_PHRASE)), newAccountFromPhrase: jest.fn(() => Promise.resolve()), - phraseToAddress: jest.fn(() => Promise.resolve('0x123')), + phraseToAddress: jest.fn(() => Promise.resolve(ADDRESS_TO)), setAccountName: jest.fn(() => Promise.resolve()), setAccountMeta: jest.fn(() => Promise.resolve()) }, @@ -24,7 +33,7 @@ export const api = { }; export const erc20 = { - address: 'foo', + address: 'THIBCoin', decimals: 18 }; @@ -36,7 +45,8 @@ export const makeContract = { contractObject: { instance: { transfer: { - estimateGas: () => Promise.resolve(new BigNumber(123)) + estimateGas: () => + Promise.resolve(new BigNumber(GAS_ESTIMATE_CONTRACT_TX)) } } }, @@ -50,9 +60,32 @@ export const post$ = { }) }; -export const tx = { - amount: 0.01, // In Ether or in token - from: '0x456', - gasPrice: 4, // in Gwei - to: '0x123' +export const txEth = { + amount: AMOUNT, // In Ether + from: ADDRESS_FROM, + gasPrice: GAS_PRICE, + to: ADDRESS_TO, + token: eth +}; + +const txErc20Base = { + amount: AMOUNT, // In token + from: ADDRESS_FROM, + gasPrice: GAS_PRICE, + to: ADDRESS_TO, + token: erc20 +}; + +export const txErc20 = { + ...txErc20Base, + args: [ + txErc20Base.to, + new BigNumber(txErc20Base.amount).multipliedBy( + new BigNumber(10).pow(txErc20Base.token.decimals) + ) + ], + options: { + from: txErc20Base.from, + gasPrice: toWei(txErc20Base.gasPrice, 'shannon') // shannon == gwei + } }; diff --git a/packages/fether-react/src/utils/transaction.spec.js b/packages/fether-react/src/utils/transaction.spec.js index f580b36fa..4b7d6e8c9 100644 --- a/packages/fether-react/src/utils/transaction.spec.js +++ b/packages/fether-react/src/utils/transaction.spec.js @@ -39,13 +39,13 @@ describe('estimateGas', () => { }); test('should call estimateGasForErc20 with token', () => { - expect(estimateGas(mock.tx, mock.erc20, mock.api)).resolves.toEqual( + expect(estimateGas(mock.txErc20, mock.erc20, mock.api)).resolves.toEqual( new BigNumber(154) ); }); test('should call estimateGasForEth with token', () => { - expect(estimateGas(mock.tx, mock.eth, mock.api)).resolves.toEqual( + expect(estimateGas(mock.txEth, mock.eth, mock.api)).resolves.toEqual( new BigNumber(570) ); }); From cc280b7c8245889ed639e4d56d6d43320a76b795 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Fri, 1 Feb 2019 13:30:47 +1100 Subject: [PATCH 088/153] fix: Remove Babel plugins that broke yarn electron build but are unnecessary --- packages/fether-electron/babel.config.js | 5 +---- packages/fether-electron/package.json | 1 - 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/packages/fether-electron/babel.config.js b/packages/fether-electron/babel.config.js index 41b44e8d6..f3a623b23 100644 --- a/packages/fether-electron/babel.config.js +++ b/packages/fether-electron/babel.config.js @@ -1,7 +1,4 @@ module.exports = { - plugins: [ - '@babel/plugin-proposal-class-properties', - '@babel/plugin-transform-modules-commonjs' - ], + plugins: ['@babel/plugin-proposal-class-properties'], presets: ['@babel/preset-env'] }; diff --git a/packages/fether-electron/package.json b/packages/fether-electron/package.json index ce70af7d5..15d2a5972 100644 --- a/packages/fether-electron/package.json +++ b/packages/fether-electron/package.json @@ -52,7 +52,6 @@ "devDependencies": { "@babel/cli": "^7.0.0-beta.49", "@babel/core": "^7.0.0-beta.49", - "@babel/plugin-transform-modules-commonjs": "^7.2.0", "@babel/preset-env": "^7.0.0-beta.49", "babel-jest": "^24.0.0", "copyfiles": "^2.0.0", From cc9ece9387835b3cd37f7cff512a518cee78b8b5 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Fri, 1 Feb 2019 13:50:17 +1100 Subject: [PATCH 089/153] refactor: Remove unnecessary use of extend library dependency and use Object.assign instead --- packages/fether-electron/src/main/app/options/index.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/fether-electron/src/main/app/options/index.js b/packages/fether-electron/src/main/app/options/index.js index 35742514e..1b2b49f26 100644 --- a/packages/fether-electron/src/main/app/options/index.js +++ b/packages/fether-electron/src/main/app/options/index.js @@ -3,8 +3,6 @@ // // SPDX-License-Identifier: BSD-3-Clause -import extend from 'extend'; - import { DEFAULT_OPTIONS, TASKBAR_OPTIONS } from './config'; let hasCalledInitFetherAppOptions = false; @@ -19,13 +17,13 @@ class FetherAppOptions { // Allow user to get/set options prior or to pass custom options this.options = withTaskbar - ? extend( + ? Object.assign( this.options, DEFAULT_OPTIONS, TASKBAR_OPTIONS, customOptions || {} ) - : extend(this.options, DEFAULT_OPTIONS, customOptions || {}); + : Object.assign(this.options, DEFAULT_OPTIONS, customOptions || {}); return this.options; }; From a246b80e4b99a948150fe7885f7e21a574ee7c03 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Fri, 1 Feb 2019 14:21:23 +1100 Subject: [PATCH 090/153] review-fix: Convert FetherApp options into function instead of class --- .../src/main/app/options/index.js | 37 ++----------------- packages/fether-electron/src/main/index.js | 5 +-- 2 files changed, 6 insertions(+), 36 deletions(-) diff --git a/packages/fether-electron/src/main/app/options/index.js b/packages/fether-electron/src/main/app/options/index.js index 1b2b49f26..dc0bee4e8 100644 --- a/packages/fether-electron/src/main/app/options/index.js +++ b/packages/fether-electron/src/main/app/options/index.js @@ -5,36 +5,7 @@ import { DEFAULT_OPTIONS, TASKBAR_OPTIONS } from './config'; -let hasCalledInitFetherAppOptions = false; - -class FetherAppOptions { - options = {}; - - create = (withTaskbar, customOptions) => { - if (hasCalledInitFetherAppOptions) { - throw new Error('Unable to initialise Fether app options more than once'); - } - - // Allow user to get/set options prior or to pass custom options - this.options = withTaskbar - ? Object.assign( - this.options, - DEFAULT_OPTIONS, - TASKBAR_OPTIONS, - customOptions || {} - ) - : Object.assign(this.options, DEFAULT_OPTIONS, customOptions || {}); - - return this.options; - }; - - get = opt => { - return this.options[opt]; - }; - - set = (opt, val) => { - this.options[opt] = val; - }; -} - -export default FetherAppOptions; +export default (withTaskbar, customOptions) => + withTaskbar + ? Object.assign({}, DEFAULT_OPTIONS, TASKBAR_OPTIONS, customOptions || {}) + : Object.assign({}, DEFAULT_OPTIONS, customOptions || {}); diff --git a/packages/fether-electron/src/main/index.js b/packages/fether-electron/src/main/index.js index 908097db5..311b93685 100644 --- a/packages/fether-electron/src/main/index.js +++ b/packages/fether-electron/src/main/index.js @@ -8,7 +8,7 @@ import electron from 'electron'; import Pino from './app/utils/pino'; import FetherApp from './app'; -import FetherAppOptions from './app/options'; +import fetherAppOptions from './app/options'; const { app } = electron; const pino = Pino(); @@ -26,8 +26,7 @@ if (process.platform === 'win32') { } const fetherAppInstance = new FetherApp(); -const fetherAppOptionsInstance = new FetherAppOptions(); -const options = fetherAppOptionsInstance.create(withTaskbar, {}); +const options = fetherAppOptions(withTaskbar, {}); app.on('ready', () => { fetherAppInstance.create(app, options); From 546e44dd58bc1cefb620f882790f886a95d29cf7 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Fri, 1 Feb 2019 14:22:14 +1100 Subject: [PATCH 091/153] fix: Do not show taskbar icon when run in TASKBAR=false mode --- packages/fether-electron/src/main/app/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/fether-electron/src/main/app/index.js b/packages/fether-electron/src/main/app/index.js index ec87d5ccc..17cb9ad87 100644 --- a/packages/fether-electron/src/main/app/index.js +++ b/packages/fether-electron/src/main/app/index.js @@ -51,11 +51,11 @@ class FetherApp { this.fetherApp.window.setProgressBar(0.4); this.createPositioner(); - this.createTray(); this.setupRequestListeners(); this.setupWindowListeners(); if (options.withTaskbar) { + this.createTray(); this.loadTaskbar(); } this.fetherApp.window.setProgressBar(0.6); @@ -578,7 +578,7 @@ class FetherApp { } else if (cachedBounds) { // Cached value will be used if showWindow is called without bounds data trayPos = cachedBounds; - } else if (tray.getBounds) { + } else if (tray && tray.getBounds) { // Get the current tray bounds trayPos = tray.getBounds(); } From 2dccca1f783c6722493f4bec6078444d9590cc96 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Fri, 1 Feb 2019 14:58:50 +1100 Subject: [PATCH 092/153] review-fix: Convert FetherApp class create method into constructor --- packages/fether-electron/src/main/app/index.js | 4 ++-- packages/fether-electron/src/main/index.js | 5 ++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/packages/fether-electron/src/main/app/index.js b/packages/fether-electron/src/main/app/index.js index 17cb9ad87..1846970d5 100644 --- a/packages/fether-electron/src/main/app/index.js +++ b/packages/fether-electron/src/main/app/index.js @@ -32,7 +32,7 @@ let hasCalledInitFetherApp = false; class FetherApp { fetherApp = new events.EventEmitter(); - create = (electronApp, options) => { + constructor (electronApp, options) { if (hasCalledInitFetherApp) { this.fetherApp.emit( 'error', @@ -69,7 +69,7 @@ class FetherApp { this.fetherApp.window.setProgressBar(-1); this.fetherApp.emit('after-create-app'); - }; + } // Enable with `DEBUG=true yarn start` and access Developer Tools debugSetup = () => { diff --git a/packages/fether-electron/src/main/index.js b/packages/fether-electron/src/main/index.js index 311b93685..45ba30ad5 100644 --- a/packages/fether-electron/src/main/index.js +++ b/packages/fether-electron/src/main/index.js @@ -25,11 +25,10 @@ if (process.platform === 'win32') { withTaskbar = false; } -const fetherAppInstance = new FetherApp(); const options = fetherAppOptions(withTaskbar, {}); app.on('ready', () => { - fetherAppInstance.create(app, options); + return new FetherApp(app, options); }); // Event triggered by clicking the Electron icon in the menu Dock @@ -47,7 +46,7 @@ app.on('activate', (event, hasVisibleWindows) => { return; } - fetherAppInstance.create(app, options); + return new FetherApp(app, options); }); app.on('window-all-closed', () => { From c04a3acccf59773911b5441e38723d5530b5134d Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Sat, 2 Feb 2019 10:29:48 +1100 Subject: [PATCH 093/153] refactor: Move FetherApp methods into methods folder --- README.md | 2 +- .../fether-electron/src/main/app/index.js | 783 ++---------------- .../app/methods/calculateWindowPosition.js | 43 + .../src/main/app/methods/createPositioner.js | 12 + .../src/main/app/methods/createTray.js | 16 + .../src/main/app/methods/createWindow.js | 40 + .../src/main/app/methods/fixWindowPosition.js | 56 ++ .../main/app/methods/getScreenResolution.js | 19 + .../src/main/app/methods/hideWindow.js | 18 + .../src/main/app/methods/index.js | 60 ++ .../src/main/app/methods/loadTray.js | 43 + .../src/main/app/methods/moveWindowUp.js | 42 + .../src/main/app/methods/onTrayClick.js | 24 + .../src/main/app/methods/onWindowClose.js | 11 + .../app/methods/processSaveWindowPosition.js | 75 ++ .../src/main/app/methods/setupAppListeners.js | 78 ++ .../src/main/app/methods/setupDebug.js | 15 + .../src/main/app/methods/setupGlobals.js | 14 + .../src/main/app/methods/setupLogger.js | 17 + .../src/main/app/methods/setupMenu.js | 17 + .../main/app/methods/setupParityEthereum.js | 14 + .../main/app/methods/setupRequestListeners.js | 37 + .../src/main/app/methods/setupSecurity.js | 11 + .../main/app/methods/setupWin32Listeners.js | 98 +++ .../main/app/methods/setupWindowListeners.js | 74 ++ .../src/main/app/methods/showTrayBalloon.js | 21 + .../src/main/app/methods/showWindow.js | 72 ++ .../src/main/app/methods/updateProgress.js | 19 + .../src/main/app/methods/windowClear.js | 19 + .../src/main/app/options/config/index.js | 2 +- .../src/main/app/utils/window.js | 6 +- .../src/main/app/utils/window.spec.js | 6 +- packages/fether-electron/src/main/index.js | 8 +- 33 files changed, 1059 insertions(+), 713 deletions(-) create mode 100644 packages/fether-electron/src/main/app/methods/calculateWindowPosition.js create mode 100644 packages/fether-electron/src/main/app/methods/createPositioner.js create mode 100644 packages/fether-electron/src/main/app/methods/createTray.js create mode 100644 packages/fether-electron/src/main/app/methods/createWindow.js create mode 100644 packages/fether-electron/src/main/app/methods/fixWindowPosition.js create mode 100644 packages/fether-electron/src/main/app/methods/getScreenResolution.js create mode 100644 packages/fether-electron/src/main/app/methods/hideWindow.js create mode 100644 packages/fether-electron/src/main/app/methods/index.js create mode 100644 packages/fether-electron/src/main/app/methods/loadTray.js create mode 100644 packages/fether-electron/src/main/app/methods/moveWindowUp.js create mode 100644 packages/fether-electron/src/main/app/methods/onTrayClick.js create mode 100644 packages/fether-electron/src/main/app/methods/onWindowClose.js create mode 100644 packages/fether-electron/src/main/app/methods/processSaveWindowPosition.js create mode 100644 packages/fether-electron/src/main/app/methods/setupAppListeners.js create mode 100644 packages/fether-electron/src/main/app/methods/setupDebug.js create mode 100644 packages/fether-electron/src/main/app/methods/setupGlobals.js create mode 100644 packages/fether-electron/src/main/app/methods/setupLogger.js create mode 100644 packages/fether-electron/src/main/app/methods/setupMenu.js create mode 100644 packages/fether-electron/src/main/app/methods/setupParityEthereum.js create mode 100644 packages/fether-electron/src/main/app/methods/setupRequestListeners.js create mode 100644 packages/fether-electron/src/main/app/methods/setupSecurity.js create mode 100644 packages/fether-electron/src/main/app/methods/setupWin32Listeners.js create mode 100644 packages/fether-electron/src/main/app/methods/setupWindowListeners.js create mode 100644 packages/fether-electron/src/main/app/methods/showTrayBalloon.js create mode 100644 packages/fether-electron/src/main/app/methods/showWindow.js create mode 100644 packages/fether-electron/src/main/app/methods/updateProgress.js create mode 100644 packages/fether-electron/src/main/app/methods/windowClear.js diff --git a/README.md b/README.md index 234b956cf..a83fb7449 100644 --- a/README.md +++ b/README.md @@ -117,7 +117,7 @@ yarn start > Developer Tools: Open developer tools automatically by running `DEBUG=true yarn start` when not in the production environment -# Run without taskbar +# Run without taskbar mode (no tray icon) ```bash TASKBAR=false yarn start diff --git a/packages/fether-electron/src/main/app/index.js b/packages/fether-electron/src/main/app/index.js index 1846970d5..8252f716b 100644 --- a/packages/fether-electron/src/main/app/index.js +++ b/packages/fether-electron/src/main/app/index.js @@ -3,29 +3,36 @@ // // SPDX-License-Identifier: BSD-3-Clause -import parityElectron from '@parity/electron'; -import electron, { screen, Tray } from 'electron'; -import Positioner from 'electron-positioner'; import events from 'events'; -import debounce from 'lodash/debounce'; -import { productName } from '../../../electron-builder.json'; -import Pino from './utils/pino'; -import { getScreenResolution, shouldFixWindowPosition } from './utils/window'; import { - getSavedWindowPosition, - hasSavedWindowPosition, - saveWindowPosition -} from './settings'; -import { addMenu } from './menu'; -import cli from './cli'; -import messages from './messages'; -import ParityEthereum from './parityEthereum'; - -const { BrowserWindow, ipcMain, session } = electron; -const pino = Pino(); - -const withDebug = process.env.DEBUG === 'true'; + setupAppListeners, + createWindow, + updateProgress, + createPositioner, + setupRequestListeners, + createTray, + loadTray, + showTrayBalloon, + setupDebug, + setupSecurity, + setupLogger, + setupParityEthereum, + setupGlobals, + setupMenu, + getScreenResolution, + calculateWindowPosition, + onTrayClick, + fixWindowPosition, + showWindow, + moveWindowUp, + processSaveWindowPosition, + setupWindowListeners, + setupWin32Listeners, + hideWindow, + windowClear, + onWindowClose +} from './methods'; let hasCalledInitFetherApp = false; @@ -42,688 +49,60 @@ class FetherApp { this.fetherApp.app = electronApp; this.fetherApp.options = options; - - this.setupAppListeners(); - - this.fetherApp.emit('create-app'); - - this.createWindow(); - this.fetherApp.window.setProgressBar(0.4); - - this.createPositioner(); - this.setupRequestListeners(); - this.setupWindowListeners(); - - if (options.withTaskbar) { - this.createTray(); - this.loadTaskbar(); - } - this.fetherApp.window.setProgressBar(0.6); - - this.debugSetup(); - this.finalise(); - this.fetherApp.window.setProgressBar(0.8); - - this.showWindow(undefined); - this.fetherApp.window.setProgressBar(1.0); - - this.fetherApp.window.setProgressBar(-1); - this.fetherApp.emit('after-create-app'); } - - // Enable with `DEBUG=true yarn start` and access Developer Tools - debugSetup = () => { - if (withDebug && this.fetherApp.options.webPreferences.devTools) { - this.fetherApp.window.webContents.openDevTools(); - } - }; - - createPositioner = () => { - this.fetherApp.positioner = new Positioner(this.fetherApp.window); - }; - - createTray = () => { - let { options } = this.fetherApp; - - this.fetherApp.tray = new Tray(options.icon); - }; - - showTrayBalloon = () => { - let { tray } = this.fetherApp; - - tray.displayBalloon({ - title: 'Fether Menu', - content: `Press ALT in the Fether window to toggle the menu` - }); - }; - - finalise = () => { - // Security to prevent window contents from being captured by other apps - this.fetherApp.window.setContentProtection(true); - - // Set options for @parity/electron - parityElectron({ - logger: namespace => log => Pino({ name: namespace }).info(log) - }); - - // Download, install, and run Parity Ethereum if not running and requested - const parityEthereumInstance = new ParityEthereum(); - parityEthereumInstance.setup(this.fetherApp.window); - - // Globals for fether-react parityStore - global.wsInterface = cli.wsInterface; - global.wsPort = cli.wsPort; - - // Add application menu - addMenu(this.fetherApp.window); - pino.info('Finished configuring Electron menu'); - }; - - setupRequestListeners = () => { - // Listen to messages from renderer process - ipcMain.on('asynchronous-message', (...args) => { - return messages(this.fetherApp.window, ...args); - }); - - // WS calls have Origin `file://` by default, which is not trusted. - // We override Origin header on all WS connections with an authorized one. - session.defaultSession.webRequest.onBeforeSendHeaders( - { - urls: ['ws://*/*', 'wss://*/*'] - }, - (details, callback) => { - if (!this.fetherApp.window) { - // There might be a split second where the user closes the app, so - // this.fether.window is null, but there is still a network request done. - return; - } - details.requestHeaders.Origin = `parity://${ - this.fetherApp.window.id - }.ui.parity`; - callback({ requestHeaders: details.requestHeaders }); // eslint-disable-line - } - ); - }; - - setupWindowListeners = () => { - // Open external links in browser - this.fetherApp.window.webContents.on('new-window', (event, url) => { - event.preventDefault(); - electron.shell.openExternal(url); - }); - - // Linux (unchecked on others) - this.fetherApp.window.on('move', () => { - /** - * On Linux using this with debouncing is the closest equivalent - * to using 'moved' (not supported on Linux) with debouncing - */ - debounce(() => { - this.saveWindowPosition(); - }, 1000); - }); - - // macOS (not Windows or Linux) - this.fetherApp.window.on('moved', () => { - /** - * On macOS save the position in the 'moved' event since if - * we run it just in 'close' instead, then if the Fether app - * crashes after they've moved the Fether window then it won't run - * 'close' and it won't save the window position. - * - * On Windows we use the equivalent WM_EXITSIZEMOVE that detects - * the equivalent of 'moved' - * - * On Linux the closest equivalent to achieving 'moved' is debouncing - * on the 'move' event. It also works in 'close' even when app crashes - */ - this.saveWindowPosition(); - }); - - // macOS and Linux (not Windows) - this.fetherApp.window.on('resize', () => { - pino.info('Detected resize event'); - this.moveWindowUp(); - setTimeout(() => { - this.moveWindowUp(); - }, 5000); - }); - - this.fetherApp.window.on('blur', () => { - this.fetherApp.options.alwaysOnTop ? this.emitBlur() : this.hideWindow(); - }); - - this.fetherApp.window.on('close', () => { - this.onClose(); - }); - - this.fetherApp.window.on('closed', () => { - this.fetherApp.window = null; - - this.fetherApp.emit('after-closed-window'); - }); - - this.addWin32Listeners(); - }; - - addWin32Listeners = () => { - if (process.platform === 'win32') { - /** - * Hook WM_SYSKEYUP - * - * Open the Fether Electron menu when the Fether window is active - * and the user enters a keyboard combination of both the ALT and 'm' keys - * - * Reference: https://docs.microsoft.com/en-gb/windows/desktop/inputdev/wm-syskeyup - */ - this.fetherApp.window.hookWindowMessage( - Number.parseInt('0x0105'), - (wParam, lParam) => { - // Reference: https://nodejs.org/api/buffer.html - /** - * Detect when user presses ALT+keyCode. - * i.e. Use `wParam && wParam.readUInt32LE(0) === 77` to detect ALT+m - */ - if (wParam) { - this.showTrayBalloon(); - } - } - ); - - /** - * Hook WM_SYSCOMMAND - * - * Detect events on Windows - * - * Credit: http://robmayhew.com/listening-for-events-from-windows-in-electron-tutorial/ - */ - this.fetherApp.window.hookWindowMessage( - Number.parseInt('0x0112'), - (wParam, lParam) => { - let eventName = null; - - if (wParam.readUInt32LE(0) === 0xf060) { - // SC_CLOSE - eventName = 'close'; - this.onClose(); - } else if (wParam.readUInt32LE(0) === 0xf030) { - // SC_MAXIMIZE - eventName = 'maximize'; - this.showTrayBalloon(); - } else if (wParam.readUInt32LE(0) === 0xf020) { - // SC_MINIMIZE - eventName = 'minimize'; - this.saveWindowPosition(); - } else if (wParam.readUInt32LE(0) === 0xf120) { - // SC_RESTORE - eventName = 'restored'; - this.showTrayBalloon(); - } - - if (eventName !== null) { - pino.info('Detected event:', eventName); - } - } - ); - - /** - * Hook WM_EXITSIZEMOVE - * - * Detect event on Windows when Fether window was moved - * or resized - */ - this.fetherApp.window.hookWindowMessage( - Number.parseInt('0x0232'), - (wParam, lParam) => { - pino.info('Detected completion of move or resize event'); - - // Move Fether window back up into view if it was a resize event - // that causes the bottom to be cropped - this.moveWindowUp(); - - // Try again after a delay incase Fether window resize occurs - // x seconds after navigating to a new page. - setTimeout(() => { - this.moveWindowUp(); - }, 5000); - - // Save Fether window position to Electron settings - this.saveWindowPosition(); - } - ); - } - }; - - /** - * If the Fether window is restored on a page with a small window height - * and the window is positioned close to the bottom of the screen, then - * we do not want it to crop the bottom of the window when the user navigates - * to a page with a larger window height. So if the user navigates to a page - * with a larger window height that causes it to be cropped, then we will - * automatically move the window upward so it is viewable to the user - */ - moveWindowUp = () => { - if (!this.fetherApp.window) { - return; - } - - pino.info('Fether window resized. Moving it back up into view if required'); - - const position = this.fetherApp.window.getPosition(); - const positionStruct = { - x: position[0], - y: position[1] - }; - const trayDepth = this.fetherApp.trayDepth || 40; // Default incase resizes on load - const currentScreenResolution = this.getScreenResolution(); - const windowHeight = this.fetherApp.window.getSize()[1]; - const maxWindowY = currentScreenResolution.y - windowHeight - trayDepth; - const adjustY = positionStruct.y - maxWindowY; - - if (adjustY > 0) { - this.fetherApp.emit('moved-window-up-into-view'); - this.fetherApp.window.setPosition(positionStruct.x, maxWindowY); - } - }; - - saveWindowPosition = () => { - if (!this.fetherApp.window) { - return; - } - - const { previousScreenResolution } = this.fetherApp; - const currentScreenResolution = this.getScreenResolution(); - - this.fetherApp.previousScreenResolution = getScreenResolution( - previousScreenResolution, - currentScreenResolution - ); - - // Get the latest position. The window may have been moved to a different - // screen with smaller resolution. We must move it to prevent cropping. - const position = this.fetherApp.window.getPosition(); - - const positionStruct = { - x: position[0], - y: position[1] - }; - - const fixedWindowPosition = this.fixWindowPosition(positionStruct); - - const newFixedPosition = { - x: fixedWindowPosition.x || positionStruct.x, - y: fixedWindowPosition.y || positionStruct.y - }; - - /** - * Only move it immediately back into the threshold of screen tray bounds - * if the screen resolution reduced to prevent it from being cropped. - * Do not call this all the time otherwise it will crash with - * a call stack exceeded if the user keeps trying to move it outside the screen bounds - * and it would also prevent the user from moving it to a different screen at all. - */ - if ( - shouldFixWindowPosition(previousScreenResolution, currentScreenResolution) - ) { - // Move window to the fixed x-coordinate position if that required fixing - if (fixedWindowPosition.x) { - this.fetherApp.window.setPosition( - fixedWindowPosition.x, - positionStruct.y, - true - ); - } - - // Move window to the fixed y-coordinate position if that required fixing - if (fixedWindowPosition.y) { - this.fetherApp.window.setPosition( - positionStruct.x, - fixedWindowPosition.y, - true - ); - } - } - - saveWindowPosition(newFixedPosition || positionStruct); - - this.fetherApp.emit('after-moved-window-position-saved'); - }; - - loadTaskbar = () => { - const { app, options, tray } = this.fetherApp; - - this.fetherApp.emit('load-taskbar'); - - if (app.dock && !options.showDockIcon) { - app.dock.hide(); - } - - const defaultClickEvent = options.showOnRightClick - ? 'right-click' - : 'click'; - - // Note: See https://github.com/RocketChat/Rocket.Chat.Electron/issues/44 - if (process.platform === 'win32') { - this.showTrayBalloon(); - } - - tray.on(defaultClickEvent, this.clickedTray); - tray.on('double-click', this.clickedTray); - // Right click event handler does not work on Windows as intended - tray.on('right-click', () => { - if (process.platform === 'win32') { - pino.info('Detected right click on Windows'); - this.showTrayBalloon(); - } - }); - tray.setToolTip(options.tooltip); - tray.setHighlightMode('never'); - }; - - createWindow = () => { - const { options } = this.fetherApp; - - this.fetherApp.emit('create-window'); - - this.fetherApp.window = new BrowserWindow(options); - - if (options.showOnAllWorkspaces !== false) { - this.fetherApp.window.setVisibleOnAllWorkspaces(true); - } - - if (process.platform !== 'darwin') { - /** - * Toggle the Fether menu bar in the frame on Windows. Note that - * if not shown by default then when it is shown it causes cropping of the bottom - * of the window when menu open/close toggled. The user will need to be informed - * that pressing ALT displays the Fether menu - */ - this.fetherApp.window.setAutoHideMenuBar(true); // ALT shows menu bar - this.fetherApp.window.setMenuBarVisibility(false); - } - - // Opens file:///path/to/build/index.html in prod mode, or whatever is - // passed to ELECTRON_START_URL - this.fetherApp.window.loadURL(options.index); - - this.fetherApp.emit('after-create-window'); - }; - - showWindow = trayPos => { - if (!this.fetherApp.window) { - this.createWindow(); - } - - this.fetherApp.emit('show-window'); - - const calculatedWindowPosition = this.calculateWindowPosition(trayPos); - - pino.info('Calculated window position: ', calculatedWindowPosition); - - const mainScreen = screen.getPrimaryDisplay(); - // const allScreens = screen.getAllDisplays(); - const mainScreenDimensions = mainScreen.size; - const mainScreenWorkAreaSize = mainScreen.workAreaSize; - - // workAreaSize does not include the taskbar depth - this.fetherApp.trayDepth = Math.max( - mainScreenDimensions.width - mainScreenWorkAreaSize.width, - mainScreenDimensions.height - mainScreenWorkAreaSize.height - ); - - pino.info( - 'Previously saved window position exists: ', - hasSavedWindowPosition() - ); - - const loadedWindowPosition = hasSavedWindowPosition() - ? getSavedWindowPosition() - : undefined; - - pino.info('Loaded window position: ', loadedWindowPosition); - - const fixedWindowPosition = this.fixWindowPosition(loadedWindowPosition); - - pino.info('Fixed window position: ', fixedWindowPosition); - - /** - * Since the user may change the taskbar tray to be on any side of the screen. - * If the user moved the window out of where the tray would be in the screen resolution bounds. - * Restore the window so it is fully visible adjacent to where the tray would be. - */ - const x = - (fixedWindowPosition && fixedWindowPosition.x) || - (loadedWindowPosition && loadedWindowPosition.x) || - calculatedWindowPosition.x; - - const y = - (fixedWindowPosition && fixedWindowPosition.y) || - (loadedWindowPosition && loadedWindowPosition.y) || - calculatedWindowPosition.y; - - this.fetherApp.window.setPosition(x, y); - this.fetherApp.window.show(); - - this.fetherApp.emit('after-show-window'); - }; - - hideWindow = () => { - if (!this.fetherApp.window) { - return; - } - - this.saveWindowPosition(); // Save window position when hide, particularly necessary on Linux - - this.fetherApp.emit('hide-window'); - this.fetherApp.window.hide(); - this.fetherApp.emit('after-hide-window'); - }; - - /** - * Proposes a fixed window position that may be used if the window is moved - * out of the screen bounds threshold. If the window is moved across to a - * second monitor (without screen mirroring) then if the screen is hidden - * and then shown again (by pressing the Fether tray icon), since the - * coordinates of the window are outside the screen bounds the window - * will be restored into the users primary screen. - */ - fixWindowPosition = proposedWindowPosition => { - const { trayDepth } = this.fetherApp; - - if (!proposedWindowPosition) { - return; - } - - const newPosition = { - x: undefined, - y: undefined - }; - - const currentScreenResolution = this.getScreenResolution(); - - const windowWidth = this.fetherApp.window.getSize()[0]; - const windowHeight = this.fetherApp.window.getSize()[1]; - - if (proposedWindowPosition.x < trayDepth) { - newPosition.x = trayDepth; - } - - if (proposedWindowPosition.y < trayDepth) { - newPosition.y = trayDepth; - } - - if ( - proposedWindowPosition.x >= - currentScreenResolution.x - windowWidth - trayDepth - ) { - newPosition.x = currentScreenResolution.x - windowWidth - trayDepth; - } - - if ( - proposedWindowPosition.y >= - currentScreenResolution.y - windowHeight - trayDepth - ) { - newPosition.y = currentScreenResolution.y - windowHeight - trayDepth; - } - - return newPosition; - }; - - calculateWindowPosition = trayPos => { - const { cachedBounds, options, positioner, tray } = this.fetherApp; - - if (trayPos && trayPos.x !== 0) { - // Cache the bounds - this.fetherApp.cachedBounds = trayPos; - } else if (cachedBounds) { - // Cached value will be used if showWindow is called without bounds data - trayPos = cachedBounds; - } else if (tray && tray.getBounds) { - // Get the current tray bounds - trayPos = tray.getBounds(); - } - - // Default the window to the right if `trayPos` bounds are undefined or null. - let noBoundsPosition = null; - - if ( - (trayPos === undefined || (trayPos && trayPos.x === 0)) && - options.windowPosition && - options.windowPosition.substr(0, 4) === 'tray' - ) { - noBoundsPosition = - process.platform === 'win32' ? 'bottomRight' : 'topRight'; - } - - const position = positioner.calculate( - noBoundsPosition || options.windowPosition, - trayPos - ); - - return { - x: options.x ? options.x : position.x, - y: options.y ? options.y : position.y - }; - }; - - // https://ourcodeworld.com/articles/read/285/how-to-get-the-screen-width-and-height-in-electron-framework - getScreenResolution = () => { - const mainScreen = screen.getPrimaryDisplay(); - const mainScreenDimensions = mainScreen.size; - - return { - x: mainScreenDimensions.width, - y: mainScreenDimensions.height - }; - }; - - windowClear = () => { - if (this.fetherApp.window) { - // Remove relevant events when window object deleted - const events = ['close', 'move', 'moved', 'resize']; - for (let event in events) { - this.fetherApp.window.removeAllListeners(event); - } - delete this.fetherApp.window; - } - - this.fetherApp.emit('after-close-window'); - }; - - emitBlur = () => { - this.fetherApp.emit('blur-window'); - }; - - onClose = () => { - this.saveWindowPosition(); - this.windowClear(); - }; - - clickedTray = (e, bounds) => { - const { cachedBounds, window } = this.fetherApp; - - if ( - e.altKey || - e.shiftKey || - e.ctrlKey || - e.metaKey || - (window && window.isVisible()) - ) { - return this.hideWindow(); - } - - // cachedBounds are needed for double-clicked event - this.fetherApp.cachedBounds = bounds || cachedBounds; - this.showWindow(this.fetherApp.cachedBounds); - }; - - setupAppListeners = () => { - this.fetherApp.on('create-app', () => { - pino.info( - `Starting ${productName} (${ - this.fetherApp.options.withTaskbar ? 'with' : 'without' - } taskbar)...` - ); - }); - - this.fetherApp.on('create-window', () => { - pino.info('Creating window'); - }); - - this.fetherApp.on('after-create-window', () => { - pino.info('Finished creating window'); - }); - - this.fetherApp.on('load-taskbar', () => { - pino.info('Configuring taskbar for the window'); - }); - - this.fetherApp.on('show-window', () => { - pino.info('Showing window'); - }); - - this.fetherApp.on('after-show-window', () => { - pino.info('Finished showing window'); - }); - - this.fetherApp.on('after-create-app', () => { - pino.info(`Ready to use ${productName}`); - }); - - this.fetherApp.on('hide-window', () => { - pino.info('Hiding window on blur since not on top'); - }); - - this.fetherApp.on('after-hide-window', () => { - pino.info('Finished hiding window'); - }); - - this.fetherApp.on('blur-window', () => { - pino.info('Blur window since lost focus when on top'); - }); - - this.fetherApp.on('after-moved-window-position-saved', () => { - const position = getSavedWindowPosition(); - - pino.info( - `Saved window position to (x: ${position.x}, y: ${ - position.y - }) after move` - ); - }); - - this.fetherApp.on('moved-window-up-into-view', () => { - pino.info('Moved window up into view'); - }); - - this.fetherApp.on('after-close-window', () => { - pino.info('Deleted window upon close'); - }); - - this.fetherApp.on('error', error => { - console.error(error); - }); - }; } -export default FetherApp; +FetherApp.prototype.setupAppListeners = setupAppListeners; +FetherApp.prototype.createWindow = createWindow; +FetherApp.prototype.updateProgress = updateProgress; +FetherApp.prototype.createPositioner = createPositioner; +FetherApp.prototype.setupRequestListeners = setupRequestListeners; +FetherApp.prototype.createTray = createTray; +FetherApp.prototype.loadTray = loadTray; +FetherApp.prototype.showTrayBalloon = showTrayBalloon; +FetherApp.prototype.setupDebug = setupDebug; +FetherApp.prototype.setupSecurity = setupSecurity; +FetherApp.prototype.setupLogger = setupLogger; +FetherApp.prototype.setupParityEthereum = setupParityEthereum; +FetherApp.prototype.setupGlobals = setupGlobals; +FetherApp.prototype.setupMenu = setupMenu; +FetherApp.prototype.getScreenResolution = getScreenResolution; +FetherApp.prototype.calculateWindowPosition = calculateWindowPosition; +FetherApp.prototype.onTrayClick = onTrayClick; +FetherApp.prototype.fixWindowPosition = fixWindowPosition; +FetherApp.prototype.showWindow = showWindow; +FetherApp.prototype.moveWindowUp = moveWindowUp; +FetherApp.prototype.processSaveWindowPosition = processSaveWindowPosition; +FetherApp.prototype.setupWindowListeners = setupWindowListeners; +FetherApp.prototype.setupWin32Listeners = setupWin32Listeners; +FetherApp.prototype.hideWindow = hideWindow; +FetherApp.prototype.windowClear = windowClear; +FetherApp.prototype.onWindowClose = onWindowClose; + +const createFetherApp = (app, options) => { + const fetherApp = new FetherApp(app, options); + + // Context of fetherApp passed to each method + fetherApp.setupAppListeners.apply(fetherApp); + fetherApp.createWindow.apply(fetherApp); + fetherApp.updateProgress.apply(fetherApp, [0.4]); // eslint-disable-line + fetherApp.createPositioner.apply(fetherApp); + fetherApp.setupRequestListeners.apply(fetherApp); + fetherApp.createTray.apply(fetherApp); + fetherApp.updateProgress.apply(fetherApp, [0.6]); // eslint-disable-line + fetherApp.loadTray.apply(fetherApp); + fetherApp.setupDebug.apply(fetherApp); + fetherApp.setupSecurity.apply(fetherApp); + fetherApp.setupLogger.apply(fetherApp); + fetherApp.setupParityEthereum.apply(fetherApp); + fetherApp.setupGlobals.apply(fetherApp); + fetherApp.setupMenu.apply(fetherApp); + fetherApp.updateProgress.apply(fetherApp, [0.8]); // eslint-disable-line + fetherApp.showWindow.apply(fetherApp, undefined); + fetherApp.updateProgress.apply(fetherApp, [1.0]); // eslint-disable-line + fetherApp.setupWindowListeners.apply(fetherApp); + fetherApp.setupWin32Listeners.apply(fetherApp); + fetherApp.updateProgress.apply(fetherApp, [-1, "after-create-app"]); // eslint-disable-line +}; + +export default createFetherApp; diff --git a/packages/fether-electron/src/main/app/methods/calculateWindowPosition.js b/packages/fether-electron/src/main/app/methods/calculateWindowPosition.js new file mode 100644 index 000000000..7c212db9f --- /dev/null +++ b/packages/fether-electron/src/main/app/methods/calculateWindowPosition.js @@ -0,0 +1,43 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. +// +// SPDX-License-Identifier: BSD-3-Clause + +function calculateWindowPosition (trayPos) { + const { cachedBounds, options, positioner, tray } = this.fetherApp; + + if (trayPos && trayPos.x !== 0) { + // Cache the bounds + this.fetherApp.cachedBounds = trayPos; + } else if (cachedBounds) { + // Cached value will be used if showWindow is called without bounds data + trayPos = cachedBounds; + } else if (tray && tray.getBounds) { + // Get the current tray bounds + trayPos = tray.getBounds(); + } + + // Default the window to the right if `trayPos` bounds are undefined or null. + let noBoundsPosition = null; + + if ( + (trayPos === undefined || (trayPos && trayPos.x === 0)) && + options.windowPosition && + options.windowPosition.substr(0, 4) === 'tray' + ) { + noBoundsPosition = + process.platform === 'win32' ? 'bottomRight' : 'topRight'; + } + + const position = positioner.calculate( + noBoundsPosition || options.windowPosition, + trayPos + ); + + return { + x: options.x ? options.x : position.x, + y: options.y ? options.y : position.y + }; +} + +export default calculateWindowPosition; diff --git a/packages/fether-electron/src/main/app/methods/createPositioner.js b/packages/fether-electron/src/main/app/methods/createPositioner.js new file mode 100644 index 000000000..6478472cc --- /dev/null +++ b/packages/fether-electron/src/main/app/methods/createPositioner.js @@ -0,0 +1,12 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. +// +// SPDX-License-Identifier: BSD-3-Clause + +import Positioner from 'electron-positioner'; + +function createPositioner () { + this.fetherApp.positioner = new Positioner(this.fetherApp.window); +} + +export default createPositioner; diff --git a/packages/fether-electron/src/main/app/methods/createTray.js b/packages/fether-electron/src/main/app/methods/createTray.js new file mode 100644 index 000000000..797c2ede6 --- /dev/null +++ b/packages/fether-electron/src/main/app/methods/createTray.js @@ -0,0 +1,16 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. +// +// SPDX-License-Identifier: BSD-3-Clause + +import { Tray } from 'electron'; + +function createTray () { + let { options } = this.fetherApp; + + if (options.withTaskbar) { + this.fetherApp.tray = new Tray(options.icon); + } +} + +export default createTray; diff --git a/packages/fether-electron/src/main/app/methods/createWindow.js b/packages/fether-electron/src/main/app/methods/createWindow.js new file mode 100644 index 000000000..fc6bbd0ea --- /dev/null +++ b/packages/fether-electron/src/main/app/methods/createWindow.js @@ -0,0 +1,40 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. +// +// SPDX-License-Identifier: BSD-3-Clause + +import electron from 'electron'; + +const { BrowserWindow } = electron; + +function createWindow () { + const { options } = this.fetherApp; + + this.fetherApp.emit('create-app'); + this.fetherApp.emit('create-window'); + + this.fetherApp.window = new BrowserWindow(options); + + if (options.showOnAllWorkspaces !== false) { + this.fetherApp.window.setVisibleOnAllWorkspaces(true); + } + + if (process.platform !== 'darwin') { + /** + * Toggle the Fether menu bar in the frame on Windows. Note that + * if not shown by default then when it is shown it causes cropping of the bottom + * of the window when menu open/close toggled. The user will need to be informed + * that pressing ALT displays the Fether menu + */ + this.fetherApp.window.setAutoHideMenuBar(true); // ALT shows menu bar + this.fetherApp.window.setMenuBarVisibility(false); + } + + // Opens file:///path/to/build/index.html in prod mode, or whatever is + // passed to ELECTRON_START_URL + this.fetherApp.window.loadURL(options.index); + + this.fetherApp.emit('after-create-window'); +} + +export default createWindow; diff --git a/packages/fether-electron/src/main/app/methods/fixWindowPosition.js b/packages/fether-electron/src/main/app/methods/fixWindowPosition.js new file mode 100644 index 000000000..230038790 --- /dev/null +++ b/packages/fether-electron/src/main/app/methods/fixWindowPosition.js @@ -0,0 +1,56 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. +// +// SPDX-License-Identifier: BSD-3-Clause + +/** + * Proposes a fixed window position that may be used if the window is moved + * out of the screen bounds threshold. If the window is moved across to a + * second monitor (without screen mirroring) then if the screen is hidden + * and then shown again (by pressing the Fether tray icon), since the + * coordinates of the window are outside the screen bounds the window + * will be restored into the users primary screen. + */ +function fixWindowPosition (proposedWindowPosition) { + const { trayDepth } = this.fetherApp; + + if (!proposedWindowPosition) { + return; + } + + const newPosition = { + x: undefined, + y: undefined + }; + + const currentScreenResolution = this.getScreenResolution(); + + const windowWidth = this.fetherApp.window.getSize()[0]; + const windowHeight = this.fetherApp.window.getSize()[1]; + + if (proposedWindowPosition.x < trayDepth) { + newPosition.x = trayDepth; + } + + if (proposedWindowPosition.y < trayDepth) { + newPosition.y = trayDepth; + } + + if ( + proposedWindowPosition.x >= + currentScreenResolution.x - windowWidth - trayDepth + ) { + newPosition.x = currentScreenResolution.x - windowWidth - trayDepth; + } + + if ( + proposedWindowPosition.y >= + currentScreenResolution.y - windowHeight - trayDepth + ) { + newPosition.y = currentScreenResolution.y - windowHeight - trayDepth; + } + + return newPosition; +} + +export default fixWindowPosition; diff --git a/packages/fether-electron/src/main/app/methods/getScreenResolution.js b/packages/fether-electron/src/main/app/methods/getScreenResolution.js new file mode 100644 index 000000000..50618eb87 --- /dev/null +++ b/packages/fether-electron/src/main/app/methods/getScreenResolution.js @@ -0,0 +1,19 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. +// +// SPDX-License-Identifier: BSD-3-Clause + +import { screen } from 'electron'; + +// https://ourcodeworld.com/articles/read/285/how-to-get-the-screen-width-and-height-in-electron-framework +function getScreenResolution () { + const mainScreen = screen.getPrimaryDisplay(); + const mainScreenDimensions = mainScreen.size; + + return { + x: mainScreenDimensions.width, + y: mainScreenDimensions.height + }; +} + +export default getScreenResolution; diff --git a/packages/fether-electron/src/main/app/methods/hideWindow.js b/packages/fether-electron/src/main/app/methods/hideWindow.js new file mode 100644 index 000000000..b794b50e1 --- /dev/null +++ b/packages/fether-electron/src/main/app/methods/hideWindow.js @@ -0,0 +1,18 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. +// +// SPDX-License-Identifier: BSD-3-Clause + +function hideWindow () { + if (!this.fetherApp.window) { + return; + } + + this.processSaveWindowPosition(); // Save window position when hide, particularly necessary on Linux + + this.fetherApp.emit('hide-window'); + this.fetherApp.window.hide(); + this.fetherApp.emit('after-hide-window'); +} + +export default hideWindow; diff --git a/packages/fether-electron/src/main/app/methods/index.js b/packages/fether-electron/src/main/app/methods/index.js new file mode 100644 index 000000000..c0ddfb011 --- /dev/null +++ b/packages/fether-electron/src/main/app/methods/index.js @@ -0,0 +1,60 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. +// +// SPDX-License-Identifier: BSD-3-Clause + +import setupAppListeners from './setupAppListeners'; +import createWindow from './createWindow'; +import updateProgress from './updateProgress'; +import createPositioner from './createPositioner'; +import setupRequestListeners from './setupRequestListeners'; +import createTray from './createTray'; +import loadTray from './loadTray'; +import showTrayBalloon from './showTrayBalloon'; +import setupDebug from './setupDebug'; +import setupSecurity from './setupSecurity'; +import setupLogger from './setupLogger'; +import setupParityEthereum from './setupParityEthereum'; +import setupGlobals from './setupGlobals'; +import setupMenu from './setupMenu'; +import getScreenResolution from './getScreenResolution'; +import calculateWindowPosition from './calculateWindowPosition'; +import onTrayClick from './onTrayClick'; +import fixWindowPosition from './fixWindowPosition'; +import showWindow from './showWindow'; +import moveWindowUp from './moveWindowUp'; +import processSaveWindowPosition from './processSaveWindowPosition'; +import setupWindowListeners from './setupWindowListeners'; +import setupWin32Listeners from './setupWin32Listeners'; +import hideWindow from './hideWindow'; +import windowClear from './windowClear'; +import onWindowClose from './onWindowClose'; + +export { + setupAppListeners, + createWindow, + updateProgress, + createPositioner, + setupRequestListeners, + createTray, + loadTray, + showTrayBalloon, + setupDebug, + setupSecurity, + setupLogger, + setupParityEthereum, + setupGlobals, + setupMenu, + getScreenResolution, + calculateWindowPosition, + onTrayClick, + fixWindowPosition, + showWindow, + moveWindowUp, + processSaveWindowPosition, + setupWindowListeners, + setupWin32Listeners, + hideWindow, + windowClear, + onWindowClose +}; diff --git a/packages/fether-electron/src/main/app/methods/loadTray.js b/packages/fether-electron/src/main/app/methods/loadTray.js new file mode 100644 index 000000000..4819ae7e3 --- /dev/null +++ b/packages/fether-electron/src/main/app/methods/loadTray.js @@ -0,0 +1,43 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. +// +// SPDX-License-Identifier: BSD-3-Clause + +import Pino from '../utils/pino'; + +const pino = Pino(); + +function loadTray () { + const { app, options, tray } = this.fetherApp; + + if (options.withTaskbar) { + this.fetherApp.emit('load-tray'); + + if (app.dock && !options.showDockIcon) { + app.dock.hide(); + } + + const defaultClickEvent = options.showOnRightClick + ? 'right-click' + : 'click'; + + // Note: See https://github.com/RocketChat/Rocket.Chat.Electron/issues/44 + if (process.platform === 'win32') { + this.showTrayBalloon(); + } + + tray.on(defaultClickEvent, () => this.onTrayClick(this.fetherApp)); + tray.on('double-click', () => this.onTrayClick(this.fetherApp)); + // Right click event handler does not work on Windows as intended + tray.on('right-click', () => { + if (process.platform === 'win32') { + pino.info('Detected right click on Windows'); + this.showTrayBalloon(); + } + }); + tray.setToolTip(options.tooltip); + tray.setHighlightMode('never'); + } +} + +export default loadTray; diff --git a/packages/fether-electron/src/main/app/methods/moveWindowUp.js b/packages/fether-electron/src/main/app/methods/moveWindowUp.js new file mode 100644 index 000000000..0419275d1 --- /dev/null +++ b/packages/fether-electron/src/main/app/methods/moveWindowUp.js @@ -0,0 +1,42 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. +// +// SPDX-License-Identifier: BSD-3-Clause + +import Pino from '../utils/pino'; + +const pino = Pino(); + +/** + * If the Fether window is restored on a page with a small window height + * and the window is positioned close to the bottom of the screen, then + * we do not want it to crop the bottom of the window when the user navigates + * to a page with a larger window height. So if the user navigates to a page + * with a larger window height that causes it to be cropped, then we will + * automatically move the window upward so it is viewable to the user + */ +function moveWindowUp () { + if (!this.fetherApp.window) { + return; + } + + pino.info('Fether window resized. Moving it back up into view if required'); + + const position = this.fetherApp.window.getPosition(); + const positionStruct = { + x: position[0], + y: position[1] + }; + const trayDepth = this.fetherApp.trayDepth || 40; // Default incase resizes on load + const currentScreenResolution = this.getScreenResolution(); + const windowHeight = this.fetherApp.window.getSize()[1]; + const maxWindowY = currentScreenResolution.y - windowHeight - trayDepth; + const adjustY = positionStruct.y - maxWindowY; + + if (adjustY > 0) { + this.fetherApp.emit('moved-window-up-into-view'); + this.fetherApp.window.setPosition(positionStruct.x, maxWindowY); + } +} + +export default moveWindowUp; diff --git a/packages/fether-electron/src/main/app/methods/onTrayClick.js b/packages/fether-electron/src/main/app/methods/onTrayClick.js new file mode 100644 index 000000000..a1fd8f0e7 --- /dev/null +++ b/packages/fether-electron/src/main/app/methods/onTrayClick.js @@ -0,0 +1,24 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. +// +// SPDX-License-Identifier: BSD-3-Clause + +function onTrayClick (e, bounds) { + const { cachedBounds, window } = this.fetherApp; + + if ( + e.altKey || + e.shiftKey || + e.ctrlKey || + e.metaKey || + (window && window.isVisible()) + ) { + return this.hideWindow(); + } + + // cachedBounds are needed for double-clicked event + this.fetherApp.cachedBounds = bounds || cachedBounds; + this.showWindow(this.fetherApp.cachedBounds); +} + +export default onTrayClick; diff --git a/packages/fether-electron/src/main/app/methods/onWindowClose.js b/packages/fether-electron/src/main/app/methods/onWindowClose.js new file mode 100644 index 000000000..2d7798573 --- /dev/null +++ b/packages/fether-electron/src/main/app/methods/onWindowClose.js @@ -0,0 +1,11 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. +// +// SPDX-License-Identifier: BSD-3-Clause + +function onWindowClose () { + this.processSaveWindowPosition(); + this.windowClear(); +} + +export default onWindowClose; diff --git a/packages/fether-electron/src/main/app/methods/processSaveWindowPosition.js b/packages/fether-electron/src/main/app/methods/processSaveWindowPosition.js new file mode 100644 index 000000000..cd3a03bf9 --- /dev/null +++ b/packages/fether-electron/src/main/app/methods/processSaveWindowPosition.js @@ -0,0 +1,75 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. +// +// SPDX-License-Identifier: BSD-3-Clause + +import { + getChangedScreenResolution, + shouldFixWindowPosition +} from '../utils/window'; +import { saveWindowPosition } from '../settings'; + +function processSaveWindowPosition () { + if (!this.fetherApp.window) { + return; + } + + const { previousScreenResolution } = this.fetherApp; + const currentScreenResolution = this.getScreenResolution(); + + this.fetherApp.previousScreenResolution = getChangedScreenResolution( + previousScreenResolution, + currentScreenResolution + ); + + // Get the latest position. The window may have been moved to a different + // screen with smaller resolution. We must move it to prevent cropping. + const position = this.fetherApp.window.getPosition(); + + const positionStruct = { + x: position[0], + y: position[1] + }; + + const fixedWindowPosition = this.fixWindowPosition(positionStruct); + + const newFixedPosition = { + x: fixedWindowPosition.x || positionStruct.x, + y: fixedWindowPosition.y || positionStruct.y + }; + + /** + * Only move it immediately back into the threshold of screen tray bounds + * if the screen resolution reduced to prevent it from being cropped. + * Do not call this all the time otherwise it will crash with + * a call stack exceeded if the user keeps trying to move it outside the screen bounds + * and it would also prevent the user from moving it to a different screen at all. + */ + if ( + shouldFixWindowPosition(previousScreenResolution, currentScreenResolution) + ) { + // Move window to the fixed x-coordinate position if that required fixing + if (fixedWindowPosition.x) { + this.fetherApp.window.setPosition( + fixedWindowPosition.x, + positionStruct.y, + true + ); + } + + // Move window to the fixed y-coordinate position if that required fixing + if (fixedWindowPosition.y) { + this.fetherApp.window.setPosition( + positionStruct.x, + fixedWindowPosition.y, + true + ); + } + } + + saveWindowPosition(newFixedPosition || positionStruct); + + this.fetherApp.emit('after-moved-window-position-saved'); +} + +export default processSaveWindowPosition; diff --git a/packages/fether-electron/src/main/app/methods/setupAppListeners.js b/packages/fether-electron/src/main/app/methods/setupAppListeners.js new file mode 100644 index 000000000..86c975af7 --- /dev/null +++ b/packages/fether-electron/src/main/app/methods/setupAppListeners.js @@ -0,0 +1,78 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. +// +// SPDX-License-Identifier: BSD-3-Clause + +import { productName } from '../../../../electron-builder.json'; +import { getSavedWindowPosition } from '../settings'; +import Pino from '../utils/pino'; + +const pino = Pino(); + +function setupAppListeners () { + this.fetherApp.on('create-app', () => { + pino.info( + `Starting ${productName} (${ + this.fetherApp.options.withTaskbar ? 'with' : 'without' + } tray icon)...` + ); + }); + + this.fetherApp.on('create-window', () => { + pino.info('Creating window'); + }); + + this.fetherApp.on('after-create-window', () => { + pino.info('Finished creating window'); + }); + + this.fetherApp.on('load-tray', () => { + pino.info('Configuring taskbar mode for the window'); + }); + + this.fetherApp.on('show-window', () => { + pino.info('Showing window'); + }); + + this.fetherApp.on('after-show-window', () => { + pino.info('Finished showing window'); + }); + + this.fetherApp.on('after-create-app', () => { + pino.info(`Ready to use ${productName}`); + }); + + this.fetherApp.on('hide-window', () => { + pino.info('Hiding window on blur since not on top'); + }); + + this.fetherApp.on('after-hide-window', () => { + pino.info('Finished hiding window'); + }); + + this.fetherApp.on('blur-window', () => { + pino.info('Blur window since lost focus when on top'); + }); + + this.fetherApp.on('after-moved-window-position-saved', () => { + const position = getSavedWindowPosition(); + + pino.info( + `Saved window position to (x: ${position.x}, y: ${position.y}) after move` + ); + }); + + this.fetherApp.on('moved-window-up-into-view', () => { + pino.info('Moved window up into view'); + }); + + this.fetherApp.on('after-close-window', () => { + pino.info('Deleted window upon close'); + }); + + this.fetherApp.on('error', error => { + console.error(error); + }); +} + +export default setupAppListeners; diff --git a/packages/fether-electron/src/main/app/methods/setupDebug.js b/packages/fether-electron/src/main/app/methods/setupDebug.js new file mode 100644 index 000000000..32d254e68 --- /dev/null +++ b/packages/fether-electron/src/main/app/methods/setupDebug.js @@ -0,0 +1,15 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. +// +// SPDX-License-Identifier: BSD-3-Clause + +const withDebug = process.env.DEBUG === 'true'; + +function setupDebug () { + // Enable with `DEBUG=true yarn start` and access Developer Tools + if (withDebug && this.fetherApp.options.webPreferences.devTools) { + this.fetherApp.window.webContents.openDevTools(); + } +} + +export default setupDebug; diff --git a/packages/fether-electron/src/main/app/methods/setupGlobals.js b/packages/fether-electron/src/main/app/methods/setupGlobals.js new file mode 100644 index 000000000..90f57d213 --- /dev/null +++ b/packages/fether-electron/src/main/app/methods/setupGlobals.js @@ -0,0 +1,14 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. +// +// SPDX-License-Identifier: BSD-3-Clause + +import cli from '../cli'; + +function setupGlobals () { + // Globals for fether-react parityStore + global.wsInterface = cli.wsInterface; + global.wsPort = cli.wsPort; +} + +export default setupGlobals; diff --git a/packages/fether-electron/src/main/app/methods/setupLogger.js b/packages/fether-electron/src/main/app/methods/setupLogger.js new file mode 100644 index 000000000..cebc95fa4 --- /dev/null +++ b/packages/fether-electron/src/main/app/methods/setupLogger.js @@ -0,0 +1,17 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. +// +// SPDX-License-Identifier: BSD-3-Clause + +import parityElectron from '@parity/electron'; + +import Pino from '../utils/pino'; + +function setupLogger () { + // Set options for @parity/electron + parityElectron({ + logger: namespace => log => Pino({ name: namespace }).info(log) + }); +} + +export default setupLogger; diff --git a/packages/fether-electron/src/main/app/methods/setupMenu.js b/packages/fether-electron/src/main/app/methods/setupMenu.js new file mode 100644 index 000000000..ee68418fb --- /dev/null +++ b/packages/fether-electron/src/main/app/methods/setupMenu.js @@ -0,0 +1,17 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. +// +// SPDX-License-Identifier: BSD-3-Clause + +import { addMenu } from '../menu'; +import Pino from '../utils/pino'; + +const pino = Pino(); + +function setupMenu () { + // Add application menu + addMenu(this.fetherApp.window); + pino.info('Finished configuring Electron menu'); +} + +export default setupMenu; diff --git a/packages/fether-electron/src/main/app/methods/setupParityEthereum.js b/packages/fether-electron/src/main/app/methods/setupParityEthereum.js new file mode 100644 index 000000000..ac6921b95 --- /dev/null +++ b/packages/fether-electron/src/main/app/methods/setupParityEthereum.js @@ -0,0 +1,14 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. +// +// SPDX-License-Identifier: BSD-3-Clause + +import ParityEthereum from '../parityEthereum'; + +function setupParityEthereum () { + // Download, install, and run Parity Ethereum if not running and requested + const parityEthereumInstance = new ParityEthereum(); + parityEthereumInstance.setup(this.fetherApp.window); +} + +export default setupParityEthereum; diff --git a/packages/fether-electron/src/main/app/methods/setupRequestListeners.js b/packages/fether-electron/src/main/app/methods/setupRequestListeners.js new file mode 100644 index 000000000..b7e22f3e9 --- /dev/null +++ b/packages/fether-electron/src/main/app/methods/setupRequestListeners.js @@ -0,0 +1,37 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. +// +// SPDX-License-Identifier: BSD-3-Clause + +import electron from 'electron'; + +import messages from '../messages'; +const { ipcMain, session } = electron; + +function setupRequestListeners () { + // Listen to messages from renderer process + ipcMain.on('asynchronous-message', (...args) => { + return messages(this.fetherApp.window, ...args); + }); + + // WS calls have Origin `file://` by default, which is not trusted. + // We override Origin header on all WS connections with an authorized one. + session.defaultSession.webRequest.onBeforeSendHeaders( + { + urls: ['ws://*/*', 'wss://*/*'] + }, + (details, callback) => { + if (!this.fetherApp.window) { + // There might be a split second where the user closes the app, so + // this.fether.window is null, but there is still a network request done. + return; + } + details.requestHeaders.Origin = `parity://${ + this.fetherApp.window.id + }.ui.parity`; + callback({ requestHeaders: details.requestHeaders }); // eslint-disable-line + } + ); +} + +export default setupRequestListeners; diff --git a/packages/fether-electron/src/main/app/methods/setupSecurity.js b/packages/fether-electron/src/main/app/methods/setupSecurity.js new file mode 100644 index 000000000..046980dcd --- /dev/null +++ b/packages/fether-electron/src/main/app/methods/setupSecurity.js @@ -0,0 +1,11 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. +// +// SPDX-License-Identifier: BSD-3-Clause + +function setupSecurity () { + // Security to prevent window contents from being captured by other apps + this.fetherApp.window.setContentProtection(true); +} + +export default setupSecurity; diff --git a/packages/fether-electron/src/main/app/methods/setupWin32Listeners.js b/packages/fether-electron/src/main/app/methods/setupWin32Listeners.js new file mode 100644 index 000000000..b549c2887 --- /dev/null +++ b/packages/fether-electron/src/main/app/methods/setupWin32Listeners.js @@ -0,0 +1,98 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. +// +// SPDX-License-Identifier: BSD-3-Clause + +import Pino from '../utils/pino'; + +const pino = Pino(); + +function setupWin32Listeners () { + if (process.platform === 'win32') { + /** + * Hook WM_SYSKEYUP + * + * Open the Fether Electron menu when the Fether window is active + * and the user enters a keyboard combination of both the ALT and 'm' keys + * + * Reference: https://docs.microsoft.com/en-gb/windows/desktop/inputdev/wm-syskeyup + */ + this.fetherApp.window.hookWindowMessage( + Number.parseInt('0x0105'), + (wParam, lParam) => { + // Reference: https://nodejs.org/api/buffer.html + /** + * Detect when user presses ALT+keyCode. + * i.e. Use `wParam && wParam.readUInt32LE(0) === 77` to detect ALT+m + */ + if (wParam) { + this.showTrayBalloon(); + } + } + ); + + /** + * Hook WM_SYSCOMMAND + * + * Detect events on Windows + * + * Credit: http://robmayhew.com/listening-for-events-from-windows-in-electron-tutorial/ + */ + this.fetherApp.window.hookWindowMessage( + Number.parseInt('0x0112'), + (wParam, lParam) => { + let eventName = null; + + if (wParam.readUInt32LE(0) === 0xf060) { + // SC_CLOSE + eventName = 'close'; + this.onWindowClose(); + } else if (wParam.readUInt32LE(0) === 0xf030) { + // SC_MAXIMIZE + eventName = 'maximize'; + this.showTrayBalloon(); + } else if (wParam.readUInt32LE(0) === 0xf020) { + // SC_MINIMIZE + eventName = 'minimize'; + this.processSaveWindowPosition(); + } else if (wParam.readUInt32LE(0) === 0xf120) { + // SC_RESTORE + eventName = 'restored'; + this.showTrayBalloon(); + } + + if (eventName !== null) { + pino.info('Detected event:', eventName); + } + } + ); + + /** + * Hook WM_EXITSIZEMOVE + * + * Detect event on Windows when Fether window was moved + * or resized + */ + this.fetherApp.window.hookWindowMessage( + Number.parseInt('0x0232'), + (wParam, lParam) => { + pino.info('Detected completion of move or resize event'); + + // Move Fether window back up into view if it was a resize event + // that causes the bottom to be cropped + this.moveWindowUp(); + + // Try again after a delay incase Fether window resize occurs + // x seconds after navigating to a new page. + setTimeout(() => { + this.moveWindowUp(); + }, 5000); + + // Save Fether window position to Electron settings + this.processSaveWindowPosition(); + } + ); + } +} + +export default setupWin32Listeners; diff --git a/packages/fether-electron/src/main/app/methods/setupWindowListeners.js b/packages/fether-electron/src/main/app/methods/setupWindowListeners.js new file mode 100644 index 000000000..854bbaf8b --- /dev/null +++ b/packages/fether-electron/src/main/app/methods/setupWindowListeners.js @@ -0,0 +1,74 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. +// +// SPDX-License-Identifier: BSD-3-Clause + +import electron from 'electron'; +import debounce from 'lodash/debounce'; + +import Pino from '../utils/pino'; + +const pino = Pino(); + +function setupWindowListeners () { + // Open external links in browser + this.fetherApp.window.webContents.on('new-window', (event, url) => { + event.preventDefault(); + electron.shell.openExternal(url); + }); + + // Linux (unchecked on others) + this.fetherApp.window.on('move', () => { + /** + * On Linux using this with debouncing is the closest equivalent + * to using 'moved' (not supported on Linux) with debouncing + */ + debounce(() => { + this.processSaveWindowPosition(); + }, 1000); + }); + + // macOS (not Windows or Linux) + this.fetherApp.window.on('moved', () => { + /** + * On macOS save the position in the 'moved' event since if + * we run it just in 'close' instead, then if the Fether app + * crashes after they've moved the Fether window then it won't run + * 'close' and it won't save the window position. + * + * On Windows we use the equivalent WM_EXITSIZEMOVE that detects + * the equivalent of 'moved' + * + * On Linux the closest equivalent to achieving 'moved' is debouncing + * on the 'move' event. It also works in 'close' even when app crashes + */ + this.processSaveWindowPosition(); + }); + + // macOS and Linux (not Windows) + this.fetherApp.window.on('resize', () => { + pino.info('Detected resize event'); + this.moveWindowUp(); + setTimeout(() => { + this.moveWindowUp(); + }, 5000); + }); + + this.fetherApp.window.on('blur', () => { + this.fetherApp.options.alwaysOnTop + ? this.fetherApp.emit('blur-window') + : this.hideWindow(); + }); + + this.fetherApp.window.on('close', () => { + this.onWindowClose(); + }); + + this.fetherApp.window.on('closed', () => { + this.fetherApp.window = null; + + this.fetherApp.emit('after-closed-window'); + }); +} + +export default setupWindowListeners; diff --git a/packages/fether-electron/src/main/app/methods/showTrayBalloon.js b/packages/fether-electron/src/main/app/methods/showTrayBalloon.js new file mode 100644 index 000000000..421c1a37a --- /dev/null +++ b/packages/fether-electron/src/main/app/methods/showTrayBalloon.js @@ -0,0 +1,21 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. +// +// SPDX-License-Identifier: BSD-3-Clause + +import Pino from '../utils/pino'; + +const pino = Pino(); + +function showTrayBalloon () { + let { tray } = this.fetherApp; + + pino.info('Showing Tray Balloon'); + + tray.displayBalloon({ + title: 'Fether Menu', + content: `Press ALT in the Fether window to toggle the menu` + }); +} + +export default showTrayBalloon; diff --git a/packages/fether-electron/src/main/app/methods/showWindow.js b/packages/fether-electron/src/main/app/methods/showWindow.js new file mode 100644 index 000000000..70f736656 --- /dev/null +++ b/packages/fether-electron/src/main/app/methods/showWindow.js @@ -0,0 +1,72 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. +// +// SPDX-License-Identifier: BSD-3-Clause + +import { screen } from 'electron'; + +import { getSavedWindowPosition, hasSavedWindowPosition } from '../settings'; + +import Pino from '../utils/pino'; + +const pino = Pino(); + +function showWindow (trayPos) { + if (!this.fetherApp.window) { + this.createWindow(); + } + + this.fetherApp.emit('show-window'); + + const calculatedWindowPosition = this.calculateWindowPosition(trayPos); + + pino.info('Calculated window position: ', calculatedWindowPosition); + + const mainScreen = screen.getPrimaryDisplay(); + // const allScreens = screen.getAllDisplays(); + const mainScreenDimensions = mainScreen.size; + const mainScreenWorkAreaSize = mainScreen.workAreaSize; + + // workAreaSize does not include the tray depth + this.fetherApp.trayDepth = Math.max( + mainScreenDimensions.width - mainScreenWorkAreaSize.width, + mainScreenDimensions.height - mainScreenWorkAreaSize.height + ); + + pino.info( + 'Previously saved window position exists: ', + hasSavedWindowPosition() + ); + + const loadedWindowPosition = hasSavedWindowPosition() + ? getSavedWindowPosition() + : undefined; + + pino.info('Loaded window position: ', loadedWindowPosition); + + const fixedWindowPosition = this.fixWindowPosition(loadedWindowPosition); + + pino.info('Fixed window position: ', fixedWindowPosition); + + /** + * Since the user may change the tray to be on any side of the screen. + * If the user moved the window out of where the tray would be in the screen resolution bounds. + * Restore the window so it is fully visible adjacent to where the tray would be. + */ + const x = + (fixedWindowPosition && fixedWindowPosition.x) || + (loadedWindowPosition && loadedWindowPosition.x) || + calculatedWindowPosition.x; + + const y = + (fixedWindowPosition && fixedWindowPosition.y) || + (loadedWindowPosition && loadedWindowPosition.y) || + calculatedWindowPosition.y; + + this.fetherApp.window.setPosition(x, y); + this.fetherApp.window.show(); + + this.fetherApp.emit('after-show-window'); +} + +export default showWindow; diff --git a/packages/fether-electron/src/main/app/methods/updateProgress.js b/packages/fether-electron/src/main/app/methods/updateProgress.js new file mode 100644 index 000000000..06cd82550 --- /dev/null +++ b/packages/fether-electron/src/main/app/methods/updateProgress.js @@ -0,0 +1,19 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. +// +// SPDX-License-Identifier: BSD-3-Clause + +// Optionally update the progress bar shown on the Dock icon +// (i.e. 0.1 is 10%, 1.0 is 100%, -1 hides progress bar). +// Optionally emit event +function updateProgress (percentage, eventListenerName) { + if (percentage) { + this.fetherApp.window.setProgressBar(percentage); + } + + if (eventListenerName) { + this.fetherApp.emit(eventListenerName); + } +} + +export default updateProgress; diff --git a/packages/fether-electron/src/main/app/methods/windowClear.js b/packages/fether-electron/src/main/app/methods/windowClear.js new file mode 100644 index 000000000..a3d57677a --- /dev/null +++ b/packages/fether-electron/src/main/app/methods/windowClear.js @@ -0,0 +1,19 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. +// +// SPDX-License-Identifier: BSD-3-Clause + +function windowClear () { + if (this.fetherApp.window) { + // Remove relevant events when window object deleted + const events = ['close', 'move', 'moved', 'resize']; + for (let event in events) { + this.fetherApp.window.removeAllListeners(event); + } + delete this.fetherApp.window; + } + + this.fetherApp.emit('after-close-window'); +} + +export default windowClear; diff --git a/packages/fether-electron/src/main/app/options/config/index.js b/packages/fether-electron/src/main/app/options/config/index.js index df140570b..e12bb4289 100644 --- a/packages/fether-electron/src/main/app/options/config/index.js +++ b/packages/fether-electron/src/main/app/options/config/index.js @@ -48,7 +48,7 @@ const TASKBAR_OPTIONS = { frame: false, hasShadow: true, height: 464, - show: false, // Run showWindow later when taskbar has loaded in FetherApp + show: false, // Run showWindow later when tray has loaded in FetherApp showDockIcon: true, // On Linux the user must click the tray icon and then click the tooltip // to toggle the Fether window open/close diff --git a/packages/fether-electron/src/main/app/utils/window.js b/packages/fether-electron/src/main/app/utils/window.js index 7dbbf005c..c940e3080 100644 --- a/packages/fether-electron/src/main/app/utils/window.js +++ b/packages/fether-electron/src/main/app/utils/window.js @@ -10,7 +10,7 @@ const pino = Pino(); * Returns the latest window resolution if it differs from the previous resolution. * Note that the previous window resolution may be undefined if being changed in settings. */ -const getScreenResolution = ( +const getChangedScreenResolution = ( previousScreenResolution, currentScreenResolution ) => { @@ -37,7 +37,7 @@ const shouldFixWindowPosition = ( currentScreenResolution ) => { pino.info( - 'Window position (previous, current): ', + 'Window resolution (previous, current): ', previousScreenResolution, currentScreenResolution ); @@ -53,4 +53,4 @@ const shouldFixWindowPosition = ( return false; }; -export { getScreenResolution, shouldFixWindowPosition }; +export { getChangedScreenResolution, shouldFixWindowPosition }; diff --git a/packages/fether-electron/src/main/app/utils/window.spec.js b/packages/fether-electron/src/main/app/utils/window.spec.js index 660163b78..e8a3bacc2 100644 --- a/packages/fether-electron/src/main/app/utils/window.spec.js +++ b/packages/fether-electron/src/main/app/utils/window.spec.js @@ -5,7 +5,7 @@ /* eslint-env jest */ -import { getScreenResolution, shouldFixWindowPosition } from './window'; +import { getChangedScreenResolution, shouldFixWindowPosition } from './window'; jest.mock('./pino', () => () => ({ info: () => {} @@ -29,7 +29,7 @@ describe('window resolution', () => { test('should return previous resolution if it was defined and current resolution is the same', () => { const previousScreenResolution = largeScreenResolution; const currentScreenResolution = largeScreenResolution; - const screenResolution = getScreenResolution( + const screenResolution = getChangedScreenResolution( previousScreenResolution, currentScreenResolution ); @@ -39,7 +39,7 @@ describe('window resolution', () => { test('should return current resolution if either its x or y coordinate differs in the previous resolution', () => { const previousScreenResolution = largeScreenResolution; const currentScreenResolution = smallScreenResolution; - const screenResolution = getScreenResolution( + const screenResolution = getChangedScreenResolution( previousScreenResolution, currentScreenResolution ); diff --git a/packages/fether-electron/src/main/index.js b/packages/fether-electron/src/main/index.js index 45ba30ad5..a3c3c3ef7 100644 --- a/packages/fether-electron/src/main/index.js +++ b/packages/fether-electron/src/main/index.js @@ -7,7 +7,7 @@ import { killParity } from '@parity/electron'; import electron from 'electron'; import Pino from './app/utils/pino'; -import FetherApp from './app'; +import createFetherApp from './app'; import fetherAppOptions from './app/options'; const { app } = electron; @@ -15,6 +15,8 @@ const pino = Pino(); let withTaskbar = process.env.TASKBAR !== 'false'; +pino.info('Platform detected: ', process.platform); + // Disable gpu acceleration on linux // https://github.com/parity-js/fether/issues/85 if (!['darwin', 'win32'].includes(process.platform)) { @@ -28,7 +30,7 @@ if (process.platform === 'win32') { const options = fetherAppOptions(withTaskbar, {}); app.on('ready', () => { - return new FetherApp(app, options); + return createFetherApp(app, options); }); // Event triggered by clicking the Electron icon in the menu Dock @@ -46,7 +48,7 @@ app.on('activate', (event, hasVisibleWindows) => { return; } - return new FetherApp(app, options); + return createFetherApp(app, options); }); app.on('window-all-closed', () => { From e0b77f745b1eef1e27604d460985dfadca208351 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Sat, 2 Feb 2019 11:45:15 +1100 Subject: [PATCH 094/153] fix: Fix config --- .../fether-electron/src/main/app/methods/loadTray.js | 2 +- .../src/main/app/options/config/index.js | 12 ++++++------ packages/fether-electron/src/main/index.js | 4 ---- 3 files changed, 7 insertions(+), 11 deletions(-) diff --git a/packages/fether-electron/src/main/app/methods/loadTray.js b/packages/fether-electron/src/main/app/methods/loadTray.js index 4819ae7e3..d3dbc6f8c 100644 --- a/packages/fether-electron/src/main/app/methods/loadTray.js +++ b/packages/fether-electron/src/main/app/methods/loadTray.js @@ -13,7 +13,7 @@ function loadTray () { if (options.withTaskbar) { this.fetherApp.emit('load-tray'); - if (app.dock && !options.showDockIcon) { + if (process.platform === 'darwin' && app.dock && !options.showDockIcon) { app.dock.hide(); } diff --git a/packages/fether-electron/src/main/app/options/config/index.js b/packages/fether-electron/src/main/app/options/config/index.js index e12bb4289..4ffd40f77 100644 --- a/packages/fether-electron/src/main/app/options/config/index.js +++ b/packages/fether-electron/src/main/app/options/config/index.js @@ -20,6 +20,7 @@ const INDEX_HTML_PATH = const ICON_PATH = path.join(staticPath, 'assets', 'icons', 'icon.png'); const shouldUseDevTools = process.env.NODE_ENV !== 'production'; +const shouldUseFrame = process.platform === 'win32'; const windowPosition = process.platform === 'win32' ? 'trayBottomCenter' : 'trayCenter'; @@ -27,12 +28,15 @@ const windowPosition = // API docs: https://electronjs.org/docs/api/browser-window const DEFAULT_OPTIONS = { alwaysOnTop: true, + dir: staticPath, frame: true, height: 640, + hasShadow: true, icon: ICON_PATH, index: INDEX_HTML_PATH, resizable: false, - show: false, + show: false, // Run showWindow later + showDockIcon: true, // macOS usage only tabbingIdentifier: 'parity', webPreferences: { devTools: shouldUseDevTools, // Security @@ -44,12 +48,8 @@ const DEFAULT_OPTIONS = { }; const TASKBAR_OPTIONS = { - dir: staticPath, - frame: false, - hasShadow: true, + frame: shouldUseFrame, height: 464, - show: false, // Run showWindow later when tray has loaded in FetherApp - showDockIcon: true, // On Linux the user must click the tray icon and then click the tooltip // to toggle the Fether window open/close tooltip: 'Click to toggle Fether window', diff --git a/packages/fether-electron/src/main/index.js b/packages/fether-electron/src/main/index.js index a3c3c3ef7..1cc11748a 100644 --- a/packages/fether-electron/src/main/index.js +++ b/packages/fether-electron/src/main/index.js @@ -23,10 +23,6 @@ if (!['darwin', 'win32'].includes(process.platform)) { app.disableHardwareAcceleration(); } -if (process.platform === 'win32') { - withTaskbar = false; -} - const options = fetherAppOptions(withTaskbar, {}); app.on('ready', () => { From 00c95b07decb4bf3d9d22fcba85d939e8fc181c6 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Sat, 2 Feb 2019 12:26:36 +1100 Subject: [PATCH 095/153] refactor: Move setup of listeners to end --- packages/fether-electron/src/main/app/index.js | 10 +++++----- packages/fether-electron/src/main/app/methods/index.js | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/packages/fether-electron/src/main/app/index.js b/packages/fether-electron/src/main/app/index.js index 8252f716b..c1d95a362 100644 --- a/packages/fether-electron/src/main/app/index.js +++ b/packages/fether-electron/src/main/app/index.js @@ -27,11 +27,11 @@ import { showWindow, moveWindowUp, processSaveWindowPosition, - setupWindowListeners, - setupWin32Listeners, hideWindow, windowClear, - onWindowClose + onWindowClose, + setupWindowListeners, + setupWin32Listeners } from './methods'; let hasCalledInitFetherApp = false; @@ -73,11 +73,11 @@ FetherApp.prototype.fixWindowPosition = fixWindowPosition; FetherApp.prototype.showWindow = showWindow; FetherApp.prototype.moveWindowUp = moveWindowUp; FetherApp.prototype.processSaveWindowPosition = processSaveWindowPosition; -FetherApp.prototype.setupWindowListeners = setupWindowListeners; -FetherApp.prototype.setupWin32Listeners = setupWin32Listeners; FetherApp.prototype.hideWindow = hideWindow; FetherApp.prototype.windowClear = windowClear; FetherApp.prototype.onWindowClose = onWindowClose; +FetherApp.prototype.setupWindowListeners = setupWindowListeners; +FetherApp.prototype.setupWin32Listeners = setupWin32Listeners; const createFetherApp = (app, options) => { const fetherApp = new FetherApp(app, options); diff --git a/packages/fether-electron/src/main/app/methods/index.js b/packages/fether-electron/src/main/app/methods/index.js index c0ddfb011..818fb4a1d 100644 --- a/packages/fether-electron/src/main/app/methods/index.js +++ b/packages/fether-electron/src/main/app/methods/index.js @@ -24,11 +24,11 @@ import fixWindowPosition from './fixWindowPosition'; import showWindow from './showWindow'; import moveWindowUp from './moveWindowUp'; import processSaveWindowPosition from './processSaveWindowPosition'; -import setupWindowListeners from './setupWindowListeners'; -import setupWin32Listeners from './setupWin32Listeners'; import hideWindow from './hideWindow'; import windowClear from './windowClear'; import onWindowClose from './onWindowClose'; +import setupWindowListeners from './setupWindowListeners'; +import setupWin32Listeners from './setupWin32Listeners'; export { setupAppListeners, @@ -52,9 +52,9 @@ export { showWindow, moveWindowUp, processSaveWindowPosition, - setupWindowListeners, - setupWin32Listeners, hideWindow, windowClear, - onWindowClose + onWindowClose, + setupWindowListeners, + setupWin32Listeners }; From 79ea08a46a7bda0ca0158a4915e128935e211b4c Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Sat, 2 Feb 2019 14:19:00 +1100 Subject: [PATCH 096/153] fix: Return menu from getMenu --- packages/fether-electron/src/main/app/menu/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/fether-electron/src/main/app/menu/index.js b/packages/fether-electron/src/main/app/menu/index.js index 72c6f1062..d8e3e1b5d 100644 --- a/packages/fether-electron/src/main/app/menu/index.js +++ b/packages/fether-electron/src/main/app/menu/index.js @@ -11,7 +11,7 @@ const { Menu } = electron; const menu = Menu.buildFromTemplate(template); const getMenu = () => { - return menu; + return Menu.getApplicationMenu(); }; const addMenu = fetherAppWindow => { From 1f2a846e1039515ff1865bbaa6cfdefad5781aa1 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Sat, 2 Feb 2019 18:00:25 +1100 Subject: [PATCH 097/153] chore: Replace small tray icon with white on black icon --- .../static/assets/icons/icon@2x.png | Bin 3181 -> 2657 bytes .../static/assets/icons/icon@3x.png | Bin 4899 -> 3658 bytes .../static/assets/icons/icon_white@2x.png | Bin 0 -> 3181 bytes .../static/assets/icons/icon_white@3x.png | Bin 0 -> 4899 bytes 4 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 packages/fether-electron/static/assets/icons/icon_white@2x.png create mode 100644 packages/fether-electron/static/assets/icons/icon_white@3x.png diff --git a/packages/fether-electron/static/assets/icons/icon@2x.png b/packages/fether-electron/static/assets/icons/icon@2x.png index f33a32c8f0b35ee1ca8b154962727236fe00b387..c9425d5def6b76271b7175bc708ecc59c887505c 100644 GIT binary patch delta 1430 zcma))YgEz)0LA|*qNt}eD>Ks~)Rrjxkc56ER2>CK`<+V(>&1-WQD~qEHC<$S+NI$uCZ7Z5YJ9NzzKAS<@LE^(4`eEm1{NtcE>;_PS%&(zxCXr(yaI|M;EFog1ue#^vFOo9;V#mt`alxjLjDJ}1kQ z!r<9bqf2SFQ_R_1RQDrkX=v#|TJO^-3M_G9fc9;BIp1UnnO!1{5JnbAi2?gL&Vb~m z?<211t;LeunlnE?UsY8lK9s)A<$N6dj?v+-??hRQ+qXcWP`IRQ6erikPN!#PWo4zM z1xPhNGyMOa`aHuufH@uYXVv1%!LFH;R6c*eY&Mf@oS=JZ2JYP@r=8I{e)=ARo|`t- zz74u%;0~48K_I_IT?GUg!WQN6Hc3xoW03qMSWKE29;g}4G%sY;MvQ~WnFNo#yu8x> z@k+RVIyC%fO_bHU-?aL%{GR6`<=Kjgitv6`Lx|*D!e(1r+dJM6 zJG+>en9OUuW|6EL)a&)9%HeD6>2YzQU8d&wIn!5{B9Z)E z&KK^}(AF7@4YTjxNX(-=qh5(9+1J|ITI`WIFnWSaq1Zy9E2KaR=kP#FI`_%)oF1D>>)Yhm$w5W!)=+*?@erZ0T3MPvr44jS5E-w5$EW2bzPM)daXe*75WOaWfJ zcmYSq?nB_S?{^^-3PrD8AM92{CX=hHtD(8u2m~W;c4cLyDQzTp@QHb0S)p)4V9NV} zUf^f$=8$fQ<6Kzj7|_!%eeA*@`e^gAc*+!DCPal_m8*SMR$5YhUDkX}n4NJ`V2dnyYoB#j- delta 1971 zcma)*c{J1uAI8UEMk%6&i5kmH-7uQfEQ(&&Hfn}TU1S~nrXh?Nj3qzZM2kX~Mk!>< zl6#rlYiDG8!yr?#T`FYX=?zJ*^Pcnm@t*Vkald~*=Q+>!bDrnpfqC^5gaQl#k&(M< z?iSY!;*hy`G%0Fi{DV!iML0)>ocvq}H4V=!puT<_2TAdp8l zKdr;^;d%iyAFj8r4=sqp<#9te+#s3}g-WD&QArp)iABXw2t*?c#fajKVd3yBfJh)= z$zH7gy4eQ%Uh=&+BddlY5U^ALU{f&!0+EOzdb5cbFK>W|0eq-L5|K>>SU#kCXt|&N zo-kW3%i`~S6~eO!*a3Wh*n`|0NYIPa8@e4l&nSI0xGNI^Bn zOwFOl;MmR7#za5Qy_Qd!m7hOEPg^3qM`7gFbab>7JG)hd#3P4_g_*Vf9Kv@s^?CaK+ZlU-3=;OP=b zXL4d}qw-%>A@Eo-YAa9$X~E``8_n>$&K|zMrXkba6uGgn(LWzHrt0Do zy%Je>{=$Wxp&?^aGRPB&M1vWrx#Qs@shw;G2BS0j0OVB6mY}@cDE_6^z`($FW!ZJg zmYush)1t+q11pBBBa!681j*#Sqwc!1gMVHYEZs;&ZmR^a84Sixc6MMxbF*AkRTZ0X zP00;9LUdUesXI%j?}BI;`8Q0isvwbEG#>Mz{>roYhuk2FX63M~zYVi>nx}K4t&P4X zk)|xeXx&vYwD*j?)Uvg;HO1V)TQ};bu_Iw#})n3RCIN9$3J~q zUYm9(=e`fL*hr|V?gfg}UJT9KSXUlkZEZ_ zpJSS!4Hx<(U0q&f1H}awZpk&4_}fcigM;;Gef?XFjb?tAFZ%`rkluVRJM*D!>IVZJw0(K+ThSYRY<GSxAy84Hy zp1d;!PHI=zbJIht)o$??78l`K#$S~oLZQ%!noZd4k9QfCmCZUGl@T8g)t@|J5X>q| zRoMeWAd&z46rA}8^t|DJzz)HNL1psB6jA~wtcpPR1k~Y%Md~g&Xl?X{RIgdZtmRTq zd`V4Qr(~F&x^E9GQy|ExsOXCxbN&dQ2sB$wGD1%squZiB+YI`4jbNd1v4-xo1-e#u z3JMG9F=CIScaN*OrAg7l=|r?|2lN(;jI{boEOWHmdttZ+-jJ^E=u{U;0`>L0_4V>}bSD z>{aTs_lx;2UZiz(F(G<-di`S1)UhNc4rE^k-}T)S2wwf}R->+|DHMyphmI%;^wEqC z(X;$~YQzdEtme_eLLg)Zx^q=9h>rT#TyDqocx$pov4{BaZ!Q(mzP`kcPY)LH84cl3 zn69(&Bc>A4MADR~EVDiqwWxhVQO$5^rdQw4t@;`&Y_9+1{7^+z#Okq~ZCZ~a@1JyV zbhL_!`f9JCe(|jxsIbg^I6#$vyo?H9W19v%hnFYxUyF z%C?QIZTGCfZtV5kr>=go6YM?>`ts)IS&HTzYqkQZDcjS}I4N0ow*>h_Mdjr5m$dS; wg9ayll0FP6|88^m-gw$uOyPyxk^x}Zls1cF9`Q`Cf$SXJf@%J{nP>dJ0T7CO&Hw-a diff --git a/packages/fether-electron/static/assets/icons/icon@3x.png b/packages/fether-electron/static/assets/icons/icon@3x.png index c930c704dbd2298ef13411533e90c9543e8acf58..42c3aaae43b35e2dedfd6c842f555423a70ee12f 100644 GIT binary patch delta 2580 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 TPN=iL3IG-+Hi-8(Jf8gvf?V2| delta 3735 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 Date: Sun, 3 Feb 2019 00:10:42 +1100 Subject: [PATCH 098/153] feat: Change taskbar icons to white on transparent with 5x sizes --- .../static/assets/icons/icon.png | Bin 2199 -> 2146 bytes .../static/assets/icons/icon@2x.png | Bin 2657 -> 3417 bytes .../static/assets/icons/icon@3x.png | Bin 3658 -> 6959 bytes .../static/assets/icons/icon@4x.png | Bin 9430 -> 15963 bytes .../static/assets/icons/icon@5x.png | Bin 20607 -> 14408 bytes 5 files changed, 0 insertions(+), 0 deletions(-) diff --git a/packages/fether-electron/static/assets/icons/icon.png b/packages/fether-electron/static/assets/icons/icon.png index 0e3e52463bb3264288b2ff4a1682bbe7672e603c..70e557ed8c3e48e7e7766ed075eb030ef899264d 100644 GIT binary patch delta 731 zcmbO(_())aCF7-yRy|BsM!E*ZAqECk24+@6#d(r0H51Cz^6q+ZmzG$m7=4PrBqtyg{=DYfR23CQ z1}^u&oTKax4Dt$`lTLh|qY@agCX1Do;q}!lDc|MW*B!p)vT%{q<0sREgzFjD{{EZV ztQDkpQ0?s>)(5{Hsn6p1x^K<1&z0(3i)I(cUXVzh5)>!g=$CuB*v_v{i+;LH%A8fEH_uUk#W7gg_ul67H^1B1+so8xFVdQ&MBb@0Jw$+aR2}S delta 918 zcmaDPFkNthB_qQ|s~#pRLtSIT5JMv?QzI)ABW*)ND+2>1g^Jt)E8oaD9u9G#4ycBH_ixz$D2yEorhbOBitq*RsrUCB}_P3dJR^WhGYS z8L4?#Jv%vpZ9{$X?eh%`3{1A3E{-7>g&2S?eKu59V{8yYWe zt&Lt2%yns_h|H$+g5JpyO_%t@-cDP(OQn0+tAyPuqEai>#C!~Wd1fr~Oy)Uq`Kb85 zCkL9#|IaCYzkB-gNk{J9jpg(_x^t(cVrG!gx)80U7cT}*Fj4b-SYHq^DTOhz!Ra9n zgNmZ2Zl9+Wev)BjG1y{2ke*VdE?#zVq&tE>+$Kv++!-oqo;l8(@9m(1n zShsFn&(7poBJ~a{Lzdml`IJ|AGo+r+C*qiu<ur(^RwwC$*0fznDte0MH@!W8iVO#F!qB61f4;1)q<$nGC?d!zk={@O6hKWe` z(Jec6+%Wb0+?DEi>-O!}T;I+uoSYG$^Y7xnfBUL7yn3=jg;9qwQRc+cq9czBqqc9i zspn?lU~B&Jfce8Q)lAlk*F7qeIg576G#+3%nKCJDbLai{>LOeZ%XZIQDIYtj>wtm7 z&KR|c9tBmux)&~VmywtMd|*??ojV`a$36def@7iw%k6Ew2U?|9NHDIye)`7`i{Rkk z6eG!;+iH_fe$Wy*RJ8kN^x8|;uRnjY;MF7(wm$_`vHW~|7N_Js9{E1ya?QN8YjwrM z#6JA~ySI2oNuI((nbN&+*KggLr8KcaPhY>@NNiO&E4 diff --git a/packages/fether-electron/static/assets/icons/icon@2x.png b/packages/fether-electron/static/assets/icons/icon@2x.png index c9425d5def6b76271b7175bc708ecc59c887505c..e12cf0d073a4058c7098a6456415b47ffbf917ad 100644 GIT binary patch delta 2016 zcma)&SzMBd0>wW~5S6P~u4#ruS&bAsAGEjxqg2|an7M*L?pC1Xf_U96rIH34Gc7AE zov__)6iaVrij-?+}OYo-pBDbvfH=Q&U3{C?;BAI^x`>(%G1VNd|j(G%_FoVT~s zg?8Pgo!8aJ6KEtd4KMA|-SCgs>L!S}Ashk^%i&;f96pF4;s_vyO2+aqcrKC8rxK}n zkV-`%PemQ`@SxFSLSmzM(LyGD2a3&&;qYkOn2<0o?O14xFh&p>bBq>3W|PR+5Ilwr z;;SX zlPDM>pG?NGNgR+v0Hy2oSpTkAqF2NKxp*p%&8K3>ARdb$f}|fr5cT>}g00>sC11wr;dIQ+44q!$UU( z&1?eN=awcWUEl`5cGacWmgD~J`5(@f8#4|V!@Ez}0G_y1BoG4cJwmD#O~e@h#wI2@ zC|y$*m=3CRA6u2gb)mD;@TT=krf|eGpKE>EQPrZ-`AsfQHCl#CU+DvfD|?^o+)*k$I_GS^dMz92q#|pMZ1RzR z&Q-rHIx3&osh<+rdTTnMj{Z(3<=4$CO%oc11scg&`*fs7zcXF@A%3`0$jL7K^Xtbi zRKVLCXRrZv(A&I7&_%rLE6d1{IH>&%d&A9L5O=WfcHmWC9~sh6{3d(~p%Uc&eC^jS zg3+Yn9pt8tGS4&FI4Ej%`uXmKg4T+J@e+%dw$3shL1A=oMEZ;Qep|*-{AKG;qP0yq z={9*#onQb4bcp)3&;a;e7eDONf+$afbyYwPFplEM; z)S!<|-qV?!o6pgkigsPJU|3}$QJ`c_&-DCEA`eySS)NApcy@1!I->Ncz%LE^eNXY27T)}6u{S(6v#E6H#>lZ6^;Fzk!ZrIx zg&u1T4b~DN9^KCL7qLri21B4kY?<-WExg>Q{oWs^!MWDswxDE%T4S=IwRR}F#BSze zbp0JMG{cqMVOZ_h{svR<(@f;dq`!WXusNl4qrkcYKr?9p#qxuWfz^8_W}qsIGBL|k z>yQ|k(n^Yd{q}>2gzsI0shz+=lvsJhp5`|1ojwmb}j3jG&ZuW1@Ixx?d@suw^ zx$U11zRGgA^XO6Bz`Mvn=vYy}@26&sfy1%|<MsONmx{FO_brD%gF)##eTm{lgi5ftY?25H7Nif5ns1s87c?`N1X6dz5X3M6X&$JiCNI(@{gj*Wyj zuU%z28Xv7mXrPGHT7#i#LAB;8@yf)veb+XAtDC3;X*AdRq2-n5uiQ0mBv`?dcQ!s~ z^q}8~jEH!GT6JDxl8WwhdAimzG!MqrLn3`}JR99rw08r|OR-jrfHR z$O36s`2f+;b}Hu(=~u4HBHb6WjhZI;Ne3ER@M;>>yp@Iy?7CtdCuoccHaPKo~j delta 1370 zcma)%YgCd40ERymQPk6#l^JOfYReJ@dGi(Kr+dhf6_m zaCneNNKPSQINu`?r_xUD-%p{XrwG%yf=oIs4EeDM2KgWbgXX4SK{5`N5(;8aI5LTY zN+yv&6o&|M@fbXwi^IxaI0g8BhKH4hLKvSXY9W{XKWDi-9J=At-9%`E#6!Ug1OUi7 zI_;YydrLYLiP7;~?|aoN1<)X8&saB9E$k80;DcMu;03TeMw#1!6SlW@uXA*oR753h zxbG2Ak)1T+?Ur@;yu45fL*z-#UgdcnvF8fVy^o~jyUGtT3{PevVMz-^j2}BIGc5M7 z*(K^2d2E526ta)&2}o}4c*L{3wcAtM^XKR1RVtPEP}UZ&3-Qc5X19NT66LaP-vWg~ z;ZjwzIJF_pnw68Ao12~ujG8wl(G-)#8ico|mWS85u)1n~mz^0o`3U zbnh-L{jARY%lBB!oYh?a7Jtjc89R%=!_FZea}Qy=c=o# zqXv?j!X)PtH#$2z-wA-YxWvZB=3E!FisZeZ(P%tfiCFE*jE@)Xw6xC8S-!gxzr6dv zL%m+F9Ia9+7vD_#%SBy8%bp-FiRsB-Q}%@GyjkX=%NLtQTx@;IxA)b;mqZUv5H2Yc z{D+s#iN0_+lg*$~sli?sO7?0QYfR>*+4pZGwsC>kScR1BZEtTc^UWC=KS_&>bcRA# zsG)Z5;h}1GcgA($hpn5v)TKv%QhBZGnNXT{`vwT3T9Kgz6wt=5wsz zn!!-@>XrM{L#J&)LH_EzJO?@m=0|jopIi|qtSUO3HK*RAaX5J7$YYCz&0={V{QP>R zGnv|pThOr{49qC41~t*s<7Iq*{d808FW zyJC?+2?*#N97K9X0?(g6MIyikphbEIn z85vFW^|K@7-D0s=B9WY7Q-OxKonc`K$FB)}i>aESA7;mHrJ}uoKh4&=YrgVa>jv=o zd_v_wTf;b$`2oiN1%Kslw5@eMC diff --git a/packages/fether-electron/static/assets/icons/icon@3x.png b/packages/fether-electron/static/assets/icons/icon@3x.png index 42c3aaae43b35e2dedfd6c842f555423a70ee12f..e477eaf55f88820cf0f9ae4b443d824426d80bdd 100644 GIT binary patch delta 5669 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 diff --git a/packages/fether-electron/static/assets/icons/icon@5x.png b/packages/fether-electron/static/assets/icons/icon@5x.png index 7d90fe6210006212de371179f21868e28cb7a75c..8d657d065d66557e4aa33b8713a5fdef983ff5a3 100644 GIT binary patch delta 12936 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 T<6Q?1Dx{&Rqw-$)QP}?lRvUod delta 19255 zcmXV&byQT}*T(PA-Q6PHUD6;3C?F+W(%m63LrH^lNH>U}gmgDZr*wCB^WN`oy=(CY zYq9Rkojd#N^X%vO9QvJJav}RxF0v{WDViqVn9!cU|E0we7(8~T$CK7<}vl-#p@JA zQbzFvHJs20Sv8C2A){xtXqpJ?0vovLLJJZkmhU{J0*N+~e%n~Z^Vx$%th2}(=2RF+ zzpN)2RQWp5^IC~eCemqW_v8sZA1&+_+jQzeZwvT3(97ikW{wf|=aw2*%VD^ByfQg{ z4(Lp@6BA6e9UE8`HI%I#Wq#jilG-gn%mx6#G7vyAGLP1YiZjrkx)UNXQ?8TGES8Hj z6`dO#)60bcAjy6NfE{L_3xF8?oPShM$9%^Nz1vFp{KSCv)ui3K`Sy81OqT~)RS>t- zL6mq$N@$n(W!SqJfaR<(KAgCfR0KdHIT}%b?!TEF#6q#e(df6=JI#pTtt@^Svf_4a z4WE#d9WA2djORAg(NQR0kWns92n(C9u~q_q2Y+m5D_+s!z5GNXhEcHuBdE>}6wsS3 zQOS0`lI=A4eGhpSWE<-2a6y^M`uKhUV(cdZA>+3}7}@AqK4~L-lUDN+8j4BI@Z8kp zy>t3u{cJsGYe?M!Yj-y|Jo9}C;#U)#)9HvKWfn&IVf>F{Cy@tdC5B!JhT;4GD$~G%Fb3QcHU8$zI8T%| zIN3@2%#~%g%hCCAz8KIvd=^%0avRSS&hdA)DG*R2l0912c-MV74gIagsBuwBlcy4H zg^&9r?I@yq2#;F=^`Sx-lN-jKMlp8d+x>%GKVdEoefH&tD|jzcid3EoKLS`~+-AG* z=PV^N`TGq8%k0gbv|-q&`u zu@T;-nWza~JDHxc&>q>6kk9gythwR4+8Hh=$U*CE!m-4;FbQQ6%!KbA@F9E`@$q;F zPvSVZ_ctfl;8!>Id!FqN2f%4d*g4=5791$#vI$lY5uGGc`we2~WQY}AIYX&(y2dXR zt)F?4G^)k(fb)-4`-MN&e^N`I%}w(rqL461zSYouVwIhTexz|@!Ass}n8}5M5kYF?HvSf@$VZF6M^)RYqXPB_J7=9eRqG{A&c`)yT(Wz8 zQNQ*H?E&Ic@cL^UAuMdS;%p;9aTvYWCXIomu&iM{g0;IXThyCp&nNl< z_65?6i0J%stdU+Xw8dA~rU87YrD0z?{8t_B?o(1y^3HX;5fMiltO@6=#`JNa60=#v z#-DV71BOQ%okn<;otGZ9B+}c*snOah+b(bvkY7qrdqs|sAmroh68ekKglG8)=Pzd$x`S94a`sg zATeIOdke^=(JA3sXh}kD5uJ)uEg_0Q$00fxUA4u|l!b|&C_phI?(hK*u#nqXDZ|ci zB?%>R=b<0HVjkl`U`u1;s9%LUyt{q_G_tYpy?gV1>JpgL)l-ZlV!y3L@9Q~&OUHoB zW#1Dc8FlN1q0&7pmFrZ8T@dWLhkQ(GS!8^TsL~_6ll5P3$S8(cjAq%pd;CxcVK8ej z9V>OU^nF-)2@F$JR}W(NklyWgVyYvQ0p;L|f`??&J8Jc8!OTM}N#yuSo;^pYoUa`x z3Q&pIb?G=*!Nz3wciZIS8pK+de#xZr-xDT~l$6BmZ}eYJ>Qe&Wt4LJj?X`Eu@%iG# z=y&#I88bJ9^6o%Hbb_{n*-E29g^@M4h!EwgHwj}7uV!Uf9Mdg^)AI#z08{A7+pbr^ zU26q9I)ZJiuWNh1ORB~)lz{D1RZR^pry>RQbjH{J@9h1PF@VusJvhsqT zc@ExJR2TC;8Uqm(AcQk+Tz#J~*~8L0NJBcxF(RX>sp-6;)YLkGLn7!v;Y?M@a8vIF z3wt(ag1`bha@IXddoN~wLiN;%bnlx_*F+7!fSo%!jDqtuF7v3ih?9^3GrE}DuBIug z3l(PrI@vf30>6(C&s<{+Fw%;6ozgT2)mbOdg_RVqX%wIiq9kdTfNQMBZ&XOl^QGye zRj-^crGV#sTna`j9Q1Y#x#vX0<50GIK`E*$?Q*I0>0ux#Z%i5b$v{Q7+9KMNYPW4c7e@@~#A zj>qTP&bhF^QS5S}T*tzkx)`<9SgTA{ma1}Am6ec~SjplUF5TQP7jZuBugjbo97IA` zM^IBsYtWxFlPwd<5d#Nl)66R`B)A6D)A((Pg!RkUZ{EfyCm(QkZdZrfF%Tlf-C69U zqW~;Ni#i@J4N56$KZs=f1`b=8Ycs_C(lgkU(1|$`pTrF{Jtj-li~s)3>Th43qlPRx zF5kbVGAXn?XHik~1l}aJYE+Z?0?nw_#X5N07(wgnrU29zyT&*P8Nd!m(ffT0d;ZC- zUdaFJ4c+&QWa@)jWUk+%D4Cx%E~4~9z8vO^ZJj7ea4r_sN#+uy8i5L&%Sw88noYK#I) zLYia>iOGc)60t_*y;iNuwW&D;e(A*I+BUb2#wW63dpA9no(e|Msmwe@kI6`po=ma8PuJcPjtj~__4@q4F&X!d!n zP`eCGPwn>k>EU}?1_SAI;{ZRhlXMf?o^zwVQ=>MtnphSgNlfYkwo_MLCpM)Bfif{V zZBAL);Nhm`bWu9mY4Jt8s%6V41^^vvf}}i_0vS0pXrH4$eCQ-9>~yavS|Q{U zVWz?x1@r2^@=SzSq4*AU zodt6S0zlZiLx}Z8vQ2;qN&S+8Dj&xRhy3rkO}zKA9_-$G)v@6C|4=mGO4$A0;^YF)^3JI52vT6nOLluTOYQT z0eX6Rp)Z#u{}S@At*CTMD=LrQUJIAdu#9$^AsrPeJ^=<_M@RN37a<-@41NfV!OErEE9{)~op@K09l$n|3 zZwm9>6ciK!n|vW3z$f|f_rWG_25eBF0$lC?EWvxw5zMS8eMOsR%=J#0`1>_Zh{;{F zsJ?*#d$v`25Z;7(UT5C{`!_#Bw@g(iV&M$s#>exaXo3!X_OYYwb%q9d zrDQtGR8`>#v~*reWwjpYF9&R4ikN~O;n)-w78Z;lJ6%LB>zJlY_Zc1M4WTo;IQ<_= zlioK=p5f7$%)FrirDChOp;YhhC6=Yq)yp%w6_l-(oHu%>QAvMLgigMV3+uqgLnSGL zRkq%(lHBmg=^Ym%lIn_M@_OKCDEM0v^}T{_UWwJE5vRRKNVzAQS5J_)%o7 z|9#o9p>F!4#dtpg&PVM0QmcSi$*pMCW*q74k_yw!5mE)`R9CM-eV_J~muF9rCieq^ z2Ie-Z6gC}c{X?3o-SPa%qTiM`RJ^hRm2f~m%Nv(ArK!ze>B9YE>A80aD{x=CcHe2* z7_=p1VQO{ebxl%3pzc~GN*?scpdfPz4K*Qo+>YUnhiq5w0nS6!J?q=qW>zmDa zc%Fo!`VK-WwU*Hh!=i?`FjzR6FsS|OY4^MnSYP{V6`8e>X6tbNtKnQDIC%k|d|Xpb z+&`U>!r*g@zru=xbH6?DNc^MQ+z)07PC_DtK>;7+uBMZ;4I{F+Zm54IZW2|k?@|%z zQp$YIL?#853fPZC&@gAe$yQ8XMFqrxB8B!Uw$3#t#T^vJp+4D~Rm{`I3F5ts!Vd}S z8t(k*{2x5Flgk=94J?RqN@9w9Fw?h7=|0`2r<08f=XrXMMiEn~?ywEF!y$&7kO*a9 z$-X`pm$5KUI7Zeze&YV1*dg3$`u>7wHZg~cmWK*TO&IaQp(MtL^J zI-$to3T3#@;<6l(1ju(6WmJmH!>dL!LZGz#ddcyXs5AH#xAVl)`VlFT2|zJ>m7`GW zI4i}{6>U7@k_v&=FsScF5YmLEUBhVh5f)5M8{r%~y93e9)^8tcf#iL!7~m4}YgpfT z{WtWrKP>4Ii3_Ryip!}$5OJYhzVa3sn2c@sC&l3bV+Jhd*n{C1fknuw-}f!m4}Uyi zngG%Qdob!>fQ$dA(vIf42+T>cq1{1>r=5YM$)k_YPMC+$1ZzL9>()eOqneDviZAZD zgjKMkS7#&!OEtVPaK%>U8GsFc7tH_g9V)P^W9Tpq(PS@|HpqPBNFcS`C*-1PH{yx= zD3(tM90{`6w(nzo<42Q=xgdo_mcN^e_yi+%pVU$Q_2tUunFZSsqVIs6<+ZNR^j5Ke zldVjh*Af^qWz$jEnNT}i`h;k`^feHo?|L=u_3~71IAWQ^p88GZzxvSP!hlbKE(D#l zy+AO!noOe_j%J&UbotVcqOnu?U-x^XTi?q5^)RT4NHO${1HN_j^inGM+_c-MIfKt7hT3wbEn`kb4Yg+*?7R03XdG2qFHF5;a~m?RAlGwB{(Yk(2_ zl_t;T6C?rhmybq6Yu!m`)l7ICj|3}3b!wfBLfD0F%hmSf$x&ax$(R8u%crOWFr(*h z6aGTGDmc42UShR*!RX2u3p>DX{d$v?Ks@l=c=&k1ftE50}5+*-YNC?`b2J zSHIQ3CvokgY`z}lVm^U3Bh!PD1)&!9m(p zW~dI$XL7^VUd@KG^qM&I(sU$}?jQKm2?P}G%4ZMWauEbhnnRxg9Pq={4L1|p%k3Xq z9@dlUsehE=U?ED%rjxB4Tt&=7CoP6?P(xSUxE{q$e#<4=KJM?^oJo@JoY6|-kQ-TD zJ9?y1ER6fE`&e}*{xb64{zV--`$H!jU&wu*0765&!vH9x_!j3?RmIPu#uG@1V`cH> ze8M{88rTH}1E3Cey(hC&d>U3lj6;Hr`t>aI3=%v#QV%=BorRfiia%^rkBa9L8~T2% zUL>U}g%3VV>JyUg0!6Z2YK6w-!7OLdlMj9k)DSlj$ywd>`taZH7-yJNwJ}}#MF+u#`pvPz&UlsKBj|G1SL~Eb_TU&^aMt(|nT*q1KA*O&0f4XOseN8-yEJGkEZtfNF#gAC^KKWtlv62qn7rHlx!X+3EB4l!+;)> zNr+dBhpa4nZA7PU5g7`eup5-!=_FXQFJYFa6u91q>@;5x*dv*nn>$nX5`HI~`8j#a z!F){c1>Mf*ULkA&YlH>ccp2lb?Lnj_i5uSCfzeBHjjzV%aQx(CwXN|Zj{_E&3FX{A zrPq#BrL64eBq}`0xjIrNCb=v@F}l#}iYYDHovtI)xc?rgbE zP(%cpkd7d2E-d%LXWWVaEA$U<6*v&dR~ojgkKje@g-?sUL>X5%tT+QTlH|TT7(&F0v zt3vdZ`KGJRPX3?dy3oC6UP(DGsdCIIVK?eW?&@JB65ccz23Ljo4cf7fVS=*TeE&)LtbDfwTTE0lt{eE<0kt^LG;+UZ}F)K0pB*Up?CRr2EaE9d^_4-KhFm zS-5u71^E=t3$8ur*JzOw(2fCA&Ly^)xcr27Ly&-DZ;+owSVnLnhQXEsOX!KUAQUjd z)s@+ox7PyVz#>*Vw&BcdEsH?A=Lbw9(fkudsSsjgw*#-s|;v-5Kb~N@W zlohLEt6w0Y4)5O-gbLY6f%lN8TY4sd^Rt|wuUZ^tCCmg!2IcOD48-L*Gjfj+z~MB% z<4^C&N}B{6M33+qAGls%h8gg-vj9Oy{n|7XSV87G07h7zM+EKZ8^Dz})4IqKbb#`g zXL^x=Wb?DLGED&Gr1>IdX&q=cg0`oMHtS2v_i&u%DZ_WxE*Uw zbO^qG!^b$)O(wF!b$Hu%z>6h(Z@EARLI@j*5Dce}lN$Gpl(!x3 zwAD*kCYDOL~{9TSi}iX6)*{Af$04l$07Lx>sy65?c{U!EV7I=C=A zj^{C9P(*~M+SKbQe40FcTVELVU*|u$1Q;1?NA{hlb5U!iI%hGfcNZ%(w0W=PV^rzz z6z&#tyFz(sGELm-KDS`t(VKS$qpnlR94%z$@BPaX^Vyb$YH$TadBDnd#&TsI4S?T6 z#W#n`KkxsU4<%1839O&R_ig-ERhyiX6PZ_w#ricq_J$Gua`zwpPu*HLAgX>32?tli z{kVKzCuZYx=%8XJ<1<|t>1=rGlmTG^=o9BMB&qT$5|YI{0ztbe**(0qD6UF))%E+f>>AjiOO zJCo}Ujd}Csk|`o0q8w+IMdO6V#v4&%4~H&a-*=#phITsofYB%LlsEb3pOheE= zf#HMG0DVfY9h`eKrx)7r(~!~aaKfUUujHOkR_D|=btYzS8?P_(lW4@U-Y8K)^RiC0^_bP||1=S=?bO^Ypn?mn`10vX-V1S@H38V9Hu!U1PfvLlPRKTVs`5 zhmzKj*0R9l}05BxN2(M_Qs-K12^M`#3s*?iE`V7T-u z5tm#jIfes~vb0VO|2e-x86)*4RnSM(aLEjwRP702QUY0CxkS-`SwkO8jIPyUnb7en zbJWhbFdO=l?eC6XhqmB$&U*P9so|C>w>dKKgDFevUim87>f z=h@4&7e=l1LUOwhfg?etfL}UCnw{Jqcv1Tw@0elAO-)=bnHhRlMX~LR4X%VKp;285 zAt51+W`lT&?~33N> zgFDnrM6yMaqydXqiK6)ECzPR?CGi?S!fa%-CmTwsT)jecghW$I7+Ny(NH6mI5`+0^ z{m9m$yX&9spBK z_WBHSYI`885|$wZr1Zy7zIm^D9zO~Z%HXg8L-%<;P+|>ci?5scBAN0~3dd{K#VL9R z(uqipj5oU5q9=;Bt~u1NeXZF`Ou31##dOMogOj{j^2v@{HxD#OjHFxzJ1!yl7#lt3 z`1FtFPns_C5L6(4@?i|G*~50@(~ zD4@s1b*AVObXmXnt=U;+KJ=d56$uF2wP-4Q*M}*%$YeX9E+e9p)szFS?gwfwn!SJH z`SKTSXG8^}f^*fDqctvei}i72{39Y8xRSEfN6FGqRH*@19peG~MA3e2Qn2?@4t?_O z1vTLMVpajEOia;-?|2(dcmVk66ZUz`V9GRk?%?DY%CATzu`lQ__fD3MoU*|0!PU$X zqmXp7D^^@B(Y!Z`R3THfqU&Ej6VA9oQ{gw$koe->ctPkhxiz7zGxFG$qW9zC&INO0 zBDC58JDN;PSG|GF%won({zszdE3xcR#s@n-vS@c9(k*3^DRl0y1((N5-vQO??O}C~ zPTbdWyFY1Jwc`mXCCfIij(@UWYlzT0g6|qJiWDd{olg}dBhWh*%KC|c4LxBJ&mzi6 zsJzyu+#)}{D>u25E6PjtV(#~6tMR;$GU$$>&k=tVwFDK&Gc>xR2FtwSW44QeRSKAs zJ=~lvP$za8svrah`5*pkdBglSYT-yu2=6C4W0yqSH@G15hs%zl52d44^RnSTm5g)8cYr1fkw6qR$*D*ffI;8uMUgZK_nAd6JovQ@&U^(@YQsgEqFn za0Lyq^KMCGutjf;|6ZR&R6h;jVj=zp7jF}1v07f*&q}~*DlFtv$i#!D(AoEhdK6=_ zq-L-znCG99v?yF!;VDJjz)km${lfSOwZFDHW$It&1(Eg#vT}<+F-gOL4UGrXDmGTf zfytcBQcVJ6EQ-{`-V4rV99}jkKi-?F87X5PP;1tLaf`0h0ITW|V=4<=ss}x1&$()c z)YQpMpO%omS{6OKUb?2{m;PlenmPDQvS?=^O-dwT-(9D{Bi*ki-RhDq0d$1+FKGFO zBT|jQCrXirwK=s`L-Aq1}jNWl?;zrG3 zwy26@|KmAAbyec_@b}0yvwaZ`nV$F6jA z;1@j!4(ZrF)U->HuwHf5jq1^<$hs zY)#$soywA8mSh=ol$`le6 zIu0h#9ur>3;1yO5k#*{)e8sHO1<-tvs;20SfCoYjZ!ooGh&>nl*WlIRsEAC&Y$5VU7s%*KaBdl zJYh2@i2^lXMS~eQ3A^7(OTi9)l4x;cHuP8}OSH5B1E28&!4=ZTMqywe+_1H_>@^iO zbUmCAbv4%Ohj2clJZJ*0d*DvrZqhS*|F$&DdaBxf+#12O=e`-uZr9)i$%JuXNI#c1#TZ5rGP$EY#bO4MSWK0C6nZ$EY0NqrTk~~V zh6{%CzucW6lr3mDOA3?$nuBbhI@UXOwvS#V$Akdw{Xm7V0&A1UQN$#%_>1rNq8-PU zD=p^_hI&47uFt|06zfo?x8^l3~0Fb6ucJR6+1{@*7e&s5_Dd_J_lz zA?mgL<)7d8QH<4|&t@ck8F#=Lc>mBmuV@uHDEkoeHvHw4XT{zQ21;J|F|j_ZD-=7w zpg{JbnxgNOq9h$fr;5Z=Ffz5T>a=TL45f^-Gq--m8xI6_7JvC}BNo5Sep~`#V%y{a z2BN`d$Mr;<2YvG)1asO>6DUsaUY>ycg3T9!z9dn4vxUaxB{Gl8-H(ZhiDATwhl>sP z22CECSBDXV)TXzmCdOihG`WVfYg`#vNFBz?hAdC?uq+p&0uf5zQ2IRWci!F&x9RoI zDYJo~AZ%S2UQ4&F{2;WCd8W2kc+&FyM>IAQpE%I-Npgl0wGf5T9~z<=NF>n|p1{Bi zZq`$80lg}-@Ulrof!_&gHO`G#PWhN{wt?n4&hVDY&EDx*KQ$Zq-v`lG{`!TwXFY)+F+0<_WeO?zbpGfs(QH^rl5F_)>0kJv`){?W;IKQY z_MKjH?(D0B8Ec2fz0vo`U0gyN7x{h*e^5fC%aWQSBBV~gw1D#h2>!9@CYpU3VCXHq z*KA}Cta{YUAzJf0iD>YzT=^B?|9od@v(oA}Zwc<*Bs*#&P;aynb;cu02v1a*$Mghb zqEB^HEx3zD(s!4LzbQaEb+&t2DmlN=pjH<3K>~Q-SC;uxWwId$Zf)R*3=i1Y+Wz)9 z(mnI}`qBR_S|yqh4GQs4#0xdr?eEWhSO>uZBMIsLKMU(rv0Bj3(9wI83TqdSQjQl_ z-P@W+L~^5{8?U2}N{iv$hP9pDPP_3{!o=ZqPp;KP1XBx547bJ>v%ZLc3a9XW(mPha z2SYj*ZyN=72URW}bCc9r*~a*oKN_ErRZXdH54Ni!tP)rLd~iptNd#5P`sJwQ`tk)( zNe!}de>2|@doH=B?75`>RUf-Qjx{NO2ZS3xGtod7`TH4yBQX(!tR{>2{maX$6nH+^ zAv)zQher3JDcf2PTKHf6(Cg^;x;uRQB45Gh&yK+-ZrluBK8NaYvW)rF`pU>*C~YrKU0xQwyfm~znaWLXrvk03D?ZY5 z#aXPrkvwuXU{?c!%;N}bvO_wHlB5^~3nAh?I-Bx^P#gl2#SX38~MQhD`F0O_N*MHee?!wF0s;&H`nK}DV4DZ(f%Z=x=FedKPMj&? zUd8GIpafND*gN{t z_*lSX{gGESK}RZ%3Dyej?}QilHxEG&ft!n>_{}i*i|R3Kbl!FA-#MD@!3FC5FYRZU;tyt zl8$D|nF9m}%dd^eVbQ-wiTj-iS!M@RfV6zETc*FCAS4Jm;XfzL7@L6dFuxhvA$F## zfJX#laZC7mDE&3Jn-ynlKQo{Nd4z9n(rBGbm-UC^l9LBK18(Mrr-#e*EyQ3F5HDnJ zdnw{OR7o)k*l&Oe$Pr_)&U%l7_zR)^y;<(UTLJK%5}AQhkmc%o&SDh2BWQmOXf3e6 z`|l6yX(+}bFzF`5fzPBrI&7VF)}n0%8#d7_pomM5av3%l-z_gHro}1rtcSRyyu3y) z>OJT}y}7-{0#YN8M6t+BI~?I0H5pFpN(}6N@ClraygX444h?a8of?aZxR))h&mkfk zZbZUPuut-z?~Doxa^C}O@Q(BhfMeHob-%~O?o?_0UN1QWSeA=EJB%VF5%;YhRx^hp z&H_Sct=V?K*odKXd9k<(kl!Bq>eZ?8gWZ1iEEKMTW<=~n^l-jGJqmZU2aYbq{opGo ztvD+3Gcf=tJ63?i(qt!iWo|1eqzUd8rPcgGF2y0!9wcZvxJ)es%g!ulXBen-(gN#!AA|6-k z5=+&od-^}-9}>MLCP8mic}98e_Za!6MAqH}R8;GQ-M^>9>zL{*T5m`jg#h~H`x8_R@WDugec;T z_b{X()Fh$sZ(8rs%+2qL#`OfP`jK3~P)5Y5hz_x)_$SMAL(2C2l-wh>&xG&Rnm}0=pwJMUz9u-`c!atxeC}#=r=bN|7#4}!pBvP` z2(0bZfH*>mD!KS;=2&_P5x20f7^JirPISZvL@(mT?ZAAsk036t=BH2i?W&_$VkO}C zU{OlWrxzCXio7?M622`s>^e=|(HjBepQXVuhZwmr;RpHUe}3B}KY#M(o6o%%aFQU^ zTSW(bLh4P>7-fW|{QdDmR4JuZ-ZImj2tpGYNzXVG9^?<^ogewg_{Byg+f_g(!DvZ# zW4*t}8wD6n)T%oSH@SZdNRz)ZgG)8{80M2jG7t!(zAXPv z5}E+0K3wmN&DYwp4LBam{G6(`RB;|tLT;J}y*N*h9EwkN12vh_rj7A!zo~uupaHBJ zIE1H$vd1dNP)h`W(K)&8Oa%nEJXk<(YFit*XO18T*G%GFTv)Q5&6NP{tG`)dj4VqF;&v%r+oG&cF zSIJOj1pLLQqh)c?Zb9^eYwh?91p$tRmhEK~ekllg&pQb|vM-m1))vlWJQu)UetLTR z8C-aFy{k>`zj`l^jQlo>+Uu*k!9`Qwr?l@$@!V;r|8w?WVaASUVcp179R3bJiSu) z3TQN>Hs0(iI6gm}e7#t#gGyjh2>lxQ)PAIJP6)b2XAiLw&vQ;$-eF-@y#M$hi^<^= zTMDCT^SWdpa^f5#VoU-j2}a2^))y8^=LT&iQ1~Q|W41HGcT}eet#I*_!Npnr^LPzp zG;f%@@Y_?P2v}ojB_2=V4ZiFZR<*tm5)!(twnM;6LCBwwhzJibrBMD?*SwhH+5Lx1 z%#ahLnnv;dkqI?1$>6u|zE5IO5e4fuKPFS;EGX9bo4U*333$X{;N(Ux{-kDavLE`2 zgIT`}N$lVZkK{Sc<7i=gfBFY|9J>mI(YGG_cFiA>7#$yxhWl`n0BCaXdEIV!3cu4{RKbo@|dbCDV zA08v$X8~mRzL88-h$tG=(rv#UtooQL$3F_K|dX zZ|26Cbt0Tf_x4m2&zW~C(NSPcZpt&v3IhX_KvjEK9XN{bgJk|9lt;#49hV`%=y9F6 z7k%LuD(=TOJX{d{1n;y1Vh@tD&Hp0UXcBH(|1`)qby0{_G;SqG(#+S`4;2pyg=sd} zGqLfGym|3GH@7k^FSet}#D{$k^RJRx&9FRbo9zwxI~a_s64NbM;g-g2b7>{wypC{n zu(IOzdKom52R5K*-7zFTZU}KGg2C~?daW~rVM;QKv= z%>qaL-n|Gti}x9Pac}{!+XYZ_PVkP3%77y$Z=&UTeCM9&^c`A#%Q`QJ?o8fel1C9q z#PU?dg(M=q6bhiGP3rp`)pEaH-U4eVmUKw)IGPn2j&C)yMkTzNOknc|vv4RX03Law z_3181iqw?eIu$rq|BYm0V`DY(bTgS^GJ zn5m&>%O+mFa#HLhWT#e2Mo5oc0Pxd9%3L zzhwTWLL6RAY5! z+T}ta_9gKvCN)RXU!3O?iI=-rRC)*1sA2;Ab|!MfA({CoFS*jv(p)HqwxoOvMPYHa z|NJ-HN)Y9puQ$mzNdt{Sxvi}hykydID0MeOhTw|tWbnKdm#+dd11#2#puEF07Wag1 z$@gM-KH5uvX~APDyZm-REo_h;G}Vm<=S6y$mqR@m}}8XB@g$?UwjP%SdL z$afZSUNc&8`@)RMSvlkm_1uh6UM`M$#gX{YU&sY)K3(BQdnpqaJB%sKJc#*R7yQ(# z(^XZ%i~(?Ki-J*CZS~%kg&xlR4!XZSVtun)Jsg&z*t0DZv;8+ML13kO=$$(0nHneW z{=W6@*pJ=*xYx;3>hP9u3JkDFJ19}n^65aC=2WBmK@`au!llnT^N%?Y?!H_bOtQW( zZ1TVaLn7sjo6lglG(fn3G*xB-O=vFPzVJz$8JyRcg^5f0 zCnLY4MF(XH-x0g(?gWyvil*l;EbK?L&rKkg3xe0zHQuAyFG${>OytZ&!D|d=88C^#fMx-3nhPe-=}`&V$4Gh)+AXh??|8l7sXNPwcEWnp|EyJ2or~ zi&8|kZb_WssI<+BPf?xP=Y5_@3EzC7&a9F5RuTbP2*$L6rY0dKnOm9}ZF!^_9R(|u zsMoJt(S7b9Nm;S*8=OICLZCj+I=#>O@L0wPcwB%??2FqXU9qjstLncck-TGB%l;4c z!?+;=pw$oVwu%g$QyuRC)di2ElExxASFtHqhQKiYx3ayaBGc+F17Vh58JDw`nylMl z5NAhqu_mN&c*Dj+5-wxl2sF@tvhiB{%>e_LNzfuyk(E7ZgSJJb3)r*Vqgi3fAG`d% z1kVrIRwR5G5yctL_fU%a04{+g=*yFiMK|wpc%4ObcUZCOcdn(X&zHO7ZX&}Af+QFd zPuQY3pOB9OBDXYQw}dXUjG@8>=%EChyAyzz*tXx%3J;GT0C(4_z-RbV8?ex#La zvIzq4oRYHWhsm8Bj{$)D;amU$u|E5P(HE|TFw0<_YKu75BB}%aT?I|M$~xHgDD<^` zE65%dgF=CED!@5fhRo8qBM@n!uvQI`*5;e?6f_(9+^~JbDW>6n9**_eaA{#`%Vqqp zW%L_sBsl-ZljR3D?{((VIWRK+@35!B_Zu+QPy+=~y?>o)S}x;AdpJI$6`0P{fCnmC zrqd57ka7Kt>j=`eu@e~8Lt`k}FSru!5qG)Q(+J<3g0;^FVurmMcA0X`!mit4Lr|9K z)@K_eKRZ)5AqqbG`8LMyOp-5Q$MS@IjG-XA+|{T1PUXB=ps7Zp6+ z9b&!qu>Y||57uI%JL}cqzsYYA_Q|-TL1r!!nFuS`wbs9DvRrJ18l*rCY22{tQ2aTV1hW->pQEBb{y&6avbyrm1G{ ziyHTDUQxGk0}0Gl9V5yyP8712jZ12qXyN`4cgF-b$4Qa@y_EM}5Ai_HzJ&5Zt_(8B zamALXWQ+eZ>E5V8M)!LTA@1fyj!9e&H-x+WF{As(=Iu}lr=b4JRWS7Aybq?16E17j z5r{Zd^nrXyP87T|RD?%9lTL(iORC~~dsfke-QQlICs|gmpDA$ip5$!m(BbyUzY)B} z$r&lr`IJu@W8ldR^ zEih%IDxP*d6asr|Eyv(qwAaA=hyMh6A9dw~-VtU}8cm*SxK-v-{3b0}EQO#cJLM$u z|3gJG1K}HS(nx1o zU??o5zcU2A6vP)ae!F9TiI!`IN5)cp`}Xaix!k(hIY@(4AC}Z6mc~9|4}*EZ)}0wM z=SOMPG0(%K;x#VU?e{KCOY2Z$Hy?6Rf%O4y`+GhYAqqS~y_K9X<) z6(=|M^zxC%_bSb@um3F?7r%!iPtpNiCDQk(`0XTmJ=Qtp`VH}*l7Fuvepj$o1Dc}N zAY!U%O;$vHmdu9hDZj}db&Ky)SZJ^-@$y`^##8*-*%KaE5;K7YZrxc3uTut0ptj4% zhJxXItjG1yiVFBq%GG}_QGIBIQzlk&aLlha57m(q^&e0z{uf0d9Iu=uYVDm#*T|$~ zk9IJ#CDg*nb|_39GAInPzzQI@2LB<|$x|*Zu9Qx)+>-nz1#Y3I46DKCCcY{yjXuJor{AQ)RE|2#J^6Du(7+`^2T1( z*{cs@Vu_hapXz>A@HrjV+a>rD)9}?Q<_uez>=t7-RJBj}(Oc!oE zTVEcAGqTD1u<(?Tus$EE8EgEu`{|z=2AOGLO*Y2_1k3kF3w6c#jLK%R6%={+g=v5; zekH?ZIJey#S9oN3WR{-*Z!5fwxBU9s*)}M2zQMJ4n{R^bjIOL@_Mq_7^P?rYVtmxh z8^jQ3LJGF{x3&YhufmC3%cQh{7%K3$)D4_uETP!cav()9Uh?sE(_8MO3Ul+ht6@Q> z|4!`*;k<vrf8hXEG6FfH{?~vfMhUqM8Mp z<0UnaoY=zF#5_Zj8<`So z4m5?kD*w-i^Hu;sanTg)-EkS0{R52}OnlmEve|&?+OU;nUh=n)E|mgbCH)c4FXMTB z=I{8`Mvy4yS;gql#tl0h=_tupQbuMgE-}~r69#l*x$Igm{Ml~8Q1W`mtgDiQC?H?; zeElb^6!FruB`q=YrD;+L{;}|Y(_et+V||vgnWP7w8o2qS7jK@Df3m+nV=_l;VhR&~ zV(RV}T@+G8nprJ`suFoqG;uA5QVohp~BIYP;4)-811;I;e1CLqOx^kDR}5 zKWPrun-PCwE)RI@c8{<~z@t`mAx(cKU+RD5E79$3I-guYPf<~YR_wLrz&PIWCr_?H z)sB_&MMx*53YEBqNQekGd0GKnLCrH&j~F*7#|R!K|69K-A@C2=%GpQLhewRSKr#YB7!cta26 z{-y2jHZ0jwNm>wf3u)ub3>oi0eSp?c^#=)Dw~&7KiMyJY;BLNWW;$ci`J)0e!;EVv zH+t{WKA!K>SKPX@4$G&4GcG&HWu;_&=4TTqhkACGm=*y#T_M zYl_cH4ogOv{jC@N=(nKRR6l>3ICpFpRA;U}kPEHMP!=zAumvshJN<_u?F-!BqK)9? z03|mN!YI$vV=nqP-@Upj85bpDB6z*q${Mc0+4rS6SDK;51E=@1J*}~?QjaxsM8W%* z_R3M2VT)EfXAOg_T##Uk?3Q_@`i<1xfzmd~=%3P-p9aEOK~9)qN<*2Y_m%u!bCo_m-8pLW}*`yv@sf)!3BS z5D^@^Bv#CBbYW1Pj@llj_M%9D(dDTly1%?>SGR%Lx%QmuDG6=Xp6|@%?^YoZX`!6} z8@OOu%Nd)t1)bWfLs>z(_tx25no7V2NvbWGjkJNm1#y6V6n`>@y;PEUVMOR`AxW5p z^9>1MjPUbtn$gu-YYgHE>U%oMi2_05@8x!!3_aT5TiC$)>UYkzuY?%MfvMdg?%fyw zP)pTu5a+CP%*ZYN5z1wrDhfNLK$2{^CHckMMb!gy*UsxTvG6`P59!&hn4jlqXuT#H zN~Y!d>C>=D#dEu@sIF5>=s&$=4jB@X$xGnsMnU?aHNZIJGTh zJP-W^?8u+(9C)@1A}+9Z!`H7)Rlfb5f{|i8CsFU8pJmmlJb|{Dl%>q#V=^2S`_D1szBs zXk*F;E;wh8t4AA1K{UqN@`dC@7ODU^GNh6yTIq3ypr5!esh+dLp~vwVE>~b}0Mg$SVgh?xC2qZ*hK|GoN3;- zSK^z}SR)EG(D@3pLu1(4X$)?PmD1I$MN$Iy2bFBd&wcyl;WmOyWQ)jsDX=vEqIaT8 z?KOBasGPf#K&XkCW?B-u)LN0TRf{3Si!r|bGN@;+NMF#8BDJ4!aUEC~Ie`57HWUy% z|B#*0V;_IX`0!^o+)dXpudQ`B$?|RtG}Ux6e~M-`yUk~$q6BRK&c9Yc1d~x|Dc{t= z9BZJ;GTO#T8U8?p%Q*l(699>izC-g|zjo_5`T{u0LW;>A)%0HBrx=uB)J3QyNWh_i zHY%1)3rm&G@pz|zz;`-9AeL>+2AJG%adLcTyfnA53CP3BmObhB!LuSfB?onGAMNzv z>rpm<$TH>+q~fj%-E4PM?~7ubfK3hN#zAhHI$=sE!{E>`iwto0O+)q0spl>d+Wo;SS}#vQzsm z4P%5~;wJdbFD7v Date: Sun, 3 Feb 2019 06:32:47 +1100 Subject: [PATCH 099/153] fix: Improve 16x16 icon monotone transparent --- .../static/assets/icons/icon.png | Bin 2146 -> 1614 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/packages/fether-electron/static/assets/icons/icon.png b/packages/fether-electron/static/assets/icons/icon.png index 70e557ed8c3e48e7e7766ed075eb030ef899264d..ec30bac9cef34e05620c163c6dcedb0f9db6e06e 100644 GIT binary patch literal 1614 zcmdT^O-NKx6#nj;Nk>OB#8x4=j3^K(aM7Y%M1h7-(WcF)BTdeXGBc7x(8jhw+n{}$ za$%8CftwbAErf^`ZOYX|xJXU({oK=c?!57*jSwyBUe3GUIp^MU?mIuXe_;3u4C*7v z<%pvc60wX+;tT1yNGwr}?mCR5lg&H%tg|u;kKAnkz@?$$WT_xXku_)C4&XSTCl03O z!Avz<>giQG`RQVg=etPF7(@nDWKlv7dI6^|mP^zn^Ohrqbg28}oP#U8Os7L4-N0H5SJ4Xj?2CL94-2;qzREk8yB{EP1`EI&N#dHkFfj9S zpVscl0^Z9l=VOsJmK*|>oyY4Bal7g==H}*VbVY;=_l>#t#r6p>3}q>6$)7$k#CxmJg?cSM00FjHPCkAC Dx){BN literal 2146 zcmb_ee{9rL9Pf;qfM6yd;#90R+F-5a;A*kCa6w2ouj3$V>`n&_RPUMp*ls2s>b$ZtxiZt~owOCMD z)rp~u*}TFY@J8J1%>j>ZVu>$QBCr!8;xC_@~1nrk|~XDC6lpOurLz&fC@F!3i6mcW)_M=A4RDEK?4qdlN_f2LE(i50bWD42vu#} zG4(#euQ9 z@Yw!DEY|AUhMC0!UR%=wGSL_lfh>wN7Xk&js;VR`&xe+V67eX7D-<$KU6G|Q4^kpe z>xLxKJizvn!YPq91RzHY!w@53VRU}n*17^81oMkqLbo-{@wYrK%r+Etikazg2pJ@}?RK2HR`R(;hA0F@DEFYbF?;&o@?gf3;@S`_(`ARMK^Rff8 zs;4eKvGUi!+S&?YQq#ihr#C%J+(S+r`0UIpwF}#~cT`pqCl7YisN3G#vG-7XXlu>L zu}xE_5mgue9DHtGTj=BaPhF@y`p36(Hcvjgd;521dgrX)`m*=b{+Zgwwx!cnx8#Pu zZtP!L{qEsYBPUb0TJNl?BA+<<($cq1Tzd8BjE>G{MpUhC*7>?O4}SFlsM)aQ*f!8t zyXR8nx{=?0oIXD>_r7$+u(h~**YK82wdU#Sahd) Date: Sun, 3 Feb 2019 06:38:39 +1100 Subject: [PATCH 100/153] remove old 16x16 icon --- .../fether-electron/static/assets/icons/icon.png | Bin 1614 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 packages/fether-electron/static/assets/icons/icon.png diff --git a/packages/fether-electron/static/assets/icons/icon.png b/packages/fether-electron/static/assets/icons/icon.png deleted file mode 100644 index ec30bac9cef34e05620c163c6dcedb0f9db6e06e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1614 zcmdT^O-NKx6#nj;Nk>OB#8x4=j3^K(aM7Y%M1h7-(WcF)BTdeXGBc7x(8jhw+n{}$ za$%8CftwbAErf^`ZOYX|xJXU({oK=c?!57*jSwyBUe3GUIp^MU?mIuXe_;3u4C*7v z<%pvc60wX+;tT1yNGwr}?mCR5lg&H%tg|u;kKAnkz@?$$WT_xXku_)C4&XSTCl03O z!Avz<>giQG`RQVg=etPF7(@nDWKlv7dI6^|mP^zn^Ohrqbg28}oP#U8Os7L4-N0H5SJ4Xj?2CL94-2;qzREk8yB{EP1`EI&N#dHkFfj9S zpVscl0^Z9l=VOsJmK*|>oyY4Bal7g==H}*VbVY;=_l>#t#r6p>3}q>6$)7$k#CxmJg?cSM00FjHPCkAC Dx){BN From 9757370f1627436690d0cf77e84a1f676959f73f Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Sun, 3 Feb 2019 06:39:03 +1100 Subject: [PATCH 101/153] add new 16x16 icon --- .../fether-electron/static/assets/icons/icon.png | Bin 0 -> 1614 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 packages/fether-electron/static/assets/icons/icon.png diff --git a/packages/fether-electron/static/assets/icons/icon.png b/packages/fether-electron/static/assets/icons/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ec30bac9cef34e05620c163c6dcedb0f9db6e06e GIT binary patch literal 1614 zcmdT^O-NKx6#nj;Nk>OB#8x4=j3^K(aM7Y%M1h7-(WcF)BTdeXGBc7x(8jhw+n{}$ za$%8CftwbAErf^`ZOYX|xJXU({oK=c?!57*jSwyBUe3GUIp^MU?mIuXe_;3u4C*7v z<%pvc60wX+;tT1yNGwr}?mCR5lg&H%tg|u;kKAnkz@?$$WT_xXku_)C4&XSTCl03O z!Avz<>giQG`RQVg=etPF7(@nDWKlv7dI6^|mP^zn^Ohrqbg28}oP#U8Os7L4-N0H5SJ4Xj?2CL94-2;qzREk8yB{EP1`EI&N#dHkFfj9S zpVscl0^Z9l=VOsJmK*|>oyY4Bal7g==H}*VbVY;=_l>#t#r6p>3}q>6$)7$k#CxmJg?cSM00FjHPCkAC Dx){BN literal 0 HcmV?d00001 From a1aa02e56af8ea194525ec343328a0c0ceac6ee7 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Sun, 3 Feb 2019 06:54:26 +1100 Subject: [PATCH 102/153] move old tray icons --- .../static/assets/icons/{ => old}/icon_white@2x.png | Bin .../static/assets/icons/{ => old}/icon_white@3x.png | Bin 2 files changed, 0 insertions(+), 0 deletions(-) rename packages/fether-electron/static/assets/icons/{ => old}/icon_white@2x.png (100%) rename packages/fether-electron/static/assets/icons/{ => old}/icon_white@3x.png (100%) diff --git a/packages/fether-electron/static/assets/icons/icon_white@2x.png b/packages/fether-electron/static/assets/icons/old/icon_white@2x.png similarity index 100% rename from packages/fether-electron/static/assets/icons/icon_white@2x.png rename to packages/fether-electron/static/assets/icons/old/icon_white@2x.png diff --git a/packages/fether-electron/static/assets/icons/icon_white@3x.png b/packages/fether-electron/static/assets/icons/old/icon_white@3x.png similarity index 100% rename from packages/fether-electron/static/assets/icons/icon_white@3x.png rename to packages/fether-electron/static/assets/icons/old/icon_white@3x.png From 2819f62e5d02bb524e968a1b6213493f4c954942 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Sun, 3 Feb 2019 09:02:54 +1100 Subject: [PATCH 103/153] chore: Tray icon rename old white background icons. Windows use .ico for tray --- .../src/main/app/options/config/index.js | 5 ++++- .../old/{icon_white@2x.png => icon@2x.png} | Bin .../old/{icon_white@3x.png => icon@3x.png} | Bin .../static/assets/icons/old/icon@4x.png | Bin 0 -> 9430 bytes .../static/assets/icons/old/icon@5x.png | Bin 0 -> 20607 bytes .../static/assets/icons/win/icon.ico | Bin 0 -> 33536 bytes 6 files changed, 4 insertions(+), 1 deletion(-) rename packages/fether-electron/static/assets/icons/old/{icon_white@2x.png => icon@2x.png} (100%) rename packages/fether-electron/static/assets/icons/old/{icon_white@3x.png => icon@3x.png} (100%) create mode 100644 packages/fether-electron/static/assets/icons/old/icon@4x.png create mode 100644 packages/fether-electron/static/assets/icons/old/icon@5x.png create mode 100644 packages/fether-electron/static/assets/icons/win/icon.ico diff --git a/packages/fether-electron/src/main/app/options/config/index.js b/packages/fether-electron/src/main/app/options/config/index.js index 4ffd40f77..39396fdd9 100644 --- a/packages/fether-electron/src/main/app/options/config/index.js +++ b/packages/fether-electron/src/main/app/options/config/index.js @@ -17,7 +17,10 @@ const INDEX_HTML_PATH = }); // Icon path differs when started with `yarn electron` or `yarn start` -const ICON_PATH = path.join(staticPath, 'assets', 'icons', 'icon.png'); +const ICON_PATH = + process.platform === 'win32' + ? path.join(staticPath, 'assets', 'icons', 'win', 'icon.ico') + : path.join(staticPath, 'assets', 'icons', 'icon.png'); const shouldUseDevTools = process.env.NODE_ENV !== 'production'; const shouldUseFrame = process.platform === 'win32'; diff --git a/packages/fether-electron/static/assets/icons/old/icon_white@2x.png b/packages/fether-electron/static/assets/icons/old/icon@2x.png similarity index 100% rename from packages/fether-electron/static/assets/icons/old/icon_white@2x.png rename to packages/fether-electron/static/assets/icons/old/icon@2x.png diff --git a/packages/fether-electron/static/assets/icons/old/icon_white@3x.png b/packages/fether-electron/static/assets/icons/old/icon@3x.png similarity index 100% rename from packages/fether-electron/static/assets/icons/old/icon_white@3x.png rename to packages/fether-electron/static/assets/icons/old/icon@3x.png diff --git a/packages/fether-electron/static/assets/icons/old/icon@4x.png b/packages/fether-electron/static/assets/icons/old/icon@4x.png new file mode 100644 index 0000000000000000000000000000000000000000..5831c576b2c749c6884495662f49ec7bca57c48e GIT binary patch literal 9430 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 A7XSbN literal 0 HcmV?d00001 diff --git a/packages/fether-electron/static/assets/icons/old/icon@5x.png b/packages/fether-electron/static/assets/icons/old/icon@5x.png new file mode 100644 index 0000000000000000000000000000000000000000..7d90fe6210006212de371179f21868e28cb7a75c GIT binary patch literal 20607 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 E3uT4g^8f$< literal 0 HcmV?d00001 diff --git a/packages/fether-electron/static/assets/icons/win/icon.ico b/packages/fether-electron/static/assets/icons/win/icon.ico new file mode 100644 index 0000000000000000000000000000000000000000..4f8aa555b83d76d2fdc4872299ae9c26538e5217 GIT binary patch literal 33536 zcmd432|QL?7chRzp%6kLGD|3>kTJ8$SVTpkgbWcXGA2Wri)1V$At_^ImU#-9GxQkB zOyn`0|K88-xo`L0>Q?Xj{l9Phe#<`3Is5Fr_TFo+y`}>}2oMs4h6Vv8J92>-L39xW zVPg8@w=X$@6oGr}?0@`z4C*OSA;|9CUw(5V$kcZ50s#2Fg*1YMD6992AK0c1V zfBzo;6P8l|LjW=X#J>m2EdWyit^>ru=g*(f`no#w$&(axYHAXH8(%&H7x*@a!S!wY z16Z!EuAqYh188}9IT{=sghoe4p$iKOUsr+Gp#b4{Ck@6XTAqut%zxN*OE^9C&`DMp_@O-KFwd{OxOZ}1rW z?!(_(TU$dXCMM9Ho*pzK<0llF{rvgQ>iGBnq#xc`TwFxowzs1d73FATya~tA+0g;suS7#ag3&u+ zp>vC_{L;o>_U{_lzW{%@e+S4Aq=X1T+zIe4{d)=P!gt`i zP|g5Rg#dAclRvn(fz0|D_(C%YC`AE!0jvNB7Yfo05$?;^0DS<81BB!I*QQ~eFSrYo z_W+In{Br^4W@k|-o4x}04E7rXa5q2#fZyx~-UkSI<`lrc@ILqrWX~%4;ll^Cy1EL5 z`}rF%2=18x{Kr_pJ$&0X;CdF|KVW)#8h!RG1MG(!++O=fg+FdUhPwg~&Mj^nu>69M z?r*j|Gc%30wYH-D@7|#{)>f#ktquC_-9Ls1UdI9K;~YSIyRZ}h_>WBv?x9OdOX%d} zB-j%T=+pFc^u>$kIN9pq?uO3H%)lz&0ytM90P*v3_gj_VJ-Ao$a&yr)EiHiNcc`U> zIqK+e87(X*z^%vk-UIjJ0K&D{3lIbFA22;V1>{);t{pf((^FI6OqxPtqN7ng-Q#F% zYz#U-{};LXbsLbcBmues{F4X4H4dO`z+f=Ac^(=XLI(#2(YCf$+}yOawV_>|ov59i zEl!RO4-eyC`+Io{+$jG0O~`-nJn8}G5#&jDu0%!MM|E|Nq1ILxQ719V~YYHMSSI|E!?uAwIl^ue55LXYWaq5S;3xPIYtFE3AYY;5cs zv<+{; z`6-4M-vW3p!Zpaw&cg8y+*=yzM{s??dvGtn_J06yecb^5gFoRraNpJgy#VqM+y`(i z;k^0#`=KXK>Z56CssFaeAb);$e?dNN2RZ|!8}eueIJ?iCGev!FdgFAF^z^jv@eL#o zzrTpV^>^h1tO#X9Sy?HL{#S*CDAX&UZUXuE2M`CI;bb)^zboJ1`%pGRJrRz@)YKRa z3Jk#Mf#1*_V08#z%Qw6n{jPk5dQC}537VIe3wY`!n*8X|w{(j?T1L^o$Y*#6fCqRv z`rY#d(%K62RENv<=nv%0Kh78YVfj@ba2$PjV!ke+%orRTz@3#}-~V#`-ShEpeZaAN z^L&SU^lxX%PoMAjK41yjhxk9yPgW5bWC@{01`sl&1R=tqJJ6VZ72rGg_hDPGP1rWn z!`K1J0)%!T4xj<}i|}R4M4;pZXaX=1;2VHYU&ekxD396zLjC&!Kwg0GonP$jKh@#8 z00{v?{VNb)7eLtGp8$FD8+!@riIC6k02BrIOLTzx_;ua_uH68B_mG8pMQLdXsPbKa zvIy#`TLI$Q{m%&hd4;b7NtYWm^3Umn7>UhFe^Aeaa{twd1fZ=yny!bbr)xJ_iiE7#rfLb{YyV;^B#Bz=U@lGw?C=~pFy4Q{{2XBmP0Z3 z$67$&4D@F~o`k*$O$~KaO6nkPU%)l`7w8Aiq5fb9a0%cy0qSz_{QU&R4fU>p{(hXT z0eKDTMwft176Wv4sLQ~)f%@v+y?fBBSFik=91;%;C?qi=nMEJ z!0|#|Fexb!XVby?_V&Jk?g6|8Z6(O>(C(n8+l+E@u%pg^|J>c(fE}WZwP1;B2HwlS2qYCz^F$REPdcK7ZbRCM27 z+}MvF)4|z10k?0V65#|9bv_I=H`p8@B8BRCI+eq@`%X7GSNe}4M>#lHxB z2rv#357r#|)!Ttz$n5+%-1!gX#ZSQB&tFKxzv>^bUAPxUMuu@?eEqr-=wAm>8{lh! zvi2K3_3x4Lr~UzzAW#Y7PwQXM--+7;Ko^4X4FmlXIN!tfI{VxGzvy3I^$%(ISN#*V z1<&N#+8Ufae;ddecrN_JUWc!C0{n;m`8OKGK%IZpzhPs;!x-HDhx_j*0QM~h5I5hj z&%Xoy87SdA{LuaY&w)Pr2^|Ca7mV@z0HBPAbN)m715XR6hv$cXwZC9o2LU2oXR6 z_dgK%RRHfH00~O|K%xQACTtt_0sDe|!oH!O0>+BY0Q}QW!3BQ&kKoHX!u2Ev2>IF= zU^u`MfPDbrAq|!FC4f-b8~|7WFbbd8_{}EaL+RT^!2tdgO@I1gwfbRkR zlz<2IAV9+$>Q~UNg}OdBK*-bo+W+rXfNcYWbaMgp1lR>|72tmhYoLLCfH1ZX&u!Sp z?~?hC_h4IJkOq`i03qE_cKs_rTLk)%e*qwmT?Ghb+<(ni_%=W(4DcC1xb8m

!0K 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 R+noRa002ovPDHLkV1k4f*O~wT literal 0 HcmV?d00001 From d47830355d743fde33d324fac2569543ae214fb5 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Sun, 3 Feb 2019 09:25:07 +1100 Subject: [PATCH 104/153] remove 16x16 tray icon since invisible on non-retina --- .../fether-electron/static/assets/icons/icon.png | Bin 1614 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 packages/fether-electron/static/assets/icons/icon.png diff --git a/packages/fether-electron/static/assets/icons/icon.png b/packages/fether-electron/static/assets/icons/icon.png deleted file mode 100644 index ec30bac9cef34e05620c163c6dcedb0f9db6e06e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1614 zcmdT^O-NKx6#nj;Nk>OB#8x4=j3^K(aM7Y%M1h7-(WcF)BTdeXGBc7x(8jhw+n{}$ za$%8CftwbAErf^`ZOYX|xJXU({oK=c?!57*jSwyBUe3GUIp^MU?mIuXe_;3u4C*7v z<%pvc60wX+;tT1yNGwr}?mCR5lg&H%tg|u;kKAnkz@?$$WT_xXku_)C4&XSTCl03O z!Avz<>giQG`RQVg=etPF7(@nDWKlv7dI6^|mP^zn^Ohrqbg28}oP#U8Os7L4-N0H5SJ4Xj?2CL94-2;qzREk8yB{EP1`EI&N#dHkFfj9S zpVscl0^Z9l=VOsJmK*|>oyY4Bal7g==H}*VbVY;=_l>#t#r6p>3}q>6$)7$k#CxmJg?cSM00FjHPCkAC Dx){BN From e42e8f59399cc3de2191dbe5b3e91dce750dfba5 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Sun, 3 Feb 2019 09:26:37 +1100 Subject: [PATCH 105/153] replace with new 16x16 tray icon --- .../fether-electron/static/assets/icons/icon.png | Bin 0 -> 1423 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 packages/fether-electron/static/assets/icons/icon.png diff --git a/packages/fether-electron/static/assets/icons/icon.png b/packages/fether-electron/static/assets/icons/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..92d3d6a2a0d40be95ea3a7fe370d240dabc71410 GIT binary patch literal 1423 zcmaJ>eQXnD7=PEg$rcu8Q0GSCj>9Y>yWU4Xu6M4sU9W{I-Ih^wi6-to-rFu~d)@Ws zy2;#T$QU1g3?%`B2#uh^ABZtQ1B!z|nA637G=4>gOAHaB2&iK^sBgD*^2fp@mwTV* zp5OEQp09UXWBt0)lFAYQKxufr(1gBaxp!F+00nJ-emRYV3NzSjZq!w?OEe(xE4l=+ za9nJKO;A+2J3fQ809XgLXtUWI*}%(s+$QF1Z0UFsp#iA%rjw%F4oysgty;o^Up@6H zj%kVqf7ThHBFO-3)7JMGaAQw>RPJe)IR*DViPffgpq;B$U?bk3Q(@gRt+11r$>$2N)qm`sNjw30CWEcWj5UK8jDW-`;YIWX&08_G| zB~49FU^$PXq<5Mg95J0wA)bsx79A&23xz@@BhzA%q-_)#kLU85vrd^!@P8UhTBoAj zNk}%ql-_B`s2}R;JQ&sP?tyZKhz;LhXs9V-Owi@dI82yf!GoheHbql-6-qS6ax!6O zMTu}Ij7qpgCrda~mx~gel3TL7^M01X`|DUC+Aw)M#5iIL)5fY0;2g`7FR(7%qWN;EuBy+=a$1vqpXhL(x z#nnK<;&Q4<3Gc51+X?b>*A)j`}Y2T3)vt^7hSKKYZWnn78+z zsAYF;Y4rJ$9hFL9OVGD}V(is#&lZgC0|kRI3;)w{<}!-^&b4>XXd@ej)s~&vdqbal zvD5Xt3r_NUjj!j&zDL1VvsIP6UR?Rd%#BNA_8K_2%G*zCTh|Vsuzoi^aHbcuU4ef8 znZU@H^_Rh_$5R`5%?i9%P q2R^Er__e&F5bvpd%lbunofVw?o%>`}%ku5HD>59c7mn4nyz(Du5A(YK literal 0 HcmV?d00001 From dc3d47e39a9759391cb926d9227c6e82c69ab6b7 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Sun, 3 Feb 2019 10:14:24 +1100 Subject: [PATCH 106/153] move white 16x16 tray icon to old since non-retina has white background and appears invisible --- .../static/assets/icons/{ => old}/icon.png | Bin 1 file changed, 0 insertions(+), 0 deletions(-) rename packages/fether-electron/static/assets/icons/{ => old}/icon.png (100%) diff --git a/packages/fether-electron/static/assets/icons/icon.png b/packages/fether-electron/static/assets/icons/old/icon.png similarity index 100% rename from packages/fether-electron/static/assets/icons/icon.png rename to packages/fether-electron/static/assets/icons/old/icon.png From 3edd2cb79c716d1628d3b371fc082dfc2419a644 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Sun, 3 Feb 2019 10:15:09 +1100 Subject: [PATCH 107/153] fix: Add 16x16 black icon for non-retina since tray background is white --- .../fether-electron/static/assets/icons/icon.png | Bin 0 -> 2027 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 packages/fether-electron/static/assets/icons/icon.png diff --git a/packages/fether-electron/static/assets/icons/icon.png b/packages/fether-electron/static/assets/icons/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..57330c5c76d93d2a2728174c1367168bd7ec70ca GIT binary patch literal 2027 zcma)73vAS69Pfz2*mw>x1{3KDgbnQVdF{2~+~e-XPPsA06pWMDYro#g?%K2MxNRE3 zYi5Kjz>E*vAU;4%2qZXpC@h#5V<1kLQHhN3h%<{Q&dGFP1LD`a?KX8Pm-PBQe!u_w z|L^wlvgOmW=4BxWGCf%8uYm7a&XYMAK{Bcb&JDuN)OhLB7J_8Yah?q1jkbpnWb!nv za;?2Kv_h1Pm`hTOFmTny;t-7>%L?k^l3W99Gz=n|?#22}p2kp3@nUP-Au<&AfoiR^ z!33)t$|~iC8d*@Vg2&Khbs`iH1Ga?L#iF_;)_Jj{ToJCFV**2y5WB{U6*&sgwV`s< zXP5wWyEt5?SQ6z07sZjRn|c(bNs1>(H$ieZNr|LKq$zadhe2(oqKXy%k`Y~S=f$dR zJ1!DLB9U+<7?)v22uctHf}{zW#vuZ?>UCSH!*y%Hs02T-WK)aVnxUhPL@8|4+FlG= znsOl)4~5c#b!#M0Fl0oX6elPbNyK7~UrDrOSAa1yCPZ76^>IK{0L!Q~WdPv|#>jyU zQ1gfn_dpJ80J@!~!_faXc~p-gr*ZLGGnx#OA`>7AVo;t1eWKD1#j6e5u&RxJ5uLtH z2EtJQqb061HCQxK)NjbOj>w?ji@_V0qA8*Z!j!-ZGS2W)7-tn)#XXXn$61x*NXZ@c zgc;AMoQe2F#k{|SrFbgfFQTY`P#j=Gp z7+jUY49@b5iVG4f49YD4H_3(FZk|i>MV|>I+b}B)BRX2C<)e{6eLkl$J!oD?k~Q54 zPyRR-@JlxEVh|zVB#o0yB`Ltdh2^`Hg8yU+8Zs13t^Wsn^Qi^2=5VtFwd4EQ)o;5eLi zQBIqrvg!w>wgD(5rV&GvbuMZX#8{ET3?Rc{oC>QRoTV5KE^s8kX@yl)ffZq$}}!{C=%y+mczq5+_F3^Fud&M6+mM|+Qd@Lf?2B{nGLJK z^CPRM1~tOw5+&K`bLgf7J#ox%4kvQs-by9KPgDaaa$Lgyp2ZZ*GE_SunV={FTjCz8 zD#etmB|QS*@FkMI63&=PIY*>YGv;^lZrn(N0Z1OfIq59Z0~&79BOd5bvV<-N%~fAl&CvB|^zliPw{D&ie;MpKJGEs_@1>gHK@oWk zIs8N!MYeXn{&~~xX-O#}Y%ov~_3aMi+PX9N4qBC;#%Yfu{LOyH4Nzsi{Bf$xO5G(CmlrX82{U{Wvz< Q?|hDffinN$;^(&f2|l;GeE Date: Sun, 3 Feb 2019 10:25:51 +1100 Subject: [PATCH 108/153] remove old 16x16 non-retina tray icon since bad shape --- .../fether-electron/static/assets/icons/icon.png | Bin 2027 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 packages/fether-electron/static/assets/icons/icon.png diff --git a/packages/fether-electron/static/assets/icons/icon.png b/packages/fether-electron/static/assets/icons/icon.png deleted file mode 100644 index 57330c5c76d93d2a2728174c1367168bd7ec70ca..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2027 zcma)73vAS69Pfz2*mw>x1{3KDgbnQVdF{2~+~e-XPPsA06pWMDYro#g?%K2MxNRE3 zYi5Kjz>E*vAU;4%2qZXpC@h#5V<1kLQHhN3h%<{Q&dGFP1LD`a?KX8Pm-PBQe!u_w z|L^wlvgOmW=4BxWGCf%8uYm7a&XYMAK{Bcb&JDuN)OhLB7J_8Yah?q1jkbpnWb!nv za;?2Kv_h1Pm`hTOFmTny;t-7>%L?k^l3W99Gz=n|?#22}p2kp3@nUP-Au<&AfoiR^ z!33)t$|~iC8d*@Vg2&Khbs`iH1Ga?L#iF_;)_Jj{ToJCFV**2y5WB{U6*&sgwV`s< zXP5wWyEt5?SQ6z07sZjRn|c(bNs1>(H$ieZNr|LKq$zadhe2(oqKXy%k`Y~S=f$dR zJ1!DLB9U+<7?)v22uctHf}{zW#vuZ?>UCSH!*y%Hs02T-WK)aVnxUhPL@8|4+FlG= znsOl)4~5c#b!#M0Fl0oX6elPbNyK7~UrDrOSAa1yCPZ76^>IK{0L!Q~WdPv|#>jyU zQ1gfn_dpJ80J@!~!_faXc~p-gr*ZLGGnx#OA`>7AVo;t1eWKD1#j6e5u&RxJ5uLtH z2EtJQqb061HCQxK)NjbOj>w?ji@_V0qA8*Z!j!-ZGS2W)7-tn)#XXXn$61x*NXZ@c zgc;AMoQe2F#k{|SrFbgfFQTY`P#j=Gp z7+jUY49@b5iVG4f49YD4H_3(FZk|i>MV|>I+b}B)BRX2C<)e{6eLkl$J!oD?k~Q54 zPyRR-@JlxEVh|zVB#o0yB`Ltdh2^`Hg8yU+8Zs13t^Wsn^Qi^2=5VtFwd4EQ)o;5eLi zQBIqrvg!w>wgD(5rV&GvbuMZX#8{ET3?Rc{oC>QRoTV5KE^s8kX@yl)ffZq$}}!{C=%y+mczq5+_F3^Fud&M6+mM|+Qd@Lf?2B{nGLJK z^CPRM1~tOw5+&K`bLgf7J#ox%4kvQs-by9KPgDaaa$Lgyp2ZZ*GE_SunV={FTjCz8 zD#etmB|QS*@FkMI63&=PIY*>YGv;^lZrn(N0Z1OfIq59Z0~&79BOd5bvV<-N%~fAl&CvB|^zliPw{D&ie;MpKJGEs_@1>gHK@oWk zIs8N!MYeXn{&~~xX-O#}Y%ov~_3aMi+PX9N4qBC;#%Yfu{LOyH4Nzsi{Bf$xO5G(CmlrX82{U{Wvz< Q?|hDffinN$;^(&f2|l;GeE Date: Sun, 3 Feb 2019 10:26:37 +1100 Subject: [PATCH 109/153] fix: Add new 16x16 non-retina with tweaked shape --- .../fether-electron/static/assets/icons/icon.png | Bin 0 -> 2206 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 packages/fether-electron/static/assets/icons/icon.png diff --git a/packages/fether-electron/static/assets/icons/icon.png b/packages/fether-electron/static/assets/icons/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..51fae9f7d1c1050647516abefae2156d1a35755f GIT binary patch literal 2206 zcmb_eYitx%6dqDSv53*|upq>7T9w!Aymn@GMi$uaZXe>-vTUSaY?#NL-Lbnf!_2hZ zmOs3z6s)|2pkPQ)4Afw>QllXaKB9&wAQ6cEknp2Xj1Lk7!9b{YcDvgWt776Nvpe_R zbIy0a@0@$?b~V)3Oe~vTh9Jnqy4pw_{@&|7DrHF)-J2#bG-u*A2eFU` zh&IL=(6DI(l=X4ALitIQ7km^)`dMloN|O{%kSsxRI7x|QK%^;j=z~EtTh+vPq3^{f2fL&RQoBOibg^d6&0$YOgJP&$pA}N3tT8%@U1f(S27e(z}6wQ!gB)8 z`UAK?(E;2qr~sG!tcdNX1Y+R4Fx68aM-KN06HrsDZ1gw zGkb&=h)6C7V$edsNg5}a1S!D6h2=Y!g5PA`G-j&0*8Ue$iWF&9B&pj>;lWWQSNd0D zRS`AQ&PcF^^o*1Qgk>Z#w3s3>Y^F^c0>j-gBj@YF;Rf5(^fX*>;x$!hT{O&50>|OB zkMfR5KC2O6>#abow#^Kht8-BwMPpTw89>T1PRSb7m|~#X90_n*g>ffer`)Hsr64 zsE>S~fHN>p!&_E3iRDOz#-#v7;ymx?aG8fgKTit`uduudXpAUsu~v6r*4l@9!&0zn z=q;^7M0mJFN%77(q$xor-Zs3+(P#*gCXs4@!8J){ARMFNf&_aA#R`BWIhkd7uHfI6 z0x;x=gu^USjOZ_BF%RRIn%gGXAe4kh;ts1S@2R9DBMD&hC30N7F7@9T-C6PH0Y_tW zTV4Loj0lfXK3zn<*oHHiTN}}&VM=pTu=9Jb#VZF6ikB8JpjbA%lHNAoli@9>)kQ*y zKzDci=;I}!$-y7$%f5XX0P2sml?TS&9J_c=V$)W0pU#_lwv}<;&IO&rR*w)Oxgk$H&a+hmUW0 z>HIIP-KF(iJM9nl_bhtzY#DO1T={JF`hgG2ot~cMGuIHvjx&!w^g?yTN%?x|w9@U@ zR?WC%)GT=>(zNHq_vd=2l-xIM;Hm6u3l8?^i!WZgQP~wgl!#W-r?yVmEuML{@0*JK zr&B*CXRJdHK5|dx*%hmI1uEzI@BXA>dp|n9{tfZOcU6b`?%zD^T$6Ka+rGz;6|*LH zY+kf~Ij~9=byIV&W7y^1Z6AGYH6qqeR}W#^k1$Qm7xvz`^6BR12io3goOdgEp|+`J z$&s4gOZ{JL7+CN8x<)NUmbF-cNx=t{lZX4Re%1Loc9~nes!#8Fwe#YZ!JV~(4?azo ep{3U+3?hRYsH+>h_bv7QLDWU-BX3o$T=yr4NaNE0 literal 0 HcmV?d00001 From f2f2736a23918e49fd5bbae44dc32358692849f3 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Sun, 3 Feb 2019 10:33:09 +1100 Subject: [PATCH 110/153] remove old 16x16 non-retina tray icon since bad shape --- .../fether-electron/static/assets/icons/icon.png | Bin 2206 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 packages/fether-electron/static/assets/icons/icon.png diff --git a/packages/fether-electron/static/assets/icons/icon.png b/packages/fether-electron/static/assets/icons/icon.png deleted file mode 100644 index 51fae9f7d1c1050647516abefae2156d1a35755f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2206 zcmb_eYitx%6dqDSv53*|upq>7T9w!Aymn@GMi$uaZXe>-vTUSaY?#NL-Lbnf!_2hZ zmOs3z6s)|2pkPQ)4Afw>QllXaKB9&wAQ6cEknp2Xj1Lk7!9b{YcDvgWt776Nvpe_R zbIy0a@0@$?b~V)3Oe~vTh9Jnqy4pw_{@&|7DrHF)-J2#bG-u*A2eFU` zh&IL=(6DI(l=X4ALitIQ7km^)`dMloN|O{%kSsxRI7x|QK%^;j=z~EtTh+vPq3^{f2fL&RQoBOibg^d6&0$YOgJP&$pA}N3tT8%@U1f(S27e(z}6wQ!gB)8 z`UAK?(E;2qr~sG!tcdNX1Y+R4Fx68aM-KN06HrsDZ1gw zGkb&=h)6C7V$edsNg5}a1S!D6h2=Y!g5PA`G-j&0*8Ue$iWF&9B&pj>;lWWQSNd0D zRS`AQ&PcF^^o*1Qgk>Z#w3s3>Y^F^c0>j-gBj@YF;Rf5(^fX*>;x$!hT{O&50>|OB zkMfR5KC2O6>#abow#^Kht8-BwMPpTw89>T1PRSb7m|~#X90_n*g>ffer`)Hsr64 zsE>S~fHN>p!&_E3iRDOz#-#v7;ymx?aG8fgKTit`uduudXpAUsu~v6r*4l@9!&0zn z=q;^7M0mJFN%77(q$xor-Zs3+(P#*gCXs4@!8J){ARMFNf&_aA#R`BWIhkd7uHfI6 z0x;x=gu^USjOZ_BF%RRIn%gGXAe4kh;ts1S@2R9DBMD&hC30N7F7@9T-C6PH0Y_tW zTV4Loj0lfXK3zn<*oHHiTN}}&VM=pTu=9Jb#VZF6ikB8JpjbA%lHNAoli@9>)kQ*y zKzDci=;I}!$-y7$%f5XX0P2sml?TS&9J_c=V$)W0pU#_lwv}<;&IO&rR*w)Oxgk$H&a+hmUW0 z>HIIP-KF(iJM9nl_bhtzY#DO1T={JF`hgG2ot~cMGuIHvjx&!w^g?yTN%?x|w9@U@ zR?WC%)GT=>(zNHq_vd=2l-xIM;Hm6u3l8?^i!WZgQP~wgl!#W-r?yVmEuML{@0*JK zr&B*CXRJdHK5|dx*%hmI1uEzI@BXA>dp|n9{tfZOcU6b`?%zD^T$6Ka+rGz;6|*LH zY+kf~Ij~9=byIV&W7y^1Z6AGYH6qqeR}W#^k1$Qm7xvz`^6BR12io3goOdgEp|+`J z$&s4gOZ{JL7+CN8x<)NUmbF-cNx=t{lZX4Re%1Loc9~nes!#8Fwe#YZ!JV~(4?azo ep{3U+3?hRYsH+>h_bv7QLDWU-BX3o$T=yr4NaNE0 From 1cacdea96a2c49ec8c61dc5d22b67cc3eab7f228 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Sun, 3 Feb 2019 10:37:07 +1100 Subject: [PATCH 111/153] fix: Add new 16x16 non-retina with tweaked shape --- .../fether-electron/static/assets/icons/icon.png | Bin 0 -> 2224 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 packages/fether-electron/static/assets/icons/icon.png diff --git a/packages/fether-electron/static/assets/icons/icon.png b/packages/fether-electron/static/assets/icons/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..4b4e0046031a4b83eb5808a32cedb9ea27e568ec GIT binary patch literal 2224 zcmb_ed2AF_7@vhuEk`XuN zBs78%A|V0-LNzr+O)ONya8Wz~oPXIf7}YXq4)Kb@47CSaiv(5NNc*o~8?F;r9C*itr3hLb)J z(}HVEuy{>Py|SiB5mjvdJaleaf&p}3$!J=SCsI<{jb-9W@ZFv!Ff?OgHMud54Tvra z*P=ed1Ssp|aD{S_C@(rGj&!lq6DUnmJVCMq$>Ag=k%B~1XzqhSG*gXAb^gj6796>; zm}Mm;f@o=Jakel{!)zodQ4|T1CTJRm7I>;PVaaJck(!>5;0Gzi)RLBFBv3n|95I?L zHwJf_rJyIn;X>d~+-rv9Iu^Ej$fuuC?Z@l2Xjg#dA&!+0ski7F6E#th3y#f-lR zU0BW}!UllZk`|d76pbAB8%nbsGURt-aK))=suTqgO5{ZaXLvb+yHq-g3o^^&t|-Tm zG8+*hjF68roWIA*`zu`(PX+uQiVBF{0ORwB0a9S;N|E#U^1h)&%90Zb$YW~|TLrX0 zlY)X%E}4SZJd2B>0&s-{G$RW@pcp0NFZoO$TZUP081cMPYx9{veLh>60y;A+D_X)% z&#WO{z%N_CjX?_$Cuy8y>PZm_7s~f>3VxGW)3Bjx(bm71Ql!Li63g9V3J;DdTk^je ztBMpgOkIW=(sa2I5XnR%h89XB`HZ+>LSVQ%X6Ss#=c_f1s1}C{sk$mJ8VdM0O5`}4 zc2f2+$yU`5Ol>t#D@{X3Gdh>F;c~1*7(hlMI2DNsxQk*0T;xcA)2b^P6g)IiP6s%fnt~V?O zt8#B~4I;wBCCQ3?&LK@1GO@Q|PYy>zl%q1K3Je~VBMgLNqPQr-9zwAqU`Z~*vOJgf zZ;1gIa!A2p6)8q?QTZxnVNyoaYLQLgX@p1OK2??VRAO?X5y0k4WVqU0>c2C(Kk;V) zhhub)F8^mngiR@1E+Q+o!AfS{Pt_%%7KHzr3Df&Sth)a$|^Q(gtuTi z@RK0h3-=+oK1J{qwxb1ClAZ=Y`UE8QhAKZAlbN1Bj z=T|;cviG;pyz}YzK7Yl(YV5=@TOMf`_2aK6#$4^0+|ypXQ&*}34Ksd6PC4#uU56dK z)HnXj%x#ChoKx{=a6h15{mCpX3v@jB_LAMv?XefT!z=yX0d>`g*sk~J6W{*UU_4Xb* z`N@bR)?ZF~2Cx9GLRB}ek51BZ`n_4mE-N6(pC zr`8{By*sUc&xLQy(^Jyr54EA)JLh8k$co_2_OH9XYwat4$dSBU!a24DFHccc_I~l~ zm0P#{9h06rc Date: Sun, 3 Feb 2019 12:07:33 +1100 Subject: [PATCH 112/153] fix: Add dock icon to static folder and set it so it appears in development on macos --- .../src/main/app/methods/createTray.js | 6 +++++- .../src/main/app/options/config/index.js | 6 ++++++ .../static/assets/icons/iconDock.png | Bin 0 -> 17209 bytes 3 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 packages/fether-electron/static/assets/icons/iconDock.png diff --git a/packages/fether-electron/src/main/app/methods/createTray.js b/packages/fether-electron/src/main/app/methods/createTray.js index 797c2ede6..7c505a707 100644 --- a/packages/fether-electron/src/main/app/methods/createTray.js +++ b/packages/fether-electron/src/main/app/methods/createTray.js @@ -6,10 +6,14 @@ import { Tray } from 'electron'; function createTray () { - let { options } = this.fetherApp; + let { app, options } = this.fetherApp; if (options.withTaskbar) { this.fetherApp.tray = new Tray(options.icon); + + if (process.platform === 'darwin' && app.dock) { + app.dock.setIcon(options.iconDock); + } } } diff --git a/packages/fether-electron/src/main/app/options/config/index.js b/packages/fether-electron/src/main/app/options/config/index.js index 39396fdd9..858f6d1ad 100644 --- a/packages/fether-electron/src/main/app/options/config/index.js +++ b/packages/fether-electron/src/main/app/options/config/index.js @@ -22,6 +22,11 @@ const ICON_PATH = ? path.join(staticPath, 'assets', 'icons', 'win', 'icon.ico') : path.join(staticPath, 'assets', 'icons', 'icon.png'); +const ICON_DOCK_PATH = + process.platform === 'darwin' + ? path.join(staticPath, 'assets', 'icons', 'iconDock.png') + : ''; + const shouldUseDevTools = process.env.NODE_ENV !== 'production'; const shouldUseFrame = process.platform === 'win32'; @@ -36,6 +41,7 @@ const DEFAULT_OPTIONS = { height: 640, hasShadow: true, icon: ICON_PATH, + iconDock: ICON_DOCK_PATH, index: INDEX_HTML_PATH, resizable: false, show: false, // Run showWindow later diff --git a/packages/fether-electron/static/assets/icons/iconDock.png b/packages/fether-electron/static/assets/icons/iconDock.png new file mode 100644 index 0000000000000000000000000000000000000000..6f55faf43d83f1262f56821854e61ea004c5b7c6 GIT binary patch literal 17209 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 ATmS$7 literal 0 HcmV?d00001 From aed978aef8225c421cf18c3a81e0467e51fc6baf Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Sun, 3 Feb 2019 12:21:54 +1100 Subject: [PATCH 113/153] fix: Rename to __Template so on macOS the image adapts to both light and dark menu bars See https://github.com/electron/electron/blob/master/docs/api/native-image.md#template-image --- .../assets/icons/{icon.png => iconTemplate.png} | Bin .../icons/{old/icon@2x.png => iconTemplate@2x.png} | Bin .../icons/{old/icon@3x.png => iconTemplate@3x.png} | Bin .../icons/{old/icon@4x.png => iconTemplate@4x.png} | Bin .../icons/{old/icon@5x.png => iconTemplate@5x.png} | Bin .../static/assets/icons/{old => old-white}/icon.png | Bin .../static/assets/icons/{ => old-white}/icon@2x.png | Bin .../static/assets/icons/{ => old-white}/icon@3x.png | Bin .../static/assets/icons/{ => old-white}/icon@4x.png | Bin .../static/assets/icons/{ => old-white}/icon@5x.png | Bin 10 files changed, 0 insertions(+), 0 deletions(-) rename packages/fether-electron/static/assets/icons/{icon.png => iconTemplate.png} (100%) rename packages/fether-electron/static/assets/icons/{old/icon@2x.png => iconTemplate@2x.png} (100%) rename packages/fether-electron/static/assets/icons/{old/icon@3x.png => iconTemplate@3x.png} (100%) rename packages/fether-electron/static/assets/icons/{old/icon@4x.png => iconTemplate@4x.png} (100%) rename packages/fether-electron/static/assets/icons/{old/icon@5x.png => iconTemplate@5x.png} (100%) rename packages/fether-electron/static/assets/icons/{old => old-white}/icon.png (100%) rename packages/fether-electron/static/assets/icons/{ => old-white}/icon@2x.png (100%) rename packages/fether-electron/static/assets/icons/{ => old-white}/icon@3x.png (100%) rename packages/fether-electron/static/assets/icons/{ => old-white}/icon@4x.png (100%) rename packages/fether-electron/static/assets/icons/{ => old-white}/icon@5x.png (100%) diff --git a/packages/fether-electron/static/assets/icons/icon.png b/packages/fether-electron/static/assets/icons/iconTemplate.png similarity index 100% rename from packages/fether-electron/static/assets/icons/icon.png rename to packages/fether-electron/static/assets/icons/iconTemplate.png diff --git a/packages/fether-electron/static/assets/icons/old/icon@2x.png b/packages/fether-electron/static/assets/icons/iconTemplate@2x.png similarity index 100% rename from packages/fether-electron/static/assets/icons/old/icon@2x.png rename to packages/fether-electron/static/assets/icons/iconTemplate@2x.png diff --git a/packages/fether-electron/static/assets/icons/old/icon@3x.png b/packages/fether-electron/static/assets/icons/iconTemplate@3x.png similarity index 100% rename from packages/fether-electron/static/assets/icons/old/icon@3x.png rename to packages/fether-electron/static/assets/icons/iconTemplate@3x.png diff --git a/packages/fether-electron/static/assets/icons/old/icon@4x.png b/packages/fether-electron/static/assets/icons/iconTemplate@4x.png similarity index 100% rename from packages/fether-electron/static/assets/icons/old/icon@4x.png rename to packages/fether-electron/static/assets/icons/iconTemplate@4x.png diff --git a/packages/fether-electron/static/assets/icons/old/icon@5x.png b/packages/fether-electron/static/assets/icons/iconTemplate@5x.png similarity index 100% rename from packages/fether-electron/static/assets/icons/old/icon@5x.png rename to packages/fether-electron/static/assets/icons/iconTemplate@5x.png diff --git a/packages/fether-electron/static/assets/icons/old/icon.png b/packages/fether-electron/static/assets/icons/old-white/icon.png similarity index 100% rename from packages/fether-electron/static/assets/icons/old/icon.png rename to packages/fether-electron/static/assets/icons/old-white/icon.png diff --git a/packages/fether-electron/static/assets/icons/icon@2x.png b/packages/fether-electron/static/assets/icons/old-white/icon@2x.png similarity index 100% rename from packages/fether-electron/static/assets/icons/icon@2x.png rename to packages/fether-electron/static/assets/icons/old-white/icon@2x.png diff --git a/packages/fether-electron/static/assets/icons/icon@3x.png b/packages/fether-electron/static/assets/icons/old-white/icon@3x.png similarity index 100% rename from packages/fether-electron/static/assets/icons/icon@3x.png rename to packages/fether-electron/static/assets/icons/old-white/icon@3x.png diff --git a/packages/fether-electron/static/assets/icons/icon@4x.png b/packages/fether-electron/static/assets/icons/old-white/icon@4x.png similarity index 100% rename from packages/fether-electron/static/assets/icons/icon@4x.png rename to packages/fether-electron/static/assets/icons/old-white/icon@4x.png diff --git a/packages/fether-electron/static/assets/icons/icon@5x.png b/packages/fether-electron/static/assets/icons/old-white/icon@5x.png similarity index 100% rename from packages/fether-electron/static/assets/icons/icon@5x.png rename to packages/fether-electron/static/assets/icons/old-white/icon@5x.png From 13fd3cc70d2b9d6c96b47cfea79a095a01e1fa08 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Sun, 3 Feb 2019 12:24:45 +1100 Subject: [PATCH 114/153] fix: Rename to use template icon file with _Template postfix on macOS --- packages/fether-electron/src/main/app/options/config/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/fether-electron/src/main/app/options/config/index.js b/packages/fether-electron/src/main/app/options/config/index.js index 858f6d1ad..3cd9e0b98 100644 --- a/packages/fether-electron/src/main/app/options/config/index.js +++ b/packages/fether-electron/src/main/app/options/config/index.js @@ -20,7 +20,7 @@ const INDEX_HTML_PATH = const ICON_PATH = process.platform === 'win32' ? path.join(staticPath, 'assets', 'icons', 'win', 'icon.ico') - : path.join(staticPath, 'assets', 'icons', 'icon.png'); + : path.join(staticPath, 'assets', 'icons', 'iconTemplate.png'); const ICON_DOCK_PATH = process.platform === 'darwin' From c0daacbb90b580457c0685ad740563099b0af580 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Sun, 3 Feb 2019 12:42:34 +1100 Subject: [PATCH 115/153] refactor: Move mac tray icons into subfolder --- .../src/main/app/options/config/index.js | 33 ++++++++++++------ .../icons/{iconTemplate.png => icon.png} | Bin .../{iconTemplate@2x.png => icon@2x.png} | Bin .../{iconTemplate@3x.png => icon@3x.png} | Bin .../{iconTemplate@4x.png => icon@4x.png} | Bin .../{iconTemplate@5x.png => icon@5x.png} | Bin .../assets/icons/{ => mac}/iconDock.png | Bin .../static/assets/icons/mac/iconTemplate.png | Bin 0 -> 2224 bytes .../assets/icons/mac/iconTemplate@2x.png | Bin 0 -> 3890 bytes .../assets/icons/mac/iconTemplate@3x.png | Bin 0 -> 7993 bytes .../assets/icons/mac/iconTemplate@4x.png | Bin 0 -> 20122 bytes .../assets/icons/mac/iconTemplate@5x.png | Bin 0 -> 16749 bytes 12 files changed, 23 insertions(+), 10 deletions(-) rename packages/fether-electron/static/assets/icons/{iconTemplate.png => icon.png} (100%) rename packages/fether-electron/static/assets/icons/{iconTemplate@2x.png => icon@2x.png} (100%) rename packages/fether-electron/static/assets/icons/{iconTemplate@3x.png => icon@3x.png} (100%) rename packages/fether-electron/static/assets/icons/{iconTemplate@4x.png => icon@4x.png} (100%) rename packages/fether-electron/static/assets/icons/{iconTemplate@5x.png => icon@5x.png} (100%) rename packages/fether-electron/static/assets/icons/{ => mac}/iconDock.png (100%) create mode 100644 packages/fether-electron/static/assets/icons/mac/iconTemplate.png create mode 100644 packages/fether-electron/static/assets/icons/mac/iconTemplate@2x.png create mode 100644 packages/fether-electron/static/assets/icons/mac/iconTemplate@3x.png create mode 100644 packages/fether-electron/static/assets/icons/mac/iconTemplate@4x.png create mode 100644 packages/fether-electron/static/assets/icons/mac/iconTemplate@5x.png diff --git a/packages/fether-electron/src/main/app/options/config/index.js b/packages/fether-electron/src/main/app/options/config/index.js index 3cd9e0b98..5dda88173 100644 --- a/packages/fether-electron/src/main/app/options/config/index.js +++ b/packages/fether-electron/src/main/app/options/config/index.js @@ -17,15 +17,28 @@ const INDEX_HTML_PATH = }); // Icon path differs when started with `yarn electron` or `yarn start` -const ICON_PATH = - process.platform === 'win32' - ? path.join(staticPath, 'assets', 'icons', 'win', 'icon.ico') - : path.join(staticPath, 'assets', 'icons', 'iconTemplate.png'); +let iconPath = path.join(staticPath, 'assets', 'icons', 'icon.png'); +let iconDockPath = ''; -const ICON_DOCK_PATH = - process.platform === 'darwin' - ? path.join(staticPath, 'assets', 'icons', 'iconDock.png') - : ''; +if (process.platform === 'win32') { + iconPath = path.join(staticPath, 'assets', 'icons', 'win', 'icon.ico'); +} else if (process.platform === 'darwin') { + // https://github.com/electron/electron/blob/master/docs/api/native-image.md#template-image + iconPath = path.join( + staticPath, + 'assets', + 'icons', + 'mac', + 'iconTemplate.png' + ); + iconDockPath = path.join( + staticPath, + 'assets', + 'icons', + 'mac', + 'iconDock.png' + ); +} const shouldUseDevTools = process.env.NODE_ENV !== 'production'; const shouldUseFrame = process.platform === 'win32'; @@ -40,8 +53,8 @@ const DEFAULT_OPTIONS = { frame: true, height: 640, hasShadow: true, - icon: ICON_PATH, - iconDock: ICON_DOCK_PATH, + icon: iconPath, + iconDock: iconDockPath, index: INDEX_HTML_PATH, resizable: false, show: false, // Run showWindow later diff --git a/packages/fether-electron/static/assets/icons/iconTemplate.png b/packages/fether-electron/static/assets/icons/icon.png similarity index 100% rename from packages/fether-electron/static/assets/icons/iconTemplate.png rename to packages/fether-electron/static/assets/icons/icon.png diff --git a/packages/fether-electron/static/assets/icons/iconTemplate@2x.png b/packages/fether-electron/static/assets/icons/icon@2x.png similarity index 100% rename from packages/fether-electron/static/assets/icons/iconTemplate@2x.png rename to packages/fether-electron/static/assets/icons/icon@2x.png diff --git a/packages/fether-electron/static/assets/icons/iconTemplate@3x.png b/packages/fether-electron/static/assets/icons/icon@3x.png similarity index 100% rename from packages/fether-electron/static/assets/icons/iconTemplate@3x.png rename to packages/fether-electron/static/assets/icons/icon@3x.png diff --git a/packages/fether-electron/static/assets/icons/iconTemplate@4x.png b/packages/fether-electron/static/assets/icons/icon@4x.png similarity index 100% rename from packages/fether-electron/static/assets/icons/iconTemplate@4x.png rename to packages/fether-electron/static/assets/icons/icon@4x.png diff --git a/packages/fether-electron/static/assets/icons/iconTemplate@5x.png b/packages/fether-electron/static/assets/icons/icon@5x.png similarity index 100% rename from packages/fether-electron/static/assets/icons/iconTemplate@5x.png rename to packages/fether-electron/static/assets/icons/icon@5x.png diff --git a/packages/fether-electron/static/assets/icons/iconDock.png b/packages/fether-electron/static/assets/icons/mac/iconDock.png similarity index 100% rename from packages/fether-electron/static/assets/icons/iconDock.png rename to packages/fether-electron/static/assets/icons/mac/iconDock.png diff --git a/packages/fether-electron/static/assets/icons/mac/iconTemplate.png b/packages/fether-electron/static/assets/icons/mac/iconTemplate.png new file mode 100644 index 0000000000000000000000000000000000000000..4b4e0046031a4b83eb5808a32cedb9ea27e568ec GIT binary patch literal 2224 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 alkx_6`Lo7XdXC8c)jHZb+Z0&&?fo}ZRZJ8B literal 0 HcmV?d00001 diff --git a/packages/fether-electron/static/assets/icons/mac/iconTemplate@3x.png b/packages/fether-electron/static/assets/icons/mac/iconTemplate@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..325c7f6b6a755ef743b7b97642bbddf1e175e57d GIT binary patch literal 7993 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 J8%3*t{{VN0DRBS* literal 0 HcmV?d00001 diff --git a/packages/fether-electron/static/assets/icons/mac/iconTemplate@4x.png b/packages/fether-electron/static/assets/icons/mac/iconTemplate@4x.png new file mode 100644 index 0000000000000000000000000000000000000000..ca5f0668557738f67533b436870b7cc966bbbb80 GIT binary patch literal 20122 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 literal 0 HcmV?d00001 From 3d4e54ce1561be9ad2ebe8129a53acf329b0b25e Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Sun, 3 Feb 2019 13:01:34 +1100 Subject: [PATCH 116/153] fix: Add icon.png amongst _Template.png files otherwise does not compile --- .../static/assets/icons/mac/icon.png | Bin 0 -> 2224 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 packages/fether-electron/static/assets/icons/mac/icon.png diff --git a/packages/fether-electron/static/assets/icons/mac/icon.png b/packages/fether-electron/static/assets/icons/mac/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..4b4e0046031a4b83eb5808a32cedb9ea27e568ec GIT binary patch literal 2224 zcmb_ed2AF_7@vhuEk`XuN zBs78%A|V0-LNzr+O)ONya8Wz~oPXIf7}YXq4)Kb@47CSaiv(5NNc*o~8?F;r9C*itr3hLb)J z(}HVEuy{>Py|SiB5mjvdJaleaf&p}3$!J=SCsI<{jb-9W@ZFv!Ff?OgHMud54Tvra z*P=ed1Ssp|aD{S_C@(rGj&!lq6DUnmJVCMq$>Ag=k%B~1XzqhSG*gXAb^gj6796>; zm}Mm;f@o=Jakel{!)zodQ4|T1CTJRm7I>;PVaaJck(!>5;0Gzi)RLBFBv3n|95I?L zHwJf_rJyIn;X>d~+-rv9Iu^Ej$fuuC?Z@l2Xjg#dA&!+0ski7F6E#th3y#f-lR zU0BW}!UllZk`|d76pbAB8%nbsGURt-aK))=suTqgO5{ZaXLvb+yHq-g3o^^&t|-Tm zG8+*hjF68roWIA*`zu`(PX+uQiVBF{0ORwB0a9S;N|E#U^1h)&%90Zb$YW~|TLrX0 zlY)X%E}4SZJd2B>0&s-{G$RW@pcp0NFZoO$TZUP081cMPYx9{veLh>60y;A+D_X)% z&#WO{z%N_CjX?_$Cuy8y>PZm_7s~f>3VxGW)3Bjx(bm71Ql!Li63g9V3J;DdTk^je ztBMpgOkIW=(sa2I5XnR%h89XB`HZ+>LSVQ%X6Ss#=c_f1s1}C{sk$mJ8VdM0O5`}4 zc2f2+$yU`5Ol>t#D@{X3Gdh>F;c~1*7(hlMI2DNsxQk*0T;xcA)2b^P6g)IiP6s%fnt~V?O zt8#B~4I;wBCCQ3?&LK@1GO@Q|PYy>zl%q1K3Je~VBMgLNqPQr-9zwAqU`Z~*vOJgf zZ;1gIa!A2p6)8q?QTZxnVNyoaYLQLgX@p1OK2??VRAO?X5y0k4WVqU0>c2C(Kk;V) zhhub)F8^mngiR@1E+Q+o!AfS{Pt_%%7KHzr3Df&Sth)a$|^Q(gtuTi z@RK0h3-=+oK1J{qwxb1ClAZ=Y`UE8QhAKZAlbN1Bj z=T|;cviG;pyz}YzK7Yl(YV5=@TOMf`_2aK6#$4^0+|ypXQ&*}34Ksd6PC4#uU56dK z)HnXj%x#ChoKx{=a6h15{mCpX3v@jB_LAMv?XefT!z=yX0d>`g*sk~J6W{*UU_4Xb* z`N@bR)?ZF~2Cx9GLRB}ek51BZ`n_4mE-N6(pC zr`8{By*sUc&xLQy(^Jyr54EA)JLh8k$co_2_OH9XYwat4$dSBU!a24DFHccc_I~l~ zm0P#{9h06rc Date: Sun, 3 Feb 2019 15:33:02 +1100 Subject: [PATCH 117/153] fix: Fix quality of icon used in balloon on Windows to be 64x64px --- .../src/main/app/methods/showTrayBalloon.js | 16 ++++++++++++++-- .../static/assets/icons/win/iconBalloon.png | Bin 0 -> 6959 bytes 2 files changed, 14 insertions(+), 2 deletions(-) create mode 100644 packages/fether-electron/static/assets/icons/win/iconBalloon.png diff --git a/packages/fether-electron/src/main/app/methods/showTrayBalloon.js b/packages/fether-electron/src/main/app/methods/showTrayBalloon.js index 421c1a37a..27a35f2ac 100644 --- a/packages/fether-electron/src/main/app/methods/showTrayBalloon.js +++ b/packages/fether-electron/src/main/app/methods/showTrayBalloon.js @@ -3,8 +3,19 @@ // // SPDX-License-Identifier: BSD-3-Clause +import path from './path'; + +import staticPath from '../utils/staticPath'; import Pino from '../utils/pino'; +const iconBalloonPath = path.join( + staticPath, + 'assets', + 'icons', + 'win', + 'iconBalloon.png' +); + const pino = Pino(); function showTrayBalloon () { @@ -13,8 +24,9 @@ function showTrayBalloon () { pino.info('Showing Tray Balloon'); tray.displayBalloon({ - title: 'Fether Menu', - content: `Press ALT in the Fether window to toggle the menu` + content: `Press ALT in the Fether window to toggle the menu`, + icon: iconBalloonPath, + title: 'Fether Menu' }); } diff --git a/packages/fether-electron/static/assets/icons/win/iconBalloon.png b/packages/fether-electron/static/assets/icons/win/iconBalloon.png new file mode 100644 index 0000000000000000000000000000000000000000..e477eaf55f88820cf0f9ae4b443d824426d80bdd GIT binary patch literal 6959 zcmb_>2{@GN-~W&@goGsNG?r?_n8h{*$r@wHmMGhpMI&P{GuDWqDPrtGWlcf|p^$7P z&2gMUlg3t(Buga8();Lide8e_zxVzBuJ`)S^*l4rb3fnvyWOAfaz7JiYjaFgSXLMW z0*P9fo7e-tM>kLKHV}w!*w4@$xDoOd|UP4?4Qm}`2d03j3f6;5heBdq<6iD$^>VSz-4 zFdIjF*jc;|LBZe%L@xvbFrX0WI7kS^*N=t?(O3Av7Xw^x4#O27KS=0j^%V>^1wx#y zZ6U_gKq5p_O$&xcY9JumI%-HQgoY+k6@o$_wc!X&I6@1CKw=PR3 z?+@VwJe=rDq!9h+G=LWQi`M@Pl}@Fdq5co7e?9&$0sz-qTmO>rFLj|%eu<#bO@jb4 zemdk|Qqvqm{fTgUB8|!j#1l<}05ugit?|bg2NH2~YM>*P>ihRX+5W9E#MpRqVbBn$ zH4abq+q6UZAG3%iI66^ZVUq%eL;;5*3WY&xVl*^WkiZ%u{vx%e63C>`U!*!P1PVAD zQR)~?1O|opFQfo&2sk?K|4B^1V@T9M3J$QEOu=~*;r@Q!3XosE#28b3seyoCKs)t+ zj$0TT+XhleWMAL`&Hk7X#KP2A3#p@}1w*MJf2eD1jj`~f(Q$rwqJ@dR0^lJvGMRw! zBI*!HNHhtC&{o%gX=rO`z;v{95HO;KHVUn+i9=~>{+e$>#WOZ>usQ#)kRVX;0FVDv zPm4gn>1YtuVcOc-1QJHj@oPDdh`;1fofbF zG;VwBrJbfi!gi_&dHv`be|cq4Qr)43`DZ=`LTJ zJGUGhIk^@&sbQ@A2r(aHpx3*FQ}cd${bW$xYzN5y>pbpG3_lCkx*VaD_Ca?KD;gRP z0=+YlOfR&rU{0>kilAY_o(O&Yt+rT0Wz)J-rVYGxl}4s})iMJ+RVycD8a)?2_i<@; z$^ButWbeWgQf+VGr9yDc?X~(Gt4JpPCDO&t=AEaDH0bDb(9R1xL7v|?)SXg>*kadh z1aFd=I2pMk=VU;+6ZzAabE6kkImOZ2RE7;kdJte+YX4=N%(nrbnWdP?Lq2!*P12Ou zy|Z7!PGZ>Wt&Os>OWPXVX2vZoyY3Y3f)@9FDID;TXXDZA7)MNEwfz(!HO_?pzN=WQ zZ5AuE@B#xv$6QaF)nSL96lVqBj?_A$RqtNHm)iaI(@j7W7CC42sTK5R2z+ zS;>P|m9B9T`|hr1lIivzc@0$BPRTd{(C>kAg2M>0#H6IFJx+_-F|B!{ z=AE#fP?ZGNwnnwvnm4kN(`HZZ-FYW^->ov?6DM{G@PXycp--2?hSj!lGevCZaeR8c zmT2~Bfm>4$<<$j-h*e)Kg$F?zmO6gh+DrSMf-OE%(&xf`Agbc8zq@6Q!-VAbOKvYB1qAG+LG8{k0`YzprmGRjF#O>{{q>k2r?K|PrWT>jbu z7c`vTZjqVd91vVy&2DQYe$vYuN4H$DDS5xJfEsU9+r;Pkp$rf2r%#_YZ_DRS(etO* z4VKo$MQRI7H^cc`v_t1qfw3Fe{rEK+S6 zyc=p8w-VLBS@aTD5o=;Xl;hxXEkd{M+KU9dbT20mE7UaKEY%7w(b zeiY<$<+=qYn&c0Yi-2R$ryU{E@1uDswO>U_c*nPvB&Tu)o1BxBkd$Nq6>bkdU|}S~ zI^CgQd zRtG1-A~<2%j00!ws<=D5kX}Z~J%riU=t|x*%$#({&I?AfT{X9_o#h2t_uVZuQ3zmE zJFi*xY3%oF;8i`H*lz1^I97gJ;{oG7jql}7r(15Es_>d}-h-1dNw;rocGaZ?1ni6z z$0`@+PNqD1WcspRzv)f=REl?Q+rlT!=Qp{TTH>b9wo3|4JdcYLlD)w9VQJf3sC#H& zAXl9Ub#<4p|NZcC*arc* zF1})^9+Kn*qt{8HxvPqObdQhWViIM-xx`9;*X3D+NI}^LmCKLb1n=w0t{CvSXksT& zOdpoIE6e*58((-d^+s<4@A~~upQ?)n%0i)OHf@N6so|#JJ^=Kh#@ZW@`1Xd!v5^+m z#r0)j;ldhMd(vjd(PlC%__eI8uWjw^=L($Vwj8a3W?((Y4ZH?f)+fFil1|9{Sle|; z=oOXe+)sLfyr6}?K8GF%nEGepMq)O78+*KUv6(S(F@gyb^1Ul7*SfF|p=F~Ry|0JWdw?a@fg9ZqLbIEmE;c_TUi|v4j_;ZB&asuH?<5(L_yyy> zyN5#9F_Vq02QNRaK%_^hRwbD+AyEa>kl3T*v5Ljjsnz%HIOnJPAwSJUwUV|yUC?vo zw14hT-_!LeX&fzf=+L3+7kr6Up6ZwM&eMFn-Xs%wrS4T1w+M=@bs`ctCU$yZWem}M zti2VJdc93ie81K06Rc4!vW41?E_*ZF3^bn1S3K_T@3-YQ-i7G#mbBFCjUl?&V)tuW zNtQZ(cxs~XX>!14NzdqsWLa6Hi(PsSPKHa7esm4R*L(g&6(>QYccFDr@A2cu%*clx zZ??YX*hxL`B#~Gw+0q|Ap)PVnns`6mRFhvmVv1`S!!6y^t@j$F;o zUYR>p@r6aI&2~Jo^ooudE{cu1?Rpw_OEl}nr{k?C)k5g=Qx#6~8CX7%WDemhi|oGh z>&6Z*qXh>C2U(DYY@(6cm6^j>FZxz{i(Sf^7YL~C_bhkwlD=fZ)T|%pksEQ zw`dk0x$E8gTLo|6h;uniJvMdmfW^%WtY`+7qOtYe*U587{3$+7&OH3xZh#T3eO6P)^^SMq< zJ+}$TKJkSgKP<0O|7;u7Jj)_`&|E$Ogm3?mN?OP>AMBWy}kT|PiP$eV&L!%#% zI*Xjj3kH1Mk0}?gM}BWBF2>*DPQzt7K|Q2JilwC`Ty`ip{DI25ckk*GbXgm<13vo} z^mbTUUS2`7$#PwH?Mn$xfh9=}Sh6^)PVpEU0yd`o`L(^>sGyv@Tro7Ohmenzt5dZc zs`ah{(*6-3w)e1bYFW9tH|4tGXp1zfhoh_QuRAW5wl0?4BnM}5Cb}b5zc9eX#~X5b zD)gUA=Z!_w6AN6`@IgV+0aBuGkDLXP%X-TO1*|{@O2#J^Dc_KNGY-ujn3^Jc2aw}ZhcK;Y4ElWP0)VU=j=lL&h{e4{{nZ76PldC)mfM*`qKpe`*_R=D&PCJ|hjIMz6==oY0A4_;XL7*V52%fKGU=$))^mU__vG_>XVC5I4EniO zyU@ev8ILhK{#f-V&{eVLlqhj~h1j(xJNW;opD|YD*xNQ1X>Ukq|ciNveoT z>cRL&_7Mrhou)f;L*Hc^i*)?%S28jwtSIDP2JR4NLat?W6K16aa3`fq8%|{|nROsq zqy_lmA1MeJqOXqMD>=?E8&!@xV3RCfXr8)O(cRtcBiALFbMpZd%(P&S`*9iTk#F$Ve{Y?&y_$SxhJVW8^548S8gZ6#O)!}-VY9t z`@TfSoY;TC0P#jVD=+V&l7;PwrBg1M2GXq8J1AW(3B;G|$yLySWRsQ98imo!Zi2fg z2q&|RRp3!Yeg%t9je>yT)+K$*2PNXN2N=5SMM6p6{nXvDp#Z3*w!XeoR`$?9yplIF za%^}UA=6h>&pW@M`;TD(7i5T{{Yh$X`mZN-QOxH^P+QKK3{85vkMC(2PFYhBW ziLXQXY6d^9KA-9rErjNxpL@By*s{+$oF--ZhjS@C7;`Z)7LO+zl@UL}XoG`v^8cUtrd*sAYbp;P&Fk5Wg3fk6`X ze(G#cQ!uatQ7+bqSMYIpq1`w#^3xp$l#HjInJDn_f_@8j3r^P6Pwys-sDRrC zhy9ih11&t;UKk6N=p_5Z=^WxECWyNT;XFOPurfr+o!lsaVyjY# zI=8vgKt8gQk_R)}TOw9-?N2O;fX+1VJVZL?Nk&gxrA(WEW^VSlk_23cIp+Lu^n4RJ zXVgw=tDRhQr$DMw^yEr8u*5JXld*_uODSw?G!QYi#R5_HyY?>A!Qr{(s+;-C zh_Tih5nrB}%r^0@xCF^qCnG!YuSb}OSS5=t^<#GE6kCY~z?%p1G7V@XCe^4; z+hc(Zdh7|yH+BLt-GaCE|EQ7JP+N)qe!68Y#$K3HQ&46x-~727*j_9jvkQ5MJH>rc zc*#}m;)O@1QO{`$D{CddJBte-ae;zozFMOcmlyj|mH0)rvxsdqs_jtz-o>u*oSJaGYBvSO5~%EN}U+_!kp82XRfm3z5p z_F_I%7$ieb&pt0wG;hTVP?I*TZr+nrA$C&~s13ktj@KDga{iYK-**lcxvDLbPMn}J zQc`qje17umK?=lD7hV>%lvWjW1#^)t(z0iPvvCwH16Q@aTkCme>+ z@o%7P8|A6$g_zELI3+%(Jmn!Lyhv+}9Pob1PX-c@P+eVpejM#IbGL5yv4D?afm=$L zcBzGcfUpPEMawcQ7mM7325$s6+;HL}2UPa15#~=udCZCB`SF+R{VoVjPq&%v9go`l OOUuI4#-!57lldQ#5;Y?L literal 0 HcmV?d00001 From adf87378a3694e357bddfa72315abc65b13e7fff Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Tue, 5 Feb 2019 13:37:01 +1100 Subject: [PATCH 118/153] review-fix: Fix incorrectly loaded path dependency --- .../fether-electron/src/main/app/methods/showTrayBalloon.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/fether-electron/src/main/app/methods/showTrayBalloon.js b/packages/fether-electron/src/main/app/methods/showTrayBalloon.js index 27a35f2ac..3ff534955 100644 --- a/packages/fether-electron/src/main/app/methods/showTrayBalloon.js +++ b/packages/fether-electron/src/main/app/methods/showTrayBalloon.js @@ -3,7 +3,7 @@ // // SPDX-License-Identifier: BSD-3-Clause -import path from './path'; +import path from 'path'; import staticPath from '../utils/staticPath'; import Pino from '../utils/pino'; From 3f3d288fac38f6bfa3840bb4d260f9b8da0c569c Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Tue, 5 Feb 2019 14:19:01 +1100 Subject: [PATCH 119/153] fix: Fixes Cannot read getGlobal of undefined since remote must be enabled in fether-electron config to use fether-react --- packages/fether-electron/src/main/app/options/config/index.js | 2 +- packages/fether-react/src/stores/parityStore.js | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/fether-electron/src/main/app/options/config/index.js b/packages/fether-electron/src/main/app/options/config/index.js index 5dda88173..46b6a1715 100644 --- a/packages/fether-electron/src/main/app/options/config/index.js +++ b/packages/fether-electron/src/main/app/options/config/index.js @@ -62,7 +62,7 @@ const DEFAULT_OPTIONS = { tabbingIdentifier: 'parity', webPreferences: { devTools: shouldUseDevTools, // Security - enableRemoteModule: false + enableRemoteModule: true // Remote is required in fether-react parityStore.js }, width: 360, windowPosition: windowPosition, // Required diff --git a/packages/fether-react/src/stores/parityStore.js b/packages/fether-react/src/stores/parityStore.js index 15925fa32..c5225f76e 100644 --- a/packages/fether-react/src/stores/parityStore.js +++ b/packages/fether-react/src/stores/parityStore.js @@ -43,6 +43,9 @@ export class ParityStore { this.setToken(token); } + // FIXME - consider moving to start of this constructor block since + // if `setToken` method is called then `connectToApi` is called, which + // requires `electron` to be defined if (!electron) { debug( 'Not in Electron, ParityStore will only have limited capabilities.' From 27ca625dd756c90f9e8e7da862484e6b8c280e8c Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Tue, 5 Feb 2019 14:20:27 +1100 Subject: [PATCH 120/153] review-fix: Remove empty craco config file from fether electron --- packages/fether-electron/craco.config.js | 1 - 1 file changed, 1 deletion(-) delete mode 100644 packages/fether-electron/craco.config.js diff --git a/packages/fether-electron/craco.config.js b/packages/fether-electron/craco.config.js deleted file mode 100644 index f053ebf79..000000000 --- a/packages/fether-electron/craco.config.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = {}; From dba6a222a762c7609899fe7c4ff206a4a6e53d0d Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Tue, 5 Feb 2019 14:47:02 +1100 Subject: [PATCH 121/153] fix: Add changes made in PR #403 to fix bug #401 --- packages/fether-electron/package.json | 13 +++++---- yarn.lock | 42 ++++++++++++--------------- 2 files changed, 25 insertions(+), 30 deletions(-) diff --git a/packages/fether-electron/package.json b/packages/fether-electron/package.json index ffdaef52e..146ab665a 100644 --- a/packages/fether-electron/package.json +++ b/packages/fether-electron/package.json @@ -40,26 +40,27 @@ }, "dependencies": { "@parity/electron": "^4.0.0", - "commander": "^2.15.1", + "ansi-styles": "^3.2.1", + "commander": "^2.19.0", "commander-remaining-args": "^1.2.0", "electron-positioner": "^4.1.0", "electron-settings": "^3.2.0", "fether-react": "^0.3.0", "pino": "^4.16.1", "pino-multi-stream": "^3.1.2", - "source-map-support": "^0.5.6" + "source-map-support": "^0.5.10" }, "devDependencies": { "@babel/cli": "^7.0.0-beta.49", "@babel/core": "^7.0.0-beta.49", "@babel/preset-env": "^7.0.0-beta.49", "babel-jest": "^24.0.0", - "copyfiles": "^2.0.0", + "copyfiles": "^2.1.0", "cross-env": "^5.2.0", "electron": "^4.0.1", - "electron-builder": "^20.29.0", - "electron-webpack": "^2.1.2", + "electron-builder": "^20.38.5", + "electron-webpack": "^2.6.1", "jest": "^24.0.0", - "webpack": "^4.7.0" + "webpack": "^4.29.1" } } \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index fe89e32a9..bee995352 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3926,7 +3926,7 @@ commander@2.17.x, commander@~2.17.1: resolved "https://registry.yarnpkg.com/commander/-/commander-2.17.1.tgz#bd77ab7de6de94205ceacc72f1716d29f20a77bf" integrity sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg== -commander@^2.11.0, commander@^2.15.1, commander@^2.8.1: +commander@^2.11.0, commander@^2.19.0, commander@^2.8.1: version "2.19.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a" integrity sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg== @@ -4183,7 +4183,7 @@ copy-descriptor@^0.1.0: resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= -copyfiles@^2.0.0: +copyfiles@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/copyfiles/-/copyfiles-2.1.0.tgz#0e2a4188162d6b2f3c5adfe34e9c0bd564d23164" integrity sha512-cAeDE0vL/koE9WSEGxqPpSyvU638Kgfu6wfrnj7kqp9FWa1CWsU54Coo6sdYZP4GstWa39tL/wIVJWfXcujgNA== @@ -5155,7 +5155,7 @@ ejs@^2.6.1: resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.6.1.tgz#498ec0d495655abc6f23cd61868d926464071aa0" integrity sha512-0xy4A/twfrRCnkhfk8ErDi5DqdAsAqeGxht4xkCUrsvhhbQNs7E+4jV0CN7+NKIY0aHE72+XvqtBIXzD31ZbXQ== -electron-builder@^20.29.0: +electron-builder@^20.38.5: version "20.38.5" resolved "https://registry.yarnpkg.com/electron-builder/-/electron-builder-20.38.5.tgz#31b3913a68b4911afd4cfc7bcd2522c5808040cd" integrity sha512-p88IDHhH2J4hA6KwRBJY+OfVZuFtFIShY3Uh/TwYAfbX0v1RhKZytuGdO8sty2zcWxDYX74xDBv+X9oN6qEIRQ== @@ -5262,7 +5262,7 @@ electron-webpack-js@~2.3.0: babel-loader "^8.0.5" babel-plugin-component "^1.1.1" -electron-webpack@^2.1.2: +electron-webpack@^2.6.1: version "2.6.1" resolved "https://registry.yarnpkg.com/electron-webpack/-/electron-webpack-2.6.1.tgz#69425faa780215586f8290b55279bad1d2f6c974" integrity sha512-PHr5/5syGsHzuFxQCzLuvBmPfE+MCDgllcR6s6nDrQC69pZ2ICACiKVVFO+Q2wVb2XBfH31jozaFZ6hscreuwg== @@ -7621,11 +7621,6 @@ ip-regex@^2.1.0: resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-2.1.0.tgz#fa78bf5d2e6913c911ce9f819ee5146bb6d844e9" integrity sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk= -ip-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-3.0.0.tgz#0a934694b4066558c46294244a23cc33116bf732" - integrity sha512-T8wDtjy+Qf2TAPDQmBp0eGKJ8GavlWlUnamr3wRn6vvdZlKVuJXXMlSncYFRYgVHOM3If5NR1H4+OvVQU9Idvg== - ip@^1.1.0, ip@^1.1.5: version "1.1.5" resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" @@ -9903,7 +9898,12 @@ miller-rabin@^4.0.0: bn.js "^4.0.0" brorand "^1.0.1" -"mime-db@>= 1.36.0 < 2", mime-db@^1.28.0, mime-db@~1.37.0: +"mime-db@>= 1.36.0 < 2", mime-db@^1.28.0: + version "1.38.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.38.0.tgz#1a2aab16da9eb167b49c6e4df2d9c68d63d8e2ad" + integrity sha512-bqVioMFFzc2awcdJZIzR3HjZFX20QhilVS7hytkKrv7xFAn8bM1gzc/FOX2awLISvWe0PV8ptFKcon+wZ5qYkg== + +mime-db@~1.37.0: version "1.37.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.37.0.tgz#0b6a0ce6fdbe9576e25f1f2d2fde8830dc0ad0d8" integrity sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg== @@ -14723,11 +14723,11 @@ toposort@^1.0.0: integrity sha1-LmhELZ9k7HILjMieZEOsbKqVACk= tough-cookie@>=2.3.3: - version "3.0.0" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-3.0.0.tgz#d2bceddebde633153ff20a52fa844a0dc71dacef" - integrity sha512-LHMvg+RBP/mAVNqVbOX8t+iJ+tqhBA/t49DuI7+IDAWHrASnesqSu1vWbKB7UrE2yk+HMFUBMadRGMkB4VCfog== + version "3.0.1" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-3.0.1.tgz#9df4f57e739c26930a018184887f4adb7dca73b2" + integrity sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg== dependencies: - ip-regex "^3.0.0" + ip-regex "^2.1.0" psl "^1.1.28" punycode "^2.1.1" @@ -15345,15 +15345,10 @@ webidl-conversions@^4.0.2: resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" integrity sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg== -webpack-cli-scripts@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/webpack-cli-scripts/-/webpack-cli-scripts-1.0.2.tgz#d03894217830e2b1e3e6fdbc2b175059942d94f6" - integrity sha512-U/ggmuoxclQgwtot3saL/nfVioJZ3CIYrontvStCfksIE+j7O66LVd29hgPP6cUBVMOnqyaELCsqUf9arNCpMQ== - webpack-cli@^3.1.2: - version "3.2.2" - resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-3.2.2.tgz#1e6a638ff81d491d0bec7db11910a55450e4189a" - integrity sha512-RMYcJeEjNgmCi5c3UwpdWjy+QIxuN8W/u/Dq+FUxWScCwXpOdfSEhqKVov3GFbsB4cS9/hdciJ4Y36vgTaHMWw== + version "3.2.3" + resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-3.2.3.tgz#13653549adfd8ccd920ad7be1ef868bacc22e346" + integrity sha512-Ik3SjV6uJtWIAN5jp5ZuBMWEAaP5E4V78XJ2nI+paFPh8v4HPSwo/myN0r29Xc/6ZKnd2IdrAlpSgNOu2CDQ6Q== dependencies: chalk "^2.4.1" cross-spawn "^6.0.5" @@ -15365,7 +15360,6 @@ webpack-cli@^3.1.2: loader-utils "^1.1.0" supports-color "^5.5.0" v8-compile-cache "^2.0.2" - webpack-cli-scripts "^1.0.2" yargs "^12.0.4" webpack-dev-middleware@3.4.0: @@ -15483,7 +15477,7 @@ webpack@4.19.1: watchpack "^1.5.0" webpack-sources "^1.2.0" -webpack@^4.7.0: +webpack@^4.29.1: version "4.29.1" resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.29.1.tgz#a6533d7bc6a6b1ed188cb029d53d231be777e175" integrity sha512-dY3KyQIVeg6cDPj9G5Bnjy9Pt9SoCpbNWl0RDKHstbd3MWe0dG9ri4RQRpCm43iToy3zoA1IMOpFkJ8Clnc7FQ== From 0d9f269913998d34e96de38573b207c2f6553c25 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Tue, 5 Feb 2019 15:02:34 +1100 Subject: [PATCH 122/153] test: Update to latest Babel 7 plugins following migration guide and remove stage-0 so test passes --- packages/fether-electron/babel.config.js | 2 +- packages/fether-electron/package.json | 7 ++++--- packages/fether-react/babel.config.js | 6 +----- packages/fether-react/package.json | 7 ++++--- yarn.lock | 6 +++--- 5 files changed, 13 insertions(+), 15 deletions(-) diff --git a/packages/fether-electron/babel.config.js b/packages/fether-electron/babel.config.js index f3a623b23..7238a1fe2 100644 --- a/packages/fether-electron/babel.config.js +++ b/packages/fether-electron/babel.config.js @@ -1,4 +1,4 @@ module.exports = { - plugins: ['@babel/plugin-proposal-class-properties'], + plugins: [['@babel/plugin-proposal-class-properties', { loose: false }]], presets: ['@babel/preset-env'] }; diff --git a/packages/fether-electron/package.json b/packages/fether-electron/package.json index 146ab665a..935a560c2 100644 --- a/packages/fether-electron/package.json +++ b/packages/fether-electron/package.json @@ -51,9 +51,10 @@ "source-map-support": "^0.5.10" }, "devDependencies": { - "@babel/cli": "^7.0.0-beta.49", - "@babel/core": "^7.0.0-beta.49", - "@babel/preset-env": "^7.0.0-beta.49", + "@babel/cli": "^7.2.3", + "@babel/core": "^7.2.2", + "@babel/plugin-proposal-class-properties": "^7.3.0", + "@babel/preset-env": "^7.3.1", "babel-jest": "^24.0.0", "copyfiles": "^2.1.0", "cross-env": "^5.2.0", diff --git a/packages/fether-react/babel.config.js b/packages/fether-react/babel.config.js index 496fdd838..6eaaa0851 100644 --- a/packages/fether-react/babel.config.js +++ b/packages/fether-react/babel.config.js @@ -6,9 +6,5 @@ module.exports = { '@babel/plugin-transform-modules-commonjs', '@babel/plugin-transform-runtime' ], - presets: [ - '@babel/preset-env', - '@babel/preset-react', - ['@babel/preset-stage-0', { decoratorsLegacy: true }] - ] + presets: ['@babel/preset-env', '@babel/preset-react'] }; diff --git a/packages/fether-react/package.json b/packages/fether-react/package.json index ea20f5194..387051bbc 100644 --- a/packages/fether-react/package.json +++ b/packages/fether-react/package.json @@ -72,13 +72,14 @@ "rxjs": "^6.2.0" }, "devDependencies": { - "@babel/cli": "^7.0.0-beta.49", - "@babel/core": "^7.0.0-beta.49", + "@babel/cli": "^7.2.3", + "@babel/core": "^7.2.2", "@babel/plugin-transform-modules-commonjs": "^7.2.0", "@babel/plugin-transform-runtime": "^7.2.0", "@babel/plugin-proposal-pipeline-operator": "^7.3.0", "@babel/plugin-proposal-decorators": "^7.2.0", - "@babel/preset-env": "^7.0.0-beta.49", + "@babel/plugin-proposal-class-properties": "^7.3.0", + "@babel/preset-env": "^7.3.1", "babel-jest": "^24.0.0", "capitalize": "^1.0.0", "jest": "^24.0.0", diff --git a/yarn.lock b/yarn.lock index bee995352..f5a56bc7f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12,7 +12,7 @@ resolved "https://registry.yarnpkg.com/7zip/-/7zip-0.0.6.tgz#9cafb171af82329490353b4816f03347aa150a30" integrity sha1-nK+xca+CMpSQNTtIFvAzR6oVCjA= -"@babel/cli@^7.0.0-beta.49", "@babel/cli@^7.2.3": +"@babel/cli@^7.2.3": version "7.2.3" resolved "https://registry.yarnpkg.com/@babel/cli/-/cli-7.2.3.tgz#1b262e42a3e959d28ab3d205ba2718e1923cfee6" integrity sha512-bfna97nmJV6nDJhXNPeEfxyMjWnt6+IjUAaDPiYRTBlm8L41n8nvw6UAqUCbvpFfU246gHPxW7sfWwqtF4FcYA== @@ -56,7 +56,7 @@ semver "^5.4.1" source-map "^0.5.0" -"@babel/core@^7.0.0-beta.49", "@babel/core@^7.0.1", "@babel/core@^7.1.0", "@babel/core@^7.2.2": +"@babel/core@^7.0.1", "@babel/core@^7.1.0", "@babel/core@^7.2.2": version "7.2.2" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.2.2.tgz#07adba6dde27bb5ad8d8672f15fde3e08184a687" integrity sha512-59vB0RWt09cAct5EIe58+NzGP4TFSD3Bz//2/ELy3ZeTeKF6VTD1AXlH8BGGbCX0PuobZBsIzO7IAI9PH67eKw== @@ -854,7 +854,7 @@ js-levenshtein "^1.1.3" semver "^5.3.0" -"@babel/preset-env@^7.0.0", "@babel/preset-env@^7.0.0-beta.49", "@babel/preset-env@^7.2.3", "@babel/preset-env@^7.3.1": +"@babel/preset-env@^7.0.0", "@babel/preset-env@^7.2.3", "@babel/preset-env@^7.3.1": version "7.3.1" resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.3.1.tgz#389e8ca6b17ae67aaf9a2111665030be923515db" integrity sha512-FHKrD6Dxf30e8xgHQO0zJZpUPfVZg+Xwgz5/RdSWCbza9QLNk4Qbp40ctRoqDxml3O8RMzB1DU55SXeDG6PqHQ== From e9b95dc02dd4b32db2d9503db1c366afdd8b2d89 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Tue, 5 Feb 2019 17:10:16 +1100 Subject: [PATCH 123/153] WIP --- .../fether-electron/src/main/app/index.js | 108 +++++++++--------- .../app/methods/calculateWindowPosition.js | 8 +- .../src/main/app/methods/createPositioner.js | 6 +- .../src/main/app/methods/createTray.js | 8 +- .../src/main/app/methods/createWindow.js | 22 ++-- .../src/main/app/methods/fixWindowPosition.js | 12 +- .../src/main/app/methods/hideWindow.js | 14 ++- .../src/main/app/methods/loadTray.js | 16 +-- .../src/main/app/methods/moveWindowUp.js | 18 +-- .../src/main/app/methods/onTrayClick.js | 12 +- .../src/main/app/methods/onWindowClose.js | 6 +- .../app/methods/processSaveWindowPosition.js | 22 ++-- .../src/main/app/methods/setupAppListeners.js | 34 +++--- .../src/main/app/methods/setupDebug.js | 8 +- .../src/main/app/methods/setupMenu.js | 6 +- .../main/app/methods/setupParityEthereum.js | 6 +- .../main/app/methods/setupRequestListeners.js | 10 +- .../src/main/app/methods/setupSecurity.js | 6 +- .../main/app/methods/setupWin32Listeners.js | 26 +++-- .../main/app/methods/setupWindowListeners.js | 38 +++--- .../src/main/app/methods/showTrayBalloon.js | 6 +- .../src/main/app/methods/showWindow.js | 22 ++-- .../src/main/app/methods/updateProgress.js | 8 +- .../src/main/app/methods/windowClear.js | 12 +- 24 files changed, 240 insertions(+), 194 deletions(-) diff --git a/packages/fether-electron/src/main/app/index.js b/packages/fether-electron/src/main/app/index.js index c1d95a362..bb8c20a11 100644 --- a/packages/fether-electron/src/main/app/index.js +++ b/packages/fether-electron/src/main/app/index.js @@ -49,60 +49,62 @@ class FetherApp { this.fetherApp.app = electronApp; this.fetherApp.options = options; - } -} -FetherApp.prototype.setupAppListeners = setupAppListeners; -FetherApp.prototype.createWindow = createWindow; -FetherApp.prototype.updateProgress = updateProgress; -FetherApp.prototype.createPositioner = createPositioner; -FetherApp.prototype.setupRequestListeners = setupRequestListeners; -FetherApp.prototype.createTray = createTray; -FetherApp.prototype.loadTray = loadTray; -FetherApp.prototype.showTrayBalloon = showTrayBalloon; -FetherApp.prototype.setupDebug = setupDebug; -FetherApp.prototype.setupSecurity = setupSecurity; -FetherApp.prototype.setupLogger = setupLogger; -FetherApp.prototype.setupParityEthereum = setupParityEthereum; -FetherApp.prototype.setupGlobals = setupGlobals; -FetherApp.prototype.setupMenu = setupMenu; -FetherApp.prototype.getScreenResolution = getScreenResolution; -FetherApp.prototype.calculateWindowPosition = calculateWindowPosition; -FetherApp.prototype.onTrayClick = onTrayClick; -FetherApp.prototype.fixWindowPosition = fixWindowPosition; -FetherApp.prototype.showWindow = showWindow; -FetherApp.prototype.moveWindowUp = moveWindowUp; -FetherApp.prototype.processSaveWindowPosition = processSaveWindowPosition; -FetherApp.prototype.hideWindow = hideWindow; -FetherApp.prototype.windowClear = windowClear; -FetherApp.prototype.onWindowClose = onWindowClose; -FetherApp.prototype.setupWindowListeners = setupWindowListeners; -FetherApp.prototype.setupWin32Listeners = setupWin32Listeners; + // Context of fetherApp passed to each method + this.fetherApp.setupAppListeners = setupAppListeners(this); + this.fetherApp.createWindow = createWindow(this); + this.fetherApp.updateProgress = updateProgress(this); + this.fetherApp.createPositioner = createPositioner(this); + this.fetherApp.setupRequestListeners = setupRequestListeners(this); + this.fetherApp.createTray = createTray(this); + this.fetherApp.loadTray = loadTray(this); + this.fetherApp.showTrayBalloon = showTrayBalloon(this); + this.fetherApp.setupDebug = setupDebug(this); + this.fetherApp.setupSecurity = setupSecurity(this); + this.fetherApp.setupLogger = setupLogger(); + this.fetherApp.setupParityEthereum = setupParityEthereum(this); + this.fetherApp.setupGlobals = setupGlobals(); + this.fetherApp.setupMenu = setupMenu(this); + this.fetherApp.getScreenResolution = getScreenResolution(this); + this.fetherApp.calculateWindowPosition = calculateWindowPosition(this); + this.fetherApp.getScreenResolution = getScreenResolution(); + this.fetherApp.onTrayClick = onTrayClick(this); + this.fetherApp.fixWindowPosition = fixWindowPosition(this); + this.fetherApp.getScreenResolution = getScreenResolution(this); + this.fetherApp.showWindow = showWindow(this); + this.fetherApp.moveWindowUp = moveWindowUp(this); + this.fetherApp.processSaveWindowPosition = processSaveWindowPosition(this); + this.fetherApp.hideWindow = hideWindow(this); + this.fetherApp.windowClear = windowClear(this); + this.fetherApp.onWindowClose = onWindowClose(); + this.fetherApp.setupWindowListeners = setupWindowListeners(this); + this.fetherApp.setupWin32Listeners = setupWin32Listeners(this); + + const { fetherApp } = this; -const createFetherApp = (app, options) => { - const fetherApp = new FetherApp(app, options); + fetherApp.setupAppListeners.apply(fetherApp); + fetherApp.createWindow.apply(fetherApp); + fetherApp.updateProgress.apply(fetherApp, [0.4]); // eslint-disable-line + fetherApp.createPositioner.apply(fetherApp); + fetherApp.setupRequestListeners.apply(fetherApp); + fetherApp.createTray.apply(fetherApp); + fetherApp.updateProgress.apply(fetherApp, [0.6]); // eslint-disable-line + fetherApp.loadTray.apply(fetherApp); + fetherApp.setupDebug.apply(fetherApp); + fetherApp.setupSecurity.apply(fetherApp); + fetherApp.setupLogger.apply(); + fetherApp.setupParityEthereum.apply(fetherApp); + fetherApp.setupGlobals.apply(); + fetherApp.setupMenu.apply(fetherApp); + fetherApp.updateProgress.apply(fetherApp, [0.8]); // eslint-disable-line + fetherApp.showWindow.apply(fetherApp, undefined); + fetherApp.updateProgress.apply(fetherApp, [1.0]); // eslint-disable-line + fetherApp.setupWindowListeners.apply(fetherApp); + fetherApp.setupWin32Listeners.apply(fetherApp); + fetherApp.updateProgress.apply(fetherApp, [-1, "after-create-app"]); // eslint-disable-line + } +} - // Context of fetherApp passed to each method - fetherApp.setupAppListeners.apply(fetherApp); - fetherApp.createWindow.apply(fetherApp); - fetherApp.updateProgress.apply(fetherApp, [0.4]); // eslint-disable-line - fetherApp.createPositioner.apply(fetherApp); - fetherApp.setupRequestListeners.apply(fetherApp); - fetherApp.createTray.apply(fetherApp); - fetherApp.updateProgress.apply(fetherApp, [0.6]); // eslint-disable-line - fetherApp.loadTray.apply(fetherApp); - fetherApp.setupDebug.apply(fetherApp); - fetherApp.setupSecurity.apply(fetherApp); - fetherApp.setupLogger.apply(fetherApp); - fetherApp.setupParityEthereum.apply(fetherApp); - fetherApp.setupGlobals.apply(fetherApp); - fetherApp.setupMenu.apply(fetherApp); - fetherApp.updateProgress.apply(fetherApp, [0.8]); // eslint-disable-line - fetherApp.showWindow.apply(fetherApp, undefined); - fetherApp.updateProgress.apply(fetherApp, [1.0]); // eslint-disable-line - fetherApp.setupWindowListeners.apply(fetherApp); - fetherApp.setupWin32Listeners.apply(fetherApp); - fetherApp.updateProgress.apply(fetherApp, [-1, "after-create-app"]); // eslint-disable-line -}; +const fetherApp = new FetherApp(app, options); -export default createFetherApp; +export default FetherApp; diff --git a/packages/fether-electron/src/main/app/methods/calculateWindowPosition.js b/packages/fether-electron/src/main/app/methods/calculateWindowPosition.js index 7c212db9f..e897f5c23 100644 --- a/packages/fether-electron/src/main/app/methods/calculateWindowPosition.js +++ b/packages/fether-electron/src/main/app/methods/calculateWindowPosition.js @@ -3,12 +3,14 @@ // // SPDX-License-Identifier: BSD-3-Clause -function calculateWindowPosition (trayPos) { - const { cachedBounds, options, positioner, tray } = this.fetherApp; +function calculateWindowPosition (thatFA, trayPos) { + const { fetherApp } = thatFA; + + const { cachedBounds, options, positioner, tray } = fetherApp; if (trayPos && trayPos.x !== 0) { // Cache the bounds - this.fetherApp.cachedBounds = trayPos; + fetherApp.cachedBounds = trayPos; } else if (cachedBounds) { // Cached value will be used if showWindow is called without bounds data trayPos = cachedBounds; diff --git a/packages/fether-electron/src/main/app/methods/createPositioner.js b/packages/fether-electron/src/main/app/methods/createPositioner.js index 6478472cc..676b32364 100644 --- a/packages/fether-electron/src/main/app/methods/createPositioner.js +++ b/packages/fether-electron/src/main/app/methods/createPositioner.js @@ -5,8 +5,10 @@ import Positioner from 'electron-positioner'; -function createPositioner () { - this.fetherApp.positioner = new Positioner(this.fetherApp.window); +function createPositioner (thatFA) { + const { fetherApp } = thatFA; + + fetherApp.positioner = new Positioner(fetherApp.window); } export default createPositioner; diff --git a/packages/fether-electron/src/main/app/methods/createTray.js b/packages/fether-electron/src/main/app/methods/createTray.js index 7c505a707..fb461f839 100644 --- a/packages/fether-electron/src/main/app/methods/createTray.js +++ b/packages/fether-electron/src/main/app/methods/createTray.js @@ -5,11 +5,13 @@ import { Tray } from 'electron'; -function createTray () { - let { app, options } = this.fetherApp; +function createTray (thatFA) { + const { fetherApp } = thatFA; + + let { app, options } = fetherApp; if (options.withTaskbar) { - this.fetherApp.tray = new Tray(options.icon); + fetherApp.tray = new Tray(options.icon); if (process.platform === 'darwin' && app.dock) { app.dock.setIcon(options.iconDock); diff --git a/packages/fether-electron/src/main/app/methods/createWindow.js b/packages/fether-electron/src/main/app/methods/createWindow.js index fc6bbd0ea..2fbda8e01 100644 --- a/packages/fether-electron/src/main/app/methods/createWindow.js +++ b/packages/fether-electron/src/main/app/methods/createWindow.js @@ -7,16 +7,18 @@ import electron from 'electron'; const { BrowserWindow } = electron; -function createWindow () { - const { options } = this.fetherApp; +function createWindow (thatFA) { + const { fetherApp } = thatFA; - this.fetherApp.emit('create-app'); - this.fetherApp.emit('create-window'); + const { options } = fetherApp; - this.fetherApp.window = new BrowserWindow(options); + fetherApp.emit('create-app'); + fetherApp.emit('create-window'); + + fetherApp.window = new BrowserWindow(options); if (options.showOnAllWorkspaces !== false) { - this.fetherApp.window.setVisibleOnAllWorkspaces(true); + fetherApp.window.setVisibleOnAllWorkspaces(true); } if (process.platform !== 'darwin') { @@ -26,15 +28,15 @@ function createWindow () { * of the window when menu open/close toggled. The user will need to be informed * that pressing ALT displays the Fether menu */ - this.fetherApp.window.setAutoHideMenuBar(true); // ALT shows menu bar - this.fetherApp.window.setMenuBarVisibility(false); + fetherApp.window.setAutoHideMenuBar(true); // ALT shows menu bar + fetherApp.window.setMenuBarVisibility(false); } // Opens file:///path/to/build/index.html in prod mode, or whatever is // passed to ELECTRON_START_URL - this.fetherApp.window.loadURL(options.index); + fetherApp.window.loadURL(options.index); - this.fetherApp.emit('after-create-window'); + fetherApp.emit('after-create-window'); } export default createWindow; diff --git a/packages/fether-electron/src/main/app/methods/fixWindowPosition.js b/packages/fether-electron/src/main/app/methods/fixWindowPosition.js index 230038790..4623b66d4 100644 --- a/packages/fether-electron/src/main/app/methods/fixWindowPosition.js +++ b/packages/fether-electron/src/main/app/methods/fixWindowPosition.js @@ -11,8 +11,10 @@ * coordinates of the window are outside the screen bounds the window * will be restored into the users primary screen. */ -function fixWindowPosition (proposedWindowPosition) { - const { trayDepth } = this.fetherApp; +function fixWindowPosition (thatFA, proposedWindowPosition) { + const { fetherApp } = thatFA; + + const { trayDepth } = fetherApp; if (!proposedWindowPosition) { return; @@ -23,10 +25,10 @@ function fixWindowPosition (proposedWindowPosition) { y: undefined }; - const currentScreenResolution = this.getScreenResolution(); + const currentScreenResolution = thatFA.getScreenResolution(); - const windowWidth = this.fetherApp.window.getSize()[0]; - const windowHeight = this.fetherApp.window.getSize()[1]; + const windowWidth = fetherApp.window.getSize()[0]; + const windowHeight = fetherApp.window.getSize()[1]; if (proposedWindowPosition.x < trayDepth) { newPosition.x = trayDepth; diff --git a/packages/fether-electron/src/main/app/methods/hideWindow.js b/packages/fether-electron/src/main/app/methods/hideWindow.js index b794b50e1..164bdd2d6 100644 --- a/packages/fether-electron/src/main/app/methods/hideWindow.js +++ b/packages/fether-electron/src/main/app/methods/hideWindow.js @@ -3,16 +3,18 @@ // // SPDX-License-Identifier: BSD-3-Clause -function hideWindow () { - if (!this.fetherApp.window) { +function hideWindow (thatFA) { + const { fetherApp } = thatFA; + + if (!fetherApp.window) { return; } - this.processSaveWindowPosition(); // Save window position when hide, particularly necessary on Linux + thatFA.processSaveWindowPosition(); // Save window position when hide, particularly necessary on Linux - this.fetherApp.emit('hide-window'); - this.fetherApp.window.hide(); - this.fetherApp.emit('after-hide-window'); + fetherApp.emit('hide-window'); + fetherApp.window.hide(); + fetherApp.emit('after-hide-window'); } export default hideWindow; diff --git a/packages/fether-electron/src/main/app/methods/loadTray.js b/packages/fether-electron/src/main/app/methods/loadTray.js index d3dbc6f8c..e0627fa73 100644 --- a/packages/fether-electron/src/main/app/methods/loadTray.js +++ b/packages/fether-electron/src/main/app/methods/loadTray.js @@ -7,11 +7,13 @@ import Pino from '../utils/pino'; const pino = Pino(); -function loadTray () { - const { app, options, tray } = this.fetherApp; +function loadTray (thatFA) { + const { fetherApp } = thatFA; + + const { app, options, tray } = fetherApp; if (options.withTaskbar) { - this.fetherApp.emit('load-tray'); + fetherApp.emit('load-tray'); if (process.platform === 'darwin' && app.dock && !options.showDockIcon) { app.dock.hide(); @@ -23,16 +25,16 @@ function loadTray () { // Note: See https://github.com/RocketChat/Rocket.Chat.Electron/issues/44 if (process.platform === 'win32') { - this.showTrayBalloon(); + thatFA.showTrayBalloon(); } - tray.on(defaultClickEvent, () => this.onTrayClick(this.fetherApp)); - tray.on('double-click', () => this.onTrayClick(this.fetherApp)); + tray.on(defaultClickEvent, () => thatFA.onTrayClick(fetherApp)); + tray.on('double-click', () => thatFA.onTrayClick(fetherApp)); // Right click event handler does not work on Windows as intended tray.on('right-click', () => { if (process.platform === 'win32') { pino.info('Detected right click on Windows'); - this.showTrayBalloon(); + thatFA.showTrayBalloon(); } }); tray.setToolTip(options.tooltip); diff --git a/packages/fether-electron/src/main/app/methods/moveWindowUp.js b/packages/fether-electron/src/main/app/methods/moveWindowUp.js index 0419275d1..14b04a846 100644 --- a/packages/fether-electron/src/main/app/methods/moveWindowUp.js +++ b/packages/fether-electron/src/main/app/methods/moveWindowUp.js @@ -15,27 +15,29 @@ const pino = Pino(); * with a larger window height that causes it to be cropped, then we will * automatically move the window upward so it is viewable to the user */ -function moveWindowUp () { - if (!this.fetherApp.window) { +function moveWindowUp (thatFA) { + const { fetherApp } = thatFA; + + if (!fetherApp.window) { return; } pino.info('Fether window resized. Moving it back up into view if required'); - const position = this.fetherApp.window.getPosition(); + const position = fetherApp.window.getPosition(); const positionStruct = { x: position[0], y: position[1] }; - const trayDepth = this.fetherApp.trayDepth || 40; // Default incase resizes on load - const currentScreenResolution = this.getScreenResolution(); - const windowHeight = this.fetherApp.window.getSize()[1]; + const trayDepth = fetherApp.trayDepth || 40; // Default incase resizes on load + const currentScreenResolution = thatFA.getScreenResolution(); + const windowHeight = fetherApp.window.getSize()[1]; const maxWindowY = currentScreenResolution.y - windowHeight - trayDepth; const adjustY = positionStruct.y - maxWindowY; if (adjustY > 0) { - this.fetherApp.emit('moved-window-up-into-view'); - this.fetherApp.window.setPosition(positionStruct.x, maxWindowY); + fetherApp.emit('moved-window-up-into-view'); + fetherApp.window.setPosition(positionStruct.x, maxWindowY); } } diff --git a/packages/fether-electron/src/main/app/methods/onTrayClick.js b/packages/fether-electron/src/main/app/methods/onTrayClick.js index a1fd8f0e7..4f1438017 100644 --- a/packages/fether-electron/src/main/app/methods/onTrayClick.js +++ b/packages/fether-electron/src/main/app/methods/onTrayClick.js @@ -3,8 +3,10 @@ // // SPDX-License-Identifier: BSD-3-Clause -function onTrayClick (e, bounds) { - const { cachedBounds, window } = this.fetherApp; +function onTrayClick (thatFA, e, bounds) { + const { fetherApp } = thatFA; + + const { cachedBounds, window } = fetherApp; if ( e.altKey || @@ -13,12 +15,12 @@ function onTrayClick (e, bounds) { e.metaKey || (window && window.isVisible()) ) { - return this.hideWindow(); + return thatFA.hideWindow(); } // cachedBounds are needed for double-clicked event - this.fetherApp.cachedBounds = bounds || cachedBounds; - this.showWindow(this.fetherApp.cachedBounds); + fetherApp.cachedBounds = bounds || cachedBounds; + thatFA.showWindow(fetherApp.cachedBounds); } export default onTrayClick; diff --git a/packages/fether-electron/src/main/app/methods/onWindowClose.js b/packages/fether-electron/src/main/app/methods/onWindowClose.js index 2d7798573..1ada004de 100644 --- a/packages/fether-electron/src/main/app/methods/onWindowClose.js +++ b/packages/fether-electron/src/main/app/methods/onWindowClose.js @@ -3,9 +3,9 @@ // // SPDX-License-Identifier: BSD-3-Clause -function onWindowClose () { - this.processSaveWindowPosition(); - this.windowClear(); +function onWindowClose (thatFA) { + thatFA.processSaveWindowPosition(); + thatFA.windowClear(); } export default onWindowClose; diff --git a/packages/fether-electron/src/main/app/methods/processSaveWindowPosition.js b/packages/fether-electron/src/main/app/methods/processSaveWindowPosition.js index cd3a03bf9..27005f74a 100644 --- a/packages/fether-electron/src/main/app/methods/processSaveWindowPosition.js +++ b/packages/fether-electron/src/main/app/methods/processSaveWindowPosition.js @@ -9,29 +9,31 @@ import { } from '../utils/window'; import { saveWindowPosition } from '../settings'; -function processSaveWindowPosition () { - if (!this.fetherApp.window) { +function processSaveWindowPosition (thatFA) { + const { fetherApp } = thatFA; + + if (!fetherApp.window) { return; } - const { previousScreenResolution } = this.fetherApp; - const currentScreenResolution = this.getScreenResolution(); + const { previousScreenResolution } = fetherApp; + const currentScreenResolution = thatFA.getScreenResolution(); - this.fetherApp.previousScreenResolution = getChangedScreenResolution( + fetherApp.previousScreenResolution = getChangedScreenResolution( previousScreenResolution, currentScreenResolution ); // Get the latest position. The window may have been moved to a different // screen with smaller resolution. We must move it to prevent cropping. - const position = this.fetherApp.window.getPosition(); + const position = fetherApp.window.getPosition(); const positionStruct = { x: position[0], y: position[1] }; - const fixedWindowPosition = this.fixWindowPosition(positionStruct); + const fixedWindowPosition = thatFA.fixWindowPosition(positionStruct); const newFixedPosition = { x: fixedWindowPosition.x || positionStruct.x, @@ -50,7 +52,7 @@ function processSaveWindowPosition () { ) { // Move window to the fixed x-coordinate position if that required fixing if (fixedWindowPosition.x) { - this.fetherApp.window.setPosition( + fetherApp.window.setPosition( fixedWindowPosition.x, positionStruct.y, true @@ -59,7 +61,7 @@ function processSaveWindowPosition () { // Move window to the fixed y-coordinate position if that required fixing if (fixedWindowPosition.y) { - this.fetherApp.window.setPosition( + fetherApp.window.setPosition( positionStruct.x, fixedWindowPosition.y, true @@ -69,7 +71,7 @@ function processSaveWindowPosition () { saveWindowPosition(newFixedPosition || positionStruct); - this.fetherApp.emit('after-moved-window-position-saved'); + fetherApp.emit('after-moved-window-position-saved'); } export default processSaveWindowPosition; diff --git a/packages/fether-electron/src/main/app/methods/setupAppListeners.js b/packages/fether-electron/src/main/app/methods/setupAppListeners.js index 86c975af7..796feb52c 100644 --- a/packages/fether-electron/src/main/app/methods/setupAppListeners.js +++ b/packages/fether-electron/src/main/app/methods/setupAppListeners.js @@ -9,52 +9,54 @@ import Pino from '../utils/pino'; const pino = Pino(); -function setupAppListeners () { - this.fetherApp.on('create-app', () => { +function setupAppListeners (thatFA) { + const { fetherApp } = thatFA; + + fetherApp.on('create-app', () => { pino.info( `Starting ${productName} (${ - this.fetherApp.options.withTaskbar ? 'with' : 'without' + fetherApp.options.withTaskbar ? 'with' : 'without' } tray icon)...` ); }); - this.fetherApp.on('create-window', () => { + fetherApp.on('create-window', () => { pino.info('Creating window'); }); - this.fetherApp.on('after-create-window', () => { + fetherApp.on('after-create-window', () => { pino.info('Finished creating window'); }); - this.fetherApp.on('load-tray', () => { + fetherApp.on('load-tray', () => { pino.info('Configuring taskbar mode for the window'); }); - this.fetherApp.on('show-window', () => { + fetherApp.on('show-window', () => { pino.info('Showing window'); }); - this.fetherApp.on('after-show-window', () => { + fetherApp.on('after-show-window', () => { pino.info('Finished showing window'); }); - this.fetherApp.on('after-create-app', () => { + fetherApp.on('after-create-app', () => { pino.info(`Ready to use ${productName}`); }); - this.fetherApp.on('hide-window', () => { + fetherApp.on('hide-window', () => { pino.info('Hiding window on blur since not on top'); }); - this.fetherApp.on('after-hide-window', () => { + fetherApp.on('after-hide-window', () => { pino.info('Finished hiding window'); }); - this.fetherApp.on('blur-window', () => { + fetherApp.on('blur-window', () => { pino.info('Blur window since lost focus when on top'); }); - this.fetherApp.on('after-moved-window-position-saved', () => { + fetherApp.on('after-moved-window-position-saved', () => { const position = getSavedWindowPosition(); pino.info( @@ -62,15 +64,15 @@ function setupAppListeners () { ); }); - this.fetherApp.on('moved-window-up-into-view', () => { + fetherApp.on('moved-window-up-into-view', () => { pino.info('Moved window up into view'); }); - this.fetherApp.on('after-close-window', () => { + fetherApp.on('after-close-window', () => { pino.info('Deleted window upon close'); }); - this.fetherApp.on('error', error => { + fetherApp.on('error', error => { console.error(error); }); } diff --git a/packages/fether-electron/src/main/app/methods/setupDebug.js b/packages/fether-electron/src/main/app/methods/setupDebug.js index 32d254e68..5db1199e9 100644 --- a/packages/fether-electron/src/main/app/methods/setupDebug.js +++ b/packages/fether-electron/src/main/app/methods/setupDebug.js @@ -5,10 +5,12 @@ const withDebug = process.env.DEBUG === 'true'; -function setupDebug () { +function setupDebug (thatFA) { + const { fetherApp } = thatFA; + // Enable with `DEBUG=true yarn start` and access Developer Tools - if (withDebug && this.fetherApp.options.webPreferences.devTools) { - this.fetherApp.window.webContents.openDevTools(); + if (withDebug && fetherApp.options.webPreferences.devTools) { + fetherApp.window.webContents.openDevTools(); } } diff --git a/packages/fether-electron/src/main/app/methods/setupMenu.js b/packages/fether-electron/src/main/app/methods/setupMenu.js index ee68418fb..b54940805 100644 --- a/packages/fether-electron/src/main/app/methods/setupMenu.js +++ b/packages/fether-electron/src/main/app/methods/setupMenu.js @@ -8,9 +8,11 @@ import Pino from '../utils/pino'; const pino = Pino(); -function setupMenu () { +function setupMenu (thatFA) { + const { fetherApp } = thatFA; + // Add application menu - addMenu(this.fetherApp.window); + addMenu(fetherApp.window); pino.info('Finished configuring Electron menu'); } diff --git a/packages/fether-electron/src/main/app/methods/setupParityEthereum.js b/packages/fether-electron/src/main/app/methods/setupParityEthereum.js index ac6921b95..29770fa86 100644 --- a/packages/fether-electron/src/main/app/methods/setupParityEthereum.js +++ b/packages/fether-electron/src/main/app/methods/setupParityEthereum.js @@ -5,10 +5,12 @@ import ParityEthereum from '../parityEthereum'; -function setupParityEthereum () { +function setupParityEthereum (thatFA) { + const { fetherApp } = thatFA; + // Download, install, and run Parity Ethereum if not running and requested const parityEthereumInstance = new ParityEthereum(); - parityEthereumInstance.setup(this.fetherApp.window); + parityEthereumInstance.setup(fetherApp.window); } export default setupParityEthereum; diff --git a/packages/fether-electron/src/main/app/methods/setupRequestListeners.js b/packages/fether-electron/src/main/app/methods/setupRequestListeners.js index b7e22f3e9..1fe301d61 100644 --- a/packages/fether-electron/src/main/app/methods/setupRequestListeners.js +++ b/packages/fether-electron/src/main/app/methods/setupRequestListeners.js @@ -8,10 +8,12 @@ import electron from 'electron'; import messages from '../messages'; const { ipcMain, session } = electron; -function setupRequestListeners () { +function setupRequestListeners (thatFA) { + const { fetherApp } = thatFA; + // Listen to messages from renderer process ipcMain.on('asynchronous-message', (...args) => { - return messages(this.fetherApp.window, ...args); + return messages(fetherApp.window, ...args); }); // WS calls have Origin `file://` by default, which is not trusted. @@ -21,13 +23,13 @@ function setupRequestListeners () { urls: ['ws://*/*', 'wss://*/*'] }, (details, callback) => { - if (!this.fetherApp.window) { + if (!fetherApp.window) { // There might be a split second where the user closes the app, so // this.fether.window is null, but there is still a network request done. return; } details.requestHeaders.Origin = `parity://${ - this.fetherApp.window.id + fetherApp.window.id }.ui.parity`; callback({ requestHeaders: details.requestHeaders }); // eslint-disable-line } diff --git a/packages/fether-electron/src/main/app/methods/setupSecurity.js b/packages/fether-electron/src/main/app/methods/setupSecurity.js index 046980dcd..b584282c9 100644 --- a/packages/fether-electron/src/main/app/methods/setupSecurity.js +++ b/packages/fether-electron/src/main/app/methods/setupSecurity.js @@ -3,9 +3,11 @@ // // SPDX-License-Identifier: BSD-3-Clause -function setupSecurity () { +function setupSecurity (thatFA) { + const { fetherApp } = thatFA; + // Security to prevent window contents from being captured by other apps - this.fetherApp.window.setContentProtection(true); + fetherApp.window.setContentProtection(true); } export default setupSecurity; diff --git a/packages/fether-electron/src/main/app/methods/setupWin32Listeners.js b/packages/fether-electron/src/main/app/methods/setupWin32Listeners.js index b549c2887..2c3c241a4 100644 --- a/packages/fether-electron/src/main/app/methods/setupWin32Listeners.js +++ b/packages/fether-electron/src/main/app/methods/setupWin32Listeners.js @@ -7,7 +7,9 @@ import Pino from '../utils/pino'; const pino = Pino(); -function setupWin32Listeners () { +function setupWin32Listeners (thatFA) { + const { fetherApp } = thatFA; + if (process.platform === 'win32') { /** * Hook WM_SYSKEYUP @@ -17,7 +19,7 @@ function setupWin32Listeners () { * * Reference: https://docs.microsoft.com/en-gb/windows/desktop/inputdev/wm-syskeyup */ - this.fetherApp.window.hookWindowMessage( + fetherApp.window.hookWindowMessage( Number.parseInt('0x0105'), (wParam, lParam) => { // Reference: https://nodejs.org/api/buffer.html @@ -26,7 +28,7 @@ function setupWin32Listeners () { * i.e. Use `wParam && wParam.readUInt32LE(0) === 77` to detect ALT+m */ if (wParam) { - this.showTrayBalloon(); + thatFA.showTrayBalloon(); } } ); @@ -38,7 +40,7 @@ function setupWin32Listeners () { * * Credit: http://robmayhew.com/listening-for-events-from-windows-in-electron-tutorial/ */ - this.fetherApp.window.hookWindowMessage( + fetherApp.window.hookWindowMessage( Number.parseInt('0x0112'), (wParam, lParam) => { let eventName = null; @@ -46,19 +48,19 @@ function setupWin32Listeners () { if (wParam.readUInt32LE(0) === 0xf060) { // SC_CLOSE eventName = 'close'; - this.onWindowClose(); + thatFA.onWindowClose(); } else if (wParam.readUInt32LE(0) === 0xf030) { // SC_MAXIMIZE eventName = 'maximize'; - this.showTrayBalloon(); + thatFA.showTrayBalloon(); } else if (wParam.readUInt32LE(0) === 0xf020) { // SC_MINIMIZE eventName = 'minimize'; - this.processSaveWindowPosition(); + thatFA.processSaveWindowPosition(); } else if (wParam.readUInt32LE(0) === 0xf120) { // SC_RESTORE eventName = 'restored'; - this.showTrayBalloon(); + thatFA.showTrayBalloon(); } if (eventName !== null) { @@ -73,23 +75,23 @@ function setupWin32Listeners () { * Detect event on Windows when Fether window was moved * or resized */ - this.fetherApp.window.hookWindowMessage( + fetherApp.window.hookWindowMessage( Number.parseInt('0x0232'), (wParam, lParam) => { pino.info('Detected completion of move or resize event'); // Move Fether window back up into view if it was a resize event // that causes the bottom to be cropped - this.moveWindowUp(); + thatFA.moveWindowUp(); // Try again after a delay incase Fether window resize occurs // x seconds after navigating to a new page. setTimeout(() => { - this.moveWindowUp(); + thatFA.moveWindowUp(); }, 5000); // Save Fether window position to Electron settings - this.processSaveWindowPosition(); + thatFA.processSaveWindowPosition(); } ); } diff --git a/packages/fether-electron/src/main/app/methods/setupWindowListeners.js b/packages/fether-electron/src/main/app/methods/setupWindowListeners.js index 854bbaf8b..ffde6c97d 100644 --- a/packages/fether-electron/src/main/app/methods/setupWindowListeners.js +++ b/packages/fether-electron/src/main/app/methods/setupWindowListeners.js @@ -10,26 +10,28 @@ import Pino from '../utils/pino'; const pino = Pino(); -function setupWindowListeners () { +function setupWindowListeners (thatFA) { + const { fetherApp } = thatFA; + // Open external links in browser - this.fetherApp.window.webContents.on('new-window', (event, url) => { + fetherApp.window.webContents.on('new-window', (event, url) => { event.preventDefault(); electron.shell.openExternal(url); }); // Linux (unchecked on others) - this.fetherApp.window.on('move', () => { + fetherApp.window.on('move', () => { /** * On Linux using this with debouncing is the closest equivalent * to using 'moved' (not supported on Linux) with debouncing */ debounce(() => { - this.processSaveWindowPosition(); + thatFA.processSaveWindowPosition(); }, 1000); }); // macOS (not Windows or Linux) - this.fetherApp.window.on('moved', () => { + fetherApp.window.on('moved', () => { /** * On macOS save the position in the 'moved' event since if * we run it just in 'close' instead, then if the Fether app @@ -42,32 +44,32 @@ function setupWindowListeners () { * On Linux the closest equivalent to achieving 'moved' is debouncing * on the 'move' event. It also works in 'close' even when app crashes */ - this.processSaveWindowPosition(); + thatFA.processSaveWindowPosition(); }); // macOS and Linux (not Windows) - this.fetherApp.window.on('resize', () => { + fetherApp.window.on('resize', () => { pino.info('Detected resize event'); - this.moveWindowUp(); + thatFA.moveWindowUp(); setTimeout(() => { - this.moveWindowUp(); + thatFA.moveWindowUp(); }, 5000); }); - this.fetherApp.window.on('blur', () => { - this.fetherApp.options.alwaysOnTop - ? this.fetherApp.emit('blur-window') - : this.hideWindow(); + fetherApp.window.on('blur', () => { + fetherApp.options.alwaysOnTop + ? fetherApp.emit('blur-window') + : thatFA.hideWindow(); }); - this.fetherApp.window.on('close', () => { - this.onWindowClose(); + fetherApp.window.on('close', () => { + thatFA.onWindowClose(); }); - this.fetherApp.window.on('closed', () => { - this.fetherApp.window = null; + fetherApp.window.on('closed', () => { + fetherApp.window = null; - this.fetherApp.emit('after-closed-window'); + fetherApp.emit('after-closed-window'); }); } diff --git a/packages/fether-electron/src/main/app/methods/showTrayBalloon.js b/packages/fether-electron/src/main/app/methods/showTrayBalloon.js index 3ff534955..405872279 100644 --- a/packages/fether-electron/src/main/app/methods/showTrayBalloon.js +++ b/packages/fether-electron/src/main/app/methods/showTrayBalloon.js @@ -18,8 +18,10 @@ const iconBalloonPath = path.join( const pino = Pino(); -function showTrayBalloon () { - let { tray } = this.fetherApp; +function showTrayBalloon (thatFA) { + const { fetherApp } = thatFA; + + let { tray } = fetherApp; pino.info('Showing Tray Balloon'); diff --git a/packages/fether-electron/src/main/app/methods/showWindow.js b/packages/fether-electron/src/main/app/methods/showWindow.js index 70f736656..678780e79 100644 --- a/packages/fether-electron/src/main/app/methods/showWindow.js +++ b/packages/fether-electron/src/main/app/methods/showWindow.js @@ -11,14 +11,16 @@ import Pino from '../utils/pino'; const pino = Pino(); -function showWindow (trayPos) { - if (!this.fetherApp.window) { - this.createWindow(); +function showWindow (thatFA, trayPos) { + const { fetherApp } = thatFA; + + if (!fetherApp.window) { + thatFA.createWindow(); } - this.fetherApp.emit('show-window'); + fetherApp.emit('show-window'); - const calculatedWindowPosition = this.calculateWindowPosition(trayPos); + const calculatedWindowPosition = thatFA.calculateWindowPosition(trayPos); pino.info('Calculated window position: ', calculatedWindowPosition); @@ -28,7 +30,7 @@ function showWindow (trayPos) { const mainScreenWorkAreaSize = mainScreen.workAreaSize; // workAreaSize does not include the tray depth - this.fetherApp.trayDepth = Math.max( + fetherApp.trayDepth = Math.max( mainScreenDimensions.width - mainScreenWorkAreaSize.width, mainScreenDimensions.height - mainScreenWorkAreaSize.height ); @@ -44,7 +46,7 @@ function showWindow (trayPos) { pino.info('Loaded window position: ', loadedWindowPosition); - const fixedWindowPosition = this.fixWindowPosition(loadedWindowPosition); + const fixedWindowPosition = thatFA.fixWindowPosition(loadedWindowPosition); pino.info('Fixed window position: ', fixedWindowPosition); @@ -63,10 +65,10 @@ function showWindow (trayPos) { (loadedWindowPosition && loadedWindowPosition.y) || calculatedWindowPosition.y; - this.fetherApp.window.setPosition(x, y); - this.fetherApp.window.show(); + fetherApp.window.setPosition(x, y); + fetherApp.window.show(); - this.fetherApp.emit('after-show-window'); + fetherApp.emit('after-show-window'); } export default showWindow; diff --git a/packages/fether-electron/src/main/app/methods/updateProgress.js b/packages/fether-electron/src/main/app/methods/updateProgress.js index 06cd82550..ed0bad713 100644 --- a/packages/fether-electron/src/main/app/methods/updateProgress.js +++ b/packages/fether-electron/src/main/app/methods/updateProgress.js @@ -6,13 +6,15 @@ // Optionally update the progress bar shown on the Dock icon // (i.e. 0.1 is 10%, 1.0 is 100%, -1 hides progress bar). // Optionally emit event -function updateProgress (percentage, eventListenerName) { +function updateProgress (thatFA, percentage, eventListenerName) { + const { fetherApp } = thatFA; + if (percentage) { - this.fetherApp.window.setProgressBar(percentage); + fetherApp.window.setProgressBar(percentage); } if (eventListenerName) { - this.fetherApp.emit(eventListenerName); + fetherApp.emit(eventListenerName); } } diff --git a/packages/fether-electron/src/main/app/methods/windowClear.js b/packages/fether-electron/src/main/app/methods/windowClear.js index a3d57677a..9c6c2e264 100644 --- a/packages/fether-electron/src/main/app/methods/windowClear.js +++ b/packages/fether-electron/src/main/app/methods/windowClear.js @@ -3,17 +3,19 @@ // // SPDX-License-Identifier: BSD-3-Clause -function windowClear () { - if (this.fetherApp.window) { +function windowClear (fetherApp) { + const { fetherApp } = fetherApp; + + if (fetherApp.window) { // Remove relevant events when window object deleted const events = ['close', 'move', 'moved', 'resize']; for (let event in events) { - this.fetherApp.window.removeAllListeners(event); + fetherApp.window.removeAllListeners(event); } - delete this.fetherApp.window; + delete fetherApp.window; } - this.fetherApp.emit('after-close-window'); + fetherApp.emit('after-close-window'); } export default windowClear; From 6ad5502f3f3da1d1bb14063176659b158ee53e3d Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Tue, 5 Feb 2019 18:03:08 +1100 Subject: [PATCH 124/153] WIP - Refactor methods to be directly associated with class. Yet to do same to fetherApp.emit for setupAppListeners --- .../fether-electron/src/main/app/index.js | 108 +++++++++--------- .../app/methods/calculateWindowPosition.js | 6 +- .../src/main/app/methods/createPositioner.js | 4 +- .../src/main/app/methods/createTray.js | 6 +- .../src/main/app/methods/createWindow.js | 14 +-- .../src/main/app/methods/fixWindowPosition.js | 8 +- .../src/main/app/methods/hideWindow.js | 4 +- .../src/main/app/methods/loadTray.js | 8 +- .../src/main/app/methods/moveWindowUp.js | 10 +- .../src/main/app/methods/onTrayClick.js | 10 +- .../app/methods/processSaveWindowPosition.js | 26 ++--- .../src/main/app/methods/setupAppListeners.js | 32 +++--- .../src/main/app/methods/setupDebug.js | 6 +- .../src/main/app/methods/setupMenu.js | 4 +- .../main/app/methods/setupParityEthereum.js | 4 +- .../main/app/methods/setupRequestListeners.js | 10 +- .../src/main/app/methods/setupSecurity.js | 4 +- .../main/app/methods/setupWin32Listeners.js | 8 +- .../main/app/methods/setupWindowListeners.js | 18 +-- .../src/main/app/methods/showTrayBalloon.js | 4 +- .../src/main/app/methods/showWindow.js | 8 +- .../src/main/app/methods/updateProgress.js | 2 +- .../src/main/app/methods/windowClear.js | 10 +- packages/fether-electron/src/main/index.js | 6 +- 24 files changed, 139 insertions(+), 181 deletions(-) diff --git a/packages/fether-electron/src/main/app/index.js b/packages/fether-electron/src/main/app/index.js index bb8c20a11..29c1811ff 100644 --- a/packages/fether-electron/src/main/app/index.js +++ b/packages/fether-electron/src/main/app/index.js @@ -47,64 +47,60 @@ class FetherApp { ); } - this.fetherApp.app = electronApp; - this.fetherApp.options = options; + this.app = electronApp; + this.options = options; - // Context of fetherApp passed to each method - this.fetherApp.setupAppListeners = setupAppListeners(this); - this.fetherApp.createWindow = createWindow(this); - this.fetherApp.updateProgress = updateProgress(this); - this.fetherApp.createPositioner = createPositioner(this); - this.fetherApp.setupRequestListeners = setupRequestListeners(this); - this.fetherApp.createTray = createTray(this); - this.fetherApp.loadTray = loadTray(this); - this.fetherApp.showTrayBalloon = showTrayBalloon(this); - this.fetherApp.setupDebug = setupDebug(this); - this.fetherApp.setupSecurity = setupSecurity(this); - this.fetherApp.setupLogger = setupLogger(); - this.fetherApp.setupParityEthereum = setupParityEthereum(this); - this.fetherApp.setupGlobals = setupGlobals(); - this.fetherApp.setupMenu = setupMenu(this); - this.fetherApp.getScreenResolution = getScreenResolution(this); - this.fetherApp.calculateWindowPosition = calculateWindowPosition(this); - this.fetherApp.getScreenResolution = getScreenResolution(); - this.fetherApp.onTrayClick = onTrayClick(this); - this.fetherApp.fixWindowPosition = fixWindowPosition(this); - this.fetherApp.getScreenResolution = getScreenResolution(this); - this.fetherApp.showWindow = showWindow(this); - this.fetherApp.moveWindowUp = moveWindowUp(this); - this.fetherApp.processSaveWindowPosition = processSaveWindowPosition(this); - this.fetherApp.hideWindow = hideWindow(this); - this.fetherApp.windowClear = windowClear(this); - this.fetherApp.onWindowClose = onWindowClose(); - this.fetherApp.setupWindowListeners = setupWindowListeners(this); - this.fetherApp.setupWin32Listeners = setupWin32Listeners(this); - - const { fetherApp } = this; - - fetherApp.setupAppListeners.apply(fetherApp); - fetherApp.createWindow.apply(fetherApp); - fetherApp.updateProgress.apply(fetherApp, [0.4]); // eslint-disable-line - fetherApp.createPositioner.apply(fetherApp); - fetherApp.setupRequestListeners.apply(fetherApp); - fetherApp.createTray.apply(fetherApp); - fetherApp.updateProgress.apply(fetherApp, [0.6]); // eslint-disable-line - fetherApp.loadTray.apply(fetherApp); - fetherApp.setupDebug.apply(fetherApp); - fetherApp.setupSecurity.apply(fetherApp); - fetherApp.setupLogger.apply(); - fetherApp.setupParityEthereum.apply(fetherApp); - fetherApp.setupGlobals.apply(); - fetherApp.setupMenu.apply(fetherApp); - fetherApp.updateProgress.apply(fetherApp, [0.8]); // eslint-disable-line - fetherApp.showWindow.apply(fetherApp, undefined); - fetherApp.updateProgress.apply(fetherApp, [1.0]); // eslint-disable-line - fetherApp.setupWindowListeners.apply(fetherApp); - fetherApp.setupWin32Listeners.apply(fetherApp); - fetherApp.updateProgress.apply(fetherApp, [-1, "after-create-app"]); // eslint-disable-line + this.setupAppListeners(); + this.createWindow(); + this.updateProgress(0.4, undefined); // eslint-disable-line + this.createPositioner(); + this.setupRequestListeners(); + this.createTray(); + this.updateProgress(0.6, undefined); // eslint-disable-line + this.loadTray(); + this.setupDebug(); + this.setupSecurity(); + this.setupLogger.apply(); + this.setupParityEthereum(); + this.setupGlobals(); + this.setupMenu(); + this.updateProgress(0.8, undefined); // eslint-disable-line + this.showWindow(undefined); + this.updateProgress(1.0, undefined); // eslint-disable-line + this.setupWindowListeners(); + this.setupWin32Listeners(); + this.updateProgress(-1, "after-create-app"); // eslint-disable-line } -} -const fetherApp = new FetherApp(app, options); + setupAppListeners = () => setupAppListeners(this); + createWindow = () => createWindow(this); + updateProgress = (percentage, eventListenerName) => + updateProgress(this, percentage, eventListenerName); + createPositioner = () => createPositioner(this); + setupRequestListeners = () => setupRequestListeners(this); + createTray = () => createTray(this); + loadTray = () => loadTray(this); + showTrayBalloon = () => showTrayBalloon(this); + setupDebug = () => setupDebug(this); + setupSecurity = () => setupSecurity(this); + setupLogger = () => setupLogger(); + setupParityEthereum = () => setupParityEthereum(this); + setupGlobals = () => setupGlobals(); + setupMenu = () => setupMenu(this); + getScreenResolution = () => getScreenResolution(this); + calculateWindowPosition = () => calculateWindowPosition(this); + getScreenResolution = () => getScreenResolution(); + onTrayClick = (e, bounds) => onTrayClick(this, e, bounds); + fixWindowPosition = positionStruct => fixWindowPosition(this, positionStruct); + getScreenResolution = () => getScreenResolution(this); + showWindow = trayPos => showWindow(this, trayPos); + moveWindowUp = () => moveWindowUp(this); + processSaveWindowPosition = () => processSaveWindowPosition(this); + hideWindow = () => hideWindow(this); + windowClear = () => windowClear(this); + onWindowClose = () => onWindowClose(); + setupWindowListeners = () => setupWindowListeners(this); + setupWin32Listeners = () => setupWin32Listeners(this); +} export default FetherApp; diff --git a/packages/fether-electron/src/main/app/methods/calculateWindowPosition.js b/packages/fether-electron/src/main/app/methods/calculateWindowPosition.js index e897f5c23..2cf022a25 100644 --- a/packages/fether-electron/src/main/app/methods/calculateWindowPosition.js +++ b/packages/fether-electron/src/main/app/methods/calculateWindowPosition.js @@ -4,13 +4,11 @@ // SPDX-License-Identifier: BSD-3-Clause function calculateWindowPosition (thatFA, trayPos) { - const { fetherApp } = thatFA; - - const { cachedBounds, options, positioner, tray } = fetherApp; + const { cachedBounds, options, positioner, tray } = thatFA; if (trayPos && trayPos.x !== 0) { // Cache the bounds - fetherApp.cachedBounds = trayPos; + thatFA.cachedBounds = trayPos; } else if (cachedBounds) { // Cached value will be used if showWindow is called without bounds data trayPos = cachedBounds; diff --git a/packages/fether-electron/src/main/app/methods/createPositioner.js b/packages/fether-electron/src/main/app/methods/createPositioner.js index 676b32364..8969eed50 100644 --- a/packages/fether-electron/src/main/app/methods/createPositioner.js +++ b/packages/fether-electron/src/main/app/methods/createPositioner.js @@ -6,9 +6,7 @@ import Positioner from 'electron-positioner'; function createPositioner (thatFA) { - const { fetherApp } = thatFA; - - fetherApp.positioner = new Positioner(fetherApp.window); + thatFA.positioner = new Positioner(thatFA.window); } export default createPositioner; diff --git a/packages/fether-electron/src/main/app/methods/createTray.js b/packages/fether-electron/src/main/app/methods/createTray.js index fb461f839..895cd1eaf 100644 --- a/packages/fether-electron/src/main/app/methods/createTray.js +++ b/packages/fether-electron/src/main/app/methods/createTray.js @@ -6,12 +6,10 @@ import { Tray } from 'electron'; function createTray (thatFA) { - const { fetherApp } = thatFA; - - let { app, options } = fetherApp; + const { app, options } = thatFA; if (options.withTaskbar) { - fetherApp.tray = new Tray(options.icon); + thatFA.tray = new Tray(options.icon); if (process.platform === 'darwin' && app.dock) { app.dock.setIcon(options.iconDock); diff --git a/packages/fether-electron/src/main/app/methods/createWindow.js b/packages/fether-electron/src/main/app/methods/createWindow.js index 2fbda8e01..94db3a614 100644 --- a/packages/fether-electron/src/main/app/methods/createWindow.js +++ b/packages/fether-electron/src/main/app/methods/createWindow.js @@ -8,17 +8,15 @@ import electron from 'electron'; const { BrowserWindow } = electron; function createWindow (thatFA) { - const { fetherApp } = thatFA; - - const { options } = fetherApp; + const { fetherApp, options } = thatFA; fetherApp.emit('create-app'); fetherApp.emit('create-window'); - fetherApp.window = new BrowserWindow(options); + thatFA.window = new BrowserWindow(options); if (options.showOnAllWorkspaces !== false) { - fetherApp.window.setVisibleOnAllWorkspaces(true); + thatFA.window.setVisibleOnAllWorkspaces(true); } if (process.platform !== 'darwin') { @@ -28,13 +26,13 @@ function createWindow (thatFA) { * of the window when menu open/close toggled. The user will need to be informed * that pressing ALT displays the Fether menu */ - fetherApp.window.setAutoHideMenuBar(true); // ALT shows menu bar - fetherApp.window.setMenuBarVisibility(false); + thatFA.window.setAutoHideMenuBar(true); // ALT shows menu bar + thatFA.window.setMenuBarVisibility(false); } // Opens file:///path/to/build/index.html in prod mode, or whatever is // passed to ELECTRON_START_URL - fetherApp.window.loadURL(options.index); + thatFA.window.loadURL(options.index); fetherApp.emit('after-create-window'); } diff --git a/packages/fether-electron/src/main/app/methods/fixWindowPosition.js b/packages/fether-electron/src/main/app/methods/fixWindowPosition.js index 4623b66d4..1736405bf 100644 --- a/packages/fether-electron/src/main/app/methods/fixWindowPosition.js +++ b/packages/fether-electron/src/main/app/methods/fixWindowPosition.js @@ -12,9 +12,7 @@ * will be restored into the users primary screen. */ function fixWindowPosition (thatFA, proposedWindowPosition) { - const { fetherApp } = thatFA; - - const { trayDepth } = fetherApp; + const { trayDepth } = thatFA; if (!proposedWindowPosition) { return; @@ -27,8 +25,8 @@ function fixWindowPosition (thatFA, proposedWindowPosition) { const currentScreenResolution = thatFA.getScreenResolution(); - const windowWidth = fetherApp.window.getSize()[0]; - const windowHeight = fetherApp.window.getSize()[1]; + const windowWidth = thatFA.window.getSize()[0]; + const windowHeight = thatFA.window.getSize()[1]; if (proposedWindowPosition.x < trayDepth) { newPosition.x = trayDepth; diff --git a/packages/fether-electron/src/main/app/methods/hideWindow.js b/packages/fether-electron/src/main/app/methods/hideWindow.js index 164bdd2d6..c00e5d046 100644 --- a/packages/fether-electron/src/main/app/methods/hideWindow.js +++ b/packages/fether-electron/src/main/app/methods/hideWindow.js @@ -6,14 +6,14 @@ function hideWindow (thatFA) { const { fetherApp } = thatFA; - if (!fetherApp.window) { + if (!thatFA.window) { return; } thatFA.processSaveWindowPosition(); // Save window position when hide, particularly necessary on Linux fetherApp.emit('hide-window'); - fetherApp.window.hide(); + thatFA.window.hide(); fetherApp.emit('after-hide-window'); } diff --git a/packages/fether-electron/src/main/app/methods/loadTray.js b/packages/fether-electron/src/main/app/methods/loadTray.js index e0627fa73..fca5727f3 100644 --- a/packages/fether-electron/src/main/app/methods/loadTray.js +++ b/packages/fether-electron/src/main/app/methods/loadTray.js @@ -8,9 +8,7 @@ import Pino from '../utils/pino'; const pino = Pino(); function loadTray (thatFA) { - const { fetherApp } = thatFA; - - const { app, options, tray } = fetherApp; + const { fetherApp, app, options, tray } = thatFA; if (options.withTaskbar) { fetherApp.emit('load-tray'); @@ -28,8 +26,8 @@ function loadTray (thatFA) { thatFA.showTrayBalloon(); } - tray.on(defaultClickEvent, () => thatFA.onTrayClick(fetherApp)); - tray.on('double-click', () => thatFA.onTrayClick(fetherApp)); + tray.on(defaultClickEvent, () => thatFA.onTrayClick(thatFA)); + tray.on('double-click', () => thatFA.onTrayClick(thatFA)); // Right click event handler does not work on Windows as intended tray.on('right-click', () => { if (process.platform === 'win32') { diff --git a/packages/fether-electron/src/main/app/methods/moveWindowUp.js b/packages/fether-electron/src/main/app/methods/moveWindowUp.js index 14b04a846..07a279e9f 100644 --- a/packages/fether-electron/src/main/app/methods/moveWindowUp.js +++ b/packages/fether-electron/src/main/app/methods/moveWindowUp.js @@ -18,26 +18,26 @@ const pino = Pino(); function moveWindowUp (thatFA) { const { fetherApp } = thatFA; - if (!fetherApp.window) { + if (!thatFA.window) { return; } pino.info('Fether window resized. Moving it back up into view if required'); - const position = fetherApp.window.getPosition(); + const position = thatFA.window.getPosition(); const positionStruct = { x: position[0], y: position[1] }; - const trayDepth = fetherApp.trayDepth || 40; // Default incase resizes on load + const trayDepth = thatFA.trayDepth || 40; // Default incase resizes on load const currentScreenResolution = thatFA.getScreenResolution(); - const windowHeight = fetherApp.window.getSize()[1]; + const windowHeight = thatFA.window.getSize()[1]; const maxWindowY = currentScreenResolution.y - windowHeight - trayDepth; const adjustY = positionStruct.y - maxWindowY; if (adjustY > 0) { fetherApp.emit('moved-window-up-into-view'); - fetherApp.window.setPosition(positionStruct.x, maxWindowY); + thatFA.window.setPosition(positionStruct.x, maxWindowY); } } diff --git a/packages/fether-electron/src/main/app/methods/onTrayClick.js b/packages/fether-electron/src/main/app/methods/onTrayClick.js index 4f1438017..fc6f863b2 100644 --- a/packages/fether-electron/src/main/app/methods/onTrayClick.js +++ b/packages/fether-electron/src/main/app/methods/onTrayClick.js @@ -4,23 +4,21 @@ // SPDX-License-Identifier: BSD-3-Clause function onTrayClick (thatFA, e, bounds) { - const { fetherApp } = thatFA; - - const { cachedBounds, window } = fetherApp; + const { cachedBounds } = thatFA; if ( e.altKey || e.shiftKey || e.ctrlKey || e.metaKey || - (window && window.isVisible()) + (thatFA.window && thatFA.window.isVisible()) ) { return thatFA.hideWindow(); } // cachedBounds are needed for double-clicked event - fetherApp.cachedBounds = bounds || cachedBounds; - thatFA.showWindow(fetherApp.cachedBounds); + thatFA.cachedBounds = bounds || cachedBounds; + thatFA.showWindow(thatFA.cachedBounds); } export default onTrayClick; diff --git a/packages/fether-electron/src/main/app/methods/processSaveWindowPosition.js b/packages/fether-electron/src/main/app/methods/processSaveWindowPosition.js index 27005f74a..51cbbe7c8 100644 --- a/packages/fether-electron/src/main/app/methods/processSaveWindowPosition.js +++ b/packages/fether-electron/src/main/app/methods/processSaveWindowPosition.js @@ -12,21 +12,20 @@ import { saveWindowPosition } from '../settings'; function processSaveWindowPosition (thatFA) { const { fetherApp } = thatFA; - if (!fetherApp.window) { + if (!thatFA.window) { return; } - const { previousScreenResolution } = fetherApp; const currentScreenResolution = thatFA.getScreenResolution(); - fetherApp.previousScreenResolution = getChangedScreenResolution( - previousScreenResolution, + thatFA.previousScreenResolution = getChangedScreenResolution( + thatFA.previousScreenResolution, currentScreenResolution ); // Get the latest position. The window may have been moved to a different // screen with smaller resolution. We must move it to prevent cropping. - const position = fetherApp.window.getPosition(); + const position = thatFA.window.getPosition(); const positionStruct = { x: position[0], @@ -48,24 +47,19 @@ function processSaveWindowPosition (thatFA) { * and it would also prevent the user from moving it to a different screen at all. */ if ( - shouldFixWindowPosition(previousScreenResolution, currentScreenResolution) + shouldFixWindowPosition( + thatFA.previousScreenResolution, + currentScreenResolution + ) ) { // Move window to the fixed x-coordinate position if that required fixing if (fixedWindowPosition.x) { - fetherApp.window.setPosition( - fixedWindowPosition.x, - positionStruct.y, - true - ); + thatFA.window.setPosition(fixedWindowPosition.x, positionStruct.y, true); } // Move window to the fixed y-coordinate position if that required fixing if (fixedWindowPosition.y) { - fetherApp.window.setPosition( - positionStruct.x, - fixedWindowPosition.y, - true - ); + thatFA.window.setPosition(positionStruct.x, fixedWindowPosition.y, true); } } diff --git a/packages/fether-electron/src/main/app/methods/setupAppListeners.js b/packages/fether-electron/src/main/app/methods/setupAppListeners.js index 796feb52c..51547874c 100644 --- a/packages/fether-electron/src/main/app/methods/setupAppListeners.js +++ b/packages/fether-electron/src/main/app/methods/setupAppListeners.js @@ -10,53 +10,51 @@ import Pino from '../utils/pino'; const pino = Pino(); function setupAppListeners (thatFA) { - const { fetherApp } = thatFA; - - fetherApp.on('create-app', () => { + thatFA.fetherApp.on('create-app', () => { pino.info( `Starting ${productName} (${ - fetherApp.options.withTaskbar ? 'with' : 'without' + thatFA.options.withTaskbar ? 'with' : 'without' } tray icon)...` ); }); - fetherApp.on('create-window', () => { + thatFA.fetherApp.on('create-window', () => { pino.info('Creating window'); }); - fetherApp.on('after-create-window', () => { + thatFA.fetherApp.on('after-create-window', () => { pino.info('Finished creating window'); }); - fetherApp.on('load-tray', () => { + thatFA.fetherApp.on('load-tray', () => { pino.info('Configuring taskbar mode for the window'); }); - fetherApp.on('show-window', () => { + thatFA.fetherApp.on('show-window', () => { pino.info('Showing window'); }); - fetherApp.on('after-show-window', () => { + thatFA.fetherApp.on('after-show-window', () => { pino.info('Finished showing window'); }); - fetherApp.on('after-create-app', () => { + thatFA.fetherApp.on('after-create-app', () => { pino.info(`Ready to use ${productName}`); }); - fetherApp.on('hide-window', () => { + thatFA.fetherApp.on('hide-window', () => { pino.info('Hiding window on blur since not on top'); }); - fetherApp.on('after-hide-window', () => { + thatFA.fetherApp.on('after-hide-window', () => { pino.info('Finished hiding window'); }); - fetherApp.on('blur-window', () => { + thatFA.fetherApp.on('blur-window', () => { pino.info('Blur window since lost focus when on top'); }); - fetherApp.on('after-moved-window-position-saved', () => { + thatFA.fetherApp.on('after-moved-window-position-saved', () => { const position = getSavedWindowPosition(); pino.info( @@ -64,15 +62,15 @@ function setupAppListeners (thatFA) { ); }); - fetherApp.on('moved-window-up-into-view', () => { + thatFA.fetherApp.on('moved-window-up-into-view', () => { pino.info('Moved window up into view'); }); - fetherApp.on('after-close-window', () => { + thatFA.fetherApp.on('after-close-window', () => { pino.info('Deleted window upon close'); }); - fetherApp.on('error', error => { + thatFA.fetherApp.on('error', error => { console.error(error); }); } diff --git a/packages/fether-electron/src/main/app/methods/setupDebug.js b/packages/fether-electron/src/main/app/methods/setupDebug.js index 5db1199e9..48935d799 100644 --- a/packages/fether-electron/src/main/app/methods/setupDebug.js +++ b/packages/fether-electron/src/main/app/methods/setupDebug.js @@ -6,11 +6,9 @@ const withDebug = process.env.DEBUG === 'true'; function setupDebug (thatFA) { - const { fetherApp } = thatFA; - // Enable with `DEBUG=true yarn start` and access Developer Tools - if (withDebug && fetherApp.options.webPreferences.devTools) { - fetherApp.window.webContents.openDevTools(); + if (withDebug && thatFA.options.webPreferences.devTools) { + thatFA.window.webContents.openDevTools(); } } diff --git a/packages/fether-electron/src/main/app/methods/setupMenu.js b/packages/fether-electron/src/main/app/methods/setupMenu.js index b54940805..4acde0baa 100644 --- a/packages/fether-electron/src/main/app/methods/setupMenu.js +++ b/packages/fether-electron/src/main/app/methods/setupMenu.js @@ -9,10 +9,8 @@ import Pino from '../utils/pino'; const pino = Pino(); function setupMenu (thatFA) { - const { fetherApp } = thatFA; - // Add application menu - addMenu(fetherApp.window); + addMenu(thatFA.window); pino.info('Finished configuring Electron menu'); } diff --git a/packages/fether-electron/src/main/app/methods/setupParityEthereum.js b/packages/fether-electron/src/main/app/methods/setupParityEthereum.js index 29770fa86..869811d1f 100644 --- a/packages/fether-electron/src/main/app/methods/setupParityEthereum.js +++ b/packages/fether-electron/src/main/app/methods/setupParityEthereum.js @@ -6,11 +6,9 @@ import ParityEthereum from '../parityEthereum'; function setupParityEthereum (thatFA) { - const { fetherApp } = thatFA; - // Download, install, and run Parity Ethereum if not running and requested const parityEthereumInstance = new ParityEthereum(); - parityEthereumInstance.setup(fetherApp.window); + parityEthereumInstance.setup(thatFA.window); } export default setupParityEthereum; diff --git a/packages/fether-electron/src/main/app/methods/setupRequestListeners.js b/packages/fether-electron/src/main/app/methods/setupRequestListeners.js index 1fe301d61..460def29f 100644 --- a/packages/fether-electron/src/main/app/methods/setupRequestListeners.js +++ b/packages/fether-electron/src/main/app/methods/setupRequestListeners.js @@ -9,11 +9,9 @@ import messages from '../messages'; const { ipcMain, session } = electron; function setupRequestListeners (thatFA) { - const { fetherApp } = thatFA; - // Listen to messages from renderer process ipcMain.on('asynchronous-message', (...args) => { - return messages(fetherApp.window, ...args); + return messages(thatFA.window, ...args); }); // WS calls have Origin `file://` by default, which is not trusted. @@ -23,14 +21,12 @@ function setupRequestListeners (thatFA) { urls: ['ws://*/*', 'wss://*/*'] }, (details, callback) => { - if (!fetherApp.window) { + if (!thatFA.window) { // There might be a split second where the user closes the app, so // this.fether.window is null, but there is still a network request done. return; } - details.requestHeaders.Origin = `parity://${ - fetherApp.window.id - }.ui.parity`; + details.requestHeaders.Origin = `parity://${thatFA.window.id}.ui.parity`; callback({ requestHeaders: details.requestHeaders }); // eslint-disable-line } ); diff --git a/packages/fether-electron/src/main/app/methods/setupSecurity.js b/packages/fether-electron/src/main/app/methods/setupSecurity.js index b584282c9..d5e2dcafe 100644 --- a/packages/fether-electron/src/main/app/methods/setupSecurity.js +++ b/packages/fether-electron/src/main/app/methods/setupSecurity.js @@ -4,10 +4,8 @@ // SPDX-License-Identifier: BSD-3-Clause function setupSecurity (thatFA) { - const { fetherApp } = thatFA; - // Security to prevent window contents from being captured by other apps - fetherApp.window.setContentProtection(true); + thatFA.window.setContentProtection(true); } export default setupSecurity; diff --git a/packages/fether-electron/src/main/app/methods/setupWin32Listeners.js b/packages/fether-electron/src/main/app/methods/setupWin32Listeners.js index 2c3c241a4..13bcbb4ee 100644 --- a/packages/fether-electron/src/main/app/methods/setupWin32Listeners.js +++ b/packages/fether-electron/src/main/app/methods/setupWin32Listeners.js @@ -8,8 +8,6 @@ import Pino from '../utils/pino'; const pino = Pino(); function setupWin32Listeners (thatFA) { - const { fetherApp } = thatFA; - if (process.platform === 'win32') { /** * Hook WM_SYSKEYUP @@ -19,7 +17,7 @@ function setupWin32Listeners (thatFA) { * * Reference: https://docs.microsoft.com/en-gb/windows/desktop/inputdev/wm-syskeyup */ - fetherApp.window.hookWindowMessage( + thatFA.window.hookWindowMessage( Number.parseInt('0x0105'), (wParam, lParam) => { // Reference: https://nodejs.org/api/buffer.html @@ -40,7 +38,7 @@ function setupWin32Listeners (thatFA) { * * Credit: http://robmayhew.com/listening-for-events-from-windows-in-electron-tutorial/ */ - fetherApp.window.hookWindowMessage( + thatFA.window.hookWindowMessage( Number.parseInt('0x0112'), (wParam, lParam) => { let eventName = null; @@ -75,7 +73,7 @@ function setupWin32Listeners (thatFA) { * Detect event on Windows when Fether window was moved * or resized */ - fetherApp.window.hookWindowMessage( + thatFA.window.hookWindowMessage( Number.parseInt('0x0232'), (wParam, lParam) => { pino.info('Detected completion of move or resize event'); diff --git a/packages/fether-electron/src/main/app/methods/setupWindowListeners.js b/packages/fether-electron/src/main/app/methods/setupWindowListeners.js index ffde6c97d..deefbe45d 100644 --- a/packages/fether-electron/src/main/app/methods/setupWindowListeners.js +++ b/packages/fether-electron/src/main/app/methods/setupWindowListeners.js @@ -14,13 +14,13 @@ function setupWindowListeners (thatFA) { const { fetherApp } = thatFA; // Open external links in browser - fetherApp.window.webContents.on('new-window', (event, url) => { + thatFA.window.webContents.on('new-window', (event, url) => { event.preventDefault(); electron.shell.openExternal(url); }); // Linux (unchecked on others) - fetherApp.window.on('move', () => { + thatFA.window.on('move', () => { /** * On Linux using this with debouncing is the closest equivalent * to using 'moved' (not supported on Linux) with debouncing @@ -31,7 +31,7 @@ function setupWindowListeners (thatFA) { }); // macOS (not Windows or Linux) - fetherApp.window.on('moved', () => { + thatFA.window.on('moved', () => { /** * On macOS save the position in the 'moved' event since if * we run it just in 'close' instead, then if the Fether app @@ -48,7 +48,7 @@ function setupWindowListeners (thatFA) { }); // macOS and Linux (not Windows) - fetherApp.window.on('resize', () => { + thatFA.window.on('resize', () => { pino.info('Detected resize event'); thatFA.moveWindowUp(); setTimeout(() => { @@ -56,18 +56,18 @@ function setupWindowListeners (thatFA) { }, 5000); }); - fetherApp.window.on('blur', () => { - fetherApp.options.alwaysOnTop + thatFA.window.on('blur', () => { + thatFA.options.alwaysOnTop ? fetherApp.emit('blur-window') : thatFA.hideWindow(); }); - fetherApp.window.on('close', () => { + thatFA.window.on('close', () => { thatFA.onWindowClose(); }); - fetherApp.window.on('closed', () => { - fetherApp.window = null; + thatFA.window.on('closed', () => { + thatFA.window = null; fetherApp.emit('after-closed-window'); }); diff --git a/packages/fether-electron/src/main/app/methods/showTrayBalloon.js b/packages/fether-electron/src/main/app/methods/showTrayBalloon.js index 405872279..b2ad788c5 100644 --- a/packages/fether-electron/src/main/app/methods/showTrayBalloon.js +++ b/packages/fether-electron/src/main/app/methods/showTrayBalloon.js @@ -19,9 +19,7 @@ const iconBalloonPath = path.join( const pino = Pino(); function showTrayBalloon (thatFA) { - const { fetherApp } = thatFA; - - let { tray } = fetherApp; + const { tray } = thatFA; pino.info('Showing Tray Balloon'); diff --git a/packages/fether-electron/src/main/app/methods/showWindow.js b/packages/fether-electron/src/main/app/methods/showWindow.js index 678780e79..55dfa27ba 100644 --- a/packages/fether-electron/src/main/app/methods/showWindow.js +++ b/packages/fether-electron/src/main/app/methods/showWindow.js @@ -14,7 +14,7 @@ const pino = Pino(); function showWindow (thatFA, trayPos) { const { fetherApp } = thatFA; - if (!fetherApp.window) { + if (!thatFA.window) { thatFA.createWindow(); } @@ -30,7 +30,7 @@ function showWindow (thatFA, trayPos) { const mainScreenWorkAreaSize = mainScreen.workAreaSize; // workAreaSize does not include the tray depth - fetherApp.trayDepth = Math.max( + thatFA.trayDepth = Math.max( mainScreenDimensions.width - mainScreenWorkAreaSize.width, mainScreenDimensions.height - mainScreenWorkAreaSize.height ); @@ -65,8 +65,8 @@ function showWindow (thatFA, trayPos) { (loadedWindowPosition && loadedWindowPosition.y) || calculatedWindowPosition.y; - fetherApp.window.setPosition(x, y); - fetherApp.window.show(); + thatFA.window.setPosition(x, y); + thatFA.window.show(); fetherApp.emit('after-show-window'); } diff --git a/packages/fether-electron/src/main/app/methods/updateProgress.js b/packages/fether-electron/src/main/app/methods/updateProgress.js index ed0bad713..0382a8cfc 100644 --- a/packages/fether-electron/src/main/app/methods/updateProgress.js +++ b/packages/fether-electron/src/main/app/methods/updateProgress.js @@ -10,7 +10,7 @@ function updateProgress (thatFA, percentage, eventListenerName) { const { fetherApp } = thatFA; if (percentage) { - fetherApp.window.setProgressBar(percentage); + thatFA.window.setProgressBar(percentage); } if (eventListenerName) { diff --git a/packages/fether-electron/src/main/app/methods/windowClear.js b/packages/fether-electron/src/main/app/methods/windowClear.js index 9c6c2e264..573536425 100644 --- a/packages/fether-electron/src/main/app/methods/windowClear.js +++ b/packages/fether-electron/src/main/app/methods/windowClear.js @@ -3,16 +3,16 @@ // // SPDX-License-Identifier: BSD-3-Clause -function windowClear (fetherApp) { - const { fetherApp } = fetherApp; +function windowClear (thatFA) { + const { fetherApp } = thatFA; - if (fetherApp.window) { + if (thatFA.window) { // Remove relevant events when window object deleted const events = ['close', 'move', 'moved', 'resize']; for (let event in events) { - fetherApp.window.removeAllListeners(event); + thatFA.window.removeAllListeners(event); } - delete fetherApp.window; + delete thatFA.window; } fetherApp.emit('after-close-window'); diff --git a/packages/fether-electron/src/main/index.js b/packages/fether-electron/src/main/index.js index 1cc11748a..a19de8987 100644 --- a/packages/fether-electron/src/main/index.js +++ b/packages/fether-electron/src/main/index.js @@ -7,7 +7,7 @@ import { killParity } from '@parity/electron'; import electron from 'electron'; import Pino from './app/utils/pino'; -import createFetherApp from './app'; +import FetherApp from './app'; import fetherAppOptions from './app/options'; const { app } = electron; @@ -26,7 +26,7 @@ if (!['darwin', 'win32'].includes(process.platform)) { const options = fetherAppOptions(withTaskbar, {}); app.on('ready', () => { - return createFetherApp(app, options); + return new FetherApp(app, options); }); // Event triggered by clicking the Electron icon in the menu Dock @@ -44,7 +44,7 @@ app.on('activate', (event, hasVisibleWindows) => { return; } - return createFetherApp(app, options); + return new FetherApp(app, options); }); app.on('window-all-closed', () => { From 32d53c6f0388c7818de1db5e3207646106283548 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Tue, 5 Feb 2019 18:05:03 +1100 Subject: [PATCH 125/153] refactor: Remove double quotes From 1867a8328722d7d08765638a123502eb0bc5dcf1 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Tue, 5 Feb 2019 18:22:18 +1100 Subject: [PATCH 126/153] refactor: Reorder methods alphabetically --- .../fether-electron/src/main/app/index.js | 78 +++++++++---------- .../src/main/app/methods/index.js | 74 +++++++++--------- packages/fether-electron/src/main/index.js | 2 +- 3 files changed, 76 insertions(+), 78 deletions(-) diff --git a/packages/fether-electron/src/main/app/index.js b/packages/fether-electron/src/main/app/index.js index 29c1811ff..93266051a 100644 --- a/packages/fether-electron/src/main/app/index.js +++ b/packages/fether-electron/src/main/app/index.js @@ -6,32 +6,32 @@ import events from 'events'; import { - setupAppListeners, - createWindow, - updateProgress, + calculateWindowPosition, createPositioner, - setupRequestListeners, createTray, + createWindow, + fixWindowPosition, + getScreenResolution, + hideWindow, loadTray, - showTrayBalloon, + moveWindowUp, + onTrayClick, + onWindowClose, + processSaveWindowPosition, + setupAppListeners, setupDebug, - setupSecurity, - setupLogger, - setupParityEthereum, setupGlobals, + setupLogger, setupMenu, - getScreenResolution, - calculateWindowPosition, - onTrayClick, - fixWindowPosition, - showWindow, - moveWindowUp, - processSaveWindowPosition, - hideWindow, - windowClear, - onWindowClose, + setupParityEthereum, + setupRequestListeners, + setupSecurity, setupWindowListeners, - setupWin32Listeners + setupWin32Listeners, + showTrayBalloon, + showWindow, + updateProgress, + windowClear } from './methods'; let hasCalledInitFetherApp = false; @@ -72,35 +72,33 @@ class FetherApp { this.updateProgress(-1, "after-create-app"); // eslint-disable-line } - setupAppListeners = () => setupAppListeners(this); - createWindow = () => createWindow(this); - updateProgress = (percentage, eventListenerName) => - updateProgress(this, percentage, eventListenerName); + calculateWindowPosition = () => calculateWindowPosition(this); createPositioner = () => createPositioner(this); - setupRequestListeners = () => setupRequestListeners(this); createTray = () => createTray(this); + createWindow = () => createWindow(this); + fixWindowPosition = positionStruct => fixWindowPosition(this, positionStruct); + getScreenResolution = () => getScreenResolution(); + hideWindow = () => hideWindow(this); loadTray = () => loadTray(this); - showTrayBalloon = () => showTrayBalloon(this); + moveWindowUp = () => moveWindowUp(this); + onTrayClick = (e, bounds) => onTrayClick(this, e, bounds); + onWindowClose = () => onWindowClose(); + processSaveWindowPosition = () => processSaveWindowPosition(this); + setupAppListeners = () => setupAppListeners(this); setupDebug = () => setupDebug(this); - setupSecurity = () => setupSecurity(this); - setupLogger = () => setupLogger(); - setupParityEthereum = () => setupParityEthereum(this); setupGlobals = () => setupGlobals(); + setupLogger = () => setupLogger(); setupMenu = () => setupMenu(this); - getScreenResolution = () => getScreenResolution(this); - calculateWindowPosition = () => calculateWindowPosition(this); - getScreenResolution = () => getScreenResolution(); - onTrayClick = (e, bounds) => onTrayClick(this, e, bounds); - fixWindowPosition = positionStruct => fixWindowPosition(this, positionStruct); - getScreenResolution = () => getScreenResolution(this); - showWindow = trayPos => showWindow(this, trayPos); - moveWindowUp = () => moveWindowUp(this); - processSaveWindowPosition = () => processSaveWindowPosition(this); - hideWindow = () => hideWindow(this); - windowClear = () => windowClear(this); - onWindowClose = () => onWindowClose(); + setupParityEthereum = () => setupParityEthereum(this); + setupRequestListeners = () => setupRequestListeners(this); + setupSecurity = () => setupSecurity(this); setupWindowListeners = () => setupWindowListeners(this); setupWin32Listeners = () => setupWin32Listeners(this); + showTrayBalloon = () => showTrayBalloon(this); + showWindow = trayPos => showWindow(this, trayPos); + updateProgress = (percentage, eventListenerName) => + updateProgress(this, percentage, eventListenerName); + windowClear = () => windowClear(this); } export default FetherApp; diff --git a/packages/fether-electron/src/main/app/methods/index.js b/packages/fether-electron/src/main/app/methods/index.js index 818fb4a1d..1d7dc8c0f 100644 --- a/packages/fether-electron/src/main/app/methods/index.js +++ b/packages/fether-electron/src/main/app/methods/index.js @@ -3,58 +3,58 @@ // // SPDX-License-Identifier: BSD-3-Clause -import setupAppListeners from './setupAppListeners'; -import createWindow from './createWindow'; -import updateProgress from './updateProgress'; +import calculateWindowPosition from './calculateWindowPosition'; import createPositioner from './createPositioner'; -import setupRequestListeners from './setupRequestListeners'; import createTray from './createTray'; +import createWindow from './createWindow'; +import fixWindowPosition from './fixWindowPosition'; +import getScreenResolution from './getScreenResolution'; +import hideWindow from './hideWindow'; import loadTray from './loadTray'; -import showTrayBalloon from './showTrayBalloon'; +import moveWindowUp from './moveWindowUp'; +import onTrayClick from './onTrayClick'; +import onWindowClose from './onWindowClose'; +import processSaveWindowPosition from './processSaveWindowPosition'; +import setupAppListeners from './setupAppListeners'; import setupDebug from './setupDebug'; -import setupSecurity from './setupSecurity'; -import setupLogger from './setupLogger'; -import setupParityEthereum from './setupParityEthereum'; import setupGlobals from './setupGlobals'; +import setupLogger from './setupLogger'; import setupMenu from './setupMenu'; -import getScreenResolution from './getScreenResolution'; -import calculateWindowPosition from './calculateWindowPosition'; -import onTrayClick from './onTrayClick'; -import fixWindowPosition from './fixWindowPosition'; -import showWindow from './showWindow'; -import moveWindowUp from './moveWindowUp'; -import processSaveWindowPosition from './processSaveWindowPosition'; -import hideWindow from './hideWindow'; -import windowClear from './windowClear'; -import onWindowClose from './onWindowClose'; +import setupParityEthereum from './setupParityEthereum'; +import setupRequestListeners from './setupRequestListeners'; +import setupSecurity from './setupSecurity'; import setupWindowListeners from './setupWindowListeners'; import setupWin32Listeners from './setupWin32Listeners'; +import showTrayBalloon from './showTrayBalloon'; +import showWindow from './showWindow'; +import updateProgress from './updateProgress'; +import windowClear from './windowClear'; export { - setupAppListeners, - createWindow, - updateProgress, + calculateWindowPosition, createPositioner, - setupRequestListeners, createTray, + createWindow, + fixWindowPosition, + getScreenResolution, + hideWindow, loadTray, - showTrayBalloon, + moveWindowUp, + onTrayClick, + onWindowClose, + processSaveWindowPosition, + setupAppListeners, setupDebug, - setupSecurity, - setupLogger, - setupParityEthereum, setupGlobals, + setupLogger, setupMenu, - getScreenResolution, - calculateWindowPosition, - onTrayClick, - fixWindowPosition, - showWindow, - moveWindowUp, - processSaveWindowPosition, - hideWindow, - windowClear, - onWindowClose, + setupRequestListeners, + setupParityEthereum, + setupSecurity, setupWindowListeners, - setupWin32Listeners + setupWin32Listeners, + showTrayBalloon, + showWindow, + updateProgress, + windowClear }; diff --git a/packages/fether-electron/src/main/index.js b/packages/fether-electron/src/main/index.js index a19de8987..e6dcad74b 100644 --- a/packages/fether-electron/src/main/index.js +++ b/packages/fether-electron/src/main/index.js @@ -3,8 +3,8 @@ // // SPDX-License-Identifier: BSD-3-Clause -import { killParity } from '@parity/electron'; import electron from 'electron'; +import { killParity } from '@parity/electron'; import Pino from './app/utils/pino'; import FetherApp from './app'; From 8115e9b85ecfb0c41dade31e172d8ac6588c1e98 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Tue, 5 Feb 2019 18:26:09 +1100 Subject: [PATCH 127/153] refactor: Remove double quotes From 9d5c0f1c703d4c1be21a46e4d05f59d09b9ec1b8 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Tue, 5 Feb 2019 18:31:55 +1100 Subject: [PATCH 128/153] refactor: Remove eslint-disable-lines since no longer used --- packages/fether-electron/src/main/app/index.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/fether-electron/src/main/app/index.js b/packages/fether-electron/src/main/app/index.js index 93266051a..46f038b1e 100644 --- a/packages/fether-electron/src/main/app/index.js +++ b/packages/fether-electron/src/main/app/index.js @@ -52,11 +52,11 @@ class FetherApp { this.setupAppListeners(); this.createWindow(); - this.updateProgress(0.4, undefined); // eslint-disable-line + this.updateProgress(0.4, undefined); this.createPositioner(); this.setupRequestListeners(); this.createTray(); - this.updateProgress(0.6, undefined); // eslint-disable-line + this.updateProgress(0.6, undefined); this.loadTray(); this.setupDebug(); this.setupSecurity(); @@ -64,12 +64,12 @@ class FetherApp { this.setupParityEthereum(); this.setupGlobals(); this.setupMenu(); - this.updateProgress(0.8, undefined); // eslint-disable-line + this.updateProgress(0.8, undefined); this.showWindow(undefined); - this.updateProgress(1.0, undefined); // eslint-disable-line + this.updateProgress(1.0, undefined); this.setupWindowListeners(); this.setupWin32Listeners(); - this.updateProgress(-1, "after-create-app"); // eslint-disable-line + this.updateProgress(-1, 'after-create-app'); } calculateWindowPosition = () => calculateWindowPosition(this); From 48e5bd6689859d08710d844304c0922de51a0675 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Tue, 5 Feb 2019 18:32:16 +1100 Subject: [PATCH 129/153] refactor: Update according to eslint recommendation --- .../fether-react/src/utils/transaction.js | 24 ++++++++++--------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/packages/fether-react/src/utils/transaction.js b/packages/fether-react/src/utils/transaction.js index 1bf6f3d74..b28e488f8 100644 --- a/packages/fether-react/src/utils/transaction.js +++ b/packages/fether-react/src/utils/transaction.js @@ -142,17 +142,19 @@ const getEthereumTx = tx => { txParams.to = token.address; txParams.data = '0x' + - new Abi(eip20).functions.find(f => f._name === 'transfer').encodeCall([ - new Token('address', to), - new Token( - 'uint', - '0x' + - new BigNumber(amount) - .multipliedBy(new BigNumber(10).pow(token.decimals)) - .toNumber() - .toString(16) - ) - ]); + new Abi(eip20).functions + .find(f => f._name === 'transfer') + .encodeCall([ + new Token('address', to), + new Token( + 'uint', + '0x' + + new BigNumber(amount) + .multipliedBy(new BigNumber(10).pow(token.decimals)) + .toNumber() + .toString(16) + ) + ]); } return new EthereumTx(txParams); From fcb43a944d095c54909af36a15f6faa7b15cec81 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Tue, 5 Feb 2019 18:49:49 +1100 Subject: [PATCH 130/153] refactor: Rename thatFA to fetherApp now that everythings in order --- .../fether-electron/src/main/app/index.js | 10 +++--- .../app/methods/calculateWindowPosition.js | 6 ++-- .../src/main/app/methods/createPositioner.js | 4 +-- .../src/main/app/methods/createTray.js | 6 ++-- .../src/main/app/methods/createWindow.js | 14 ++++---- .../src/main/app/methods/fixWindowPosition.js | 10 +++--- .../src/main/app/methods/hideWindow.js | 10 +++--- .../src/main/app/methods/loadTray.js | 12 +++---- .../src/main/app/methods/moveWindowUp.js | 16 ++++----- .../src/main/app/methods/onTrayClick.js | 12 +++---- .../src/main/app/methods/onWindowClose.js | 6 ++-- .../app/methods/processSaveWindowPosition.js | 30 +++++++++------- .../src/main/app/methods/setupAppListeners.js | 32 ++++++++--------- .../src/main/app/methods/setupDebug.js | 6 ++-- .../src/main/app/methods/setupMenu.js | 4 +-- .../main/app/methods/setupParityEthereum.js | 4 +-- .../main/app/methods/setupRequestListeners.js | 10 +++--- .../src/main/app/methods/setupSecurity.js | 4 +-- .../main/app/methods/setupWin32Listeners.js | 24 ++++++------- .../main/app/methods/setupWindowListeners.js | 34 +++++++++---------- .../src/main/app/methods/showTrayBalloon.js | 4 +-- .../src/main/app/methods/showWindow.js | 18 +++++----- .../src/main/app/methods/updateProgress.js | 6 ++-- .../src/main/app/methods/windowClear.js | 10 +++--- 24 files changed, 145 insertions(+), 147 deletions(-) diff --git a/packages/fether-electron/src/main/app/index.js b/packages/fether-electron/src/main/app/index.js index 46f038b1e..0dc540ac2 100644 --- a/packages/fether-electron/src/main/app/index.js +++ b/packages/fether-electron/src/main/app/index.js @@ -3,7 +3,7 @@ // // SPDX-License-Identifier: BSD-3-Clause -import events from 'events'; +import EventEmitter from 'events'; import { calculateWindowPosition, @@ -36,12 +36,14 @@ import { let hasCalledInitFetherApp = false; -class FetherApp { - fetherApp = new events.EventEmitter(); +class FetherApp extends EventEmitter { + // fetherApp = new events.EventEmitter(); constructor (electronApp, options) { + super(); + if (hasCalledInitFetherApp) { - this.fetherApp.emit( + this.emit( 'error', new Error('Unable to initialise Fether app more than once') ); diff --git a/packages/fether-electron/src/main/app/methods/calculateWindowPosition.js b/packages/fether-electron/src/main/app/methods/calculateWindowPosition.js index 2cf022a25..b3be97a16 100644 --- a/packages/fether-electron/src/main/app/methods/calculateWindowPosition.js +++ b/packages/fether-electron/src/main/app/methods/calculateWindowPosition.js @@ -3,12 +3,12 @@ // // SPDX-License-Identifier: BSD-3-Clause -function calculateWindowPosition (thatFA, trayPos) { - const { cachedBounds, options, positioner, tray } = thatFA; +function calculateWindowPosition (fetherApp, trayPos) { + const { cachedBounds, options, positioner, tray } = fetherApp; if (trayPos && trayPos.x !== 0) { // Cache the bounds - thatFA.cachedBounds = trayPos; + fetherApp.cachedBounds = trayPos; } else if (cachedBounds) { // Cached value will be used if showWindow is called without bounds data trayPos = cachedBounds; diff --git a/packages/fether-electron/src/main/app/methods/createPositioner.js b/packages/fether-electron/src/main/app/methods/createPositioner.js index 8969eed50..f5fa29417 100644 --- a/packages/fether-electron/src/main/app/methods/createPositioner.js +++ b/packages/fether-electron/src/main/app/methods/createPositioner.js @@ -5,8 +5,8 @@ import Positioner from 'electron-positioner'; -function createPositioner (thatFA) { - thatFA.positioner = new Positioner(thatFA.window); +function createPositioner (fetherApp) { + fetherApp.positioner = new Positioner(fetherApp.window); } export default createPositioner; diff --git a/packages/fether-electron/src/main/app/methods/createTray.js b/packages/fether-electron/src/main/app/methods/createTray.js index 895cd1eaf..4a6b88df9 100644 --- a/packages/fether-electron/src/main/app/methods/createTray.js +++ b/packages/fether-electron/src/main/app/methods/createTray.js @@ -5,11 +5,11 @@ import { Tray } from 'electron'; -function createTray (thatFA) { - const { app, options } = thatFA; +function createTray (fetherApp) { + const { app, options } = fetherApp; if (options.withTaskbar) { - thatFA.tray = new Tray(options.icon); + fetherApp.tray = new Tray(options.icon); if (process.platform === 'darwin' && app.dock) { app.dock.setIcon(options.iconDock); diff --git a/packages/fether-electron/src/main/app/methods/createWindow.js b/packages/fether-electron/src/main/app/methods/createWindow.js index 94db3a614..30ce95fec 100644 --- a/packages/fether-electron/src/main/app/methods/createWindow.js +++ b/packages/fether-electron/src/main/app/methods/createWindow.js @@ -7,16 +7,16 @@ import electron from 'electron'; const { BrowserWindow } = electron; -function createWindow (thatFA) { - const { fetherApp, options } = thatFA; +function createWindow (fetherApp) { + const { options } = fetherApp; fetherApp.emit('create-app'); fetherApp.emit('create-window'); - thatFA.window = new BrowserWindow(options); + fetherApp.window = new BrowserWindow(options); if (options.showOnAllWorkspaces !== false) { - thatFA.window.setVisibleOnAllWorkspaces(true); + fetherApp.window.setVisibleOnAllWorkspaces(true); } if (process.platform !== 'darwin') { @@ -26,13 +26,13 @@ function createWindow (thatFA) { * of the window when menu open/close toggled. The user will need to be informed * that pressing ALT displays the Fether menu */ - thatFA.window.setAutoHideMenuBar(true); // ALT shows menu bar - thatFA.window.setMenuBarVisibility(false); + fetherApp.window.setAutoHideMenuBar(true); // ALT shows menu bar + fetherApp.window.setMenuBarVisibility(false); } // Opens file:///path/to/build/index.html in prod mode, or whatever is // passed to ELECTRON_START_URL - thatFA.window.loadURL(options.index); + fetherApp.window.loadURL(options.index); fetherApp.emit('after-create-window'); } diff --git a/packages/fether-electron/src/main/app/methods/fixWindowPosition.js b/packages/fether-electron/src/main/app/methods/fixWindowPosition.js index 1736405bf..306085818 100644 --- a/packages/fether-electron/src/main/app/methods/fixWindowPosition.js +++ b/packages/fether-electron/src/main/app/methods/fixWindowPosition.js @@ -11,8 +11,8 @@ * coordinates of the window are outside the screen bounds the window * will be restored into the users primary screen. */ -function fixWindowPosition (thatFA, proposedWindowPosition) { - const { trayDepth } = thatFA; +function fixWindowPosition (fetherApp, proposedWindowPosition) { + const { trayDepth } = fetherApp; if (!proposedWindowPosition) { return; @@ -23,10 +23,10 @@ function fixWindowPosition (thatFA, proposedWindowPosition) { y: undefined }; - const currentScreenResolution = thatFA.getScreenResolution(); + const currentScreenResolution = fetherApp.getScreenResolution(); - const windowWidth = thatFA.window.getSize()[0]; - const windowHeight = thatFA.window.getSize()[1]; + const windowWidth = fetherApp.window.getSize()[0]; + const windowHeight = fetherApp.window.getSize()[1]; if (proposedWindowPosition.x < trayDepth) { newPosition.x = trayDepth; diff --git a/packages/fether-electron/src/main/app/methods/hideWindow.js b/packages/fether-electron/src/main/app/methods/hideWindow.js index c00e5d046..2621c1ad8 100644 --- a/packages/fether-electron/src/main/app/methods/hideWindow.js +++ b/packages/fether-electron/src/main/app/methods/hideWindow.js @@ -3,17 +3,15 @@ // // SPDX-License-Identifier: BSD-3-Clause -function hideWindow (thatFA) { - const { fetherApp } = thatFA; - - if (!thatFA.window) { +function hideWindow (fetherApp) { + if (!fetherApp.window) { return; } - thatFA.processSaveWindowPosition(); // Save window position when hide, particularly necessary on Linux + fetherApp.processSaveWindowPosition(); // Save window position when hide, particularly necessary on Linux fetherApp.emit('hide-window'); - thatFA.window.hide(); + fetherApp.window.hide(); fetherApp.emit('after-hide-window'); } diff --git a/packages/fether-electron/src/main/app/methods/loadTray.js b/packages/fether-electron/src/main/app/methods/loadTray.js index fca5727f3..4cbcf09c5 100644 --- a/packages/fether-electron/src/main/app/methods/loadTray.js +++ b/packages/fether-electron/src/main/app/methods/loadTray.js @@ -7,8 +7,8 @@ import Pino from '../utils/pino'; const pino = Pino(); -function loadTray (thatFA) { - const { fetherApp, app, options, tray } = thatFA; +function loadTray (fetherApp) { + const { app, options, tray } = fetherApp; if (options.withTaskbar) { fetherApp.emit('load-tray'); @@ -23,16 +23,16 @@ function loadTray (thatFA) { // Note: See https://github.com/RocketChat/Rocket.Chat.Electron/issues/44 if (process.platform === 'win32') { - thatFA.showTrayBalloon(); + fetherApp.showTrayBalloon(); } - tray.on(defaultClickEvent, () => thatFA.onTrayClick(thatFA)); - tray.on('double-click', () => thatFA.onTrayClick(thatFA)); + tray.on(defaultClickEvent, () => fetherApp.onTrayClick(fetherApp)); + tray.on('double-click', () => fetherApp.onTrayClick(fetherApp)); // Right click event handler does not work on Windows as intended tray.on('right-click', () => { if (process.platform === 'win32') { pino.info('Detected right click on Windows'); - thatFA.showTrayBalloon(); + fetherApp.showTrayBalloon(); } }); tray.setToolTip(options.tooltip); diff --git a/packages/fether-electron/src/main/app/methods/moveWindowUp.js b/packages/fether-electron/src/main/app/methods/moveWindowUp.js index 07a279e9f..e47087e80 100644 --- a/packages/fether-electron/src/main/app/methods/moveWindowUp.js +++ b/packages/fether-electron/src/main/app/methods/moveWindowUp.js @@ -15,29 +15,27 @@ const pino = Pino(); * with a larger window height that causes it to be cropped, then we will * automatically move the window upward so it is viewable to the user */ -function moveWindowUp (thatFA) { - const { fetherApp } = thatFA; - - if (!thatFA.window) { +function moveWindowUp (fetherApp) { + if (!fetherApp.window) { return; } pino.info('Fether window resized. Moving it back up into view if required'); - const position = thatFA.window.getPosition(); + const position = fetherApp.window.getPosition(); const positionStruct = { x: position[0], y: position[1] }; - const trayDepth = thatFA.trayDepth || 40; // Default incase resizes on load - const currentScreenResolution = thatFA.getScreenResolution(); - const windowHeight = thatFA.window.getSize()[1]; + const trayDepth = fetherApp.trayDepth || 40; // Default incase resizes on load + const currentScreenResolution = fetherApp.getScreenResolution(); + const windowHeight = fetherApp.window.getSize()[1]; const maxWindowY = currentScreenResolution.y - windowHeight - trayDepth; const adjustY = positionStruct.y - maxWindowY; if (adjustY > 0) { fetherApp.emit('moved-window-up-into-view'); - thatFA.window.setPosition(positionStruct.x, maxWindowY); + fetherApp.window.setPosition(positionStruct.x, maxWindowY); } } diff --git a/packages/fether-electron/src/main/app/methods/onTrayClick.js b/packages/fether-electron/src/main/app/methods/onTrayClick.js index fc6f863b2..06d2aa93a 100644 --- a/packages/fether-electron/src/main/app/methods/onTrayClick.js +++ b/packages/fether-electron/src/main/app/methods/onTrayClick.js @@ -3,22 +3,22 @@ // // SPDX-License-Identifier: BSD-3-Clause -function onTrayClick (thatFA, e, bounds) { - const { cachedBounds } = thatFA; +function onTrayClick (fetherApp, e, bounds) { + const { cachedBounds } = fetherApp; if ( e.altKey || e.shiftKey || e.ctrlKey || e.metaKey || - (thatFA.window && thatFA.window.isVisible()) + (fetherApp.window && fetherApp.window.isVisible()) ) { - return thatFA.hideWindow(); + return fetherApp.hideWindow(); } // cachedBounds are needed for double-clicked event - thatFA.cachedBounds = bounds || cachedBounds; - thatFA.showWindow(thatFA.cachedBounds); + fetherApp.cachedBounds = bounds || cachedBounds; + fetherApp.showWindow(fetherApp.cachedBounds); } export default onTrayClick; diff --git a/packages/fether-electron/src/main/app/methods/onWindowClose.js b/packages/fether-electron/src/main/app/methods/onWindowClose.js index 1ada004de..939463bd2 100644 --- a/packages/fether-electron/src/main/app/methods/onWindowClose.js +++ b/packages/fether-electron/src/main/app/methods/onWindowClose.js @@ -3,9 +3,9 @@ // // SPDX-License-Identifier: BSD-3-Clause -function onWindowClose (thatFA) { - thatFA.processSaveWindowPosition(); - thatFA.windowClear(); +function onWindowClose (fetherApp) { + fetherApp.processSaveWindowPosition(); + fetherApp.windowClear(); } export default onWindowClose; diff --git a/packages/fether-electron/src/main/app/methods/processSaveWindowPosition.js b/packages/fether-electron/src/main/app/methods/processSaveWindowPosition.js index 51cbbe7c8..9e6f741d4 100644 --- a/packages/fether-electron/src/main/app/methods/processSaveWindowPosition.js +++ b/packages/fether-electron/src/main/app/methods/processSaveWindowPosition.js @@ -9,30 +9,28 @@ import { } from '../utils/window'; import { saveWindowPosition } from '../settings'; -function processSaveWindowPosition (thatFA) { - const { fetherApp } = thatFA; - - if (!thatFA.window) { +function processSaveWindowPosition (fetherApp) { + if (!fetherApp.window) { return; } - const currentScreenResolution = thatFA.getScreenResolution(); + const currentScreenResolution = fetherApp.getScreenResolution(); - thatFA.previousScreenResolution = getChangedScreenResolution( - thatFA.previousScreenResolution, + fetherApp.previousScreenResolution = getChangedScreenResolution( + fetherApp.previousScreenResolution, currentScreenResolution ); // Get the latest position. The window may have been moved to a different // screen with smaller resolution. We must move it to prevent cropping. - const position = thatFA.window.getPosition(); + const position = fetherApp.window.getPosition(); const positionStruct = { x: position[0], y: position[1] }; - const fixedWindowPosition = thatFA.fixWindowPosition(positionStruct); + const fixedWindowPosition = fetherApp.fixWindowPosition(positionStruct); const newFixedPosition = { x: fixedWindowPosition.x || positionStruct.x, @@ -48,18 +46,26 @@ function processSaveWindowPosition (thatFA) { */ if ( shouldFixWindowPosition( - thatFA.previousScreenResolution, + fetherApp.previousScreenResolution, currentScreenResolution ) ) { // Move window to the fixed x-coordinate position if that required fixing if (fixedWindowPosition.x) { - thatFA.window.setPosition(fixedWindowPosition.x, positionStruct.y, true); + fetherApp.window.setPosition( + fixedWindowPosition.x, + positionStruct.y, + true + ); } // Move window to the fixed y-coordinate position if that required fixing if (fixedWindowPosition.y) { - thatFA.window.setPosition(positionStruct.x, fixedWindowPosition.y, true); + fetherApp.window.setPosition( + positionStruct.x, + fixedWindowPosition.y, + true + ); } } diff --git a/packages/fether-electron/src/main/app/methods/setupAppListeners.js b/packages/fether-electron/src/main/app/methods/setupAppListeners.js index 51547874c..c48f3ed0f 100644 --- a/packages/fether-electron/src/main/app/methods/setupAppListeners.js +++ b/packages/fether-electron/src/main/app/methods/setupAppListeners.js @@ -9,52 +9,52 @@ import Pino from '../utils/pino'; const pino = Pino(); -function setupAppListeners (thatFA) { - thatFA.fetherApp.on('create-app', () => { +function setupAppListeners (fetherApp) { + fetherApp.on('create-app', () => { pino.info( `Starting ${productName} (${ - thatFA.options.withTaskbar ? 'with' : 'without' + fetherApp.options.withTaskbar ? 'with' : 'without' } tray icon)...` ); }); - thatFA.fetherApp.on('create-window', () => { + fetherApp.on('create-window', () => { pino.info('Creating window'); }); - thatFA.fetherApp.on('after-create-window', () => { + fetherApp.on('after-create-window', () => { pino.info('Finished creating window'); }); - thatFA.fetherApp.on('load-tray', () => { + fetherApp.on('load-tray', () => { pino.info('Configuring taskbar mode for the window'); }); - thatFA.fetherApp.on('show-window', () => { + fetherApp.on('show-window', () => { pino.info('Showing window'); }); - thatFA.fetherApp.on('after-show-window', () => { + fetherApp.on('after-show-window', () => { pino.info('Finished showing window'); }); - thatFA.fetherApp.on('after-create-app', () => { + fetherApp.on('after-create-app', () => { pino.info(`Ready to use ${productName}`); }); - thatFA.fetherApp.on('hide-window', () => { + fetherApp.on('hide-window', () => { pino.info('Hiding window on blur since not on top'); }); - thatFA.fetherApp.on('after-hide-window', () => { + fetherApp.on('after-hide-window', () => { pino.info('Finished hiding window'); }); - thatFA.fetherApp.on('blur-window', () => { + fetherApp.on('blur-window', () => { pino.info('Blur window since lost focus when on top'); }); - thatFA.fetherApp.on('after-moved-window-position-saved', () => { + fetherApp.on('after-moved-window-position-saved', () => { const position = getSavedWindowPosition(); pino.info( @@ -62,15 +62,15 @@ function setupAppListeners (thatFA) { ); }); - thatFA.fetherApp.on('moved-window-up-into-view', () => { + fetherApp.on('moved-window-up-into-view', () => { pino.info('Moved window up into view'); }); - thatFA.fetherApp.on('after-close-window', () => { + fetherApp.on('after-close-window', () => { pino.info('Deleted window upon close'); }); - thatFA.fetherApp.on('error', error => { + fetherApp.on('error', error => { console.error(error); }); } diff --git a/packages/fether-electron/src/main/app/methods/setupDebug.js b/packages/fether-electron/src/main/app/methods/setupDebug.js index 48935d799..eee4a4b54 100644 --- a/packages/fether-electron/src/main/app/methods/setupDebug.js +++ b/packages/fether-electron/src/main/app/methods/setupDebug.js @@ -5,10 +5,10 @@ const withDebug = process.env.DEBUG === 'true'; -function setupDebug (thatFA) { +function setupDebug (fetherApp) { // Enable with `DEBUG=true yarn start` and access Developer Tools - if (withDebug && thatFA.options.webPreferences.devTools) { - thatFA.window.webContents.openDevTools(); + if (withDebug && fetherApp.options.webPreferences.devTools) { + fetherApp.window.webContents.openDevTools(); } } diff --git a/packages/fether-electron/src/main/app/methods/setupMenu.js b/packages/fether-electron/src/main/app/methods/setupMenu.js index 4acde0baa..6f2565ebd 100644 --- a/packages/fether-electron/src/main/app/methods/setupMenu.js +++ b/packages/fether-electron/src/main/app/methods/setupMenu.js @@ -8,9 +8,9 @@ import Pino from '../utils/pino'; const pino = Pino(); -function setupMenu (thatFA) { +function setupMenu (fetherApp) { // Add application menu - addMenu(thatFA.window); + addMenu(fetherApp.window); pino.info('Finished configuring Electron menu'); } diff --git a/packages/fether-electron/src/main/app/methods/setupParityEthereum.js b/packages/fether-electron/src/main/app/methods/setupParityEthereum.js index 869811d1f..2c1d0330d 100644 --- a/packages/fether-electron/src/main/app/methods/setupParityEthereum.js +++ b/packages/fether-electron/src/main/app/methods/setupParityEthereum.js @@ -5,10 +5,10 @@ import ParityEthereum from '../parityEthereum'; -function setupParityEthereum (thatFA) { +function setupParityEthereum (fetherApp) { // Download, install, and run Parity Ethereum if not running and requested const parityEthereumInstance = new ParityEthereum(); - parityEthereumInstance.setup(thatFA.window); + parityEthereumInstance.setup(fetherApp.window); } export default setupParityEthereum; diff --git a/packages/fether-electron/src/main/app/methods/setupRequestListeners.js b/packages/fether-electron/src/main/app/methods/setupRequestListeners.js index 460def29f..108e8c3e0 100644 --- a/packages/fether-electron/src/main/app/methods/setupRequestListeners.js +++ b/packages/fether-electron/src/main/app/methods/setupRequestListeners.js @@ -8,10 +8,10 @@ import electron from 'electron'; import messages from '../messages'; const { ipcMain, session } = electron; -function setupRequestListeners (thatFA) { +function setupRequestListeners (fetherApp) { // Listen to messages from renderer process ipcMain.on('asynchronous-message', (...args) => { - return messages(thatFA.window, ...args); + return messages(fetherApp.window, ...args); }); // WS calls have Origin `file://` by default, which is not trusted. @@ -21,12 +21,14 @@ function setupRequestListeners (thatFA) { urls: ['ws://*/*', 'wss://*/*'] }, (details, callback) => { - if (!thatFA.window) { + if (!fetherApp.window) { // There might be a split second where the user closes the app, so // this.fether.window is null, but there is still a network request done. return; } - details.requestHeaders.Origin = `parity://${thatFA.window.id}.ui.parity`; + details.requestHeaders.Origin = `parity://${ + fetherApp.window.id + }.ui.parity`; callback({ requestHeaders: details.requestHeaders }); // eslint-disable-line } ); diff --git a/packages/fether-electron/src/main/app/methods/setupSecurity.js b/packages/fether-electron/src/main/app/methods/setupSecurity.js index d5e2dcafe..9a71309c6 100644 --- a/packages/fether-electron/src/main/app/methods/setupSecurity.js +++ b/packages/fether-electron/src/main/app/methods/setupSecurity.js @@ -3,9 +3,9 @@ // // SPDX-License-Identifier: BSD-3-Clause -function setupSecurity (thatFA) { +function setupSecurity (fetherApp) { // Security to prevent window contents from being captured by other apps - thatFA.window.setContentProtection(true); + fetherApp.window.setContentProtection(true); } export default setupSecurity; diff --git a/packages/fether-electron/src/main/app/methods/setupWin32Listeners.js b/packages/fether-electron/src/main/app/methods/setupWin32Listeners.js index 13bcbb4ee..032d6795c 100644 --- a/packages/fether-electron/src/main/app/methods/setupWin32Listeners.js +++ b/packages/fether-electron/src/main/app/methods/setupWin32Listeners.js @@ -7,7 +7,7 @@ import Pino from '../utils/pino'; const pino = Pino(); -function setupWin32Listeners (thatFA) { +function setupWin32Listeners (fetherApp) { if (process.platform === 'win32') { /** * Hook WM_SYSKEYUP @@ -17,7 +17,7 @@ function setupWin32Listeners (thatFA) { * * Reference: https://docs.microsoft.com/en-gb/windows/desktop/inputdev/wm-syskeyup */ - thatFA.window.hookWindowMessage( + fetherApp.window.hookWindowMessage( Number.parseInt('0x0105'), (wParam, lParam) => { // Reference: https://nodejs.org/api/buffer.html @@ -26,7 +26,7 @@ function setupWin32Listeners (thatFA) { * i.e. Use `wParam && wParam.readUInt32LE(0) === 77` to detect ALT+m */ if (wParam) { - thatFA.showTrayBalloon(); + fetherApp.showTrayBalloon(); } } ); @@ -38,7 +38,7 @@ function setupWin32Listeners (thatFA) { * * Credit: http://robmayhew.com/listening-for-events-from-windows-in-electron-tutorial/ */ - thatFA.window.hookWindowMessage( + fetherApp.window.hookWindowMessage( Number.parseInt('0x0112'), (wParam, lParam) => { let eventName = null; @@ -46,19 +46,19 @@ function setupWin32Listeners (thatFA) { if (wParam.readUInt32LE(0) === 0xf060) { // SC_CLOSE eventName = 'close'; - thatFA.onWindowClose(); + fetherApp.onWindowClose(); } else if (wParam.readUInt32LE(0) === 0xf030) { // SC_MAXIMIZE eventName = 'maximize'; - thatFA.showTrayBalloon(); + fetherApp.showTrayBalloon(); } else if (wParam.readUInt32LE(0) === 0xf020) { // SC_MINIMIZE eventName = 'minimize'; - thatFA.processSaveWindowPosition(); + fetherApp.processSaveWindowPosition(); } else if (wParam.readUInt32LE(0) === 0xf120) { // SC_RESTORE eventName = 'restored'; - thatFA.showTrayBalloon(); + fetherApp.showTrayBalloon(); } if (eventName !== null) { @@ -73,23 +73,23 @@ function setupWin32Listeners (thatFA) { * Detect event on Windows when Fether window was moved * or resized */ - thatFA.window.hookWindowMessage( + fetherApp.window.hookWindowMessage( Number.parseInt('0x0232'), (wParam, lParam) => { pino.info('Detected completion of move or resize event'); // Move Fether window back up into view if it was a resize event // that causes the bottom to be cropped - thatFA.moveWindowUp(); + fetherApp.moveWindowUp(); // Try again after a delay incase Fether window resize occurs // x seconds after navigating to a new page. setTimeout(() => { - thatFA.moveWindowUp(); + fetherApp.moveWindowUp(); }, 5000); // Save Fether window position to Electron settings - thatFA.processSaveWindowPosition(); + fetherApp.processSaveWindowPosition(); } ); } diff --git a/packages/fether-electron/src/main/app/methods/setupWindowListeners.js b/packages/fether-electron/src/main/app/methods/setupWindowListeners.js index deefbe45d..d99024f7a 100644 --- a/packages/fether-electron/src/main/app/methods/setupWindowListeners.js +++ b/packages/fether-electron/src/main/app/methods/setupWindowListeners.js @@ -10,28 +10,26 @@ import Pino from '../utils/pino'; const pino = Pino(); -function setupWindowListeners (thatFA) { - const { fetherApp } = thatFA; - +function setupWindowListeners (fetherApp) { // Open external links in browser - thatFA.window.webContents.on('new-window', (event, url) => { + fetherApp.window.webContents.on('new-window', (event, url) => { event.preventDefault(); electron.shell.openExternal(url); }); // Linux (unchecked on others) - thatFA.window.on('move', () => { + fetherApp.window.on('move', () => { /** * On Linux using this with debouncing is the closest equivalent * to using 'moved' (not supported on Linux) with debouncing */ debounce(() => { - thatFA.processSaveWindowPosition(); + fetherApp.processSaveWindowPosition(); }, 1000); }); // macOS (not Windows or Linux) - thatFA.window.on('moved', () => { + fetherApp.window.on('moved', () => { /** * On macOS save the position in the 'moved' event since if * we run it just in 'close' instead, then if the Fether app @@ -44,30 +42,30 @@ function setupWindowListeners (thatFA) { * On Linux the closest equivalent to achieving 'moved' is debouncing * on the 'move' event. It also works in 'close' even when app crashes */ - thatFA.processSaveWindowPosition(); + fetherApp.processSaveWindowPosition(); }); // macOS and Linux (not Windows) - thatFA.window.on('resize', () => { + fetherApp.window.on('resize', () => { pino.info('Detected resize event'); - thatFA.moveWindowUp(); + fetherApp.moveWindowUp(); setTimeout(() => { - thatFA.moveWindowUp(); + fetherApp.moveWindowUp(); }, 5000); }); - thatFA.window.on('blur', () => { - thatFA.options.alwaysOnTop + fetherApp.window.on('blur', () => { + fetherApp.options.alwaysOnTop ? fetherApp.emit('blur-window') - : thatFA.hideWindow(); + : fetherApp.hideWindow(); }); - thatFA.window.on('close', () => { - thatFA.onWindowClose(); + fetherApp.window.on('close', () => { + fetherApp.onWindowClose(); }); - thatFA.window.on('closed', () => { - thatFA.window = null; + fetherApp.window.on('closed', () => { + fetherApp.window = null; fetherApp.emit('after-closed-window'); }); diff --git a/packages/fether-electron/src/main/app/methods/showTrayBalloon.js b/packages/fether-electron/src/main/app/methods/showTrayBalloon.js index b2ad788c5..15bdd8035 100644 --- a/packages/fether-electron/src/main/app/methods/showTrayBalloon.js +++ b/packages/fether-electron/src/main/app/methods/showTrayBalloon.js @@ -18,8 +18,8 @@ const iconBalloonPath = path.join( const pino = Pino(); -function showTrayBalloon (thatFA) { - const { tray } = thatFA; +function showTrayBalloon (fetherApp) { + const { tray } = fetherApp; pino.info('Showing Tray Balloon'); diff --git a/packages/fether-electron/src/main/app/methods/showWindow.js b/packages/fether-electron/src/main/app/methods/showWindow.js index 55dfa27ba..5aad47ef4 100644 --- a/packages/fether-electron/src/main/app/methods/showWindow.js +++ b/packages/fether-electron/src/main/app/methods/showWindow.js @@ -11,16 +11,14 @@ import Pino from '../utils/pino'; const pino = Pino(); -function showWindow (thatFA, trayPos) { - const { fetherApp } = thatFA; - - if (!thatFA.window) { - thatFA.createWindow(); +function showWindow (fetherApp, trayPos) { + if (!fetherApp.window) { + fetherApp.createWindow(); } fetherApp.emit('show-window'); - const calculatedWindowPosition = thatFA.calculateWindowPosition(trayPos); + const calculatedWindowPosition = fetherApp.calculateWindowPosition(trayPos); pino.info('Calculated window position: ', calculatedWindowPosition); @@ -30,7 +28,7 @@ function showWindow (thatFA, trayPos) { const mainScreenWorkAreaSize = mainScreen.workAreaSize; // workAreaSize does not include the tray depth - thatFA.trayDepth = Math.max( + fetherApp.trayDepth = Math.max( mainScreenDimensions.width - mainScreenWorkAreaSize.width, mainScreenDimensions.height - mainScreenWorkAreaSize.height ); @@ -46,7 +44,7 @@ function showWindow (thatFA, trayPos) { pino.info('Loaded window position: ', loadedWindowPosition); - const fixedWindowPosition = thatFA.fixWindowPosition(loadedWindowPosition); + const fixedWindowPosition = fetherApp.fixWindowPosition(loadedWindowPosition); pino.info('Fixed window position: ', fixedWindowPosition); @@ -65,8 +63,8 @@ function showWindow (thatFA, trayPos) { (loadedWindowPosition && loadedWindowPosition.y) || calculatedWindowPosition.y; - thatFA.window.setPosition(x, y); - thatFA.window.show(); + fetherApp.window.setPosition(x, y); + fetherApp.window.show(); fetherApp.emit('after-show-window'); } diff --git a/packages/fether-electron/src/main/app/methods/updateProgress.js b/packages/fether-electron/src/main/app/methods/updateProgress.js index 0382a8cfc..c143a5952 100644 --- a/packages/fether-electron/src/main/app/methods/updateProgress.js +++ b/packages/fether-electron/src/main/app/methods/updateProgress.js @@ -6,11 +6,9 @@ // Optionally update the progress bar shown on the Dock icon // (i.e. 0.1 is 10%, 1.0 is 100%, -1 hides progress bar). // Optionally emit event -function updateProgress (thatFA, percentage, eventListenerName) { - const { fetherApp } = thatFA; - +function updateProgress (fetherApp, percentage, eventListenerName) { if (percentage) { - thatFA.window.setProgressBar(percentage); + fetherApp.window.setProgressBar(percentage); } if (eventListenerName) { diff --git a/packages/fether-electron/src/main/app/methods/windowClear.js b/packages/fether-electron/src/main/app/methods/windowClear.js index 573536425..d1b2702cc 100644 --- a/packages/fether-electron/src/main/app/methods/windowClear.js +++ b/packages/fether-electron/src/main/app/methods/windowClear.js @@ -3,16 +3,14 @@ // // SPDX-License-Identifier: BSD-3-Clause -function windowClear (thatFA) { - const { fetherApp } = thatFA; - - if (thatFA.window) { +function windowClear (fetherApp) { + if (fetherApp.window) { // Remove relevant events when window object deleted const events = ['close', 'move', 'moved', 'resize']; for (let event in events) { - thatFA.window.removeAllListeners(event); + fetherApp.window.removeAllListeners(event); } - delete thatFA.window; + delete fetherApp.window; } fetherApp.emit('after-close-window'); From b56184468dd3a76c55680072367eac71ab394344 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Tue, 5 Feb 2019 20:39:09 +1100 Subject: [PATCH 131/153] refactor: Polishing up. Shorten names and destructuring --- .../fether-electron/src/main/app/index.js | 18 +-- .../app/methods/calculateWindowPosition.js | 4 +- .../src/main/app/methods/createPositioner.js | 2 +- .../src/main/app/methods/createTray.js | 9 +- .../src/main/app/methods/createWindow.js | 17 ++- .../src/main/app/methods/fixWindowPosition.js | 33 ++---- .../main/app/methods/getScreenResolution.js | 7 +- .../src/main/app/methods/hideWindow.js | 9 +- .../src/main/app/methods/index.js | 16 +-- .../src/main/app/methods/loadTray.js | 10 +- .../src/main/app/methods/moveWindowUp.js | 22 ++-- .../src/main/app/methods/onTrayClick.js | 18 ++- .../src/main/app/methods/onWindowClose.js | 6 +- .../app/methods/processSaveWindowPosition.js | 59 ++++----- .../src/main/app/methods/setupAppListeners.js | 6 +- .../src/main/app/methods/setupDebug.js | 5 +- .../src/main/app/methods/setupMenu.js | 5 +- .../main/app/methods/setupParityEthereum.js | 2 +- .../main/app/methods/setupRequestListeners.js | 10 +- .../src/main/app/methods/setupSecurity.js | 2 +- .../main/app/methods/setupWin32Listeners.js | 112 +++++++++--------- .../main/app/methods/setupWindowListeners.js | 45 ++++--- .../src/main/app/methods/showWindow.js | 38 +++--- .../src/main/app/methods/updateProgress.js | 4 +- .../src/main/app/methods/windowClear.js | 8 +- 25 files changed, 230 insertions(+), 237 deletions(-) diff --git a/packages/fether-electron/src/main/app/index.js b/packages/fether-electron/src/main/app/index.js index 0dc540ac2..67f9f9923 100644 --- a/packages/fether-electron/src/main/app/index.js +++ b/packages/fether-electron/src/main/app/index.js @@ -6,18 +6,18 @@ import EventEmitter from 'events'; import { - calculateWindowPosition, + calculateWinPosition, createPositioner, createTray, createWindow, - fixWindowPosition, + fixWinPosition, getScreenResolution, hideWindow, loadTray, moveWindowUp, onTrayClick, onWindowClose, - processSaveWindowPosition, + processSaveWinPosition, setupAppListeners, setupDebug, setupGlobals, @@ -26,7 +26,7 @@ import { setupParityEthereum, setupRequestListeners, setupSecurity, - setupWindowListeners, + setupWinListeners, setupWin32Listeners, showTrayBalloon, showWindow, @@ -69,23 +69,23 @@ class FetherApp extends EventEmitter { this.updateProgress(0.8, undefined); this.showWindow(undefined); this.updateProgress(1.0, undefined); - this.setupWindowListeners(); + this.setupWinListeners(); this.setupWin32Listeners(); this.updateProgress(-1, 'after-create-app'); } - calculateWindowPosition = () => calculateWindowPosition(this); + calculateWinPosition = () => calculateWinPosition(this); createPositioner = () => createPositioner(this); createTray = () => createTray(this); createWindow = () => createWindow(this); - fixWindowPosition = positionStruct => fixWindowPosition(this, positionStruct); + fixWinPosition = positionStruct => fixWinPosition(this, positionStruct); getScreenResolution = () => getScreenResolution(); hideWindow = () => hideWindow(this); loadTray = () => loadTray(this); moveWindowUp = () => moveWindowUp(this); onTrayClick = (e, bounds) => onTrayClick(this, e, bounds); onWindowClose = () => onWindowClose(); - processSaveWindowPosition = () => processSaveWindowPosition(this); + processSaveWinPosition = () => processSaveWinPosition(this); setupAppListeners = () => setupAppListeners(this); setupDebug = () => setupDebug(this); setupGlobals = () => setupGlobals(); @@ -94,7 +94,7 @@ class FetherApp extends EventEmitter { setupParityEthereum = () => setupParityEthereum(this); setupRequestListeners = () => setupRequestListeners(this); setupSecurity = () => setupSecurity(this); - setupWindowListeners = () => setupWindowListeners(this); + setupWinListeners = () => setupWinListeners(this); setupWin32Listeners = () => setupWin32Listeners(this); showTrayBalloon = () => showTrayBalloon(this); showWindow = trayPos => showWindow(this, trayPos); diff --git a/packages/fether-electron/src/main/app/methods/calculateWindowPosition.js b/packages/fether-electron/src/main/app/methods/calculateWindowPosition.js index b3be97a16..88571a8dc 100644 --- a/packages/fether-electron/src/main/app/methods/calculateWindowPosition.js +++ b/packages/fether-electron/src/main/app/methods/calculateWindowPosition.js @@ -3,7 +3,7 @@ // // SPDX-License-Identifier: BSD-3-Clause -function calculateWindowPosition (fetherApp, trayPos) { +function calculateWinPosition (fetherApp, trayPos) { const { cachedBounds, options, positioner, tray } = fetherApp; if (trayPos && trayPos.x !== 0) { @@ -40,4 +40,4 @@ function calculateWindowPosition (fetherApp, trayPos) { }; } -export default calculateWindowPosition; +export default calculateWinPosition; diff --git a/packages/fether-electron/src/main/app/methods/createPositioner.js b/packages/fether-electron/src/main/app/methods/createPositioner.js index f5fa29417..327152bdf 100644 --- a/packages/fether-electron/src/main/app/methods/createPositioner.js +++ b/packages/fether-electron/src/main/app/methods/createPositioner.js @@ -6,7 +6,7 @@ import Positioner from 'electron-positioner'; function createPositioner (fetherApp) { - fetherApp.positioner = new Positioner(fetherApp.window); + fetherApp.positioner = new Positioner(fetherApp.win); } export default createPositioner; diff --git a/packages/fether-electron/src/main/app/methods/createTray.js b/packages/fether-electron/src/main/app/methods/createTray.js index 4a6b88df9..015f66fa5 100644 --- a/packages/fether-electron/src/main/app/methods/createTray.js +++ b/packages/fether-electron/src/main/app/methods/createTray.js @@ -6,13 +6,16 @@ import { Tray } from 'electron'; function createTray (fetherApp) { - const { app, options } = fetherApp; + const { + app: { dock }, + options + } = fetherApp; if (options.withTaskbar) { fetherApp.tray = new Tray(options.icon); - if (process.platform === 'darwin' && app.dock) { - app.dock.setIcon(options.iconDock); + if (process.platform === 'darwin' && dock) { + dock.setIcon(options.iconDock); } } } diff --git a/packages/fether-electron/src/main/app/methods/createWindow.js b/packages/fether-electron/src/main/app/methods/createWindow.js index 30ce95fec..f39eae548 100644 --- a/packages/fether-electron/src/main/app/methods/createWindow.js +++ b/packages/fether-electron/src/main/app/methods/createWindow.js @@ -13,26 +13,25 @@ function createWindow (fetherApp) { fetherApp.emit('create-app'); fetherApp.emit('create-window'); - fetherApp.window = new BrowserWindow(options); + fetherApp.win = new BrowserWindow(options); if (options.showOnAllWorkspaces !== false) { - fetherApp.window.setVisibleOnAllWorkspaces(true); + fetherApp.win.setVisibleOnAllWorkspaces(true); } if (process.platform !== 'darwin') { /** - * Toggle the Fether menu bar in the frame on Windows. Note that - * if not shown by default then when it is shown it causes cropping of the bottom - * of the window when menu open/close toggled. The user will need to be informed - * that pressing ALT displays the Fether menu + * Toggle the Fether menu bar in the frame on Windows or Linux. + * If not shown by default then when shown it crops the bottom + * of the window when menu open/close toggled. */ - fetherApp.window.setAutoHideMenuBar(true); // ALT shows menu bar - fetherApp.window.setMenuBarVisibility(false); + fetherApp.win.setAutoHideMenuBar(true); // Pressing ALT shows menu bar + fetherApp.win.setMenuBarVisibility(false); } // Opens file:///path/to/build/index.html in prod mode, or whatever is // passed to ELECTRON_START_URL - fetherApp.window.loadURL(options.index); + fetherApp.win.loadURL(options.index); fetherApp.emit('after-create-window'); } diff --git a/packages/fether-electron/src/main/app/methods/fixWindowPosition.js b/packages/fether-electron/src/main/app/methods/fixWindowPosition.js index 306085818..37a6086fd 100644 --- a/packages/fether-electron/src/main/app/methods/fixWindowPosition.js +++ b/packages/fether-electron/src/main/app/methods/fixWindowPosition.js @@ -11,22 +11,17 @@ * coordinates of the window are outside the screen bounds the window * will be restored into the users primary screen. */ -function fixWindowPosition (fetherApp, proposedWindowPosition) { - const { trayDepth } = fetherApp; +function fixWinPosition (fetherApp, proposedWindowPosition) { + const { trayDepth, win } = fetherApp; if (!proposedWindowPosition) { return; } - const newPosition = { - x: undefined, - y: undefined - }; - - const currentScreenResolution = fetherApp.getScreenResolution(); - - const windowWidth = fetherApp.window.getSize()[0]; - const windowHeight = fetherApp.window.getSize()[1]; + const newPosition = { x: undefined, y: undefined }; + const resolution = fetherApp.getScreenResolution(); + const winWidth = win.getSize()[0]; + const winHeight = win.getSize()[1]; if (proposedWindowPosition.x < trayDepth) { newPosition.x = trayDepth; @@ -36,21 +31,15 @@ function fixWindowPosition (fetherApp, proposedWindowPosition) { newPosition.y = trayDepth; } - if ( - proposedWindowPosition.x >= - currentScreenResolution.x - windowWidth - trayDepth - ) { - newPosition.x = currentScreenResolution.x - windowWidth - trayDepth; + if (proposedWindowPosition.x >= resolution.x - winWidth - trayDepth) { + newPosition.x = resolution.x - winWidth - trayDepth; } - if ( - proposedWindowPosition.y >= - currentScreenResolution.y - windowHeight - trayDepth - ) { - newPosition.y = currentScreenResolution.y - windowHeight - trayDepth; + if (proposedWindowPosition.y >= resolution.y - winHeight - trayDepth) { + newPosition.y = resolution.y - winHeight - trayDepth; } return newPosition; } -export default fixWindowPosition; +export default fixWinPosition; diff --git a/packages/fether-electron/src/main/app/methods/getScreenResolution.js b/packages/fether-electron/src/main/app/methods/getScreenResolution.js index 50618eb87..06f74f6ed 100644 --- a/packages/fether-electron/src/main/app/methods/getScreenResolution.js +++ b/packages/fether-electron/src/main/app/methods/getScreenResolution.js @@ -8,12 +8,9 @@ import { screen } from 'electron'; // https://ourcodeworld.com/articles/read/285/how-to-get-the-screen-width-and-height-in-electron-framework function getScreenResolution () { const mainScreen = screen.getPrimaryDisplay(); - const mainScreenDimensions = mainScreen.size; + const mainScreenDims = mainScreen.size; - return { - x: mainScreenDimensions.width, - y: mainScreenDimensions.height - }; + return { x: mainScreenDims.width, y: mainScreenDims.height }; } export default getScreenResolution; diff --git a/packages/fether-electron/src/main/app/methods/hideWindow.js b/packages/fether-electron/src/main/app/methods/hideWindow.js index 2621c1ad8..7287f1b5c 100644 --- a/packages/fether-electron/src/main/app/methods/hideWindow.js +++ b/packages/fether-electron/src/main/app/methods/hideWindow.js @@ -4,14 +4,15 @@ // SPDX-License-Identifier: BSD-3-Clause function hideWindow (fetherApp) { - if (!fetherApp.window) { + const { emit, processSaveWinPosition, win } = fetherApp; + + if (!win) { return; } - fetherApp.processSaveWindowPosition(); // Save window position when hide, particularly necessary on Linux - + processSaveWinPosition(); // Save window position when hide, particularly necessary on Linux fetherApp.emit('hide-window'); - fetherApp.window.hide(); + win.hide(); fetherApp.emit('after-hide-window'); } diff --git a/packages/fether-electron/src/main/app/methods/index.js b/packages/fether-electron/src/main/app/methods/index.js index 1d7dc8c0f..7f81604a6 100644 --- a/packages/fether-electron/src/main/app/methods/index.js +++ b/packages/fether-electron/src/main/app/methods/index.js @@ -3,18 +3,18 @@ // // SPDX-License-Identifier: BSD-3-Clause -import calculateWindowPosition from './calculateWindowPosition'; +import calculateWinPosition from './calculateWinPosition'; import createPositioner from './createPositioner'; import createTray from './createTray'; import createWindow from './createWindow'; -import fixWindowPosition from './fixWindowPosition'; +import fixWinPosition from './fixWinPosition'; import getScreenResolution from './getScreenResolution'; import hideWindow from './hideWindow'; import loadTray from './loadTray'; import moveWindowUp from './moveWindowUp'; import onTrayClick from './onTrayClick'; import onWindowClose from './onWindowClose'; -import processSaveWindowPosition from './processSaveWindowPosition'; +import processSaveWinPosition from './processSaveWinPosition'; import setupAppListeners from './setupAppListeners'; import setupDebug from './setupDebug'; import setupGlobals from './setupGlobals'; @@ -23,7 +23,7 @@ import setupMenu from './setupMenu'; import setupParityEthereum from './setupParityEthereum'; import setupRequestListeners from './setupRequestListeners'; import setupSecurity from './setupSecurity'; -import setupWindowListeners from './setupWindowListeners'; +import setupWinListeners from './setupWinListeners'; import setupWin32Listeners from './setupWin32Listeners'; import showTrayBalloon from './showTrayBalloon'; import showWindow from './showWindow'; @@ -31,18 +31,18 @@ import updateProgress from './updateProgress'; import windowClear from './windowClear'; export { - calculateWindowPosition, + calculateWinPosition, createPositioner, createTray, createWindow, - fixWindowPosition, + fixWinPosition, getScreenResolution, hideWindow, loadTray, moveWindowUp, onTrayClick, onWindowClose, - processSaveWindowPosition, + processSaveWinPosition, setupAppListeners, setupDebug, setupGlobals, @@ -51,7 +51,7 @@ export { setupRequestListeners, setupParityEthereum, setupSecurity, - setupWindowListeners, + setupWinListeners, setupWin32Listeners, showTrayBalloon, showWindow, diff --git a/packages/fether-electron/src/main/app/methods/loadTray.js b/packages/fether-electron/src/main/app/methods/loadTray.js index 4cbcf09c5..0e38ffaea 100644 --- a/packages/fether-electron/src/main/app/methods/loadTray.js +++ b/packages/fether-electron/src/main/app/methods/loadTray.js @@ -8,7 +8,7 @@ import Pino from '../utils/pino'; const pino = Pino(); function loadTray (fetherApp) { - const { app, options, tray } = fetherApp; + const { app, onTrayClick, options, showTrayBalloon, tray } = fetherApp; if (options.withTaskbar) { fetherApp.emit('load-tray'); @@ -23,16 +23,16 @@ function loadTray (fetherApp) { // Note: See https://github.com/RocketChat/Rocket.Chat.Electron/issues/44 if (process.platform === 'win32') { - fetherApp.showTrayBalloon(); + showTrayBalloon(); } - tray.on(defaultClickEvent, () => fetherApp.onTrayClick(fetherApp)); - tray.on('double-click', () => fetherApp.onTrayClick(fetherApp)); + tray.on(defaultClickEvent, () => onTrayClick(fetherApp)); + tray.on('double-click', () => onTrayClick(fetherApp)); // Right click event handler does not work on Windows as intended tray.on('right-click', () => { if (process.platform === 'win32') { pino.info('Detected right click on Windows'); - fetherApp.showTrayBalloon(); + showTrayBalloon(); } }); tray.setToolTip(options.tooltip); diff --git a/packages/fether-electron/src/main/app/methods/moveWindowUp.js b/packages/fether-electron/src/main/app/methods/moveWindowUp.js index e47087e80..f05b21c0b 100644 --- a/packages/fether-electron/src/main/app/methods/moveWindowUp.js +++ b/packages/fether-electron/src/main/app/methods/moveWindowUp.js @@ -16,26 +16,24 @@ const pino = Pino(); * automatically move the window upward so it is viewable to the user */ function moveWindowUp (fetherApp) { - if (!fetherApp.window) { + const { emit, getScreenResolution, win } = fetherApp; + + if (!win) { return; } pino.info('Fether window resized. Moving it back up into view if required'); - - const position = fetherApp.window.getPosition(); - const positionStruct = { - x: position[0], - y: position[1] - }; + const position = win.getPosition(); + const positionStruct = { x: position[0], y: position[1] }; const trayDepth = fetherApp.trayDepth || 40; // Default incase resizes on load - const currentScreenResolution = fetherApp.getScreenResolution(); - const windowHeight = fetherApp.window.getSize()[1]; - const maxWindowY = currentScreenResolution.y - windowHeight - trayDepth; - const adjustY = positionStruct.y - maxWindowY; + const resolution = getScreenResolution(); + const winHeight = win.getSize()[1]; + const maxWinY = resolution.y - winHeight - trayDepth; + const adjustY = positionStruct.y - maxWinY; if (adjustY > 0) { fetherApp.emit('moved-window-up-into-view'); - fetherApp.window.setPosition(positionStruct.x, maxWindowY); + win.setPosition(positionStruct.x, maxWinY); } } diff --git a/packages/fether-electron/src/main/app/methods/onTrayClick.js b/packages/fether-electron/src/main/app/methods/onTrayClick.js index 06d2aa93a..a7df100e1 100644 --- a/packages/fether-electron/src/main/app/methods/onTrayClick.js +++ b/packages/fether-electron/src/main/app/methods/onTrayClick.js @@ -4,21 +4,17 @@ // SPDX-License-Identifier: BSD-3-Clause function onTrayClick (fetherApp, e, bounds) { - const { cachedBounds } = fetherApp; + const { cachedBounds, hideWindow, win } = fetherApp; + const { altKey, ctrlKey, metaKey, shiftKey } = e; - if ( - e.altKey || - e.shiftKey || - e.ctrlKey || - e.metaKey || - (fetherApp.window && fetherApp.window.isVisible()) - ) { - return fetherApp.hideWindow(); + if (altKey || shiftKey || ctrlKey || metaKey || (win && win.isVisible())) { + return hideWindow(); } // cachedBounds are needed for double-clicked event - fetherApp.cachedBounds = bounds || cachedBounds; - fetherApp.showWindow(fetherApp.cachedBounds); + const newCacheBounds = bounds || cachedBounds; + fetherApp.cachedBounds = newCacheBounds; + fetherApp.showWindow(newCacheBounds); } export default onTrayClick; diff --git a/packages/fether-electron/src/main/app/methods/onWindowClose.js b/packages/fether-electron/src/main/app/methods/onWindowClose.js index 939463bd2..d1c258e13 100644 --- a/packages/fether-electron/src/main/app/methods/onWindowClose.js +++ b/packages/fether-electron/src/main/app/methods/onWindowClose.js @@ -4,8 +4,10 @@ // SPDX-License-Identifier: BSD-3-Clause function onWindowClose (fetherApp) { - fetherApp.processSaveWindowPosition(); - fetherApp.windowClear(); + const { processSaveWinPosition, windowClear } = fetherApp; + + processSaveWinPosition(); + windowClear(); } export default onWindowClose; diff --git a/packages/fether-electron/src/main/app/methods/processSaveWindowPosition.js b/packages/fether-electron/src/main/app/methods/processSaveWindowPosition.js index 9e6f741d4..3d93460b7 100644 --- a/packages/fether-electron/src/main/app/methods/processSaveWindowPosition.js +++ b/packages/fether-electron/src/main/app/methods/processSaveWindowPosition.js @@ -9,69 +9,60 @@ import { } from '../utils/window'; import { saveWindowPosition } from '../settings'; -function processSaveWindowPosition (fetherApp) { - if (!fetherApp.window) { +function processSaveWinPosition (fetherApp) { + const { + emit, + fixWinPosition, + getScreenResolution, + previousScreenResolution, + win + } = fetherApp; + + if (!win) { return; } - const currentScreenResolution = fetherApp.getScreenResolution(); + const resolution = getScreenResolution(); fetherApp.previousScreenResolution = getChangedScreenResolution( - fetherApp.previousScreenResolution, - currentScreenResolution + previousScreenResolution, + resolution ); // Get the latest position. The window may have been moved to a different // screen with smaller resolution. We must move it to prevent cropping. - const position = fetherApp.window.getPosition(); + const position = win.getPosition(); - const positionStruct = { - x: position[0], - y: position[1] - }; + const positionStruct = { x: position[0], y: position[1] }; - const fixedWindowPosition = fetherApp.fixWindowPosition(positionStruct); + const fixedWinPosition = fixWinPosition(positionStruct); const newFixedPosition = { - x: fixedWindowPosition.x || positionStruct.x, - y: fixedWindowPosition.y || positionStruct.y + x: fixedWinPosition.x || positionStruct.x, + y: fixedWinPosition.y || positionStruct.y }; /** * Only move it immediately back into the threshold of screen tray bounds - * if the screen resolution reduced to prevent it from being cropped. + * to prevent it from being cropped if the screen resolution is reduced. * Do not call this all the time otherwise it will crash with * a call stack exceeded if the user keeps trying to move it outside the screen bounds * and it would also prevent the user from moving it to a different screen at all. */ - if ( - shouldFixWindowPosition( - fetherApp.previousScreenResolution, - currentScreenResolution - ) - ) { + if (shouldFixWindowPosition(previousScreenResolution, resolution)) { // Move window to the fixed x-coordinate position if that required fixing - if (fixedWindowPosition.x) { - fetherApp.window.setPosition( - fixedWindowPosition.x, - positionStruct.y, - true - ); + if (fixedWinPosition.x) { + win.setPosition(fixedWinPosition.x, positionStruct.y, true); } // Move window to the fixed y-coordinate position if that required fixing - if (fixedWindowPosition.y) { - fetherApp.window.setPosition( - positionStruct.x, - fixedWindowPosition.y, - true - ); + if (fixedWinPosition.y) { + win.setPosition(positionStruct.x, fixedWinPosition.y, true); } } saveWindowPosition(newFixedPosition || positionStruct); - fetherApp.emit('after-moved-window-position-saved'); } -export default processSaveWindowPosition; +export default processSaveWinPosition; diff --git a/packages/fether-electron/src/main/app/methods/setupAppListeners.js b/packages/fether-electron/src/main/app/methods/setupAppListeners.js index c48f3ed0f..cc67bfed7 100644 --- a/packages/fether-electron/src/main/app/methods/setupAppListeners.js +++ b/packages/fether-electron/src/main/app/methods/setupAppListeners.js @@ -55,11 +55,9 @@ function setupAppListeners (fetherApp) { }); fetherApp.on('after-moved-window-position-saved', () => { - const position = getSavedWindowPosition(); + const pos = getSavedWindowPosition(); - pino.info( - `Saved window position to (x: ${position.x}, y: ${position.y}) after move` - ); + pino.info(`Saved window position after move (x: ${pos.x}, y: ${pos.y})`); }); fetherApp.on('moved-window-up-into-view', () => { diff --git a/packages/fether-electron/src/main/app/methods/setupDebug.js b/packages/fether-electron/src/main/app/methods/setupDebug.js index eee4a4b54..a7577278e 100644 --- a/packages/fether-electron/src/main/app/methods/setupDebug.js +++ b/packages/fether-electron/src/main/app/methods/setupDebug.js @@ -6,9 +6,10 @@ const withDebug = process.env.DEBUG === 'true'; function setupDebug (fetherApp) { + const { options, win } = fetherApp; // Enable with `DEBUG=true yarn start` and access Developer Tools - if (withDebug && fetherApp.options.webPreferences.devTools) { - fetherApp.window.webContents.openDevTools(); + if (withDebug && options.webPreferences.devTools) { + win.webContents.openDevTools(); } } diff --git a/packages/fether-electron/src/main/app/methods/setupMenu.js b/packages/fether-electron/src/main/app/methods/setupMenu.js index 6f2565ebd..f7675d297 100644 --- a/packages/fether-electron/src/main/app/methods/setupMenu.js +++ b/packages/fether-electron/src/main/app/methods/setupMenu.js @@ -9,8 +9,9 @@ import Pino from '../utils/pino'; const pino = Pino(); function setupMenu (fetherApp) { - // Add application menu - addMenu(fetherApp.window); + // Add Fether menu + addMenu(fetherApp.win); + pino.info('Finished configuring Electron menu'); } diff --git a/packages/fether-electron/src/main/app/methods/setupParityEthereum.js b/packages/fether-electron/src/main/app/methods/setupParityEthereum.js index 2c1d0330d..1c413455b 100644 --- a/packages/fether-electron/src/main/app/methods/setupParityEthereum.js +++ b/packages/fether-electron/src/main/app/methods/setupParityEthereum.js @@ -8,7 +8,7 @@ import ParityEthereum from '../parityEthereum'; function setupParityEthereum (fetherApp) { // Download, install, and run Parity Ethereum if not running and requested const parityEthereumInstance = new ParityEthereum(); - parityEthereumInstance.setup(fetherApp.window); + parityEthereumInstance.setup(fetherApp.win); } export default setupParityEthereum; diff --git a/packages/fether-electron/src/main/app/methods/setupRequestListeners.js b/packages/fether-electron/src/main/app/methods/setupRequestListeners.js index 108e8c3e0..1baa1509f 100644 --- a/packages/fether-electron/src/main/app/methods/setupRequestListeners.js +++ b/packages/fether-electron/src/main/app/methods/setupRequestListeners.js @@ -9,9 +9,11 @@ import messages from '../messages'; const { ipcMain, session } = electron; function setupRequestListeners (fetherApp) { + const { win } = fetherApp; + // Listen to messages from renderer process ipcMain.on('asynchronous-message', (...args) => { - return messages(fetherApp.window, ...args); + return messages(win, ...args); }); // WS calls have Origin `file://` by default, which is not trusted. @@ -21,14 +23,12 @@ function setupRequestListeners (fetherApp) { urls: ['ws://*/*', 'wss://*/*'] }, (details, callback) => { - if (!fetherApp.window) { + if (!win) { // There might be a split second where the user closes the app, so // this.fether.window is null, but there is still a network request done. return; } - details.requestHeaders.Origin = `parity://${ - fetherApp.window.id - }.ui.parity`; + details.requestHeaders.Origin = `parity://${win.id}.ui.parity`; callback({ requestHeaders: details.requestHeaders }); // eslint-disable-line } ); diff --git a/packages/fether-electron/src/main/app/methods/setupSecurity.js b/packages/fether-electron/src/main/app/methods/setupSecurity.js index 9a71309c6..9a170b0d6 100644 --- a/packages/fether-electron/src/main/app/methods/setupSecurity.js +++ b/packages/fether-electron/src/main/app/methods/setupSecurity.js @@ -5,7 +5,7 @@ function setupSecurity (fetherApp) { // Security to prevent window contents from being captured by other apps - fetherApp.window.setContentProtection(true); + fetherApp.win.setContentProtection(true); } export default setupSecurity; diff --git a/packages/fether-electron/src/main/app/methods/setupWin32Listeners.js b/packages/fether-electron/src/main/app/methods/setupWin32Listeners.js index 032d6795c..f4a1e7cc0 100644 --- a/packages/fether-electron/src/main/app/methods/setupWin32Listeners.js +++ b/packages/fether-electron/src/main/app/methods/setupWin32Listeners.js @@ -8,90 +8,86 @@ import Pino from '../utils/pino'; const pino = Pino(); function setupWin32Listeners (fetherApp) { + const { + moveWindowUp, + onWindowClose, + processSaveWinPosition, + showTrayBalloon, + win + } = fetherApp; + if (process.platform === 'win32') { /** * Hook WM_SYSKEYUP * * Open the Fether Electron menu when the Fether window is active - * and the user enters a keyboard combination of both the ALT and 'm' keys - * + * and the user enters a keyboard ALT key or both ALT and another key together. * Reference: https://docs.microsoft.com/en-gb/windows/desktop/inputdev/wm-syskeyup */ - fetherApp.window.hookWindowMessage( - Number.parseInt('0x0105'), - (wParam, lParam) => { - // Reference: https://nodejs.org/api/buffer.html - /** - * Detect when user presses ALT+keyCode. - * i.e. Use `wParam && wParam.readUInt32LE(0) === 77` to detect ALT+m - */ - if (wParam) { - fetherApp.showTrayBalloon(); - } + win.hookWindowMessage(Number.parseInt('0x0105'), (wParam, lParam) => { + /** + * Detect when user presses ALT+keyCode. + * i.e. Use `wParam && wParam.readUInt32LE(0) === 77` to detect ALT+m. + * Reference: https://nodejs.org/api/buffer.html + */ + if (wParam) { + showTrayBalloon(); } - ); + }); /** * Hook WM_SYSCOMMAND * * Detect events on Windows - * * Credit: http://robmayhew.com/listening-for-events-from-windows-in-electron-tutorial/ */ - fetherApp.window.hookWindowMessage( - Number.parseInt('0x0112'), - (wParam, lParam) => { - let eventName = null; + win.hookWindowMessage(Number.parseInt('0x0112'), (wParam, lParam) => { + let eventName = null; - if (wParam.readUInt32LE(0) === 0xf060) { - // SC_CLOSE - eventName = 'close'; - fetherApp.onWindowClose(); - } else if (wParam.readUInt32LE(0) === 0xf030) { - // SC_MAXIMIZE - eventName = 'maximize'; - fetherApp.showTrayBalloon(); - } else if (wParam.readUInt32LE(0) === 0xf020) { - // SC_MINIMIZE - eventName = 'minimize'; - fetherApp.processSaveWindowPosition(); - } else if (wParam.readUInt32LE(0) === 0xf120) { - // SC_RESTORE - eventName = 'restored'; - fetherApp.showTrayBalloon(); - } + if (wParam.readUInt32LE(0) === 0xf060) { + // SC_CLOSE + eventName = 'close'; + onWindowClose(); + } else if (wParam.readUInt32LE(0) === 0xf030) { + // SC_MAXIMIZE + eventName = 'maximize'; + showTrayBalloon(); + } else if (wParam.readUInt32LE(0) === 0xf020) { + // SC_MINIMIZE + eventName = 'minimize'; + processSaveWinPosition(); + } else if (wParam.readUInt32LE(0) === 0xf120) { + // SC_RESTORE + eventName = 'restored'; + showTrayBalloon(); + } - if (eventName !== null) { - pino.info('Detected event:', eventName); - } + if (eventName !== null) { + pino.info('Detected event:', eventName); } - ); + }); /** * Hook WM_EXITSIZEMOVE * - * Detect event on Windows when Fether window was moved - * or resized + * Detect event on Windows when Fether window was moved or resized */ - fetherApp.window.hookWindowMessage( - Number.parseInt('0x0232'), - (wParam, lParam) => { - pino.info('Detected completion of move or resize event'); + win.hookWindowMessage(Number.parseInt('0x0232'), (wParam, lParam) => { + pino.info('Detected completion of move or resize event'); - // Move Fether window back up into view if it was a resize event - // that causes the bottom to be cropped - fetherApp.moveWindowUp(); + // Move Fether window back up into view if it was a resize event + // that causes the bottom to be cropped + moveWindowUp(); - // Try again after a delay incase Fether window resize occurs - // x seconds after navigating to a new page. - setTimeout(() => { - fetherApp.moveWindowUp(); - }, 5000); + // Try again after a delay incase Fether window resize occurs + // x seconds after navigating to a new page. + setTimeout(() => { + moveWindowUp(); + }, 5000); - // Save Fether window position to Electron settings - fetherApp.processSaveWindowPosition(); - } - ); + // Save Fether window position to Electron settings + processSaveWinPosition(); + }); } } diff --git a/packages/fether-electron/src/main/app/methods/setupWindowListeners.js b/packages/fether-electron/src/main/app/methods/setupWindowListeners.js index d99024f7a..a2e172a00 100644 --- a/packages/fether-electron/src/main/app/methods/setupWindowListeners.js +++ b/packages/fether-electron/src/main/app/methods/setupWindowListeners.js @@ -10,26 +10,36 @@ import Pino from '../utils/pino'; const pino = Pino(); -function setupWindowListeners (fetherApp) { +function setupWinListeners (fetherApp) { + const { + emit, + hideWindow, + moveWindowUp, + onWindowClose, + options, + processSaveWinPosition, + win + } = fetherApp; + // Open external links in browser - fetherApp.window.webContents.on('new-window', (event, url) => { + win.webContents.on('new-window', (event, url) => { event.preventDefault(); electron.shell.openExternal(url); }); // Linux (unchecked on others) - fetherApp.window.on('move', () => { + win.on('move', () => { /** * On Linux using this with debouncing is the closest equivalent * to using 'moved' (not supported on Linux) with debouncing */ debounce(() => { - fetherApp.processSaveWindowPosition(); + processSaveWinPosition(); }, 1000); }); // macOS (not Windows or Linux) - fetherApp.window.on('moved', () => { + win.on('moved', () => { /** * On macOS save the position in the 'moved' event since if * we run it just in 'close' instead, then if the Fether app @@ -42,33 +52,32 @@ function setupWindowListeners (fetherApp) { * On Linux the closest equivalent to achieving 'moved' is debouncing * on the 'move' event. It also works in 'close' even when app crashes */ - fetherApp.processSaveWindowPosition(); + processSaveWinPosition(); }); // macOS and Linux (not Windows) - fetherApp.window.on('resize', () => { + win.on('resize', () => { pino.info('Detected resize event'); - fetherApp.moveWindowUp(); + + moveWindowUp(); setTimeout(() => { - fetherApp.moveWindowUp(); + moveWindowUp(); }, 5000); }); - fetherApp.window.on('blur', () => { - fetherApp.options.alwaysOnTop - ? fetherApp.emit('blur-window') - : fetherApp.hideWindow(); + win.on('blur', () => { + options.alwaysOnTop ? fetherApp.emit('blur-window') : hideWindow(); }); - fetherApp.window.on('close', () => { - fetherApp.onWindowClose(); + win.on('close', () => { + onWindowClose(); }); - fetherApp.window.on('closed', () => { - fetherApp.window = null; + win.on('closed', () => { + fetherApp.win = null; fetherApp.emit('after-closed-window'); }); } -export default setupWindowListeners; +export default setupWinListeners; diff --git a/packages/fether-electron/src/main/app/methods/showWindow.js b/packages/fether-electron/src/main/app/methods/showWindow.js index 5aad47ef4..4e719af7f 100644 --- a/packages/fether-electron/src/main/app/methods/showWindow.js +++ b/packages/fether-electron/src/main/app/methods/showWindow.js @@ -12,25 +12,33 @@ import Pino from '../utils/pino'; const pino = Pino(); function showWindow (fetherApp, trayPos) { - if (!fetherApp.window) { - fetherApp.createWindow(); + const { + calculateWinPosition, + createWindow, + emit, + fixWinPosition, + win + } = fetherApp; + + if (!win) { + createWindow(); } fetherApp.emit('show-window'); - const calculatedWindowPosition = fetherApp.calculateWindowPosition(trayPos); + const calculatedWinPosition = calculateWinPosition(trayPos); - pino.info('Calculated window position: ', calculatedWindowPosition); + pino.info('Calculated window position: ', calculatedWinPosition); const mainScreen = screen.getPrimaryDisplay(); // const allScreens = screen.getAllDisplays(); - const mainScreenDimensions = mainScreen.size; + const mainScreenDims = mainScreen.size; const mainScreenWorkAreaSize = mainScreen.workAreaSize; // workAreaSize does not include the tray depth fetherApp.trayDepth = Math.max( - mainScreenDimensions.width - mainScreenWorkAreaSize.width, - mainScreenDimensions.height - mainScreenWorkAreaSize.height + mainScreenDims.width - mainScreenWorkAreaSize.width, + mainScreenDims.height - mainScreenWorkAreaSize.height ); pino.info( @@ -44,9 +52,9 @@ function showWindow (fetherApp, trayPos) { pino.info('Loaded window position: ', loadedWindowPosition); - const fixedWindowPosition = fetherApp.fixWindowPosition(loadedWindowPosition); + const fixedWinPosition = fixWinPosition(loadedWindowPosition); - pino.info('Fixed window position: ', fixedWindowPosition); + pino.info('Fixed window position: ', fixedWinPosition); /** * Since the user may change the tray to be on any side of the screen. @@ -54,17 +62,17 @@ function showWindow (fetherApp, trayPos) { * Restore the window so it is fully visible adjacent to where the tray would be. */ const x = - (fixedWindowPosition && fixedWindowPosition.x) || + (fixedWinPosition && fixedWinPosition.x) || (loadedWindowPosition && loadedWindowPosition.x) || - calculatedWindowPosition.x; + calculatedWinPosition.x; const y = - (fixedWindowPosition && fixedWindowPosition.y) || + (fixedWinPosition && fixedWinPosition.y) || (loadedWindowPosition && loadedWindowPosition.y) || - calculatedWindowPosition.y; + calculatedWinPosition.y; - fetherApp.window.setPosition(x, y); - fetherApp.window.show(); + win.setPosition(x, y); + win.show(); fetherApp.emit('after-show-window'); } diff --git a/packages/fether-electron/src/main/app/methods/updateProgress.js b/packages/fether-electron/src/main/app/methods/updateProgress.js index c143a5952..9a6c60c32 100644 --- a/packages/fether-electron/src/main/app/methods/updateProgress.js +++ b/packages/fether-electron/src/main/app/methods/updateProgress.js @@ -7,8 +7,10 @@ // (i.e. 0.1 is 10%, 1.0 is 100%, -1 hides progress bar). // Optionally emit event function updateProgress (fetherApp, percentage, eventListenerName) { + const { emit, win } = fetherApp; + if (percentage) { - fetherApp.window.setProgressBar(percentage); + win.setProgressBar(percentage); } if (eventListenerName) { diff --git a/packages/fether-electron/src/main/app/methods/windowClear.js b/packages/fether-electron/src/main/app/methods/windowClear.js index d1b2702cc..684e40e1d 100644 --- a/packages/fether-electron/src/main/app/methods/windowClear.js +++ b/packages/fether-electron/src/main/app/methods/windowClear.js @@ -4,13 +4,15 @@ // SPDX-License-Identifier: BSD-3-Clause function windowClear (fetherApp) { - if (fetherApp.window) { + const { emit, win } = fetherApp; + + if (win) { // Remove relevant events when window object deleted const events = ['close', 'move', 'moved', 'resize']; for (let event in events) { - fetherApp.window.removeAllListeners(event); + win.removeAllListeners(event); } - delete fetherApp.window; + delete fetherApp.win; } fetherApp.emit('after-close-window'); From 6c06a36d0c5acfa9302f5ed0f26fee3a7a7074ad Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Tue, 5 Feb 2019 20:41:26 +1100 Subject: [PATCH 132/153] fix: Fix linting errors --- .../fether-electron/src/main/app/methods/hideWindow.js | 2 +- .../fether-electron/src/main/app/methods/moveWindowUp.js | 2 +- .../src/main/app/methods/processSaveWindowPosition.js | 1 - .../src/main/app/methods/setupWindowListeners.js | 1 - .../fether-electron/src/main/app/methods/showWindow.js | 8 +------- .../src/main/app/methods/updateProgress.js | 2 +- .../fether-electron/src/main/app/methods/windowClear.js | 2 +- 7 files changed, 5 insertions(+), 13 deletions(-) diff --git a/packages/fether-electron/src/main/app/methods/hideWindow.js b/packages/fether-electron/src/main/app/methods/hideWindow.js index 7287f1b5c..7bb3d94f1 100644 --- a/packages/fether-electron/src/main/app/methods/hideWindow.js +++ b/packages/fether-electron/src/main/app/methods/hideWindow.js @@ -4,7 +4,7 @@ // SPDX-License-Identifier: BSD-3-Clause function hideWindow (fetherApp) { - const { emit, processSaveWinPosition, win } = fetherApp; + const { processSaveWinPosition, win } = fetherApp; if (!win) { return; diff --git a/packages/fether-electron/src/main/app/methods/moveWindowUp.js b/packages/fether-electron/src/main/app/methods/moveWindowUp.js index f05b21c0b..89a7ab5e5 100644 --- a/packages/fether-electron/src/main/app/methods/moveWindowUp.js +++ b/packages/fether-electron/src/main/app/methods/moveWindowUp.js @@ -16,7 +16,7 @@ const pino = Pino(); * automatically move the window upward so it is viewable to the user */ function moveWindowUp (fetherApp) { - const { emit, getScreenResolution, win } = fetherApp; + const { getScreenResolution, win } = fetherApp; if (!win) { return; diff --git a/packages/fether-electron/src/main/app/methods/processSaveWindowPosition.js b/packages/fether-electron/src/main/app/methods/processSaveWindowPosition.js index 3d93460b7..567f3b7ae 100644 --- a/packages/fether-electron/src/main/app/methods/processSaveWindowPosition.js +++ b/packages/fether-electron/src/main/app/methods/processSaveWindowPosition.js @@ -11,7 +11,6 @@ import { saveWindowPosition } from '../settings'; function processSaveWinPosition (fetherApp) { const { - emit, fixWinPosition, getScreenResolution, previousScreenResolution, diff --git a/packages/fether-electron/src/main/app/methods/setupWindowListeners.js b/packages/fether-electron/src/main/app/methods/setupWindowListeners.js index a2e172a00..bfad109da 100644 --- a/packages/fether-electron/src/main/app/methods/setupWindowListeners.js +++ b/packages/fether-electron/src/main/app/methods/setupWindowListeners.js @@ -12,7 +12,6 @@ const pino = Pino(); function setupWinListeners (fetherApp) { const { - emit, hideWindow, moveWindowUp, onWindowClose, diff --git a/packages/fether-electron/src/main/app/methods/showWindow.js b/packages/fether-electron/src/main/app/methods/showWindow.js index 4e719af7f..f432833b9 100644 --- a/packages/fether-electron/src/main/app/methods/showWindow.js +++ b/packages/fether-electron/src/main/app/methods/showWindow.js @@ -12,13 +12,7 @@ import Pino from '../utils/pino'; const pino = Pino(); function showWindow (fetherApp, trayPos) { - const { - calculateWinPosition, - createWindow, - emit, - fixWinPosition, - win - } = fetherApp; + const { calculateWinPosition, createWindow, fixWinPosition, win } = fetherApp; if (!win) { createWindow(); diff --git a/packages/fether-electron/src/main/app/methods/updateProgress.js b/packages/fether-electron/src/main/app/methods/updateProgress.js index 9a6c60c32..eeb11fa22 100644 --- a/packages/fether-electron/src/main/app/methods/updateProgress.js +++ b/packages/fether-electron/src/main/app/methods/updateProgress.js @@ -7,7 +7,7 @@ // (i.e. 0.1 is 10%, 1.0 is 100%, -1 hides progress bar). // Optionally emit event function updateProgress (fetherApp, percentage, eventListenerName) { - const { emit, win } = fetherApp; + const { win } = fetherApp; if (percentage) { win.setProgressBar(percentage); diff --git a/packages/fether-electron/src/main/app/methods/windowClear.js b/packages/fether-electron/src/main/app/methods/windowClear.js index 684e40e1d..9d65ed25c 100644 --- a/packages/fether-electron/src/main/app/methods/windowClear.js +++ b/packages/fether-electron/src/main/app/methods/windowClear.js @@ -4,7 +4,7 @@ // SPDX-License-Identifier: BSD-3-Clause function windowClear (fetherApp) { - const { emit, win } = fetherApp; + const { win } = fetherApp; if (win) { // Remove relevant events when window object deleted From 18c953657f6213ebc1079f0b5da53ec45958ab9a Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Tue, 5 Feb 2019 20:47:54 +1100 Subject: [PATCH 133/153] refactor: Rename files to match function names --- .../{calculateWindowPosition.js => calculateWinPosition.js} | 0 .../main/app/methods/{fixWindowPosition.js => fixWinPosition.js} | 0 .../{processSaveWindowPosition.js => processSaveWinPosition.js} | 0 .../app/methods/{setupWindowListeners.js => setupWinListeners.js} | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename packages/fether-electron/src/main/app/methods/{calculateWindowPosition.js => calculateWinPosition.js} (100%) rename packages/fether-electron/src/main/app/methods/{fixWindowPosition.js => fixWinPosition.js} (100%) rename packages/fether-electron/src/main/app/methods/{processSaveWindowPosition.js => processSaveWinPosition.js} (100%) rename packages/fether-electron/src/main/app/methods/{setupWindowListeners.js => setupWinListeners.js} (100%) diff --git a/packages/fether-electron/src/main/app/methods/calculateWindowPosition.js b/packages/fether-electron/src/main/app/methods/calculateWinPosition.js similarity index 100% rename from packages/fether-electron/src/main/app/methods/calculateWindowPosition.js rename to packages/fether-electron/src/main/app/methods/calculateWinPosition.js diff --git a/packages/fether-electron/src/main/app/methods/fixWindowPosition.js b/packages/fether-electron/src/main/app/methods/fixWinPosition.js similarity index 100% rename from packages/fether-electron/src/main/app/methods/fixWindowPosition.js rename to packages/fether-electron/src/main/app/methods/fixWinPosition.js diff --git a/packages/fether-electron/src/main/app/methods/processSaveWindowPosition.js b/packages/fether-electron/src/main/app/methods/processSaveWinPosition.js similarity index 100% rename from packages/fether-electron/src/main/app/methods/processSaveWindowPosition.js rename to packages/fether-electron/src/main/app/methods/processSaveWinPosition.js diff --git a/packages/fether-electron/src/main/app/methods/setupWindowListeners.js b/packages/fether-electron/src/main/app/methods/setupWinListeners.js similarity index 100% rename from packages/fether-electron/src/main/app/methods/setupWindowListeners.js rename to packages/fether-electron/src/main/app/methods/setupWinListeners.js From dbf6dab13ac83a30c80ede8f1c1dfbb16f356171 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Tue, 5 Feb 2019 20:59:19 +1100 Subject: [PATCH 134/153] fix: Use constructor when creating ParityEthereum class instance --- .../src/main/app/methods/setupParityEthereum.js | 3 +-- packages/fether-electron/src/main/app/parityEthereum/index.js | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/packages/fether-electron/src/main/app/methods/setupParityEthereum.js b/packages/fether-electron/src/main/app/methods/setupParityEthereum.js index 1c413455b..8a6f9ca25 100644 --- a/packages/fether-electron/src/main/app/methods/setupParityEthereum.js +++ b/packages/fether-electron/src/main/app/methods/setupParityEthereum.js @@ -7,8 +7,7 @@ import ParityEthereum from '../parityEthereum'; function setupParityEthereum (fetherApp) { // Download, install, and run Parity Ethereum if not running and requested - const parityEthereumInstance = new ParityEthereum(); - parityEthereumInstance.setup(fetherApp.win); + return new ParityEthereum(fetherApp.win); } export default setupParityEthereum; diff --git a/packages/fether-electron/src/main/app/parityEthereum/index.js b/packages/fether-electron/src/main/app/parityEthereum/index.js index 0269c91e5..9709d3ae9 100644 --- a/packages/fether-electron/src/main/app/parityEthereum/index.js +++ b/packages/fether-electron/src/main/app/parityEthereum/index.js @@ -21,7 +21,7 @@ const pino = Pino(); let hasCalledInitParityEthereum = false; class ParityEthereum { - setup = fetherAppWindow => { + constructor (fetherAppWindow) { if (hasCalledInitParityEthereum) { throw new Error('Unable to initialise Parity Ethereum more than once'); } @@ -55,7 +55,7 @@ class ParityEthereum { global.isParityRunning = isRunning; // Send this variable to renderers via IPC }) .catch(handleError); - }; + } install = fetherAppWindow => { return fetchParity(fetherAppWindow, { From 0387a3f11dd211558b68244d82d8ae0f04f160d8 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Tue, 5 Feb 2019 22:40:32 +1100 Subject: [PATCH 135/153] fix: Must pass context of fetherApp as argument to different methods --- packages/fether-electron/src/main/app/index.js | 2 +- .../src/main/app/methods/hideWindow.js | 2 +- .../src/main/app/methods/loadTray.js | 4 ++-- .../src/main/app/methods/onTrayClick.js | 4 ++-- .../src/main/app/methods/onWindowClose.js | 4 ++-- .../main/app/methods/processSaveWinPosition.js | 2 +- .../src/main/app/methods/setupWin32Listeners.js | 16 ++++++++-------- .../src/main/app/methods/setupWinListeners.js | 12 ++++++------ .../src/main/app/methods/showWindow.js | 6 +++--- 9 files changed, 26 insertions(+), 26 deletions(-) diff --git a/packages/fether-electron/src/main/app/index.js b/packages/fether-electron/src/main/app/index.js index 67f9f9923..26f970b9d 100644 --- a/packages/fether-electron/src/main/app/index.js +++ b/packages/fether-electron/src/main/app/index.js @@ -84,7 +84,7 @@ class FetherApp extends EventEmitter { loadTray = () => loadTray(this); moveWindowUp = () => moveWindowUp(this); onTrayClick = (e, bounds) => onTrayClick(this, e, bounds); - onWindowClose = () => onWindowClose(); + onWindowClose = () => onWindowClose(this); processSaveWinPosition = () => processSaveWinPosition(this); setupAppListeners = () => setupAppListeners(this); setupDebug = () => setupDebug(this); diff --git a/packages/fether-electron/src/main/app/methods/hideWindow.js b/packages/fether-electron/src/main/app/methods/hideWindow.js index 7bb3d94f1..9c8514026 100644 --- a/packages/fether-electron/src/main/app/methods/hideWindow.js +++ b/packages/fether-electron/src/main/app/methods/hideWindow.js @@ -10,7 +10,7 @@ function hideWindow (fetherApp) { return; } - processSaveWinPosition(); // Save window position when hide, particularly necessary on Linux + processSaveWinPosition(fetherApp); // Save window position when hide, particularly necessary on Linux fetherApp.emit('hide-window'); win.hide(); fetherApp.emit('after-hide-window'); diff --git a/packages/fether-electron/src/main/app/methods/loadTray.js b/packages/fether-electron/src/main/app/methods/loadTray.js index 0e38ffaea..68bde2ec6 100644 --- a/packages/fether-electron/src/main/app/methods/loadTray.js +++ b/packages/fether-electron/src/main/app/methods/loadTray.js @@ -23,7 +23,7 @@ function loadTray (fetherApp) { // Note: See https://github.com/RocketChat/Rocket.Chat.Electron/issues/44 if (process.platform === 'win32') { - showTrayBalloon(); + showTrayBalloon(fetherApp); } tray.on(defaultClickEvent, () => onTrayClick(fetherApp)); @@ -32,7 +32,7 @@ function loadTray (fetherApp) { tray.on('right-click', () => { if (process.platform === 'win32') { pino.info('Detected right click on Windows'); - showTrayBalloon(); + showTrayBalloon(fetherApp); } }); tray.setToolTip(options.tooltip); diff --git a/packages/fether-electron/src/main/app/methods/onTrayClick.js b/packages/fether-electron/src/main/app/methods/onTrayClick.js index a7df100e1..d7572dddf 100644 --- a/packages/fether-electron/src/main/app/methods/onTrayClick.js +++ b/packages/fether-electron/src/main/app/methods/onTrayClick.js @@ -8,13 +8,13 @@ function onTrayClick (fetherApp, e, bounds) { const { altKey, ctrlKey, metaKey, shiftKey } = e; if (altKey || shiftKey || ctrlKey || metaKey || (win && win.isVisible())) { - return hideWindow(); + return hideWindow(fetherApp); } // cachedBounds are needed for double-clicked event const newCacheBounds = bounds || cachedBounds; fetherApp.cachedBounds = newCacheBounds; - fetherApp.showWindow(newCacheBounds); + fetherApp.showWindow(fetherApp, newCacheBounds); } export default onTrayClick; diff --git a/packages/fether-electron/src/main/app/methods/onWindowClose.js b/packages/fether-electron/src/main/app/methods/onWindowClose.js index d1c258e13..02b59ab8d 100644 --- a/packages/fether-electron/src/main/app/methods/onWindowClose.js +++ b/packages/fether-electron/src/main/app/methods/onWindowClose.js @@ -6,8 +6,8 @@ function onWindowClose (fetherApp) { const { processSaveWinPosition, windowClear } = fetherApp; - processSaveWinPosition(); - windowClear(); + processSaveWinPosition(fetherApp); + windowClear(fetherApp); } export default onWindowClose; diff --git a/packages/fether-electron/src/main/app/methods/processSaveWinPosition.js b/packages/fether-electron/src/main/app/methods/processSaveWinPosition.js index 567f3b7ae..3af5662fe 100644 --- a/packages/fether-electron/src/main/app/methods/processSaveWinPosition.js +++ b/packages/fether-electron/src/main/app/methods/processSaveWinPosition.js @@ -34,7 +34,7 @@ function processSaveWinPosition (fetherApp) { const positionStruct = { x: position[0], y: position[1] }; - const fixedWinPosition = fixWinPosition(positionStruct); + const fixedWinPosition = fixWinPosition(fetherApp, positionStruct); const newFixedPosition = { x: fixedWinPosition.x || positionStruct.x, diff --git a/packages/fether-electron/src/main/app/methods/setupWin32Listeners.js b/packages/fether-electron/src/main/app/methods/setupWin32Listeners.js index f4a1e7cc0..098420700 100644 --- a/packages/fether-electron/src/main/app/methods/setupWin32Listeners.js +++ b/packages/fether-electron/src/main/app/methods/setupWin32Listeners.js @@ -31,7 +31,7 @@ function setupWin32Listeners (fetherApp) { * Reference: https://nodejs.org/api/buffer.html */ if (wParam) { - showTrayBalloon(); + showTrayBalloon(fetherApp); } }); @@ -47,19 +47,19 @@ function setupWin32Listeners (fetherApp) { if (wParam.readUInt32LE(0) === 0xf060) { // SC_CLOSE eventName = 'close'; - onWindowClose(); + onWindowClose(fetherApp); } else if (wParam.readUInt32LE(0) === 0xf030) { // SC_MAXIMIZE eventName = 'maximize'; - showTrayBalloon(); + showTrayBalloon(fetherApp); } else if (wParam.readUInt32LE(0) === 0xf020) { // SC_MINIMIZE eventName = 'minimize'; - processSaveWinPosition(); + processSaveWinPosition(fetherApp); } else if (wParam.readUInt32LE(0) === 0xf120) { // SC_RESTORE eventName = 'restored'; - showTrayBalloon(); + showTrayBalloon(fetherApp); } if (eventName !== null) { @@ -77,16 +77,16 @@ function setupWin32Listeners (fetherApp) { // Move Fether window back up into view if it was a resize event // that causes the bottom to be cropped - moveWindowUp(); + moveWindowUp(fetherApp); // Try again after a delay incase Fether window resize occurs // x seconds after navigating to a new page. setTimeout(() => { - moveWindowUp(); + moveWindowUp(fetherApp); }, 5000); // Save Fether window position to Electron settings - processSaveWinPosition(); + processSaveWinPosition(fetherApp); }); } } diff --git a/packages/fether-electron/src/main/app/methods/setupWinListeners.js b/packages/fether-electron/src/main/app/methods/setupWinListeners.js index bfad109da..0560bfa07 100644 --- a/packages/fether-electron/src/main/app/methods/setupWinListeners.js +++ b/packages/fether-electron/src/main/app/methods/setupWinListeners.js @@ -33,7 +33,7 @@ function setupWinListeners (fetherApp) { * to using 'moved' (not supported on Linux) with debouncing */ debounce(() => { - processSaveWinPosition(); + processSaveWinPosition(fetherApp); }, 1000); }); @@ -51,25 +51,25 @@ function setupWinListeners (fetherApp) { * On Linux the closest equivalent to achieving 'moved' is debouncing * on the 'move' event. It also works in 'close' even when app crashes */ - processSaveWinPosition(); + processSaveWinPosition(fetherApp); }); // macOS and Linux (not Windows) win.on('resize', () => { pino.info('Detected resize event'); - moveWindowUp(); + moveWindowUp(fetherApp); setTimeout(() => { - moveWindowUp(); + moveWindowUp(fetherApp); }, 5000); }); win.on('blur', () => { - options.alwaysOnTop ? fetherApp.emit('blur-window') : hideWindow(); + options.alwaysOnTop ? fetherApp.emit('blur-window') : hideWindow(fetherApp); }); win.on('close', () => { - onWindowClose(); + onWindowClose(fetherApp); }); win.on('closed', () => { diff --git a/packages/fether-electron/src/main/app/methods/showWindow.js b/packages/fether-electron/src/main/app/methods/showWindow.js index f432833b9..a9d248597 100644 --- a/packages/fether-electron/src/main/app/methods/showWindow.js +++ b/packages/fether-electron/src/main/app/methods/showWindow.js @@ -15,12 +15,12 @@ function showWindow (fetherApp, trayPos) { const { calculateWinPosition, createWindow, fixWinPosition, win } = fetherApp; if (!win) { - createWindow(); + createWindow(fetherApp); } fetherApp.emit('show-window'); - const calculatedWinPosition = calculateWinPosition(trayPos); + const calculatedWinPosition = calculateWinPosition(fetherApp, trayPos); pino.info('Calculated window position: ', calculatedWinPosition); @@ -46,7 +46,7 @@ function showWindow (fetherApp, trayPos) { pino.info('Loaded window position: ', loadedWindowPosition); - const fixedWinPosition = fixWinPosition(loadedWindowPosition); + const fixedWinPosition = fixWinPosition(fetherApp, loadedWindowPosition); pino.info('Fixed window position: ', fixedWinPosition); From 22d7c136f0086d1af24bdb3105dc7d328936f770 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Tue, 5 Feb 2019 23:37:39 +1100 Subject: [PATCH 136/153] review-fix: Remove commented out old event emitter line of code --- packages/fether-electron/src/main/app/index.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/fether-electron/src/main/app/index.js b/packages/fether-electron/src/main/app/index.js index 26f970b9d..906ad5d56 100644 --- a/packages/fether-electron/src/main/app/index.js +++ b/packages/fether-electron/src/main/app/index.js @@ -37,8 +37,6 @@ import { let hasCalledInitFetherApp = false; class FetherApp extends EventEmitter { - // fetherApp = new events.EventEmitter(); - constructor (electronApp, options) { super(); From dd47b9b5586c855e12f2aab52423d892ca7da3cb Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Wed, 6 Feb 2019 00:23:15 +1100 Subject: [PATCH 137/153] WIP - attempt to address review comments --- packages/fether-electron/babel.config.js | 4 ---- packages/fether-electron/package.json | 8 +------- packages/fether-react/babel.config.js | 10 ---------- packages/fether-react/package.json | 11 +---------- 4 files changed, 2 insertions(+), 31 deletions(-) delete mode 100644 packages/fether-electron/babel.config.js delete mode 100644 packages/fether-react/babel.config.js diff --git a/packages/fether-electron/babel.config.js b/packages/fether-electron/babel.config.js deleted file mode 100644 index 7238a1fe2..000000000 --- a/packages/fether-electron/babel.config.js +++ /dev/null @@ -1,4 +0,0 @@ -module.exports = { - plugins: [['@babel/plugin-proposal-class-properties', { loose: false }]], - presets: ['@babel/preset-env'] -}; diff --git a/packages/fether-electron/package.json b/packages/fether-electron/package.json index 935a560c2..64e08376e 100644 --- a/packages/fether-electron/package.json +++ b/packages/fether-electron/package.json @@ -36,7 +36,7 @@ "prerelease": "./scripts/revertElectronBug.sh", "release": "electron-builder", "start": "cross-env ELECTRON_START_URL=http://localhost:3000 electron-webpack dev --ws-origins all", - "test": "jest --all --color --coverage" + "test": "ln -sf ../../node_modules/react-scripts node_modules/ && cross-env SKIP_PREFLIGHT_CHECK=true craco test" }, "dependencies": { "@parity/electron": "^4.0.0", @@ -51,17 +51,11 @@ "source-map-support": "^0.5.10" }, "devDependencies": { - "@babel/cli": "^7.2.3", - "@babel/core": "^7.2.2", - "@babel/plugin-proposal-class-properties": "^7.3.0", - "@babel/preset-env": "^7.3.1", - "babel-jest": "^24.0.0", "copyfiles": "^2.1.0", "cross-env": "^5.2.0", "electron": "^4.0.1", "electron-builder": "^20.38.5", "electron-webpack": "^2.6.1", - "jest": "^24.0.0", "webpack": "^4.29.1" } } \ No newline at end of file diff --git a/packages/fether-react/babel.config.js b/packages/fether-react/babel.config.js deleted file mode 100644 index 6eaaa0851..000000000 --- a/packages/fether-react/babel.config.js +++ /dev/null @@ -1,10 +0,0 @@ -module.exports = { - plugins: [ - ['@babel/plugin-proposal-decorators', { legacy: true }], // should be first plugin listed - ['@babel/plugin-proposal-class-properties', { loose: true }], - ['@babel/plugin-proposal-pipeline-operator', { proposal: 'minimal' }], - '@babel/plugin-transform-modules-commonjs', - '@babel/plugin-transform-runtime' - ], - presets: ['@babel/preset-env', '@babel/preset-react'] -}; diff --git a/packages/fether-react/package.json b/packages/fether-react/package.json index 387051bbc..ed583d5ec 100644 --- a/packages/fether-react/package.json +++ b/packages/fether-react/package.json @@ -31,10 +31,9 @@ "start": "npm-run-all -p start-*", "start-css": "npm run build-css -- --watch --recursive", "start-js": "cross-env SKIP_PREFLIGHT_CHECK=true BROWSER=none craco start --react-scripts ../../node_modules/react-scripts", - "test": "jest --all --color --coverage" + "test": "ln -sf ../../node_modules/react-scripts node_modules/ && cross-env SKIP_PREFLIGHT_CHECK=true craco test" }, "dependencies": { - "@babel/runtime": "^7.3.1", "@craco/craco": "^3.3.1", "@parity/abi": "^3.0.27", "@parity/api": "^3.0.27", @@ -72,15 +71,7 @@ "rxjs": "^6.2.0" }, "devDependencies": { - "@babel/cli": "^7.2.3", - "@babel/core": "^7.2.2", - "@babel/plugin-transform-modules-commonjs": "^7.2.0", - "@babel/plugin-transform-runtime": "^7.2.0", - "@babel/plugin-proposal-pipeline-operator": "^7.3.0", "@babel/plugin-proposal-decorators": "^7.2.0", - "@babel/plugin-proposal-class-properties": "^7.3.0", - "@babel/preset-env": "^7.3.1", - "babel-jest": "^24.0.0", "capitalize": "^1.0.0", "jest": "^24.0.0", "node-sass": "^4.11.0", From 7ec18551b5d1d118b5c2c5c32ab74c3144bc5a36 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Wed, 6 Feb 2019 00:30:00 +1100 Subject: [PATCH 138/153] WIP --- packages/fether-electron/package.json | 12 ++++++------ packages/fether-react/package.json | 1 - 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/packages/fether-electron/package.json b/packages/fether-electron/package.json index 64e08376e..843340703 100644 --- a/packages/fether-electron/package.json +++ b/packages/fether-electron/package.json @@ -41,21 +41,21 @@ "dependencies": { "@parity/electron": "^4.0.0", "ansi-styles": "^3.2.1", - "commander": "^2.19.0", + "commander": "^2.15.1", "commander-remaining-args": "^1.2.0", "electron-positioner": "^4.1.0", "electron-settings": "^3.2.0", "fether-react": "^0.3.0", "pino": "^4.16.1", "pino-multi-stream": "^3.1.2", - "source-map-support": "^0.5.10" + "source-map-support": "^0.5.6" }, "devDependencies": { - "copyfiles": "^2.1.0", + "copyfiles": "^2.0.0", "cross-env": "^5.2.0", "electron": "^4.0.1", - "electron-builder": "^20.38.5", - "electron-webpack": "^2.6.1", - "webpack": "^4.29.1" + "electron-builder": "^20.29.0", + "electron-webpack": "^2.1.2", + "webpack": "^4.7.0" } } \ No newline at end of file diff --git a/packages/fether-react/package.json b/packages/fether-react/package.json index ed583d5ec..05e773b90 100644 --- a/packages/fether-react/package.json +++ b/packages/fether-react/package.json @@ -73,7 +73,6 @@ "devDependencies": { "@babel/plugin-proposal-decorators": "^7.2.0", "capitalize": "^1.0.0", - "jest": "^24.0.0", "node-sass": "^4.11.0", "node-sass-chokidar": "^1.3.4", "npm-run-all": "^4.1.2" From 2673b0c2376d6b0cc1c0f2eb840b833b3f40d2e8 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Wed, 6 Feb 2019 00:36:35 +1100 Subject: [PATCH 139/153] WIP - use craco in fether-react, and jest in fether-electron, as instructed, but tests still dont work --- packages/fether-electron/package.json | 2 +- packages/fether-react/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/fether-electron/package.json b/packages/fether-electron/package.json index 843340703..c1f2c7291 100644 --- a/packages/fether-electron/package.json +++ b/packages/fether-electron/package.json @@ -36,7 +36,7 @@ "prerelease": "./scripts/revertElectronBug.sh", "release": "electron-builder", "start": "cross-env ELECTRON_START_URL=http://localhost:3000 electron-webpack dev --ws-origins all", - "test": "ln -sf ../../node_modules/react-scripts node_modules/ && cross-env SKIP_PREFLIGHT_CHECK=true craco test" + "test": "jest --all --color --coverage" }, "dependencies": { "@parity/electron": "^4.0.0", diff --git a/packages/fether-react/package.json b/packages/fether-react/package.json index 05e773b90..3e58f5696 100644 --- a/packages/fether-react/package.json +++ b/packages/fether-react/package.json @@ -31,7 +31,7 @@ "start": "npm-run-all -p start-*", "start-css": "npm run build-css -- --watch --recursive", "start-js": "cross-env SKIP_PREFLIGHT_CHECK=true BROWSER=none craco start --react-scripts ../../node_modules/react-scripts", - "test": "ln -sf ../../node_modules/react-scripts node_modules/ && cross-env SKIP_PREFLIGHT_CHECK=true craco test" + "test": "ln -sf ../../../node_modules/react-scripts node_modules/ && cross-env SKIP_PREFLIGHT_CHECK=true craco test" }, "dependencies": { "@craco/craco": "^3.3.1", From 3aecfbaa8c797b3d873c51e2d6674509b1889ecf Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Wed, 6 Feb 2019 00:54:59 +1100 Subject: [PATCH 140/153] WIP - restore fether-electron's babel.config.js so tests pass --- packages/fether-electron/babel.config.js | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 packages/fether-electron/babel.config.js diff --git a/packages/fether-electron/babel.config.js b/packages/fether-electron/babel.config.js new file mode 100644 index 000000000..7238a1fe2 --- /dev/null +++ b/packages/fether-electron/babel.config.js @@ -0,0 +1,4 @@ +module.exports = { + plugins: [['@babel/plugin-proposal-class-properties', { loose: false }]], + presets: ['@babel/preset-env'] +}; From 688ceca8d63ee462885bfd3e08524f0eabefe7f5 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Wed, 6 Feb 2019 01:04:00 +1100 Subject: [PATCH 141/153] chore: Restore newer versions since tests still pass --- packages/fether-electron/package.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/fether-electron/package.json b/packages/fether-electron/package.json index c1f2c7291..e244f56e7 100644 --- a/packages/fether-electron/package.json +++ b/packages/fether-electron/package.json @@ -41,21 +41,21 @@ "dependencies": { "@parity/electron": "^4.0.0", "ansi-styles": "^3.2.1", - "commander": "^2.15.1", + "commander": "^2.19.0", "commander-remaining-args": "^1.2.0", "electron-positioner": "^4.1.0", "electron-settings": "^3.2.0", "fether-react": "^0.3.0", "pino": "^4.16.1", "pino-multi-stream": "^3.1.2", - "source-map-support": "^0.5.6" + "source-map-support": "^0.5.10" }, "devDependencies": { - "copyfiles": "^2.0.0", + "copyfiles": "^2.1.0", "cross-env": "^5.2.0", "electron": "^4.0.1", - "electron-builder": "^20.29.0", - "electron-webpack": "^2.1.2", - "webpack": "^4.7.0" + "electron-builder": "^20.38.5", + "electron-webpack": "^2.6.1", + "webpack": "^4.29.1" } } \ No newline at end of file From b497ba24470e161337c0a2e8d2c166eb62a9e73b Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Wed, 6 Feb 2019 02:25:12 +1100 Subject: [PATCH 142/153] fix: Do not show balloon message every time ALT key is pressed on Windows --- .../src/main/app/methods/setupWin32Listeners.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/fether-electron/src/main/app/methods/setupWin32Listeners.js b/packages/fether-electron/src/main/app/methods/setupWin32Listeners.js index 098420700..1f30a8d73 100644 --- a/packages/fether-electron/src/main/app/methods/setupWin32Listeners.js +++ b/packages/fether-electron/src/main/app/methods/setupWin32Listeners.js @@ -31,7 +31,8 @@ function setupWin32Listeners (fetherApp) { * Reference: https://nodejs.org/api/buffer.html */ if (wParam) { - showTrayBalloon(fetherApp); + pino.info('Detected ALT key pressed to toggle the Fether menu'); + // showTrayBalloon(fetherApp); } }); From 9e0b9b75f127bae59c81935e618ef10c433dab9b Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Wed, 6 Feb 2019 02:25:34 +1100 Subject: [PATCH 143/153] chore: Update yarn.lock --- yarn.lock | 603 ++---------------------------------------------------- 1 file changed, 12 insertions(+), 591 deletions(-) diff --git a/yarn.lock b/yarn.lock index f5a56bc7f..4955fc174 100644 --- a/yarn.lock +++ b/yarn.lock @@ -56,7 +56,7 @@ semver "^5.4.1" source-map "^0.5.0" -"@babel/core@^7.0.1", "@babel/core@^7.1.0", "@babel/core@^7.2.2": +"@babel/core@^7.0.1", "@babel/core@^7.2.2": version "7.2.2" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.2.2.tgz#07adba6dde27bb5ad8d8672f15fde3e08184a687" integrity sha512-59vB0RWt09cAct5EIe58+NzGP4TFSD3Bz//2/ELy3ZeTeKF6VTD1AXlH8BGGbCX0PuobZBsIzO7IAI9PH67eKw== @@ -76,7 +76,7 @@ semver "^5.4.1" source-map "^0.5.0" -"@babel/generator@^7.0.0", "@babel/generator@^7.1.6", "@babel/generator@^7.2.2": +"@babel/generator@^7.1.6", "@babel/generator@^7.2.2": version "7.3.2" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.3.2.tgz#fff31a7b2f2f3dad23ef8e01be45b0d5c2fc0132" integrity sha512-f3QCuPppXxtZOEm5GWPra/uYUjmNQlu9pbAD8D/9jze4pTY83rTtB1igTBSwvkeNlC5gR24zFFkz+2WHLFQhqQ== @@ -372,14 +372,6 @@ "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-syntax-optional-catch-binding" "^7.2.0" -"@babel/plugin-proposal-pipeline-operator@^7.3.0": - version "7.3.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-pipeline-operator/-/plugin-proposal-pipeline-operator-7.3.2.tgz#cc6be43c8455422f2faca39b9355558f0bff5a3f" - integrity sha512-wuzx8U/KZLJYoqU6joiaKY0PixHuYZ3Vxys+wPahNAZEEm+EDb1eTc19DuJob3BdxYSD9PWPbwyoRbhkdoYErg== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-pipeline-operator" "^7.3.0" - "@babel/plugin-proposal-unicode-property-regex@^7.0.0", "@babel/plugin-proposal-unicode-property-regex@^7.2.0": version "7.2.0" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.2.0.tgz#abe7281fe46c95ddc143a65e5358647792039520" @@ -459,13 +451,6 @@ dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-syntax-pipeline-operator@^7.3.0": - version "7.3.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-pipeline-operator/-/plugin-syntax-pipeline-operator-7.3.0.tgz#06146d1cd0da3bb5f8354f9ec17f13e007182709" - integrity sha512-LAa3ZcOAyfPOUDTp0W5EiXGSAFh1vz9sD8yY7sZzWzEkZdIC404pqBP60Yfu9GJDj0ggh+UTQY6EYlIDXVr0/Q== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-typescript@^7.2.0": version "7.2.0" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.2.0.tgz#55d240536bd314dcbbec70fd949c5cabaed1de29" @@ -743,16 +728,6 @@ resolve "^1.8.1" semver "^5.5.1" -"@babel/plugin-transform-runtime@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.2.0.tgz#566bc43f7d0aedc880eaddbd29168d0f248966ea" - integrity sha512-jIgkljDdq4RYDnJyQsiWbdvGeei/0MOTtSHKO/rfbd/mXBxNpdlulMx49L0HQ4pug1fXannxoqCI+fYSle9eSw== - dependencies: - "@babel/helper-module-imports" "^7.0.0" - "@babel/helper-plugin-utils" "^7.0.0" - resolve "^1.8.1" - semver "^5.5.1" - "@babel/plugin-transform-shorthand-properties@^7.0.0", "@babel/plugin-transform-shorthand-properties@^7.2.0": version "7.2.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.2.0.tgz#6333aee2f8d6ee7e28615457298934a3b46198f0" @@ -929,14 +904,14 @@ dependencies: regenerator-runtime "^0.12.0" -"@babel/runtime@^7.0.0", "@babel/runtime@^7.0.0-beta.49", "@babel/runtime@^7.1.2", "@babel/runtime@^7.1.5", "@babel/runtime@^7.3.1": +"@babel/runtime@^7.0.0", "@babel/runtime@^7.0.0-beta.49", "@babel/runtime@^7.1.2", "@babel/runtime@^7.1.5": version "7.3.1" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.3.1.tgz#574b03e8e8a9898eaf4a872a92ea20b7846f6f2a" integrity sha512-7jGW8ppV0ant637pIqAcFfQDDH1orEPGJb8aXfUozuCU3QqX7rX4DA8iwrbPrR1hcH0FTTHz47yQnk+bl5xHQA== dependencies: regenerator-runtime "^0.12.0" -"@babel/template@^7.0.0", "@babel/template@^7.1.0", "@babel/template@^7.1.2", "@babel/template@^7.2.2": +"@babel/template@^7.1.0", "@babel/template@^7.1.2", "@babel/template@^7.2.2": version "7.2.2" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.2.2.tgz#005b3fdf0ed96e88041330379e0da9a708eb2907" integrity sha512-zRL0IMM02AUDwghf5LMSSDEz7sBCO2YnNmpg3uWTZj/v1rcG2BmQUvaGU8GhU8BvfMh1k2KIAYZ7Ji9KXPUg7g== @@ -2249,13 +2224,6 @@ append-transform@^0.4.0: dependencies: default-require-extensions "^1.0.0" -append-transform@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/append-transform/-/append-transform-1.0.0.tgz#046a52ae582a228bd72f58acfbe2967c678759ab" - integrity sha512-P009oYkeHyU742iSZJzZZywj4QRJdnTWffaKuJQLablCZ1uz6/cW4yaRgcDaoQ+uwOxxnt0gRUcwfsNP2ri0gw== - dependencies: - default-require-extensions "^2.0.0" - aproba@^1.0.3, aproba@^1.1.1, aproba@^1.1.2: version "1.2.0" resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" @@ -2471,7 +2439,7 @@ async@^1.5.2: resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" integrity sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo= -async@^2.1.4, async@^2.5.0, async@^2.6.1: +async@^2.1.4, async@^2.5.0: version "2.6.1" resolved "https://registry.yarnpkg.com/async/-/async-2.6.1.tgz#b245a23ca71930044ec53fa46aa00a3e87c6a610" integrity sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ== @@ -2644,14 +2612,6 @@ babel-jest@23.6.0, babel-jest@^23.6.0: babel-plugin-istanbul "^4.1.6" babel-preset-jest "^23.2.0" -babel-jest@^24.0.0: - version "24.0.0" - resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-24.0.0.tgz#8a0c767f03f4a595fb921afdab13ff126edd00da" - integrity sha512-YGKRbZUjoRmNIAyG7x4wYxUyHvHPFpYXj6Mx1A5cslhaQOUgP/+LF3wtFgMuOQkIpjbVNBufmOnVY0QVwB5v9Q== - dependencies: - babel-plugin-istanbul "^5.1.0" - babel-preset-jest "^24.0.0" - babel-loader@8.0.4: version "8.0.4" resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.0.4.tgz#7bbf20cbe4560629e2e41534147692d3fecbdce6" @@ -2711,25 +2671,11 @@ babel-plugin-istanbul@^4.1.6: istanbul-lib-instrument "^1.10.1" test-exclude "^4.2.1" -babel-plugin-istanbul@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-5.1.0.tgz#6892f529eff65a3e2d33d87dc5888ffa2ecd4a30" - integrity sha512-CLoXPRSUWiR8yao8bShqZUIC6qLfZVVY3X1wj+QPNXu0wfmrRRfarh1LYy+dYMVI+bDj0ghy3tuqFFRFZmL1Nw== - dependencies: - find-up "^3.0.0" - istanbul-lib-instrument "^3.0.0" - test-exclude "^5.0.0" - babel-plugin-jest-hoist@^23.2.0: version "23.2.0" resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-23.2.0.tgz#e61fae05a1ca8801aadee57a6d66b8cefaf44167" integrity sha1-5h+uBaHKiAGq3uV6bWa4zvr0QWc= -babel-plugin-jest-hoist@^24.0.0: - version "24.0.0" - resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-24.0.0.tgz#3adf030b6fd67e4311479a54b24077bdfc226ec9" - integrity sha512-ipefE7YWNyRNVaV/MonUb/I5nef53ZRFR74P9meMGmJxqt8s1BJmfhw11YeIMbcjXN4fxtWUaskZZe8yreXE1Q== - babel-plugin-macros@2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/babel-plugin-macros/-/babel-plugin-macros-2.4.2.tgz#21b1a2e82e2130403c5ff785cba6548e9b644b28" @@ -2769,14 +2715,6 @@ babel-preset-jest@^23.2.0: babel-plugin-jest-hoist "^23.2.0" babel-plugin-syntax-object-rest-spread "^6.13.0" -babel-preset-jest@^24.0.0: - version "24.0.0" - resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-24.0.0.tgz#d23782e5e036cff517859640a80960bd628bd82b" - integrity sha512-ECMMOLvNDCmsn3geBa3JkwzylcfpThMpAdfreONQm8EmXcs4tXUpXZDQPxiIMg7nMobTuAC2zDGIKrbrBXW2Vg== - dependencies: - "@babel/plugin-syntax-object-rest-spread" "^7.0.0" - babel-plugin-jest-hoist "^24.0.0" - babel-preset-react-app@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/babel-preset-react-app/-/babel-preset-react-app-7.0.0.tgz#86bf71e43cb8d36e40da69f8b4ad5d6f945dec93" @@ -3425,11 +3363,6 @@ callsites@^2.0.0: resolved "https://registry.yarnpkg.com/callsites/-/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50" integrity sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA= -callsites@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.0.0.tgz#fb7eb569b72ad7a45812f93fd9430a3e410b3dd3" - integrity sha512-tWnkwu9YEq2uzlBDI4RcLn8jrFvF9AOi8PxDNU3hZZjJcjkcRAq3vCI+vZcg1SuxISDYe86k9VZFwAxDiJGoAw== - camel-case@3.0.x: version "3.0.0" resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-3.0.0.tgz#ca3c3688a4e9cf3a4cda777dc4dcbc713249cf73" @@ -3959,11 +3892,6 @@ compare-version@^0.1.2: resolved "https://registry.yarnpkg.com/compare-version/-/compare-version-0.1.2.tgz#0162ec2d9351f5ddd59a9202cba935366a725080" integrity sha1-AWLsLZNR9d3VmpICy6k1NmpyUIA= -compare-versions@^3.2.1: - version "3.4.0" - resolved "https://registry.yarnpkg.com/compare-versions/-/compare-versions-3.4.0.tgz#e0747df5c9cb7f054d6d3dc3e1dbc444f9e92b26" - integrity sha512-tK69D7oNXXqUW3ZNo/z7NXTEz22TCF0pTE+YF9cxvaAM9XnkLo1fV621xCLrRR6aevJlKxExkss0vWqUCUpqdg== - component-emitter@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6" @@ -4774,13 +4702,6 @@ default-require-extensions@^1.0.0: dependencies: strip-bom "^2.0.0" -default-require-extensions@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/default-require-extensions/-/default-require-extensions-2.0.0.tgz#f5f8fbb18a7d6d50b21f641f649ebb522cfe24f7" - integrity sha1-9fj7sYp9bVCyH2QfZJ67Uiz+JPc= - dependencies: - strip-bom "^3.0.0" - defaults@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.3.tgz#c656051e9817d9ff08ed881477f3fe4019f3ef7d" @@ -4922,11 +4843,6 @@ dezalgo@^1.0.0: asap "^2.0.0" wrappy "1" -diff-sequences@^24.0.0: - version "24.0.0" - resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-24.0.0.tgz#cdf8e27ed20d8b8d3caccb4e0c0d8fe31a173013" - integrity sha512-46OkIuVGBBnrC0soO/4LHu5LHGHx0uhP65OVz8XOrAJpqiCB2aVIuESvjI1F9oqebuvY8lekS1pt6TN7vt7qsw== - diff@^3.2.0: version "3.5.0" resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" @@ -5974,17 +5890,6 @@ expect@^23.6.0: jest-message-util "^23.4.0" jest-regex-util "^23.3.0" -expect@^24.0.0: - version "24.0.0" - resolved "https://registry.yarnpkg.com/expect/-/expect-24.0.0.tgz#71f71d88a4202746fc79849bb4c6498008b5ef03" - integrity sha512-qDHRU4lGsme0xjg8dXp/RQhvO9XIo9FWqVo7dTHDPBwzy25JGEHAWFsnpmRYErB50tgi/6euo3ir5e/kF9LUTA== - dependencies: - ansi-styles "^3.2.0" - jest-get-type "^24.0.0" - jest-matcher-utils "^24.0.0" - jest-message-util "^24.0.0" - jest-regex-util "^24.0.0" - express@^4.16.2: version "4.16.4" resolved "https://registry.yarnpkg.com/express/-/express-4.16.4.tgz#fddef61926109e24c515ea97fd2f1bdbf62df12e" @@ -6241,7 +6146,7 @@ filename-regex@^2.0.0: resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26" integrity sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY= -fileset@^2.0.2, fileset@^2.0.3: +fileset@^2.0.2: version "2.0.3" resolved "https://registry.yarnpkg.com/fileset/-/fileset-2.0.3.tgz#8e7548a96d3cc2327ee5e674168723a333bba2a0" integrity sha1-jnVIqW08wjJ+5eZ0FocjozO7oqA= @@ -6928,7 +6833,7 @@ handle-thing@^2.0.0: resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.0.tgz#0e039695ff50c93fc288557d696f3c1dc6776754" integrity sha512-d4sze1JNC454Wdo2fkuyzCr6aHcbL6PGGuFAz0Li/NcOm1tCHGnWDRmJP85dh9IhQErTc2svWFEX5xHIOo//kQ== -handlebars@^4.0.11, handlebars@^4.0.2, handlebars@^4.0.3: +handlebars@^4.0.2, handlebars@^4.0.3: version "4.0.12" resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.0.12.tgz#2c15c8a96d46da5e266700518ba8cb8d919d5bc5" integrity sha512-RhmTekP+FZL+XNhwS1Wf+bTTZpdLougwt5pcgA1tuz6Jcx0fpH/7z0qd71RKnZHBCxIRBHfBOnio4gViPemNzA== @@ -7838,11 +7743,6 @@ is-generator-fn@^1.0.0: resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-1.0.0.tgz#969d49e1bb3329f6bb7f09089be26578b2ddd46a" integrity sha1-lp1J4bszKfa7fwkIm+JleLLd1Go= -is-generator-fn@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.0.0.tgz#038c31b774709641bda678b1f06a4e3227c10b3e" - integrity sha512-elzyIdM7iKoFHzcrndIqjYomImhxrFRnGP3galODoII4TB9gI7mZ+FnlLQmmjf27SxHS2gKEeyhX5/+YRS6H9g== - is-glob@^2.0.0, is-glob@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" @@ -8133,35 +8033,11 @@ istanbul-api@^1.3.1: mkdirp "^0.5.1" once "^1.4.0" -istanbul-api@^2.0.8: - version "2.1.0" - resolved "https://registry.yarnpkg.com/istanbul-api/-/istanbul-api-2.1.0.tgz#37ab0c2c3e83065462f5254b94749d6157846c4e" - integrity sha512-+Ygg4t1StoiNlBGc6x0f8q/Bv26FbZqP/+jegzfNpU7Q8o+4ZRoJxJPhBkgE/UonpAjtxnE4zCZIyJX+MwLRMQ== - dependencies: - async "^2.6.1" - compare-versions "^3.2.1" - fileset "^2.0.3" - istanbul-lib-coverage "^2.0.3" - istanbul-lib-hook "^2.0.3" - istanbul-lib-instrument "^3.1.0" - istanbul-lib-report "^2.0.4" - istanbul-lib-source-maps "^3.0.2" - istanbul-reports "^2.1.0" - js-yaml "^3.12.0" - make-dir "^1.3.0" - minimatch "^3.0.4" - once "^1.4.0" - istanbul-lib-coverage@^1.2.0, istanbul-lib-coverage@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-1.2.1.tgz#ccf7edcd0a0bb9b8f729feeb0930470f9af664f0" integrity sha512-PzITeunAgyGbtY1ibVIUiV679EFChHjoMNRibEIobvmrCRaIgwLxNucOSimtNWUhEib/oO7QY2imD75JVgCJWQ== -istanbul-lib-coverage@^2.0.2, istanbul-lib-coverage@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz#0b891e5ad42312c2b9488554f603795f9a2211ba" - integrity sha512-dKWuzRGCs4G+67VfW9pBFFz2Jpi4vSp/k7zBcJ888ofV5Mi1g5CUML5GvMvV6u9Cjybftu+E8Cgp+k0dI1E5lw== - istanbul-lib-hook@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/istanbul-lib-hook/-/istanbul-lib-hook-1.2.2.tgz#bc6bf07f12a641fbf1c85391d0daa8f0aea6bf86" @@ -8169,13 +8045,6 @@ istanbul-lib-hook@^1.2.2: dependencies: append-transform "^0.4.0" -istanbul-lib-hook@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/istanbul-lib-hook/-/istanbul-lib-hook-2.0.3.tgz#e0e581e461c611be5d0e5ef31c5f0109759916fb" - integrity sha512-CLmEqwEhuCYtGcpNVJjLV1DQyVnIqavMLFHV/DP+np/g3qvdxu3gsPqYoJMXm15sN84xOlckFB3VNvRbf5yEgA== - dependencies: - append-transform "^1.0.0" - istanbul-lib-instrument@^1.10.1, istanbul-lib-instrument@^1.10.2: version "1.10.2" resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-1.10.2.tgz#1f55ed10ac3c47f2bdddd5307935126754d0a9ca" @@ -8189,19 +8058,6 @@ istanbul-lib-instrument@^1.10.1, istanbul-lib-instrument@^1.10.2: istanbul-lib-coverage "^1.2.1" semver "^5.3.0" -istanbul-lib-instrument@^3.0.0, istanbul-lib-instrument@^3.0.1, istanbul-lib-instrument@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-3.1.0.tgz#a2b5484a7d445f1f311e93190813fa56dfb62971" - integrity sha512-ooVllVGT38HIk8MxDj/OIHXSYvH+1tq/Vb38s8ixt9GoJadXska4WkGY+0wkmtYCZNYtaARniH/DixUGGLZ0uA== - dependencies: - "@babel/generator" "^7.0.0" - "@babel/parser" "^7.0.0" - "@babel/template" "^7.0.0" - "@babel/traverse" "^7.0.0" - "@babel/types" "^7.0.0" - istanbul-lib-coverage "^2.0.3" - semver "^5.5.0" - istanbul-lib-report@^1.1.5: version "1.1.5" resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-1.1.5.tgz#f2a657fc6282f96170aaf281eb30a458f7f4170c" @@ -8212,15 +8068,6 @@ istanbul-lib-report@^1.1.5: path-parse "^1.0.5" supports-color "^3.1.2" -istanbul-lib-report@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-2.0.4.tgz#bfd324ee0c04f59119cb4f07dab157d09f24d7e4" - integrity sha512-sOiLZLAWpA0+3b5w5/dq0cjm2rrNdAfHWaGhmn7XEFW6X++IV9Ohn+pnELAl9K3rfpaeBfbmH9JU5sejacdLeA== - dependencies: - istanbul-lib-coverage "^2.0.3" - make-dir "^1.3.0" - supports-color "^6.0.0" - istanbul-lib-source-maps@^1.2.4, istanbul-lib-source-maps@^1.2.6: version "1.2.6" resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.6.tgz#37b9ff661580f8fca11232752ee42e08c6675d8f" @@ -8232,17 +8079,6 @@ istanbul-lib-source-maps@^1.2.4, istanbul-lib-source-maps@^1.2.6: rimraf "^2.6.1" source-map "^0.5.3" -istanbul-lib-source-maps@^3.0.1, istanbul-lib-source-maps@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.2.tgz#f1e817229a9146e8424a28e5d69ba220fda34156" - integrity sha512-JX4v0CiKTGp9fZPmoxpu9YEkPbEqCqBbO3403VabKjH+NRXo72HafD5UgnjTEqHL2SAjaZK1XDuDOkn6I5QVfQ== - dependencies: - debug "^4.1.1" - istanbul-lib-coverage "^2.0.3" - make-dir "^1.3.0" - rimraf "^2.6.2" - source-map "^0.6.1" - istanbul-reports@^1.5.1: version "1.5.1" resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-1.5.1.tgz#97e4dbf3b515e8c484caea15d6524eebd3ff4e1a" @@ -8250,13 +8086,6 @@ istanbul-reports@^1.5.1: dependencies: handlebars "^4.0.3" -istanbul-reports@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-2.1.0.tgz#87b8b55cd1901ba1748964c98ddd8900ce306d59" - integrity sha512-azQdSX+dtTtkQEfqq20ICxWi6eOHXyHIgMFw1VOOVi8iIPWeCWRgCyFh/CsBKIhcgskMI8ExXmU7rjXTRCIJ+A== - dependencies: - handlebars "^4.0.11" - jest-changed-files@^23.4.2: version "23.4.2" resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-23.4.2.tgz#1eed688370cd5eebafe4ae93d34bb3b64968fe83" @@ -8264,14 +8093,6 @@ jest-changed-files@^23.4.2: dependencies: throat "^4.0.0" -jest-changed-files@^24.0.0: - version "24.0.0" - resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-24.0.0.tgz#c02c09a8cc9ca93f513166bc773741bd39898ff7" - integrity sha512-nnuU510R9U+UX0WNb5XFEcsrMqriSiRLeO9KWDFgPrpToaQm60prfQYpxsXigdClpvNot5bekDY440x9dNGnsQ== - dependencies: - execa "^1.0.0" - throat "^4.0.0" - jest-cli@^23.6.0: version "23.6.0" resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-23.6.0.tgz#61ab917744338f443ef2baa282ddffdd658a5da4" @@ -8314,50 +8135,6 @@ jest-cli@^23.6.0: which "^1.2.12" yargs "^11.0.0" -jest-cli@^24.0.0: - version "24.0.0" - resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-24.0.0.tgz#691fd4f7bce2574c1865db6844a43b56e60ce2a4" - integrity sha512-mElnFipLaGxo1SiQ1CLvuaz3eX07MJc4HcyKrApSJf8xSdY1/EwaHurKwu1g2cDiwIgY8uHj7UcF5OYbtiBOWg== - dependencies: - ansi-escapes "^3.0.0" - chalk "^2.0.1" - exit "^0.1.2" - glob "^7.1.2" - graceful-fs "^4.1.15" - import-local "^2.0.0" - is-ci "^2.0.0" - istanbul-api "^2.0.8" - istanbul-lib-coverage "^2.0.2" - istanbul-lib-instrument "^3.0.1" - istanbul-lib-source-maps "^3.0.1" - jest-changed-files "^24.0.0" - jest-config "^24.0.0" - jest-environment-jsdom "^24.0.0" - jest-get-type "^24.0.0" - jest-haste-map "^24.0.0" - jest-message-util "^24.0.0" - jest-regex-util "^24.0.0" - jest-resolve-dependencies "^24.0.0" - jest-runner "^24.0.0" - jest-runtime "^24.0.0" - jest-snapshot "^24.0.0" - jest-util "^24.0.0" - jest-validate "^24.0.0" - jest-watcher "^24.0.0" - jest-worker "^24.0.0" - micromatch "^3.1.10" - node-notifier "^5.2.1" - p-each-series "^1.0.0" - pirates "^4.0.0" - prompts "^2.0.1" - realpath-native "^1.0.0" - rimraf "^2.5.4" - slash "^2.0.0" - string-length "^2.0.0" - strip-ansi "^5.0.0" - which "^1.2.12" - yargs "^12.0.2" - jest-config@^23.6.0: version "23.6.0" resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-23.6.0.tgz#f82546a90ade2d8c7026fbf6ac5207fc22f8eb1d" @@ -8378,28 +8155,6 @@ jest-config@^23.6.0: micromatch "^2.3.11" pretty-format "^23.6.0" -jest-config@^24.0.0: - version "24.0.0" - resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-24.0.0.tgz#878abe03c060c74a0ec30d3cd5dd1897873e030e" - integrity sha512-9/soqWL5YSq1ZJtgVJ5YYPCL1f9Mi2lVCp5+OXuYBOaN8DHSFRCSWip0rQ6N+mPTOEIAlCvcUH8zaPOwK4hePg== - dependencies: - "@babel/core" "^7.1.0" - babel-jest "^24.0.0" - chalk "^2.0.1" - glob "^7.1.1" - jest-environment-jsdom "^24.0.0" - jest-environment-node "^24.0.0" - jest-get-type "^24.0.0" - jest-jasmine2 "^24.0.0" - jest-regex-util "^24.0.0" - jest-resolve "^24.0.0" - jest-util "^24.0.0" - jest-validate "^24.0.0" - micromatch "^3.1.10" - pretty-format "^24.0.0" - realpath-native "^1.0.2" - uuid "^3.3.2" - jest-diff@^23.6.0: version "23.6.0" resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-23.6.0.tgz#1500f3f16e850bb3d71233408089be099f610c7d" @@ -8410,16 +8165,6 @@ jest-diff@^23.6.0: jest-get-type "^22.1.0" pretty-format "^23.6.0" -jest-diff@^24.0.0: - version "24.0.0" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-24.0.0.tgz#a3e5f573dbac482f7d9513ac9cfa21644d3d6b34" - integrity sha512-XY5wMpRaTsuMoU+1/B2zQSKQ9RdE9gsLkGydx3nvApeyPijLA8GtEvIcPwISRCer+VDf9W1mStTYYq6fPt8ryA== - dependencies: - chalk "^2.0.1" - diff-sequences "^24.0.0" - jest-get-type "^24.0.0" - pretty-format "^24.0.0" - jest-docblock@^23.2.0: version "23.2.0" resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-23.2.0.tgz#f085e1f18548d99fdd69b20207e6fd55d91383a7" @@ -8427,13 +8172,6 @@ jest-docblock@^23.2.0: dependencies: detect-newline "^2.1.0" -jest-docblock@^24.0.0: - version "24.0.0" - resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-24.0.0.tgz#54d77a188743e37f62181a91a01eb9222289f94e" - integrity sha512-KfAKZ4SN7CFOZpWg4i7g7MSlY0M+mq7K0aMqENaG2vHuhC9fc3vkpU/iNN9sOus7v3h3Y48uEjqz3+Gdn2iptA== - dependencies: - detect-newline "^2.1.0" - jest-each@^23.6.0: version "23.6.0" resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-23.6.0.tgz#ba0c3a82a8054387016139c733a05242d3d71575" @@ -8442,16 +8180,6 @@ jest-each@^23.6.0: chalk "^2.0.1" pretty-format "^23.6.0" -jest-each@^24.0.0: - version "24.0.0" - resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-24.0.0.tgz#10987a06b21c7ffbfb7706c89d24c52ed864be55" - integrity sha512-gFcbY4Cu55yxExXMkjrnLXov3bWO3dbPAW7HXb31h/DNWdNc/6X8MtxGff8nh3/MjkF9DpVqnj0KsPKuPK0cpA== - dependencies: - chalk "^2.0.1" - jest-get-type "^24.0.0" - jest-util "^24.0.0" - pretty-format "^24.0.0" - jest-environment-jsdom@^23.4.0: version "23.4.0" resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-23.4.0.tgz#056a7952b3fea513ac62a140a2c368c79d9e6023" @@ -8461,15 +8189,6 @@ jest-environment-jsdom@^23.4.0: jest-util "^23.4.0" jsdom "^11.5.1" -jest-environment-jsdom@^24.0.0: - version "24.0.0" - resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-24.0.0.tgz#5affa0654d6e44cd798003daa1a8701dbd6e4d11" - integrity sha512-1YNp7xtxajTRaxbylDc2pWvFnfDTH5BJJGyVzyGAKNt/lEULohwEV9zFqTgG4bXRcq7xzdd+sGFws+LxThXXOw== - dependencies: - jest-mock "^24.0.0" - jest-util "^24.0.0" - jsdom "^11.5.1" - jest-environment-node@^23.4.0: version "23.4.0" resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-23.4.0.tgz#57e80ed0841dea303167cce8cd79521debafde10" @@ -8478,24 +8197,11 @@ jest-environment-node@^23.4.0: jest-mock "^23.2.0" jest-util "^23.4.0" -jest-environment-node@^24.0.0: - version "24.0.0" - resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-24.0.0.tgz#330948980656ed8773ce2e04eb597ed91e3c7190" - integrity sha512-62fOFcaEdU0VLaq8JL90TqwI7hLn0cOKOl8vY2n477vRkCJRojiRRtJVRzzCcgFvs6gqU97DNqX5R0BrBP6Rxg== - dependencies: - jest-mock "^24.0.0" - jest-util "^24.0.0" - jest-get-type@^22.1.0: version "22.4.3" resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-22.4.3.tgz#e3a8504d8479342dd4420236b322869f18900ce4" integrity sha512-/jsz0Y+V29w1chdXVygEKSz2nBoHoYqNShPe+QgxSNjAuP1i8+k4LbQNrfoliKej0P45sivkSCh7yiD6ubHS3w== -jest-get-type@^24.0.0: - version "24.0.0" - resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-24.0.0.tgz#36e72930b78e33da59a4f63d44d332188278940b" - integrity sha512-z6/Eyf6s9ZDGz7eOvl+fzpuJmN9i0KyTt1no37/dHu8galssxz5ZEgnc1KaV8R31q1khxyhB4ui/X5ZjjPk77w== - jest-haste-map@^23.6.0: version "23.6.0" resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-23.6.0.tgz#2e3eb997814ca696d62afdb3f2529f5bbc935e16" @@ -8510,20 +8216,6 @@ jest-haste-map@^23.6.0: micromatch "^2.3.11" sane "^2.0.0" -jest-haste-map@^24.0.0: - version "24.0.0" - resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-24.0.0.tgz#e9ef51b2c9257384b4d6beb83bd48c65b37b5e6e" - integrity sha512-CcViJyUo41IQqttLxXVdI41YErkzBKbE6cS6dRAploCeutePYfUimWd3C9rQEWhX0YBOQzvNsC0O9nYxK2nnxQ== - dependencies: - fb-watchman "^2.0.0" - graceful-fs "^4.1.15" - invariant "^2.2.4" - jest-serializer "^24.0.0" - jest-util "^24.0.0" - jest-worker "^24.0.0" - micromatch "^3.1.10" - sane "^3.0.0" - jest-jasmine2@^23.6.0: version "23.6.0" resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-23.6.0.tgz#840e937f848a6c8638df24360ab869cc718592e0" @@ -8542,23 +8234,6 @@ jest-jasmine2@^23.6.0: jest-util "^23.4.0" pretty-format "^23.6.0" -jest-jasmine2@^24.0.0: - version "24.0.0" - resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-24.0.0.tgz#7d87be9d8b32d34ac5980ad646b7ae7f99e33a19" - integrity sha512-q1xEV9KHM0bgfBj3yrkrjRF5kxpNDkWPCwVfSPN1DC+pD6J5wrM9/u2BgzhKhALXiaZUUhJ+f/OcEC0Gwpw90A== - dependencies: - "@babel/traverse" "^7.1.0" - chalk "^2.0.1" - co "^4.6.0" - expect "^24.0.0" - is-generator-fn "^2.0.0" - jest-each "^24.0.0" - jest-matcher-utils "^24.0.0" - jest-message-util "^24.0.0" - jest-snapshot "^24.0.0" - jest-util "^24.0.0" - pretty-format "^24.0.0" - jest-leak-detector@^23.6.0: version "23.6.0" resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-23.6.0.tgz#e4230fd42cf381a1a1971237ad56897de7e171de" @@ -8566,13 +8241,6 @@ jest-leak-detector@^23.6.0: dependencies: pretty-format "^23.6.0" -jest-leak-detector@^24.0.0: - version "24.0.0" - resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-24.0.0.tgz#78280119fd05ee98317daee62cddb3aa537a31c6" - integrity sha512-ZYHJYFeibxfsDSKowjDP332pStuiFT2xfc5R67Rjm/l+HFJWJgNIOCOlQGeXLCtyUn3A23+VVDdiCcnB6dTTrg== - dependencies: - pretty-format "^24.0.0" - jest-matcher-utils@^23.6.0: version "23.6.0" resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-23.6.0.tgz#726bcea0c5294261a7417afb6da3186b4b8cac80" @@ -8582,16 +8250,6 @@ jest-matcher-utils@^23.6.0: jest-get-type "^22.1.0" pretty-format "^23.6.0" -jest-matcher-utils@^24.0.0: - version "24.0.0" - resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-24.0.0.tgz#fc9c41cfc49b2c3ec14e576f53d519c37729d579" - integrity sha512-LQTDmO+aWRz1Tf9HJg+HlPHhDh1E1c65kVwRFo5mwCVp5aQDzlkz4+vCvXhOKFjitV2f0kMdHxnODrXVoi+rlA== - dependencies: - chalk "^2.0.1" - jest-diff "^24.0.0" - jest-get-type "^24.0.0" - pretty-format "^24.0.0" - jest-message-util@^23.4.0: version "23.4.0" resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-23.4.0.tgz#17610c50942349508d01a3d1e0bda2c079086a9f" @@ -8603,27 +8261,11 @@ jest-message-util@^23.4.0: slash "^1.0.0" stack-utils "^1.0.1" -jest-message-util@^24.0.0: - version "24.0.0" - resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-24.0.0.tgz#a07a141433b2c992dbaec68d4cbfe470ba289619" - integrity sha512-J9ROJIwz/IeC+eV1XSwnRK4oAwPuhmxEyYx1+K5UI+pIYwFZDSrfZaiWTdq0d2xYFw4Xiu+0KQWsdsQpgJMf3Q== - dependencies: - "@babel/code-frame" "^7.0.0" - chalk "^2.0.1" - micromatch "^3.1.10" - slash "^2.0.0" - stack-utils "^1.0.1" - jest-mock@^23.2.0: version "23.2.0" resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-23.2.0.tgz#ad1c60f29e8719d47c26e1138098b6d18b261134" integrity sha1-rRxg8p6HGdR8JuETgJi20YsmETQ= -jest-mock@^24.0.0: - version "24.0.0" - resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-24.0.0.tgz#9a4b53e01d66a0e780f7d857462d063e024c617d" - integrity sha512-sQp0Hu5fcf5NZEh1U9eIW2qD0BwJZjb63Yqd98PQJFvf/zzUTBoUAwv/Dc/HFeNHIw1f3hl/48vNn+j3STaI7A== - jest-pnp-resolver@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.0.1.tgz#f397cd71dbcd4a1947b2e435f6da8e9a347308fa" @@ -8634,11 +8276,6 @@ jest-regex-util@^23.3.0: resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-23.3.0.tgz#5f86729547c2785c4002ceaa8f849fe8ca471bc5" integrity sha1-X4ZylUfCeFxAAs6qj4Sf6MpHG8U= -jest-regex-util@^24.0.0: - version "24.0.0" - resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-24.0.0.tgz#4feee8ec4a358f5bee0a654e94eb26163cb9089a" - integrity sha512-Jv/uOTCuC+PY7WpJl2mpoI+WbY2ut73qwwO9ByJJNwOCwr1qWhEW2Lyi2S9ZewUdJqeVpEBisdEVZSI+Zxo58Q== - jest-resolve-dependencies@^23.6.0: version "23.6.0" resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-23.6.0.tgz#b4526af24c8540d9a3fab102c15081cf509b723d" @@ -8647,14 +8284,6 @@ jest-resolve-dependencies@^23.6.0: jest-regex-util "^23.3.0" jest-snapshot "^23.6.0" -jest-resolve-dependencies@^24.0.0: - version "24.0.0" - resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-24.0.0.tgz#86540611d660bdcaab8b87d069247d3832811d94" - integrity sha512-CJGS5ME2g5wL16o3Y22ga9p5ntNT5CUYX40/0lYj9ic9jB5YHm/qMKTgbFt9kowEBiMOFpXy15dWtBTEU54+zg== - dependencies: - jest-regex-util "^24.0.0" - jest-snapshot "^24.0.0" - jest-resolve@23.6.0, jest-resolve@^23.6.0: version "23.6.0" resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-23.6.0.tgz#cf1d1a24ce7ee7b23d661c33ba2150f3aebfa0ae" @@ -8664,15 +8293,6 @@ jest-resolve@23.6.0, jest-resolve@^23.6.0: chalk "^2.0.1" realpath-native "^1.0.0" -jest-resolve@^24.0.0: - version "24.0.0" - resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-24.0.0.tgz#0206cfe842324f8796b01f706f4075309bf7b405" - integrity sha512-uKDGyJqNaBQKox1DJzm27CJobADsIMNgZGusXhtYzl98LKu/fKuokkRsd7EBVgoDA80HKHc3LOPKuYLryMu1vw== - dependencies: - browser-resolve "^1.11.3" - chalk "^2.0.1" - realpath-native "^1.0.0" - jest-runner@^23.6.0: version "23.6.0" resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-23.6.0.tgz#3894bd219ffc3f3cb94dc48a4170a2e6f23a5a38" @@ -8692,25 +8312,6 @@ jest-runner@^23.6.0: source-map-support "^0.5.6" throat "^4.0.0" -jest-runner@^24.0.0: - version "24.0.0" - resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-24.0.0.tgz#00b280d52d23286111a8ed0362ed958283f7f0e3" - integrity sha512-XefXm2XimKtwdfi2am4364GfCmLD1tOjiRtDexY65diCXt4Rw23rxj2wiW7p9s8Nh9dzJQNmrheqZ5rzvn762g== - dependencies: - exit "^0.1.2" - graceful-fs "^4.1.15" - jest-config "^24.0.0" - jest-docblock "^24.0.0" - jest-haste-map "^24.0.0" - jest-jasmine2 "^24.0.0" - jest-leak-detector "^24.0.0" - jest-message-util "^24.0.0" - jest-runtime "^24.0.0" - jest-util "^24.0.0" - jest-worker "^24.0.0" - source-map-support "^0.5.6" - throat "^4.0.0" - jest-runtime@^23.6.0: version "23.6.0" resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-23.6.0.tgz#059e58c8ab445917cd0e0d84ac2ba68de8f23082" @@ -8738,44 +8339,11 @@ jest-runtime@^23.6.0: write-file-atomic "^2.1.0" yargs "^11.0.0" -jest-runtime@^24.0.0: - version "24.0.0" - resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-24.0.0.tgz#bc80756f5458c2c8e4db86f44b687ff692026c13" - integrity sha512-UeVoTGiij8upcqfyBlJvImws7IGY+ZWtgVpt1h4VmVbyei39tVGia/20VoP3yvodS6FdjTwBj+JzVNuoh/9UTw== - dependencies: - "@babel/core" "^7.1.0" - babel-plugin-istanbul "^5.1.0" - chalk "^2.0.1" - convert-source-map "^1.4.0" - exit "^0.1.2" - fast-json-stable-stringify "^2.0.0" - glob "^7.1.3" - graceful-fs "^4.1.15" - jest-config "^24.0.0" - jest-haste-map "^24.0.0" - jest-message-util "^24.0.0" - jest-regex-util "^24.0.0" - jest-resolve "^24.0.0" - jest-snapshot "^24.0.0" - jest-util "^24.0.0" - jest-validate "^24.0.0" - micromatch "^3.1.10" - realpath-native "^1.0.0" - slash "^2.0.0" - strip-bom "3.0.0" - write-file-atomic "^2.4.2" - yargs "^12.0.2" - jest-serializer@^23.0.1: version "23.0.1" resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-23.0.1.tgz#a3776aeb311e90fe83fab9e533e85102bd164165" integrity sha1-o3dq6zEekP6D+rnlM+hRAr0WQWU= -jest-serializer@^24.0.0: - version "24.0.0" - resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-24.0.0.tgz#522c44a332cdd194d8c0531eb06a1ee5afb4256b" - integrity sha512-9FKxQyrFgHtx3ozU+1a8v938ILBE7S8Ko3uiAVjT8Yfi2o91j/fj81jacCQZ/Ihjiff/VsUCXVgQ+iF1XdImOw== - jest-snapshot@^23.6.0: version "23.6.0" resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-23.6.0.tgz#f9c2625d1b18acda01ec2d2b826c0ce58a5aa17a" @@ -8792,22 +8360,6 @@ jest-snapshot@^23.6.0: pretty-format "^23.6.0" semver "^5.5.0" -jest-snapshot@^24.0.0: - version "24.0.0" - resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-24.0.0.tgz#fb447a753a3271660b3d89d068698014eb14c414" - integrity sha512-7OcrckVnfzVYxSGPYl2Sn+HyT30VpDv+FMBFbQxSQ6DV2K9Js6vYT6d4SBPKp6DfDiEL2txNssJBxtlvF+Dymw== - dependencies: - "@babel/types" "^7.0.0" - chalk "^2.0.1" - jest-diff "^24.0.0" - jest-matcher-utils "^24.0.0" - jest-message-util "^24.0.0" - jest-resolve "^24.0.0" - mkdirp "^0.5.1" - natural-compare "^1.4.0" - pretty-format "^24.0.0" - semver "^5.5.0" - jest-util@^23.4.0: version "23.4.0" resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-23.4.0.tgz#4d063cb927baf0a23831ff61bec2cbbf49793561" @@ -8822,20 +8374,6 @@ jest-util@^23.4.0: slash "^1.0.0" source-map "^0.6.0" -jest-util@^24.0.0: - version "24.0.0" - resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-24.0.0.tgz#fd38fcafd6dedbd0af2944d7a227c0d91b68f7d6" - integrity sha512-QxsALc4wguYS7cfjdQSOr5HTkmjzkHgmZvIDkcmPfl1ib8PNV8QUWLwbKefCudWS0PRKioV+VbQ0oCUPC691fQ== - dependencies: - callsites "^3.0.0" - chalk "^2.0.1" - graceful-fs "^4.1.15" - is-ci "^2.0.0" - jest-message-util "^24.0.0" - mkdirp "^0.5.1" - slash "^2.0.0" - source-map "^0.6.0" - jest-validate@^23.6.0: version "23.6.0" resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-23.6.0.tgz#36761f99d1ed33fcd425b4e4c5595d62b6597474" @@ -8846,17 +8384,6 @@ jest-validate@^23.6.0: leven "^2.1.0" pretty-format "^23.6.0" -jest-validate@^24.0.0: - version "24.0.0" - resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-24.0.0.tgz#aa8571a46983a6538328fef20406b4a496b6c020" - integrity sha512-vMrKrTOP4BBFIeOWsjpsDgVXATxCspC9S1gqvbJ3Tnn/b9ACsJmteYeVx9830UMV28Cob1RX55x96Qq3Tfad4g== - dependencies: - camelcase "^5.0.0" - chalk "^2.0.1" - jest-get-type "^24.0.0" - leven "^2.1.0" - pretty-format "^24.0.0" - jest-watcher@^23.4.0: version "23.4.0" resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-23.4.0.tgz#d2e28ce74f8dad6c6afc922b92cabef6ed05c91c" @@ -8866,16 +8393,6 @@ jest-watcher@^23.4.0: chalk "^2.0.1" string-length "^2.0.0" -jest-watcher@^24.0.0: - version "24.0.0" - resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-24.0.0.tgz#20d44244d10b0b7312410aefd256c1c1eef68890" - integrity sha512-GxkW2QrZ4YxmW1GUWER05McjVDunBlKMFfExu+VsGmXJmpej1saTEKvONdx5RJBlVdpPI5x6E3+EDQSIGgl53g== - dependencies: - ansi-escapes "^3.0.0" - chalk "^2.0.1" - jest-util "^24.0.0" - string-length "^2.0.0" - jest-worker@^23.2.0: version "23.2.0" resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-23.2.0.tgz#faf706a8da36fae60eb26957257fa7b5d8ea02b9" @@ -8883,14 +8400,6 @@ jest-worker@^23.2.0: dependencies: merge-stream "^1.0.1" -jest-worker@^24.0.0: - version "24.0.0" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-24.0.0.tgz#3d3483b077bf04f412f47654a27bba7e947f8b6d" - integrity sha512-s64/OThpfQvoCeHG963MiEZOAAxu8kHsaL/rCMF7lpdzo7vgF0CtPml9hfguOMgykgH/eOm4jFP4ibfHLruytg== - dependencies: - merge-stream "^1.0.1" - supports-color "^6.1.0" - jest@23.6.0: version "23.6.0" resolved "https://registry.yarnpkg.com/jest/-/jest-23.6.0.tgz#ad5835e923ebf6e19e7a1d7529a432edfee7813d" @@ -8899,14 +8408,6 @@ jest@23.6.0: import-local "^1.0.0" jest-cli "^23.6.0" -jest@^24.0.0: - version "24.0.0" - resolved "https://registry.yarnpkg.com/jest/-/jest-24.0.0.tgz#b8e2c8e6274e1092c7f56e57762a1fdc7800201e" - integrity sha512-1Z2EblP4BnERbWZGtipGb9zjHDq7nCHgCY7V57F5SYaFRJV4DE1HKoOz+CRC5OrAThN9OVhRlUhTzsTFArg2iQ== - dependencies: - import-local "^2.0.0" - jest-cli "^24.0.0" - joi@^11.1.1: version "11.4.0" resolved "https://registry.yarnpkg.com/joi/-/joi-11.4.0.tgz#f674897537b625e9ac3d0b7e1604c828ad913ccb" @@ -9202,11 +8703,6 @@ kleur@^2.0.1: resolved "https://registry.yarnpkg.com/kleur/-/kleur-2.0.2.tgz#b704f4944d95e255d038f0cb05fb8a602c55a300" integrity sha512-77XF9iTllATmG9lSlIv0qdQ2BQ/h9t0bJllHlbvsQ0zUWfU7Yi0S8L5JXzPZgkefIiajLmBJJ4BsMJmqcf7oxQ== -kleur@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.1.tgz#4f5b313f5fa315432a400f19a24db78d451ede62" - integrity sha512-P3kRv+B+Ra070ng2VKQqW4qW7gd/v3iD8sy/zOdcYRsfiD+QBokQNOps/AfP6Hr48cBhIIBFWckB9aO+IZhrWg== - last-call-webpack-plugin@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/last-call-webpack-plugin/-/last-call-webpack-plugin-3.0.0.tgz#9742df0e10e3cf46e5c0381c2de90d3a7a2d7555" @@ -9636,7 +9132,7 @@ lru-queue@0.1: dependencies: es5-ext "~0.10.2" -make-dir@^1.0.0, make-dir@^1.3.0: +make-dir@^1.0.0: version "1.3.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c" integrity sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ== @@ -10278,11 +9774,6 @@ node-loader@^0.6.0: resolved "https://registry.yarnpkg.com/node-loader/-/node-loader-0.6.0.tgz#c797ef51095ed5859902b157f6384f6361e05ae8" integrity sha1-x5fvUQle1YWZArFX9jhPY2HgWug= -node-modules-regexp@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz#8d9dbe28964a4ac5712e9131642107c71e90ec40" - integrity sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA= - node-notifier@^5.2.1: version "5.4.0" resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-5.4.0.tgz#7b455fdce9f7de0c63538297354f3db468426e6a" @@ -10781,13 +10272,6 @@ p-defer@^1.0.0: resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-1.0.0.tgz#9f6eb182f6c9aa8cd743004a7d4f96b196b0fb0c" integrity sha1-n26xgvbJqozXQwBKfU+WsZaw+ww= -p-each-series@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-each-series/-/p-each-series-1.0.0.tgz#930f3d12dd1f50e7434457a22cd6f04ac6ad7f71" - integrity sha1-kw89Et0fUOdDRFeiLNbwSsatf3E= - dependencies: - p-reduce "^1.0.0" - p-finally@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" @@ -11171,13 +10655,6 @@ pino@^4.16.1, pino@^4.7.1: quick-format-unescaped "^1.1.2" split2 "^2.2.0" -pirates@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.0.tgz#850b18781b4ac6ec58a43c9ed9ec5fe6796addbd" - integrity sha512-8t5BsXy1LUIjn3WWOlOuFDuKswhQb/tkak641lvBgmPOBUQHXveORtlMCp6OdPV1dtuTaEahKA8VNz6uLfKBtA== - dependencies: - node-modules-regexp "^1.0.0" - pkg-conf@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/pkg-conf/-/pkg-conf-2.1.0.tgz#2126514ca6f2abfebd168596df18ba57867f0058" @@ -12199,14 +11676,6 @@ pretty-format@^23.6.0: ansi-regex "^3.0.0" ansi-styles "^3.2.0" -pretty-format@^24.0.0: - version "24.0.0" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-24.0.0.tgz#cb6599fd73ac088e37ed682f61291e4678f48591" - integrity sha512-LszZaKG665djUcqg5ZQq+XzezHLKrxsA86ZABTozp+oNhkdqa+tG2dX4qa6ERl5c/sRDrAa3lHmwnvKoP+OG/g== - dependencies: - ansi-regex "^4.0.0" - ansi-styles "^3.2.0" - private@^0.1.6, private@^0.1.8: version "0.1.8" resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" @@ -12275,14 +11744,6 @@ prompts@^0.1.9: kleur "^2.0.1" sisteransi "^0.1.1" -prompts@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.0.1.tgz#201b3718b4276fb407f037db48c0029d6465245c" - integrity sha512-8lnEOSIGQbgbnO47+13S+H204L8ISogGulyi0/NNEFAQ9D1VMNTrJ9SBX2Ra03V4iPn/zt36HQMndRYkaPoWiQ== - dependencies: - kleur "^3.0.0" - sisteransi "^1.0.0" - promzard@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/promzard/-/promzard-0.3.0.tgz#26a5d6ee8c7dee4cb12208305acfb93ba382a9ee" @@ -12784,14 +12245,6 @@ read-pkg-up@^3.0.0: find-up "^2.0.0" read-pkg "^3.0.0" -read-pkg-up@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-4.0.0.tgz#1b221c6088ba7799601c808f91161c66e58f8978" - integrity sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA== - dependencies: - find-up "^3.0.0" - read-pkg "^3.0.0" - read-pkg@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" @@ -12896,7 +12349,7 @@ readdirp@^2.0.0: micromatch "^3.1.10" readable-stream "^2.0.2" -realpath-native@^1.0.0, realpath-native@^1.0.2: +realpath-native@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/realpath-native/-/realpath-native-1.0.2.tgz#cd51ce089b513b45cf9b1516c82989b51ccc6560" integrity sha512-+S3zTvVt9yTntFrBpm7TQmQ3tzpCrnA1a/y+3cUHAc9ZR6aIjG0WNLR+Rj79QpJktY+VeW/TQtFlQ1bzsehI8g== @@ -13428,23 +12881,6 @@ sane@^2.0.0: optionalDependencies: fsevents "^1.2.3" -sane@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/sane/-/sane-3.1.0.tgz#995193b7dc1445ef1fe41ddfca2faf9f111854c6" - integrity sha512-G5GClRRxT1cELXfdAq7UKtUsv8q/ZC5k8lQGmjEm4HcAl3HzBy68iglyNCmw4+0tiXPCBZntslHlRhbnsSws+Q== - dependencies: - anymatch "^2.0.0" - capture-exit "^1.2.0" - exec-sh "^0.2.0" - execa "^1.0.0" - fb-watchman "^2.0.0" - micromatch "^3.1.4" - minimist "^1.1.1" - walker "~1.0.5" - watch "~0.18.0" - optionalDependencies: - fsevents "^1.2.3" - sanitize-filename@^1.6.1: version "1.6.1" resolved "https://registry.yarnpkg.com/sanitize-filename/-/sanitize-filename-1.6.1.tgz#612da1c96473fa02dccda92dcd5b4ab164a6772a" @@ -13795,11 +13231,6 @@ sisteransi@^0.1.1: resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-0.1.1.tgz#5431447d5f7d1675aac667ccd0b865a4994cb3ce" integrity sha512-PmGOd02bM9YO5ifxpw36nrNMBTptEtfRl4qUYl9SndkolplkrZZOW7PGHjrZL53QvMVj9nQ+TKqUnRsw4tJa4g== -sisteransi@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.0.tgz#77d9622ff909080f1c19e5f4a1df0c1b0a27b88c" - integrity sha512-N+z4pHB4AmUv0SjveWRd6q1Nj5w62m5jodv+GD8lvmbY/83T/rpbJGZOnK5T149OldDj4Db07BSv9xY4K6NTPQ== - slash@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" @@ -14397,7 +13828,7 @@ supports-color@^5.1.0, supports-color@^5.3.0, supports-color@^5.4.0, supports-co dependencies: has-flag "^3.0.0" -supports-color@^6.0.0, supports-color@^6.1.0: +supports-color@^6.1.0: version "6.1.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.1.0.tgz#0764abc69c63d5ac842dd4867e8d025e880df8f3" integrity sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ== @@ -14577,16 +14008,6 @@ test-exclude@^4.2.1: read-pkg-up "^1.0.1" require-main-filename "^1.0.1" -test-exclude@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-5.1.0.tgz#6ba6b25179d2d38724824661323b73e03c0c1de1" - integrity sha512-gwf0S2fFsANC55fSeSqpb8BYk6w3FDvwZxfNjeF6FRgvFa43r+7wRiA/Q0IxoRU37wB/LE8IQ4221BsNucTaCA== - dependencies: - arrify "^1.0.1" - minimatch "^3.0.4" - read-pkg-up "^4.0.0" - require-main-filename "^1.0.1" - text-extensions@^1.0.0: version "1.9.0" resolved "https://registry.yarnpkg.com/text-extensions/-/text-extensions-1.9.0.tgz#1853e45fee39c945ce6f6c36b2d659b5aabc2a26" @@ -15766,7 +15187,7 @@ wrappy@1: resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= -write-file-atomic@^2.0.0, write-file-atomic@^2.1.0, write-file-atomic@^2.3.0, write-file-atomic@^2.4.2: +write-file-atomic@^2.0.0, write-file-atomic@^2.1.0, write-file-atomic@^2.3.0: version "2.4.2" resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.4.2.tgz#a7181706dfba17855d221140a9c06e15fcdd87b9" integrity sha512-s0b6vB3xIVRLWywa6X9TOMA7k9zio0TMOsl9ZnDkliA/cfJlpHXAscj0gbHVJiTdIuAYpIyqS5GW91fqm6gG5g== @@ -15965,7 +15386,7 @@ yargs@^11.0.0: y18n "^3.2.1" yargs-parser "^9.0.2" -yargs@^12.0.1, yargs@^12.0.2, yargs@^12.0.4, yargs@^12.0.5: +yargs@^12.0.1, yargs@^12.0.4, yargs@^12.0.5: version "12.0.5" resolved "https://registry.yarnpkg.com/yargs/-/yargs-12.0.5.tgz#05f5997b609647b64f66b81e3b4b10a368e7ad13" integrity sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw== From ea705cdb2ab82e5da1af4b972447686c8f526956 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Wed, 6 Feb 2019 02:34:24 +1100 Subject: [PATCH 144/153] test: Update fether-react test command per Axel recommendation in PR #404 comments --- packages/fether-react/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/fether-react/package.json b/packages/fether-react/package.json index 3e58f5696..548b99293 100644 --- a/packages/fether-react/package.json +++ b/packages/fether-react/package.json @@ -31,7 +31,7 @@ "start": "npm-run-all -p start-*", "start-css": "npm run build-css -- --watch --recursive", "start-js": "cross-env SKIP_PREFLIGHT_CHECK=true BROWSER=none craco start --react-scripts ../../node_modules/react-scripts", - "test": "ln -sf ../../../node_modules/react-scripts node_modules/ && cross-env SKIP_PREFLIGHT_CHECK=true craco test" + "test": "ln -s ../../../node_modules/react-scripts node_modules/ && cross-env SKIP_PREFLIGHT_CHECK=true craco test; EXIT_CODE=$?; rm node_modules/react-scripts; exit $EXIT_CODE" }, "dependencies": { "@craco/craco": "^3.3.1", From b8ec52b74904862ef1f0e2467ae51633bafe403f Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Wed, 6 Feb 2019 03:12:03 +1100 Subject: [PATCH 145/153] chore: Revert to using older version of commander --- packages/fether-electron/package.json | 2 +- yarn.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/fether-electron/package.json b/packages/fether-electron/package.json index e244f56e7..ed8e6abc5 100644 --- a/packages/fether-electron/package.json +++ b/packages/fether-electron/package.json @@ -41,7 +41,7 @@ "dependencies": { "@parity/electron": "^4.0.0", "ansi-styles": "^3.2.1", - "commander": "^2.19.0", + "commander": "^2.15.1", "commander-remaining-args": "^1.2.0", "electron-positioner": "^4.1.0", "electron-settings": "^3.2.0", diff --git a/yarn.lock b/yarn.lock index 4e39e7090..7cd28facc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3859,7 +3859,7 @@ commander@2.17.x, commander@~2.17.1: resolved "https://registry.yarnpkg.com/commander/-/commander-2.17.1.tgz#bd77ab7de6de94205ceacc72f1716d29f20a77bf" integrity sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg== -commander@^2.11.0, commander@^2.19.0, commander@^2.8.1: +commander@^2.11.0, commander@^2.15.1, commander@^2.8.1: version "2.19.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a" integrity sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg== From 060d7d3e120c451a909f7d36c5f867ae28025211 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Wed, 6 Feb 2019 05:59:08 +1100 Subject: [PATCH 146/153] feat: Show frame on Linux too. Menu visible on load for non-macOS. Remove auto-hide menu --- README.md | 10 +++++----- .../src/main/app/methods/createWindow.js | 4 ++-- .../src/main/app/options/config/index.js | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 04c977923..33edbdd90 100644 --- a/README.md +++ b/README.md @@ -144,15 +144,14 @@ Taskbar mode is `true` by default. Taskbar mode is `true` by default. * Enabled `true` - * Fether window may be toggled minimise/restore by clicking the Fether tray icon to reveal a tooltip - that says "Click to toggle Fether window" and then clicking the tooltip. - * Fether window does not have a frame (i.e. no close/minimise icons) + * Fether window may be toggled minimise/restore by clicking the Fether tray icon to reveal a tooltip that says "Click to toggle Fether window" and then clicking the tooltip. + * Fether window may not have a frame (i.e. no close/minimise icons) if `frame: false` in packages/fether-electron/src/main/app/options/config/index.js * Disabled `false` * Fether window may be toggled open by clicking the Fether dock icon * Fether window has a frame (with close/minimise icons) * Always - * Fether menu is not shown in the tray by default. Show the Fether menu in the tray by clicking - the Fether window and then holding down the ALT key to reveal it. + * Fether menu may not be not shown in the tray by default depending on whether `setMenuBarVisibility` has been set. Show the Fether menu in the tray by clicking the Fether window and then holding down the ALT key to reveal it. + * Fether menu may be configured to automatically hide by setting `setAutoHideMenuBar` * Fether window position is saved upon move, minimising, and close so it is restored in the same position. ### Windows @@ -164,6 +163,7 @@ Taskbar mode is always `false` since the Fether menu does not appear without a f * Fether window has a frame (with close/minimise icons). * Always * Fether menu is shown in the Fether window by clicking the Fether window and then holding down the ALT key to reveal it. + * Fether menu may be configured to automatically hide by setting `setAutoHideMenuBar` * Fether tray icon does nothing * Fether window position is saved upon move, minimising, and close so it is restored in the same position. diff --git a/packages/fether-electron/src/main/app/methods/createWindow.js b/packages/fether-electron/src/main/app/methods/createWindow.js index f39eae548..9ecfcb111 100644 --- a/packages/fether-electron/src/main/app/methods/createWindow.js +++ b/packages/fether-electron/src/main/app/methods/createWindow.js @@ -25,8 +25,8 @@ function createWindow (fetherApp) { * If not shown by default then when shown it crops the bottom * of the window when menu open/close toggled. */ - fetherApp.win.setAutoHideMenuBar(true); // Pressing ALT shows menu bar - fetherApp.win.setMenuBarVisibility(false); + fetherApp.win.setAutoHideMenuBar(false); // Pressing ALT shows menu bar + fetherApp.win.setMenuBarVisibility(true); } // Opens file:///path/to/build/index.html in prod mode, or whatever is diff --git a/packages/fether-electron/src/main/app/options/config/index.js b/packages/fether-electron/src/main/app/options/config/index.js index 46b6a1715..b5ceedee3 100644 --- a/packages/fether-electron/src/main/app/options/config/index.js +++ b/packages/fether-electron/src/main/app/options/config/index.js @@ -41,7 +41,7 @@ if (process.platform === 'win32') { } const shouldUseDevTools = process.env.NODE_ENV !== 'production'; -const shouldUseFrame = process.platform === 'win32'; +const shouldUseFrame = process.platform !== 'darwin'; const windowPosition = process.platform === 'win32' ? 'trayBottomCenter' : 'trayCenter'; From 21b974c8ffd0299465814ad88ed991c0bc134416 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Wed, 6 Feb 2019 09:18:25 +1100 Subject: [PATCH 147/153] fix: Remove unnecessary leftover .apply --- packages/fether-electron/src/main/app/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/fether-electron/src/main/app/index.js b/packages/fether-electron/src/main/app/index.js index 906ad5d56..3ba137ef5 100644 --- a/packages/fether-electron/src/main/app/index.js +++ b/packages/fether-electron/src/main/app/index.js @@ -60,7 +60,7 @@ class FetherApp extends EventEmitter { this.loadTray(); this.setupDebug(); this.setupSecurity(); - this.setupLogger.apply(); + this.setupLogger(); this.setupParityEthereum(); this.setupGlobals(); this.setupMenu(); From 80accae3821785bdd52c2acfa852e46415e745e4 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Wed, 6 Feb 2019 09:20:22 +1100 Subject: [PATCH 148/153] refactor: Move menu logic into setupMenu method --- packages/fether-electron/src/main/app/menu/index.js | 3 +-- .../src/main/app/methods/createWindow.js | 10 ---------- .../fether-electron/src/main/app/methods/setupMenu.js | 10 +++++++++- 3 files changed, 10 insertions(+), 13 deletions(-) diff --git a/packages/fether-electron/src/main/app/menu/index.js b/packages/fether-electron/src/main/app/menu/index.js index d8e3e1b5d..b1ed5239b 100644 --- a/packages/fether-electron/src/main/app/menu/index.js +++ b/packages/fether-electron/src/main/app/menu/index.js @@ -14,9 +14,8 @@ const getMenu = () => { return Menu.getApplicationMenu(); }; -const addMenu = fetherAppWindow => { +const addMenu = () => { Menu.setApplicationMenu(menu); - fetherAppWindow.setAutoHideMenuBar(true); }; export { addMenu, getMenu }; diff --git a/packages/fether-electron/src/main/app/methods/createWindow.js b/packages/fether-electron/src/main/app/methods/createWindow.js index 9ecfcb111..45f2902ec 100644 --- a/packages/fether-electron/src/main/app/methods/createWindow.js +++ b/packages/fether-electron/src/main/app/methods/createWindow.js @@ -19,16 +19,6 @@ function createWindow (fetherApp) { fetherApp.win.setVisibleOnAllWorkspaces(true); } - if (process.platform !== 'darwin') { - /** - * Toggle the Fether menu bar in the frame on Windows or Linux. - * If not shown by default then when shown it crops the bottom - * of the window when menu open/close toggled. - */ - fetherApp.win.setAutoHideMenuBar(false); // Pressing ALT shows menu bar - fetherApp.win.setMenuBarVisibility(true); - } - // Opens file:///path/to/build/index.html in prod mode, or whatever is // passed to ELECTRON_START_URL fetherApp.win.loadURL(options.index); diff --git a/packages/fether-electron/src/main/app/methods/setupMenu.js b/packages/fether-electron/src/main/app/methods/setupMenu.js index f7675d297..f465e8131 100644 --- a/packages/fether-electron/src/main/app/methods/setupMenu.js +++ b/packages/fether-electron/src/main/app/methods/setupMenu.js @@ -10,7 +10,15 @@ const pino = Pino(); function setupMenu (fetherApp) { // Add Fether menu - addMenu(fetherApp.win); + addMenu(); + + /** + * Toggle the Fether menu bar in the frame. + * If not shown by default then when shown it may crop the bottom + * of the window when menu open/close toggled on Windows. + */ + fetherApp.win.setAutoHideMenuBar(false); // Pressing ALT shows menu bar + fetherApp.win.setMenuBarVisibility(true); pino.info('Finished configuring Electron menu'); } From 510b7e950e9c7c864284269efaf364c0957679cb Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Wed, 6 Feb 2019 13:20:08 +1100 Subject: [PATCH 149/153] fix: createWindow may be called from showWindow too, but we were not calling setupMenu there --- packages/fether-electron/src/main/app/index.js | 1 - packages/fether-electron/src/main/app/methods/createWindow.js | 4 +++- packages/fether-electron/src/main/app/options/config/index.js | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/fether-electron/src/main/app/index.js b/packages/fether-electron/src/main/app/index.js index 3ba137ef5..a87324271 100644 --- a/packages/fether-electron/src/main/app/index.js +++ b/packages/fether-electron/src/main/app/index.js @@ -63,7 +63,6 @@ class FetherApp extends EventEmitter { this.setupLogger(); this.setupParityEthereum(); this.setupGlobals(); - this.setupMenu(); this.updateProgress(0.8, undefined); this.showWindow(undefined); this.updateProgress(1.0, undefined); diff --git a/packages/fether-electron/src/main/app/methods/createWindow.js b/packages/fether-electron/src/main/app/methods/createWindow.js index 45f2902ec..ce8be85c7 100644 --- a/packages/fether-electron/src/main/app/methods/createWindow.js +++ b/packages/fether-electron/src/main/app/methods/createWindow.js @@ -8,7 +8,7 @@ import electron from 'electron'; const { BrowserWindow } = electron; function createWindow (fetherApp) { - const { options } = fetherApp; + const { options, setupMenu } = fetherApp; fetherApp.emit('create-app'); fetherApp.emit('create-window'); @@ -19,6 +19,8 @@ function createWindow (fetherApp) { fetherApp.win.setVisibleOnAllWorkspaces(true); } + setupMenu(fetherApp); + // Opens file:///path/to/build/index.html in prod mode, or whatever is // passed to ELECTRON_START_URL fetherApp.win.loadURL(options.index); diff --git a/packages/fether-electron/src/main/app/options/config/index.js b/packages/fether-electron/src/main/app/options/config/index.js index b5ceedee3..46b6a1715 100644 --- a/packages/fether-electron/src/main/app/options/config/index.js +++ b/packages/fether-electron/src/main/app/options/config/index.js @@ -41,7 +41,7 @@ if (process.platform === 'win32') { } const shouldUseDevTools = process.env.NODE_ENV !== 'production'; -const shouldUseFrame = process.platform !== 'darwin'; +const shouldUseFrame = process.platform === 'win32'; const windowPosition = process.platform === 'win32' ? 'trayBottomCenter' : 'trayCenter'; From 1210a11ca27aaf05a35e590a09faade375f38117 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Thu, 7 Feb 2019 06:03:15 +1100 Subject: [PATCH 150/153] fix: Allow dev tools in production --- packages/fether-electron/src/main/app/options/config/index.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/fether-electron/src/main/app/options/config/index.js b/packages/fether-electron/src/main/app/options/config/index.js index 46b6a1715..b4313bc20 100644 --- a/packages/fether-electron/src/main/app/options/config/index.js +++ b/packages/fether-electron/src/main/app/options/config/index.js @@ -40,7 +40,6 @@ if (process.platform === 'win32') { ); } -const shouldUseDevTools = process.env.NODE_ENV !== 'production'; const shouldUseFrame = process.platform === 'win32'; const windowPosition = @@ -61,7 +60,7 @@ const DEFAULT_OPTIONS = { showDockIcon: true, // macOS usage only tabbingIdentifier: 'parity', webPreferences: { - devTools: shouldUseDevTools, // Security + devTools: true, enableRemoteModule: true // Remote is required in fether-react parityStore.js }, width: 360, From 66f28207208dd2aaba5ac3834fe40f322f34a67d Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Thu, 7 Feb 2019 09:23:00 +1100 Subject: [PATCH 151/153] fix: Fix bug where Fether window closed and webrequest received when no fetherApp.win --- .../src/main/app/methods/setupRequestListeners.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/fether-electron/src/main/app/methods/setupRequestListeners.js b/packages/fether-electron/src/main/app/methods/setupRequestListeners.js index 1baa1509f..2d17e1cf9 100644 --- a/packages/fether-electron/src/main/app/methods/setupRequestListeners.js +++ b/packages/fether-electron/src/main/app/methods/setupRequestListeners.js @@ -23,7 +23,7 @@ function setupRequestListeners (fetherApp) { urls: ['ws://*/*', 'wss://*/*'] }, (details, callback) => { - if (!win) { + if (!win || !win.id) { // There might be a split second where the user closes the app, so // this.fether.window is null, but there is still a network request done. return; From f1d7792a0276433d8d618e494eef3c8e1fcdb1f2 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Thu, 7 Feb 2019 10:19:14 +1100 Subject: [PATCH 152/153] fix: Fix error when click tray icon to re-open Fether window after choosing Window > Close --- .../fether-electron/src/main/app/index.js | 23 ++++++++++++++----- .../src/main/app/methods/createWindow.js | 14 ++++++++++- .../src/main/app/methods/onTrayClick.js | 2 +- .../main/app/methods/setupRequestListeners.js | 8 +++---- .../src/main/app/methods/showWindow.js | 16 ++++++++++--- 5 files changed, 47 insertions(+), 16 deletions(-) diff --git a/packages/fether-electron/src/main/app/index.js b/packages/fether-electron/src/main/app/index.js index a87324271..5019f8426 100644 --- a/packages/fether-electron/src/main/app/index.js +++ b/packages/fether-electron/src/main/app/index.js @@ -47,27 +47,38 @@ class FetherApp extends EventEmitter { ); } + /** + * After the Fether instance and fetherApp.win has been created. + * If the user then chooses from the Fether Menu "Window > Close" + * it runs windowClear, which deletes fetherApp.win and associated + * listeners since the 'close' event also occurs when the user exits. + * If the user then clicks the tray icon to re-open the Fether window, + * it will run the onTrayClick method, which calls fetherApp.showWindow + * and if fetherApp.win does not exist, it runs showWindow and createWindow + * to restore create fetherApp.win again and associated listeners. However we + * do not need to run all the fetherApp methods again like we did on the + * when fetherApp.win was first created (i.e. createTray, loadTray, + * setupDebug, setupSecurity, setupLogger, setupParityEthereum, setupGlobals) + */ this.app = electronApp; this.options = options; - this.setupAppListeners(); this.createWindow(); this.updateProgress(0.4, undefined); - this.createPositioner(); - this.setupRequestListeners(); + + // These methods are called only once when Fether instance is created + // (i.e. not called again when the Fether window closed and re-opened) this.createTray(); - this.updateProgress(0.6, undefined); this.loadTray(); this.setupDebug(); this.setupSecurity(); this.setupLogger(); this.setupParityEthereum(); this.setupGlobals(); + this.updateProgress(0.8, undefined); this.showWindow(undefined); this.updateProgress(1.0, undefined); - this.setupWinListeners(); - this.setupWin32Listeners(); this.updateProgress(-1, 'after-create-app'); } diff --git a/packages/fether-electron/src/main/app/methods/createWindow.js b/packages/fether-electron/src/main/app/methods/createWindow.js index ce8be85c7..4b1a97445 100644 --- a/packages/fether-electron/src/main/app/methods/createWindow.js +++ b/packages/fether-electron/src/main/app/methods/createWindow.js @@ -8,9 +8,18 @@ import electron from 'electron'; const { BrowserWindow } = electron; function createWindow (fetherApp) { - const { options, setupMenu } = fetherApp; + const { + createPositioner, + options, + setupAppListeners, + setupMenu, + setupRequestListeners + } = fetherApp; fetherApp.emit('create-app'); + + setupAppListeners(fetherApp); + fetherApp.emit('create-window'); fetherApp.win = new BrowserWindow(options); @@ -25,6 +34,9 @@ function createWindow (fetherApp) { // passed to ELECTRON_START_URL fetherApp.win.loadURL(options.index); + createPositioner(fetherApp); + setupRequestListeners(fetherApp); + fetherApp.emit('after-create-window'); } diff --git a/packages/fether-electron/src/main/app/methods/onTrayClick.js b/packages/fether-electron/src/main/app/methods/onTrayClick.js index d7572dddf..0ede1a6ef 100644 --- a/packages/fether-electron/src/main/app/methods/onTrayClick.js +++ b/packages/fether-electron/src/main/app/methods/onTrayClick.js @@ -7,7 +7,7 @@ function onTrayClick (fetherApp, e, bounds) { const { cachedBounds, hideWindow, win } = fetherApp; const { altKey, ctrlKey, metaKey, shiftKey } = e; - if (altKey || shiftKey || ctrlKey || metaKey || (win && win.isVisible())) { + if ((win && win.isVisible()) || altKey || shiftKey || ctrlKey || metaKey) { return hideWindow(fetherApp); } diff --git a/packages/fether-electron/src/main/app/methods/setupRequestListeners.js b/packages/fether-electron/src/main/app/methods/setupRequestListeners.js index 2d17e1cf9..6fdb84f68 100644 --- a/packages/fether-electron/src/main/app/methods/setupRequestListeners.js +++ b/packages/fether-electron/src/main/app/methods/setupRequestListeners.js @@ -9,11 +9,9 @@ import messages from '../messages'; const { ipcMain, session } = electron; function setupRequestListeners (fetherApp) { - const { win } = fetherApp; - // Listen to messages from renderer process ipcMain.on('asynchronous-message', (...args) => { - return messages(win, ...args); + return messages(fetherApp.win, ...args); }); // WS calls have Origin `file://` by default, which is not trusted. @@ -23,12 +21,12 @@ function setupRequestListeners (fetherApp) { urls: ['ws://*/*', 'wss://*/*'] }, (details, callback) => { - if (!win || !win.id) { + if (!fetherApp.win || !fetherApp.win.id) { // There might be a split second where the user closes the app, so // this.fether.window is null, but there is still a network request done. return; } - details.requestHeaders.Origin = `parity://${win.id}.ui.parity`; + details.requestHeaders.Origin = `parity://${fetherApp.win.id}.ui.parity`; callback({ requestHeaders: details.requestHeaders }); // eslint-disable-line } ); diff --git a/packages/fether-electron/src/main/app/methods/showWindow.js b/packages/fether-electron/src/main/app/methods/showWindow.js index a9d248597..6849b1e25 100644 --- a/packages/fether-electron/src/main/app/methods/showWindow.js +++ b/packages/fether-electron/src/main/app/methods/showWindow.js @@ -12,7 +12,14 @@ import Pino from '../utils/pino'; const pino = Pino(); function showWindow (fetherApp, trayPos) { - const { calculateWinPosition, createWindow, fixWinPosition, win } = fetherApp; + const { + calculateWinPosition, + createWindow, + fixWinPosition, + setupWinListeners, + setupWin32Listeners, + win + } = fetherApp; if (!win) { createWindow(fetherApp); @@ -65,8 +72,11 @@ function showWindow (fetherApp, trayPos) { (loadedWindowPosition && loadedWindowPosition.y) || calculatedWinPosition.y; - win.setPosition(x, y); - win.show(); + fetherApp.win.setPosition(x, y); + fetherApp.win.show(); + + setupWinListeners(fetherApp); + setupWin32Listeners(fetherApp); fetherApp.emit('after-show-window'); } From b4318dae4c15a4e292aef60aee1ccc8ee6cc5545 Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Fri, 8 Feb 2019 04:56:32 +1100 Subject: [PATCH 153/153] fix: Resize Fether window on Windows with additional height upon load to fit the Feedback button since the menu is shown --- packages/fether-electron/src/main/app/messages/index.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/packages/fether-electron/src/main/app/messages/index.js b/packages/fether-electron/src/main/app/messages/index.js index 8c0007ee0..b671ebf97 100644 --- a/packages/fether-electron/src/main/app/messages/index.js +++ b/packages/fether-electron/src/main/app/messages/index.js @@ -21,7 +21,14 @@ export default async (fetherAppWindow, event, action, ...args) => { case 'app-resize': { const [width] = fetherAppWindow.getContentSize(); const newHeight = args[0]; - fetherAppWindow.setContentSize(width, Math.round(newHeight) + 2); + const feedbackButtonHeight = 20; + const resizeHeight = newHeight + 2; + const height = + process.platform === 'win32' && fetherAppWindow.isMenuBarVisible() + ? resizeHeight + feedbackButtonHeight + : resizeHeight; + + fetherAppWindow.setContentSize(width, height); break; } case 'check-clock-sync': {