diff options
author | Stefan Malzner <stefan@adlk.io> | 2019-02-11 12:48:04 +0100 |
---|---|---|
committer | Stefan Malzner <stefan@adlk.io> | 2019-02-11 12:48:04 +0100 |
commit | 3262ab46335ba42fe521c0b3f6165b87b990dbdd (patch) | |
tree | b88bcbf50e7ca8d3723eeb7b4765fbaf3acec054 | |
parent | fix(App): Ignore network changed error (diff) | |
download | ferdium-app-3262ab46335ba42fe521c0b3f6165b87b990dbdd.tar.gz ferdium-app-3262ab46335ba42fe521c0b3f6165b87b990dbdd.tar.zst ferdium-app-3262ab46335ba42fe521c0b3f6165b87b990dbdd.zip |
Add option to login via deep link
-rw-r--r-- | src/index.js | 72 | ||||
-rw-r--r-- | src/stores/AppStore.js | 1 | ||||
-rw-r--r-- | src/stores/UserStore.js | 27 |
3 files changed, 56 insertions, 44 deletions
diff --git a/src/index.js b/src/index.js index f34df8c17..8d3b04845 100644 --- a/src/index.js +++ b/src/index.js | |||
@@ -4,7 +4,6 @@ import { | |||
4 | shell, | 4 | shell, |
5 | ipcMain, | 5 | ipcMain, |
6 | } from 'electron'; | 6 | } from 'electron'; |
7 | |||
8 | import fs from 'fs-extra'; | 7 | import fs from 'fs-extra'; |
9 | import path from 'path'; | 8 | import path from 'path'; |
10 | import windowStateKeeper from 'electron-window-state'; | 9 | import windowStateKeeper from 'electron-window-state'; |
@@ -44,6 +43,17 @@ const debug = require('debug')('Franz:App'); | |||
44 | let mainWindow; | 43 | let mainWindow; |
45 | let willQuitApp = false; | 44 | let willQuitApp = false; |
46 | 45 | ||
46 | // Register methods to be called once the window has been loaded. | ||
47 | let onDidLoadFns = []; | ||
48 | |||
49 | function onDidLoad(fn) { | ||
50 | if (onDidLoadFns) { | ||
51 | onDidLoadFns.push(fn); | ||
52 | } else if (mainWindow) { | ||
53 | fn(mainWindow); | ||
54 | } | ||
55 | } | ||
56 | |||
47 | // Ensure that the recipe directory exists | 57 | // Ensure that the recipe directory exists |
48 | fs.emptyDirSync(path.join(app.getPath('userData'), 'recipes', 'temp')); | 58 | fs.emptyDirSync(path.join(app.getPath('userData'), 'recipes', 'temp')); |
49 | fs.ensureFileSync(path.join(app.getPath('userData'), 'window-state.json')); | 59 | fs.ensureFileSync(path.join(app.getPath('userData'), 'window-state.json')); |
@@ -83,40 +93,7 @@ if (!gotTheLock) { | |||
83 | } | 93 | } |
84 | } | 94 | } |
85 | }); | 95 | }); |
86 | |||
87 | // Create myWindow, load the rest of the app, etc... | ||
88 | app.on('ready', () => { | ||
89 | }); | ||
90 | } | 96 | } |
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 | 97 | ||
121 | // Fix Unity indicator issue | 98 | // Fix Unity indicator issue |
122 | // https://github.com/electron/electron/issues/9046 | 99 | // https://github.com/electron/electron/issues/9046 |
@@ -166,6 +143,14 @@ const createWindow = () => { | |||
166 | }, | 143 | }, |
167 | }); | 144 | }); |
168 | 145 | ||
146 | mainWindow.webContents.on('did-finish-load', () => { | ||
147 | const fns = onDidLoadFns; | ||
148 | onDidLoadFns = null; | ||
149 | for (const fn of fns) { | ||
150 | fn(mainWindow); | ||
151 | } | ||
152 | }); | ||
153 | |||
169 | // Initialize System Tray | 154 | // Initialize System Tray |
170 | const trayIcon = new Tray(); | 155 | const trayIcon = new Tray(); |
171 | 156 | ||
@@ -259,6 +244,13 @@ const createWindow = () => { | |||
259 | // initialization and is ready to create browser windows. | 244 | // initialization and is ready to create browser windows. |
260 | // Some APIs can only be used after this event occurs. | 245 | // Some APIs can only be used after this event occurs. |
261 | app.on('ready', () => { | 246 | app.on('ready', () => { |
247 | // Register App URL | ||
248 | app.setAsDefaultProtocolClient('franz'); | ||
249 | |||
250 | if (isDevMode) { | ||
251 | app.setAsDefaultProtocolClient('franz-dev'); | ||
252 | } | ||
253 | |||
262 | if (process.platform === 'win32') { | 254 | if (process.platform === 'win32') { |
263 | app.setUserTasks([{ | 255 | app.setUserTasks([{ |
264 | program: process.execPath, | 256 | program: process.execPath, |
@@ -336,13 +328,13 @@ app.on('activate', () => { | |||
336 | }); | 328 | }); |
337 | 329 | ||
338 | app.on('will-finish-launching', () => { | 330 | app.on('will-finish-launching', () => { |
339 | // Protocol handler for osx | 331 | // Protocol handler for macOS |
340 | app.on('open-url', (event, url) => { | 332 | app.on('open-url', (event, url) => { |
341 | event.preventDefault(); | 333 | event.preventDefault(); |
342 | console.log(`open-url event: ${url}`); | 334 | |
343 | handleDeepLink(mainWindow, url); | 335 | onDidLoad((window) => { |
336 | debug('open-url event', url); | ||
337 | handleDeepLink(window, url); | ||
338 | }); | ||
344 | }); | 339 | }); |
345 | }); | 340 | }); |
346 | |||
347 | // Register App URL | ||
348 | app.setAsDefaultProtocolClient('franz'); | ||
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 |