Merge branch 'master' of https://git.loafle.net/ucap-web/next-ucap-messenger
This commit is contained in:
commit
a7fb5b2c4b
|
@ -51,7 +51,7 @@
|
|||
</ng-template>
|
||||
|
||||
<ucap-message-list-item
|
||||
*ngFor="let message of messageList"
|
||||
*ngFor="let message of messageRetrieveList$ | async"
|
||||
[message]="message"
|
||||
(click)="onClickDetail(message)"
|
||||
class="message-item"
|
||||
|
@ -63,7 +63,7 @@
|
|||
</ng-template>
|
||||
|
||||
<ucap-message-list-item
|
||||
*ngFor="let message of messageList"
|
||||
*ngFor="let message of messageSendList$ | async"
|
||||
[message]="message"
|
||||
(click)="onClickDetail(message)"
|
||||
class="message-item"
|
||||
|
@ -75,7 +75,7 @@
|
|||
</ng-template>
|
||||
|
||||
<ucap-message-list-item
|
||||
*ngFor="let message of messageList"
|
||||
*ngFor="let message of messageReservationList$ | async"
|
||||
[message]="message"
|
||||
(click)="onClickDetail(message)"
|
||||
class="message-item"
|
||||
|
@ -116,7 +116,7 @@
|
|||
</div>
|
||||
<div>
|
||||
<ucap-message-list-item
|
||||
*ngFor="let message of messageList"
|
||||
*ngFor="let message of messageSearchList$ | async"
|
||||
[message]="message"
|
||||
(click)="onClickDetail(message)"
|
||||
class="message-item"
|
||||
|
|
|
@ -8,8 +8,8 @@ import {
|
|||
Input,
|
||||
AfterViewChecked
|
||||
} from '@angular/core';
|
||||
import { Subscription, of } from 'rxjs';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { of, Observable } from 'rxjs';
|
||||
import { Store, select } from '@ngrx/store';
|
||||
import { map, catchError, take } from 'rxjs/operators';
|
||||
import { NGXLogger } from 'ngx-logger';
|
||||
|
||||
|
@ -21,9 +21,7 @@ import { KEY_LOGIN_RES_INFO } from '@app/types/login-res-info.type';
|
|||
import {
|
||||
MessageApiService,
|
||||
MessageType,
|
||||
RetrieveRequest,
|
||||
MessageList,
|
||||
RetrieveSearchRequest,
|
||||
MessageSearchType,
|
||||
DetailRequest,
|
||||
MessageDetailInfo,
|
||||
|
@ -50,6 +48,9 @@ import {
|
|||
KEY_VER_INFO
|
||||
} from '@app/types';
|
||||
|
||||
import * as AppStore from '@app/store';
|
||||
import * as MessageStore from '@app/store/messenger/message';
|
||||
|
||||
@Component({
|
||||
selector: 'app-layout-chat-left-sidenav-message',
|
||||
templateUrl: './message.component.html',
|
||||
|
@ -73,19 +74,13 @@ export class MessageBoxComponent
|
|||
sessionVerinfo: VersionInfo2Response;
|
||||
environmentsInfo: EnvironmentsInfo;
|
||||
|
||||
messageList: MessageList[] = [];
|
||||
|
||||
messageRecieveListSubscription: Subscription;
|
||||
messageSendListSubscription: Subscription;
|
||||
messageReservationListSubscription: Subscription;
|
||||
messageSearchListSubscription: Subscription;
|
||||
messageRetrieveList$: Observable<MessageList[]>;
|
||||
messageSendList$: Observable<MessageList[]>;
|
||||
messageReservationList$: Observable<MessageList[]>;
|
||||
messageSearchList$: Observable<MessageList[]>;
|
||||
|
||||
currentTabIndex = 0;
|
||||
defaultPageSize = 1000; // default
|
||||
recieveCurrentPage = 0; // start index is 0.
|
||||
sendCurrentPage = 0; // start index is 0.
|
||||
reservationCurrentPage = 0; // start index is 0.
|
||||
searchCurrentPage = 0; // start index is 0.
|
||||
|
||||
currentTotalCount = 0;
|
||||
currentPage = 0;
|
||||
|
@ -124,8 +119,23 @@ export class MessageBoxComponent
|
|||
searchMessageSearchType: [MessageSearchType.Name]
|
||||
});
|
||||
|
||||
this.messageRetrieveList$ = this.store.pipe(
|
||||
select(AppStore.MessengerSelector.MessageSelector.selectAllReceiveList)
|
||||
);
|
||||
this.messageSendList$ = this.store.pipe(
|
||||
select(AppStore.MessengerSelector.MessageSelector.selectAllSendList)
|
||||
);
|
||||
this.messageReservationList$ = this.store.pipe(
|
||||
select(
|
||||
AppStore.MessengerSelector.MessageSelector.selectAllReservationList
|
||||
)
|
||||
);
|
||||
this.messageSearchList$ = this.store.pipe(
|
||||
select(AppStore.MessengerSelector.MessageSelector.selectAllSearchList)
|
||||
);
|
||||
|
||||
// 초기 검색은 수신함.
|
||||
this.getRetrieveMessage(MessageType.Receive, this.recieveCurrentPage);
|
||||
this.getRetrieveMessage(MessageType.Receive, 0);
|
||||
|
||||
if (!!this.tabs) {
|
||||
this.tabs.realignInkBar();
|
||||
|
@ -139,51 +149,34 @@ export class MessageBoxComponent
|
|||
}
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
if (!!this.messageRecieveListSubscription) {
|
||||
this.messageRecieveListSubscription.unsubscribe();
|
||||
}
|
||||
if (!!this.messageSendListSubscription) {
|
||||
this.messageSendListSubscription.unsubscribe();
|
||||
}
|
||||
if (!!this.messageReservationListSubscription) {
|
||||
this.messageReservationListSubscription.unsubscribe();
|
||||
}
|
||||
if (!!this.messageSearchListSubscription) {
|
||||
this.messageSearchListSubscription.unsubscribe();
|
||||
}
|
||||
}
|
||||
ngOnDestroy(): void {}
|
||||
|
||||
onSelectedIndexTab(value: number) {
|
||||
this.tabs.selectedIndex = value;
|
||||
}
|
||||
onSelectedIndexChange(value: number) {
|
||||
this.currentTabIndex = value;
|
||||
let type: MessageType;
|
||||
let messageType: MessageType;
|
||||
switch (value) {
|
||||
case 0:
|
||||
// Recieve
|
||||
type = MessageType.Receive;
|
||||
this.recieveCurrentPage = 0;
|
||||
messageType = MessageType.Receive;
|
||||
break;
|
||||
case 1:
|
||||
// Send
|
||||
type = MessageType.Send;
|
||||
this.sendCurrentPage = 0;
|
||||
messageType = MessageType.Send;
|
||||
break;
|
||||
case 2:
|
||||
// Reservation
|
||||
type = MessageType.Reservation;
|
||||
this.reservationCurrentPage = 0;
|
||||
messageType = MessageType.Reservation;
|
||||
break;
|
||||
}
|
||||
|
||||
this.getRetrieveMessage(type, 0);
|
||||
this.getRetrieveMessage(messageType, 0);
|
||||
}
|
||||
|
||||
/** 쪽지 검색 관련 */
|
||||
onChangeSelection(event: MatSelectChange) {
|
||||
this.searchCurrentPage = 0;
|
||||
this.getSearchMessage(
|
||||
event.value,
|
||||
this.fgSearchType.get('searchMessageSearchType').value,
|
||||
|
@ -191,7 +184,6 @@ export class MessageBoxComponent
|
|||
);
|
||||
}
|
||||
onChangeSearchType(event: MatRadioChange) {
|
||||
this.searchCurrentPage = 0;
|
||||
this.getSearchMessage(
|
||||
this.fgSearchType.get('searchMessageType').value,
|
||||
event.value,
|
||||
|
@ -202,8 +194,6 @@ export class MessageBoxComponent
|
|||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
this.searchCurrentPage = 0;
|
||||
|
||||
this.getSearchMessage(
|
||||
MessageType.All,
|
||||
MessageSearchType.Name,
|
||||
|
@ -216,125 +206,27 @@ export class MessageBoxComponent
|
|||
searchStr: string
|
||||
) {
|
||||
this.isSearch = true;
|
||||
this.messageSendListSubscription = this.messageApiService
|
||||
.retrieveSearchMessage({
|
||||
userSeq: this.loginRes.userSeq,
|
||||
deviceType: DeviceType.PC,
|
||||
tokenKey: this.loginRes.tokenString,
|
||||
type: messageType,
|
||||
pageSize: this.defaultPageSize,
|
||||
pageCount: this.searchCurrentPage,
|
||||
|
||||
searchTitle: searchType === MessageSearchType.Title ? searchStr : '',
|
||||
searchName: searchType === MessageSearchType.Name ? searchStr : '',
|
||||
searchContent:
|
||||
searchType === MessageSearchType.Contents ? searchStr : ''
|
||||
} as RetrieveSearchRequest)
|
||||
.pipe(
|
||||
take(1),
|
||||
map(res => {
|
||||
if (res.responseCode === MessageStatusCode.Success) {
|
||||
this.currentTotalCount = res.totalCount;
|
||||
this.currentPage = res.pageCount;
|
||||
this.searchCurrentPage = res.pageCount;
|
||||
this.messageList = res.messageList;
|
||||
} else {
|
||||
}
|
||||
}),
|
||||
catchError(error => of(this.logger.error(error)))
|
||||
)
|
||||
.subscribe();
|
||||
this.store.dispatch(
|
||||
MessageStore.searchMessage({
|
||||
messageType,
|
||||
searchType,
|
||||
searchStr
|
||||
})
|
||||
);
|
||||
}
|
||||
onClickSearchCancel() {
|
||||
this.isSearch = false;
|
||||
this.getRetrieveMessage(MessageType.Receive, this.recieveCurrentPage);
|
||||
this.getRetrieveMessage(MessageType.Receive, 0);
|
||||
}
|
||||
|
||||
/** 쪽지 타입별 조회 */
|
||||
getRetrieveMessage(type: MessageType, trgtPageIndex: number) {
|
||||
switch (type) {
|
||||
case MessageType.Receive:
|
||||
{
|
||||
this.messageSendListSubscription = this.messageApiService
|
||||
.retrieveReceiveMessage({
|
||||
userSeq: this.loginRes.userSeq,
|
||||
deviceType: DeviceType.PC,
|
||||
tokenKey: this.loginRes.tokenString,
|
||||
type: MessageType.Receive,
|
||||
pageSize: this.defaultPageSize,
|
||||
pageCount: this.recieveCurrentPage
|
||||
} as RetrieveRequest)
|
||||
.pipe(
|
||||
take(1),
|
||||
map(res => {
|
||||
if (res.responseCode === MessageStatusCode.Success) {
|
||||
this.currentTotalCount = res.totalCount;
|
||||
this.currentPage = res.pageCount;
|
||||
this.recieveCurrentPage = res.pageCount;
|
||||
this.messageList = res.messageList;
|
||||
} else {
|
||||
}
|
||||
}),
|
||||
catchError(error => of(this.logger.error(error)))
|
||||
)
|
||||
.subscribe();
|
||||
}
|
||||
break;
|
||||
case MessageType.Send:
|
||||
{
|
||||
this.messageSendListSubscription = this.messageApiService
|
||||
.retrieveSendMessage({
|
||||
userSeq: this.loginRes.userSeq,
|
||||
deviceType: DeviceType.PC,
|
||||
tokenKey: this.loginRes.tokenString,
|
||||
type: MessageType.Send,
|
||||
pageSize: this.defaultPageSize,
|
||||
pageCount: this.sendCurrentPage
|
||||
} as RetrieveRequest)
|
||||
.pipe(
|
||||
take(1),
|
||||
map(res => {
|
||||
if (res.responseCode === MessageStatusCode.Success) {
|
||||
this.currentTotalCount = res.totalCount;
|
||||
this.currentPage = res.pageCount;
|
||||
this.sendCurrentPage = res.pageCount;
|
||||
this.messageList = res.messageList;
|
||||
} else {
|
||||
}
|
||||
}),
|
||||
catchError(error => of(this.logger.error(error)))
|
||||
)
|
||||
.subscribe();
|
||||
}
|
||||
break;
|
||||
case MessageType.Reservation:
|
||||
{
|
||||
this.messageSendListSubscription = this.messageApiService
|
||||
.retrieveReservationMessage({
|
||||
userSeq: this.loginRes.userSeq,
|
||||
deviceType: DeviceType.PC,
|
||||
tokenKey: this.loginRes.tokenString,
|
||||
type: MessageType.Reservation,
|
||||
pageSize: this.defaultPageSize,
|
||||
pageCount: this.reservationCurrentPage
|
||||
} as RetrieveRequest)
|
||||
.pipe(
|
||||
take(1),
|
||||
map(res => {
|
||||
if (res.responseCode === MessageStatusCode.Success) {
|
||||
this.currentTotalCount = res.totalCount;
|
||||
this.currentPage = res.pageCount;
|
||||
this.reservationCurrentPage = res.pageCount;
|
||||
this.messageList = res.messageList;
|
||||
} else {
|
||||
}
|
||||
}),
|
||||
catchError(error => of(this.logger.error(error)))
|
||||
)
|
||||
.subscribe();
|
||||
}
|
||||
break;
|
||||
}
|
||||
getRetrieveMessage(messageType: MessageType, trgtPageIndex: number) {
|
||||
this.store.dispatch(
|
||||
MessageStore.retrieveMessage({
|
||||
messageType
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
/** 쪽지 상세보기 */
|
||||
|
|
|
@ -151,27 +151,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
::ng-deep .mat-paginator {
|
||||
.mat-paginator-container {
|
||||
justify-content: center;
|
||||
}
|
||||
.mat-paginator-navigation-first {
|
||||
order: 1;
|
||||
}
|
||||
.mat-paginator-navigation-previous {
|
||||
order: 2;
|
||||
}
|
||||
// override material paginator page switch
|
||||
.mat-paginator-range-label {
|
||||
order: 3;
|
||||
}
|
||||
.mat-paginator-navigation-next {
|
||||
order: 4;
|
||||
}
|
||||
.mat-paginator-navigation-last {
|
||||
order: 5;
|
||||
}
|
||||
}
|
||||
::ng-deep .mat-form-field-appearance-legacy {
|
||||
.mat-form-field-infix {
|
||||
padding: 6px;
|
||||
|
|
|
@ -66,6 +66,11 @@
|
|||
box-sizing: border-box;
|
||||
display: flex;
|
||||
border-top: 1px solid #dddddd;
|
||||
.mat-paginator {
|
||||
.mat-paginator-container {
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
.btn-box {
|
||||
height: 50px;
|
||||
padding-bottom: 10px;
|
||||
|
@ -77,7 +82,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
.mat-paginator {
|
||||
/*::ng-deep .mat-paginator {
|
||||
.mat-paginator-container {
|
||||
justify-content: center;
|
||||
}
|
||||
|
@ -97,7 +102,7 @@
|
|||
.mat-paginator-navigation-last {
|
||||
order: 5;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
.mat-form-field-appearance-legacy {
|
||||
.mat-form-field-infix {
|
||||
padding: 6px;
|
||||
|
|
|
@ -3,6 +3,7 @@ import { Action, combineReducers, Selector, createSelector } from '@ngrx/store';
|
|||
|
||||
import * as ChatStore from './chat';
|
||||
import * as EventStore from './event';
|
||||
import * as MessageStore from './message';
|
||||
import * as OptionStore from './option';
|
||||
import * as QueryStore from './query';
|
||||
import * as RoomStore from './room';
|
||||
|
@ -13,6 +14,7 @@ import * as SettingsStore from './settings';
|
|||
export interface State {
|
||||
chat: ChatStore.State;
|
||||
event: EventStore.State;
|
||||
message: MessageStore.State;
|
||||
option: OptionStore.State;
|
||||
query: QueryStore.State;
|
||||
room: RoomStore.State;
|
||||
|
@ -24,6 +26,7 @@ export interface State {
|
|||
export const effects: Type<any>[] = [
|
||||
ChatStore.Effects,
|
||||
EventStore.Effects,
|
||||
MessageStore.Effects,
|
||||
OptionStore.Effects,
|
||||
QueryStore.Effects,
|
||||
RoomStore.Effects,
|
||||
|
@ -36,6 +39,7 @@ export function reducers(state: State | undefined, action: Action) {
|
|||
return combineReducers({
|
||||
chat: ChatStore.reducer,
|
||||
event: EventStore.reducer,
|
||||
message: MessageStore.reducer,
|
||||
option: OptionStore.reducer,
|
||||
query: QueryStore.reducer,
|
||||
room: RoomStore.reducer,
|
||||
|
@ -53,6 +57,9 @@ export function selectors<S>(selector: Selector<any, State>) {
|
|||
EventSelector: EventStore.selectors(
|
||||
createSelector(selector, (state: State) => state.event)
|
||||
),
|
||||
MessageSelector: MessageStore.selectors(
|
||||
createSelector(selector, (state: State) => state.message)
|
||||
),
|
||||
OptionSelector: OptionStore.selectors(
|
||||
createSelector(selector, (state: State) => state.option)
|
||||
),
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
import { createAction, props } from '@ngrx/store';
|
||||
import {
|
||||
MessageType,
|
||||
RetrieveResponse,
|
||||
MessageSearchType
|
||||
} from '@ucap-webmessenger/api-message';
|
||||
|
||||
export const retrieveMessage = createAction(
|
||||
'[Messenger::Message] RetrieveMessage',
|
||||
props<{
|
||||
messageType: MessageType;
|
||||
pageSize?: number;
|
||||
pageCount?: number;
|
||||
}>()
|
||||
);
|
||||
export const retrieveMessageSuccess = createAction(
|
||||
'[Messenger::Message] RetrieveMessage Success',
|
||||
props<{ res: RetrieveResponse; messageType: MessageType }>()
|
||||
);
|
||||
export const retrieveMessageFailure = createAction(
|
||||
'[Messenger::Message] RetrieveMessage Failure',
|
||||
props<{ error: any }>()
|
||||
);
|
||||
|
||||
export const searchMessage = createAction(
|
||||
'[Messenger::Message] searchMessage',
|
||||
props<{
|
||||
messageType: MessageType;
|
||||
pageSize?: number;
|
||||
pageCount?: number;
|
||||
searchType?: MessageSearchType;
|
||||
searchStr?: string;
|
||||
}>()
|
||||
);
|
||||
export const searchMessageSuccess = createAction(
|
||||
'[Messenger::Message] searchMessage Success',
|
||||
props<{ res: RetrieveResponse; messageType: MessageType }>()
|
||||
);
|
||||
export const searchMessageFailure = createAction(
|
||||
'[Messenger::Message] searchMessage Failure',
|
||||
props<{ error: any }>()
|
||||
);
|
|
@ -0,0 +1,210 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
|
||||
import { Actions, createEffect, ofType } from '@ngrx/effects';
|
||||
|
||||
import { Store, select } from '@ngrx/store';
|
||||
|
||||
import { NGXLogger } from 'ngx-logger';
|
||||
|
||||
import { of } from 'rxjs';
|
||||
import {
|
||||
tap,
|
||||
switchMap,
|
||||
map,
|
||||
catchError,
|
||||
exhaustMap,
|
||||
withLatestFrom,
|
||||
concatMap,
|
||||
take
|
||||
} from 'rxjs/operators';
|
||||
import moment from 'moment';
|
||||
|
||||
import * as ChatStore from '@app/store/messenger/chat';
|
||||
import * as RoomStore from '@app/store/messenger/room';
|
||||
import * as SyncStore from '@app/store/messenger/sync';
|
||||
|
||||
import { SessionStorageService } from '@ucap-webmessenger/web-storage';
|
||||
import { KEY_ENVIRONMENTS_INFO } from './../../../types/environment.type';
|
||||
import { LoginInfo, KEY_LOGIN_INFO, EnvironmentsInfo } from '@app/types';
|
||||
import { Dictionary } from '@ngrx/entity';
|
||||
import { openSuccess, openFailure } from '../room';
|
||||
import { LoginResponse } from '@ucap-webmessenger/protocol-authentication';
|
||||
import { KEY_LOGIN_RES_INFO } from '@app/types/login-res-info.type';
|
||||
import { StatusCode, MessageStatusCode } from '@ucap-webmessenger/api';
|
||||
import { environment } from '../../../../environments/environment';
|
||||
import {
|
||||
AlertDialogComponent,
|
||||
AlertDialogResult,
|
||||
AlertDialogData,
|
||||
DialogService
|
||||
} from '@ucap-webmessenger/ui';
|
||||
import {
|
||||
retrieveMessage,
|
||||
retrieveMessageFailure,
|
||||
retrieveMessageSuccess,
|
||||
searchMessage,
|
||||
searchMessageSuccess,
|
||||
searchMessageFailure
|
||||
} from './actions';
|
||||
import {
|
||||
MessageApiService,
|
||||
RetrieveRequest,
|
||||
MessageType,
|
||||
RetrieveSearchRequest,
|
||||
MessageSearchType
|
||||
} from '@ucap-webmessenger/api-message';
|
||||
|
||||
@Injectable()
|
||||
export class Effects {
|
||||
retrieveMessage$ = createEffect(
|
||||
() => {
|
||||
// const loginResInfo: LoginResponse = this.sessionStorageService.get<
|
||||
// LoginResponse
|
||||
// >(KEY_LOGIN_RES_INFO);
|
||||
const environmentsInfo = this.sessionStorageService.get<EnvironmentsInfo>(
|
||||
KEY_ENVIRONMENTS_INFO
|
||||
);
|
||||
|
||||
return this.actions$.pipe(
|
||||
ofType(retrieveMessage),
|
||||
withLatestFrom(
|
||||
this.store.pipe(
|
||||
select(
|
||||
(state: any) =>
|
||||
state.account.authentication.loginRes as LoginResponse
|
||||
)
|
||||
)
|
||||
),
|
||||
switchMap(([req, loginResInfo]) => {
|
||||
const request: RetrieveRequest = {
|
||||
userSeq: loginResInfo.userSeq,
|
||||
deviceType: environmentsInfo.deviceType,
|
||||
tokenKey: loginResInfo.tokenString,
|
||||
type: req.messageType,
|
||||
pageSize: !!req.pageSize ? req.pageSize : 1000,
|
||||
pageCount: !!req.pageCount ? req.pageCount : 0
|
||||
};
|
||||
|
||||
switch (req.messageType) {
|
||||
case MessageType.Receive: {
|
||||
return this.messageApiService
|
||||
.retrieveReceiveMessage(request)
|
||||
.pipe(
|
||||
map(res => {
|
||||
if (res.responseCode === MessageStatusCode.Success) {
|
||||
this.store.dispatch(
|
||||
retrieveMessageSuccess({
|
||||
res,
|
||||
messageType: req.messageType
|
||||
})
|
||||
);
|
||||
}
|
||||
}),
|
||||
catchError(error => of(retrieveMessageFailure({ error })))
|
||||
);
|
||||
}
|
||||
case MessageType.Send: {
|
||||
return this.messageApiService.retrieveSendMessage(request).pipe(
|
||||
map(res => {
|
||||
if (res.responseCode === MessageStatusCode.Success) {
|
||||
this.store.dispatch(
|
||||
retrieveMessageSuccess({
|
||||
res,
|
||||
messageType: req.messageType
|
||||
})
|
||||
);
|
||||
}
|
||||
}),
|
||||
catchError(error => of(retrieveMessageFailure({ error })))
|
||||
);
|
||||
}
|
||||
case MessageType.Reservation: {
|
||||
return this.messageApiService
|
||||
.retrieveReservationMessage(request)
|
||||
.pipe(
|
||||
map(res => {
|
||||
if (res.responseCode === MessageStatusCode.Success) {
|
||||
this.store.dispatch(
|
||||
retrieveMessageSuccess({
|
||||
res,
|
||||
messageType: req.messageType
|
||||
})
|
||||
);
|
||||
}
|
||||
}),
|
||||
catchError(error => of(retrieveMessageFailure({ error })))
|
||||
);
|
||||
}
|
||||
}
|
||||
})
|
||||
);
|
||||
},
|
||||
{ dispatch: false }
|
||||
);
|
||||
|
||||
searchMessage$ = createEffect(
|
||||
() => {
|
||||
const environmentsInfo = this.sessionStorageService.get<EnvironmentsInfo>(
|
||||
KEY_ENVIRONMENTS_INFO
|
||||
);
|
||||
|
||||
return this.actions$.pipe(
|
||||
ofType(searchMessage),
|
||||
withLatestFrom(
|
||||
this.store.pipe(
|
||||
select(
|
||||
(state: any) =>
|
||||
state.account.authentication.loginRes as LoginResponse
|
||||
)
|
||||
)
|
||||
),
|
||||
switchMap(([req, loginResInfo]) => {
|
||||
const request: RetrieveRequest = {
|
||||
userSeq: loginResInfo.userSeq,
|
||||
deviceType: environmentsInfo.deviceType,
|
||||
tokenKey: loginResInfo.tokenString,
|
||||
type: req.messageType,
|
||||
pageSize: !!req.pageSize ? req.pageSize : 1000,
|
||||
pageCount: !!req.pageCount ? req.pageCount : 0
|
||||
};
|
||||
|
||||
return this.messageApiService
|
||||
.retrieveSearchMessage({
|
||||
...request,
|
||||
searchTitle:
|
||||
req.searchType === MessageSearchType.Title ? req.searchStr : '',
|
||||
searchName:
|
||||
req.searchType === MessageSearchType.Name ? req.searchStr : '',
|
||||
searchContent:
|
||||
req.searchType === MessageSearchType.Contents
|
||||
? req.searchStr
|
||||
: ''
|
||||
} as RetrieveSearchRequest)
|
||||
.pipe(
|
||||
map(res => {
|
||||
if (res.responseCode === MessageStatusCode.Success) {
|
||||
this.store.dispatch(
|
||||
searchMessageSuccess({
|
||||
res,
|
||||
messageType: req.messageType
|
||||
})
|
||||
);
|
||||
}
|
||||
}),
|
||||
catchError(error => of(searchMessageFailure({ error })))
|
||||
);
|
||||
})
|
||||
);
|
||||
},
|
||||
{ dispatch: false }
|
||||
);
|
||||
|
||||
constructor(
|
||||
private actions$: Actions,
|
||||
private store: Store<any>,
|
||||
private messageApiService: MessageApiService,
|
||||
private sessionStorageService: SessionStorageService,
|
||||
private dialogService: DialogService,
|
||||
private logger: NGXLogger
|
||||
) {}
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
export * from './actions';
|
||||
export * from './effects';
|
||||
export * from './reducers';
|
||||
export * from './state';
|
|
@ -0,0 +1,100 @@
|
|||
import { createReducer, on } from '@ngrx/store';
|
||||
import {
|
||||
initialState,
|
||||
adapterReceiveList,
|
||||
adapterSendList,
|
||||
adapterReservationList,
|
||||
adapterSearchList
|
||||
} from './state';
|
||||
import * as AuthenticationStore from '@app/store/account/authentication';
|
||||
import {
|
||||
retrieveMessageSuccess,
|
||||
retrieveMessage,
|
||||
searchMessage,
|
||||
searchMessageSuccess
|
||||
} from './actions';
|
||||
import { MessageType } from '@ucap-webmessenger/api-message';
|
||||
|
||||
export const reducer = createReducer(
|
||||
initialState,
|
||||
|
||||
on(retrieveMessage, (state, action) => {
|
||||
switch (action.messageType) {
|
||||
case MessageType.Receive: {
|
||||
return {
|
||||
...state,
|
||||
receiveListProcessing: true
|
||||
};
|
||||
}
|
||||
case MessageType.Send: {
|
||||
return {
|
||||
...state,
|
||||
sendListProcessing: true
|
||||
};
|
||||
}
|
||||
case MessageType.Reservation: {
|
||||
return {
|
||||
...state,
|
||||
reservationListProcessing: true
|
||||
};
|
||||
}
|
||||
}
|
||||
}),
|
||||
on(retrieveMessageSuccess, (state, action) => {
|
||||
switch (action.messageType) {
|
||||
case MessageType.Receive: {
|
||||
return {
|
||||
...state,
|
||||
receiveList: adapterReceiveList.upsertMany(action.res.messageList, {
|
||||
...state.receiveList
|
||||
}),
|
||||
receiveListProcessing: false
|
||||
};
|
||||
}
|
||||
case MessageType.Send: {
|
||||
return {
|
||||
...state,
|
||||
sendList: adapterSendList.upsertMany(action.res.messageList, {
|
||||
...state.sendList
|
||||
}),
|
||||
sendListProcessing: false
|
||||
};
|
||||
}
|
||||
case MessageType.Reservation: {
|
||||
return {
|
||||
...state,
|
||||
reservationList: adapterReservationList.upsertMany(
|
||||
action.res.messageList,
|
||||
{
|
||||
...state.reservationList
|
||||
}
|
||||
),
|
||||
reservationListProcessing: false
|
||||
};
|
||||
}
|
||||
}
|
||||
}),
|
||||
|
||||
on(searchMessage, (state, action) => {
|
||||
return {
|
||||
...state,
|
||||
searchList: adapterSearchList.removeAll(state.searchList),
|
||||
searchListProcessing: true
|
||||
};
|
||||
}),
|
||||
on(searchMessageSuccess, (state, action) => {
|
||||
return {
|
||||
...state,
|
||||
searchList: adapterSearchList.upsertMany(action.res.messageList, {
|
||||
...state.searchList
|
||||
}),
|
||||
searchListProcessing: false
|
||||
};
|
||||
}),
|
||||
|
||||
on(AuthenticationStore.logoutInitialize, (state, action) => {
|
||||
return {
|
||||
...initialState
|
||||
};
|
||||
})
|
||||
);
|
|
@ -0,0 +1,218 @@
|
|||
import { Selector, createSelector } from '@ngrx/store';
|
||||
import { EntityState, createEntityAdapter } from '@ngrx/entity';
|
||||
|
||||
import { MessageList } from '@ucap-webmessenger/api-message';
|
||||
|
||||
import {
|
||||
InfoResponse,
|
||||
Info,
|
||||
EventJson
|
||||
} from '@ucap-webmessenger/protocol-event';
|
||||
import { FileInfo, FileDownloadInfo } from '@ucap-webmessenger/protocol-file';
|
||||
|
||||
export interface ReceiveListState extends EntityState<MessageList> {}
|
||||
export interface SendListState extends EntityState<MessageList> {}
|
||||
export interface ReservationListState extends EntityState<MessageList> {}
|
||||
export interface SearchListState extends EntityState<MessageList> {}
|
||||
|
||||
export interface InfoListState extends EntityState<Info<EventJson>> {}
|
||||
export interface FileInfoListState extends EntityState<FileInfo> {}
|
||||
export interface FileInfoCheckListState extends EntityState<FileDownloadInfo> {}
|
||||
|
||||
export interface State {
|
||||
receiveListProcessing: boolean;
|
||||
receiveList: ReceiveListState;
|
||||
receiveTotalCount: number;
|
||||
receivePage: number;
|
||||
|
||||
sendListProcessing: boolean;
|
||||
sendList: SendListState;
|
||||
sendTotalCount: number;
|
||||
sendPage: number;
|
||||
|
||||
reservationListProcessing: boolean;
|
||||
reservationList: ReservationListState;
|
||||
reservationTotalCount: number;
|
||||
reservationPage: number;
|
||||
|
||||
searchListProcessing: boolean;
|
||||
searchList: SearchListState;
|
||||
searchTotalCount: number;
|
||||
searchPage: number;
|
||||
}
|
||||
|
||||
export const adapterReceiveList = createEntityAdapter<MessageList>({
|
||||
selectId: info => info.msgId,
|
||||
sortComparer: (a, b) => {
|
||||
return b.msgId - a.msgId;
|
||||
}
|
||||
});
|
||||
export const adapterSendList = createEntityAdapter<MessageList>({
|
||||
selectId: info => info.msgId,
|
||||
sortComparer: (a, b) => {
|
||||
return b.msgId - a.msgId;
|
||||
}
|
||||
});
|
||||
export const adapterReservationList = createEntityAdapter<MessageList>({
|
||||
selectId: info => info.msgId,
|
||||
sortComparer: (a, b) => {
|
||||
return b.msgId - a.msgId;
|
||||
}
|
||||
});
|
||||
export const adapterSearchList = createEntityAdapter<MessageList>({
|
||||
selectId: info => info.msgId,
|
||||
sortComparer: (a, b) => {
|
||||
return b.msgId - a.msgId;
|
||||
}
|
||||
});
|
||||
|
||||
const receiveListInitialState: ReceiveListState = adapterReceiveList.getInitialState(
|
||||
{}
|
||||
);
|
||||
const sendListInitialState: SendListState = adapterSendList.getInitialState({});
|
||||
const reservationListInitialState: ReservationListState = adapterReservationList.getInitialState(
|
||||
{}
|
||||
);
|
||||
const searchListInitialState: SearchListState = adapterSearchList.getInitialState(
|
||||
{}
|
||||
);
|
||||
|
||||
export const initialState: State = {
|
||||
receiveListProcessing: false,
|
||||
receiveList: receiveListInitialState,
|
||||
receiveTotalCount: 0,
|
||||
receivePage: 0,
|
||||
|
||||
sendListProcessing: false,
|
||||
sendList: sendListInitialState,
|
||||
sendTotalCount: 0,
|
||||
sendPage: 0,
|
||||
|
||||
reservationListProcessing: false,
|
||||
reservationList: reservationListInitialState,
|
||||
reservationTotalCount: 0,
|
||||
reservationPage: 0,
|
||||
|
||||
searchListProcessing: false,
|
||||
searchList: searchListInitialState,
|
||||
searchTotalCount: 0,
|
||||
searchPage: 0
|
||||
};
|
||||
|
||||
const {
|
||||
selectAll: ngeSelectAllReceiveList,
|
||||
selectEntities: ngeSelectEntitiesReceiveList,
|
||||
selectIds: ngeSelectIdsReceiveList,
|
||||
selectTotal: ngeSelectTotalReceiveList
|
||||
} = adapterReceiveList.getSelectors();
|
||||
const {
|
||||
selectAll: ngeSelectAllSendList,
|
||||
selectEntities: ngeSelectEntitiesSendList,
|
||||
selectIds: ngeSelectIdsSendList,
|
||||
selectTotal: ngeSelectTotalSendList
|
||||
} = adapterSendList.getSelectors();
|
||||
const {
|
||||
selectAll: ngeSelectAllReservationList,
|
||||
selectEntities: ngeSelectEntitiesReservationList,
|
||||
selectIds: ngeSelectIdsReservationList,
|
||||
selectTotal: ngeSelectTotalReservationList
|
||||
} = adapterReservationList.getSelectors();
|
||||
const {
|
||||
selectAll: ngeSelectAllSearchList,
|
||||
selectEntities: ngeSelectEntitiesSearchList,
|
||||
selectIds: ngeSelectIdsSearchList,
|
||||
selectTotal: ngeSelectTotalSearchList
|
||||
} = adapterSearchList.getSelectors();
|
||||
|
||||
export function selectors<S>(selector: Selector<any, State>) {
|
||||
const selectReceiveList = createSelector(
|
||||
selector,
|
||||
(state: State) => state.receiveList
|
||||
);
|
||||
const selectSendList = createSelector(
|
||||
selector,
|
||||
(state: State) => state.sendList
|
||||
);
|
||||
const selectReservationList = createSelector(
|
||||
selector,
|
||||
(state: State) => state.reservationList
|
||||
);
|
||||
const selectSearchList = createSelector(
|
||||
selector,
|
||||
(state: State) => state.searchList
|
||||
);
|
||||
|
||||
return {
|
||||
receiveListProcessing: createSelector(
|
||||
selector,
|
||||
(state: State) => state.receiveListProcessing
|
||||
),
|
||||
sendListProcessing: createSelector(
|
||||
selector,
|
||||
(state: State) => state.sendListProcessing
|
||||
),
|
||||
reservationListProcessing: createSelector(
|
||||
selector,
|
||||
(state: State) => state.reservationListProcessing
|
||||
),
|
||||
searchListProcessing: createSelector(
|
||||
selector,
|
||||
(state: State) => state.searchListProcessing
|
||||
),
|
||||
|
||||
selectAllReceiveList: createSelector(
|
||||
selectReceiveList,
|
||||
ngeSelectAllReceiveList
|
||||
),
|
||||
selectEntitiesReceiveList: createSelector(
|
||||
selectReceiveList,
|
||||
ngeSelectEntitiesReceiveList
|
||||
),
|
||||
selectReceiveList: (seq: number) =>
|
||||
createSelector(
|
||||
selectReceiveList,
|
||||
ngeSelectEntitiesReceiveList,
|
||||
(_, entities) => (!!entities ? entities[seq] : undefined)
|
||||
),
|
||||
|
||||
selectAllSendList: createSelector(selectSendList, ngeSelectAllSendList),
|
||||
selectEntitiesSendList: createSelector(
|
||||
selectSendList,
|
||||
ngeSelectEntitiesSendList
|
||||
),
|
||||
selectSendList: (seq: number) =>
|
||||
createSelector(selectSendList, ngeSelectEntitiesSendList, (_, entities) =>
|
||||
!!entities ? entities[seq] : undefined
|
||||
),
|
||||
|
||||
selectAllReservationList: createSelector(
|
||||
selectReservationList,
|
||||
ngeSelectAllReservationList
|
||||
),
|
||||
selectEntitiesReservationList: createSelector(
|
||||
selectReservationList,
|
||||
ngeSelectEntitiesReservationList
|
||||
),
|
||||
selectReservationList: (seq: number) =>
|
||||
createSelector(
|
||||
selectReservationList,
|
||||
ngeSelectEntitiesReservationList,
|
||||
(_, entities) => (!!entities ? entities[seq] : undefined)
|
||||
),
|
||||
|
||||
selectAllSearchList: createSelector(
|
||||
selectSearchList,
|
||||
ngeSelectAllSearchList
|
||||
),
|
||||
selectEntitiesSearchList: createSelector(
|
||||
selectSearchList,
|
||||
ngeSelectEntitiesSearchList
|
||||
),
|
||||
selectSearchList: (seq: number) =>
|
||||
createSelector(
|
||||
selectSearchList,
|
||||
ngeSelectEntitiesSearchList,
|
||||
(_, entities) => (!!entities ? entities[seq] : undefined)
|
||||
)
|
||||
};
|
||||
}
|
|
@ -2,6 +2,7 @@
|
|||
display: flex;
|
||||
align-content: center;
|
||||
flex-flow: row;
|
||||
align-items: flex-end;
|
||||
.line {
|
||||
height: 1px;
|
||||
background-color: #cccccc;
|
||||
|
|
|
@ -7,4 +7,5 @@
|
|||
color: #ffffff;
|
||||
border-radius: 100px;
|
||||
justify-content: center;
|
||||
margin: 10px 0 20px;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<div class="chat-messages" #scrollMe>
|
||||
<!--<div class="chat-messages" #scrollMe>
|
||||
<div class="message-row" *ngIf="eventRemain && messages.length > 0">
|
||||
<button mat-button (click)="onClickMore($event)">
|
||||
이전 대화 보기
|
||||
|
@ -14,7 +14,45 @@
|
|||
}})개
|
||||
</span>
|
||||
</button>
|
||||
</div>-->
|
||||
<div class="chat-messages" #scrollMe>
|
||||
<div class="unRead-count" *ngIf="
|
||||
!!roomInfo &&
|
||||
!!firstEventSeq &&
|
||||
roomInfo.lastReadEventSeq < firstEventSeq
|
||||
">
|
||||
<span class="line"></span>
|
||||
<span class="count">
|
||||
안읽은 메시지가 <span class="text-warn-color">({{ firstEventSeq - (roomInfo.lastReadEventSeq + 1) }})</span>개
|
||||
더 있습니다.
|
||||
</span>
|
||||
<span class="line"></span>
|
||||
</div>
|
||||
<div
|
||||
*ngIf="eventRemain && messages.length > 0"
|
||||
class="message-row view-previous bg-accent-dark"
|
||||
>
|
||||
<button mat-button (click)="onClickMore($event)">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="20"
|
||||
height="20"
|
||||
viewBox="0 0 20 20"
|
||||
stroke="currentColor"
|
||||
fill="none"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<circle class="st0" cx="10" cy="10" r="7.3" />
|
||||
<polyline class="st0" points="12.9,10 10,7.1 7.1,10 " />
|
||||
<line class="st0" x1="10" y1="12.9" x2="10" y2="7.1" />
|
||||
</svg>
|
||||
이전 대화 보기
|
||||
</button>
|
||||
<span class="line"></span>
|
||||
</div>
|
||||
|
||||
<!-- MESSAGE -->
|
||||
<div
|
||||
*ngFor="let message of messages; let i = index"
|
||||
|
|
|
@ -158,3 +158,43 @@ $meBox-bg: #ffffff;
|
|||
white-space: pre-wrap;
|
||||
word-break: break-word;
|
||||
}
|
||||
.view-previous {
|
||||
display: flex;
|
||||
align-content: center;
|
||||
flex-flow: row;
|
||||
background-color: rgba(0, 0, 0, 0.4);
|
||||
padding: 4px 10px;
|
||||
color: #ffffff;
|
||||
border-radius: 100px;
|
||||
justify-content: center;
|
||||
margin: 10px 0 20px;
|
||||
button {
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
width: 100%;
|
||||
svg {
|
||||
stroke: #ffffff;
|
||||
align-self: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
.unRead-count {
|
||||
display: flex;
|
||||
justify-items: self-end;
|
||||
flex-flow: row;
|
||||
align-items: flex-end;
|
||||
.line {
|
||||
height: 1px;
|
||||
background-color: #cccccc;
|
||||
width: 40%;
|
||||
flex: 1 1 auto;
|
||||
margin-bottom: 10px;
|
||||
display: inline-flex;
|
||||
}
|
||||
.count {
|
||||
width: 260px;
|
||||
font-size: 13px;
|
||||
text-align: center;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,8 @@
|
|||
@import 'partials/icons';
|
||||
@import 'partials/normalize';
|
||||
@import 'partials/scrollbars';
|
||||
@import 'partials/presence.scss';
|
||||
@import 'partials/paginator';
|
||||
@import 'partials/presence';
|
||||
@import 'partials/list-item';
|
||||
@import 'partials/dialogs';
|
||||
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
@charset 'utf-8';
|
||||
|
||||
.mat-paginator {
|
||||
.mat-paginator-container {
|
||||
justify-content: center;
|
||||
}
|
||||
.mat-paginator-navigation-first {
|
||||
order: 1;
|
||||
}
|
||||
.mat-paginator-navigation-previous {
|
||||
order: 2;
|
||||
}
|
||||
// override material paginator page switch
|
||||
.mat-paginator-range-label {
|
||||
order: 3;
|
||||
}
|
||||
.mat-paginator-navigation-next {
|
||||
order: 4;
|
||||
}
|
||||
.mat-paginator-navigation-last {
|
||||
order: 5;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user