diff options
author | Stefan Malzner <stefan@adlk.io> | 2019-01-05 21:12:42 +0100 |
---|---|---|
committer | Stefan Malzner <stefan@adlk.io> | 2019-01-05 21:12:42 +0100 |
commit | 904eb333103e0d3b9f6c23ca49d76d403f43ded3 (patch) | |
tree | 8f3367d306fb4d9d9f82e6bc5dd502853e63cbca /src | |
parent | Add lerna instructions (diff) | |
download | ferdium-app-904eb333103e0d3b9f6c23ca49d76d403f43ded3.tar.gz ferdium-app-904eb333103e0d3b9f6c23ca49d76d403f43ded3.tar.zst ferdium-app-904eb333103e0d3b9f6c23ca49d76d403f43ded3.zip |
Merge
Diffstat (limited to 'src')
-rw-r--r-- | src/helpers/password-helpers.js | 4 | ||||
-rw-r--r-- | src/index.js | 80 | ||||
-rw-r--r-- | src/models/Service.js | 22 | ||||
-rw-r--r-- | src/stores/ServicesStore.js | 16 | ||||
-rw-r--r-- | src/stores/UIStore.js | 7 | ||||
-rw-r--r-- | src/webview/recipe.js | 17 |
6 files changed, 99 insertions, 47 deletions
diff --git a/src/helpers/password-helpers.js b/src/helpers/password-helpers.js index 7aacaa4d0..cf461e4f7 100644 --- a/src/helpers/password-helpers.js +++ b/src/helpers/password-helpers.js | |||
@@ -1,7 +1,7 @@ | |||
1 | import { SHA256 } from 'jshashes'; | 1 | import crypto from 'crypto'; |
2 | 2 | ||
3 | export function hash(password) { | 3 | export function hash(password) { |
4 | return new SHA256().b64(password); | 4 | return crypto.createHash('sha256').update(password).digest('base64'); |
5 | } | 5 | } |
6 | 6 | ||
7 | export function scorePassword(password) { | 7 | export function scorePassword(password) { |
diff --git a/src/index.js b/src/index.js index 830166dcf..75da4ff88 100644 --- a/src/index.js +++ b/src/index.js | |||
@@ -46,35 +46,69 @@ if (isWindows) { | |||
46 | } | 46 | } |
47 | 47 | ||
48 | // Force single window | 48 | // Force single window |
49 | const isSecondInstance = app.makeSingleInstance((argv) => { | 49 | const gotTheLock = app.requestSingleInstanceLock(); |
50 | if (mainWindow) { | 50 | if (!gotTheLock) { |
51 | if (mainWindow.isMinimized()) mainWindow.restore(); | 51 | app.quit(); |
52 | mainWindow.focus(); | 52 | } else { |
53 | app.on('second-instance', (event, argv) => { | ||
54 | // Someone tried to run a second instance, we should focus our window. | ||
55 | if (mainWindow) { | ||
56 | if (mainWindow.isMinimized()) mainWindow.restore(); | ||
57 | mainWindow.focus(); | ||
53 | 58 | ||
54 | if (process.platform === 'win32') { | 59 | if (isWindows) { |
55 | // Keep only command line / deep linked arguments | 60 | // Keep only command line / deep linked arguments |
56 | const url = argv.slice(1); | 61 | const url = argv.slice(1); |
57 | 62 | ||
58 | if (url) { | 63 | if (url) { |
59 | handleDeepLink(mainWindow, url.toString()); | 64 | handleDeepLink(mainWindow, url.toString()); |
65 | } | ||
60 | } | 66 | } |
61 | } | ||
62 | } | ||
63 | 67 | ||
64 | if (argv.includes('--reset-window')) { | 68 | if (argv.includes('--reset-window')) { |
65 | // Needs to be delayed to not interfere with mainWindow.restore(); | 69 | // Needs to be delayed to not interfere with mainWindow.restore(); |
66 | setTimeout(() => { | 70 | setTimeout(() => { |
67 | debug('Resetting windows via Task'); | 71 | debug('Resetting windows via Task'); |
68 | mainWindow.setPosition(DEFAULT_WINDOW_OPTIONS.x + 100, DEFAULT_WINDOW_OPTIONS.y + 100); | 72 | mainWindow.setPosition(DEFAULT_WINDOW_OPTIONS.x + 100, DEFAULT_WINDOW_OPTIONS.y + 100); |
69 | mainWindow.setSize(DEFAULT_WINDOW_OPTIONS.width, DEFAULT_WINDOW_OPTIONS.height); | 73 | mainWindow.setSize(DEFAULT_WINDOW_OPTIONS.width, DEFAULT_WINDOW_OPTIONS.height); |
70 | }, 1); | 74 | }, 1); |
71 | } | 75 | } |
72 | }); | 76 | } |
77 | }); | ||
73 | 78 | ||
74 | if (isSecondInstance) { | 79 | // Create myWindow, load the rest of the app, etc... |
75 | console.log('An instance of Franz is already running. Exiting...'); | 80 | app.on('ready', () => { |
76 | app.exit(); | 81 | }); |
77 | } | 82 | } |
83 | // const isSecondInstance = app.makeSingleInstance((argv) => { | ||
84 | // if (mainWindow) { | ||
85 | // if (mainWindow.isMinimized()) mainWindow.restore(); | ||
86 | // mainWindow.focus(); | ||
87 | |||
88 | // if (process.platform === 'win32') { | ||
89 | // // Keep only command line / deep linked arguments | ||
90 | // const url = argv.slice(1); | ||
91 | |||
92 | // if (url) { | ||
93 | // handleDeepLink(mainWindow, url.toString()); | ||
94 | // } | ||
95 | // } | ||
96 | // } | ||
97 | |||
98 | // if (argv.includes('--reset-window')) { | ||
99 | // // Needs to be delayed to not interfere with mainWindow.restore(); | ||
100 | // setTimeout(() => { | ||
101 | // debug('Resetting windows via Task'); | ||
102 | // mainWindow.setPosition(DEFAULT_WINDOW_OPTIONS.x + 100, DEFAULT_WINDOW_OPTIONS.y + 100); | ||
103 | // mainWindow.setSize(DEFAULT_WINDOW_OPTIONS.width, DEFAULT_WINDOW_OPTIONS.height); | ||
104 | // }, 1); | ||
105 | // } | ||
106 | // }); | ||
107 | |||
108 | // if (isSecondInstance) { | ||
109 | // console.log('An instance of Franz is already running. Exiting...'); | ||
110 | // app.exit(); | ||
111 | // } | ||
78 | 112 | ||
79 | // Fix Unity indicator issue | 113 | // Fix Unity indicator issue |
80 | // https://github.com/electron/electron/issues/9046 | 114 | // https://github.com/electron/electron/issues/9046 |
diff --git a/src/models/Service.js b/src/models/Service.js index 4cc6102ff..7a955a6d9 100644 --- a/src/models/Service.js +++ b/src/models/Service.js | |||
@@ -114,6 +114,13 @@ export default class Service { | |||
114 | }); | 114 | }); |
115 | } | 115 | } |
116 | 116 | ||
117 | @computed get shareWithWebview() { | ||
118 | return { | ||
119 | spellcheckerLanguage: this.spellcheckerLanguage, | ||
120 | isDarkModeEnabled: this.isDarkModeEnabled, | ||
121 | }; | ||
122 | } | ||
123 | |||
117 | @computed get url() { | 124 | @computed get url() { |
118 | if (this.recipe.hasCustomUrl && this.customUrl) { | 125 | if (this.recipe.hasCustomUrl && this.customUrl) { |
119 | let url; | 126 | let url; |
@@ -162,14 +169,14 @@ export default class Service { | |||
162 | return userAgent; | 169 | return userAgent; |
163 | } | 170 | } |
164 | 171 | ||
165 | initializeWebViewEvents(store) { | 172 | initializeWebViewEvents({ handleIPCMessage, openWindow }) { |
166 | this.webview.addEventListener('ipc-message', e => store.actions.service.handleIPCMessage({ | 173 | this.webview.addEventListener('ipc-message', e => handleIPCMessage({ |
167 | serviceId: this.id, | 174 | serviceId: this.id, |
168 | channel: e.channel, | 175 | channel: e.channel, |
169 | args: e.args, | 176 | args: e.args, |
170 | })); | 177 | })); |
171 | 178 | ||
172 | this.webview.addEventListener('new-window', (event, url, frameName, options) => store.actions.service.openWindow({ | 179 | this.webview.addEventListener('new-window', (event, url, frameName, options) => openWindow({ |
173 | event, | 180 | event, |
174 | url, | 181 | url, |
175 | frameName, | 182 | frameName, |
@@ -182,17 +189,20 @@ export default class Service { | |||
182 | this.isError = false; | 189 | this.isError = false; |
183 | }); | 190 | }); |
184 | 191 | ||
185 | this.webview.addEventListener('did-frame-finish-load', () => { | 192 | const didLoad = () => { |
186 | this.isLoading = false; | 193 | this.isLoading = false; |
187 | 194 | ||
188 | if (!this.isError) { | 195 | if (!this.isError) { |
189 | this.isFirstLoad = false; | 196 | this.isFirstLoad = false; |
190 | } | 197 | } |
191 | }); | 198 | }; |
199 | |||
200 | this.webview.addEventListener('did-frame-finish-load', didLoad.bind(this)); | ||
201 | this.webview.addEventListener('did-navigate', didLoad.bind(this)); | ||
192 | 202 | ||
193 | this.webview.addEventListener('did-fail-load', (event) => { | 203 | this.webview.addEventListener('did-fail-load', (event) => { |
194 | debug('Service failed to load', this.name, event); | 204 | debug('Service failed to load', this.name, event); |
195 | if (event.isMainFrame) { | 205 | if (event.isMainFrame && event.errorCode !== -3) { |
196 | this.isError = true; | 206 | this.isError = true; |
197 | this.errorMessage = event.errorDescription; | 207 | this.errorMessage = event.errorDescription; |
198 | this.isLoading = false; | 208 | this.isLoading = false; |
diff --git a/src/stores/ServicesStore.js b/src/stores/ServicesStore.js index 5b70ca271..84f84891a 100644 --- a/src/stores/ServicesStore.js +++ b/src/stores/ServicesStore.js | |||
@@ -1,5 +1,8 @@ | |||
1 | import { | 1 | import { |
2 | action, reaction, computed, observable, | 2 | action, |
3 | reaction, | ||
4 | computed, | ||
5 | observable, | ||
3 | } from 'mobx'; | 6 | } from 'mobx'; |
4 | import { debounce, remove } from 'lodash'; | 7 | import { debounce, remove } from 'lodash'; |
5 | 8 | ||
@@ -323,7 +326,11 @@ export default class ServicesStore extends Store { | |||
323 | service.webview = webview; | 326 | service.webview = webview; |
324 | 327 | ||
325 | if (!service.isAttached) { | 328 | if (!service.isAttached) { |
326 | service.initializeWebViewEvents(this); | 329 | debug('Webview is not attached, initializing'); |
330 | service.initializeWebViewEvents({ | ||
331 | handleIPCMessage: this.actions.service.handleIPCMessage, | ||
332 | openWindow: this.actions.service.openWindow, | ||
333 | }); | ||
327 | service.initializeWebViewListener(); | 334 | service.initializeWebViewListener(); |
328 | } | 335 | } |
329 | 336 | ||
@@ -644,14 +651,15 @@ export default class ServicesStore extends Store { | |||
644 | const service = this.one(serviceId); | 651 | const service = this.one(serviceId); |
645 | 652 | ||
646 | if (service.webview) { | 653 | if (service.webview) { |
647 | service.webview.send('initialize-recipe', service); | 654 | debug('Initialize recipe', service.recipe.id, service.name); |
655 | service.webview.send('initialize-recipe', service.shareWithWebview, service.recipe); | ||
648 | } | 656 | } |
649 | } | 657 | } |
650 | 658 | ||
651 | _initRecipePolling(serviceId) { | 659 | _initRecipePolling(serviceId) { |
652 | const service = this.one(serviceId); | 660 | const service = this.one(serviceId); |
653 | 661 | ||
654 | const delay = 1000; | 662 | const delay = 2000; |
655 | 663 | ||
656 | if (service) { | 664 | if (service) { |
657 | if (service.timer !== null) { | 665 | if (service.timer !== null) { |
diff --git a/src/stores/UIStore.js b/src/stores/UIStore.js index d37ebe4c7..188c2fc44 100644 --- a/src/stores/UIStore.js +++ b/src/stores/UIStore.js | |||
@@ -1,8 +1,7 @@ | |||
1 | import { action, observable, computed } from 'mobx'; | 1 | import { action, observable, computed } from 'mobx'; |
2 | import theme from '@meetfranz/theme'; | ||
2 | 3 | ||
3 | import Store from './lib/Store'; | 4 | import Store from './lib/Store'; |
4 | import * as themeDefault from '../theme/default'; | ||
5 | import * as themeDark from '../theme/dark'; | ||
6 | 5 | ||
7 | export default class UIStore extends Store { | 6 | export default class UIStore extends Store { |
8 | @observable showServicesUpdatedInfoBar = false; | 7 | @observable showServicesUpdatedInfoBar = false; |
@@ -24,10 +23,10 @@ export default class UIStore extends Store { | |||
24 | 23 | ||
25 | @computed get theme() { | 24 | @computed get theme() { |
26 | if (this.stores.settings.all.app.darkMode) { | 25 | if (this.stores.settings.all.app.darkMode) { |
27 | return Object.assign({}, themeDefault, themeDark); | 26 | return theme('dark'); |
28 | } | 27 | } |
29 | 28 | ||
30 | return themeDefault; | 29 | return theme('default'); |
31 | } | 30 | } |
32 | 31 | ||
33 | // Actions | 32 | // Actions |
diff --git a/src/webview/recipe.js b/src/webview/recipe.js index 944883899..9aa89ce01 100644 --- a/src/webview/recipe.js +++ b/src/webview/recipe.js | |||
@@ -42,9 +42,9 @@ class RecipeController { | |||
42 | 42 | ||
43 | async initialize() { | 43 | async initialize() { |
44 | Object.keys(this.ipcEvents).forEach((channel) => { | 44 | Object.keys(this.ipcEvents).forEach((channel) => { |
45 | ipcRenderer.on(channel, (event, data) => { | 45 | ipcRenderer.on(channel, (...args) => { |
46 | debug('Received IPC event for channel', channel, 'with', data); | 46 | debug('Received IPC event for channel', channel, 'with', ...args); |
47 | this[this.ipcEvents[channel]](event, data); | 47 | this[this.ipcEvents[channel]](...args); |
48 | }); | 48 | }); |
49 | }); | 49 | }); |
50 | 50 | ||
@@ -62,17 +62,18 @@ class RecipeController { | |||
62 | autorun(() => this.update()); | 62 | autorun(() => this.update()); |
63 | } | 63 | } |
64 | 64 | ||
65 | loadRecipeModule(event, data) { | 65 | loadRecipeModule(event, config, recipe) { |
66 | debug('loadRecipeModule'); | 66 | debug('loadRecipeModule'); |
67 | const modulePath = path.join(data.recipe.path, 'webview.js'); | 67 | const modulePath = path.join(recipe.path, 'webview.js'); |
68 | debug('module path', modulePath); | ||
68 | // Delete module from cache | 69 | // Delete module from cache |
69 | delete require.cache[require.resolve(modulePath)]; | 70 | delete require.cache[require.resolve(modulePath)]; |
70 | try { | 71 | try { |
71 | // eslint-disable-next-line | 72 | // eslint-disable-next-line |
72 | require(modulePath)(new RecipeWebview(), data); | 73 | require(modulePath)(new RecipeWebview(), {...config, recipe,}); |
73 | debug('Initialize Recipe', data); | 74 | debug('Initialize Recipe', config, recipe); |
74 | 75 | ||
75 | this.settings.service = data; | 76 | this.settings.service = config; |
76 | } catch (err) { | 77 | } catch (err) { |
77 | console.error('Recipe initialization failed', err); | 78 | console.error('Recipe initialization failed', err); |
78 | } | 79 | } |