aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--package-lock.json49
-rw-r--r--package.json5
-rw-r--r--src/environment.js6
-rw-r--r--src/index.js87
-rw-r--r--src/models/Service.js2
-rw-r--r--src/stores/AppStore.js1
-rw-r--r--src/stores/UserStore.js27
7 files changed, 90 insertions, 87 deletions
diff --git a/package-lock.json b/package-lock.json
index f339aaf51..b665aef82 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1203,9 +1203,9 @@
1203 } 1203 }
1204 }, 1204 },
1205 "@types/node": { 1205 "@types/node": {
1206 "version": "10.12.19", 1206 "version": "10.12.23",
1207 "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.19.tgz", 1207 "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.23.tgz",
1208 "integrity": "sha512-2NVovndCjJQj6fUUn9jCgpP4WSqr+u1SoUZMZyJkhGeBFsm6dE46l31S7lPUYt9uQ28XI+ibrJA1f5XyH5HNtA==", 1208 "integrity": "sha512-EKhb5NveQ3NlW5EV7B0VRtDKwUfVey8LuJRl9pp5iW0se87/ZqLjG0PMf2MCzPXAJYWZN5Ltg7pHIAf9/Dm1tQ==",
1209 "dev": true 1209 "dev": true
1210 }, 1210 },
1211 "JSONStream": { 1211 "JSONStream": {
@@ -3977,11 +3977,6 @@
3977 "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", 3977 "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz",
3978 "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=" 3978 "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU="
3979 }, 3979 },
3980 "deep-equal": {
3981 "version": "1.0.1",
3982 "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz",
3983 "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU="
3984 },
3985 "deep-extend": { 3980 "deep-extend": {
3986 "version": "0.6.0", 3981 "version": "0.6.0",
3987 "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", 3982 "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
@@ -4289,9 +4284,9 @@
4289 "dev": true 4284 "dev": true
4290 }, 4285 },
4291 "electron": { 4286 "electron": {
4292 "version": "4.0.2", 4287 "version": "4.0.4",
4293 "resolved": "https://registry.npmjs.org/electron/-/electron-4.0.2.tgz", 4288 "resolved": "https://registry.npmjs.org/electron/-/electron-4.0.4.tgz",
4294 "integrity": "sha512-H0pmSvOVuC+Mq/+cYNXbCDBmqq5d1xYUVdBOjqGJuwuwJeP7qDHF35JA3cq+ARzq/CbwlXq98zdW6i6+x3U24g==", 4289 "integrity": "sha512-zG5VtLrmPfmw1fXY/3BEtRZk7OZ7djQhweZ6rW+R5NeF6s8RTz/AwTGtLoBo4z8wmJ5QTy0Y941FZw4pe5YlpA==",
4295 "dev": true, 4290 "dev": true,
4296 "requires": { 4291 "requires": {
4297 "@types/node": "^10.12.18", 4292 "@types/node": "^10.12.18",
@@ -4620,6 +4615,11 @@
4620 "unixify": "1.0.0" 4615 "unixify": "1.0.0"
4621 } 4616 }
4622 }, 4617 },
4618 "electron-is-dev": {
4619 "version": "1.0.1",
4620 "resolved": "https://registry.npmjs.org/electron-is-dev/-/electron-is-dev-1.0.1.tgz",
4621 "integrity": "sha512-iwM3EotA9HTXqMGpQRkR/kT8OZqBbdfHTnlwcxsjSLYqY8svvsq0MuujsWCn3/vtgRmDv/PC/gKUUpoZvi5C1w=="
4622 },
4623 "electron-osx-sign": { 4623 "electron-osx-sign": {
4624 "version": "0.4.11", 4624 "version": "0.4.11",
4625 "resolved": "https://registry.npmjs.org/electron-osx-sign/-/electron-osx-sign-0.4.11.tgz", 4625 "resolved": "https://registry.npmjs.org/electron-osx-sign/-/electron-osx-sign-0.4.11.tgz",
@@ -4752,23 +4752,12 @@
4752 } 4752 }
4753 }, 4753 },
4754 "electron-window-state": { 4754 "electron-window-state": {
4755 "version": "4.1.1", 4755 "version": "5.0.3",
4756 "resolved": "https://registry.npmjs.org/electron-window-state/-/electron-window-state-4.1.1.tgz", 4756 "resolved": "https://registry.npmjs.org/electron-window-state/-/electron-window-state-5.0.3.tgz",
4757 "integrity": "sha1-azT9wxs4UU3+yLfI97XUrdtnYy0=", 4757 "integrity": "sha512-1mNTwCfkolXl3kMf50yW3vE2lZj0y92P/HYWFBrb+v2S/pCka5mdwN3cagKm458A7NjndSwijynXgcLWRodsVg==",
4758 "requires": { 4758 "requires": {
4759 "deep-equal": "^1.0.1", 4759 "jsonfile": "^4.0.0",
4760 "jsonfile": "^2.2.3",
4761 "mkdirp": "^0.5.1" 4760 "mkdirp": "^0.5.1"
4762 },
4763 "dependencies": {
4764 "jsonfile": {
4765 "version": "2.4.0",
4766 "resolved": "http://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz",
4767 "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=",
4768 "requires": {
4769 "graceful-fs": "^4.1.6"
4770 }
4771 }
4772 } 4761 }
4773 }, 4762 },
4774 "email-addresses": { 4763 "email-addresses": {
@@ -13324,7 +13313,7 @@
13324 "dependencies": { 13313 "dependencies": {
13325 "pretty-bytes": { 13314 "pretty-bytes": {
13326 "version": "1.0.4", 13315 "version": "1.0.4",
13327 "resolved": "http://registry.npmjs.org/pretty-bytes/-/pretty-bytes-1.0.4.tgz", 13316 "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-1.0.4.tgz",
13328 "integrity": "sha1-CiLoIQYJrTVUL4yNXSFZr/B1HIQ=", 13317 "integrity": "sha1-CiLoIQYJrTVUL4yNXSFZr/B1HIQ=",
13329 "dev": true, 13318 "dev": true,
13330 "requires": { 13319 "requires": {
@@ -14035,7 +14024,7 @@
14035 }, 14024 },
14036 "readable-stream": { 14025 "readable-stream": {
14037 "version": "1.1.14", 14026 "version": "1.1.14",
14038 "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", 14027 "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
14039 "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", 14028 "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
14040 "dev": true, 14029 "dev": true,
14041 "requires": { 14030 "requires": {
@@ -14047,13 +14036,13 @@
14047 }, 14036 },
14048 "string_decoder": { 14037 "string_decoder": {
14049 "version": "0.10.31", 14038 "version": "0.10.31",
14050 "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", 14039 "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
14051 "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", 14040 "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=",
14052 "dev": true 14041 "dev": true
14053 }, 14042 },
14054 "through2": { 14043 "through2": {
14055 "version": "0.2.3", 14044 "version": "0.2.3",
14056 "resolved": "http://registry.npmjs.org/through2/-/through2-0.2.3.tgz", 14045 "resolved": "https://registry.npmjs.org/through2/-/through2-0.2.3.tgz",
14057 "integrity": "sha1-6zKE2k6jEbbMis42U3SKUqvyWj8=", 14046 "integrity": "sha1-6zKE2k6jEbbMis42U3SKUqvyWj8=",
14058 "dev": true, 14047 "dev": true,
14059 "requires": { 14048 "requires": {
diff --git a/package.json b/package.json
index a3788a51d..17e1c2bc9 100644
--- a/package.json
+++ b/package.json
@@ -39,9 +39,10 @@
39 "electron-dl": "1.12.0", 39 "electron-dl": "1.12.0",
40 "electron-fetch": "1.3.0", 40 "electron-fetch": "1.3.0",
41 "electron-hunspell": "0.1.1", 41 "electron-hunspell": "0.1.1",
42 "electron-is-dev": "1.0.1",
42 "electron-react-titlebar": "0.8.1", 43 "electron-react-titlebar": "0.8.1",
43 "electron-updater": "4.0.6", 44 "electron-updater": "4.0.6",
44 "electron-window-state": "^4.1.0", 45 "electron-window-state": "5.0.3",
45 "fs-extra": "7.0.1", 46 "fs-extra": "7.0.1",
46 "gulp-cli": "1.2.2", 47 "gulp-cli": "1.2.2",
47 "hex-to-rgba": "1.0.2", 48 "hex-to-rgba": "1.0.2",
@@ -99,7 +100,7 @@
99 "cross-env": "^5.0.5", 100 "cross-env": "^5.0.5",
100 "cz-conventional-changelog": "2.1.0", 101 "cz-conventional-changelog": "2.1.0",
101 "dotenv": "^4.0.0", 102 "dotenv": "^4.0.0",
102 "electron": "4.0.2", 103 "electron": "4.0.4",
103 "electron-builder": "20.38.4", 104 "electron-builder": "20.38.4",
104 "electron-rebuild": "^1.6.0", 105 "electron-rebuild": "^1.6.0",
105 "eslint": "5.10.0", 106 "eslint": "5.10.0",
diff --git a/src/environment.js b/src/environment.js
index e1762129b..73b1c7ab2 100644
--- a/src/environment.js
+++ b/src/environment.js
@@ -1,10 +1,12 @@
1import isDev from 'electron-is-dev';
2
1import { LIVE_API, DEV_API, LOCAL_API } from './config'; 3import { LIVE_API, DEV_API, LOCAL_API } from './config';
2 4
3export const isDevMode = Boolean(process.execPath.match(/[\\/]electron/)); 5export const isDevMode = isDev;
4export const useLiveAPI = process.env.LIVE_API; 6export const useLiveAPI = process.env.LIVE_API;
5export const useLocalAPI = process.env.LOCAL_API; 7export const useLocalAPI = process.env.LOCAL_API;
6 8
7let platform = process.platform; 9let { platform } = process;
8if (process.env.OS_PLATFORM) { 10if (process.env.OS_PLATFORM) {
9 platform = process.env.OS_PLATFORM; 11 platform = process.env.OS_PLATFORM;
10} 12}
diff --git a/src/index.js b/src/index.js
index f34df8c17..494fa97f1 100644
--- a/src/index.js
+++ b/src/index.js
@@ -4,25 +4,23 @@ import {
4 shell, 4 shell,
5 ipcMain, 5 ipcMain,
6} from 'electron'; 6} from 'electron';
7 7import isDevMode from 'electron-is-dev';
8import fs from 'fs-extra'; 8import fs from 'fs-extra';
9import path from 'path'; 9import path from 'path';
10import windowStateKeeper from 'electron-window-state'; 10import windowStateKeeper from 'electron-window-state';
11 11
12// Set app directory before loading user modules
13if (isDevMode) {
14 app.setPath('userData', path.join(app.getPath('appData'), 'FranzDev'));
15}
16
17/* eslint-disable import/first */
12import { 18import {
13 isDevMode,
14 isMac, 19 isMac,
15 isWindows, 20 isWindows,
16 isLinux, 21 isLinux,
17} from './environment'; 22} from './environment';
18
19import { mainIpcHandler as basicAuthHandler } from './features/basicAuth'; 23import { mainIpcHandler as basicAuthHandler } from './features/basicAuth';
20
21// DEV MODE: Save user data into FranzDev
22if (isDevMode) {
23 app.setPath('userData', path.join(app.getPath('appData'), 'FranzDev'));
24}
25/* eslint-disable import/first */
26import ipcApi from './electron/ipc-api'; 24import ipcApi from './electron/ipc-api';
27import Tray from './lib/Tray'; 25import Tray from './lib/Tray';
28import Settings from './electron/Settings'; 26import Settings from './electron/Settings';
@@ -44,6 +42,17 @@ const debug = require('debug')('Franz:App');
44let mainWindow; 42let mainWindow;
45let willQuitApp = false; 43let willQuitApp = false;
46 44
45// Register methods to be called once the window has been loaded.
46let onDidLoadFns = [];
47
48function onDidLoad(fn) {
49 if (onDidLoadFns) {
50 onDidLoadFns.push(fn);
51 } else if (mainWindow) {
52 fn(mainWindow);
53 }
54}
55
47// Ensure that the recipe directory exists 56// Ensure that the recipe directory exists
48fs.emptyDirSync(path.join(app.getPath('userData'), 'recipes', 'temp')); 57fs.emptyDirSync(path.join(app.getPath('userData'), 'recipes', 'temp'));
49fs.ensureFileSync(path.join(app.getPath('userData'), 'window-state.json')); 58fs.ensureFileSync(path.join(app.getPath('userData'), 'window-state.json'));
@@ -83,40 +92,7 @@ if (!gotTheLock) {
83 } 92 }
84 } 93 }
85 }); 94 });
86
87 // Create myWindow, load the rest of the app, etc...
88 app.on('ready', () => {
89 });
90} 95}
91// const isSecondInstance = app.makeSingleInstance((argv) => {
92// if (mainWindow) {
93// if (mainWindow.isMinimized()) mainWindow.restore();
94// mainWindow.focus();
95
96// if (process.platform === 'win32') {
97// // Keep only command line / deep linked arguments
98// const url = argv.slice(1);
99
100// if (url) {
101// handleDeepLink(mainWindow, url.toString());
102// }
103// }
104// }
105
106// if (argv.includes('--reset-window')) {
107// // Needs to be delayed to not interfere with mainWindow.restore();
108// setTimeout(() => {
109// debug('Resetting windows via Task');
110// mainWindow.setPosition(DEFAULT_WINDOW_OPTIONS.x + 100, DEFAULT_WINDOW_OPTIONS.y + 100);
111// mainWindow.setSize(DEFAULT_WINDOW_OPTIONS.width, DEFAULT_WINDOW_OPTIONS.height);
112// }, 1);
113// }
114// });
115
116// if (isSecondInstance) {
117// console.log('An instance of Franz is already running. Exiting...');
118// app.exit();
119// }
120 96
121// Fix Unity indicator issue 97// Fix Unity indicator issue
122// https://github.com/electron/electron/issues/9046 98// https://github.com/electron/electron/issues/9046
@@ -166,6 +142,14 @@ const createWindow = () => {
166 }, 142 },
167 }); 143 });
168 144
145 mainWindow.webContents.on('did-finish-load', () => {
146 const fns = onDidLoadFns;
147 onDidLoadFns = null;
148 for (const fn of fns) {
149 fn(mainWindow);
150 }
151 });
152
169 // Initialize System Tray 153 // Initialize System Tray
170 const trayIcon = new Tray(); 154 const trayIcon = new Tray();
171 155
@@ -259,6 +243,13 @@ const createWindow = () => {
259// initialization and is ready to create browser windows. 243// initialization and is ready to create browser windows.
260// Some APIs can only be used after this event occurs. 244// Some APIs can only be used after this event occurs.
261app.on('ready', () => { 245app.on('ready', () => {
246 // Register App URL
247 app.setAsDefaultProtocolClient('franz');
248
249 if (isDevMode) {
250 app.setAsDefaultProtocolClient('franz-dev');
251 }
252
262 if (process.platform === 'win32') { 253 if (process.platform === 'win32') {
263 app.setUserTasks([{ 254 app.setUserTasks([{
264 program: process.execPath, 255 program: process.execPath,
@@ -336,13 +327,13 @@ app.on('activate', () => {
336}); 327});
337 328
338app.on('will-finish-launching', () => { 329app.on('will-finish-launching', () => {
339 // Protocol handler for osx 330 // Protocol handler for macOS
340 app.on('open-url', (event, url) => { 331 app.on('open-url', (event, url) => {
341 event.preventDefault(); 332 event.preventDefault();
342 console.log(`open-url event: ${url}`); 333
343 handleDeepLink(mainWindow, url); 334 onDidLoad((window) => {
335 debug('open-url event', url);
336 handleDeepLink(window, url);
337 });
344 }); 338 });
345}); 339});
346
347// Register App URL
348app.setAsDefaultProtocolClient('franz');
diff --git a/src/models/Service.js b/src/models/Service.js
index eee8df8ca..8a2a8d3d8 100644
--- a/src/models/Service.js
+++ b/src/models/Service.js
@@ -202,7 +202,7 @@ export default class Service {
202 202
203 this.webview.addEventListener('did-fail-load', (event) => { 203 this.webview.addEventListener('did-fail-load', (event) => {
204 debug('Service failed to load', this.name, event); 204 debug('Service failed to load', this.name, event);
205 if (event.isMainFrame && event.errorCode !== -27 && event.errorCode !== -3) { 205 if (event.isMainFrame && event.errorCode !== -21 && event.errorCode !== -3) {
206 this.isError = true; 206 this.isError = true;
207 this.errorMessage = event.errorDescription; 207 this.errorMessage = event.errorDescription;
208 this.isLoading = false; 208 this.isLoading = false;
diff --git a/src/stores/AppStore.js b/src/stores/AppStore.js
index dd4642d70..f8030a9ac 100644
--- a/src/stores/AppStore.js
+++ b/src/stores/AppStore.js
@@ -143,6 +143,7 @@ export default class AppStore extends Store {
143 143
144 // Handle deep linking (franz://) 144 // Handle deep linking (franz://)
145 ipcRenderer.on('navigateFromDeepLink', (event, data) => { 145 ipcRenderer.on('navigateFromDeepLink', (event, data) => {
146 debug('Navigate from deep link', data);
146 const { url } = data; 147 const { url } = data;
147 if (!url) return; 148 if (!url) return;
148 149
diff --git a/src/stores/UserStore.js b/src/stores/UserStore.js
index 7addb5760..ad714a62d 100644
--- a/src/stores/UserStore.js
+++ b/src/stores/UserStore.js
@@ -129,10 +129,6 @@ export default class UserStore extends Store {
129 return Boolean(localStorage.getItem('authToken')); 129 return Boolean(localStorage.getItem('authToken'));
130 } 130 }
131 131
132 // @computed get isTokenValid() {
133 // return this.authToken !== null && moment(this.tokenExpiry).isAfter(moment());
134 // }
135
136 @computed get isTokenExpired() { 132 @computed get isTokenExpired() {
137 if (!this.authToken) return false; 133 if (!this.authToken) return false;
138 134
@@ -160,6 +156,14 @@ export default class UserStore extends Store {
160 gaEvent('User', 'login'); 156 gaEvent('User', 'login');
161 } 157 }
162 158
159 @action _tokenLogin(authToken) {
160 this._setUserData(authToken);
161
162 this.stores.router.push('/');
163
164 gaEvent('User', 'tokenLogin');
165 }
166
163 @action async _signup({ 167 @action async _signup({
164 firstname, lastname, email, password, accountType, company, 168 firstname, lastname, email, password, accountType, company,
165 }) { 169 }) {
@@ -206,6 +210,8 @@ export default class UserStore extends Store {
206 } 210 }
207 211
208 @action async _update({ userData }) { 212 @action async _update({ userData }) {
213 if (!this.isLoggedIn) return;
214
209 const response = await this.updateUserInfoRequest.execute(userData)._promise; 215 const response = await this.updateUserInfoRequest.execute(userData)._promise;
210 216
211 this.getUserInfoRequest.patch(() => response.data); 217 this.getUserInfoRequest.patch(() => response.data);
@@ -222,6 +228,7 @@ export default class UserStore extends Store {
222 // workaround mobx issue 228 // workaround mobx issue
223 localStorage.removeItem('authToken'); 229 localStorage.removeItem('authToken');
224 window.localStorage.removeItem('authToken'); 230 window.localStorage.removeItem('authToken');
231
225 this.getUserInfoRequest.invalidate().reset(); 232 this.getUserInfoRequest.invalidate().reset();
226 this.authToken = null; 233 this.authToken = null;
227 } 234 }
@@ -262,6 +269,18 @@ export default class UserStore extends Store {
262 const { router } = this.stores; 269 const { router } = this.stores;
263 const currentRoute = router.location.pathname; 270 const currentRoute = router.location.pathname;
264 if (!this.isLoggedIn 271 if (!this.isLoggedIn
272 && currentRoute.includes('token=')) {
273 router.push(this.WELCOME_ROUTE);
274 const token = currentRoute.split('=')[1];
275
276 const data = this._parseToken(token);
277 if (data) {
278 // Give this some time to sink
279 setTimeout(() => {
280 this._tokenLogin(token);
281 }, 100);
282 }
283 } else if (!this.isLoggedIn
265 && !currentRoute.includes(this.BASE_ROUTE)) { 284 && !currentRoute.includes(this.BASE_ROUTE)) {
266 router.push(this.WELCOME_ROUTE); 285 router.push(this.WELCOME_ROUTE);
267 } else if (this.isLoggedIn 286 } else if (this.isLoggedIn