From 731a9f74a083dcb33d93757d0f7d6b2ee350a6b3 Mon Sep 17 00:00:00 2001 From: leejh Date: Thu, 7 Nov 2019 16:56:14 +0900 Subject: [PATCH] =?UTF-8?q?IDLE=20=EC=B2=B4=ED=81=AC=EB=A1=9C=20=EB=B6=80?= =?UTF-8?q?=EC=9E=AC=EC=A4=91=20<>=20=EC=98=A8=EB=9D=BC=EC=9D=B8=20?= =?UTF-8?q?=EC=83=81=ED=83=9C=20=EB=B3=80=EA=B2=BD=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80.(only=20electron)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main/src/app/AppWindow.ts | 5 +- main/src/index.ts | 12 ++++ main/src/lib/idle-checker.ts | 72 +++++++++++++++++++ .../components/main.page.component.ts | 46 +++++++++++- .../lib/services/browser-native.service.ts | 15 +++- .../lib/services/electron-native.service.ts | 25 ++++++- .../src/lib/types/channel.type.ts | 2 + .../src/lib/services/native.service.ts | 3 + .../src/lib/types/window-idle.type.ts | 4 ++ .../src/public-api.ts | 1 + 10 files changed, 179 insertions(+), 6 deletions(-) create mode 100644 main/src/lib/idle-checker.ts create mode 100644 projects/ucap-webmessenger-native/src/lib/types/window-idle.type.ts diff --git a/main/src/app/AppWindow.ts b/main/src/app/AppWindow.ts index fa811b3b..4e4e1f11 100644 --- a/main/src/app/AppWindow.ts +++ b/main/src/app/AppWindow.ts @@ -6,7 +6,6 @@ import windowStateKeeper from 'electron-window-state'; import { EventEmitter } from 'events'; import { now } from '../util/now'; -import { Channel } from '@ucap-webmessenger/native-electron'; import { registerWindowStateChangedEvents } from '../lib/window-state'; export class AppWindow { @@ -214,4 +213,8 @@ export class AppWindow { public destroy() { this.window.destroy(); } + + public get browserWindow(): BrowserWindow | null { + return this.window; + } } diff --git a/main/src/index.ts b/main/src/index.ts index 6476845f..2a0a55fd 100644 --- a/main/src/index.ts +++ b/main/src/index.ts @@ -12,6 +12,8 @@ import { root } from './util/root'; import { DefaultFolder } from './lib/default-folder'; import { FileUtil } from './lib/file-util'; +import { IdleChecker } from './lib/idle-checker'; + let appWindow: AppWindow | null = null; const launchTime = now(); @@ -53,6 +55,7 @@ process.on('uncaughtException', (error: Error) => { let isDuplicateInstance = false; const gotSingleInstanceLock = app.requestSingleInstanceLock(); isDuplicateInstance = !gotSingleInstanceLock; +let idle: IdleChecker | null; app.on('second-instance', (event, args, workingDirectory) => { // Someone tried to run a second instance, we should focus our window. @@ -216,6 +219,15 @@ ipcMain.on(Channel.saveFile, async (event: IpcMainEvent, ...args: any[]) => { } }); +ipcMain.on(Channel.idleStateStart, (event: IpcMainEvent, ...args: any[]) => { + if (!!idle) { + idle.destoryChecker(); + idle = null; + } + idle = new IdleChecker(appWindow.browserWindow); // default 10min + idle.startChecker(); +}); + ipcMain.on(Channel.showNotify, (event: IpcMainEvent, ...args: any[]) => { console.log('Channel.showNotify', args); }); diff --git a/main/src/lib/idle-checker.ts b/main/src/lib/idle-checker.ts new file mode 100644 index 00000000..f66c3da6 --- /dev/null +++ b/main/src/lib/idle-checker.ts @@ -0,0 +1,72 @@ +import { powerMonitor, BrowserWindow } from 'electron'; +import { Channel } from '@ucap-webmessenger/native-electron'; +import { setInterval } from 'timers'; + +export enum IdleType { + ACTIVE = 'ACT', + IDLE = 'IDLE' +} + +export class IdleChecker { + private limitSec: number; + private intervalObject: any; + private status: IdleType; + private window: BrowserWindow | null; + + public constructor(window: BrowserWindow, limitedMin?: number) { + limitedMin = limitedMin || 10; + + this.limitSec = limitedMin * 60; + this.intervalObject = null; + this.status = IdleType.ACTIVE; + this.window = window; + } + + private doCheckIdle(): void { + const idle: number = powerMonitor.getSystemIdleTime(); + if (idle > this.limitSec) { + if (this.status === IdleType.ACTIVE) { + this.status = IdleType.IDLE; + // TODO :: USER_STATUS change away + this.window.webContents.send(Channel.idleStateChanged, this.status); + } + } else { + if (this.status === IdleType.IDLE) { + this.status = IdleType.ACTIVE; + // TODO :: USER_STATUS chage online + this.window.webContents.send(Channel.idleStateChanged, this.status); + } + } + } + + public resetIdleTime(limitedMin: number): void { + limitedMin = limitedMin || 10; + + if (!!this.intervalObject) { + clearInterval(this.intervalObject); + } + this.limitSec = limitedMin * 60; + + // storage.setIdleTimeLimit(limitedMin); + // global.opt_idleTimeLimit = limitedMin; + + this.startChecker(); + console.log('RESET IDLE TIMER in ' + limitedMin + 'm'); + } + + public startChecker() { + console.log('Idle Checker Start'); + if (!this.intervalObject) { + this.intervalObject = setInterval(() => { + this.doCheckIdle(); + }, 1000); + } + } + + public destoryChecker() { + console.log('Idle Checker Destory'); + if (!!this.intervalObject) { + clearInterval(this.intervalObject); + } + } +} diff --git a/projects/ucap-webmessenger-app/src/app/pages/messenger/components/main.page.component.ts b/projects/ucap-webmessenger-app/src/app/pages/messenger/components/main.page.component.ts index ee73a40a..6f6c3654 100644 --- a/projects/ucap-webmessenger-app/src/app/pages/messenger/components/main.page.component.ts +++ b/projects/ucap-webmessenger-app/src/app/pages/messenger/components/main.page.component.ts @@ -1,9 +1,17 @@ -import { Component, OnInit } from '@angular/core'; +import { map, tap } from 'rxjs/operators'; +import { Component, OnInit, Inject, OnDestroy } from '@angular/core'; import { Store, select } from '@ngrx/store'; import * as AppSotre from '@app/store'; -import { Observable } from 'rxjs'; +import { Observable, Subscription } from 'rxjs'; +import { + WindowIdle, + UCAP_NATIVE_SERVICE, + NativeService +} from '@ucap-webmessenger/native'; +import { StatusProtocolService } from '@ucap-webmessenger/protocol-status'; +import { StatusType, StatusCode } from '@ucap-webmessenger/core'; @Component({ selector: 'app-page-messenger-main', @@ -12,12 +20,44 @@ import { Observable } from 'rxjs'; }) export class MainPageComponent implements OnInit { selectedChat$: Observable; + idleStateChangedSubscription: Subscription; - constructor(private store: Store) {} + constructor( + @Inject(UCAP_NATIVE_SERVICE) private nativeService: NativeService, + private store: Store, + private statusProtocolService: StatusProtocolService + ) {} ngOnInit(): void { this.selectedChat$ = this.store.pipe( select(AppSotre.MessengerSelector.ChatSelector.selectedRoom) ); + + this.idleStateChangedSubscription = this.nativeService + .idleStateChanged() + .subscribe(action => { + console.log(action); + let statusType: StatusCode; + + if (action === 'IDLE') { + // away + statusType = StatusCode.Away; + } else { + // online + statusType = StatusCode.OnLine; + } + + this.statusProtocolService.status({ + statusDivisionType: StatusType.Messenger, + statusType, + statusMessage: '' + }); + }); + } + + OnDestroy(): void { + if (!!this.idleStateChangedSubscription) { + this.idleStateChangedSubscription.unsubscribe(); + } } } diff --git a/projects/ucap-webmessenger-native-browser/src/lib/services/browser-native.service.ts b/projects/ucap-webmessenger-native-browser/src/lib/services/browser-native.service.ts index 1c3d3214..a00afa78 100644 --- a/projects/ucap-webmessenger-native-browser/src/lib/services/browser-native.service.ts +++ b/projects/ucap-webmessenger-native-browser/src/lib/services/browser-native.service.ts @@ -3,7 +3,8 @@ import { Observable } from 'rxjs'; import { NativeService, WindowState, - NotiRequest + NotiRequest, + WindowIdle } from '@ucap-webmessenger/native'; import { HttpClient } from '@angular/common/http'; import { map } from 'rxjs/operators'; @@ -59,5 +60,17 @@ export class BrowserNativeService implements NativeService { windowMaximize(): void {} + idleStateChanged(): Observable { + return new Observable(subscriber => { + try { + subscriber.next(WindowIdle.Active); + } catch (error) { + subscriber.error(error); + } finally { + subscriber.complete(); + } + }); + } + constructor(private httpClient: HttpClient) {} } diff --git a/projects/ucap-webmessenger-native-electron/src/lib/services/electron-native.service.ts b/projects/ucap-webmessenger-native-electron/src/lib/services/electron-native.service.ts index 39a41285..a051e22d 100644 --- a/projects/ucap-webmessenger-native-electron/src/lib/services/electron-native.service.ts +++ b/projects/ucap-webmessenger-native-electron/src/lib/services/electron-native.service.ts @@ -5,7 +5,8 @@ import { Observable, Subject } from 'rxjs'; import { NativeService, WindowState, - NotiRequest + NotiRequest, + WindowIdle } from '@ucap-webmessenger/native'; import { Channel } from '../types/channel.type'; import { share } from 'rxjs/operators'; @@ -14,6 +15,9 @@ export class ElectronNativeService implements NativeService { private windowStateChangedSubject: Subject | null = null; private windowStateChanged$: Observable | null = null; + private idleStateChangedSubject: Subject | null = null; + private idleStateChanged$: Observable | null = null; + showNotify(noti: NotiRequest): void { ipcRenderer.send( Channel.showNotify, @@ -121,5 +125,24 @@ export class ElectronNativeService implements NativeService { } } + idleStateChanged(): Observable { + if (!this.idleStateChangedSubject) { + this.idleStateChangedSubject = new Subject(); + this.idleStateChanged$ = this.idleStateChangedSubject + .asObservable() + .pipe(share()); + } + + ipcRenderer.send(Channel.idleStateStart, 'start'); + + ipcRenderer.on( + Channel.idleStateChanged, + (event: IpcRendererEvent, idleState: WindowIdle) => { + this.idleStateChangedSubject.next(idleState); + } + ); + return this.idleStateChanged$; + } + constructor() {} } diff --git a/projects/ucap-webmessenger-native-electron/src/lib/types/channel.type.ts b/projects/ucap-webmessenger-native-electron/src/lib/types/channel.type.ts index cc86ff5d..89e518ad 100644 --- a/projects/ucap-webmessenger-native-electron/src/lib/types/channel.type.ts +++ b/projects/ucap-webmessenger-native-electron/src/lib/types/channel.type.ts @@ -1,5 +1,7 @@ export enum Channel { windowStateChanged = 'window-state-changed', + idleStateChanged = 'window-idle-state-changed', + idleStateStart = 'window-idle-state-check-start', showNotify = 'UCAP::showNotify', checkForUpdates = 'UCAP::checkForUpdates', diff --git a/projects/ucap-webmessenger-native/src/lib/services/native.service.ts b/projects/ucap-webmessenger-native/src/lib/services/native.service.ts index 4518cef0..bd9c01a0 100644 --- a/projects/ucap-webmessenger-native/src/lib/services/native.service.ts +++ b/projects/ucap-webmessenger-native/src/lib/services/native.service.ts @@ -1,6 +1,7 @@ import { Observable } from 'rxjs'; import { WindowState } from '../types/window-state.type'; +import { WindowIdle } from '../types/window-idle.type'; export interface NativeService { showNotify(noti: NotiRequest): void; @@ -16,6 +17,8 @@ export interface NativeService { windowClose(): void; windowMinimize(): void; windowMaximize(): void; + + idleStateChanged(): Observable; } export interface NotiRequest { diff --git a/projects/ucap-webmessenger-native/src/lib/types/window-idle.type.ts b/projects/ucap-webmessenger-native/src/lib/types/window-idle.type.ts new file mode 100644 index 00000000..531df30e --- /dev/null +++ b/projects/ucap-webmessenger-native/src/lib/types/window-idle.type.ts @@ -0,0 +1,4 @@ +export enum WindowIdle { + Active = 'ACT', + Idle = 'IDLE' +} diff --git a/projects/ucap-webmessenger-native/src/public-api.ts b/projects/ucap-webmessenger-native/src/public-api.ts index 8936d54a..bcd36c4f 100644 --- a/projects/ucap-webmessenger-native/src/public-api.ts +++ b/projects/ucap-webmessenger-native/src/public-api.ts @@ -6,5 +6,6 @@ export * from './lib/services/native.service'; export * from './lib/types/token'; export * from './lib/types/window-state.type'; +export * from './lib/types/window-idle.type'; export * from './lib/ucap-native.module';