next-ucap-messenger/electron-projects/ucap-webmessenger-electron/src/index.ts

830 lines
20 KiB
TypeScript
Raw Normal View History

2019-12-24 07:16:13 +00:00
import {
app,
ipcMain,
IpcMainEvent,
Tray,
Menu,
shell,
2020-01-13 04:55:54 +00:00
dialog,
2020-02-04 08:13:09 +00:00
BrowserWindow,
clipboard
2019-12-24 07:16:13 +00:00
} from 'electron';
2019-12-12 08:15:09 +00:00
import path from 'path';
import fse from 'fs-extra';
2019-12-15 16:06:07 +00:00
import semver from 'semver';
import os from 'os';
2020-01-09 09:52:08 +00:00
import ChildProcess from 'child_process';
2019-11-11 06:53:39 +00:00
2019-12-17 08:27:08 +00:00
import AutoLaunch from 'auto-launch';
2019-11-11 06:53:39 +00:00
import { AppWindow } from './app/AppWindow';
import { now } from './util/now';
import { showUncaughtException } from './crash/show-uncaught-exception';
import {
UpdaterChannel,
FileChannel,
2020-01-09 09:52:08 +00:00
ProcessChannel,
2019-11-11 06:53:39 +00:00
IdleStateChannel,
NotificationChannel,
2019-11-19 07:44:50 +00:00
ChatChannel,
2019-12-17 07:39:02 +00:00
MessengerChannel,
2020-01-23 02:23:31 +00:00
MessageChannel,
2020-02-04 08:13:09 +00:00
AppChannel,
ClipboardChannel
2019-11-11 06:53:39 +00:00
} from '@ucap-webmessenger/native-electron';
import { ElectronNotificationService } from '@ucap-webmessenger/electron-notification';
2019-12-15 16:06:07 +00:00
import { ElectronUpdateWindowService } from '@ucap-webmessenger/electron-update-window';
2019-11-11 06:53:39 +00:00
import { root } from './util/root';
import { FileUtil } from './lib/file-util';
import { IdleChecker } from './lib/idle-checker';
2019-12-12 08:15:09 +00:00
import {
NotificationRequest,
2019-12-24 02:41:50 +00:00
NotificationType,
NativePathName
2019-12-12 08:15:09 +00:00
} from '@ucap-webmessenger/native';
2020-02-10 04:45:02 +00:00
import {
ElectronAppChannel,
ElectronBrowserWindowChannel
} from '@ucap-webmessenger/electron-core';
2019-12-13 04:45:08 +00:00
2020-02-05 07:18:17 +00:00
import {
autoUpdater,
CancellationToken,
UpdateCheckResult
} from 'electron-updater';
2019-12-13 04:45:08 +00:00
import log from 'electron-log';
2019-12-12 08:15:09 +00:00
import { RendererUpdater } from './lib/renderer-updater';
2020-02-06 09:20:45 +00:00
import { appStorage } from './lib/storage';
2019-11-11 06:53:39 +00:00
2019-11-18 06:02:24 +00:00
const appIconPath = __LINUX__
2019-12-30 08:21:26 +00:00
? __DEV__
? path.join(
__dirname,
'../../',
2019-12-31 05:15:29 +00:00
'config/build/linux/icon/daesang/',
2019-12-30 08:21:26 +00:00
'256x256.png'
)
2020-01-02 05:26:14 +00:00
: path.join(__dirname, '..', '..', '/assets/icon/', '256x256.png')
2019-12-30 08:21:26 +00:00
: __DEV__
2019-12-31 05:15:29 +00:00
? path.join(
__dirname,
'../../',
'config/build/win/icon/daesang/',
'16x16.ico'
)
2020-01-02 05:26:14 +00:00
: path.join(__dirname, '..', '..', '/assets/icon/', '16x16.ico');
2019-11-18 06:02:24 +00:00
2019-11-11 06:53:39 +00:00
let appWindow: AppWindow | null = null;
2019-11-18 06:02:24 +00:00
let appTray: Tray | null = null;
2019-11-11 06:53:39 +00:00
const launchTime = now();
let readyTime: number | null = null;
type OnDidLoadFn = (window: AppWindow) => void;
let onDidLoadFns: Array<OnDidLoadFn> | null = [];
let preventQuit = false;
let notificationService: ElectronNotificationService | null;
2019-12-15 16:06:07 +00:00
let updateWindowService: ElectronUpdateWindowService | null;
2019-11-11 06:53:39 +00:00
function handleUncaughtException(error: Error) {
preventQuit = true;
// If we haven't got a window we'll assume it's because
// we've just launched and haven't created it yet.
// It could also be because we're encountering an unhandled
// exception on shutdown but that's less likely and since
// this only affects the presentation of the crash dialog
// it's a safe assumption to make.
const isLaunchError = appWindow === null;
if (appWindow) {
appWindow.destroy();
appWindow = null;
}
showUncaughtException(isLaunchError, error);
}
function getUptimeInSeconds() {
return (now() - launchTime) / 1000;
}
process.on('uncaughtException', (error: Error) => {
// error = withSourceMappedStack(error);
// reportError(error, getExtraErrorContext());
handleUncaughtException(error);
});
let isDuplicateInstance = false;
const gotSingleInstanceLock = app.requestSingleInstanceLock();
isDuplicateInstance = !gotSingleInstanceLock;
let idle: IdleChecker | null;
2019-12-12 08:15:09 +00:00
let rendererUpdater: RendererUpdater | undefined;
2019-11-11 06:53:39 +00:00
2019-12-13 04:45:08 +00:00
log.transports.file.level = 'debug';
let autoUpdaterCancellationToken: CancellationToken;
2020-02-05 07:18:17 +00:00
let updateCheckResult: UpdateCheckResult;
2019-12-13 04:45:08 +00:00
autoUpdater.autoDownload = false;
autoUpdater.logger = log;
2019-12-17 08:27:08 +00:00
const ucapMessengerLauncher = new AutoLaunch({
2019-12-18 04:44:26 +00:00
name: app.name
2019-12-17 08:27:08 +00:00
});
2019-11-11 06:53:39 +00:00
app.on(ElectronAppChannel.SecondInstance, (event, args, workingDirectory) => {
// Someone tried to run a second instance, we should focus our window.
if (appWindow) {
if (appWindow.isMinimized()) {
appWindow.restore();
}
if (!appWindow.isVisible()) {
appWindow.show();
}
appWindow.focus();
}
});
if (isDuplicateInstance) {
app.quit();
}
function createWindow() {
2019-11-18 06:02:24 +00:00
const window = new AppWindow(appIconPath);
2019-11-11 06:53:39 +00:00
if (__DEV__) {
// const {
// default: installExtension,
// REDUX_DEVTOOLS
// } = require('electron-devtools-installer');
import('electron-debug').then(ed => {
ed.default({ showDevTools: true });
});
import('electron-devtools-installer').then(edi => {
const ChromeLens = {
id: 'idikgljglpfilbhaboonnpnnincjhjkd',
2019-11-18 06:02:24 +00:00
electron: '>=1.2.1'
2019-11-11 06:53:39 +00:00
};
const extensions = [edi.REDUX_DEVTOOLS, ChromeLens];
for (const extension of extensions) {
try {
edi.default(extension);
} catch (e) {
log.error(e);
2019-11-11 06:53:39 +00:00
}
}
});
}
window.onClose(() => {
appWindow = null;
if (!__DARWIN__ && !preventQuit) {
app.quit();
}
});
window.onDidLoad(() => {
2019-12-18 08:11:58 +00:00
if (!appStorage.startupHideWindow) {
window.show();
}
2019-11-11 06:53:39 +00:00
const fns = onDidLoadFns;
onDidLoadFns = null;
for (const fn of fns) {
fn(window);
}
});
window.load();
appWindow = window;
}
2019-11-19 07:44:50 +00:00
function createTray() {
2019-11-18 06:02:24 +00:00
appTray = new Tray(appIconPath);
const contextMenu = Menu.buildFromTemplate([
{
label: '로그아웃',
// accelerator: 'Q',
// selector: 'terminate:',
click: () => {
appWindow.show();
2019-11-19 07:44:50 +00:00
appWindow.browserWindow.webContents.send(MessengerChannel.Logout);
}
},
{
label: '설정',
// accelerator: 'Q',
// selector: 'terminate:',
click: () => {
2019-11-21 01:29:19 +00:00
appWindow.show();
2019-11-19 07:44:50 +00:00
appWindow.browserWindow.webContents.send(MessengerChannel.ShowSetting);
2019-11-18 06:02:24 +00:00
}
},
{ label: '버전', submenu: [{ label: 'Ver. ' + app.getVersion() }] },
{
label: '종료',
// accelerator: 'Q',
// selector: 'terminate:',
click: () => {
// 메신저에 로그아웃 후 종료
2020-01-23 02:23:31 +00:00
appExit();
2019-11-18 06:02:24 +00:00
}
}
]);
appTray.setToolTip('DS Talk');
2019-11-18 06:02:24 +00:00
appTray.setContextMenu(contextMenu);
appTray.on('click', () => {
appWindow.isVisible() ? appWindow.hide() : appWindow.show();
});
2019-11-19 07:44:50 +00:00
}
// 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(ElectronAppChannel.Ready, () => {
if (isDuplicateInstance) {
return;
}
readyTime = now() - launchTime;
createWindow();
createTray();
2019-11-18 06:02:24 +00:00
2019-11-11 06:53:39 +00:00
notificationService = new ElectronNotificationService({
width: 340,
height: 100,
padding: 0,
borderRadius: 0,
// appIcon: iconPath,
displayTime: 5000,
defaultStyleContainer: {},
defaultStyleAppIcon: { display: 'none' },
defaultStyleImage: {},
defaultStyleClose: {},
2019-11-18 06:02:24 +00:00
defaultStyleText: {}
2019-11-11 06:53:39 +00:00
});
notificationService.options.defaultWindow.webPreferences.preload = path.join(
__dirname,
2019-12-31 05:15:29 +00:00
'assets/notification/preload.js'
2019-11-11 06:53:39 +00:00
);
notificationService.templatePath = path.join(
__dirname,
2019-12-31 05:15:29 +00:00
'assets/notification/template.html'
2019-11-11 06:53:39 +00:00
);
2019-12-15 16:06:07 +00:00
updateWindowService = new ElectronUpdateWindowService({
width: 500,
height: 160,
frame: false,
skipTaskbar: true,
alwaysOnTop: true,
maximizable: false,
onReady: () => {},
onAcceptUpdate: () => {
2020-02-10 04:45:02 +00:00
if (!!autoUpdaterCancellationToken) {
log.info('downloadUpdate already');
return;
}
2019-12-15 16:06:07 +00:00
log.info('OnAcceptUpdate');
autoUpdaterCancellationToken = new CancellationToken();
autoUpdater.downloadUpdate(autoUpdaterCancellationToken);
},
onDenyUpdate: () => {
log.info('OnDenyUpdate');
2020-02-05 07:18:17 +00:00
updateCheckResult.cancellationToken.cancel();
2019-12-15 16:06:07 +00:00
updateWindowService.close();
},
onCancelDownload: () => {
autoUpdaterCancellationToken.cancel();
updateWindowService.close();
}
});
updateWindowService.templatePath = path.join(
__dirname,
2019-12-31 05:15:29 +00:00
'assets/update-window/template.html'
2019-12-15 16:06:07 +00:00
);
// updateWindowService.show();
2019-11-11 06:53:39 +00:00
ipcMain.on('uncaught-exception', (event: IpcMainEvent, error: Error) => {
handleUncaughtException(error);
});
ipcMain.on(
'send-error-report',
(
event: IpcMainEvent,
{ error, extra }: { error: Error; extra: { [key: string]: string } }
) => {}
);
});
// Quit when all windows are closed.
app.on(ElectronAppChannel.WindowAllClosed, () => {
// 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(ElectronAppChannel.Activate, () => {
onDidLoad(window => {
window.show();
});
});
function onDidLoad(fn: OnDidLoadFn) {
if (onDidLoadFns) {
onDidLoadFns.push(fn);
} else {
if (appWindow) {
fn(appWindow);
}
}
}
2020-01-23 05:15:08 +00:00
ipcMain.on(UpdaterChannel.Apply, (event: IpcMainEvent, ...args: any[]) => {
2020-02-05 07:18:17 +00:00
if (!autoUpdater.isUpdaterActive()) {
log.info('autoUpdater is not active');
return;
}
2019-12-15 17:33:40 +00:00
2019-12-15 16:06:07 +00:00
const ver = args[0];
2019-12-15 17:33:40 +00:00
2019-12-15 16:06:07 +00:00
if (semver.lt(app.getVersion(), ver)) {
2020-02-05 07:18:17 +00:00
updateCheckResult = undefined;
2020-02-10 04:45:02 +00:00
autoUpdater
.checkForUpdatesAndNotify()
.then(r => {
updateCheckResult = r;
})
.catch(reason => {
log.error(reason);
})
.finally(() => {});
2019-12-15 16:06:07 +00:00
}
2019-11-11 06:53:39 +00:00
});
ipcMain.on(
MessengerChannel.GetNetworkInfo,
(event: IpcMainEvent, ...args: any[]) => {
const interfaces = os.networkInterfaces();
const addresses: { ip: string; mac: string }[] = [];
// tslint:disable-next-line: forin
for (const k in interfaces) {
// tslint:disable-next-line: forin
for (const k2 in interfaces[k]) {
const address = interfaces[k][k2];
if (address.family === 'IPv4' && !address.internal) {
addresses.push({ ip: address.address, mac: address.mac });
}
}
}
event.returnValue = addresses;
}
);
2020-01-13 06:41:35 +00:00
ipcMain.on(
MessengerChannel.GetVersionInfo,
(event: IpcMainEvent, ...args: any[]) => {
event.returnValue = app.getVersion();
}
);
2019-12-17 08:27:08 +00:00
ipcMain.on(
MessengerChannel.ChangeAutoLaunch,
(event: IpcMainEvent, ...args: any[]) => {
const isAutoLaunch = args[0] as boolean;
if (isAutoLaunch) {
ucapMessengerLauncher
.enable()
.then(() => {
event.returnValue = true;
log.info('AutoLaunch is enabled');
2019-12-17 08:27:08 +00:00
})
.catch(reason => {
event.returnValue = false;
});
} else {
ucapMessengerLauncher
.disable()
.then(() => {
event.returnValue = true;
log.info('AutoLaunch is disabled');
2019-12-17 08:27:08 +00:00
})
.catch(reason => {
event.returnValue = false;
});
}
}
);
2019-12-18 08:11:58 +00:00
ipcMain.on(
MessengerChannel.ChangeStartupHideWindow,
(event: IpcMainEvent, ...args: any[]) => {
const isStartupHideWindow = args[0] as boolean;
appStorage.startupHideWindow = isStartupHideWindow;
log.info(
'StartupHideWindow is changed from ',
!appStorage.startupHideWindow,
' to ',
appStorage.startupHideWindow
);
event.returnValue = true;
}
);
ipcMain.on(
MessengerChannel.ChangeDownloadPath,
(event: IpcMainEvent, ...args: any[]) => {
const downloadPath = args[0] as string;
if (!!downloadPath && downloadPath.length > 0) {
appStorage.downloadPath = downloadPath;
log.info('downloadPath is changed to ', appStorage.downloadPath);
event.returnValue = appStorage.downloadPath;
} else {
event.returnValue = '';
}
}
);
2019-12-12 08:15:09 +00:00
ipcMain.on(
UpdaterChannel.StartCheckInstant,
(event: IpcMainEvent, ...args: any[]) => {
2019-12-15 09:07:25 +00:00
// const config = args[0] as UpdateCheckConfig;
// if (!!rendererUpdater) {
// rendererUpdater.stopCheck();
// rendererUpdater = null;
// }
// rendererUpdater = new RendererUpdater(appWindow.browserWindow, config); // default 10min
// rendererUpdater.startCheck();
2019-12-12 08:15:09 +00:00
}
);
ipcMain.on(
UpdaterChannel.StopCheckInstant,
(event: IpcMainEvent, ...args: any[]) => {
2019-12-15 09:07:25 +00:00
// if (!!rendererUpdater) {
// rendererUpdater.stopCheck();
// rendererUpdater = null;
// }
2019-12-12 08:15:09 +00:00
}
);
ipcMain.on(
UpdaterChannel.ApplyInstant,
(event: IpcMainEvent, ...args: any[]) => {
2019-12-15 09:07:25 +00:00
// if (!!rendererUpdater) {
// rendererUpdater.apply();
// }
2019-12-12 08:15:09 +00:00
}
);
2019-11-11 06:53:39 +00:00
ipcMain.on(FileChannel.ReadFile, (event: IpcMainEvent, ...args: any[]) => {
const filePath = root(args[0]);
2019-11-11 06:53:39 +00:00
try {
fse.readFile(filePath, (err, data) => {
2019-11-11 06:53:39 +00:00
if (!!err) {
2019-12-18 04:44:26 +00:00
event.returnValue = err;
log.error(`File read failed path[${filePath}] err:`, err);
2019-11-11 06:53:39 +00:00
} else {
2019-12-18 04:44:26 +00:00
event.returnValue = data;
2019-11-11 06:53:39 +00:00
}
});
} catch (error) {
log.error(`File read failed path[${filePath}] err:`, error);
2019-11-11 06:53:39 +00:00
event.returnValue = null;
}
});
ipcMain.on(
FileChannel.SaveFile,
async (event: IpcMainEvent, ...args: any[]) => {
try {
const buffer: Buffer = args[0];
const fileName: string = args[1];
2019-11-13 06:28:33 +00:00
const mimeType: string = args[2];
const customSavePath: string = args[3];
2019-11-11 06:53:39 +00:00
let savePath: string = path.join(
!!appStorage.downloadPath
? appStorage.downloadPath
: app.getPath('downloads'),
2019-11-11 06:53:39 +00:00
fileName
);
if (!!customSavePath) {
savePath = customSavePath;
} else {
savePath = await FileUtil.uniqueFileName(savePath);
}
2019-11-11 06:53:39 +00:00
fse.writeFile(savePath, buffer, err => {
if (!err) {
event.returnValue = savePath;
} else {
event.returnValue = undefined;
}
});
} catch (error) {
event.returnValue = undefined;
}
}
);
ipcMain.on(
FileChannel.OpenFolderItem,
async (event: IpcMainEvent, ...args: any[]) => {
try {
let folderItem: string = args[0];
const make: boolean = args[1];
if (!folderItem) {
2019-12-24 07:16:13 +00:00
folderItem = app.getPath('downloads');
}
let isSuccess = true;
if (make) {
fse.ensureDirSync(folderItem);
}
if (isSuccess && fse.existsSync(folderItem)) {
shell.openItem(folderItem);
} else {
isSuccess = false;
}
if (isSuccess) {
event.returnValue = true;
} else {
event.returnValue = false;
}
} catch (error) {
event.returnValue = false;
}
}
);
2019-12-24 02:41:50 +00:00
ipcMain.on(FileChannel.GetPath, async (event: IpcMainEvent, ...args: any[]) => {
try {
const name: NativePathName = args[0];
event.returnValue = app.getPath(name);
} catch (error) {
event.returnValue = undefined;
}
});
2019-12-24 07:16:13 +00:00
ipcMain.on(
FileChannel.SelectDirectory,
(event: IpcMainEvent, ...args: any[]) => {
dialog
.showOpenDialog(appWindow.browserWindow, {
defaultPath: app.getPath('home'),
properties: ['openDirectory']
})
.then(value => {
event.returnValue = value.filePaths[0];
})
.catch(reason => {
event.returnValue = undefined;
});
}
);
ipcMain.on(
FileChannel.SelectSaveFilePath,
(event: IpcMainEvent, ...args: any[]) => {
2020-01-31 05:46:47 +00:00
const defaultPath = args[0];
const ext = path.extname(defaultPath);
dialog
2020-01-31 05:46:47 +00:00
.showSaveDialog({
defaultPath
})
.then(obj => {
2020-01-31 05:46:47 +00:00
const filePath =
'' !== ext && '' === path.extname(obj.filePath)
? `${obj.filePath}${ext}`
: obj.filePath;
event.returnValue = {
canceled: obj.canceled,
2020-01-31 05:46:47 +00:00
filePath
};
})
.catch(obj => {
event.returnValue = undefined;
});
}
);
2020-01-09 09:52:08 +00:00
ipcMain.on(ProcessChannel.Execute, (event: IpcMainEvent, ...args: any[]) => {
try {
const executableName: string = args[0];
const binPath = __DEV__
? path.join(__dirname, '../../', 'config/build/win/bin/')
2020-01-10 01:37:42 +00:00
: path.join(__dirname, '..', '..', '..', '/bin/');
2020-01-09 09:52:08 +00:00
const executablePath = __WIN32__
? path.join(binPath, `${executableName}.exe`)
: path.join(binPath, executableName);
const childProcess = ChildProcess.spawn(executablePath, [], {
stdio: ['ignore', 'ignore', 'ignore'],
detached: true
});
event.returnValue = childProcess.pid;
} catch (error) {
event.returnValue = undefined;
}
});
2019-11-11 06:53:39 +00:00
ipcMain.on(
IdleStateChannel.StartCheck,
(event: IpcMainEvent, ...args: any[]) => {
if (!!idle) {
idle.destoryChecker();
idle = null;
}
2019-11-11 06:53:39 +00:00
idle = new IdleChecker(appWindow.browserWindow); // default 10min
idle.startChecker();
}
);
ipcMain.on(
IdleStateChannel.StopCheck,
(event: IpcMainEvent, ...args: any[]) => {
if (!!idle) {
idle.destoryChecker();
idle = null;
}
}
);
2019-11-11 06:53:39 +00:00
2020-01-10 07:49:53 +00:00
ipcMain.on(
IdleStateChannel.ChangeLimitTime,
(event: IpcMainEvent, ...args: any[]) => {
const limitTime: number = args[0];
if (!!idle) {
idle.destoryChecker();
idle = null;
2020-01-10 07:49:53 +00:00
}
idle = new IdleChecker(appWindow.browserWindow);
idle.resetIdleTime(limitTime);
2020-01-10 07:49:53 +00:00
}
);
2019-11-11 06:53:39 +00:00
ipcMain.on(
NotificationChannel.Notify,
(event: IpcMainEvent, ...args: any[]) => {
const noti: NotificationRequest = args[0];
notificationService.notify({
title: noti.title,
text: noti.contents,
image:
noti.image ||
2019-12-31 05:15:29 +00:00
path.join(__dirname, 'assets/notification/images/img_nophoto_50.png'),
2019-11-11 06:53:39 +00:00
sound: noti.useSound
? path.join(
'file://',
__dirname,
2019-12-31 05:15:29 +00:00
'assets/notification/sounds/messageAlarm.mp3'
2019-11-11 06:53:39 +00:00
)
: '',
2019-12-20 11:25:51 +00:00
displayTime: !!noti.displayTime ? noti.displayTime : undefined,
onClick: e => {
appWindow.browserWindow.flashFrame(false);
2019-12-17 07:39:02 +00:00
if (noti.type === NotificationType.Event) {
appWindow.browserWindow.webContents.send(
ChatChannel.OpenRoom,
noti.seq
);
} else if (noti.type === NotificationType.Message) {
appWindow.browserWindow.webContents.send(
MessageChannel.OpenMessage,
noti.seq
);
}
appWindow.show();
e.close();
2019-11-18 06:02:24 +00:00
}
2019-11-11 06:53:39 +00:00
});
appWindow.browserWindow.flashFrame(true);
2019-11-11 06:53:39 +00:00
}
);
ipcMain.on(
NotificationChannel.CloseAllNotify,
(event: IpcMainEvent, ...args: any[]) => {
appWindow.browserWindow.flashFrame(false);
2019-11-11 06:53:39 +00:00
}
);
2019-12-15 16:06:07 +00:00
2020-02-04 08:13:09 +00:00
ipcMain.on(ClipboardChannel.Read, (event: IpcMainEvent, ...args: any[]) => {
try {
const text = clipboard.readText('clipboard');
const rtf = clipboard.readRTF('clipboard');
const html = clipboard.readHTML('clipboard');
const image = clipboard.readImage('clipboard');
event.returnValue = {
text,
rtf,
html,
image: !image.isEmpty() ? image.toBitmap() : undefined,
imageDataUrl: !image.isEmpty() ? image.toDataURL() : undefined
};
} catch (error) {
event.returnValue = {};
}
});
2020-01-23 02:23:31 +00:00
ipcMain.on(AppChannel.Exit, (event: IpcMainEvent, ...args: any[]) => {
appExit();
});
2019-12-15 16:06:07 +00:00
autoUpdater.on('checking-for-update', () => {
log.info('Checking for update...');
});
autoUpdater.on('update-available', info => {
log.info(info);
log.info('Update available.');
2020-01-29 06:03:48 +00:00
updateWindowService.show({
latest: info.version,
installed: app.getVersion()
});
2019-12-15 16:06:07 +00:00
});
autoUpdater.on('update-not-available', info => {
log.info('Update not available.');
});
autoUpdater.on('error', err => {
2020-02-05 07:18:17 +00:00
updateWindowService.close();
2019-12-15 16:06:07 +00:00
log.info('Error in auto-updater. ' + err);
});
autoUpdater.on('download-progress', progressObj => {
let logMessage = 'Download speed: ' + progressObj.bytesPerSecond;
logMessage = logMessage + ' - Downloaded ' + progressObj.percent + '%';
logMessage =
logMessage + ' (' + progressObj.transferred + '/' + progressObj.total + ')';
log.info(logMessage);
updateWindowService.setDownloadValue(
progressObj.transferred,
progressObj.total
);
});
autoUpdater.on('update-downloaded', info => {
log.info('Update downloaded');
updateWindowService.setDownloadComplete();
2020-01-23 05:32:46 +00:00
2020-02-10 04:45:02 +00:00
app.removeAllListeners(ElectronAppChannel.WindowAllClosed);
2020-01-29 06:03:48 +00:00
const browserWindows = BrowserWindow.getAllWindows();
// https://github.com/electron-userland/electron-builder/issues/1604#issuecomment-372091881
browserWindows.forEach(browserWindow => {
2020-02-10 04:45:02 +00:00
browserWindow.removeAllListeners(ElectronBrowserWindowChannel.Close);
browserWindow.removeAllListeners(ElectronBrowserWindowChannel.Closed);
2020-01-29 06:03:48 +00:00
});
2020-01-23 05:32:46 +00:00
setTimeout(() => {
2020-02-10 04:45:02 +00:00
updateWindowService.close();
2020-01-23 05:32:46 +00:00
autoUpdater.quitAndInstall(true, true);
}, 2000);
2019-12-15 16:06:07 +00:00
});
2020-01-23 02:23:31 +00:00
function appExit() {
appWindow = null;
app.exit();
}