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);