150 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
		
		
			
		
	
	
			150 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * @license
							 | 
						||
| 
								 | 
							
								 * MIT License
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * Copyright (c) 2017 F-List
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * Permission is hereby granted, free of charge, to any person obtaining a copy
							 | 
						||
| 
								 | 
							
								 * of this software and associated documentation files (the "Software"), to deal
							 | 
						||
| 
								 | 
							
								 * in the Software without restriction, including without limitation the rights
							 | 
						||
| 
								 | 
							
								 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
							 | 
						||
| 
								 | 
							
								 * copies of the Software, and to permit persons to whom the Software is
							 | 
						||
| 
								 | 
							
								 * furnished to do so, subject to the following conditions:
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * The above copyright notice and this permission notice shall be included in all
							 | 
						||
| 
								 | 
							
								 * copies or substantial portions of the Software.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
							 | 
						||
| 
								 | 
							
								 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
							 | 
						||
| 
								 | 
							
								 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
							 | 
						||
| 
								 | 
							
								 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
							 | 
						||
| 
								 | 
							
								 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
							 | 
						||
| 
								 | 
							
								 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
							 | 
						||
| 
								 | 
							
								 * SOFTWARE.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * This license header applies to this file and all of the non-third-party assets it includes.
							 | 
						||
| 
								 | 
							
								 * @file The entry point for the Electron main thread of F-Chat 3.0.
							 | 
						||
| 
								 | 
							
								 * @copyright 2017 F-List
							 | 
						||
| 
								 | 
							
								 * @author Maya Wolf <maya@f-list.net>
							 | 
						||
| 
								 | 
							
								 * @version 3.0
							 | 
						||
