This commit is contained in:
병준 박 2019-12-27 15:34:14 +09:00
commit 18b534d3e4
10 changed files with 501 additions and 215 deletions

View File

@ -91,8 +91,8 @@
<!--<mat-icon>device_hub</mat-icon>--> <!--<mat-icon>device_hub</mat-icon>-->
<div <div
class="icon-item" class="icon-item"
[matBadgeHidden]="badgeMessageUnReadCount <= 0" [matBadgeHidden]="(badgeMessageUnReadCount$ | async) <= 0"
[matBadge]="badgeMessageUnReadCount" [matBadge]="badgeMessageUnReadCount$ | async"
matBadgeDescription="확인하지 않은 메시지가 있습니다." matBadgeDescription="확인하지 않은 메시지가 있습니다."
matBadgeColor="accent" matBadgeColor="accent"
matBadgePosition="above after" matBadgePosition="above after"

View File

@ -17,11 +17,12 @@ import {
CreateChatDialogData, CreateChatDialogData,
CreateChatDialogResult CreateChatDialogResult
} from '@app/layouts/messenger/dialogs/chat/create-chat.dialog.component'; } from '@app/layouts/messenger/dialogs/chat/create-chat.dialog.component';
import { Subscription, of } from 'rxjs'; import { Subscription, of, Observable } from 'rxjs';
import { Store, select } from '@ngrx/store'; import { Store, select } from '@ngrx/store';
import * as AppStore from '@app/store'; import * as AppStore from '@app/store';
import * as ChatStore from '@app/store/messenger/chat'; import * as ChatStore from '@app/store/messenger/chat';
import * as MessageStore from '@app/store/messenger/message';
import * as SyncStore from '@app/store/messenger/sync'; import * as SyncStore from '@app/store/messenger/sync';
import { UserInfo } from '@ucap-webmessenger/protocol-sync'; import { UserInfo } from '@ucap-webmessenger/protocol-sync';
import { import {
@ -36,9 +37,7 @@ import { SessionStorageService } from '@ucap-webmessenger/web-storage';
import { VersionInfo2Response } from '@ucap-webmessenger/api-public'; import { VersionInfo2Response } from '@ucap-webmessenger/api-public';
import { MessageApiService, MessageType } from '@ucap-webmessenger/api-message'; import { MessageApiService, MessageType } from '@ucap-webmessenger/api-message';
import { DeviceType } from '@ucap-webmessenger/core'; import { DeviceType } from '@ucap-webmessenger/core';
import { UnreadCountRequest } from 'projects/ucap-webmessenger-api-message/src/lib/apis/unread-count';
import { map, catchError, tap } from 'rxjs/operators'; import { map, catchError, tap } from 'rxjs/operators';
import { MessageStatusCode } from '@ucap-webmessenger/api';
import { import {
MessageWriteDialogComponent, MessageWriteDialogComponent,
MessageWriteDialogResult, MessageWriteDialogResult,
@ -87,8 +86,7 @@ export class LeftSideComponent implements OnInit, OnDestroy {
badgeChatUnReadCount: number; badgeChatUnReadCount: number;
badgeChatUnReadCountSubscription: Subscription; badgeChatUnReadCountSubscription: Subscription;
badgeMessageUnReadCount: number; badgeMessageUnReadCount$: Observable<number>;
badgeMessageUnReadCountSubscription: Subscription;
badgeMessageInterval: any; badgeMessageInterval: any;
/** 조직도에서 부서원 선택 */ /** 조직도에서 부서원 선택 */
@ -109,7 +107,6 @@ export class LeftSideComponent implements OnInit, OnDestroy {
private store: Store<any>, private store: Store<any>,
private dialogService: DialogService, private dialogService: DialogService,
private sessionStorageService: SessionStorageService, private sessionStorageService: SessionStorageService,
private messageApiService: MessageApiService,
private logger: NGXLogger private logger: NGXLogger
) { ) {
this.sessionVerinfo = this.sessionStorageService.get<VersionInfo2Response>( this.sessionVerinfo = this.sessionStorageService.get<VersionInfo2Response>(
@ -139,6 +136,11 @@ export class LeftSideComponent implements OnInit, OnDestroy {
) )
.subscribe(); .subscribe();
/** About Message Badge */
this.badgeMessageUnReadCount$ = this.store.pipe(
select(AppStore.MessengerSelector.MessageSelector.unReadMessageCount)
);
this.getMessageUnreadCount(); this.getMessageUnreadCount();
this.badgeMessageInterval = setInterval( this.badgeMessageInterval = setInterval(
() => this.getMessageUnreadCount(), () => this.getMessageUnreadCount(),
@ -153,9 +155,6 @@ export class LeftSideComponent implements OnInit, OnDestroy {
if (!!this.badgeChatUnReadCountSubscription) { if (!!this.badgeChatUnReadCountSubscription) {
this.badgeChatUnReadCountSubscription.unsubscribe(); this.badgeChatUnReadCountSubscription.unsubscribe();
} }
if (!!this.badgeMessageUnReadCountSubscription) {
this.badgeMessageUnReadCountSubscription.unsubscribe();
}
if (!!this.loginResSubscription) { if (!!this.loginResSubscription) {
this.loginResSubscription.unsubscribe(); this.loginResSubscription.unsubscribe();
} }
@ -444,22 +443,7 @@ export class LeftSideComponent implements OnInit, OnDestroy {
} }
getMessageUnreadCount(): void { getMessageUnreadCount(): void {
this.badgeMessageUnReadCountSubscription = this.messageApiService this.store.dispatch(MessageStore.retrieveUnreadCount({}));
.retrieveUnreadCount({
userSeq: this.loginRes.userSeq,
deviceType: DeviceType.PC,
tokenKey: this.loginRes.tokenString
} as UnreadCountRequest)
.pipe(
map(res => {
if (res.responseCode === MessageStatusCode.Success) {
this.badgeMessageUnReadCount = res.unreadCount;
} else {
}
}),
catchError(error => of(this.logger.error(error)))
)
.subscribe();
} }
getMyProfileImageWidget(): string { getMyProfileImageWidget(): string {

View File

@ -8,9 +8,9 @@ import {
Input, Input,
AfterViewChecked AfterViewChecked
} from '@angular/core'; } from '@angular/core';
import { of, Observable } from 'rxjs'; import { Observable, Subscription } from 'rxjs';
import { Store, select } from '@ngrx/store'; import { Store, select } from '@ngrx/store';
import { map, catchError, take } from 'rxjs/operators'; import { tap } from 'rxjs/operators';
import { NGXLogger } from 'ngx-logger'; import { NGXLogger } from 'ngx-logger';
import { VersionInfo2Response } from '@ucap-webmessenger/api-public'; import { VersionInfo2Response } from '@ucap-webmessenger/api-public';
@ -23,12 +23,8 @@ import {
MessageType, MessageType,
MessageList, MessageList,
MessageSearchType, MessageSearchType,
DetailRequest, MessageDetailInfo
MessageDetailInfo,
DelRequest,
CancelReservationRequest
} from '@ucap-webmessenger/api-message'; } from '@ucap-webmessenger/api-message';
import { DeviceType } from '@ucap-webmessenger/core';
import { MessageStatusCode } from '@ucap-webmessenger/api'; import { MessageStatusCode } from '@ucap-webmessenger/api';
import { ContentType } from '@ucap-webmessenger/api-message'; import { ContentType } from '@ucap-webmessenger/api-message';
import { FormGroup, FormBuilder } from '@angular/forms'; import { FormGroup, FormBuilder } from '@angular/forms';
@ -79,6 +75,8 @@ export class MessageBoxComponent
messageReservationList$: Observable<MessageList[]>; messageReservationList$: Observable<MessageList[]>;
messageSearchList$: Observable<MessageList[]>; messageSearchList$: Observable<MessageList[]>;
messageDetailInfo: Subscription;
currentTabIndex = 0; currentTabIndex = 0;
defaultPageSize = 1000; // default defaultPageSize = 1000; // default
@ -119,9 +117,12 @@ export class MessageBoxComponent
searchMessageSearchType: [MessageSearchType.Name] searchMessageSearchType: [MessageSearchType.Name]
}); });
this.messageRetrieveList$ = this.store.pipe( this.messageRetrieveList$ = this.store
.pipe(
select(AppStore.MessengerSelector.MessageSelector.selectAllReceiveList) select(AppStore.MessengerSelector.MessageSelector.selectAllReceiveList)
); )
.pipe(tap(info => console.log(info)));
this.messageSendList$ = this.store.pipe( this.messageSendList$ = this.store.pipe(
select(AppStore.MessengerSelector.MessageSelector.selectAllSendList) select(AppStore.MessengerSelector.MessageSelector.selectAllSendList)
); );
@ -134,6 +135,53 @@ export class MessageBoxComponent
select(AppStore.MessengerSelector.MessageSelector.selectAllSearchList) select(AppStore.MessengerSelector.MessageSelector.selectAllSearchList)
); );
this.messageDetailInfo = this.store
.pipe(
select(AppStore.MessengerSelector.MessageSelector.detailMessageInfo)
)
.subscribe(async info => {
if (!!info && info.responseCode === MessageStatusCode.Success) {
// Badge Refresh in case Receive Message..
if (info.msgInfo.type === MessageType.Receive) {
this.doRefreshUnReadCount.emit();
}
// detail view..
const result = await this.dialogService.open<
MessageDetailDialogComponent,
MessageDetailDialogData,
MessageDetailDialogResult
>(MessageDetailDialogComponent, {
width: '600px',
data: {
detail: info,
loginRes: this.loginRes,
environmentsInfo: this.environmentsInfo
}
});
if (!!result) {
// Clear detail Info in state
this.store.dispatch(MessageStore.detailMessageClear({}));
switch (result.returnType) {
case 'DEL':
// 단건 삭제.
this.doMessageDelete([result.messageInfo]);
break;
case 'CANCEL_RESERVATION':
// 단건 발송취소(예약)
this.doMessageCancelReservation(result.messageInfo);
break;
case 'UPDATE':
// 예약 수정
this.getRetrieveMessage(MessageType.Reservation, 0);
break;
}
}
}
});
// 초기 검색은 수신함. // 초기 검색은 수신함.
this.getRetrieveMessage(MessageType.Receive, 0); this.getRetrieveMessage(MessageType.Receive, 0);
@ -149,7 +197,11 @@ export class MessageBoxComponent
} }
} }
ngOnDestroy(): void {} ngOnDestroy(): void {
if (!!this.messageDetailInfo) {
this.messageDetailInfo.unsubscribe();
}
}
onSelectedIndexTab(value: number) { onSelectedIndexTab(value: number) {
this.tabs.selectedIndex = value; this.tabs.selectedIndex = value;
@ -231,110 +283,34 @@ export class MessageBoxComponent
/** 쪽지 상세보기 */ /** 쪽지 상세보기 */
onClickDetail(message: MessageList) { onClickDetail(message: MessageList) {
this.messageApiService this.store.dispatch(
.detailMessage({ MessageStore.detailMessage({
userSeq: this.loginRes.userSeq, messageType: message.type,
deviceType: DeviceType.PC,
tokenKey: this.loginRes.tokenString,
type: message.type,
msgId: message.msgId msgId: message.msgId
} as DetailRequest) })
.pipe( );
take(1),
map(async res => {
if (res.responseCode === MessageStatusCode.Success) {
// Badge Refresh in case Receive Message..
if (res.msgInfo.type === MessageType.Receive) {
this.doRefreshUnReadCount.emit();
}
// detail view..
const result = await this.dialogService.open<
MessageDetailDialogComponent,
MessageDetailDialogData,
MessageDetailDialogResult
>(MessageDetailDialogComponent, {
width: '600px',
data: {
detail: res,
loginRes: this.loginRes,
environmentsInfo: this.environmentsInfo
}
});
if (!!result) {
switch (result.returnType) {
case 'DEL':
// 단건 삭제.
this.doMessageDelete([result.messageInfo]);
break;
case 'CANCEL_RESERVATION':
// 단건 발송취소(예약)
this.doMessageCancelReservation(result.messageInfo);
break;
case 'UPDATE':
// 예약 수정
this.getRetrieveMessage(MessageType.Reservation, 0);
break;
}
}
} else {
}
}),
catchError(error => of(this.logger.error(error)))
)
.subscribe();
} }
/** 쪽지(수신,발신) 삭제 */ /** 쪽지(수신,발신) 삭제 */
doMessageDelete(messageInfo: MessageDetailInfo[]): void { doMessageDelete(messageInfo: MessageDetailInfo[]): void {
const msgList: { msgId: number }[] = []; const msgList: { msgId: number }[] = [];
messageInfo.forEach(info => msgList.push({ msgId: info.msgId })); messageInfo.forEach(info => msgList.push({ msgId: info.msgId }));
this.messageApiService
.deleteMessage({ this.store.dispatch(
userSeq: this.loginRes.userSeq, MessageStore.deleteMessage({
deviceType: DeviceType.PC, messageType: messageInfo[0].type,
tokenKey: this.loginRes.tokenString,
type: messageInfo[0].type,
msgList msgList
} as DelRequest) })
.pipe( );
take(1),
map(async res => {
if (res.responseCode === MessageStatusCode.Success) {
} else {
this.logger.error('message delete Error!');
}
// 현재탭 재조회.
this.onSelectedIndexChange(this.currentTabIndex);
}),
catchError(error => of(this.logger.error(error)))
)
.subscribe();
} }
/** 쪽지(예약) 삭제 */ /** 쪽지(예약) 삭제 */
doMessageCancelReservation(messageInfo: MessageDetailInfo): void { doMessageCancelReservation(messageInfo: MessageDetailInfo): void {
this.messageApiService this.store.dispatch(
.cancelReservationMessage({ MessageStore.cancelReservationMessage({
userSeq: this.loginRes.userSeq, messageType: messageInfo.type,
deviceType: DeviceType.PC,
tokenKey: this.loginRes.tokenString,
type: messageInfo.type,
msgId: messageInfo.msgId msgId: messageInfo.msgId
} as CancelReservationRequest) })
.pipe( );
take(1),
map(async res => {
if (res.responseCode === MessageStatusCode.Success) {
} else {
this.logger.error('message(reservation) cancel Error!');
}
// 현재탭 재조회.
this.onSelectedIndexChange(this.currentTabIndex);
}),
catchError(error => of(this.logger.error(error)))
)
.subscribe();
} }
} }

