diff --git a/electron-projects/ucap-webmessenger-electron/src/app/AppWindow.ts b/electron-projects/ucap-webmessenger-electron/src/app/AppWindow.ts index 5e4be5bd..04c28b04 100644 --- a/electron-projects/ucap-webmessenger-electron/src/app/AppWindow.ts +++ b/electron-projects/ucap-webmessenger-electron/src/app/AppWindow.ts @@ -17,9 +17,11 @@ import { import { now } from '../util/now'; import { Storage } from '../lib/storage'; import { WindowStateChannel } from '@ucap-webmessenger/native-electron'; +import { Browser } from 'protractor'; export class AppWindow { private window: BrowserWindow | null = null; + private mainWindowId: number; private eventEmitter = new EventEmitter(); @@ -74,6 +76,7 @@ export class AppWindow { } this.window = new BrowserWindow(windowOptions); + this.mainWindowId = this.window.id; savedWindowState.manage(this.window); let quitting = true; @@ -87,21 +90,27 @@ export class AppWindow { }); // windows Focus or Blur state detacted. - this.window.on(ElectronBrowserWindowChannel.Focus, () => { - if (__WIN32__) { - // this.window.flashFrame(false); - } + this.window.on(ElectronBrowserWindowChannel.Focus, e => { + const allBrowsers = BrowserWindow.getAllWindows(); + const mainBrowsers = BrowserWindow.fromId(this.mainWindowId); - this.window.webContents.send( - WindowStateChannel.FocuseChanged, - ElectronBrowserWindowChannel.Focus - ); + if (!!mainBrowsers && !!mainBrowsers.isFocused()) { + this.window.webContents.send( + WindowStateChannel.FocuseChanged, + ElectronBrowserWindowChannel.Focus + ); + } }); - this.window.on(ElectronBrowserWindowChannel.Blur, () => { - this.window.webContents.send( - WindowStateChannel.FocuseChanged, - ElectronBrowserWindowChannel.Blur - ); + this.window.on(ElectronBrowserWindowChannel.Blur, e => { + const allBrowsers = BrowserWindow.getAllWindows(); + const mainBrowsers = BrowserWindow.fromId(this.mainWindowId); + + if (!!mainBrowsers && !mainBrowsers.isFocused()) { + this.window.webContents.send( + WindowStateChannel.FocuseChanged, + ElectronBrowserWindowChannel.Blur + ); + } }); // on macOS, when the user closes the window we really just hide it. This diff --git a/projects/ucap-webmessenger-app/src/app/layouts/messenger/components/main-contents/messages.component.ts b/projects/ucap-webmessenger-app/src/app/layouts/messenger/components/main-contents/messages.component.ts index 77b16a8d..de53dc59 100644 --- a/projects/ucap-webmessenger-app/src/app/layouts/messenger/components/main-contents/messages.component.ts +++ b/projects/ucap-webmessenger-app/src/app/layouts/messenger/components/main-contents/messages.component.ts @@ -135,7 +135,11 @@ import { MassDetailComponent, MassDetailDialogData } from '../../dialogs/chat/mass-detail.component'; -import { NativeService, UCAP_NATIVE_SERVICE } from '@ucap-webmessenger/native'; +import { + NativeService, + UCAP_NATIVE_SERVICE, + WindowState +} from '@ucap-webmessenger/native'; import { TranslateService } from '@ngx-translate/core'; import { @@ -157,6 +161,7 @@ import { EventDownloadRequest } from '@ucap-webmessenger/api-message'; import moment from 'moment'; +import { ElectronBrowserWindowChannel } from '@ucap-webmessenger/electron-core'; @Component({ selector: 'app-layout-messenger-messages', @@ -321,12 +326,22 @@ export class MessagesComponent implements OnInit, OnDestroy, AfterViewInit { eventList.length > 0 && gnbMenuIndex !== MainMenu.Organization ) { - this.store.dispatch( - EventStore.read({ - roomSeq: roomInfo.roomSeq, - lastReadSeq: eventList[eventList.length - 1].seq - }) - ); + const windowState = this.nativeService.getWindowState(); + // 윈도우의 상태가 최소화, tray 상태가 아니면서 조직도탭을 보고 있지 않다면, + if ( + !!windowState && + windowState.windowState !== WindowState.Minimized && + windowState.windowState !== WindowState.Hidden && + windowState.windowFocusState === + ElectronBrowserWindowChannel.Focus + ) { + this.store.dispatch( + EventStore.read({ + roomSeq: roomInfo.roomSeq, + lastReadSeq: eventList[eventList.length - 1].seq + }) + ); + } } }) ) 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 08c0729f..074b79ba 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 @@ -13,11 +13,23 @@ import { Store, select } from '@ngrx/store'; import * as AppStore from '@app/store'; import * as ChatStore from '@app/store/messenger/chat'; +import * as EventStore from '@app/store/messenger/event'; import * as MessageStore from '@app/store/messenger/message'; import * as StatusStore from '@app/store/messenger/status'; import * as SettingsStore from '@app/store/messenger/settings'; -import { Observable, Subscription, of, timer, EMPTY } from 'rxjs'; -import { UCAP_NATIVE_SERVICE, NativeService } from '@ucap-webmessenger/native'; +import { + Observable, + Subscription, + of, + timer, + EMPTY, + combineLatest +} from 'rxjs'; +import { + UCAP_NATIVE_SERVICE, + NativeService, + WindowState +} from '@ucap-webmessenger/native'; import { StatusProtocolService } from '@ucap-webmessenger/protocol-status'; import { StatusType, StatusCode } from '@ucap-webmessenger/core'; @@ -53,6 +65,7 @@ import { TranslateService } from '@ngx-translate/core'; import { LeftSideComponent } from '@app/layouts/messenger/components/left-side.component'; import { MatDrawer } from '@angular/material/sidenav'; import { LocationStrategy } from '@angular/common'; +import { ElectronBrowserWindowChannel } from '@ucap-webmessenger/electron-core'; @Component({ selector: 'app-page-messenger-main', @@ -73,6 +86,8 @@ export class MainPageComponent implements OnInit, OnDestroy { selectedChat$: Observable; selectedRightDrawer$: Observable; idleStateChangedSubscription: Subscription; + windowFocusChangedSubscription: Subscription; + chatOpenRoomSubscription: Subscription; msgOpenMessageSubscription: Subscription; myIdleCheckTimeSubscription: Subscription; @@ -139,6 +154,38 @@ export class MainPageComponent implements OnInit, OnDestroy { }) ); + this.windowFocusChangedSubscription = combineLatest([ + this.nativeService.windowFocusChanged(), + this.store.pipe(select(AppStore.MessengerSelector.RoomSelector.roomInfo)), + this.store.pipe( + select(AppStore.MessengerSelector.SettingsSelector.gnbMenuIndex) + ), + this.store.pipe( + select(AppStore.MessengerSelector.EventSelector.selectAllInfoList) + ) + ]) + .pipe( + map(([windowFocusState, roomInfo, gnbMenuIndex, eventList]) => { + if (windowFocusState === ElectronBrowserWindowChannel.Focus) { + if ( + !!roomInfo && + !!roomInfo.roomSeq && + !!eventList && + eventList.length > 0 && + gnbMenuIndex !== MainMenu.Organization + ) { + this.store.dispatch( + EventStore.read({ + roomSeq: roomInfo.roomSeq, + lastReadSeq: eventList[eventList.length - 1].seq + }) + ); + } + } + }) + ) + .subscribe(); + this.leftSideDrawerSubscription = this.store .pipe( select(AppStore.MessengerSelector.ChatSelector.selectLeftSideDrawer) @@ -270,6 +317,9 @@ export class MainPageComponent implements OnInit, OnDestroy { if (!!this.idleStateChangedSubscription) { this.idleStateChangedSubscription.unsubscribe(); } + if (!!this.windowFocusChangedSubscription) { + this.windowFocusChangedSubscription.unsubscribe(); + } if (!!this.chatOpenRoomSubscription) { this.chatOpenRoomSubscription.unsubscribe(); diff --git a/projects/ucap-webmessenger-app/src/app/services/notification.service.ts b/projects/ucap-webmessenger-app/src/app/services/notification.service.ts index 6ac6a5cc..846b6f1f 100644 --- a/projects/ucap-webmessenger-app/src/app/services/notification.service.ts +++ b/projects/ucap-webmessenger-app/src/app/services/notification.service.ts @@ -274,6 +274,7 @@ export class AppNotificationService { 'Notification::eventProtocolService::SendNotification', noti ); + const windowState = this.nativeService.getWindowState(); // Event.. this.store.dispatch( @@ -283,13 +284,29 @@ export class AppNotificationService { ); // unread count.. + let doReadRequest = false; + + // 현재 방이 열려 있고, if ( !!curRoomInfo && !!curRoomInfo.roomSeq && - curRoomInfo.roomSeq === noti.roomSeq && - gnbMenuIndex !== MainMenu.Organization + curRoomInfo.roomSeq === noti.roomSeq ) { - // 현재 방이 열려 있고, 조직도탭을 보고 있지 않다면 대화방을 보고 있다고 판단하고 event_read_req 한다. + // 윈도우의 상태가 최소화, tray 상태가 아니면서 조직도탭을 보고 있지 않다면, + if ( + !!windowState && + windowState.windowState !== WindowState.Minimized && + windowState.windowState !== WindowState.Hidden && + windowState.windowFocusState === + ElectronBrowserWindowChannel.Focus && + gnbMenuIndex !== MainMenu.Organization + ) { + // 대화방을 보고 있다고 판단하고 event_read_req 한다. + doReadRequest = true; + } + } + + if (doReadRequest) { this.store.dispatch( EventStore.read({ roomSeq: noti.roomSeq, @@ -326,8 +343,6 @@ export class AppNotificationService { if (notiOrRes.SSVC_TYPE === SSVC_TYPE_EVENT_SEND_NOTI) { let doNoti = true; - const windowState = this.nativeService.getWindowState(); - // 현재 열려 있는 방일경우 노티 안함. if ( !!curRoomInfo && diff --git a/projects/ucap-webmessenger-app/src/app/store/messenger/event/effects.ts b/projects/ucap-webmessenger-app/src/app/store/messenger/event/effects.ts index f01a16cb..d034eecd 100644 --- a/projects/ucap-webmessenger-app/src/app/store/messenger/event/effects.ts +++ b/projects/ucap-webmessenger-app/src/app/store/messenger/event/effects.ts @@ -906,15 +906,9 @@ export class Effects { withLatestFrom( this.store.pipe( select((state: any) => state.messenger.room.roomInfo as RoomInfo) - ), - this.store.pipe( - select( - (state: any) => - state.messenger.sync.room.entities as Dictionary - ) ) ), - tap(([action, roomInfo, trgtRoomInfos]) => { + tap(([action, roomInfo]) => { // opened room :: event add if (!!roomInfo && roomInfo.roomSeq === action.roomSeq) { this.store.dispatch(appendInfoList({ info: action.info })); 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 64ccb9c2..2da93198 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 @@ -226,6 +226,21 @@ export class BrowserNativeService extends NativeService { } }); } + windowFocusChanged(): Observable< + ElectronBrowserWindowChannel.Focus | ElectronBrowserWindowChannel.Blur + > { + return new Observable< + ElectronBrowserWindowChannel.Focus | ElectronBrowserWindowChannel.Blur + >(subscriber => { + try { + subscriber.next(ElectronBrowserWindowChannel.Focus); + } catch (error) { + subscriber.error(error); + } finally { + subscriber.complete(); + } + }); + } windowClose(): void {} 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 3ca355cf..d378211b 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 @@ -54,6 +54,13 @@ export class ElectronNativeService implements NativeService { private windowStateChangedSubject: Subject | null = null; private windowStateChanged$: Observable | null = null; + private windowFocusChangedSubject: Subject< + ElectronBrowserWindowChannel.Focus | ElectronBrowserWindowChannel.Blur + > | null = null; + private windowFocusChanged$: Observable< + ElectronBrowserWindowChannel.Focus | ElectronBrowserWindowChannel.Blur + > | null = null; + private idleStateChangedSubject: Subject | null = null; private idleStateChanged$: Observable | null = null; @@ -374,6 +381,32 @@ export class ElectronNativeService implements NativeService { ); return this.windowStateChanged$; } + windowFocusChanged(): Observable< + ElectronBrowserWindowChannel.Focus | ElectronBrowserWindowChannel.Blur + > { + if (!this.windowFocusChangedSubject) { + this.windowFocusChangedSubject = new Subject< + ElectronBrowserWindowChannel.Focus | ElectronBrowserWindowChannel.Blur + >(); + this.windowFocusChanged$ = this.windowFocusChangedSubject + .asObservable() + .pipe(share()); + } + + this.ipcRenderer.on( + WindowStateChannel.FocuseChanged, + ( + event: any, + status: + | ElectronBrowserWindowChannel.Focus + | ElectronBrowserWindowChannel.Blur + ) => { + this.windowFocusState = status; + this.windowFocusChangedSubject.next(status); + } + ); + return this.windowFocusChanged$; + } windowClose(): void { const currentWindow = this.remote.getCurrentWindow(); @@ -552,17 +585,5 @@ export class ElectronNativeService implements NativeService { this.shell = (window as any).require('electron').shell; this.webFrame = (window as any).require('electron').webFrame; } - - this.ipcRenderer.on( - WindowStateChannel.FocuseChanged, - ( - event: any, - status: - | ElectronBrowserWindowChannel.Focus - | ElectronBrowserWindowChannel.Blur - ) => { - this.windowFocusState = status; - } - ); } } 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 76b7aed8..b23c07c6 100644 --- a/projects/ucap-webmessenger-native/src/lib/services/native.service.ts +++ b/projects/ucap-webmessenger-native/src/lib/services/native.service.ts @@ -73,6 +73,9 @@ export abstract class NativeService { abstract onFlashFlame(): void; abstract offFlashFlame(): void; abstract windowStateChanged(): Observable; + abstract windowFocusChanged(): Observable< + ElectronBrowserWindowChannel.Focus | ElectronBrowserWindowChannel.Blur + >; abstract windowClose(): void; abstract windowMinimize(): void; abstract windowMaximize(): void;