From d11e47a272c3c219aead65a341903245b730e59b Mon Sep 17 00:00:00 2001 From: leejinho Date: Tue, 10 Dec 2019 12:38:20 +0900 Subject: [PATCH] =?UTF-8?q?=EB=8C=80=ED=99=94=EB=B0=A9=20=EB=82=B4=20?= =?UTF-8?q?=EA=B0=95=ED=87=B4=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../room-user-list.component.html | 20 ++++ .../right-drawer/room-user-list.component.ts | 93 ++++++++++++++++++- .../src/app/services/notification.service.ts | 17 ++-- .../src/app/store/messenger/room/actions.ts | 27 ++++-- .../src/app/store/messenger/room/effects.ts | 23 ++++- .../src/app/store/messenger/sync/effects.ts | 49 ++++++++-- .../src/lib/protocols/exit.ts | 8 +- 7 files changed, 204 insertions(+), 33 deletions(-) diff --git a/projects/ucap-webmessenger-app/src/app/layouts/messenger/components/right-drawer/room-user-list.component.html b/projects/ucap-webmessenger-app/src/app/layouts/messenger/components/right-drawer/room-user-list.component.html index df71280d..f658a053 100644 --- a/projects/ucap-webmessenger-app/src/app/layouts/messenger/components/right-drawer/room-user-list.component.html +++ b/projects/ucap-webmessenger-app/src/app/layouts/messenger/components/right-drawer/room-user-list.component.html @@ -5,6 +5,7 @@ [userInfo]="userInfo" [presence]="getStatusBulkInfo(userInfo) | async" [sessionVerinfo]="sessionVerinfo" + (contextmenu)="onContextMenuRoomUser($event, userInfo)" (openProfile)="onClickOpenProfile($event)" > @@ -23,3 +24,22 @@ + +
+ + + + + diff --git a/projects/ucap-webmessenger-app/src/app/layouts/messenger/components/right-drawer/room-user-list.component.ts b/projects/ucap-webmessenger-app/src/app/layouts/messenger/components/right-drawer/room-user-list.component.ts index 5d733c14..67c65b8e 100644 --- a/projects/ucap-webmessenger-app/src/app/layouts/messenger/components/right-drawer/room-user-list.component.ts +++ b/projects/ucap-webmessenger-app/src/app/layouts/messenger/components/right-drawer/room-user-list.component.ts @@ -3,7 +3,8 @@ import { OnInit, OnDestroy, Output, - EventEmitter + EventEmitter, + ViewChild } from '@angular/core'; import { Subscription } from 'rxjs'; import { Store, select } from '@ngrx/store'; @@ -13,11 +14,16 @@ import * as AppStore from '@app/store'; import * as SyncStore from '@app/store/messenger/sync'; import * as RoomStore from '@app/store/messenger/room'; -import { UserInfo } from '@ucap-webmessenger/protocol-room'; +import { UserInfo, RoomInfo } from '@ucap-webmessenger/protocol-room'; import { VersionInfo2Response } from '@ucap-webmessenger/api-public'; import { SessionStorageService } from '@ucap-webmessenger/web-storage'; import { KEY_VER_INFO } from '@app/types/ver-info.type'; -import { DialogService } from '@ucap-webmessenger/ui'; +import { + DialogService, + ConfirmDialogComponent, + ConfirmDialogResult, + ConfirmDialogData +} from '@ucap-webmessenger/ui'; import { SelectGroupDialogComponent, SelectGroupDialogResult, @@ -32,6 +38,7 @@ import { import { UserSelectDialogType } from '@app/types'; import { LoginResponse } from '@ucap-webmessenger/protocol-authentication'; import { KEY_LOGIN_RES_INFO } from '@app/types/login-res-info.type'; +import { MatMenuTrigger, MatDialog } from '@angular/material'; @Component({ selector: 'app-layout-chat-right-drawer-room-user-list', @@ -42,6 +49,13 @@ export class RoomUserListComponent implements OnInit, OnDestroy { @Output() openProfile = new EventEmitter(); + @ViewChild('roomUserContextMenuTrigger', { static: true }) + roomUserContextMenuTrigger: MatMenuTrigger; + roomUserContextMenuPosition = { x: '0px', y: '0px' }; + + roomInfo: RoomInfo; + roomInfoSubscription: Subscription; + userInfoList: UserInfo[]; userInfoListSubscription: Subscription; @@ -51,7 +65,8 @@ export class RoomUserListComponent implements OnInit, OnDestroy { constructor( private store: Store, private sessionStorageService: SessionStorageService, - private dialogService: DialogService + private dialogService: DialogService, + private dialogRef: MatDialog ) { this.loginRes = this.sessionStorageService.get( KEY_LOGIN_RES_INFO @@ -72,12 +87,35 @@ export class RoomUserListComponent implements OnInit, OnDestroy { }) ) .subscribe(); + + this.roomInfoSubscription = this.store + .pipe( + select(AppStore.MessengerSelector.RoomSelector.roomInfo), + tap(roomInfo => { + this.roomInfo = roomInfo; + this.clearView(); + }) + ) + .subscribe(); } ngOnDestroy(): void { if (!!this.userInfoListSubscription) { this.userInfoListSubscription.unsubscribe(); } + if (!!this.roomInfoSubscription) { + this.roomInfoSubscription.unsubscribe(); + } + } + + clearView() { + if ( + !!this.roomUserContextMenuTrigger && + this.roomUserContextMenuTrigger.menuOpen + ) { + this.roomUserContextMenuTrigger.closeMenu(); + } + this.dialogRef.closeAll(); } getStatusBulkInfo(buddy: UserInfo) { @@ -173,4 +211,51 @@ export class RoomUserListComponent implements OnInit, OnDestroy { } } } + + onContextMenuRoomUser(event: MouseEvent, buddy: UserInfo) { + event.preventDefault(); + event.stopPropagation(); + + if (buddy.seq === this.loginRes.userSeq) { + return; + } + + this.roomUserContextMenuPosition.x = event.clientX + 'px'; + this.roomUserContextMenuPosition.y = event.clientY + 'px'; + this.roomUserContextMenuTrigger.menu.focusFirstItem('mouse'); + this.roomUserContextMenuTrigger.menuData = { buddy }; + this.roomUserContextMenuTrigger.openMenu(); + } + + async onClickContextMenu(type: string, buddy: UserInfo) { + switch (type) { + case 'FORCING_EXIT': + { + const result = await this.dialogService.open< + ConfirmDialogComponent, + ConfirmDialogData, + ConfirmDialogResult + >(ConfirmDialogComponent, { + data: { + title: '강제 퇴장', + html: `${buddy.name} 님을 대화방에서 퇴장 시키겠습니까?` + } + }); + + if (!!result && !!result.choice && result.choice) { + this.store.dispatch( + RoomStore.exitForcing({ + req: { + roomSeq: this.roomInfo.roomSeq, + senderSeq: this.loginRes.userSeq, + type: 'A', + userSeqs: [buddy.seq] + } + }) + ); + } + } + break; + } + } } 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 0966a8ec..e1af66c9 100644 --- a/projects/ucap-webmessenger-app/src/app/services/notification.service.ts +++ b/projects/ucap-webmessenger-app/src/app/services/notification.service.ts @@ -40,7 +40,8 @@ import { SSVC_TYPE_ROOM_UPD_RES, SSVC_TYPE_ROOM_EXIT_FORCING_RES, SSVC_TYPE_ROOM_EXIT_RES, - SSVC_TYPE_ROOM_INVITE_RES + SSVC_TYPE_ROOM_INVITE_RES, + ExitForcingResponse } from '@ucap-webmessenger/protocol-room'; import { StatusProtocolService, @@ -413,14 +414,14 @@ export class AppNotificationService { case SSVC_TYPE_ROOM_EXIT_FORCING_RES: { // 내가 강퇴 진행. - const noti = notiOrRes as ExitForcingNotification; + const res = notiOrRes as ExitForcingResponse; this.logger.debug( - 'Notification::roomProtocolService::ExitForcingNotification', - noti + 'Notification::roomProtocolService::ExitForcingNotification RES', + res ); this.store.dispatch( - RoomStore.exitForcingNotificationRes({ - noti + RoomStore.exitForcingSuccess({ + res }) ); } @@ -430,11 +431,11 @@ export class AppNotificationService { // 내가 강퇴 됨. const noti = notiOrRes as ExitForcingNotification; this.logger.debug( - 'Notification::roomProtocolService::ExitForcingNotification', + 'Notification::roomProtocolService::ExitForcingNotification NOTI', noti ); this.store.dispatch( - RoomStore.exitForcingNotificationNoti({ + RoomStore.exitForcingNotification({ noti }) ); diff --git a/projects/ucap-webmessenger-app/src/app/store/messenger/room/actions.ts b/projects/ucap-webmessenger-app/src/app/store/messenger/room/actions.ts index 09201b0e..884db051 100644 --- a/projects/ucap-webmessenger-app/src/app/store/messenger/room/actions.ts +++ b/projects/ucap-webmessenger-app/src/app/store/messenger/room/actions.ts @@ -19,7 +19,9 @@ import { InviteRequest, InviteResponse, UpdateTimerSetRequest, - UpdateTimerSetResponse + UpdateTimerSetResponse, + ExitForcingRequest, + ExitForcingResponse } from '@ucap-webmessenger/protocol-room'; import { ReadNotification } from '@ucap-webmessenger/protocol-event'; @@ -27,7 +29,6 @@ export const info = createAction( '[Messenger::Room] Info', props() ); - export const infoSuccess = createAction( '[Messenger::Room] Info Success', props<{ @@ -36,7 +37,6 @@ export const infoSuccess = createAction( userInfoList: UserInfo[]; }>() ); - export const infoFailure = createAction( '[Messenger::Room] Info Failure', props<{ error: any }>() @@ -52,17 +52,26 @@ export const exitNotification = createAction( props<{ noti: ExitNotification }>() ); -export const exitForcingNotificationRes = createAction( - '[Messenger::Room] Exit Forcing Notification // Do Forcing', - props<{ noti: ExitForcingNotification }>() +export const exitForcing = createAction( + '[Messenger::Room] Exit Forcing', + props<{ req: ExitForcingRequest }>() ); -export const exitForcingNotificationNoti = createAction( - '[Messenger::Room] Exit Forcing Notification // Forcing Me', +export const exitForcingSuccess = createAction( + '[Messenger::Room] Exit Forcing Success', + props<{ res: ExitForcingResponse }>() +); +export const exitForcingFailure = createAction( + '[Messenger::Room] Exit Forcing Failure', + props<{ error: any }>() +); + +export const exitForcingNotification = createAction( + '[Messenger::Room] Exit Forcing Notification // Forcing Me', props<{ noti: ExitForcingNotification }>() ); export const updateFontNotification = createAction( - '[Messenger::Room] Update Font Notification', + '[Messenger::Room] Update Font Notification', props<{ noti: UpdateFontNotification }>() ); diff --git a/projects/ucap-webmessenger-app/src/app/store/messenger/room/effects.ts b/projects/ucap-webmessenger-app/src/app/store/messenger/room/effects.ts index 8288c8a4..262522ac 100644 --- a/projects/ucap-webmessenger-app/src/app/store/messenger/room/effects.ts +++ b/projects/ucap-webmessenger-app/src/app/store/messenger/room/effects.ts @@ -33,7 +33,8 @@ import { Open3Response, RoomType, InviteResponse, - UpdateTimerSetResponse + UpdateTimerSetResponse, + ExitForcingResponse } from '@ucap-webmessenger/protocol-room'; import * as ChatStore from '@app/store/messenger/chat'; @@ -63,7 +64,10 @@ import { inviteFailure, updateTimeRoomInterval, updateTimeRoomIntervalSuccess, - updateTimeRoomIntervalFailure + updateTimeRoomIntervalFailure, + exitForcing, + exitForcingFailure, + exitForcingSuccess } from './actions'; import { SessionStorageService } from '@ucap-webmessenger/web-storage'; import { LoginInfo, KEY_LOGIN_INFO } from '@app/types'; @@ -285,6 +289,21 @@ export class Effects { ) ); + exitForcing$ = createEffect(() => + this.actions$.pipe( + ofType(exitForcing), + map(action => action.req), + exhaustMap(req => { + return this.roomProtocolService.exitForcing(req).pipe( + map((res: ExitForcingResponse) => { + return exitForcingSuccess({ res }); + }), + catchError(error => of(exitForcingFailure({ error }))) + ); + }) + ) + ); + inviteNotification$ = createEffect( () => { return this.actions$.pipe( 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 482d9a0c..87c6e5f8 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 @@ -472,6 +472,7 @@ export class Effects { { dispatch: false } ); + // 대화상대 초대 성공 후 처리. inviteSuccess$ = createEffect(() => this.actions$.pipe( ofType(RoomStore.inviteSuccess), @@ -502,10 +503,45 @@ export class Effects { ) ); - exitForcingNotificationRes$ = createEffect( + // 대화상대 강제퇴장 수행 후 처리. + // exitForcingNotificationRes$ = createEffect( + // () => { + // return this.actions$.pipe( + // ofType(RoomStore.exitForcingNotificationRes), + // withLatestFrom( + // this.store.pipe( + // select((state: any) => state.messenger.room.roomInfo as RoomInfo) + // ), + // this.store.pipe( + // select((state: any) => state.messenger.sync.room.syncDate as string) + // ) + // ), + // tap(([action, roomInfo, roomSyncDate]) => { + // if (!!roomInfo && roomInfo.roomSeq === action.noti.roomSeq) { + // this.store.dispatch( + // ChatStore.selectedRoom({ roomSeq: action.noti.roomSeq }) + // ); + // } + + // const loginInfo = this.sessionStorageService.get( + // KEY_LOGIN_INFO + // ); + + // this.store.dispatch( + // room({ + // syncDate: roomSyncDate, + // localeCode: loginInfo.localeCode + // }) + // ); + // }) + // ); + // }, + // { dispatch: false } + // ); + exitForcingSuccess$ = createEffect( () => { return this.actions$.pipe( - ofType(RoomStore.exitForcingNotificationRes), + ofType(RoomStore.exitForcingSuccess), withLatestFrom( this.store.pipe( select((state: any) => state.messenger.room.roomInfo as RoomInfo) @@ -515,9 +551,9 @@ export class Effects { ) ), tap(([action, roomInfo, roomSyncDate]) => { - if (!!roomInfo && roomInfo.roomSeq === action.noti.roomSeq) { + if (!!roomInfo && roomInfo.roomSeq === action.res.roomSeq) { this.store.dispatch( - ChatStore.selectedRoom({ roomSeq: action.noti.roomSeq }) + ChatStore.selectedRoom({ roomSeq: action.res.roomSeq }) ); } @@ -536,10 +572,11 @@ export class Effects { }, { dispatch: false } ); - exitForcingNotificationNoti$ = createEffect( + // 대화방에서 강제퇴장 받은 후 처리. + exitForcingNotification$ = createEffect( () => { return this.actions$.pipe( - ofType(RoomStore.exitForcingNotificationNoti), + ofType(RoomStore.exitForcingNotification), withLatestFrom( this.store.pipe( select((state: any) => state.messenger.room.roomInfo as RoomInfo) diff --git a/projects/ucap-webmessenger-protocol-room/src/lib/protocols/exit.ts b/projects/ucap-webmessenger-protocol-room/src/lib/protocols/exit.ts index 16e634c0..e25b69db 100644 --- a/projects/ucap-webmessenger-protocol-room/src/lib/protocols/exit.ts +++ b/projects/ucap-webmessenger-protocol-room/src/lib/protocols/exit.ts @@ -85,7 +85,7 @@ export interface ExitForcingRequest extends ProtocolRequest { userSeqs: number[]; } -export interface ExitForcingResponse extends ProtocolRequest { +export interface ExitForcingResponse extends ProtocolResponse { // 대화방SEQ(s) roomSeq: string; // 강퇴요청타입(s) @@ -135,9 +135,9 @@ export const decodeExitForcing: ProtocolDecoder = ( userSeqs } as ExitForcingResponse); }; -export const decodeExitForcingNotification: ProtocolDecoder< - ExitForcingNotification -> = (message: ProtocolMessage) => { +export const decodeExitForcingNotification: ProtocolDecoder = ( + message: ProtocolMessage +) => { let userSeqs: number[] = []; if (message.bodyList.length > 3) { userSeqs = message.bodyList.slice(3);