View File

@ -122,9 +122,10 @@ export class MessageDetailDialogComponent implements OnInit {
// contents 내 이미지 Thumnail 파일 정보 수집. // contents 내 이미지 Thumnail 파일 정보 수집.
this.getThumbImage(); this.getThumbImage();
this.receivers = this.messageDetail.recvList.sort((a, b) => this.receivers = this.messageDetail.recvList;
a.userName < b.userName ? -1 : a.userName > b.userName ? 1 : 0 // this.receivers = this.messageDetail.recvList.sort((a, b) =>
); // a.userName < b.userName ? -1 : a.userName > b.userName ? 1 : 0
// );
} }
getSendReceiverNames(): string { getSendReceiverNames(): string {

View File

@ -13,6 +13,7 @@ import { Store, select } from '@ngrx/store';
import * as AppStore from '@app/store'; import * as AppStore from '@app/store';
import * as ChatStore from '@app/store/messenger/chat'; import * as ChatStore from '@app/store/messenger/chat';
import * as MessageStore from '@app/store/messenger/message';
import { Observable, Subscription, of } from 'rxjs'; import { Observable, Subscription, of } from 'rxjs';
import { UCAP_NATIVE_SERVICE, NativeService } from '@ucap-webmessenger/native'; import { UCAP_NATIVE_SERVICE, NativeService } from '@ucap-webmessenger/native';
@ -150,49 +151,20 @@ export class MainPageComponent implements OnInit, OnDestroy {
this.msgOpenMessageSubscription = this.nativeService this.msgOpenMessageSubscription = this.nativeService
.msgOpenMessage() .msgOpenMessage()
.subscribe(messageSeq => { .subscribe(messageSeq => {
console.log(messageSeq); // unreadCount refresh..
this.store.dispatch(MessageStore.retrieveUnreadCount({}));
this.ngZone.run(() => { this.ngZone.run(() => {
this.messageApiService /**
.detailMessage({ * .
userSeq: this.loginRes.userSeq, * state Message.component.ts .
deviceType: this.environmentsInfo.deviceType, */
tokenKey: this.loginRes.tokenString, this.store.dispatch(
type: MessageType.Receive, MessageStore.detailMessage({
messageType: MessageType.Receive,
msgId: Number(messageSeq) msgId: Number(messageSeq)
} as DetailRequest) })
.pipe( );
take(1),
map(async res => {
if (res.responseCode === MessageStatusCode.Success) {
// detail view..
const result = await this.dialogService.open<
MessageDetailDialogComponent,
MessageDetailDialogData,
MessageDetailDialogResult
>(MessageDetailDialogComponent, {
width: '600px',
data: {
detail: res,
loginRes: this.loginRes,
environmentsInfo: this.environmentsInfo
}
});
if (!!result) {
switch (result.returnType) {
case 'DEL':
// 단건 삭제.
this.doMessageDelete([result.messageInfo]);
break;
}
}
} else {
}
}),
catchError(error => of(this.logger.error(error)))
)
.subscribe();
}); });
}); });
@ -385,29 +357,4 @@ export class MainPageComponent implements OnInit, OnDestroy {
onCloseRightDrawer() { onCloseRightDrawer() {
this.rightDrawer.close(); this.rightDrawer.close();
} }
/** 쪽지(수신,발신) 삭제 */
doMessageDelete(messageInfo: MessageDetailInfo[]): void {
const msgList: { msgId: number }[] = [];
messageInfo.forEach(info => msgList.push({ msgId: info.msgId }));
this.messageApiService
.deleteMessage({
userSeq: this.loginRes.userSeq,
deviceType: DeviceType.PC,
tokenKey: this.loginRes.tokenString,
type: messageInfo[0].type,
msgList
} as DelRequest)
.pipe(
take(1),
map(async res => {
if (res.responseCode === MessageStatusCode.Success) {
} else {
this.logger.error('message delete Error!');
}
}),
catchError(error => of(this.logger.error(error)))
)
.subscribe();
}
} }

