diff --git a/projects/ucap-webmessenger-app/src/app/app.theme.scss b/projects/ucap-webmessenger-app/src/app/app.theme.scss index 0301d4f8..4eb729b8 100644 --- a/projects/ucap-webmessenger-app/src/app/app.theme.scss +++ b/projects/ucap-webmessenger-app/src/app/app.theme.scss @@ -102,7 +102,7 @@ body.theme-pink-dark { // ----------------------------------------------------------------------------------------------------- // Define the primary, accent and warn palettes -$pink-light-theme-primary-palette: mat-palette($lg-red); +$pink-light-theme-primary-palette: mat-palette($mat-pink); $pink-light-theme-accent-palette: mat-palette($mat-pink); $pink-light-theme-warn-palette: mat-palette($mat-red); diff --git a/projects/ucap-webmessenger-app/src/app/layouts/messenger/components/left-sidenav/group.component.ts b/projects/ucap-webmessenger-app/src/app/layouts/messenger/components/left-sidenav/group.component.ts index 703f17d9..6e8ca823 100644 --- a/projects/ucap-webmessenger-app/src/app/layouts/messenger/components/left-sidenav/group.component.ts +++ b/projects/ucap-webmessenger-app/src/app/layouts/messenger/components/left-sidenav/group.component.ts @@ -306,16 +306,32 @@ export class GroupComponent implements OnInit, OnDestroy { case 'EDIT_MEMBER': { const result = await this.dialogService.open< - EditGroupMemberDialogComponent, - EditGroupMemberDialogData, - EditGroupMemberDialogResult - >(EditGroupMemberDialogComponent, { - width: '220px', + CreateChatDialogComponent, + CreateChatDialogData, + CreateChatDialogResult + >(CreateChatDialogComponent, { + width: '600px', + height: '500px', data: { - title: 'Logout', - message: 'Logout ?' + type: UserSelectDialogType.EditMember, + title: 'Group Member Edit', + group } }); + + if (!!result && !!result.choice && result.choice) { + if (!!result.oldGroup) { + const userSeqs: number[] = []; + result.selectedUserList.map(user => userSeqs.push(user.seq)); + + this.store.dispatch( + SyncStore.updateGroupMember({ + oldGroup: group, + trgtUserSeq: userSeqs + }) + ); + } + } } break; case 'DELETE': 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 983b36cd..9c81d189 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 @@ -37,12 +37,15 @@ import { export interface CreateChatDialogData { type?: string; title: string; + /** CASE :: EditMember */ + group?: GroupDetailData; } export interface CreateChatDialogResult { choice: boolean; selectedUserList?: (UserInfo | UserInfoSS | UserInfoF | UserInfoDN)[]; groupName?: string; + oldGroup?: GroupDetailData; } @Component({ @@ -119,14 +122,23 @@ export class CreateChatDialogComponent implements OnInit, OnDestroy { buddyList: UserInfo[]; }[] = []; for (const group of groupList) { - groupBuddyList.push({ + const data = { group, buddyList: buddyList.filter(buddy => { return group.userSeqs.indexOf(buddy.seq) > -1; }) - }); - } + }; + groupBuddyList.push(data); + /** 그룹 멤버 변경일 경우 그룹원을 기본 셀렉트 한다. */ + if ( + this.data.type === UserSelectDialogType.EditMember && + !!this.data.group && + this.data.group.seq === group.seq + ) { + this.selectedUserList = [...data.buddyList]; + } + } return groupBuddyList; }) ); @@ -280,7 +292,11 @@ export class CreateChatDialogComponent implements OnInit, OnDestroy { groupName: this.data.type === UserSelectDialogType.NewGroup ? this.inputForm.get('groupName').value - : '' + : '', + oldGroup: + this.data.type === UserSelectDialogType.EditMember + ? this.data.group + : undefined }); } } diff --git a/projects/ucap-webmessenger-app/src/app/store/messenger/status/reducers.ts b/projects/ucap-webmessenger-app/src/app/store/messenger/status/reducers.ts index ffdb69c4..97e46b0f 100644 --- a/projects/ucap-webmessenger-app/src/app/store/messenger/status/reducers.ts +++ b/projects/ucap-webmessenger-app/src/app/store/messenger/status/reducers.ts @@ -10,9 +10,12 @@ export const reducer = createReducer( on(bulkInfoSuccess, (state, action) => { return { ...state, - statusBulkInfo: adapterStatusBulkInfo.addAll(action.statusBulkInfoList, { - ...state.statusBulkInfo - }) + statusBulkInfo: adapterStatusBulkInfo.upsertMany( + action.statusBulkInfoList, + { + ...state.statusBulkInfo + } + ) } as State; }), diff --git a/projects/ucap-webmessenger-app/src/app/store/messenger/sync/actions.ts b/projects/ucap-webmessenger-app/src/app/store/messenger/sync/actions.ts index a6e0d8e2..ece508d3 100644 --- a/projects/ucap-webmessenger-app/src/app/store/messenger/sync/actions.ts +++ b/projects/ucap-webmessenger-app/src/app/store/messenger/sync/actions.ts @@ -21,7 +21,11 @@ import { } from '@ucap-webmessenger/protocol-group'; import { AddRequest as BuddyAddRequest, - AddResponse as BuddyAddResponse + AddResponse as BuddyAddResponse, + DelRequest as BuddyDelRequest, + DelResponse as BuddyDelResponse, + UpdateRequest as BuddyUpdateRequest, + UpdateResponse as BuddyUpdateResponse } from '@ucap-webmessenger/protocol-buddy'; export const buddy2 = createAction( @@ -137,32 +141,70 @@ export const createGroupAndBuddy = createAction( trgtUserSeq: number[]; }>() ); - export const createGroupAndBuddySuccess = createAction( '[Messenger::Sync] Group & Buddy Create Success', props() ); - export const createGroupAndBuddyFailure = createAction( '[Messenger::Sync] Group & Buddy Create Failure', props<{ error: any }>() ); +/** 그룹원 수정 */ +export const updateGroupMember = createAction( + '[Messenger::Sync] Update Group Member', + props<{ + oldGroup: GroupDetailData; + trgtUserSeq: number[]; + }>() +); +export const updateGroupMemberSuccess = createAction( + '[Messenger::Sync] Update Group Member Success', + props() +); +export const updateGroupMemberFailure = createAction( + '[Messenger::Sync] Update Group Member Failure', + props<{ error: any }>() +); /** 동료 추가 */ export const addBuddy = createAction( '[Messenger::Sync] Buddy Add', props() ); - export const addBuddySuccess = createAction( '[Messenger::Sync] Buddy Add Success', props() ); - export const addBuddyFailure = createAction( '[Messenger::Sync] Buddy Add Failure', props<{ error: any }>() ); +/** 동료 삭제 */ +export const delBuddy = createAction( + '[Messenger::Sync] Buddy Del', + props() +); +export const delBuddySuccess = createAction( + '[Messenger::Sync] Buddy Del Success', + props() +); +export const delBuddyFailure = createAction( + '[Messenger::Sync] Buddy Del Failure', + props<{ error: any }>() +); +/** 동료 변경(즐겨찾기) */ +export const updateBuddy = createAction( + '[Messenger::Sync] Buddy Update', + props() +); +export const updateBuddySuccess = createAction( + '[Messenger::Sync] Buddy Update Success', + props() +); +export const updateBuddyFailure = createAction( + '[Messenger::Sync] Buddy Update Failure', + props<{ error: any }>() +); /** 그룹원 업데이트 */ export const updateGroup = createAction( 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 e095bfea..7c9c07bc 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 @@ -36,8 +36,13 @@ import { createGroupAndBuddy, addBuddy, addBuddyFailure, + delBuddy, + delBuddyFailure, updateGroup, - updateGroupFailure + updateGroupFailure, + updateGroupMember, + updateBuddy, + delBuddySuccess } from './actions'; import { SessionStorageService } from '@ucap-webmessenger/web-storage'; import { LoginInfo, KEY_LOGIN_INFO } from '@app/types'; @@ -82,7 +87,8 @@ import { } from '@ucap-webmessenger/protocol-group'; import { BuddyProtocolService, - AddResponse as BuddyAddResponse + AddResponse as BuddyAddResponse, + DelResponse as BuddyDelResponse } from '@ucap-webmessenger/protocol-buddy'; import * as ChatStore from '@app/store/messenger/chat'; @@ -456,7 +462,7 @@ export class Effects { }); if (addBuddyList.length > 0) { - this.logger.debug('add : ', addBuddyList); + this.logger.debug('addBuddyList : ', addBuddyList); this.store.dispatch(addBuddy({ userSeqs: addBuddyList })); } @@ -477,6 +483,91 @@ export class Effects { ) ); + updateGroupMember$ = createEffect( + () => { + return this.actions$.pipe( + ofType(updateGroupMember), + withLatestFrom( + this.store.pipe( + select( + (state: any) => + state.messenger.sync.buddy2.entities as Dictionary + ) + ), + this.store.pipe( + select( + (state: any) => + state.messenger.sync.group2.entities as Dictionary< + GroupDetailData + > + ) + ) + ), + tap(([action, buddyList, groupList]) => { + // Add Buddy + const addBuddyList: number[] = []; + action.trgtUserSeq.forEach(item => { + if (!buddyList[item]) { + addBuddyList.push(item); + } + }); + + // Del Buddy + let delBuddyInGroup: number[] = action.oldGroup.userSeqs.filter( + v => action.trgtUserSeq.indexOf(v) < 0 + ); + // tslint:disable-next-line: no-shadowed-variable + delBuddyInGroup = delBuddyInGroup.filter(delBuddy => { + let exist = false; + // tslint:disable-next-line: forin + for (const key in groupList) { + const group: GroupDetailData = groupList[key]; + if ( + group.seq !== action.oldGroup.seq && + group.userSeqs.filter(v => v === delBuddy).length > 0 + ) { + exist = true; + break; + } + } + return !exist; + }); + + if (addBuddyList.length > 0) { + this.logger.debug('addBuddyList : ', addBuddyList); + this.store.dispatch(addBuddy({ userSeqs: addBuddyList })); + } + + if (delBuddyInGroup.length > 0) { + this.logger.debug('delBuddyInGroup', delBuddyInGroup); + // 즐겨찾기 해제. + delBuddyInGroup.forEach(buddySeq => { + this.buddyProtocolService + .update({ + seq: buddySeq, + isFavorit: false + }) + .pipe(catchError(error => of(delBuddyFailure({ error })))); + }); + + // 동료 삭제 + this.store.dispatch(delBuddy({ userSeqs: delBuddyInGroup })); + } + + this.logger.debug('group member update', action.trgtUserSeq); + this.store.dispatch( + updateGroup({ + groupSeq: action.oldGroup.seq, + groupName: action.oldGroup.name, + userSeqs: action.trgtUserSeq + }) + ); + }) + ); + }, + { dispatch: false } + ); + addBuddy$ = createEffect(() => this.actions$.pipe( ofType(addBuddy), @@ -498,6 +589,30 @@ export class Effects { ) ); + delBuddy$ = createEffect(() => + this.actions$.pipe( + ofType(delBuddy), + withLatestFrom( + this.store.pipe( + select((state: any) => state.messenger.sync.buddy2.syncDate as string) + ) + ), + exhaustMap(([req, syncDate]) => + this.buddyProtocolService.del(req).pipe( + map((res: BuddyDelResponse) => { + return delBuddySuccess(res); + }), + // map((res: BuddyDelResponse) => { + // return buddy2({ + // syncDate + // }); + // }), + catchError(error => of(delBuddyFailure({ error }))) + ) + ) + ) + ); + updateGroup$ = createEffect(() => this.actions$.pipe( ofType(updateGroup), diff --git a/projects/ucap-webmessenger-app/src/app/store/messenger/sync/reducers.ts b/projects/ucap-webmessenger-app/src/app/store/messenger/sync/reducers.ts index 4d21705f..d5704cc5 100644 --- a/projects/ucap-webmessenger-app/src/app/store/messenger/sync/reducers.ts +++ b/projects/ucap-webmessenger-app/src/app/store/messenger/sync/reducers.ts @@ -15,7 +15,8 @@ import { refreshRoomSuccess, updateUnreadCount, createGroupSuccess, - addBuddySuccess + addBuddySuccess, + delBuddySuccess } from './actions'; import { RoomUserDetailData, @@ -202,5 +203,14 @@ export const reducer = createReducer( ...state.group2 }) }; + }), + + on(delBuddySuccess, (state, action) => { + return { + ...state, + buddy2: adapterBuddy2.removeMany(action.userSeqs, { + ...state.buddy2 + }) + }; }) ); diff --git a/projects/ucap-webmessenger-app/src/app/types/userselect.dialog.type.ts b/projects/ucap-webmessenger-app/src/app/types/userselect.dialog.type.ts index 9779d5d5..a078b50b 100644 --- a/projects/ucap-webmessenger-app/src/app/types/userselect.dialog.type.ts +++ b/projects/ucap-webmessenger-app/src/app/types/userselect.dialog.type.ts @@ -6,5 +6,5 @@ export enum UserSelectDialogType { /** 대화 전달 */ MessageForward = 'MESSAGE_FORWARD', /** 그룹멤버 변경 */ - GroupMemberUpdate = 'GROUP_MEMBER_UPDATE' + EditMember = 'EDIT_MEMBER' }