대화방 내 강퇴기능 구현
This commit is contained in:
parent
7060e3a7af
commit
d11e47a272
|
@ -5,6 +5,7 @@
|
|||
[userInfo]="userInfo"
|
||||
[presence]="getStatusBulkInfo(userInfo) | async"
|
||||
[sessionVerinfo]="sessionVerinfo"
|
||||
(contextmenu)="onContextMenuRoomUser($event, userInfo)"
|
||||
(openProfile)="onClickOpenProfile($event)"
|
||||
>
|
||||
</ucap-profile-user-list-item>
|
||||
|
@ -23,3 +24,22 @@
|
|||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
style="visibility: hidden; position: fixed"
|
||||
[style.left]="roomUserContextMenuPosition.x"
|
||||
[style.top]="roomUserContextMenuPosition.y"
|
||||
#roomUserContextMenuTrigger="matMenuTrigger"
|
||||
[matMenuTriggerFor]="roomUserContextMenu"
|
||||
></div>
|
||||
<mat-menu
|
||||
#roomUserContextMenu="matMenu"
|
||||
[hasBackdrop]="false"
|
||||
(ucapClickOutside)="roomUserContextMenuTrigger.closeMenu()"
|
||||
>
|
||||
<ng-template matMenuContent let-buddy="buddy">
|
||||
<button mat-menu-item (click)="onClickContextMenu('FORCING_EXIT', buddy)">
|
||||
대화방 퇴장
|
||||
</button>
|
||||
</ng-template>
|
||||
</mat-menu>
|
||||
|
|
|
@ -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<UserInfo>();
|
||||
|
||||
@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<any>,
|
||||
private sessionStorageService: SessionStorageService,
|
||||
private dialogService: DialogService
|
||||
private dialogService: DialogService,
|
||||
private dialogRef: MatDialog
|
||||
) {
|
||||
this.loginRes = this.sessionStorageService.get<LoginResponse>(
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
})
|
||||
);
|
||||
|
|
|
@ -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<InfoRequest>()
|
||||
);
|
||||
|
||||
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 }>()
|
||||
);
|
||||
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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<LoginInfo>(
|
||||
// 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)
|
||||
|
|
|
@ -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<ExitForcingResponse> = (
|
|||
userSeqs
|
||||
} as ExitForcingResponse);
|
||||
};
|
||||
export const decodeExitForcingNotification: ProtocolDecoder<
|
||||
ExitForcingNotification
|
||||
> = (message: ProtocolMessage) => {
|
||||
export const decodeExitForcingNotification: ProtocolDecoder<ExitForcingNotification> = (
|
||||
message: ProtocolMessage
|
||||
) => {
|
||||
let userSeqs: number[] = [];
|
||||
if (message.bodyList.length > 3) {
|
||||
userSeqs = message.bodyList.slice(3);
|
||||
|
|
Loading…
Reference in New Issue
Block a user