| 
								 | 
							
								 * @see {@link https://github.com/f-list/exported|GitHub repo}
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								import * as electron from 'electron';
							 | 
						||
| 
								 | 
							
								import log from 'electron-log';
							 | 
						||
| 
								 | 
							
								import {autoUpdater} from 'electron-updater';
							 | 
						||
| 
								 | 
							
								import * as path from 'path';
							 | 
						||
| 
								 | 
							
								import * as url from 'url';
							 | 
						||
| 
								 | 
							
								import {mkdir} from './common';
							 | 
						||
| 
								 | 
							
								import * as windowState from './window_state';
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Module to control application life.
							 | 
						||
| 
								 | 
							
								const app = electron.app;
							 | 
						||
| 
								 | 
							
								const datadir = process.argv.filter((x) => x.startsWith('--datadir='));
							 | 
						||
| 
								 | 
							
								if(datadir.length > 0) app.setPath('userData', datadir[0].substr('--datadir='.length));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Keep a global reference of the window object, if you don't, the window will
							 | 
						||
| 
								 | 
							
								// be closed automatically when the JavaScript object is garbage collected.
							 | 
						||
| 
								 | 
							
								let mainWindow: Electron.BrowserWindow | undefined;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const baseDir = app.getPath('userData');
							 | 
						||
| 
								 | 
							
								mkdir(baseDir);
							 | 
						||
| 
								 | 
							
								autoUpdater.logger = log;
							 | 
						||
| 
								 | 
							
								log.transports.file.level = 'debug';
							 | 
						||
| 
								 | 
							
								log.transports.console.level = 'debug';
							 | 
						||
| 
								 | 
							
								log.transports.file.maxSize = 5 * 1024 * 1024;
							 | 
						||
| 
								 | 
							
								log.transports.file.file = path.join(baseDir, 'log.txt');
							 | 
						||
| 
								 | 
							
								log.info('Starting application.');
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function sendUpdaterStatusToWindow(status: string, progress?: object): void {
							 | 
						||
| 
								 | 
							
								    log.info(status);
							 | 
						||
| 
								 | 
							
								    mainWindow!.webContents.send('updater-status', status, progress);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const updaterEvents = ['checking-for-update', 'update-available', 'update-not-available', 'error', 'update-downloaded'];
							 | 
						||
| 
								 | 
							
								for(const eventName of updaterEvents)
							 | 
						||
| 
								 | 
							
								    autoUpdater.on(eventName, () => {
							 | 
						||
| 
								 | 
							
								        sendUpdaterStatusToWindow(eventName);
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								autoUpdater.on('download-progress', (_, progress: object) => {
							 | 
						||
| 
								 | 
							
								    sendUpdaterStatusToWindow('download-progress', progress);
							 | 
						||
| 
								 | 
							
								});
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function runUpdater(): void {
							 | 
						||
| 
								 | 
							
								    //tslint:disable-next-line:no-floating-promises
							 | 
						||
| 
								 | 
							
								    autoUpdater.checkForUpdates();
							 | 
						||
| 
								 | 
							
								    //tslint:disable-next-line:no-floating-promises
							 | 
						||
| 
								 | 
							
								    setInterval(() => { autoUpdater.checkForUpdates(); }, 3600000);
							 | 
						||
| 
								 | 
							
								    electron.ipcMain.on('install-update', () => {
							 | 
						||
| 
								 | 
							
								        autoUpdater.quitAndInstall(false, true);
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function bindWindowEvents(window: Electron.BrowserWindow): void {
							 | 
						||
| 
								 | 
							
								    // Prevent page navigation by opening links in an external browser.
							 | 
						||
| 
								 | 
							
								    const openLinkExternally = (e: Event, linkUrl: string) => {
							 | 
						||
| 
								 | 
							
								        e.preventDefault();
							 | 
						||
| 
								 | 
							
								        electron.shell.openExternal(linkUrl);
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    window.webContents.on('will-navigate', openLinkExternally);
							 | 
						||
| 
								 | 
							
								    window.webContents.on('new-window', openLinkExternally);
							 | 
						||
| 
								 | 
							
								    // Fix focus events not properly propagating down to the document.
							 | 
						||
| 
								 | 
							
								    window.on('focus', () => mainWindow!.webContents.send('focus', true));
							 | 
						||
| 
								 | 
							
								    window.on('blur', () => mainWindow!.webContents.send('focus', false));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // Save window state when it is being closed.
							 | 
						||
| 
								 | 
							
								    window.on('close', () => windowState.setSavedWindowState(window));
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function createWindow(): void {
							 | 
						||
| 
								 | 
							
								    const lastState = windowState.getSavedWindowState();
							 | 
						||
| 
								 | 
							
								    const windowProperties = {...lastState, center: lastState.x === undefined};
							 | 
						||
| 
								 | 
							
								    // Create the browser window.
							 | 
						||
| 
								 | 
							
								    mainWindow = new electron.BrowserWindow(windowProperties);
							 | 
						||
| 
								 | 
							
								    if(lastState.maximized)
							 | 
						||
| 
								 | 
							
								        mainWindow.maximize();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // and load the index.html of the app.
							 | 
						||
| 
								 | 
							
								    mainWindow.loadURL(url.format({
							 | 
						||
| 
								 | 
							
								        pathname: path.join(__dirname, 'index.html'),
							 | 
						||
| 
								 | 
							
								        protocol: 'file:',
							 | 
						||
| 
								 | 
							
								        slashes: true
							 | 
						||
| 
								 | 
							
								    }));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    bindWindowEvents(mainWindow);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // Open the DevTools.
							 | 
						||
| 
								 | 
							
								    // mainWindow.webContents.openDevTools()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // Emitted when the window is closed.
							 | 
						||
| 
								 | 
							
								    mainWindow.on('closed', () => {
							 | 
						||
| 
								 | 
							
								        // Dereference the window object, usually you would store windows
							 | 
						||
| 
								 | 
							
								        // in an array if your app supports multi windows, this is the time
							 | 
						||
| 
								 | 
							
								        // when you should delete the corresponding element.
							 | 
						||
| 
								 | 
							
								        mainWindow = undefined;
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if(process.env.NODE_ENV === 'production') runUpdater();
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// This method will be called when Electron has finished
							 | 
						||
| 
								 | 
							
								// initialization and is ready to create browser windows.
							 | 
						||
| 
								 | 
							
								// Some APIs can only be used after this event occurs.
							 | 
						||
| 
								 | 
							
								app.on('ready', createWindow);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Quit when all windows are closed.
							 | 
						||
| 
								 | 
							
								app.on('window-all-closed', () => {
							 | 
						||
| 
								 | 
							
								    // On OS X it is common for applications and their menu bar
							 | 
						||
| 
								 | 
							
								    // to stay active until the user quits explicitly with Cmd + Q
							 | 
						||
| 
								 | 
							
								    if(process.platform !== 'darwin') app.quit();
							 | 
						||
| 
								 | 
							
								});
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								app.on('activate', () => {
							 | 
						||
| 
								 | 
							
								    // On OS X it's common to re-create a window in the app when the
							 | 
						||
| 
								 | 
							
								    // dock icon is clicked and there are no other windows open.
							 | 
						||
| 
								 | 
							
								    if(mainWindow === undefined) createWindow();
							 | 
						||
| 
								 | 
							
								});
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// In this file you can include the rest of your app's specific main process
							 | 
						||
| 
								 | 
							
								// code. You can also put them in separate files and require them here.
							 |