open room of notification is implemented

This commit is contained in:
병준 박 2019-11-12 10:38:51 +09:00
parent 8fec0e15f2
commit 1d282b59cb
9 changed files with 114 additions and 51 deletions

View File

@ -3,7 +3,7 @@ import { ElectronNotificationEventType } from '../types/event.type';
export interface ElectronNotificationEvent { export interface ElectronNotificationEvent {
type: ElectronNotificationEventType; type: ElectronNotificationEventType;
id: number; id: number;
close?: (reason: any) => void; close?: (reason?: any) => void;
} }
export interface ElectronNotification { export interface ElectronNotification {

View File

@ -5,7 +5,7 @@ import * as 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,11 +266,11 @@ export class ElectronNotificationService {
notification.onShow({ notification.onShow({
type: ElectronNotificationEventType.Show, type: ElectronNotificationEventType.Show,
id: notification.id, id: notification.id,
close: onCloseNotificationSafely close: onCloseNotificationSafely,
}); });
} }
if (!!notification.onClose) { if (!!notification.onClick) {
notificationWindow[onClickElectronNotification] = notificationWindow[onClickElectronNotification] =
notification.onClick; notification.onClick;
} else { } else {
@ -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()],
}); });
} }
} }

View File

@ -12,7 +12,8 @@ import {
UpdaterChannel, UpdaterChannel,
FileChannel, FileChannel,
IdleStateChannel, IdleStateChannel,
NotificationChannel NotificationChannel,
ChatChannel,
} from '@ucap-webmessenger/native-electron'; } from '@ucap-webmessenger/native-electron';
import { ElectronNotificationService } from '@ucap-webmessenger/electron-notification'; import { ElectronNotificationService } from '@ucap-webmessenger/electron-notification';
@ -105,7 +106,7 @@ function createWindow() {
import('electron-devtools-installer').then(edi => { import('electron-devtools-installer').then(edi => {
const ChromeLens = { const ChromeLens = {
id: 'idikgljglpfilbhaboonnpnnincjhjkd', id: 'idikgljglpfilbhaboonnpnnincjhjkd',
electron: '>=1.2.1' electron: '>=1.2.1',
}; };
const extensions = [edi.REDUX_DEVTOOLS, ChromeLens]; const extensions = [edi.REDUX_DEVTOOLS, ChromeLens];
@ -165,7 +166,7 @@ app.on(ElectronAppChannel.Ready, () => {
defaultStyleAppIcon: { display: 'none' }, defaultStyleAppIcon: { display: 'none' },
defaultStyleImage: {}, defaultStyleImage: {},
defaultStyleClose: {}, defaultStyleClose: {},
defaultStyleText: {} defaultStyleText: {},
}); });
notificationService.options.defaultWindow.webPreferences.preload = path.join( notificationService.options.defaultWindow.webPreferences.preload = path.join(
@ -289,9 +290,14 @@ ipcMain.on(
'resources/notification/sound/messageAlarm.mp3' 'resources/notification/sound/messageAlarm.mp3'
) )
: '', : '',
onClick: () => { onClick: e => {
console.log('onClick'); appWindow.browserWindow.webContents.send(
} ChatChannel.OpenRoom,
noti.roomSeq
);
appWindow.show();
e.close();
},
}); });
} }
); );

View File

