diff --git a/electron-projects/ucap-webmessenger-electron-notification/src/lib/services/electron-notification.service.ts b/electron-projects/ucap-webmessenger-electron-notification/src/lib/services/electron-notification.service.ts index ea13e059..0fdc8062 100644 --- a/electron-projects/ucap-webmessenger-electron-notification/src/lib/services/electron-notification.service.ts +++ b/electron-projects/ucap-webmessenger-electron-notification/src/lib/services/electron-notification.service.ts @@ -1,11 +1,11 @@ -import * as path from 'path'; -import * as url from 'url'; -import * as fse from 'fs-extra'; +import path from 'path'; +import url from 'url'; +import fse from 'fs-extra'; import { AnimationQueue } from '../utils/animation-queue'; import { ElectronNotificationOptions, - DefaultElectronNotificationOptions, + DefaultElectronNotificationOptions } from '../models/electron-notification-options'; import { screen, BrowserWindow, ipcMain, IpcMainEvent, shell } from 'electron'; import { ElectronNotification } from '../models/electron-notification'; @@ -43,12 +43,12 @@ export class ElectronNotificationService { constructor(options?: ElectronNotificationOptions) { this.customOptions = { - ...DefaultElectronNotificationOptions, + ...DefaultElectronNotificationOptions }; if (!!options) { this.customOptions = { ...this.customOptions, - ...options, + ...options }; } @@ -60,7 +60,7 @@ export class ElectronNotificationService { if (!!options) { this.customOptions = { ...this.customOptions, - ...options, + ...options }; } this.calcDimensions(); @@ -89,7 +89,7 @@ export class ElectronNotificationService { this.animationQueue.push({ context: this, func: this.showNotification, - args: [notification], + args: [notification] }); return notification.id; } @@ -124,7 +124,7 @@ export class ElectronNotificationService { this.lowerRightCornerPosition = { 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(); @@ -177,7 +177,7 @@ export class ElectronNotificationService { notificationWindow[onClickElectronNotification]({ type: ElectronNotificationEventType.Click, id: notification.id, - close: self.buildCloseNotificationSafely(onClose), + close: self.buildCloseNotificationSafely(onClose) }); delete notificationWindow[onClickElectronNotification]; } @@ -188,17 +188,17 @@ export class ElectronNotificationService { private calcDimensions() { this.totalDimension = { width: this.customOptions.width + this.customOptions.padding, - height: this.customOptions.height + this.customOptions.padding, + height: this.customOptions.height + this.customOptions.padding }; this.firstPosition = { x: this.lowerRightCornerPosition.x - this.totalDimension.width, - y: this.lowerRightCornerPosition.y - this.totalDimension.height, + y: this.lowerRightCornerPosition.y - this.totalDimension.height }; this.nextInsertPosition = { x: this.firstPosition.x, - y: this.firstPosition.y, + y: this.firstPosition.y }; } @@ -217,7 +217,7 @@ export class ElectronNotificationService { this.templateUrl = url.format({ pathname: this.customOptions.templatePath, protocol: 'file:', - slashes: true, + slashes: true }); } catch (e) { console.log( @@ -266,7 +266,7 @@ export class ElectronNotificationService { notification.onShow({ type: ElectronNotificationEventType.Show, id: notification.id, - close: onCloseNotificationSafely, + close: onCloseNotificationSafely }); } @@ -321,7 +321,7 @@ export class ElectronNotificationService { if (!!notificationWindow[onCloseElectronNotification]) { notificationWindow[onCloseElectronNotification]({ type: e, - id: notification.id, + id: notification.id }); delete notificationWindow[onCloseElectronNotification]; } @@ -353,7 +353,7 @@ export class ElectronNotificationService { self.animationQueue.push({ context: self, func: onClose, - args: [reason], + args: [reason] }); }; } @@ -366,7 +366,7 @@ export class ElectronNotificationService { this.animationQueue.push({ context: this, func: this.showNotification, - args: [this.notificationQueue.shift()], + args: [this.notificationQueue.shift()] }); } } diff --git a/electron-projects/ucap-webmessenger-electron-update-window/src/lib/models/electron-update-window-options.ts b/electron-projects/ucap-webmessenger-electron-update-window/src/lib/models/electron-update-window-options.ts new file mode 100644 index 00000000..2f509efe --- /dev/null +++ b/electron-projects/ucap-webmessenger-electron-update-window/src/lib/models/electron-update-window-options.ts @@ -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 + } +}; diff --git a/electron-projects/ucap-webmessenger-electron-update-window/src/lib/services/electron-update-window.service.ts b/electron-projects/ucap-webmessenger-electron-update-window/src/lib/services/electron-update-window.service.ts index 886ec675..127a550f 100644 --- a/electron-projects/ucap-webmessenger-electron-update-window/src/lib/services/electron-update-window.service.ts +++ b/electron-projects/ucap-webmessenger-electron-update-window/src/lib/services/electron-update-window.service.ts @@ -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 + + '").' + ); + } + } +} diff --git a/electron-projects/ucap-webmessenger-electron-update-window/src/lib/types/channel.type.ts b/electron-projects/ucap-webmessenger-electron-update-window/src/lib/types/channel.type.ts new file mode 100644 index 00000000..e6096c75 --- /dev/null +++ b/electron-projects/ucap-webmessenger-electron-update-window/src/lib/types/channel.type.ts @@ -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' +} diff --git a/electron-projects/ucap-webmessenger-electron-update-window/src/public-api.ts b/electron-projects/ucap-webmessenger-electron-update-window/src/public-api.ts index 8efee9e2..792a87f2 100644 --- a/electron-projects/ucap-webmessenger-electron-update-window/src/public-api.ts +++ b/electron-projects/ucap-webmessenger-electron-update-window/src/public-api.ts @@ -1,3 +1,7 @@ /* * 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'; diff --git a/electron-projects/ucap-webmessenger-electron/resources/update-window/images/btnimg_top_close.png b/electron-projects/ucap-webmessenger-electron/resources/update-window/images/btnimg_top_close.png new file mode 100644 index 00000000..0ce0aba0 Binary files /dev/null and b/electron-projects/ucap-webmessenger-electron/resources/update-window/images/btnimg_top_close.png differ diff --git a/electron-projects/ucap-webmessenger-electron/resources/update-window/preload.js b/electron-projects/ucap-webmessenger-electron/resources/update-window/preload.js index e69de29b..c1129d0b 100644 --- a/electron-projects/ucap-webmessenger-electron/resources/update-window/preload.js +++ b/electron-projects/ucap-webmessenger-electron/resources/update-window/preload.js @@ -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)'; + } +); diff --git a/electron-projects/ucap-webmessenger-electron/resources/update-window/styles/update-window.css b/electron-projects/ucap-webmessenger-electron/resources/update-window/styles/update-window.css new file mode 100644 index 00000000..d40e3fbb --- /dev/null +++ b/electron-projects/ucap-webmessenger-electron/resources/update-window/styles/update-window.css @@ -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; +} diff --git a/electron-projects/ucap-webmessenger-electron/resources/update-window/template.html b/electron-projects/ucap-webmessenger-electron/resources/update-window/template.html index e69de29b..9e697844 100644 --- a/electron-projects/ucap-webmessenger-electron/resources/update-window/template.html +++ b/electron-projects/ucap-webmessenger-electron/resources/update-window/template.html @@ -0,0 +1,86 @@ + + +
+업데이트를 설치하고 DS Talk을 재시작합니다.
+