diff --git a/projects/ucap-webmessenger-app/src/app/layouts/messenger/components/left-side.component.html b/projects/ucap-webmessenger-app/src/app/layouts/messenger/components/left-side.component.html index c8d3929f..50600652 100644 --- a/projects/ucap-webmessenger-app/src/app/layouts/messenger/components/left-side.component.html +++ b/projects/ucap-webmessenger-app/src/app/layouts/messenger/components/left-side.component.html @@ -32,6 +32,7 @@ diff --git a/projects/ucap-webmessenger-app/src/app/layouts/messenger/components/left-side.component.ts b/projects/ucap-webmessenger-app/src/app/layouts/messenger/components/left-side.component.ts index 9e1ef530..11447c9a 100644 --- a/projects/ucap-webmessenger-app/src/app/layouts/messenger/components/left-side.component.ts +++ b/projects/ucap-webmessenger-app/src/app/layouts/messenger/components/left-side.component.ts @@ -67,6 +67,26 @@ export class LeftSideComponent implements OnInit { } } + onCheckAllUser(params: { + isChecked: boolean; + userInfos: (UserInfo | UserInfoSS | UserInfoF | UserInfoDN)[]; + }) { + params.userInfos.forEach(userInfo => { + if (params.isChecked) { + if ( + this.selectedUserList.filter(user => user.seq === userInfo.seq) + .length === 0 + ) { + this.selectedUserList = [...this.selectedUserList, userInfo]; + } + } else { + this.selectedUserList = this.selectedUserList.filter( + user => user.seq !== userInfo.seq + ); + } + }); + } + /** 조직도>부서원 :: 리스트의 checkbox 의 이벤트를 받아 선택된 유저리스트를 수집. */ onCheckUser(params: { isChecked: boolean; @@ -74,15 +94,15 @@ export class LeftSideComponent implements OnInit { }) { if (params.isChecked) { if ( + params.userInfo && this.selectedUserList.filter(user => user.seq === params.userInfo.seq) - .length === 0 && - params.userInfo + .length === 0 ) { this.selectedUserList = [...this.selectedUserList, params.userInfo]; } } else { this.selectedUserList = this.selectedUserList.filter( - item => item.seq !== params.userInfo.seq + user => user.seq !== params.userInfo.seq ); } } diff --git a/projects/ucap-webmessenger-app/src/app/layouts/messenger/components/left-sidenav/organization.component.html b/projects/ucap-webmessenger-app/src/app/layouts/messenger/components/left-sidenav/organization.component.html index 65ba1626..780cb90b 100644 --- a/projects/ucap-webmessenger-app/src/app/layouts/messenger/components/left-sidenav/organization.component.html +++ b/projects/ucap-webmessenger-app/src/app/layouts/messenger/components/left-sidenav/organization.component.html @@ -11,7 +11,20 @@
- {{ getSelectedDepartmentName() }} +
+
+ {{ getSelectedDepartmentName() }} +
+
+ + +
+
@@ -22,9 +35,7 @@ style="height: calc(100% - 20px);" > (); + @Output() + checkAllUser = new EventEmitter<{ + isChecked: boolean; + userInfos: (UserInfo | UserInfoSS | UserInfoF | UserInfoDN)[]; + }>(); departmentInfoList$: Observable; selectedDepartmentUserInfoList$: Observable; + selectedDepartmentUserInfoList: UserInfoSS[] = []; + selectedDepartmentUserInfoListSubscription: Subscription; selectedDepartmentStatus$: Observable; selectedDepartmentProcessing = false; selectedDepartmentProcessingSubscription: Subscription; @@ -68,7 +75,6 @@ export class OrganizationComponent implements OnInit, OnDestroy { constructor( private store: Store, - private queryProtocolService: QueryProtocolService, private sessionStorageService: SessionStorageService, private dialogService: DialogService, private logger: NGXLogger @@ -96,11 +102,18 @@ export class OrganizationComponent implements OnInit, OnDestroy { ) .subscribe(); - this.selectedDepartmentUserInfoList$ = this.store.pipe( - select( - AppStore.MessengerSelector.QuerySelector.selectedDepartmentUserInfoList + this.selectedDepartmentUserInfoListSubscription = this.store + .pipe( + select( + AppStore.MessengerSelector.QuerySelector + .selectedDepartmentUserInfoList + ), + map(list => { + this.selectedDepartmentUserInfoList = list; + }) ) - ); + .subscribe(); + this.selectedDepartmentStatus$ = this.store.pipe( select(AppStore.MessengerSelector.QuerySelector.selectedDepartmentStatus) ); @@ -131,6 +144,9 @@ export class OrganizationComponent implements OnInit, OnDestroy { } ngOnDestroy(): void { + if (!!this.selectedDepartmentUserInfoListSubscription) { + this.selectedDepartmentUserInfoListSubscription.unsubscribe(); + } if (!!this.selectedDepartmentProcessingSubscription) { this.selectedDepartmentProcessingSubscription.unsubscribe(); } @@ -173,6 +189,23 @@ export class OrganizationComponent implements OnInit, OnDestroy { } } + /** 전체 체크여부 */ + getCheckedAllUser() { + if ( + this.selectedDepartmentUserInfoList && + this.selectedDepartmentUserInfoList.filter( + item => + !( + this.selectedUserList.filter(user => user.seq === item.seq).length > + 0 + ) + ).length > 0 + ) { + return false; + } else { + return true; + } + } /** 리스트 checkable 할 경우 checkbox 의 isChecked 를 관장하며 리스트의 전체선택 여부를 판단한다. */ getCheckedUser(userInfo: UserInfo | UserInfoSS | UserInfoF | UserInfoDN) { if (!!this.selectedUserList && this.selectedUserList.length > 0) { @@ -184,6 +217,14 @@ export class OrganizationComponent implements OnInit, OnDestroy { return false; } + /** 전체선택 이벤트 */ + onCheckAllUser(value: boolean) { + this.checkAllUser.emit({ + isChecked: value, + userInfos: this.selectedDepartmentUserInfoList + }); + } + /** 리스트가 checkable 할 경우 checkbox 의 change 이벤트를 상위 컴포넌트로 전달한다. */ onCheckUser(params: { isChecked: boolean; diff --git a/projects/ucap-webmessenger-app/src/app/layouts/messenger/components/messages.component.html b/projects/ucap-webmessenger-app/src/app/layouts/messenger/components/messages.component.html index 828706c4..24be9c99 100644 --- a/projects/ucap-webmessenger-app/src/app/layouts/messenger/components/messages.component.html +++ b/projects/ucap-webmessenger-app/src/app/layouts/messenger/components/messages.component.html @@ -73,6 +73,7 @@ ; + eventInfoStatus$: Observable; sessionVerInfo: VersionInfo2Response; isRecalledMessage = isRecalled; @@ -147,6 +149,10 @@ export class MessagesComponent implements OnInit, OnDestroy, AfterViewChecked { select(AppStore.MessengerSelector.EventSelector.selectAllInfoList) ); + this.eventInfoStatus$ = this.store.pipe( + select(AppStore.MessengerSelector.EventSelector.infoStatus) + ); + this.psChatContent.directiveRef.scrollToBottom(0, 0); } diff --git a/projects/ucap-webmessenger-app/src/app/layouts/messenger/dialogs/chat/create-chat.dialog.component.html b/projects/ucap-webmessenger-app/src/app/layouts/messenger/dialogs/chat/create-chat.dialog.component.html index 1eb36dce..25d17e0a 100644 --- a/projects/ucap-webmessenger-app/src/app/layouts/messenger/dialogs/chat/create-chat.dialog.component.html +++ b/projects/ucap-webmessenger-app/src/app/layouts/messenger/dialogs/chat/create-chat.dialog.component.html @@ -91,6 +91,7 @@ diff --git a/projects/ucap-webmessenger-app/src/app/layouts/messenger/dialogs/chat/create-chat.dialog.component.ts b/projects/ucap-webmessenger-app/src/app/layouts/messenger/dialogs/chat/create-chat.dialog.component.ts index 3a56b230..edeb600f 100644 --- a/projects/ucap-webmessenger-app/src/app/layouts/messenger/dialogs/chat/create-chat.dialog.component.ts +++ b/projects/ucap-webmessenger-app/src/app/layouts/messenger/dialogs/chat/create-chat.dialog.component.ts @@ -330,6 +330,26 @@ export class CreateChatDialogComponent implements OnInit, OnDestroy { } } + onCheckAllUser(params: { + isChecked: boolean; + userInfos: (UserInfo | UserInfoSS | UserInfoF | UserInfoDN)[]; + }) { + params.userInfos.forEach(userInfo => { + if (params.isChecked) { + if ( + this.selectedUserList.filter(user => user.seq === userInfo.seq) + .length === 0 + ) { + this.selectedUserList = [...this.selectedUserList, userInfo]; + } + } else { + this.selectedUserList = this.selectedUserList.filter( + user => user.seq !== userInfo.seq + ); + } + }); + } + /** 동료그룹>부서원, 조직도>부서원 :: 리스트의 checkbox 의 이벤트를 받아 선택된 유저리스트를 수집. */ onCheckUser(params: { isChecked: boolean; diff --git a/projects/ucap-webmessenger-app/src/app/layouts/messenger/messenger.layout.module.ts b/projects/ucap-webmessenger-app/src/app/layouts/messenger/messenger.layout.module.ts index de2f14c9..c020ed38 100644 --- a/projects/ucap-webmessenger-app/src/app/layouts/messenger/messenger.layout.module.ts +++ b/projects/ucap-webmessenger-app/src/app/layouts/messenger/messenger.layout.module.ts @@ -21,6 +21,7 @@ import { MatTabsModule } from '@angular/material/tabs'; import { MatToolbarModule } from '@angular/material/toolbar'; import { MatFormFieldModule } from '@angular/material/form-field'; import { MatInputModule } from '@angular/material/input'; +import { MatCheckboxModule } from '@angular/material'; import { DragDropModule } from '@angular/cdk/drag-drop'; import { OverlayModule } from '@angular/cdk/overlay'; @@ -63,6 +64,7 @@ import { DIALOGS } from './dialogs'; MatTabsModule, MatToolbarModule, MatChipsModule, + MatCheckboxModule, PerfectScrollbarModule, 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 c86a5968..a08f943b 100644 --- a/projects/ucap-webmessenger-app/src/app/services/notification.service.ts +++ b/projects/ucap-webmessenger-app/src/app/services/notification.service.ts @@ -1,8 +1,9 @@ +import { delGroupSuccess, buddy2 } from './../store/messenger/sync/actions'; import { Injectable } from '@angular/core'; -import { tap } from 'rxjs/operators'; +import { tap, withLatestFrom } from 'rxjs/operators'; -import { Store } from '@ngrx/store'; +import { Store, select } from '@ngrx/store'; import { SSVC_TYPE_LOGOUT_RES, @@ -35,7 +36,7 @@ import { SSVC_TYPE_ROOM_EXIT_FORCING_NOTI, SSVC_TYPE_ROOM_FONT_UPD_NOTI, InviteNotification, - UpdateNotification, + UpdateNotification as RoomUpdateNotification, SSVC_TYPE_ROOM_UPD_RES } from '@ucap-webmessenger/protocol-room'; import { @@ -53,10 +54,29 @@ import { ExitForcingNotification, UpdateFontNotification } from '@ucap-webmessenger/protocol-room'; +import { + GroupProtocolService, + SSVC_TYPE_GROUP_UPD_RES2, + UpdateNotification as GroupUpdateNotification, + SSVC_TYPE_GROUP_ADD_RES, + AddNotification as GroupAddNotification, + SSVC_TYPE_GROUP_DEL_RES, + DelNotification as GroupDelNotification +} from '@ucap-webmessenger/protocol-group'; +import { + BuddyProtocolService, + SSVC_TYPE_BUDDY_UPD_RES, + UpdateNotification as BuddyUpdateNotification, + SSVC_TYPE_BUDDY_ADD_RES, + AddNotification as BuddyAddNotification, + SSVC_TYPE_BUDDY_DEL_RES, + DelNotification as BuddyDelNotification +} from '@ucap-webmessenger/protocol-buddy'; import * as AuthenticationStore from '@app/store/account/authentication'; import * as InfoStore from '@app/store/account/info'; import * as EventStore from '@app/store/messenger/event'; +import * as SyncStore from '@app/store/messenger/sync'; import * as RoomStore from '@app/store/messenger/room'; import * as StatusStore from '@app/store/messenger/status'; @@ -67,6 +87,8 @@ export class AppNotificationService { private eventProtocolService: EventProtocolService, private infoProtocolService: InfoProtocolService, private roomProtocolService: RoomProtocolService, + private groupProtocolService: GroupProtocolService, + private buddyProtocolService: BuddyProtocolService, private statusProtocolService: StatusProtocolService, private store: Store, private logger: NGXLogger @@ -197,15 +219,115 @@ export class AppNotificationService { }) ) .subscribe(); + this.groupProtocolService.notification$ + .pipe( + withLatestFrom( + this.store.pipe( + select( + (state: any) => state.messenger.sync.group2.syncDate as string + ) + ) + ), + tap(([notiOrRes, syncDate]) => { + switch (notiOrRes.SSVC_TYPE) { + case SSVC_TYPE_GROUP_UPD_RES2: + { + const noti = notiOrRes as GroupUpdateNotification; + this.logger.debug( + 'Notification::groupProtocolService::GroupUpdateNotification', + noti + ); + this.store.dispatch( + SyncStore.group2({ + syncDate + }) + ); + } + break; + case SSVC_TYPE_GROUP_ADD_RES: + { + const noti = notiOrRes as GroupAddNotification; + this.logger.debug( + 'Notification::groupProtocolService::GroupAddNotification', + noti + ); + this.store.dispatch(SyncStore.createGroupSuccess(noti)); + } + break; + case SSVC_TYPE_GROUP_DEL_RES: + { + const noti = notiOrRes as GroupDelNotification; + this.logger.debug( + 'Notification::groupProtocolService::GroupDelNotification', + noti + ); + this.store.dispatch(SyncStore.delGroupSuccess(noti)); + } + break; + + default: + break; + } + }) + ) + .subscribe(); + this.buddyProtocolService.notification$ + .pipe( + withLatestFrom( + this.store.pipe( + select( + (state: any) => state.messenger.sync.buddy2.syncDate as string + ) + ) + ), + tap(([notiOrRes, syncDate]) => { + switch (notiOrRes.SSVC_TYPE) { + case SSVC_TYPE_BUDDY_UPD_RES: + { + const noti = notiOrRes as BuddyUpdateNotification; + this.logger.debug( + 'Notification::groupProtocolService::BuddyUpdateNotification', + noti + ); + this.store.dispatch(SyncStore.updateBuddySuccess(noti)); + } + break; + case SSVC_TYPE_BUDDY_ADD_RES: + { + const noti = notiOrRes as BuddyAddNotification; + this.logger.debug( + 'Notification::groupProtocolService::BuddyAddNotification', + noti + ); + this.store.dispatch(SyncStore.buddy2({ syncDate })); + } + break; + case SSVC_TYPE_BUDDY_DEL_RES: + { + const noti = notiOrRes as BuddyDelNotification; + this.logger.debug( + 'Notification::groupProtocolService::BuddyDelNotification', + noti + ); + this.store.dispatch(SyncStore.delBuddySuccess(noti)); + } + break; + + default: + break; + } + }) + ) + .subscribe(); this.roomProtocolService.notification$ .pipe( tap(notiOrRes => { switch (notiOrRes.SSVC_TYPE) { case SSVC_TYPE_ROOM_UPD_RES: { - const noti = notiOrRes as UpdateNotification; + const noti = notiOrRes as RoomUpdateNotification; this.logger.debug( - 'Notification::roomProtocolService::UpdateNotification', + 'Notification::roomProtocolService::RoomUpdateNotification', noti ); this.store.dispatch( diff --git a/projects/ucap-webmessenger-app/src/app/store/messenger/sync/effects.ts b/projects/ucap-webmessenger-app/src/app/store/messenger/sync/effects.ts index 45f74adb..2e3f501d 100644 --- a/projects/ucap-webmessenger-app/src/app/store/messenger/sync/effects.ts +++ b/projects/ucap-webmessenger-app/src/app/store/messenger/sync/effects.ts @@ -571,73 +571,68 @@ export class Effects { { dispatch: false } ); - delGroup$ = createEffect( - () => { - return this.actions$.pipe( - ofType(delGroup), - withLatestFrom( - this.store.pipe( - select( - (state: any) => - state.messenger.sync.group2.entities as Dictionary< - GroupDetailData - > - ) + delGroup$ = createEffect(() => + this.actions$.pipe( + ofType(delGroup), + withLatestFrom( + this.store.pipe( + select( + (state: any) => + state.messenger.sync.group2.entities as Dictionary< + GroupDetailData + > ) - ), - map(([action, groupList]) => { - // Del Buddy - const trgtBuddys = action.group.userSeqs; - // tslint:disable-next-line: no-shadowed-variable - const delBuddyList = trgtBuddys.filter(delBuddy => { - let exist = false; - // tslint:disable-next-line: forin - for (const key in groupList) { - const group: GroupDetailData = groupList[key]; - if ( - group.seq !== action.group.seq && - group.userSeqs.filter(v => v === delBuddy).length > 0 - ) { - exist = true; - break; - } + ) + ), + exhaustMap(([action, groupList]) => { + // Del Buddy + const trgtBuddys = action.group.userSeqs; + // tslint:disable-next-line: no-shadowed-variable + const delBuddyList = trgtBuddys.filter(delBuddy => { + let exist = false; + // tslint:disable-next-line: forin + for (const key in groupList) { + const group: GroupDetailData = groupList[key]; + if ( + group.seq !== action.group.seq && + group.userSeqs.filter(v => v === delBuddy).length > 0 + ) { + exist = true; + break; } - return !exist; + } + return !exist; + }); + + if (delBuddyList.length > 0) { + this.logger.debug('Del Buddy', delBuddyList); + // 즐겨찾기 해제. + delBuddyList.forEach(buddySeq => { + this.buddyProtocolService + .update({ + seq: buddySeq, + isFavorit: false + }) + .pipe(catchError(error => of(delBuddyFailure({ error })))); }); - if (delBuddyList.length > 0) { - this.logger.debug('Del Buddy', delBuddyList); - // 즐겨찾기 해제. - delBuddyList.forEach(buddySeq => { - this.buddyProtocolService - .update({ - seq: buddySeq, - isFavorit: false - }) - .pipe(catchError(error => of(delBuddyFailure({ error })))); - }); + // 동료 삭제 + this.store.dispatch(delBuddy({ userSeqs: delBuddyList })); + } - // 동료 삭제 - this.store.dispatch(delBuddy({ userSeqs: delBuddyList })); - } - - return action.group; - }), - tap(group => { - this.groupProtocolService - .del({ - groupSeq: group.seq - }) - .pipe( - map((res: GroupDelResponse) => { - return delGroupSuccess(res); - }), - catchError(error => of(delGroupFailure({ error }))) - ); - }) - ); - }, - { dispatch: false } + return this.groupProtocolService + .del({ + groupSeq: action.group.seq + }) + .pipe( + map((res: GroupDelResponse) => { + // this.store.dispatch(delGroupSuccess(res)); + return delGroupSuccess(res); + }), + catchError(error => of(delGroupFailure({ error }))) + ); + }) + ) ); addBuddy$ = createEffect(() => @@ -674,11 +669,6 @@ export class Effects { map((res: BuddyDelResponse) => { return delBuddySuccess(res); }), - // map((res: BuddyDelResponse) => { - // return buddy2({ - // syncDate - // }); - // }), catchError(error => of(delBuddyFailure({ error }))) ) ) diff --git a/projects/ucap-webmessenger-protocol-buddy/src/lib/protocols/add.ts b/projects/ucap-webmessenger-protocol-buddy/src/lib/protocols/add.ts index fd2bb3e9..c6ed7f4a 100644 --- a/projects/ucap-webmessenger-protocol-buddy/src/lib/protocols/add.ts +++ b/projects/ucap-webmessenger-protocol-buddy/src/lib/protocols/add.ts @@ -7,16 +7,22 @@ import { PacketBodyValue, ProtocolDecoder, ProtocolMessage, - decodeProtocolMessage + decodeProtocolMessage, + ProtocolNotification } from '@ucap-webmessenger/protocol'; export interface AddRequest extends ProtocolRequest { - // 0n. 사용자SEQ(n)... + /** 0n. 사용자SEQ(n)... */ userSeqs: number[]; } export interface AddResponse extends ProtocolResponse { - // 0n. 사용자SEQ(n)... + /** 0n. 사용자SEQ(n)... */ + userSeqs: number[]; +} + +export interface AddNotification extends ProtocolNotification { + /** 0n. 사용자SEQ(n)... */ userSeqs: number[]; } @@ -38,3 +44,12 @@ export const decodeAdd: ProtocolDecoder = ( userSeqs: userSeqArray } as AddResponse); }; + +export const decodeAddNotification: ProtocolDecoder = ( + message: ProtocolMessage +) => { + const userSeqArray: number[] = [...message.bodyList]; + return decodeProtocolMessage(message, { + userSeqs: userSeqArray + } as AddNotification); +}; diff --git a/projects/ucap-webmessenger-protocol-buddy/src/lib/protocols/del.ts b/projects/ucap-webmessenger-protocol-buddy/src/lib/protocols/del.ts index 8ab42e01..8f23011f 100644 --- a/projects/ucap-webmessenger-protocol-buddy/src/lib/protocols/del.ts +++ b/projects/ucap-webmessenger-protocol-buddy/src/lib/protocols/del.ts @@ -7,16 +7,22 @@ import { PacketBodyValue, ProtocolDecoder, ProtocolMessage, - decodeProtocolMessage + decodeProtocolMessage, + ProtocolNotification } from '@ucap-webmessenger/protocol'; export interface DelRequest extends ProtocolRequest { - // 0n. 사용자SEQ(n)... + /** 0n. 사용자SEQ(n)... */ userSeqs: number[]; } export interface DelResponse extends ProtocolResponse { - // 0n. 사용자SEQ(n)... + /** 0n. 사용자SEQ(n)... */ + userSeqs: number[]; +} + +export interface DelNotification extends ProtocolNotification { + /** 0n. 사용자SEQ(n)... */ userSeqs: number[]; } @@ -38,3 +44,12 @@ export const decodeDel: ProtocolDecoder = ( userSeqs: userSeqArray } as DelResponse); }; + +export const decodeDelNotification: ProtocolDecoder = ( + message: ProtocolMessage +) => { + const userSeqArray: number[] = [...message.bodyList]; + return decodeProtocolMessage(message, { + userSeqs: userSeqArray + } as DelNotification); +}; diff --git a/projects/ucap-webmessenger-protocol-buddy/src/lib/protocols/update.ts b/projects/ucap-webmessenger-protocol-buddy/src/lib/protocols/update.ts index 6ae97060..23fdffae 100644 --- a/projects/ucap-webmessenger-protocol-buddy/src/lib/protocols/update.ts +++ b/projects/ucap-webmessenger-protocol-buddy/src/lib/protocols/update.ts @@ -7,7 +7,8 @@ import { PacketBodyValue, ProtocolDecoder, ProtocolMessage, - decodeProtocolMessage + decodeProtocolMessage, + ProtocolNotification } from '@ucap-webmessenger/protocol'; export interface UpdateRequest extends ProtocolRequest { @@ -24,6 +25,13 @@ export interface UpdateResponse extends ProtocolResponse { isFavorit: boolean; } +export interface UpdateNotification extends ProtocolNotification { + // 0. 사용자SEQ(n) + seq: number; + // 1. 즐겨찾기여부(y) + isFavorit: boolean; +} + export const encodeUpdate: ProtocolEncoder = ( req: UpdateRequest ) => { @@ -46,3 +54,12 @@ export const decodeUpdate: ProtocolDecoder = ( isFavorit: message.bodyList[1] === 'Y' ? true : false } as UpdateResponse); }; + +export const decodeUpdateNotification: ProtocolDecoder = ( + message: ProtocolMessage +) => { + return decodeProtocolMessage(message, { + seq: message.bodyList[0], + isFavorit: message.bodyList[1] === 'Y' ? true : false + } as UpdateNotification); +}; diff --git a/projects/ucap-webmessenger-protocol-buddy/src/lib/services/buddy-protocol.service.ts b/projects/ucap-webmessenger-protocol-buddy/src/lib/services/buddy-protocol.service.ts index dc303f13..dac236c4 100644 --- a/projects/ucap-webmessenger-protocol-buddy/src/lib/services/buddy-protocol.service.ts +++ b/projects/ucap-webmessenger-protocol-buddy/src/lib/services/buddy-protocol.service.ts @@ -1,7 +1,7 @@ import { Injectable } from '@angular/core'; -import { Observable } from 'rxjs'; -import { map, take } from 'rxjs/operators'; +import { Observable, Subject } from 'rxjs'; +import { map, take, share, filter, tap } from 'rxjs/operators'; import { ProtocolService } from '@ucap-webmessenger/protocol'; @@ -9,33 +9,80 @@ import { SVC_TYPE_BUDDY, SSVC_TYPE_BUDDY_ADD_REQ, SSVC_TYPE_BUDDY_DEL_REQ, - SSVC_TYPE_BUDDY_UPD_REQ + SSVC_TYPE_BUDDY_UPD_REQ, + SSVC_TYPE_BUDDY_UPD_RES, + SSVC_TYPE_BUDDY_ADD_RES, + SSVC_TYPE_BUDDY_DEL_RES } from '../types/service'; import { AddRequest, encodeAdd, decodeAdd, - AddResponse + AddResponse, + decodeAddNotification, + AddNotification } from '../protocols/add'; import { DelRequest, encodeDel, decodeDel, - DelResponse + DelResponse, + decodeDelNotification, + DelNotification } from '../protocols/del'; import { UpdateRequest, decodeUpdate, encodeUpdate, - UpdateResponse + UpdateResponse, + UpdateNotification, + decodeUpdateNotification } from '../protocols/update'; +type Notifications = UpdateNotification | AddNotification | DelNotification; + @Injectable({ providedIn: 'root' }) export class BuddyProtocolService { - constructor(private protocolService: ProtocolService) {} + private notificationSubject: Subject; + public notification$: Observable; + + constructor(private protocolService: ProtocolService) { + this.notificationSubject = new Subject(); + this.notification$ = this.notificationSubject.asObservable().pipe(share()); + + this.protocolService.serverMessage + .pipe( + filter(message => message.serviceType === SVC_TYPE_BUDDY), + tap(message => { + switch (message.subServiceType) { + case SSVC_TYPE_BUDDY_UPD_RES: + { + this.notificationSubject.next( + decodeUpdateNotification(message) + ); + } + break; + case SSVC_TYPE_BUDDY_ADD_RES: + { + this.notificationSubject.next(decodeAddNotification(message)); + } + break; + case SSVC_TYPE_BUDDY_DEL_RES: + { + this.notificationSubject.next(decodeDelNotification(message)); + } + break; + + default: + break; + } + }) + ) + .subscribe(); + } public add(req: AddRequest): Observable { return this.protocolService diff --git a/projects/ucap-webmessenger-protocol-file/src/lib/types/file.type.ts b/projects/ucap-webmessenger-protocol-file/src/lib/types/file.type.ts index 9d244882..109130ff 100644 --- a/projects/ucap-webmessenger-protocol-file/src/lib/types/file.type.ts +++ b/projects/ucap-webmessenger-protocol-file/src/lib/types/file.type.ts @@ -5,6 +5,8 @@ export enum FileType { Video = 'V', // F : 파일 File = 'F', + // S : 사운드파일 + Sound = 'S', // "" 빈값이면 모든 타입을 내려줌 All = '' } diff --git a/projects/ucap-webmessenger-protocol-group/src/lib/protocols/add.ts b/projects/ucap-webmessenger-protocol-group/src/lib/protocols/add.ts index a9edf90a..e8e7335b 100644 --- a/projects/ucap-webmessenger-protocol-group/src/lib/protocols/add.ts +++ b/projects/ucap-webmessenger-protocol-group/src/lib/protocols/add.ts @@ -7,18 +7,26 @@ import { PacketBodyValue, ProtocolDecoder, ProtocolMessage, - decodeProtocolMessage + decodeProtocolMessage, + ProtocolNotification } from '@ucap-webmessenger/protocol'; export interface AddRequest extends ProtocolRequest { - // 0. 동료그룹이름 + /** 0. 동료그룹이름 */ groupName: string; } export interface AddResponse extends ProtocolResponse { - // 0: 동료그룹SEQ(n) + /** 0: 동료그룹SEQ(n) */ groupSeq: number; - // 1: 동료그룹이름(s) + /** 1: 동료그룹이름(s) */ + groupName: string; +} + +export interface AddNotification extends ProtocolNotification { + /** 0: 동료그룹SEQ(n) */ + groupSeq: number; + /** 1: 동료그룹이름(s) */ groupName: string; } @@ -38,3 +46,12 @@ export const decodeAdd: ProtocolDecoder = ( groupName: message.bodyList[1] } as AddResponse); }; + +export const decodeAddNotification: ProtocolDecoder = ( + message: ProtocolMessage +) => { + return decodeProtocolMessage(message, { + groupSeq: message.bodyList[0], + groupName: message.bodyList[1] + } as AddNotification); +}; diff --git a/projects/ucap-webmessenger-protocol-group/src/lib/protocols/del.ts b/projects/ucap-webmessenger-protocol-group/src/lib/protocols/del.ts index b283930a..6269da5c 100644 --- a/projects/ucap-webmessenger-protocol-group/src/lib/protocols/del.ts +++ b/projects/ucap-webmessenger-protocol-group/src/lib/protocols/del.ts @@ -7,16 +7,22 @@ import { PacketBodyValue, ProtocolDecoder, ProtocolMessage, - decodeProtocolMessage + decodeProtocolMessage, + ProtocolNotification } from '@ucap-webmessenger/protocol'; export interface DelRequest extends ProtocolRequest { - // 0: 동료그룹SEQ(n) + /** 동료그룹SEQ(n) */ groupSeq: number; } export interface DelResponse extends ProtocolResponse { - // 0: 동료그룹SEQ(n) + /** 동료그룹SEQ(n) */ + groupSeq: number; +} + +export interface DelNotification extends ProtocolNotification { + /** 동료그룹SEQ(n) */ groupSeq: number; } @@ -35,3 +41,11 @@ export const decodeDel: ProtocolDecoder = ( groupSeq: message.bodyList[0] } as DelResponse); }; + +export const decodeDelNotification: ProtocolDecoder = ( + message: ProtocolMessage +) => { + return decodeProtocolMessage(message, { + groupSeq: message.bodyList[0] + } as DelNotification); +}; diff --git a/projects/ucap-webmessenger-protocol-group/src/lib/protocols/update.ts b/projects/ucap-webmessenger-protocol-group/src/lib/protocols/update.ts index 303127f3..3edcf585 100644 --- a/projects/ucap-webmessenger-protocol-group/src/lib/protocols/update.ts +++ b/projects/ucap-webmessenger-protocol-group/src/lib/protocols/update.ts @@ -7,24 +7,34 @@ import { PacketBodyValue, ProtocolDecoder, ProtocolMessage, - decodeProtocolMessage + decodeProtocolMessage, + ProtocolNotification } from '@ucap-webmessenger/protocol'; export interface UpdateRequest extends ProtocolRequest { - // 0: 동료그룹SEQ(n) + /** 0: 동료그룹SEQ(n) */ groupSeq: number; - // 1: 동료그룹이름(s) + /** 1: 동료그룹이름(s) */ groupName: string; - // 2n: 사용자SEQ(n)... + /** 2n: 사용자SEQ(n)... */ userSeqs: number[]; } export interface UpdateResponse extends ProtocolResponse { - // 0: 동료그룹SEQ(n) + /** 0: 동료그룹SEQ(n) */ groupSeq: number; - // 1: 동료그룹이름(s) + /** 1: 동료그룹이름(s) */ groupName: string; - // 2n: 사용자SEQ(n)... + /** 2n: 사용자SEQ(n)... */ + userSeqs: number[]; +} + +export interface UpdateNotification extends ProtocolNotification { + /** 0: 동료그룹SEQ(n) */ + groupSeq: number; + /** 1: 동료그룹이름(s) */ + groupName: string; + /** 2n: 사용자SEQ(n)... */ userSeqs: number[]; } @@ -90,3 +100,18 @@ export const decodeUpdate2: ProtocolDecoder = ( userSeqs: userSeqArray } as UpdateResponse); }; + +export const decodeUpdate2Notification: ProtocolDecoder = ( + message: ProtocolMessage +) => { + let userSeqArray: number[] = []; + if (message.bodyList.length > 2) { + userSeqArray = message.bodyList.slice(2); + } + + return decodeProtocolMessage(message, { + groupSeq: message.bodyList[0], + groupName: message.bodyList[1], + userSeqs: userSeqArray + } as UpdateNotification); +}; diff --git a/projects/ucap-webmessenger-protocol-group/src/lib/services/group-protocol.service.ts b/projects/ucap-webmessenger-protocol-group/src/lib/services/group-protocol.service.ts index 4fa1d324..9049c2d1 100644 --- a/projects/ucap-webmessenger-protocol-group/src/lib/services/group-protocol.service.ts +++ b/projects/ucap-webmessenger-protocol-group/src/lib/services/group-protocol.service.ts @@ -1,7 +1,12 @@ +import { + SSVC_TYPE_GROUP_UPD_RES2, + SSVC_TYPE_GROUP_ADD_RES, + SSVC_TYPE_GROUP_DEL_RES +} from './../types/service'; import { Injectable } from '@angular/core'; -import { Observable } from 'rxjs'; -import { map, take } from 'rxjs/operators'; +import { Observable, Subject } from 'rxjs'; +import { map, take, share, filter, tap } from 'rxjs/operators'; import { ProtocolService } from '@ucap-webmessenger/protocol'; import { @@ -15,13 +20,17 @@ import { AddRequest, encodeAdd, decodeAdd, - AddResponse + AddResponse, + decodeAddNotification, + AddNotification } from '../protocols/add'; import { DelRequest, encodeDel, decodeDel, - DelResponse + DelResponse, + decodeDelNotification, + DelNotification } from '../protocols/del'; import { UpdateRequest, @@ -29,13 +38,54 @@ import { decodeUpdate, encodeUpdate2, decodeUpdate2, - UpdateResponse + UpdateResponse, + UpdateNotification, + decodeUpdate2Notification } from '../protocols/update'; + +type Notifications = UpdateNotification | AddNotification | DelNotification; + @Injectable({ providedIn: 'root' }) export class GroupProtocolService { - constructor(private protocolService: ProtocolService) {} + private notificationSubject: Subject; + public notification$: Observable; + + constructor(private protocolService: ProtocolService) { + this.notificationSubject = new Subject(); + this.notification$ = this.notificationSubject.asObservable().pipe(share()); + + this.protocolService.serverMessage + .pipe( + filter(message => message.serviceType === SVC_TYPE_GROUP), + tap(message => { + switch (message.subServiceType) { + case SSVC_TYPE_GROUP_UPD_RES2: + { + this.notificationSubject.next( + decodeUpdate2Notification(message) + ); + } + break; + case SSVC_TYPE_GROUP_ADD_RES: + { + this.notificationSubject.next(decodeAddNotification(message)); + } + break; + case SSVC_TYPE_GROUP_DEL_RES: + { + this.notificationSubject.next(decodeDelNotification(message)); + } + break; + + default: + break; + } + }) + ) + .subscribe(); + } public add(req: AddRequest): Observable { return this.protocolService diff --git a/projects/ucap-webmessenger-protocol-room/src/lib/services/room-protocol.service.ts b/projects/ucap-webmessenger-protocol-room/src/lib/services/room-protocol.service.ts index fb658e50..124e70a0 100644 --- a/projects/ucap-webmessenger-protocol-room/src/lib/services/room-protocol.service.ts +++ b/projects/ucap-webmessenger-protocol-room/src/lib/services/room-protocol.service.ts @@ -103,11 +103,14 @@ import { encodeUpdateFont, decodeUpdateFont, decodeUpdateFontNotification, - UpdateFontNotification + UpdateFontNotification, + decodeUpdateNotification, + UpdateNotification } from '../protocols/update'; type Notifications = | UpdateFontNotification + | UpdateNotification | InviteNotification | ExitNotification | ExitForcingNotification; @@ -130,7 +133,9 @@ export class RoomProtocolService { switch (message.subServiceType) { case SSVC_TYPE_ROOM_UPD_RES: { - this.notificationSubject.next(decodeUpdate(message)); + this.notificationSubject.next( + decodeUpdateNotification(message) + ); } break; case SSVC_TYPE_ROOM_INVITE_NOTI: diff --git a/projects/ucap-webmessenger-ui-chat/src/lib/components/message-box/attach-file.component.html b/projects/ucap-webmessenger-ui-chat/src/lib/components/message-box/attach-file.component.html index 09906b5f..95d6278d 100644 --- a/projects/ucap-webmessenger-ui-chat/src/lib/components/message-box/attach-file.component.html +++ b/projects/ucap-webmessenger-ui-chat/src/lib/components/message-box/attach-file.component.html @@ -1,20 +1,23 @@
-
+
  • {{ fileInfo.FileName }}
  • - {{ fileInfo.AttSize }} + {{ fileInfo.AttSize | ucapBytes }}
  • {{ fileInfo.FileExt }}
-
-
    +
    +
      +
    • 기간이 만료된 파일입니다.
    • +
    +
    • diff --git a/projects/ucap-webmessenger-ui-chat/src/lib/components/message-box/attach-file.component.scss b/projects/ucap-webmessenger-ui-chat/src/lib/components/message-box/attach-file.component.scss index e8649832..a3979d30 100644 --- a/projects/ucap-webmessenger-ui-chat/src/lib/components/message-box/attach-file.component.scss +++ b/projects/ucap-webmessenger-ui-chat/src/lib/components/message-box/attach-file.component.scss @@ -33,13 +33,15 @@ background-image: url(/assets/images/file/icon_talk_hwp_d.png); } } - &.ppt { + &.ppt, + &.pptx { background-image: url(/assets/images/file/icon_talk_ppt.png); &.disable { background-image: url(/assets/images/file/icon_talk_ppt_d.png); } } - &.xls { + &.xls, + &.xlsx { background-image: url(/assets/images/file/icon_talk_xls.png); &.disable { background-image: url(/assets/images/file/icon_talk_xls_d.png); diff --git a/projects/ucap-webmessenger-ui-chat/src/lib/components/message-box/attach-file.component.ts b/projects/ucap-webmessenger-ui-chat/src/lib/components/message-box/attach-file.component.ts index 655b8f64..dc185431 100644 --- a/projects/ucap-webmessenger-ui-chat/src/lib/components/message-box/attach-file.component.ts +++ b/projects/ucap-webmessenger-ui-chat/src/lib/components/message-box/attach-file.component.ts @@ -10,6 +10,9 @@ import { NGXLogger } from 'ngx-logger'; export class AttachFileComponent implements OnInit { @Input() fileInfo: FileInfo; + @Input() + expired = false; + @Output() save = new EventEmitter(); diff --git a/projects/ucap-webmessenger-ui-chat/src/lib/components/message-box/file.component.html b/projects/ucap-webmessenger-ui-chat/src/lib/components/message-box/file.component.html index 3aa86267..2caf80c8 100644 --- a/projects/ucap-webmessenger-ui-chat/src/lib/components/message-box/file.component.html +++ b/projects/ucap-webmessenger-ui-chat/src/lib/components/message-box/file.component.html @@ -1,9 +1,35 @@ - - + + - - - + + + + + diff --git a/projects/ucap-webmessenger-ui-chat/src/lib/components/message-box/file.component.ts b/projects/ucap-webmessenger-ui-chat/src/lib/components/message-box/file.component.ts index 553c2d4f..86052166 100644 --- a/projects/ucap-webmessenger-ui-chat/src/lib/components/message-box/file.component.ts +++ b/projects/ucap-webmessenger-ui-chat/src/lib/components/message-box/file.component.ts @@ -1,5 +1,5 @@ import { Component, OnInit, Output, Input, EventEmitter } from '@angular/core'; -import { Info } from '@ucap-webmessenger/protocol-event'; +import { Info, InfoResponse } from '@ucap-webmessenger/protocol-event'; import { StatusCode } from '@ucap-webmessenger/api'; import { FileType } from '@ucap-webmessenger/protocol-file'; import { NGXLogger } from 'ngx-logger'; @@ -13,6 +13,8 @@ import { FileInfo } from '../../models/file-info.json'; export class FileComponent implements OnInit { @Input() message: Info; + @Input() + eventInfoStatus: InfoResponse; @Output() save = new EventEmitter<{ fileInfo: FileInfo; type: string }>(); @@ -34,6 +36,17 @@ export class FileComponent implements OnInit { } } + getExpiredFile() { + if ( + !!this.eventInfoStatus && + this.eventInfoStatus.validFileBaseSeq < this.message.seq + ) { + return false; + } else { + return true; + } + } + onClickImageViewer(fileInfo: FileInfo) { this.imageViewer.emit(this.fileInfo); } diff --git a/projects/ucap-webmessenger-ui-chat/src/lib/components/message-box/image.component.ts b/projects/ucap-webmessenger-ui-chat/src/lib/components/message-box/image.component.ts index e34add3e..630936cf 100644 --- a/projects/ucap-webmessenger-ui-chat/src/lib/components/message-box/image.component.ts +++ b/projects/ucap-webmessenger-ui-chat/src/lib/components/message-box/image.component.ts @@ -10,6 +10,8 @@ import { FileInfo } from '../../models/file-info.json'; export class ImageComponent implements OnInit { @Input() fileInfo: FileInfo; + @Input() + expired = false; constructor(private logger: NGXLogger) {} diff --git a/projects/ucap-webmessenger-ui-chat/src/lib/components/message-box/video.component.ts b/projects/ucap-webmessenger-ui-chat/src/lib/components/message-box/video.component.ts index b53ae704..cf717735 100644 --- a/projects/ucap-webmessenger-ui-chat/src/lib/components/message-box/video.component.ts +++ b/projects/ucap-webmessenger-ui-chat/src/lib/components/message-box/video.component.ts @@ -10,6 +10,8 @@ import { FileInfo } from '../../models/file-info.json'; export class VideoComponent implements OnInit { @Input() fileInfo: FileInfo; + @Input() + expired = false; constructor(private logger: NGXLogger) {} diff --git a/projects/ucap-webmessenger-ui-chat/src/lib/components/messages.component.html b/projects/ucap-webmessenger-ui-chat/src/lib/components/messages.component.html index c211ed7c..d3b1638a 100644 --- a/projects/ucap-webmessenger-ui-chat/src/lib/components/messages.component.html +++ b/projects/ucap-webmessenger-ui-chat/src/lib/components/messages.component.html @@ -103,6 +103,7 @@