@ -1,44 +1,45 @@
import { map, tap } from 'rxjs/operators'; import { map, tap } from "rxjs/operators";
import { Component, OnInit, Inject, OnDestroy, ViewChild } from '@angular/core'; import { Component, OnInit, Inject, OnDestroy, ViewChild } from "@angular/core";
import { Store, select } from '@ngrx/store'; import { Store, select } from "@ngrx/store";
import * as AppSotre from '@app/store'; import * as AppSotre from "@app/store";
import * as ChatStore from '@app/store/messenger/chat'; import * as ChatStore from "@app/store/messenger/chat";
import { Observable, Subscription } from 'rxjs'; import { Observable, Subscription } from "rxjs";
import { import {
WindowIdle, WindowIdle,
UCAP_NATIVE_SERVICE, UCAP_NATIVE_SERVICE,
NativeService NativeService
} from '@ucap-webmessenger/native'; } from "@ucap-webmessenger/native";
import { UserInfo } from '@ucap-webmessenger/protocol-sync'; import { UserInfo } from "@ucap-webmessenger/protocol-sync";
import { import {
UserInfoSS, UserInfoSS,
UserInfoF, UserInfoF,
UserInfoDN UserInfoDN
} from '@ucap-webmessenger/protocol-query'; } from "@ucap-webmessenger/protocol-query";
import { StatusProtocolService } from '@ucap-webmessenger/protocol-status'; import { StatusProtocolService } from "@ucap-webmessenger/protocol-status";
import { StatusType, StatusCode } from '@ucap-webmessenger/core'; import { StatusType, StatusCode } from "@ucap-webmessenger/core";
import { DialogService } from '@ucap-webmessenger/ui'; import { DialogService } from "@ucap-webmessenger/ui";
import { import {
ProfileDialogComponent, ProfileDialogComponent,
ProfileDialogData, ProfileDialogData,
ProfileDialogResult ProfileDialogResult
} from '@app/layouts/messenger/dialogs/profile/profile.dialog.component'; } from "@app/layouts/messenger/dialogs/profile/profile.dialog.component";
import { MatSidenav, MatDrawer } from '@angular/material'; import { MatSidenav, MatDrawer } from "@angular/material";
@Component({ @Component({
selector: 'app-page-messenger-main', selector: "app-page-messenger-main",
templateUrl: './main.page.component.html', templateUrl: "./main.page.component.html",
styleUrls: ['./main.page.component.scss'] styleUrls: ["./main.page.component.scss"]
}) })
export class MainPageComponent implements OnInit { export class MainPageComponent implements OnInit {
selectedChat$: Observable<string | null>; selectedChat$: Observable<string | null>;
selectedRightDrawer$: Observable<string | null>; selectedRightDrawer$: Observable<string | null>;
idleStateChangedSubscription: Subscription; idleStateChangedSubscription: Subscription;
chatOpenRoomSubscription: Subscription;
@ViewChild('rightDrawer', { static: true }) rightDrawer: MatDrawer; @ViewChild("rightDrawer", { static: true }) rightDrawer: MatDrawer;
constructor( constructor(
@Inject(UCAP_NATIVE_SERVICE) private nativeService: NativeService, @Inject(UCAP_NATIVE_SERVICE) private nativeService: NativeService,
@ -74,7 +75,7 @@ export class MainPageComponent implements OnInit {
console.log(action); console.log(action);
let statusType: StatusCode; let statusType: StatusCode;
if (action === 'IDLE') { if (action === "IDLE") {
// away // away
statusType = StatusCode.Away; statusType = StatusCode.Away;
} else { } else {
@ -85,15 +86,25 @@ export class MainPageComponent implements OnInit {
this.statusProtocolService.status({ this.statusProtocolService.status({
statusDivisionType: StatusType.Messenger, statusDivisionType: StatusType.Messenger,
statusType, statusType,
statusMessage: '' statusMessage: ""
}); });
}); });
this.chatOpenRoomSubscription = this.nativeService
.chatOpenRoom()
.subscribe(roomSeq => {
this.store.dispatch(ChatStore.selectedRoom({ roomSeq }));
});
} }
OnDestroy(): void { OnDestroy(): void {
if (!!this.idleStateChangedSubscription) { if (!!this.idleStateChangedSubscription) {
this.idleStateChangedSubscription.unsubscribe(); this.idleStateChangedSubscription.unsubscribe();
} }
if (!!this.chatOpenRoomSubscription) {
this.chatOpenRoomSubscription.unsubscribe();
}
} }
onOpenedChange(event: boolean) { onOpenedChange(event: boolean) {

View File

@ -20,13 +20,16 @@ export class NotificationService {
} }
} }
notify(noti: NotificationRequest) { notify(noti: NotificationRequest, click?: () => void) {
const notification = new Notification(noti.title, { const notification = new Notification(noti.title, {
body: noti.contents, body: noti.contents,
icon: noti.image || 'assets/images/img_nophoto_50.png' icon: noti.image || 'assets/images/img_nophoto_50.png'
}); });
notification.onclick = e => { notification.onclick = e => {
console.log('notification.onclick'); console.log('notification.onclick');
if (!!click) {
click();
}
}; };
notification.onclose = e => { notification.onclose = e => {
console.log('notification.onclose'); console.log('notification.onclose');

View File

@ -1,31 +1,36 @@
import { Observable } from 'rxjs'; import { Observable, Subject } from 'rxjs';
import { import {
NativeService, NativeService,
WindowState, WindowState,
NotificationRequest, NotificationRequest,
WindowIdle WindowIdle,
} from '@ucap-webmessenger/native'; } from '@ucap-webmessenger/native';
import { HttpClient } from '@angular/common/http'; import { HttpClient } from '@angular/common/http';
import { map } from 'rxjs/operators'; import { map, share } from 'rxjs/operators';
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { TranslateLoader } from '@ngx-translate/core'; import { TranslateLoader } from '@ngx-translate/core';
import { TranslateLoaderService } from '../translate/browser-loader'; import { TranslateLoaderService } from '../translate/browser-loader';
import { NotificationService } from '../notification/notification.service'; import { NotificationService } from '../notification/notification.service';
@Injectable({ @Injectable({
providedIn: 'root' providedIn: 'root',
}) })
export class BrowserNativeService implements NativeService { export class BrowserNativeService implements NativeService {
private notificationService: NotificationService; private notificationService: NotificationService;
private chatOpenRoomSubject: Subject<string> | null = null;
private chatOpenRoom$: Observable<string> | null = null;
postAppInit(): void { postAppInit(): void {
this.notificationService.requestPermission(); this.notificationService.requestPermission();
} }
notify(noti: NotificationRequest): void { notify(noti: NotificationRequest): void {
console.log('ddd'); this.notificationService.notify(noti, () => {
this.notificationService.notify(noti); window.focus();
this.chatOpenRoomSubject.next(noti.roomSeq);
});
} }
closeAllNotify(): void {} closeAllNotify(): void {}
@ -89,6 +94,17 @@ export class BrowserNativeService implements NativeService {
}); });
} }
chatOpenRoom(): Observable<string> {
if (!this.chatOpenRoomSubject) {
this.chatOpenRoomSubject = new Subject<WindowIdle>();
this.chatOpenRoom$ = this.chatOpenRoomSubject
.asObservable()
.pipe(share());
}
return this.chatOpenRoom$;
}
getTranslateLoader(prefix?: string, suffix?: string): TranslateLoader { getTranslateLoader(prefix?: string, suffix?: string): TranslateLoader {
return new TranslateLoaderService(this, prefix, suffix); return new TranslateLoaderService(this, prefix, suffix);
} }

View File

@ -14,7 +14,8 @@ import {
UpdaterChannel, UpdaterChannel,
FileChannel, FileChannel,
WindowStateChannel, WindowStateChannel,
IdleStateChannel IdleStateChannel,
ChatChannel
} from '../types/channel.type'; } from '../types/channel.type';
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { TranslateLoaderService } from '../translate/electron-loader'; import { TranslateLoaderService } from '../translate/electron-loader';
@ -30,6 +31,9 @@ export class ElectronNativeService implements NativeService {
private idleStateChangedSubject: Subject<WindowIdle> | null = null; private idleStateChangedSubject: Subject<WindowIdle> | null = null;
private idleStateChanged$: Observable<WindowIdle> | null = null; private idleStateChanged$: Observable<WindowIdle> | null = null;
private chatOpenRoomSubject: Subject<string> | null = null;
private chatOpenRoom$: Observable<string> | null = null;
postAppInit(): void {} postAppInit(): void {}
notify(noti: NotificationRequest): void { notify(noti: NotificationRequest): void {
@ -153,6 +157,23 @@ export class ElectronNativeService implements NativeService {
return this.idleStateChanged$; return this.idleStateChanged$;
} }
chatOpenRoom(): Observable<string> {
if (!this.chatOpenRoomSubject) {
this.chatOpenRoomSubject = new Subject<WindowIdle>();
this.chatOpenRoom$ = this.chatOpenRoomSubject
.asObservable()
.pipe(share());
}
ipcRenderer.on(
ChatChannel.OpenRoom,
(event: IpcRendererEvent, roomSeq: string) => {
this.chatOpenRoomSubject.next(roomSeq);
}
);
return this.chatOpenRoom$;
}
getTranslateLoader(prefix?: string, suffix?: string): TranslateLoader { getTranslateLoader(prefix?: string, suffix?: string): TranslateLoader {
return new TranslateLoaderService(this, prefix, suffix); return new TranslateLoaderService(this, prefix, suffix);
} }

View File

@ -1,3 +1,7 @@
export enum ChatChannel {
OpenRoom = 'UCAP::chat::openRoom'
}
export enum NotificationChannel { export enum NotificationChannel {
Notify = 'UCAP::notification::notify', Notify = 'UCAP::notification::notify',
CloseAllNotify = 'UCAP::notification::closeAllNotify' CloseAllNotify = 'UCAP::notification::closeAllNotify'

View File

@ -25,5 +25,7 @@ export interface NativeService {
idleStateChanged(): Observable<WindowIdle>; idleStateChanged(): Observable<WindowIdle>;
chatOpenRoom(): Observable<string>;
getTranslateLoader(prefix?: string, suffix?: string): TranslateLoader; getTranslateLoader(prefix?: string, suffix?: string): TranslateLoader;
} }