aboutsummaryrefslogtreecommitdiffstats
path: root/src/index.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/index.js')
-rw-r--r--src/index.js134
1 files changed, 98 insertions, 36 deletions
diff --git a/src/index.js b/src/index.js
index 75da4ff88..a3c770797 100644
--- a/src/index.js
+++ b/src/index.js
@@ -1,20 +1,26 @@
1import { 1import {
2 app, BrowserWindow, shell, ipcMain, 2 app,
3 BrowserWindow,
4 shell,
5 ipcMain,
3} from 'electron'; 6} from 'electron';
4 7import isDevMode from 'electron-is-dev';
5import fs from 'fs-extra'; 8import fs from 'fs-extra';
6import path from 'path'; 9import path from 'path';
7import windowStateKeeper from 'electron-window-state'; 10import windowStateKeeper from 'electron-window-state';
8 11
9import { 12// Set app directory before loading user modules
10 isDevMode, isMac, isWindows, isLinux,
11} from './environment';
12
13// DEV MODE: Save user data into FranzDev
14if (isDevMode) { 13if (isDevMode) {
15 app.setPath('userData', path.join(app.getPath('appData'), 'FranzDev')); 14 app.setPath('userData', path.join(app.getPath('appData'), 'FranzDev'));
16} 15}
16
17/* eslint-disable import/first */ 17/* eslint-disable import/first */
18import {
19 isMac,
20 isWindows,
21 isLinux,
22} from './environment';
23import { mainIpcHandler as basicAuthHandler } from './features/basicAuth';
18import ipcApi from './electron/ipc-api'; 24import ipcApi from './electron/ipc-api';
19import Tray from './lib/Tray'; 25import Tray from './lib/Tray';
20import Settings from './electron/Settings'; 26import Settings from './electron/Settings';
@@ -36,6 +42,17 @@ const debug = require('debug')('Franz:App');
36let mainWindow; 42let mainWindow;
37let willQuitApp = false; 43let willQuitApp = false;
38 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
39// Ensure that the recipe directory exists 56// Ensure that the recipe directory exists
40fs.emptyDirSync(path.join(app.getPath('userData'), 'recipes', 'temp')); 57fs.emptyDirSync(path.join(app.getPath('userData'), 'recipes', 'temp'));
41fs.ensureFileSync(path.join(app.getPath('userData'), 'window-state.json')); 58fs.ensureFileSync(path.join(app.getPath('userData'), 'window-state.json'));
@@ -57,28 +74,25 @@ if (!gotTheLock) {
57 mainWindow.focus(); 74 mainWindow.focus();
58 75
59 if (isWindows) { 76 if (isWindows) {
60 // Keep only command line / deep linked arguments 77 onDidLoad((window) => {
61 const url = argv.slice(1); 78 // Keep only command line / deep linked arguments
62 79 const url = argv.slice(1);
63 if (url) { 80 if (url) {
64 handleDeepLink(mainWindow, url.toString()); 81 handleDeepLink(window, url.toString());
65 } 82 }
66 } 83
67 84 if (argv.includes('--reset-window')) {
68 if (argv.includes('--reset-window')) { 85 // Needs to be delayed to not interfere with mainWindow.restore();
69 // Needs to be delayed to not interfere with mainWindow.restore(); 86 setTimeout(() => {
70 setTimeout(() => { 87 debug('Resetting windows via Task');
71 debug('Resetting windows via Task'); 88 window.setPosition(DEFAULT_WINDOW_OPTIONS.x + 100, DEFAULT_WINDOW_OPTIONS.y + 100);
72 mainWindow.setPosition(DEFAULT_WINDOW_OPTIONS.x + 100, DEFAULT_WINDOW_OPTIONS.y + 100); 89 window.setSize(DEFAULT_WINDOW_OPTIONS.width, DEFAULT_WINDOW_OPTIONS.height);
73 mainWindow.setSize(DEFAULT_WINDOW_OPTIONS.width, DEFAULT_WINDOW_OPTIONS.height); 90 }, 1);
74 }, 1); 91 }
92 });
75 } 93 }
76 } 94 }
77 }); 95 });
78
79 // Create myWindow, load the rest of the app, etc...
80 app.on('ready', () => {
81 });
82} 96}
83// const isSecondInstance = app.makeSingleInstance((argv) => { 97// const isSecondInstance = app.makeSingleInstance((argv) => {
84// if (mainWindow) { 98// if (mainWindow) {
@@ -153,6 +167,17 @@ const createWindow = () => {
153 titleBarStyle: isMac ? 'hidden' : '', 167 titleBarStyle: isMac ? 'hidden' : '',
154 frame: isLinux, 168 frame: isLinux,
155 backgroundColor: !settings.get('darkMode') ? '#3498db' : '#1E1E1E', 169 backgroundColor: !settings.get('darkMode') ? '#3498db' : '#1E1E1E',
170 webPreferences: {
171 nodeIntegration: true,
172 },
173 });
174
175 mainWindow.webContents.on('did-finish-load', () => {
176 const fns = onDidLoadFns;
177 onDidLoadFns = null;
178 for (const fn of fns) {
179 fn(mainWindow);
180 }
156 }); 181 });
157 182
158 // Initialize System Tray 183 // Initialize System Tray
@@ -179,6 +204,16 @@ const createWindow = () => {
179 mainWindow.webContents.openDevTools(); 204 mainWindow.webContents.openDevTools();
180 } 205 }
181 206
207 // Windows deep linking handling on app launch
208 if (isWindows) {
209 onDidLoad((window) => {
210 const url = process.argv.slice(1);
211 if (url) {
212 handleDeepLink(window, url.toString());
213 }
214 });
215 }
216
182 // Emitted when the window is closed. 217 // Emitted when the window is closed.
183 mainWindow.on('close', (e) => { 218 mainWindow.on('close', (e) => {
184 // Dereference the window object, usually you would store windows 219 // Dereference the window object, usually you would store windows
@@ -248,6 +283,13 @@ const createWindow = () => {
248// initialization and is ready to create browser windows. 283// initialization and is ready to create browser windows.
249// Some APIs can only be used after this event occurs. 284// Some APIs can only be used after this event occurs.
250app.on('ready', () => { 285app.on('ready', () => {
286 // Register App URL
287 app.setAsDefaultProtocolClient('franz');
288
289 if (isDevMode) {
290 app.setAsDefaultProtocolClient('franz-dev');
291 }
292
251 if (process.platform === 'win32') { 293 if (process.platform === 'win32') {
252 app.setUserTasks([{ 294 app.setUserTasks([{
253 program: process.execPath, 295 program: process.execPath,
@@ -263,23 +305,43 @@ app.on('ready', () => {
263}); 305});
264 306
265// This is the worst possible implementation as the webview.webContents based callback doesn't work 🖕 307// This is the worst possible implementation as the webview.webContents based callback doesn't work 🖕
308// TODO: rewrite to handle multiple login calls
309const noop = () => null;
310let authCallback = noop;
266app.on('login', (event, webContents, request, authInfo, callback) => { 311app.on('login', (event, webContents, request, authInfo, callback) => {
267 event.preventDefault(); 312 authCallback = callback;
268 debug('browser login event', authInfo); 313 debug('browser login event', authInfo);
314 event.preventDefault();
269 if (authInfo.isProxy && authInfo.scheme === 'basic') { 315 if (authInfo.isProxy && authInfo.scheme === 'basic') {
270 webContents.send('get-service-id'); 316 webContents.send('get-service-id');
271 317
272 ipcMain.on('service-id', (e, id) => { 318 ipcMain.once('service-id', (e, id) => {
273 debug('Received service id', id); 319 debug('Received service id', id);
274 320
275 const ps = proxySettings.get(id); 321 const ps = proxySettings.get(id);
276 callback(ps.user, ps.password); 322 callback(ps.user, ps.password);
277 }); 323 });
278 } else { 324 } else if (authInfo.scheme === 'basic') {
279 // TODO: implement basic auth 325 debug('basic auth handler', authInfo);
326 basicAuthHandler(mainWindow, authInfo);
280 } 327 }
281}); 328});
282 329
330// TODO: evaluate if we need to store the authCallback for every service
331ipcMain.on('feature-basic-auth-credentials', (e, { user, password }) => {
332 debug('Received basic auth credentials', user, '********');
333
334 authCallback(user, password);
335 authCallback = noop;
336});
337
338ipcMain.on('feature-basic-auth-cancel', () => {
339 debug('Cancel basic auth');
340
341 authCallback(null);
342 authCallback = noop;
343});
344
283// Quit when all windows are closed. 345// Quit when all windows are closed.
284app.on('window-all-closed', () => { 346app.on('window-all-closed', () => {
285 // On OS X it is common for applications and their menu bar 347 // On OS X it is common for applications and their menu bar
@@ -305,13 +367,13 @@ app.on('activate', () => {
305}); 367});
306 368
307app.on('will-finish-launching', () => { 369app.on('will-finish-launching', () => {
308 // Protocol handler for osx 370 // Protocol handler for macOS
309 app.on('open-url', (event, url) => { 371 app.on('open-url', (event, url) => {
310 event.preventDefault(); 372 event.preventDefault();
311 console.log(`open-url event: ${url}`); 373
312 handleDeepLink(mainWindow, url); 374 onDidLoad((window) => {
375 debug('open-url event', url);
376 handleDeepLink(window, url);
377 });
313 }); 378 });
314}); 379});
315
316// Register App URL
317app.setAsDefaultProtocolClient('franz');