View File

@ -81,6 +81,7 @@ import {
import * as AuthenticationStore from '@app/store/account/authentication'; import * as AuthenticationStore from '@app/store/account/authentication';
import * as InfoStore from '@app/store/account/info'; import * as InfoStore from '@app/store/account/info';
import * as EventStore from '@app/store/messenger/event'; import * as EventStore from '@app/store/messenger/event';
import * as MessageStore from '@app/store/messenger/message';
import * as SyncStore from '@app/store/messenger/sync'; import * as SyncStore from '@app/store/messenger/sync';
import * as RoomStore from '@app/store/messenger/room'; import * as RoomStore from '@app/store/messenger/room';
import * as StatusStore from '@app/store/messenger/status'; import * as StatusStore from '@app/store/messenger/status';
@ -102,6 +103,7 @@ import { AppUserInfo, KEY_APP_USER_INFO } from '@app/types/app-user-info.type';
import { environment } from '../../environments/environment'; import { environment } from '../../environments/environment';
import { NotificationMethod } from '@ucap-webmessenger/core'; import { NotificationMethod } from '@ucap-webmessenger/core';
import { Dictionary } from '@ngrx/entity'; import { Dictionary } from '@ngrx/entity';
import { MessageType } from '@ucap-webmessenger/api-message';
@Injectable() @Injectable()
export class AppNotificationService { export class AppNotificationService {
@ -559,7 +561,17 @@ export class AppNotificationService {
'Notification::umgProtocolService::UmgNotiNotification', 'Notification::umgProtocolService::UmgNotiNotification',
noti noti
); );
console.log(noti);
// unreadCount refresh..
this.store.dispatch(MessageStore.retrieveUnreadCount({}));
// Receive Message List refresh..
this.store.dispatch(
MessageStore.retrieveMessage({
messageType: MessageType.Receive
})
);
// notification.. // notification..
const appUserInfo = this.localStorageService.encGet< const appUserInfo = this.localStorageService.encGet<
AppUserInfo AppUserInfo

View File

@ -2,9 +2,48 @@ import { createAction, props } from '@ngrx/store';
import { import {
MessageType, MessageType,
RetrieveResponse, RetrieveResponse,
MessageSearchType MessageSearchType,
DelRequest,
DelResponse,
DetailResponse
} from '@ucap-webmessenger/api-message'; } from '@ucap-webmessenger/api-message';
export const detailMessage = createAction(
'[Messenger::Message] Detail Message',
props<{
messageType: MessageType;
msgId: number;
}>()
);
export const detailMessageSuccess = createAction(
'[Messenger::Message] Detail Message Success',
props<{
res: DetailResponse;
}>()
);
export const detailMessageFailure = createAction(
'[Messenger::Message] Detail Message Failure',
props<{ error: any }>()
);
export const detailMessageClear = createAction(
'[Messenger::Message] Detail Message',
props()
);
export const retrieveUnreadCount = createAction(
'[Messenger::Message] RetrieveMessage UnreadCount',
props()
);
export const retrieveUnreadCountSuccess = createAction(
'[Messenger::Message] RetrieveMessage UnreadCount Success',
props<{ count: number }>()
);
export const retrieveUnreadCountFailure = createAction(
'[Messenger::Message] RetrieveMessage UnreadCount Failure',
props<{ error: any }>()
);
export const retrieveMessage = createAction( export const retrieveMessage = createAction(
'[Messenger::Message] RetrieveMessage', '[Messenger::Message] RetrieveMessage',
props<{ props<{
@ -40,3 +79,41 @@ export const searchMessageFailure = createAction(
'[Messenger::Message] searchMessage Failure', '[Messenger::Message] searchMessage Failure',
props<{ error: any }>() props<{ error: any }>()
); );
export const deleteMessage = createAction(
'[Messenger::Message] Delete Message',
props<{
messageType: MessageType;
msgList: { msgId: number }[];
}>()
);
export const deleteMessageSuccess = createAction(
'[Messenger::Message] Delete Message Success',
props<{
messageType: MessageType;
msgList: { msgId: number }[];
}>()
);
export const deleteMessageFailure = createAction(
'[Messenger::Message] Delete Message Failure',
props<{ error: any }>()
);
export const cancelReservationMessage = createAction(
'[Messenger::Message] Cancel Reservation Message',
props<{
messageType: MessageType;
msgId: number;
}>()
);
export const cancelReservationMessageSuccess = createAction(
'[Messenger::Message] Cancel Reservation Message Success',
props<{
messageType: MessageType;
msgId: number;
}>()
);
export const cancelReservationMessageFailure = createAction(
'[Messenger::Message] Cancel Reservation Message Failure',
props<{ error: any }>()
);

View File

@ -27,10 +27,9 @@ import { SessionStorageService } from '@ucap-webmessenger/web-storage';
import { KEY_ENVIRONMENTS_INFO } from './../../../types/environment.type'; import { KEY_ENVIRONMENTS_INFO } from './../../../types/environment.type';
import { LoginInfo, KEY_LOGIN_INFO, EnvironmentsInfo } from '@app/types'; import { LoginInfo, KEY_LOGIN_INFO, EnvironmentsInfo } from '@app/types';
import { Dictionary } from '@ngrx/entity'; import { Dictionary } from '@ngrx/entity';
import { openSuccess, openFailure } from '../room';
import { LoginResponse } from '@ucap-webmessenger/protocol-authentication'; import { LoginResponse } from '@ucap-webmessenger/protocol-authentication';
import { KEY_LOGIN_RES_INFO } from '@app/types/login-res-info.type'; import { KEY_LOGIN_RES_INFO } from '@app/types/login-res-info.type';
import { StatusCode, MessageStatusCode } from '@ucap-webmessenger/api'; import { MessageStatusCode } from '@ucap-webmessenger/api';
import { environment } from '../../../../environments/environment'; import { environment } from '../../../../environments/environment';
import { import {
AlertDialogComponent, AlertDialogComponent,
@ -44,18 +43,124 @@ import {
retrieveMessageSuccess, retrieveMessageSuccess,
searchMessage, searchMessage,
searchMessageSuccess, searchMessageSuccess,
searchMessageFailure searchMessageFailure,
retrieveUnreadCount,
retrieveUnreadCountSuccess,
retrieveUnreadCountFailure,
deleteMessage,
deleteMessageSuccess,
deleteMessageFailure,
cancelReservationMessage,
cancelReservationMessageSuccess,
cancelReservationMessageFailure,
detailMessage,
detailMessageFailure,
detailMessageSuccess
} from './actions'; } from './actions';
import { import {
MessageApiService, MessageApiService,
RetrieveRequest, RetrieveRequest,
MessageType, MessageType,
RetrieveSearchRequest, RetrieveSearchRequest,
MessageSearchType MessageSearchType,
DelRequest,
CancelReservationRequest,
DetailRequest
} from '@ucap-webmessenger/api-message'; } from '@ucap-webmessenger/api-message';
import { UnreadCountRequest } from 'projects/ucap-webmessenger-api-message/src/lib/apis/unread-count';
import {
MessageDetailDialogComponent,
MessageDetailDialogResult,
MessageDetailDialogData
} from '@app/layouts/messenger/dialogs/message/message-detail.dialog.component';
@Injectable() @Injectable()
export class Effects { export class Effects {
detailMessage$ = createEffect(
() => {
return this.actions$.pipe(
ofType(detailMessage),
withLatestFrom(
this.store.pipe(
select(
(state: any) =>
state.account.authentication.loginRes as LoginResponse
)
)
),
switchMap(([req, loginResInfo]) => {
const environmentsInfo = this.sessionStorageService.get<
EnvironmentsInfo
>(KEY_ENVIRONMENTS_INFO);
const request: DetailRequest = {
userSeq: loginResInfo.userSeq,
deviceType: environmentsInfo.deviceType,
tokenKey: loginResInfo.tokenString,
type: req.messageType,
msgId: req.msgId
};
return this.messageApiService.detailMessage(request).pipe(
map(res => {
if (res.responseCode === MessageStatusCode.Success) {
this.store.dispatch(
detailMessageSuccess({
res
})
);
}
}),
catchError(error => of(detailMessageFailure({ error })))
);
})
);
},
{ dispatch: false }
);
retrieveUnreadCount$ = createEffect(
() => {
return this.actions$.pipe(
ofType(retrieveUnreadCount),
withLatestFrom(
this.store.pipe(
select(
(state: any) =>
state.account.authentication.loginRes as LoginResponse
)
)
),
switchMap(([req, loginResInfo]) => {
// const loginResInfo: LoginResponse = this.sessionStorageService.get<
// LoginResponse
// >(KEY_LOGIN_RES_INFO);
const environmentsInfo = this.sessionStorageService.get<
EnvironmentsInfo
>(KEY_ENVIRONMENTS_INFO);
const request: UnreadCountRequest = {
userSeq: loginResInfo.userSeq,
deviceType: environmentsInfo.deviceType,
tokenKey: loginResInfo.tokenString
};
return this.messageApiService.retrieveUnreadCount(request).pipe(
map(res => {
if (res.responseCode === MessageStatusCode.Success) {
this.store.dispatch(
retrieveUnreadCountSuccess({
count: res.unreadCount
})
);
}
}),
catchError(error => of(retrieveUnreadCountFailure({ error })))
);
})
);
},
{ dispatch: false }
);
retrieveMessage$ = createEffect( retrieveMessage$ = createEffect(
() => { () => {
return this.actions$.pipe( return this.actions$.pipe(
@ -69,9 +174,6 @@ export class Effects {
) )
), ),
switchMap(([req, loginResInfo]) => { switchMap(([req, loginResInfo]) => {
// const loginResInfo: LoginResponse = this.sessionStorageService.get<
// LoginResponse
// >(KEY_LOGIN_RES_INFO);
const environmentsInfo = this.sessionStorageService.get< const environmentsInfo = this.sessionStorageService.get<
EnvironmentsInfo EnvironmentsInfo
>(KEY_ENVIRONMENTS_INFO); >(KEY_ENVIRONMENTS_INFO);
@ -144,10 +246,6 @@ export class Effects {
searchMessage$ = createEffect( searchMessage$ = createEffect(
() => { () => {
const environmentsInfo = this.sessionStorageService.get<EnvironmentsInfo>(
KEY_ENVIRONMENTS_INFO
);
return this.actions$.pipe( return this.actions$.pipe(
ofType(searchMessage), ofType(searchMessage),
withLatestFrom( withLatestFrom(
@ -159,6 +257,10 @@ export class Effects {
) )
), ),
switchMap(([req, loginResInfo]) => { switchMap(([req, loginResInfo]) => {
const environmentsInfo = this.sessionStorageService.get<
EnvironmentsInfo
>(KEY_ENVIRONMENTS_INFO);
const request: RetrieveRequest = { const request: RetrieveRequest = {
userSeq: loginResInfo.userSeq, userSeq: loginResInfo.userSeq,
deviceType: environmentsInfo.deviceType, deviceType: environmentsInfo.deviceType,
@ -199,6 +301,94 @@ export class Effects {
{ dispatch: false } { dispatch: false }
); );
deleteMessage$ = createEffect(
() => {
return this.actions$.pipe(
ofType(deleteMessage),
withLatestFrom(
this.store.pipe(
select(
(state: any) =>
state.account.authentication.loginRes as LoginResponse
)
)
),
switchMap(([action, loginResInfo]) => {
const environmentsInfo = this.sessionStorageService.get<
EnvironmentsInfo
>(KEY_ENVIRONMENTS_INFO);
const request: DelRequest = {
userSeq: loginResInfo.userSeq,
deviceType: environmentsInfo.deviceType,
tokenKey: loginResInfo.tokenString,
type: action.messageType,
msgList: action.msgList
};
return this.messageApiService.deleteMessage(request).pipe(
map(res => {
if (res.responseCode === MessageStatusCode.Success) {
this.store.dispatch(
deleteMessageSuccess({
messageType: action.messageType,
msgList: action.msgList
})
);
}
}),
catchError(error => of(deleteMessageFailure({ error })))
);
})
);
},
{ dispatch: false }
);
cancelReservationMessage$ = createEffect(
() => {
return this.actions$.pipe(
ofType(cancelReservationMessage),
withLatestFrom(
this.store.pipe(
select(
(state: any) =>
state.account.authentication.loginRes as LoginResponse
)
)
),
switchMap(([action, loginResInfo]) => {
const environmentsInfo = this.sessionStorageService.get<
EnvironmentsInfo
>(KEY_ENVIRONMENTS_INFO);
const request: CancelReservationRequest = {
userSeq: loginResInfo.userSeq,
deviceType: environmentsInfo.deviceType,
tokenKey: loginResInfo.tokenString,
type: action.messageType,
msgId: action.msgId
};
return this.messageApiService.cancelReservationMessage(request).pipe(
map(res => {
if (res.responseCode === MessageStatusCode.Success) {
this.store.dispatch(
cancelReservationMessageSuccess({
messageType: action.messageType,
msgId: action.msgId
})
);
}
}),
catchError(error => of(cancelReservationMessageFailure({ error })))
);
})
);
},
{ dispatch: false }
);
constructor( constructor(
private actions$: Actions, private actions$: Actions,
private store: Store<any>, private store: Store<any>,

View File

@ -11,13 +11,26 @@ import {
retrieveMessageSuccess, retrieveMessageSuccess,
retrieveMessage, retrieveMessage,
searchMessage, searchMessage,
searchMessageSuccess searchMessageSuccess,
retrieveUnreadCountSuccess,
deleteMessageSuccess,
cancelReservationMessageSuccess,
detailMessageSuccess,
detailMessageClear,
detailMessage
} from './actions'; } from './actions';
import { MessageType } from '@ucap-webmessenger/api-message'; import { MessageType } from '@ucap-webmessenger/api-message';
export const reducer = createReducer( export const reducer = createReducer(
initialState, initialState,
on(retrieveUnreadCountSuccess, (state, action) => {
return {
...state,
unReadMessageCount: action.count
};
}),
on(retrieveMessage, (state, action) => { on(retrieveMessage, (state, action) => {
switch (action.messageType) { switch (action.messageType) {
case MessageType.Receive: { case MessageType.Receive: {
@ -92,6 +105,74 @@ export const reducer = createReducer(
}; };
}), }),
on(deleteMessageSuccess, (state, action) => {
if (action.messageType === MessageType.Receive) {
return {
...state,
receiveList: adapterReceiveList.removeMany(
action.msgList.map(item => item.msgId),
{
...state.receiveList
}
),
searchList: adapterSearchList.removeMany(
action.msgList.map(item => item.msgId),
{
...state.searchList
}
)
};
} else if (action.messageType === MessageType.Send) {
return {
...state,
sendList: adapterSendList.removeMany(
action.msgList.map(item => item.msgId),
{
...state.sendList
}
),
searchList: adapterSearchList.removeMany(
action.msgList.map(item => item.msgId),
{
...state.searchList
}
)
};
}
}),
on(cancelReservationMessageSuccess, (state, action) => {
return {
...state,
reservationList: adapterReservationList.removeOne(action.msgId, {
...state.reservationList
}),
searchList: adapterSearchList.removeOne(action.msgId, {
...state.searchList
})
};
}),
on(detailMessageSuccess, (state, action) => {
return {
...state,
detailMessageInfo: action.res
};
}),
on(detailMessage, (state, action) => {
return {
...state,
detailMessageInfo: null
};
}),
on(detailMessageClear, (state, action) => {
return {
...state,
detailMessageInfo: null
};
}),
on(AuthenticationStore.logoutInitialize, (state, action) => { on(AuthenticationStore.logoutInitialize, (state, action) => {
return { return {
...initialState ...initialState

View File

@ -1,7 +1,7 @@
import { Selector, createSelector } from '@ngrx/store'; import { Selector, createSelector } from '@ngrx/store';
import { EntityState, createEntityAdapter } from '@ngrx/entity'; import { EntityState, createEntityAdapter } from '@ngrx/entity';
import { MessageList } from '@ucap-webmessenger/api-message'; import { MessageList, DetailResponse } from '@ucap-webmessenger/api-message';
import { import {
InfoResponse, InfoResponse,
@ -20,6 +20,7 @@ export interface FileInfoListState extends EntityState<FileInfo> {}
export interface FileInfoCheckListState extends EntityState<FileDownloadInfo> {} export interface FileInfoCheckListState extends EntityState<FileDownloadInfo> {}
export interface State { export interface State {
// list [S]
receiveListProcessing: boolean; receiveListProcessing: boolean;
receiveList: ReceiveListState; receiveList: ReceiveListState;
receiveTotalCount: number; receiveTotalCount: number;
@ -39,6 +40,10 @@ export interface State {
searchList: SearchListState; searchList: SearchListState;
searchTotalCount: number; searchTotalCount: number;
searchPage: number; searchPage: number;
// list [E]
unReadMessageCount: number;
detailMessageInfo: DetailResponse | null;
} }
export const adapterReceiveList = createEntityAdapter<MessageList>({ export const adapterReceiveList = createEntityAdapter<MessageList>({
@ -96,7 +101,10 @@ export const initialState: State = {
searchListProcessing: false, searchListProcessing: false,
searchList: searchListInitialState, searchList: searchListInitialState,
searchTotalCount: 0, searchTotalCount: 0,
searchPage: 0 searchPage: 0,
unReadMessageCount: 0,
detailMessageInfo: null
}; };
const { const {
@ -143,6 +151,11 @@ export function selectors<S>(selector: Selector<any, State>) {
); );
return { return {
unReadMessageCount: createSelector(
selector,
(state: State) => state.unReadMessageCount
),
receiveListProcessing: createSelector( receiveListProcessing: createSelector(
selector, selector,
(state: State) => state.receiveListProcessing (state: State) => state.receiveListProcessing
@ -213,6 +226,11 @@ export function selectors<S>(selector: Selector<any, State>) {
selectSearchList, selectSearchList,
ngeSelectEntitiesSearchList, ngeSelectEntitiesSearchList,
(_, entities) => (!!entities ? entities[seq] : undefined) (_, entities) => (!!entities ? entities[seq] : undefined)
),
detailMessageInfo: createSelector(
selector,
(state: State) => state.detailMessageInfo
) )
}; };
} }