electron update window is implemented
This commit is contained in:
parent
2baae8e81c
commit
e4a42d0dcc
@ -1,11 +1,11 @@
|
|||||||
import * as path from 'path';
|
import path from 'path';
|
||||||
import * as url from 'url';
|
import url from 'url';
|
||||||
import * as fse from 'fs-extra';
|
import fse from 'fs-extra';
|
||||||
|
|
||||||
import { AnimationQueue } from '../utils/animation-queue';
|
import { AnimationQueue } from '../utils/animation-queue';
|
||||||
import {
|
import {
|
||||||
ElectronNotificationOptions,
|
ElectronNotificationOptions,
|
||||||
DefaultElectronNotificationOptions,
|
DefaultElectronNotificationOptions
|
||||||
} from '../models/electron-notification-options';
|
} from '../models/electron-notification-options';
|
||||||
import { screen, BrowserWindow, ipcMain, IpcMainEvent, shell } from 'electron';
|
import { screen, BrowserWindow, ipcMain, IpcMainEvent, shell } from 'electron';
|
||||||
import { ElectronNotification } from '../models/electron-notification';
|
import { ElectronNotification } from '../models/electron-notification';
|
||||||
@ -43,12 +43,12 @@ export class ElectronNotificationService {
|
|||||||
|
|
||||||
constructor(options?: ElectronNotificationOptions) {
|
constructor(options?: ElectronNotificationOptions) {
|
||||||
this.customOptions = {
|
this.customOptions = {
|
||||||
...DefaultElectronNotificationOptions,
|
...DefaultElectronNotificationOptions
|
||||||
};
|
};
|
||||||
if (!!options) {
|
if (!!options) {
|
||||||
this.customOptions = {
|
this.customOptions = {
|
||||||
...this.customOptions,
|
...this.customOptions,
|
||||||
...options,
|
...options
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,7 +60,7 @@ export class ElectronNotificationService {
|
|||||||
if (!!options) {
|
if (!!options) {
|
||||||
this.customOptions = {
|
this.customOptions = {
|
||||||
...this.customOptions,
|
...this.customOptions,
|
||||||
...options,
|
...options
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
this.calcDimensions();
|
this.calcDimensions();
|
||||||
@ -89,7 +89,7 @@ export class ElectronNotificationService {
|
|||||||
this.animationQueue.push({
|
this.animationQueue.push({
|
||||||
context: this,
|
context: this,
|
||||||
func: this.showNotification,
|
func: this.showNotification,
|
||||||
args: [notification],
|
args: [notification]
|
||||||
});
|
});
|
||||||
return notification.id;
|
return notification.id;
|
||||||
}
|
}
|
||||||
@ -124,7 +124,7 @@ export class ElectronNotificationService {
|
|||||||
|
|
||||||
this.lowerRightCornerPosition = {
|
this.lowerRightCornerPosition = {
|
||||||
x: display.bounds.x + display.workArea.x + display.workAreaSize.width,
|
x: display.bounds.x + display.workArea.x + display.workAreaSize.width,
|
||||||
y: display.bounds.y + display.workArea.y + display.workAreaSize.height,
|
y: display.bounds.y + display.workArea.y + display.workAreaSize.height
|
||||||
};
|
};
|
||||||
|
|
||||||
this.calcDimensions();
|
this.calcDimensions();
|
||||||
@ -177,7 +177,7 @@ export class ElectronNotificationService {
|
|||||||
notificationWindow[onClickElectronNotification]({
|
notificationWindow[onClickElectronNotification]({
|
||||||
type: ElectronNotificationEventType.Click,
|
type: ElectronNotificationEventType.Click,
|
||||||
id: notification.id,
|
id: notification.id,
|
||||||
close: self.buildCloseNotificationSafely(onClose),
|
close: self.buildCloseNotificationSafely(onClose)
|
||||||
});
|
});
|
||||||
delete notificationWindow[onClickElectronNotification];
|
delete notificationWindow[onClickElectronNotification];
|
||||||
}
|
}
|
||||||
@ -188,17 +188,17 @@ export class ElectronNotificationService {
|
|||||||
private calcDimensions() {
|
private calcDimensions() {
|
||||||
this.totalDimension = {
|
this.totalDimension = {
|
||||||
width: this.customOptions.width + this.customOptions.padding,
|
width: this.customOptions.width + this.customOptions.padding,
|
||||||
height: this.customOptions.height + this.customOptions.padding,
|
height: this.customOptions.height + this.customOptions.padding
|
||||||
};
|
};
|
||||||
|
|
||||||
this.firstPosition = {
|
this.firstPosition = {
|
||||||
x: this.lowerRightCornerPosition.x - this.totalDimension.width,
|
x: this.lowerRightCornerPosition.x - this.totalDimension.width,
|
||||||
y: this.lowerRightCornerPosition.y - this.totalDimension.height,
|
y: this.lowerRightCornerPosition.y - this.totalDimension.height
|
||||||
};
|
};
|
||||||
|
|
||||||
this.nextInsertPosition = {
|
this.nextInsertPosition = {
|
||||||
x: this.firstPosition.x,
|
x: this.firstPosition.x,
|
||||||
y: this.firstPosition.y,
|
y: this.firstPosition.y
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -217,7 +217,7 @@ export class ElectronNotificationService {
|
|||||||
this.templateUrl = url.format({
|
this.templateUrl = url.format({
|
||||||
pathname: this.customOptions.templatePath,
|
pathname: this.customOptions.templatePath,
|
||||||
protocol: 'file:',
|
protocol: 'file:',
|
||||||
slashes: true,
|
slashes: true
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log(
|
console.log(
|
||||||
@ -266,7 +266,7 @@ export class ElectronNotificationService {
|
|||||||
notification.onShow({
|
notification.onShow({
|
||||||
type: ElectronNotificationEventType.Show,
|
type: ElectronNotificationEventType.Show,
|
||||||
id: notification.id,
|
id: notification.id,
|
||||||
close: onCloseNotificationSafely,
|
close: onCloseNotificationSafely
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -321,7 +321,7 @@ export class ElectronNotificationService {
|
|||||||
if (!!notificationWindow[onCloseElectronNotification]) {
|
if (!!notificationWindow[onCloseElectronNotification]) {
|
||||||
notificationWindow[onCloseElectronNotification]({
|
notificationWindow[onCloseElectronNotification]({
|
||||||
type: e,
|
type: e,
|
||||||
id: notification.id,
|
id: notification.id
|
||||||
});
|
});
|
||||||
delete notificationWindow[onCloseElectronNotification];
|
delete notificationWindow[onCloseElectronNotification];
|
||||||
}
|
}
|
||||||
@ -353,7 +353,7 @@ export class ElectronNotificationService {
|
|||||||
self.animationQueue.push({
|
self.animationQueue.push({
|
||||||
context: self,
|
context: self,
|
||||||
func: onClose,
|
func: onClose,
|
||||||
args: [reason],
|
args: [reason]
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -366,7 +366,7 @@ export class ElectronNotificationService {
|
|||||||
this.animationQueue.push({
|
this.animationQueue.push({
|
||||||
context: this,
|
context: this,
|
||||||
func: this.showNotification,
|
func: this.showNotification,
|
||||||
args: [this.notificationQueue.shift()],
|
args: [this.notificationQueue.shift()]
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,22 @@
|
|||||||
|
import { BrowserWindowConstructorOptions } from 'electron';
|
||||||
|
|
||||||
|
export interface ElectronUpdateWindowOptions
|
||||||
|
extends BrowserWindowConstructorOptions {
|
||||||
|
templatePath?: string;
|
||||||
|
onReady?: () => void;
|
||||||
|
onAcceptUpdate?: () => void;
|
||||||
|
onDenyUpdate?: () => void;
|
||||||
|
onCancelDownload?: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const DefaultElectronUpdateWindowOptions: ElectronUpdateWindowOptions = {
|
||||||
|
width: 500,
|
||||||
|
height: 160,
|
||||||
|
frame: false,
|
||||||
|
skipTaskbar: true,
|
||||||
|
alwaysOnTop: true,
|
||||||
|
maximizable: false,
|
||||||
|
webPreferences: {
|
||||||
|
nodeIntegration: true
|
||||||
|
}
|
||||||
|
};
|
@ -1 +1,122 @@
|
|||||||
export class ElectronUpdateWindowService {}
|
import { BrowserWindow, ipcMain } from 'electron';
|
||||||
|
import url from 'url';
|
||||||
|
import fse from 'fs-extra';
|
||||||
|
import {
|
||||||
|
ElectronUpdateWindowOptions,
|
||||||
|
DefaultElectronUpdateWindowOptions
|
||||||
|
} from '../models/electron-update-window-options';
|
||||||
|
|
||||||
|
import { Channel } from '../types/channel.type';
|
||||||
|
|
||||||
|
export class ElectronUpdateWindowService {
|
||||||
|
private customOptions: ElectronUpdateWindowOptions;
|
||||||
|
private browserWindow: BrowserWindow;
|
||||||
|
private templateUrl: string;
|
||||||
|
|
||||||
|
constructor(options: ElectronUpdateWindowOptions) {
|
||||||
|
this.customOptions = {
|
||||||
|
...DefaultElectronUpdateWindowOptions
|
||||||
|
};
|
||||||
|
if (!!options) {
|
||||||
|
this.customOptions = {
|
||||||
|
...this.customOptions,
|
||||||
|
...options
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
set options(options: ElectronUpdateWindowOptions) {
|
||||||
|
if (!!options) {
|
||||||
|
this.customOptions = {
|
||||||
|
...this.customOptions,
|
||||||
|
...options
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
get options(): ElectronUpdateWindowOptions {
|
||||||
|
return this.customOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
set templatePath(templatePath: string) {
|
||||||
|
if (!!templatePath) {
|
||||||
|
this.customOptions.templatePath = templatePath;
|
||||||
|
this.updateTemplatePath();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
get templatePath(): string {
|
||||||
|
if (!this.templateUrl) {
|
||||||
|
this.updateTemplatePath();
|
||||||
|
}
|
||||||
|
return this.templateUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
show() {
|
||||||
|
this.browserWindow = new BrowserWindow(this.customOptions);
|
||||||
|
this.browserWindow.loadURL(this.templatePath);
|
||||||
|
|
||||||
|
this.browserWindow.on('closed', () => {
|
||||||
|
this.browserWindow = null;
|
||||||
|
});
|
||||||
|
this.browserWindow.webContents.on('did-finish-load', () => {
|
||||||
|
if (process.env.NODE_ENV === 'development') {
|
||||||
|
this.browserWindow.webContents.openDevTools();
|
||||||
|
}
|
||||||
|
if (!!this.customOptions.onReady) {
|
||||||
|
this.customOptions.onReady();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
ipcMain.on(Channel.acceptUpdate, this._acceptUpdateHandler.bind(this));
|
||||||
|
ipcMain.on(Channel.denyUpdate, this._denyUpdateHandler.bind(this));
|
||||||
|
ipcMain.on(Channel.cancelDownload, this._cancelDownloadHandler.bind(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
setDownloadValue(value: number, total: number) {
|
||||||
|
this.browserWindow.webContents.send(Channel.downloadProcess, value, total);
|
||||||
|
}
|
||||||
|
setDownloadComplete() {
|
||||||
|
this.browserWindow.webContents.send(Channel.downloadComplete);
|
||||||
|
}
|
||||||
|
close() {
|
||||||
|
if (!this.browserWindow || this.browserWindow.isDestroyed()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.browserWindow.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
_acceptUpdateHandler() {
|
||||||
|
if (!!this.customOptions.onAcceptUpdate) {
|
||||||
|
this.customOptions.onAcceptUpdate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_denyUpdateHandler() {
|
||||||
|
if (!!this.customOptions.onDenyUpdate) {
|
||||||
|
this.customOptions.onDenyUpdate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_cancelDownloadHandler() {
|
||||||
|
if (!!this.customOptions.onCancelDownload) {
|
||||||
|
this.customOptions.onCancelDownload();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private updateTemplatePath() {
|
||||||
|
try {
|
||||||
|
fse.statSync(this.customOptions.templatePath).isFile();
|
||||||
|
|
||||||
|
this.templateUrl = url.format({
|
||||||
|
pathname: this.customOptions.templatePath,
|
||||||
|
protocol: 'file:',
|
||||||
|
slashes: true
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
console.log(
|
||||||
|
'electron-update-window: Could not find template ("' +
|
||||||
|
this.customOptions.templatePath +
|
||||||
|
'").'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -0,0 +1,8 @@
|
|||||||
|
export enum Channel {
|
||||||
|
acceptUpdate = 'UCAP::ElectronUpdateWindow::acceptUpdate',
|
||||||
|
denyUpdate = 'UCAP::ElectronUpdateWindow::denyUpdate',
|
||||||
|
cancelDownload = 'UCAP::ElectronUpdateWindow::cancelDownload',
|
||||||
|
|
||||||
|
downloadProcess = 'UCAP::ElectronUpdateWindow::downloadProcess',
|
||||||
|
downloadComplete = 'UCAP::ElectronUpdateWindow::downloadComplete'
|
||||||
|
}
|
@ -1,3 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Public API Surface of ucap-webmessenger-electron-update-window
|
* Public API Surface of ucap-webmessenger-electron-update-window
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
export * from './lib/models/electron-update-window-options';
|
||||||
|
export * from './lib/services/electron-update-window.service';
|
||||||
|
export * from './lib/types/channel.type';
|
||||||
|
Binary file not shown.
After Width: | Height: | Size: 3.5 KiB |
@ -0,0 +1,57 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const { ipcRenderer } = require('electron');
|
||||||
|
|
||||||
|
const updateWindowContainer = document.getElementById(
|
||||||
|
'update-window-container'
|
||||||
|
);
|
||||||
|
|
||||||
|
const confirmation = document.getElementById('confirmation');
|
||||||
|
const downloading = document.getElementById('downloading');
|
||||||
|
const update = document.getElementById('update');
|
||||||
|
|
||||||
|
const confirmationOk = document.getElementById('confirmation-ok');
|
||||||
|
const confirmationCancel = document.getElementById('confirmation-cancel');
|
||||||
|
|
||||||
|
const downloadingProgressBar = document.getElementById(
|
||||||
|
'downloading-progress-bar'
|
||||||
|
);
|
||||||
|
const downloadingProgressLabel = document.getElementById(
|
||||||
|
'downloading-progress-label'
|
||||||
|
);
|
||||||
|
const downloadingCancel = document.getElementById('downloading-cancel');
|
||||||
|
|
||||||
|
confirmationOk &&
|
||||||
|
confirmationOk.addEventListener('click', e => {
|
||||||
|
console.log('UCAP::ElectronUpdateWindow::acceptUpdate');
|
||||||
|
ipcRenderer.send('UCAP::ElectronUpdateWindow::acceptUpdate');
|
||||||
|
downloadingProgressBar.style.width = `0%`;
|
||||||
|
downloadingProgressLabel.innerText = `0%`;
|
||||||
|
updateWindowContainer.style.transform = 'translateX(-500px)';
|
||||||
|
});
|
||||||
|
|
||||||
|
confirmationCancel &&
|
||||||
|
confirmationCancel.addEventListener('click', e => {
|
||||||
|
ipcRenderer.send('UCAP::ElectronUpdateWindow::denyUpdate');
|
||||||
|
});
|
||||||
|
|
||||||
|
downloadingCancel &&
|
||||||
|
downloadingCancel.addEventListener('click', e => {
|
||||||
|
ipcRenderer.send('UCAP::ElectronUpdateWindow::cancelDownload');
|
||||||
|
});
|
||||||
|
|
||||||
|
ipcRenderer.on(
|
||||||
|
'UCAP::ElectronUpdateWindow::downloadProcess',
|
||||||
|
(event, ...args) => {
|
||||||
|
const percentage = (args[0] / args[1]) * 100;
|
||||||
|
downloadingProgressBar.style.width = `${percentage}%`;
|
||||||
|
downloadingProgressLabel.innerText = `${percentage}%`;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
ipcRenderer.on(
|
||||||
|
'UCAP::ElectronUpdateWindow::downloadComplete',
|
||||||
|
(event, ...args) => {
|
||||||
|
updateWindowContainer.style.transform = 'translateX(-1000px)';
|
||||||
|
}
|
||||||
|
);
|
@ -0,0 +1,230 @@
|
|||||||
|
@charset "utf-8";
|
||||||
|
|
||||||
|
html {
|
||||||
|
height: 100%;
|
||||||
|
overflow-y: hidden;
|
||||||
|
-webkit-user-select: none;
|
||||||
|
-webkit-app-region: drag;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
position: absolute;
|
||||||
|
width: 500px;
|
||||||
|
height: 160px;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
color: #333;
|
||||||
|
font-family: '나눔고딕', Malgun Gothic, '맑은고딕', Arial, Dotum, '돋움',
|
||||||
|
Gulim, '굴림';
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 18px !important;
|
||||||
|
-webkit-box-sizing: border-box;
|
||||||
|
-moz-box-sizing: border-box;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
div,
|
||||||
|
p,
|
||||||
|
ol,
|
||||||
|
ul,
|
||||||
|
li,
|
||||||
|
h1,
|
||||||
|
h2,
|
||||||
|
h3,
|
||||||
|
h4,
|
||||||
|
h5,
|
||||||
|
h6,
|
||||||
|
form,
|
||||||
|
iframe,
|
||||||
|
dl,
|
||||||
|
dt,
|
||||||
|
dd,
|
||||||
|
a {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
-webkit-box-sizing: border-box;
|
||||||
|
-moz-box-sizing: border-box;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.no-drag {
|
||||||
|
-webkit-app-region: no-drag;
|
||||||
|
}
|
||||||
|
|
||||||
|
.popup {
|
||||||
|
border: 1px solid #666;
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
.popup header {
|
||||||
|
width: 100%;
|
||||||
|
height: 36px;
|
||||||
|
background-image: none;
|
||||||
|
color: #6f6f6f;
|
||||||
|
background-color: #fff;
|
||||||
|
border-bottom: solid 1px #28abdb;
|
||||||
|
}
|
||||||
|
.popup header h1 {
|
||||||
|
width: 100%;
|
||||||
|
background: none;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 50px;
|
||||||
|
font-size: 14px;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
.popup .btn_close {
|
||||||
|
position: absolute;
|
||||||
|
top: 4px;
|
||||||
|
right: 4px;
|
||||||
|
width: 20px;
|
||||||
|
height: 25px;
|
||||||
|
font-size: 0;
|
||||||
|
margin-right: 6px;
|
||||||
|
vertical-align: middle;
|
||||||
|
background: url(../images/btnimg_top_close.png) no-repeat 50% 50%;
|
||||||
|
}
|
||||||
|
.popup .btn_close:hover {
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
.versionup .btns {
|
||||||
|
height: 50px;
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
.btns ul {
|
||||||
|
list-style: none;
|
||||||
|
}
|
||||||
|
.btns li {
|
||||||
|
display: inline-block;
|
||||||
|
width: 70px;
|
||||||
|
height: 30px;
|
||||||
|
margin: 0 2px;
|
||||||
|
}
|
||||||
|
.btns li a {
|
||||||
|
display: block;
|
||||||
|
width: 70px;
|
||||||
|
height: 30px;
|
||||||
|
border-radius: 3px;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 28px;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
.btnNormal {
|
||||||
|
background-color: #eee;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
.btnSpecial {
|
||||||
|
background-color: #3385bd;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
.btns li a:hover {
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
|
||||||
|
#update-window-container {
|
||||||
|
position: absolute;
|
||||||
|
width: 1500px;
|
||||||
|
height: 160px;
|
||||||
|
overflow: hidden;
|
||||||
|
margin-top: 0px;
|
||||||
|
margin-left: 0px;
|
||||||
|
|
||||||
|
-webkit-transition: all 500ms ease-in-out;
|
||||||
|
-moz-transition: all 500ms ease-in-out;
|
||||||
|
-o-transition: all 500ms ease-in-out;
|
||||||
|
transition: all 500ms ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************************************************************************
|
||||||
|
.versionup
|
||||||
|
*******************************************************************************************************************************************/
|
||||||
|
/* .versionup {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 500px;
|
||||||
|
}
|
||||||
|
.versionup.on {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
} */
|
||||||
|
.versionup {
|
||||||
|
width: 500px;
|
||||||
|
height: 160px;
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
.versionup header {
|
||||||
|
height: 50px !important;
|
||||||
|
border-bottom: none !important;
|
||||||
|
}
|
||||||
|
.versionup header h1 {
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 50px;
|
||||||
|
}
|
||||||
|
.versionup .download p {
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
.versionup .download {
|
||||||
|
position: relative;
|
||||||
|
padding: 0 20px;
|
||||||
|
}
|
||||||
|
.versionup .btns {
|
||||||
|
height: 50px;
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.versionup.step1 {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.versionup.step2 {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.versionup.step3 {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************************************************************************
|
||||||
|
progress
|
||||||
|
*******************************************************************************************************************************************/
|
||||||
|
.progress {
|
||||||
|
background-color: #efefef;
|
||||||
|
height: 12px;
|
||||||
|
margin: 0 !important;
|
||||||
|
}
|
||||||
|
.progress .bar {
|
||||||
|
width: 0%;
|
||||||
|
height: 12px;
|
||||||
|
position: relative;
|
||||||
|
color: #fff;
|
||||||
|
font-size: 11px;
|
||||||
|
text-align: right;
|
||||||
|
margin: 0 !important;
|
||||||
|
line-height: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*theme별 색상변경*/
|
||||||
|
.versionup .download p {
|
||||||
|
color: #13b7eb;
|
||||||
|
}
|
||||||
|
.progress .bar {
|
||||||
|
background-color: #13b7eb;
|
||||||
|
}
|
@ -0,0 +1,86 @@
|
|||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>DS Talk Update</title>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||||
|
<link type="text/css" rel="stylesheet" href="styles/update-window.css" />
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div id="update-window-container">
|
||||||
|
<!--[S]버전다운로드-->
|
||||||
|
<div id="confirmation" class="versionup popup step1">
|
||||||
|
<header>
|
||||||
|
<h1>DS Talk의 새로운 버전이 존재합니다.</h1>
|
||||||
|
</header>
|
||||||
|
<!-- <a class="no-drag btn_close">
|
||||||
|
<label class="global">닫기</label>
|
||||||
|
</a> -->
|
||||||
|
<div class="download">
|
||||||
|
<p>업데이트 하시겠습니까?</p>
|
||||||
|
</div>
|
||||||
|
<div class="btns">
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<a id="confirmation-ok" href="#" class="no-drag btnSpecial">
|
||||||
|
<label class="global">확인</label>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a id="confirmation-cancel" href="#" class="no-drag btnNormal">
|
||||||
|
<label class="global">취소</label>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!--[E]버전다운로드-->
|
||||||
|
<!--[S]버전다운로드-->
|
||||||
|
<div id="downloading" class="versionup popup step2">
|
||||||
|
<header>
|
||||||
|
<h1>다운로드</h1>
|
||||||
|
</header>
|
||||||
|
<!-- <a class="no-drag btn_close">
|
||||||
|
<label class="global">닫기</label>
|
||||||
|
</a> -->
|
||||||
|
<div class="download">
|
||||||
|
<p>잠시만 기다려 주십시오</p>
|
||||||
|
<div class="progress">
|
||||||
|
<div id="downloading-progress-bar" class="bar" style="width:50%;">
|
||||||
|
<label id="downloading-progress-label">50%</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="btns">
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<a id="downloading-cancel" href="#" class="no-drag btnNormal">
|
||||||
|
<label class="global">취소</label>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!--[E]버전다운로드-->
|
||||||
|
<!--[S]버전다운로드-->
|
||||||
|
<div id="update" class="versionup popup step3">
|
||||||
|
<header>
|
||||||
|
<h1>다운로드 완료</h1>
|
||||||
|
</header>
|
||||||
|
<!-- <a class="no-drag btn_close">
|
||||||
|
<label class="global">닫기</label>
|
||||||
|
</a> -->
|
||||||
|
<div class="download">
|
||||||
|
<p>업데이트를 설치하고 DS Talk을 재시작합니다.</p>
|
||||||
|
</div>
|
||||||
|
<div class="btns">
|
||||||
|
<ul></ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!--[E]버전다운로드-->
|
||||||
|
</div>
|
||||||
|
<script src="preload.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -1,6 +1,7 @@
|
|||||||
import { app, ipcMain, IpcMainEvent, Tray, Menu, shell } from 'electron';
|
import { app, ipcMain, IpcMainEvent, Tray, Menu, shell } from 'electron';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import fse from 'fs-extra';
|
import fse from 'fs-extra';
|
||||||
|
import semver from 'semver';
|
||||||
|
|
||||||
import { AppWindow } from './app/AppWindow';
|
import { AppWindow } from './app/AppWindow';
|
||||||
import { now } from './util/now';
|
import { now } from './util/now';
|
||||||
@ -15,6 +16,7 @@ import {
|
|||||||
MessengerChannel
|
MessengerChannel
|
||||||
} from '@ucap-webmessenger/native-electron';
|
} from '@ucap-webmessenger/native-electron';
|
||||||
import { ElectronNotificationService } from '@ucap-webmessenger/electron-notification';
|
import { ElectronNotificationService } from '@ucap-webmessenger/electron-notification';
|
||||||
|
import { ElectronUpdateWindowService } from '@ucap-webmessenger/electron-update-window';
|
||||||
|
|
||||||
import { root } from './util/root';
|
import { root } from './util/root';
|
||||||
import { DefaultFolder } from './lib/default-folder';
|
import { DefaultFolder } from './lib/default-folder';
|
||||||
@ -48,6 +50,7 @@ let onDidLoadFns: Array<OnDidLoadFn> | null = [];
|
|||||||
let preventQuit = false;
|
let preventQuit = false;
|
||||||
|
|
||||||
let notificationService: ElectronNotificationService | null;
|
let notificationService: ElectronNotificationService | null;
|
||||||
|
let updateWindowService: ElectronUpdateWindowService | null;
|
||||||
|
|
||||||
function handleUncaughtException(error: Error) {
|
function handleUncaughtException(error: Error) {
|
||||||
preventQuit = true;
|
preventQuit = true;
|
||||||
@ -242,6 +245,41 @@ app.on(ElectronAppChannel.Ready, () => {
|
|||||||
'resources/notification/template.html'
|
'resources/notification/template.html'
|
||||||
);
|
);
|
||||||
|
|
||||||
|
updateWindowService = new ElectronUpdateWindowService({
|
||||||
|
width: 500,
|
||||||
|
height: 160,
|
||||||
|
frame: false,
|
||||||
|
skipTaskbar: true,
|
||||||
|
alwaysOnTop: true,
|
||||||
|
maximizable: false,
|
||||||
|
onReady: () => {},
|
||||||
|
onAcceptUpdate: () => {
|
||||||
|
log.info('OnAcceptUpdate');
|
||||||
|
autoUpdaterCancellationToken = new CancellationToken();
|
||||||
|
autoUpdater.downloadUpdate(autoUpdaterCancellationToken);
|
||||||
|
},
|
||||||
|
onDenyUpdate: () => {
|
||||||
|
log.info('OnDenyUpdate');
|
||||||
|
updateWindowService.close();
|
||||||
|
},
|
||||||
|
onCancelDownload: () => {
|
||||||
|
autoUpdaterCancellationToken.cancel();
|
||||||
|
updateWindowService.close();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
updateWindowService.options.webPreferences.preload = path.join(
|
||||||
|
__dirname,
|
||||||
|
'resources/update-window/preload.js'
|
||||||
|
);
|
||||||
|
|
||||||
|
updateWindowService.templatePath = path.join(
|
||||||
|
__dirname,
|
||||||
|
'resources/update-window/template.html'
|
||||||
|
);
|
||||||
|
|
||||||
|
// updateWindowService.show();
|
||||||
|
|
||||||
ipcMain.on('uncaught-exception', (event: IpcMainEvent, error: Error) => {
|
ipcMain.on('uncaught-exception', (event: IpcMainEvent, error: Error) => {
|
||||||
handleUncaughtException(error);
|
handleUncaughtException(error);
|
||||||
});
|
});
|
||||||
@ -281,7 +319,13 @@ function onDidLoad(fn: OnDidLoadFn) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ipcMain.on(UpdaterChannel.Check, (event: IpcMainEvent, ...args: any[]) => {
|
ipcMain.on(UpdaterChannel.Check, (event: IpcMainEvent, ...args: any[]) => {
|
||||||
event.returnValue = false;
|
const ver = args[0];
|
||||||
|
if (semver.lt(app.getVersion(), ver)) {
|
||||||
|
autoUpdater.checkForUpdatesAndNotify();
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
ipcMain.on(
|
ipcMain.on(
|
||||||
@ -443,3 +487,37 @@ ipcMain.on(
|
|||||||
console.log('Channel.closeAllNotify', args);
|
console.log('Channel.closeAllNotify', args);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
autoUpdater.on('checking-for-update', () => {
|
||||||
|
log.info('Checking for update...');
|
||||||
|
});
|
||||||
|
autoUpdater.on('update-available', info => {
|
||||||
|
log.info(info);
|
||||||
|
log.info('Update available.');
|
||||||
|
|
||||||
|
updateWindowService.show();
|
||||||
|
});
|
||||||
|
autoUpdater.on('update-not-available', info => {
|
||||||
|
log.info('Update not available.');
|
||||||
|
});
|
||||||
|
autoUpdater.on('error', err => {
|
||||||
|
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();
|
||||||
|
autoUpdater.quitAndInstall(true, true);
|
||||||
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user