sync
This commit is contained in:
parent
0c121ef1ad
commit
cc59886a40
|
@ -28,4 +28,15 @@ if (!!buddies && buddies.length > 0) {
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log(userSeqsForAdd);
|
console.log(userSeqsForAdd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
update-user-dialog
|
||||||
|
manage-dialog
|
||||||
|
|
||||||
|
index.page
|
||||||
|
sidenav.page
|
||||||
|
updateMember
|
||||||
|
copy
|
||||||
|
move
|
||||||
|
add
|
||||||
|
create
|
107
documents/업무/6월/1째주/0603.txt
Normal file
107
documents/업무/6월/1째주/0603.txt
Normal file
|
@ -0,0 +1,107 @@
|
||||||
|
프로필
|
||||||
|
나와의 채팅 진행 (O)
|
||||||
|
이벤트
|
||||||
|
파라미터(loginres, userseq )
|
||||||
|
채팅
|
||||||
|
대화 이벤트
|
||||||
|
답장
|
||||||
|
대화전달
|
||||||
|
대화복사
|
||||||
|
|
||||||
|
대화 나에게 전달
|
||||||
|
액션
|
||||||
|
대화 전달
|
||||||
|
타겟 대화방 번호
|
||||||
|
타겟 대화상대 번호
|
||||||
|
roomSeq = -999
|
||||||
|
eventType = c
|
||||||
|
sentMassage
|
||||||
|
대화방 오픈
|
||||||
|
대화방 오픈 프로토콜 호출
|
||||||
|
divCd: 'forwardOpen'
|
||||||
|
오픈성공
|
||||||
|
파일 타입
|
||||||
|
텍스트 타입
|
||||||
|
이벤트 전송
|
||||||
|
대화방 선택 처리
|
||||||
|
|
||||||
|
대화방 오픈 결과
|
||||||
|
대화 전송
|
||||||
|
|
||||||
|
|
||||||
|
액션 정의
|
||||||
|
forward => file type, bundle type, text type
|
||||||
|
openAfterSend => file type, text type
|
||||||
|
openAfter => event send
|
||||||
|
roomSelected =>
|
||||||
|
|
||||||
|
이펙트
|
||||||
|
chat foward
|
||||||
|
openAfterSend
|
||||||
|
|
||||||
|
selectedRoom
|
||||||
|
selectedRoomValidate
|
||||||
|
room2 success
|
||||||
|
events
|
||||||
|
events success
|
||||||
|
read
|
||||||
|
fileInfos
|
||||||
|
read success
|
||||||
|
fileInfos success
|
||||||
|
리듀서 구현
|
||||||
|
|
||||||
|
팝업 조직도
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// forwardAfterRoomOpen$ = createEffect(() => {
|
||||||
|
// return this.actions$.pipe(
|
||||||
|
// ofType(forwardAfterRoomOpen),
|
||||||
|
// map((action) =>
|
||||||
|
// RoomActions.create({
|
||||||
|
// req: { divCd: 'forwardOpen', userSeqs: action.trgtUserSeqs }
|
||||||
|
// })
|
||||||
|
// ),
|
||||||
|
// exhaustMap((action) => {
|
||||||
|
// return [];
|
||||||
|
// })
|
||||||
|
// );
|
||||||
|
// });
|
||||||
|
|
||||||
|
|
||||||
|
/** forward */
|
||||||
|
export const forward = createAction(
|
||||||
|
'[ucap::chat::chatting] Forward',
|
||||||
|
props<{
|
||||||
|
senderSeq: string;
|
||||||
|
req: SendRequest;
|
||||||
|
trgtUserSeqs?: string[];
|
||||||
|
trgtRoomSeq?: string;
|
||||||
|
}>()
|
||||||
|
);
|
||||||
|
/** chat forward failure */
|
||||||
|
export const forwardFailure = createAction(
|
||||||
|
'[ucap::chat::chatting] Forward failure',
|
||||||
|
props<{ error: any }>()
|
||||||
|
);
|
||||||
|
|
||||||
|
export const forwardAfterRoomOpen = createAction(
|
||||||
|
'[ucap::chat::chatting] Forward after room open',
|
||||||
|
props<{
|
||||||
|
senderSeq: string;
|
||||||
|
req: SendRequest;
|
||||||
|
trgtUserSeqs?: string[];
|
||||||
|
trgtRoomSeq?: string;
|
||||||
|
}>()
|
||||||
|
);
|
||||||
|
|
||||||
|
export const roomOpenAfterForward = createAction(
|
||||||
|
'[ucap::chat::chatting] Room open after forward',
|
||||||
|
props<{
|
||||||
|
senderSeq: string;
|
||||||
|
req: SendRequest;
|
||||||
|
trgtUserSeqs?: string[];
|
||||||
|
trgtRoomSeq?: string;
|
||||||
|
}>()
|
||||||
|
);
|
26
documents/업무/6월/1째주/0604.txt
Normal file
26
documents/업무/6월/1째주/0604.txt
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
tap component
|
||||||
|
teanant search
|
||||||
|
bySearch, searchword
|
||||||
|
search result
|
||||||
|
bySearch
|
||||||
|
expansion
|
||||||
|
|
||||||
|
room list
|
||||||
|
ucap-chat-room-list-item-01
|
||||||
|
selection user
|
||||||
|
|
||||||
|
기존 절차
|
||||||
|
메세지 전송
|
||||||
|
대화방 대화 추가
|
||||||
|
대화방 갱신
|
||||||
|
대화방 마지막 대화 갱신
|
||||||
|
|
||||||
|
roomOpenAfterForward
|
||||||
|
newInfo
|
||||||
|
appedInfoList
|
||||||
|
newEventMessage
|
||||||
|
updateRoomForNewEventMessage
|
||||||
|
selectedRoom
|
||||||
|
clearEvent
|
||||||
|
info
|
||||||
|
|
70
documents/업무/6월/1째주/0605.txt
Normal file
70
documents/업무/6월/1째주/0605.txt
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
대화 복사
|
||||||
|
일반 텍스트
|
||||||
|
대용량 텍스트
|
||||||
|
일반 번역 텍스트
|
||||||
|
대용량 번역 텍스트
|
||||||
|
|
||||||
|
ucap prj
|
||||||
|
protocol-event isRecall fnc 데이터형 number로 변경
|
||||||
|
|
||||||
|
daesang recall effect
|
||||||
|
cancel (roomseq, eventseq, deviceType)
|
||||||
|
cnacelNotification()
|
||||||
|
recallInfoList - reducer
|
||||||
|
infoList 해당 메세지 갱신
|
||||||
|
대화방 갱신
|
||||||
|
|
||||||
|
대화방 eventList 갱신
|
||||||
|
|
||||||
|
대화방 새로고침
|
||||||
|
액션 생성
|
||||||
|
대화 삭제
|
||||||
|
대화 수정 -> 대화 회수
|
||||||
|
이펙트
|
||||||
|
대화방 새로고침
|
||||||
|
info2 호출 파라미터
|
||||||
|
roomId, isDetail: false, localeCode: loginRes.localeCode
|
||||||
|
리듀서
|
||||||
|
room2Success
|
||||||
|
|
||||||
|
|
||||||
|
infoRequest
|
||||||
|
roomId: string
|
||||||
|
isDetail: boolean
|
||||||
|
localeCode
|
||||||
|
|
||||||
|
InfoResponse
|
||||||
|
roomId: string;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * Refresh of Room request
|
||||||
|
// */
|
||||||
|
// export const roomRefresh = createAction(
|
||||||
|
// '[ucap::chat::room] room refresh ',
|
||||||
|
// props<RoomRequest>()
|
||||||
|
// );
|
||||||
|
// export const roomRefreshFailure = createAction(
|
||||||
|
// '[ucap::chat::room] room refresh Failure',
|
||||||
|
// props<{ error: any }>()
|
||||||
|
// );
|
||||||
|
|
||||||
|
roomRefresh$ = createEffect(() => {
|
||||||
|
return this.actions$.pipe(
|
||||||
|
ofType(roomRefresh),
|
||||||
|
switchMap((action) => {
|
||||||
|
const req = action.req;
|
||||||
|
|
||||||
|
return this.roomProtocolService.info2(req).pipe(
|
||||||
|
map((res) =>
|
||||||
|
room2Success({
|
||||||
|
roomInfo: res.roomInfo,
|
||||||
|
roomUserInfo: res.roomUserInfo
|
||||||
|
})
|
||||||
|
),
|
||||||
|
catchError((error) => of(roomFailure({ error })))
|
||||||
|
);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
234
documents/업무/6월/1째주/backup/chat/actions.ts
Normal file
234
documents/업무/6월/1째주/backup/chat/actions.ts
Normal file
|
@ -0,0 +1,234 @@
|
||||||
|
import { createAction, props } from '@ngrx/store';
|
||||||
|
|
||||||
|
import {
|
||||||
|
Info,
|
||||||
|
InfoRequest as EventInfoRequest,
|
||||||
|
InfoResponse as EventInfoResponse,
|
||||||
|
SendRequest as SendEventRequest,
|
||||||
|
SendResponse as SendEventResponse,
|
||||||
|
ReadRequest,
|
||||||
|
DelRequest,
|
||||||
|
DelResponse,
|
||||||
|
CancelRequest,
|
||||||
|
CancelResponse,
|
||||||
|
SendNotification,
|
||||||
|
ReadNotification,
|
||||||
|
CancelNotification,
|
||||||
|
DelNotification,
|
||||||
|
EventJson,
|
||||||
|
ReadResponse,
|
||||||
|
SendRequest
|
||||||
|
} from '@ucap/protocol-event';
|
||||||
|
|
||||||
|
import {
|
||||||
|
InfoRequest as FileInfoRequest,
|
||||||
|
InfoResponse as FileInfoResponse,
|
||||||
|
FileDownloadInfo,
|
||||||
|
FileInfo
|
||||||
|
} from '@ucap/protocol-file';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* retrieve list of event
|
||||||
|
*/
|
||||||
|
export const events = createAction(
|
||||||
|
'[ucap::chat::chatting] events',
|
||||||
|
props<{ req: EventInfoRequest }>()
|
||||||
|
);
|
||||||
|
/**
|
||||||
|
* Success of events request
|
||||||
|
*/
|
||||||
|
export const eventsSuccess = createAction(
|
||||||
|
'[ucap::chat::chatting] events Success',
|
||||||
|
props<{
|
||||||
|
eventInfoList: Info<EventJson>[];
|
||||||
|
res: EventInfoResponse;
|
||||||
|
remainEvent: boolean;
|
||||||
|
}>()
|
||||||
|
);
|
||||||
|
/**
|
||||||
|
* Failure of events request
|
||||||
|
*/
|
||||||
|
export const eventsFailure = createAction(
|
||||||
|
'[ucap::chat::chatting] events Failure',
|
||||||
|
props<{ roomId: string; error: any }>()
|
||||||
|
);
|
||||||
|
/**
|
||||||
|
* retrieve list of event
|
||||||
|
*/
|
||||||
|
export const moreEvents = createAction(
|
||||||
|
'[ucap::chat::chatting] events more',
|
||||||
|
props<{ roomId: string }>()
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* retrieve list of file information
|
||||||
|
*/
|
||||||
|
export const fileInfos = createAction(
|
||||||
|
'[ucap::chat::chatting] fileInfos',
|
||||||
|
props<{ req: FileInfoRequest }>()
|
||||||
|
);
|
||||||
|
/**
|
||||||
|
* Success of fileInfos request
|
||||||
|
*/
|
||||||
|
export const fileInfosSuccess = createAction(
|
||||||
|
'[ucap::chat::chatting] fileInfos Success',
|
||||||
|
props<{
|
||||||
|
fileInfoList: FileInfo[];
|
||||||
|
fileInfoCheckList: FileDownloadInfo[];
|
||||||
|
res: FileInfoResponse;
|
||||||
|
}>()
|
||||||
|
);
|
||||||
|
/**
|
||||||
|
* Failure of fileInfos request
|
||||||
|
*/
|
||||||
|
export const fileInfosFailure = createAction(
|
||||||
|
'[ucap::chat::chatting] fileInfos Failure',
|
||||||
|
props<{ roomId: string; error: any }>()
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* add new event
|
||||||
|
*/
|
||||||
|
export const addEvent = createAction(
|
||||||
|
'[ucap::chat::chatting] addEvent',
|
||||||
|
props<{
|
||||||
|
roomId: string;
|
||||||
|
info: Info<EventJson>;
|
||||||
|
SVC_TYPE?: number;
|
||||||
|
SSVC_TYPE?: number;
|
||||||
|
}>()
|
||||||
|
);
|
||||||
|
/**
|
||||||
|
* add new event Success.
|
||||||
|
*/
|
||||||
|
export const addEventSuccess = createAction(
|
||||||
|
'[ucap::chat::chatting] addEvent Success',
|
||||||
|
props<{
|
||||||
|
roomId: string;
|
||||||
|
info: Info<EventJson>;
|
||||||
|
}>()
|
||||||
|
);
|
||||||
|
|
||||||
|
export const read = createAction(
|
||||||
|
'[ucap::chat::chatting] read',
|
||||||
|
props<ReadRequest>()
|
||||||
|
);
|
||||||
|
|
||||||
|
export const readSuccess = createAction(
|
||||||
|
'[ucap::chat::chatting] read Success',
|
||||||
|
props<ReadResponse>()
|
||||||
|
);
|
||||||
|
|
||||||
|
// export const readNotification = createAction(
|
||||||
|
// '[ucap::chat::chatting] Read Notification',
|
||||||
|
// props<ReadNotification>()
|
||||||
|
// );
|
||||||
|
|
||||||
|
export const readFailure = createAction(
|
||||||
|
'[ucap::chat::chatting] read Failure',
|
||||||
|
props<{ error: any }>()
|
||||||
|
);
|
||||||
|
|
||||||
|
export const send = createAction(
|
||||||
|
'[ucap::chat::chatting] Send',
|
||||||
|
props<{ senderSeq: string; req: SendEventRequest }>()
|
||||||
|
);
|
||||||
|
|
||||||
|
export const sendSuccess = createAction(
|
||||||
|
'[ucap::chat::chatting] Send Success',
|
||||||
|
props<{
|
||||||
|
senderSeq: string;
|
||||||
|
res: SendEventResponse;
|
||||||
|
}>()
|
||||||
|
);
|
||||||
|
|
||||||
|
export const sendFailure = createAction(
|
||||||
|
'[ucap::chat::chatting] Send Failure',
|
||||||
|
props<{ error: any }>()
|
||||||
|
);
|
||||||
|
|
||||||
|
export const sendNotification = createAction(
|
||||||
|
'[ucap::chat::chatting] Send Notification',
|
||||||
|
props<{ noti: SendNotification }>()
|
||||||
|
);
|
||||||
|
|
||||||
|
/** 대화 삭제 */
|
||||||
|
export const del = createAction(
|
||||||
|
'[ucap::chat::chatting] Delete',
|
||||||
|
props<DelRequest>()
|
||||||
|
);
|
||||||
|
export const delFailure = createAction(
|
||||||
|
'[ucap::chat::chatting] Delete Failure',
|
||||||
|
props<{ error: any }>()
|
||||||
|
);
|
||||||
|
export const delNotification = createAction(
|
||||||
|
'[ucap::chat::chatting] Delete Notification || Response',
|
||||||
|
props<{ noti: DelNotification | DelResponse }>()
|
||||||
|
);
|
||||||
|
/** 대화 삭제시 열린 대화방의 대화 내용 갱신 */
|
||||||
|
export const delEventList = createAction(
|
||||||
|
'[ucap::chat::chatting] Delete InfoList',
|
||||||
|
props<{
|
||||||
|
roomId: string;
|
||||||
|
eventSeqs: number[];
|
||||||
|
}>()
|
||||||
|
);
|
||||||
|
|
||||||
|
/** forward */
|
||||||
|
export const forward = createAction(
|
||||||
|
'[ucap::chat::chatting] Forward',
|
||||||
|
props<{
|
||||||
|
senderSeq: string;
|
||||||
|
req: SendRequest;
|
||||||
|
trgtUserSeqs?: string[];
|
||||||
|
trgtRoomSeq?: string;
|
||||||
|
}>()
|
||||||
|
);
|
||||||
|
/** chat forward failure */
|
||||||
|
export const forwardFailure = createAction(
|
||||||
|
'[ucap::chat::chatting] Forward failure',
|
||||||
|
props<{ error: any }>()
|
||||||
|
);
|
||||||
|
|
||||||
|
export const forwardAfterRoomOpen = createAction(
|
||||||
|
'[ucap::chat::chatting] Forward after room open',
|
||||||
|
props<{
|
||||||
|
senderSeq: string;
|
||||||
|
req: SendRequest;
|
||||||
|
trgtUserSeqs?: string[];
|
||||||
|
trgtRoomSeq?: string;
|
||||||
|
}>()
|
||||||
|
);
|
||||||
|
|
||||||
|
export const roomOpenAfterForward = createAction(
|
||||||
|
'[ucap::chat::chatting] Room open after forward',
|
||||||
|
props<{
|
||||||
|
senderSeq: string;
|
||||||
|
req: SendRequest;
|
||||||
|
trgtUserSeqs?: string[];
|
||||||
|
trgtRoomSeq?: string;
|
||||||
|
}>()
|
||||||
|
);
|
||||||
|
|
||||||
|
/** 대화 회수 */
|
||||||
|
export const cancel = createAction(
|
||||||
|
'[ucap::chat::chatting] Cancel',
|
||||||
|
props<CancelRequest>()
|
||||||
|
);
|
||||||
|
export const cancelFailure = createAction(
|
||||||
|
'[ucap::chat::chatting] Cancel Failure',
|
||||||
|
props<{ error: any }>()
|
||||||
|
);
|
||||||
|
export const cancelNotification = createAction(
|
||||||
|
'[ucap::chat::chatting] Cancel Notification || Response',
|
||||||
|
props<{ noti: CancelNotification | CancelResponse }>()
|
||||||
|
);
|
||||||
|
/** 대화 회수시 열린 대화방의 대화 내용 갱신 */
|
||||||
|
export const updateEventList = createAction(
|
||||||
|
'[ucap::chat::chatting] Update InfoList',
|
||||||
|
props<{
|
||||||
|
roomId: string;
|
||||||
|
eventSeq: number;
|
||||||
|
sentMessage: string;
|
||||||
|
}>()
|
||||||
|
);
|
533
documents/업무/6월/1째주/backup/chat/effects.ts
Normal file
533
documents/업무/6월/1째주/backup/chat/effects.ts
Normal file
|
@ -0,0 +1,533 @@
|
||||||
|
import { of } from 'rxjs';
|
||||||
|
import {
|
||||||
|
tap,
|
||||||
|
switchMap,
|
||||||
|
map,
|
||||||
|
catchError,
|
||||||
|
exhaustMap,
|
||||||
|
concatMap,
|
||||||
|
withLatestFrom,
|
||||||
|
debounceTime,
|
||||||
|
mergeMap
|
||||||
|
} from 'rxjs/operators';
|
||||||
|
|
||||||
|
import { Injectable, Inject } from '@angular/core';
|
||||||
|
|
||||||
|
import { Store, select } from '@ngrx/store';
|
||||||
|
import { Actions, createEffect, ofType } from '@ngrx/effects';
|
||||||
|
import { Dictionary } from '@ngrx/entity';
|
||||||
|
|
||||||
|
import { EventProtocolService } from '@ucap/ng-protocol-event';
|
||||||
|
import {
|
||||||
|
RoomType,
|
||||||
|
OpenResponse as CreateResponse,
|
||||||
|
Open3Response as CreateTimerResponse,
|
||||||
|
ExitResponse as DeleteResponse,
|
||||||
|
ExitAllResponse as DeleteMultiResponse
|
||||||
|
} from '@ucap/protocol-room';
|
||||||
|
import { RoomProtocolService } from '@ucap/ng-protocol-room';
|
||||||
|
import { FileProtocolService } from '@ucap/ng-protocol-file';
|
||||||
|
|
||||||
|
import * as RoomActions from '../room/actions';
|
||||||
|
import {
|
||||||
|
events,
|
||||||
|
eventsFailure,
|
||||||
|
eventsSuccess,
|
||||||
|
read,
|
||||||
|
readFailure,
|
||||||
|
readSuccess,
|
||||||
|
fileInfos,
|
||||||
|
fileInfosFailure,
|
||||||
|
fileInfosSuccess,
|
||||||
|
send,
|
||||||
|
sendSuccess,
|
||||||
|
sendFailure,
|
||||||
|
addEvent,
|
||||||
|
addEventSuccess,
|
||||||
|
del,
|
||||||
|
delNotification,
|
||||||
|
delFailure,
|
||||||
|
delEventList,
|
||||||
|
moreEvents,
|
||||||
|
forward,
|
||||||
|
forwardFailure,
|
||||||
|
forwardAfterRoomOpen,
|
||||||
|
roomOpenAfterForward,
|
||||||
|
cancel,
|
||||||
|
cancelFailure,
|
||||||
|
cancelNotification,
|
||||||
|
updateEventList
|
||||||
|
} from './actions';
|
||||||
|
|
||||||
|
import {
|
||||||
|
InfoRequest,
|
||||||
|
ReadResponse,
|
||||||
|
FileType,
|
||||||
|
EventType,
|
||||||
|
DelResponse,
|
||||||
|
SendResponse,
|
||||||
|
CancelResponse
|
||||||
|
} from '@ucap/protocol-event';
|
||||||
|
|
||||||
|
import { ModuleConfig } from '../../config/module-config';
|
||||||
|
import { _MODULE_CONFIG } from '../../config/token';
|
||||||
|
import { Chatting } from './state';
|
||||||
|
import { ChattingSelector, RoomSelector } from '../state';
|
||||||
|
import { Router } from '@angular/router';
|
||||||
|
import { LocaleCode } from '@ucap/core';
|
||||||
|
import { LoginSelector } from '@ucap/ng-store-authentication';
|
||||||
|
import { I18nService } from '@ucap/ng-i18n';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class Effects {
|
||||||
|
events$ = createEffect(
|
||||||
|
() => {
|
||||||
|
return this.actions$.pipe(
|
||||||
|
ofType(events),
|
||||||
|
map((action) => action.req),
|
||||||
|
switchMap((req) => {
|
||||||
|
return this.eventProtocolService.info(req).pipe(
|
||||||
|
map((res) => {
|
||||||
|
if (!!res && !!res.res) {
|
||||||
|
const infoList = res.infoList;
|
||||||
|
|
||||||
|
this.store.dispatch(
|
||||||
|
eventsSuccess({
|
||||||
|
eventInfoList: infoList,
|
||||||
|
res: res.res,
|
||||||
|
remainEvent:
|
||||||
|
infoList.length === req.requestCount ? true : false
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
if (req.baseSeq === 0) {
|
||||||
|
// 최초 이벤트 목록 조회.
|
||||||
|
|
||||||
|
// SSVC_TYPE_EVENT_READ_REQ 수행.
|
||||||
|
const maxSeq = Math.max.apply(
|
||||||
|
Math,
|
||||||
|
infoList.map((v) => v.seq)
|
||||||
|
);
|
||||||
|
this.store.dispatch(
|
||||||
|
read({
|
||||||
|
roomId: req.roomId,
|
||||||
|
lastReadSeq: Number(maxSeq)
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
// File 정보 수집.
|
||||||
|
this.store.dispatch(
|
||||||
|
fileInfos({
|
||||||
|
req: {
|
||||||
|
roomId: res.res.roomId,
|
||||||
|
// { 파일타입 } cf) I : 이미지 V: 동영상 F: 파일 "" 빈값이면 모든 타입을 내려줌
|
||||||
|
type: FileType.All
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
catchError((error) =>
|
||||||
|
of(eventsFailure({ roomId: req.roomId, error }))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
},
|
||||||
|
{ dispatch: false }
|
||||||
|
);
|
||||||
|
|
||||||
|
moreEvents$ = createEffect(
|
||||||
|
() => {
|
||||||
|
return this.actions$.pipe(
|
||||||
|
ofType(moreEvents),
|
||||||
|
mergeMap(
|
||||||
|
(action) =>
|
||||||
|
of(action).pipe(
|
||||||
|
withLatestFrom(
|
||||||
|
this.store.pipe(
|
||||||
|
select(ChattingSelector.eventList, action.roomId)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
(action, latestStoreData) => latestStoreData
|
||||||
|
),
|
||||||
|
tap(([req, eventList]) => {
|
||||||
|
if (!!eventList && eventList.length > 0) {
|
||||||
|
this.store.dispatch(
|
||||||
|
events({
|
||||||
|
req: {
|
||||||
|
roomId: req.roomId,
|
||||||
|
baseSeq: eventList.sort((a, b) => a.seq - b.seq)[0].seq,
|
||||||
|
requestCount:
|
||||||
|
this.moduleConfig?.eventRequestDefaultCount || 50
|
||||||
|
} as InfoRequest
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
},
|
||||||
|
{ dispatch: false }
|
||||||
|
);
|
||||||
|
|
||||||
|
read$ = createEffect(
|
||||||
|
() => {
|
||||||
|
return this.actions$.pipe(
|
||||||
|
ofType(read),
|
||||||
|
exhaustMap((req) =>
|
||||||
|
this.eventProtocolService.read(req).pipe(
|
||||||
|
map((res: ReadResponse) => {
|
||||||
|
// room user lastReadEventSeq reset.
|
||||||
|
this.store.dispatch(readSuccess(res));
|
||||||
|
// room noReadCount reset.
|
||||||
|
this.store.dispatch(
|
||||||
|
RoomActions.updateUnreadCount({
|
||||||
|
roomId: res.roomId
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
catchError((error) => of(readFailure({ error })))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
},
|
||||||
|
{ dispatch: false }
|
||||||
|
);
|
||||||
|
|
||||||
|
fileInfos$ = createEffect(
|
||||||
|
() => {
|
||||||
|
return this.actions$.pipe(
|
||||||
|
ofType(fileInfos),
|
||||||
|
switchMap((action) => {
|
||||||
|
return this.fileProtocolService.info(action.req).pipe(
|
||||||
|
map((res) => {
|
||||||
|
this.store.dispatch(
|
||||||
|
fileInfosSuccess({
|
||||||
|
fileInfoList: res.fileInfos,
|
||||||
|
fileInfoCheckList: res.fileInfoChecks,
|
||||||
|
res: res.res
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
catchError((error) =>
|
||||||
|
of(fileInfosFailure({ roomId: action.req.roomId, error }))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
},
|
||||||
|
{ dispatch: false }
|
||||||
|
);
|
||||||
|
|
||||||
|
addEvent$ = createEffect(
|
||||||
|
() => {
|
||||||
|
return this.actions$.pipe(
|
||||||
|
ofType(addEvent),
|
||||||
|
withLatestFrom(
|
||||||
|
this.store.pipe(
|
||||||
|
select(
|
||||||
|
(state: any) =>
|
||||||
|
state.chat.chatting.chattings.entities as Dictionary<Chatting>
|
||||||
|
)
|
||||||
|
),
|
||||||
|
this.store.pipe(
|
||||||
|
select((state: any) => state.chat.chatting.activeRoomId)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
tap(([action, chattings, activeRoomId]) => {
|
||||||
|
// Room in chattings state >> event add
|
||||||
|
if (!!chattings && !!chattings[action.roomId]) {
|
||||||
|
if (action.info.type === EventType.File) {
|
||||||
|
// Retrieve event of FileType in rooms
|
||||||
|
this.store.dispatch(
|
||||||
|
fileInfos({
|
||||||
|
req: {
|
||||||
|
roomId: action.roomId,
|
||||||
|
type: FileType.All
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// room > rooms :: finalEvent-Infos refresh
|
||||||
|
this.store.dispatch(
|
||||||
|
addEventSuccess({
|
||||||
|
roomId: action.roomId,
|
||||||
|
info: action.info
|
||||||
|
})
|
||||||
|
);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
},
|
||||||
|
{ dispatch: false }
|
||||||
|
);
|
||||||
|
|
||||||
|
send$ = createEffect(() =>
|
||||||
|
this.actions$.pipe(
|
||||||
|
ofType(send),
|
||||||
|
concatMap((action) =>
|
||||||
|
this.eventProtocolService.send(action.req).pipe(
|
||||||
|
map((res) => {
|
||||||
|
return sendSuccess({
|
||||||
|
senderSeq: action.senderSeq,
|
||||||
|
res
|
||||||
|
});
|
||||||
|
}),
|
||||||
|
catchError((error) => of(sendFailure({ error })))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
sendSuccess$ = createEffect(
|
||||||
|
() => {
|
||||||
|
return this.actions$.pipe(
|
||||||
|
ofType(sendSuccess),
|
||||||
|
tap((action) => {
|
||||||
|
const res = action.res;
|
||||||
|
|
||||||
|
this.store.dispatch(
|
||||||
|
addEvent({
|
||||||
|
roomId: res.roomId,
|
||||||
|
info: res.info,
|
||||||
|
SVC_TYPE: res.SVC_TYPE,
|
||||||
|
SSVC_TYPE: res.SSVC_TYPE
|
||||||
|
})
|
||||||
|
);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
},
|
||||||
|
{ dispatch: false }
|
||||||
|
);
|
||||||
|
|
||||||
|
/*******************************************************************
|
||||||
|
* [Room Action watching.]
|
||||||
|
*******************************************************************/
|
||||||
|
selectedRoomSuccess$ = createEffect(
|
||||||
|
() => {
|
||||||
|
return this.actions$.pipe(
|
||||||
|
ofType(RoomActions.selectedRoomSuccess),
|
||||||
|
debounceTime(300),
|
||||||
|
tap((action) => {
|
||||||
|
const requestCount = this.moduleConfig?.eventRequestInitCount || 50;
|
||||||
|
const req: InfoRequest = {
|
||||||
|
roomId: action.roomId,
|
||||||
|
baseSeq: 0,
|
||||||
|
requestCount
|
||||||
|
};
|
||||||
|
|
||||||
|
this.store.dispatch(events({ req }));
|
||||||
|
})
|
||||||
|
);
|
||||||
|
},
|
||||||
|
{ dispatch: false }
|
||||||
|
);
|
||||||
|
|
||||||
|
del$ = createEffect(() =>
|
||||||
|
this.actions$.pipe(
|
||||||
|
ofType(del),
|
||||||
|
exhaustMap((req) =>
|
||||||
|
this.eventProtocolService.del(req).pipe(
|
||||||
|
map((res: DelResponse) => {
|
||||||
|
return delNotification({ noti: res });
|
||||||
|
}),
|
||||||
|
catchError((error) => of(delFailure({ error })))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
delNotification$ = createEffect(
|
||||||
|
() => {
|
||||||
|
return this.actions$.pipe(
|
||||||
|
ofType(delNotification),
|
||||||
|
map((action) => action.noti),
|
||||||
|
withLatestFrom(this.store.pipe(select(ChattingSelector.activeRoomId))),
|
||||||
|
tap(([noti, activeRoomId]) => {
|
||||||
|
// 현재 방이 오픈되어 있으면 방내용 갱신
|
||||||
|
const roomId = noti.roomId;
|
||||||
|
|
||||||
|
if (!!activeRoomId && activeRoomId === roomId) {
|
||||||
|
this.store.dispatch(
|
||||||
|
delEventList({ roomId, eventSeqs: [noti.eventSeq] })
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 대화 > 리스트의 항목 갱신
|
||||||
|
this.store.dispatch(
|
||||||
|
RoomActions.room({
|
||||||
|
req: {
|
||||||
|
roomId: noti.roomId,
|
||||||
|
isDetail: false,
|
||||||
|
localeCode: this.i18nService.currentLng.toUpperCase() as LocaleCode
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
},
|
||||||
|
{ dispatch: false }
|
||||||
|
);
|
||||||
|
|
||||||
|
forward$ = createEffect(
|
||||||
|
() => {
|
||||||
|
return this.actions$.pipe(
|
||||||
|
ofType(forward),
|
||||||
|
tap((action) => {
|
||||||
|
if (!!action.trgtRoomSeq) {
|
||||||
|
// 대화전달 후 방오픈. Exist roomSeq.
|
||||||
|
if (action.req.eventType === EventType.File) {
|
||||||
|
// file share request action
|
||||||
|
} else {
|
||||||
|
this.store.dispatch(roomOpenAfterForward(action));
|
||||||
|
}
|
||||||
|
} else if (!!action.trgtUserSeqs && action.trgtUserSeqs.length > 0) {
|
||||||
|
// 방오픈 후 대화전달.
|
||||||
|
this.store.dispatch(forwardAfterRoomOpen(action));
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
},
|
||||||
|
{ dispatch: false }
|
||||||
|
);
|
||||||
|
|
||||||
|
forwardAfterRoomOpen$ = createEffect(
|
||||||
|
() => {
|
||||||
|
let createRes: CreateResponse;
|
||||||
|
return this.actions$.pipe(
|
||||||
|
ofType(forwardAfterRoomOpen),
|
||||||
|
exhaustMap((actionReq) => {
|
||||||
|
return this.roomProtocolService
|
||||||
|
.open({ divCd: 'forwardOpen', userSeqs: actionReq.trgtUserSeqs })
|
||||||
|
.pipe(
|
||||||
|
map((res: CreateResponse) => {
|
||||||
|
createRes = res;
|
||||||
|
this.store.dispatch(RoomActions.createSuccess({ res }));
|
||||||
|
}),
|
||||||
|
map(() => {
|
||||||
|
if (actionReq.req.eventType === EventType.File) {
|
||||||
|
// file share request action
|
||||||
|
} else {
|
||||||
|
this.store.dispatch(
|
||||||
|
send({
|
||||||
|
senderSeq: actionReq.senderSeq,
|
||||||
|
req: {
|
||||||
|
roomId: createRes.roomId,
|
||||||
|
eventType: actionReq.req.eventType,
|
||||||
|
sentMessage: actionReq.req.sentMessage
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
catchError((error) => of(RoomActions.createFailure({ error })))
|
||||||
|
);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
},
|
||||||
|
{ dispatch: false }
|
||||||
|
);
|
||||||
|
|
||||||
|
roomOpenAfterForward$ = createEffect(
|
||||||
|
() => {
|
||||||
|
return this.actions$.pipe(
|
||||||
|
ofType(roomOpenAfterForward),
|
||||||
|
exhaustMap((action) => {
|
||||||
|
return this.eventProtocolService
|
||||||
|
.send({
|
||||||
|
roomId: action.trgtRoomSeq,
|
||||||
|
eventType: action.req.eventType,
|
||||||
|
sentMessage: action.req.sentMessage
|
||||||
|
})
|
||||||
|
.pipe(
|
||||||
|
map((res: SendResponse) => {
|
||||||
|
this.store.dispatch(
|
||||||
|
addEvent({
|
||||||
|
roomId: res.roomId,
|
||||||
|
info: res.info,
|
||||||
|
SVC_TYPE: res.SVC_TYPE,
|
||||||
|
SSVC_TYPE: res.SSVC_TYPE
|
||||||
|
})
|
||||||
|
);
|
||||||
|
this.store.dispatch(
|
||||||
|
RoomActions.selectedRoom({
|
||||||
|
roomId: res.roomId,
|
||||||
|
localeCode: this.i18nService.currentLng.toUpperCase() as LocaleCode
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
catchError((error) => of(RoomActions.createFailure({ error })))
|
||||||
|
);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
},
|
||||||
|
{ dispatch: false }
|
||||||
|
);
|
||||||
|
|
||||||
|
cancel$ = createEffect(() =>
|
||||||
|
this.actions$.pipe(
|
||||||
|
ofType(cancel),
|
||||||
|
exhaustMap((req) =>
|
||||||
|
this.eventProtocolService.cancel(req).pipe(
|
||||||
|
map((res: CancelResponse) => {
|
||||||
|
return delNotification({ noti: res });
|
||||||
|
}),
|
||||||
|
catchError((error) => of(delFailure({ error })))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
cancelNotification$ = createEffect(
|
||||||
|
() => {
|
||||||
|
return this.actions$.pipe(
|
||||||
|
ofType(cancelNotification),
|
||||||
|
withLatestFrom(this.store.pipe(select(ChattingSelector.activeRoomId))),
|
||||||
|
tap(([action, activeRoomId]) => {
|
||||||
|
// 현재 방이 오픈되어 있으면 방내용 갱신
|
||||||
|
if (
|
||||||
|
!!activeRoomId &&
|
||||||
|
activeRoomId.localeCompare(action.noti.roomId) === 0
|
||||||
|
) {
|
||||||
|
this.store.dispatch(
|
||||||
|
updateEventList({
|
||||||
|
roomId: action.noti.roomId,
|
||||||
|
eventSeq: action.noti.eventSeq,
|
||||||
|
sentMessage: this.i18nService.t('event.recalled')
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 대화 > 리스트의 항목 갱신
|
||||||
|
this.store.dispatch(
|
||||||
|
RoomActions.room({
|
||||||
|
req: {
|
||||||
|
roomId: action.noti.roomId,
|
||||||
|
isDetail: false,
|
||||||
|
localeCode: this.i18nService.currentLng.toUpperCase() as LocaleCode
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
},
|
||||||
|
{ dispatch: false }
|
||||||
|
);
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private actions$: Actions,
|
||||||
|
private store: Store<any>,
|
||||||
|
private router: Router,
|
||||||
|
@Inject(_MODULE_CONFIG) private moduleConfig: ModuleConfig,
|
||||||
|
private roomProtocolService: RoomProtocolService,
|
||||||
|
private eventProtocolService: EventProtocolService,
|
||||||
|
private fileProtocolService: FileProtocolService,
|
||||||
|
private i18nService: I18nService
|
||||||
|
) {
|
||||||
|
this.i18nService.setDefaultNamespace('chat');
|
||||||
|
}
|
||||||
|
}
|
253
documents/업무/6월/1째주/backup/chat/reducers.ts
Normal file
253
documents/업무/6월/1째주/backup/chat/reducers.ts
Normal file
|
@ -0,0 +1,253 @@
|
||||||
|
import { createReducer, on } from '@ngrx/store';
|
||||||
|
|
||||||
|
import {
|
||||||
|
initialState,
|
||||||
|
adapterChatting,
|
||||||
|
adapterEventList,
|
||||||
|
Chatting,
|
||||||
|
adapterFileInfoList,
|
||||||
|
adapterFileInfoCheckList
|
||||||
|
} from './state';
|
||||||
|
|
||||||
|
import * as RoomActions from '../room/actions';
|
||||||
|
import {
|
||||||
|
eventsSuccess,
|
||||||
|
eventsFailure,
|
||||||
|
fileInfosSuccess,
|
||||||
|
fileInfosFailure,
|
||||||
|
addEvent,
|
||||||
|
delEventList,
|
||||||
|
updateEventList
|
||||||
|
} from './actions';
|
||||||
|
import { Info, EventJson, EventType } from '@ucap/protocol-event';
|
||||||
|
|
||||||
|
export const reducer = createReducer(
|
||||||
|
initialState,
|
||||||
|
|
||||||
|
on(eventsSuccess, (state, action) => {
|
||||||
|
const roomId = action.res.roomId;
|
||||||
|
|
||||||
|
const chatting = state.chattings.entities[roomId] || {};
|
||||||
|
let trgtChatting: Chatting = {
|
||||||
|
roomId,
|
||||||
|
|
||||||
|
eventListProcessing: false,
|
||||||
|
eventList: adapterEventList.getInitialState(),
|
||||||
|
eventStatus: null,
|
||||||
|
remainEvent: false,
|
||||||
|
|
||||||
|
fileInfoListProcessing: false,
|
||||||
|
fileInfoList: adapterFileInfoList.getInitialState(),
|
||||||
|
fileInfoCheckList: adapterFileInfoCheckList.getInitialState(),
|
||||||
|
fileInfoSyncDate: '',
|
||||||
|
...chatting
|
||||||
|
};
|
||||||
|
|
||||||
|
trgtChatting = {
|
||||||
|
...trgtChatting,
|
||||||
|
eventList: adapterEventList.upsertMany(action.eventInfoList, {
|
||||||
|
...trgtChatting.eventList
|
||||||
|
}),
|
||||||
|
eventStatus: action.res,
|
||||||
|
remainEvent: action.remainEvent,
|
||||||
|
eventListProcessing: false
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
chattings: adapterChatting.upsertOne(trgtChatting, {
|
||||||
|
...state.chattings
|
||||||
|
})
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
|
||||||
|
on(eventsFailure, (state, action) => {
|
||||||
|
const roomId = action.roomId;
|
||||||
|
|
||||||
|
const chatting = state.chattings.entities[roomId];
|
||||||
|
let trgtChatting: Chatting;
|
||||||
|
if (!!chatting) {
|
||||||
|
trgtChatting = {
|
||||||
|
...chatting,
|
||||||
|
eventListProcessing: false
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
chattings: adapterChatting.upsertOne(trgtChatting, {
|
||||||
|
...state.chattings
|
||||||
|
})
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
|
||||||
|
on(fileInfosSuccess, (state, action) => {
|
||||||
|
const roomId = action.res?.roomId;
|
||||||
|
|
||||||
|
if (!roomId) {
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
const chatting = state.chattings.entities[roomId] || {};
|
||||||
|
let trgtChatting: Chatting = {
|
||||||
|
roomId,
|
||||||
|
|
||||||
|
eventListProcessing: false,
|
||||||
|
eventList: adapterEventList.getInitialState(),
|
||||||
|
eventStatus: null,
|
||||||
|
remainEvent: false,
|
||||||
|
|
||||||
|
fileInfoListProcessing: false,
|
||||||
|
fileInfoList: adapterFileInfoList.getInitialState(),
|
||||||
|
fileInfoCheckList: adapterFileInfoCheckList.getInitialState(),
|
||||||
|
fileInfoSyncDate: '',
|
||||||
|
...chatting
|
||||||
|
};
|
||||||
|
|
||||||
|
const fileInfoList = action.fileInfoList;
|
||||||
|
const fileInfoCheckList = action.fileInfoCheckList;
|
||||||
|
|
||||||
|
trgtChatting = {
|
||||||
|
...trgtChatting,
|
||||||
|
fileInfoList: !!fileInfoList
|
||||||
|
? adapterFileInfoList.upsertMany(fileInfoList, {
|
||||||
|
...trgtChatting.fileInfoList
|
||||||
|
})
|
||||||
|
: trgtChatting.fileInfoList,
|
||||||
|
fileInfoCheckList: !!fileInfoCheckList
|
||||||
|
? adapterFileInfoCheckList.upsertMany(fileInfoCheckList, {
|
||||||
|
...trgtChatting.fileInfoCheckList
|
||||||
|
})
|
||||||
|
: trgtChatting.fileInfoCheckList,
|
||||||
|
fileInfoListProcessing: false
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
chattings: adapterChatting.upsertOne(trgtChatting, {
|
||||||
|
...state.chattings
|
||||||
|
})
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
|
||||||
|
on(fileInfosFailure, (state, action) => {
|
||||||
|
const roomId = action.roomId;
|
||||||
|
|
||||||
|
const chatting = state.chattings.entities[roomId];
|
||||||
|
let trgtChatting: Chatting;
|
||||||
|
if (!!chatting) {
|
||||||
|
trgtChatting = {
|
||||||
|
...chatting,
|
||||||
|
fileInfoListProcessing: false
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
chattings: adapterChatting.upsertOne(trgtChatting, {
|
||||||
|
...state.chattings
|
||||||
|
})
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
|
||||||
|
on(addEvent, (state, action) => {
|
||||||
|
const roomId = action.roomId;
|
||||||
|
const eventInfo = action.info;
|
||||||
|
|
||||||
|
const chatting = state.chattings.entities[roomId];
|
||||||
|
|
||||||
|
if (!!chatting) {
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
chattings: adapterChatting.upsertOne(
|
||||||
|
{
|
||||||
|
...chatting,
|
||||||
|
eventList: adapterEventList.upsertOne(eventInfo, {
|
||||||
|
...chatting.eventList
|
||||||
|
})
|
||||||
|
},
|
||||||
|
{ ...state.chattings }
|
||||||
|
)
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
|
||||||
|
/*******************************************************************
|
||||||
|
* [Room Action watching.]
|
||||||
|
*******************************************************************/
|
||||||
|
on(RoomActions.selectedRoomSuccess, (state, action) => {
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
activeRoomId: action.roomId
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
|
||||||
|
on(RoomActions.clearSelectedRoom, (state, action) => {
|
||||||
|
if (action.roomId === state.activeRoomId) {
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
activeRoomId: null
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
|
||||||
|
on(RoomActions.close, (state, action) => {
|
||||||
|
const roomIds = action.roomIds;
|
||||||
|
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
chattings: adapterChatting.removeMany(roomIds, { ...state.chattings })
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
|
||||||
|
on(delEventList, (state, action) => {
|
||||||
|
const roomId = action.roomId;
|
||||||
|
const chatting = state.chattings.entities[roomId];
|
||||||
|
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
chattings: adapterChatting.upsertOne(
|
||||||
|
{
|
||||||
|
...chatting,
|
||||||
|
eventList: adapterEventList.removeMany(action.eventSeqs, {
|
||||||
|
...chatting.eventList
|
||||||
|
})
|
||||||
|
},
|
||||||
|
{ ...state.chattings }
|
||||||
|
)
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
|
||||||
|
on(updateEventList, (state, action) => {
|
||||||
|
const roomId = action.roomId;
|
||||||
|
const eventSeq = action.eventSeq;
|
||||||
|
const sentMessage = action.sentMessage;
|
||||||
|
const chatting = state.chattings.entities[roomId];
|
||||||
|
|
||||||
|
const statusEventInfo: Info<EventJson> = {
|
||||||
|
...chatting.eventList[eventSeq],
|
||||||
|
type: EventType.RecalledMessage,
|
||||||
|
sentMessage
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
chattings: adapterChatting.upsertOne(
|
||||||
|
{
|
||||||
|
...chatting,
|
||||||
|
eventList: adapterEventList.updateOne(
|
||||||
|
{ id: eventSeq, changes: statusEventInfo },
|
||||||
|
{
|
||||||
|
...chatting.eventList
|
||||||
|
}
|
||||||
|
)
|
||||||
|
},
|
||||||
|
{ ...state.chattings }
|
||||||
|
)
|
||||||
|
};
|
||||||
|
})
|
||||||
|
);
|
93
documents/업무/6월/1째주/backup/etc/forward.dialog.component.html
Normal file
93
documents/업무/6월/1째주/backup/etc/forward.dialog.component.html
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
<div class="dialog-container">
|
||||||
|
<app-layouts-default-dialog
|
||||||
|
[disableClose]="false"
|
||||||
|
(closed)="onClosed($event)"
|
||||||
|
>
|
||||||
|
<div appLayoutsDefaultDialog="header">
|
||||||
|
{{ 'dialog.title.newChatRoom' | ucapI18n }}
|
||||||
|
</div>
|
||||||
|
<div class="dialog-body" appLayoutsDefaultDialog="body">
|
||||||
|
<!-- search start-->
|
||||||
|
<div>
|
||||||
|
<app-organization-search-for-tenant
|
||||||
|
placeholder="이름 부서명, 전화번호, 이메일"
|
||||||
|
[(searchData)]="companySearchData"
|
||||||
|
(canceled)="onCanceled()"
|
||||||
|
class="select-user-section-search"
|
||||||
|
>
|
||||||
|
</app-organization-search-for-tenant>
|
||||||
|
</div>
|
||||||
|
<!-- search end-->
|
||||||
|
<div *ngIf="!isSearch">
|
||||||
|
<mat-tab-group mat-stretch-tabs class="tap-container tab_num2">
|
||||||
|
<!--그룹-->
|
||||||
|
<mat-tab>
|
||||||
|
<ng-template mat-tab-label>
|
||||||
|
<!-- <button class="icon-button">
|
||||||
|
<i class="mid mid-24 mdi-account-multiple"></i>
|
||||||
|
</button> -->
|
||||||
|
<p>그룹</p>
|
||||||
|
</ng-template>
|
||||||
|
<div fxFlexFill class="select-tap">
|
||||||
|
<app-group-expansion
|
||||||
|
fxFlexFill
|
||||||
|
[isDialog]="isDialog"
|
||||||
|
[selectedUserList]="selectedUserList"
|
||||||
|
[fixedUserList]="fixedUserList"
|
||||||
|
[checkable]="checkable"
|
||||||
|
(toggleCheckUser)="onToggleCheckUser($event)"
|
||||||
|
(toggleCheckGroup)="onToggleCheckGroup($event)"
|
||||||
|
class="select-user-tap-group-expansion"
|
||||||
|
></app-group-expansion>
|
||||||
|
</div>
|
||||||
|
</mat-tab>
|
||||||
|
<!--대화방 리스트-->
|
||||||
|
<ng-template mat-tab-label>
|
||||||
|
<p>대화방 리스트</p>
|
||||||
|
</ng-template>
|
||||||
|
<div fxFlexFill class="select-tap">
|
||||||
|
<div class="roomList" *ngFor="let room of roomList">
|
||||||
|
<ucap-chat-room-list-item-01
|
||||||
|
[roomInfo]="node.roomInfo"
|
||||||
|
[roomName]="getRoomName(node.roomInfo)"
|
||||||
|
[profileImageRoot]="versionInfo2Res?.profileRoot"
|
||||||
|
[defaultProfileImage]="defaultProfileImage"
|
||||||
|
[profileImage]="getRoomProfileImage(node.roomInfo)"
|
||||||
|
[checkable]="true"
|
||||||
|
(toggleItem)="onToggleItem($event)"
|
||||||
|
></ucap-chat-room-list-item-01>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<mat-tab>
|
||||||
|
</mat-tab>
|
||||||
|
</mat-tab-group>
|
||||||
|
</div>
|
||||||
|
<div *ngIf="!!isSearch"></div>
|
||||||
|
<app-group-profile-list
|
||||||
|
[searchData]="companySearchData"
|
||||||
|
[selectedUser]="selectedUserList"
|
||||||
|
[checkable]="checkable"
|
||||||
|
[isDialog]="isDialog"
|
||||||
|
(toggleCheck)="onToggleCheckUser($event)"
|
||||||
|
></app-group-profile-list>
|
||||||
|
</div>
|
||||||
|
<div appLayoutsDefaultDialog="action">
|
||||||
|
<button mat-button (click)="onCancel()">
|
||||||
|
{{
|
||||||
|
(stepper.selectedIndex === 0
|
||||||
|
? 'dialog.button.cancel'
|
||||||
|
: 'dialog.button.previous'
|
||||||
|
) | ucapI18n
|
||||||
|
}}
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
mat-button
|
||||||
|
*ngIf="stepper.selectedIndex === 0"
|
||||||
|
(click)="onConfirm()"
|
||||||
|
>
|
||||||
|
{{ 'dialog.button.selectRoomUser' | ucapI18n }}
|
||||||
|
</button>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</app-layouts-default-dialog>
|
||||||
|
</div>
|
|
@ -0,0 +1,9 @@
|
||||||
|
.dialog-container {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
.dialog-body {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
import { By } from '@angular/platform-browser';
|
||||||
|
import { DebugElement } from '@angular/core';
|
||||||
|
|
||||||
|
import { ForwardDialogComponent } from './forward.dialog.component';
|
||||||
|
|
||||||
|
describe('app::ui-chat::ForwardDialogComponent', () => {
|
||||||
|
let component: ForwardDialogComponent;
|
||||||
|
let fixture: ComponentFixture<ForwardDialogComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ForwardDialogComponent]
|
||||||
|
}).compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(ForwardDialogComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
123
documents/업무/6월/1째주/backup/etc/forward.dialog.component.ts
Normal file
123
documents/업무/6월/1째주/backup/etc/forward.dialog.component.ts
Normal file
|
@ -0,0 +1,123 @@
|
||||||
|
import { Subject } from 'rxjs';
|
||||||
|
|
||||||
|
import {
|
||||||
|
Component,
|
||||||
|
OnInit,
|
||||||
|
OnDestroy,
|
||||||
|
ChangeDetectionStrategy,
|
||||||
|
ChangeDetectorRef,
|
||||||
|
Inject,
|
||||||
|
Input
|
||||||
|
} from '@angular/core';
|
||||||
|
|
||||||
|
import {
|
||||||
|
MatDialogRef,
|
||||||
|
MAT_DIALOG_DATA,
|
||||||
|
MatDialog
|
||||||
|
} from '@angular/material/dialog';
|
||||||
|
|
||||||
|
import { UserInfo, GroupDetailData } from '@ucap/protocol-sync';
|
||||||
|
import { UserInfoSS, UserInfoF, UserInfoDN } from '@ucap/protocol-query';
|
||||||
|
import { UserInfo as RoomUserInfo } from '@ucap/protocol-room';
|
||||||
|
import { MatStepper } from '@angular/material/stepper';
|
||||||
|
import { I18nService } from '@ucap/ng-i18n';
|
||||||
|
import { GroupActions } from '@ucap/ng-store-group';
|
||||||
|
import {
|
||||||
|
AlertDialogComponent,
|
||||||
|
AlertDialogData,
|
||||||
|
AlertDialogResult
|
||||||
|
} from '@ucap/ng-ui';
|
||||||
|
import { environment } from '@environments';
|
||||||
|
|
||||||
|
export type UserInfoTypes =
|
||||||
|
| UserInfo
|
||||||
|
| UserInfoSS
|
||||||
|
| UserInfoF
|
||||||
|
| UserInfoDN
|
||||||
|
| RoomUserInfo;
|
||||||
|
|
||||||
|
export interface ForwardDialogData {}
|
||||||
|
export interface ForwardDialogResult {
|
||||||
|
userSeqs: string[];
|
||||||
|
isTimer: boolean | undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-dialog-chat-forward',
|
||||||
|
templateUrl: './forward.dialog.component.html',
|
||||||
|
styleUrls: ['./forward.dialog.component.scss'],
|
||||||
|
changeDetection: ChangeDetectionStrategy.OnPush
|
||||||
|
})
|
||||||
|
export class ForwardDialogComponent implements OnInit, OnDestroy {
|
||||||
|
currentStep = 0;
|
||||||
|
maxChatRoomUser: number;
|
||||||
|
|
||||||
|
isTimer: boolean | undefined;
|
||||||
|
selectedUserList: UserInfoTypes[] = [];
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
public dialogRef: MatDialogRef<ForwardDialogData, ForwardDialogResult>,
|
||||||
|
@Inject(MAT_DIALOG_DATA) public data: ForwardDialogData,
|
||||||
|
private i18nService: I18nService,
|
||||||
|
public dialog: MatDialog,
|
||||||
|
private changeDetectorRef: ChangeDetectorRef
|
||||||
|
) {
|
||||||
|
this.maxChatRoomUser = environment.productConfig.chat.maxChatRoomUser;
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit(): void {}
|
||||||
|
|
||||||
|
ngOnDestroy(): void {}
|
||||||
|
|
||||||
|
onClosed(event: MouseEvent): void {
|
||||||
|
this.dialogRef.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
onCancel() {
|
||||||
|
|
||||||
|
}
|
||||||
|
onConfirm() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
onChangeUserList(data: { checked: boolean; userInfo: UserInfoSS }) {
|
||||||
|
const i = this.selectedUserList.findIndex(
|
||||||
|
(u) => u.seq === data.userInfo.seq
|
||||||
|
);
|
||||||
|
|
||||||
|
if (data.checked) {
|
||||||
|
if (-1 === i) {
|
||||||
|
this.selectedUserList = [...this.selectedUserList, data.userInfo];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (-1 < i) {
|
||||||
|
this.selectedUserList = this.selectedUserList.filter(
|
||||||
|
(u) => u.seq !== data.userInfo.seq
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onChangeGroupList(params: {
|
||||||
|
isChecked: boolean;
|
||||||
|
groupBuddyList: { group: GroupDetailData; buddyList: UserInfo[] };
|
||||||
|
}) {
|
||||||
|
if (params.isChecked) {
|
||||||
|
params.groupBuddyList.buddyList.forEach((item) => {
|
||||||
|
if (
|
||||||
|
this.selectedUserList.filter((user) => user.seq === item.seq)
|
||||||
|
.length === 0
|
||||||
|
) {
|
||||||
|
this.selectedUserList = [...this.selectedUserList, item];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.selectedUserList = this.selectedUserList.filter(
|
||||||
|
(item) =>
|
||||||
|
params.groupBuddyList.buddyList.filter((del) => del.seq === item.seq)
|
||||||
|
.length === 0
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
<div class="ucap-chat-room-list-item2">
|
||||||
|
<div class="ucap-chat-room-list-item2-profile-image">
|
||||||
|
<div class="profile-image">
|
||||||
|
<img
|
||||||
|
ucapImage
|
||||||
|
[base]="profileImageRoot"
|
||||||
|
[path]="profileImage"
|
||||||
|
[default]="defaultProfileImage"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="ucap-chat-room-list-item2-info">
|
||||||
|
<div class="roomName">
|
||||||
|
<div class="chat-subject">{{ roomName }}</div>
|
||||||
|
<div *ngIf="roomInfo.roomType === RoomType.Multi" class="chat-amount">
|
||||||
|
<strong>({{ roomInfo.joinUserCount }})</strong>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="lastMessage">{{ roomInfo.finalEventMessage }}</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<mat-checkbox
|
||||||
|
*ngIf="checkable"
|
||||||
|
#checkbox
|
||||||
|
[checked]="checked"
|
||||||
|
(change)="onToggleItem(checkbox.checked)"
|
||||||
|
(click)="$event.stopPropagation()"
|
||||||
|
class="group-check"
|
||||||
|
>
|
||||||
|
</mat-checkbox>
|
||||||
|
</div>
|
|
@ -0,0 +1,34 @@
|
||||||
|
.ucap-chat-room-list-item2 {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-content: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
|
||||||
|
.ucap-chat-room-list-item2-profile-image {
|
||||||
|
display: inline-flex;
|
||||||
|
position: relative;
|
||||||
|
align-self: center;
|
||||||
|
}
|
||||||
|
.ucap-chat-room-list-item2-info {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
.roomName {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
.ico-chat-list {
|
||||||
|
.ico-off {
|
||||||
|
&-false {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
&-true {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { RoomListItem02Component } from './room-list-item-02.component';
|
||||||
|
|
||||||
|
describe('ucap::chat::RoomListItem01Component', () => {
|
||||||
|
let component: RoomListItem02Component;
|
||||||
|
let fixture: ComponentFixture<RoomListItem02Component>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [RoomListItem02Component]
|
||||||
|
}).compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(RoomListItem02Component);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,26 @@
|
||||||
|
import { moduleMetadata } from '@storybook/angular';
|
||||||
|
import { action } from '@storybook/addon-actions';
|
||||||
|
import { linkTo } from '@storybook/addon-links';
|
||||||
|
|
||||||
|
import { BrowserModule } from '@angular/platform-browser';
|
||||||
|
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||||
|
|
||||||
|
import { ChatUiModule } from '../chat-ui.module';
|
||||||
|
|
||||||
|
import { RoomListItem02Component } from './room-list-item-02.component';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
title: 'ui-chat::RoomListItem02Component',
|
||||||
|
component: RoomListItem02Component,
|
||||||
|
decorators: [
|
||||||
|
moduleMetadata({
|
||||||
|
imports: [BrowserModule, BrowserAnimationsModule, ChatUiModule],
|
||||||
|
providers: []
|
||||||
|
})
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Default = () => ({
|
||||||
|
component: RoomListItem02Component,
|
||||||
|
props: {}
|
||||||
|
});
|
|
@ -0,0 +1,20 @@
|
||||||
|
@import '~@ucap/ng-ui-material/material';
|
||||||
|
|
||||||
|
@mixin ucap-chat-room-list-item-02-theme($theme) {
|
||||||
|
$is-dark-theme: map-get($theme, is-dark);
|
||||||
|
$primary: map-get($theme, primary);
|
||||||
|
$accent: map-get($theme, accent);
|
||||||
|
$warn: map-get($theme, warn);
|
||||||
|
$background: map-get($theme, background);
|
||||||
|
$foreground: map-get($theme, foreground);
|
||||||
|
|
||||||
|
.ucap-chat-room-list-item-02-container {
|
||||||
|
border-color: mat-color($foreground, secondary-text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin ucap-chat-room-list-item-02-typography($config) {
|
||||||
|
.ucap-chat-room-list-item-01-container {
|
||||||
|
font-family: mat-font-family($config);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
import {
|
||||||
|
Component,
|
||||||
|
OnInit,
|
||||||
|
ChangeDetectionStrategy,
|
||||||
|
Input,
|
||||||
|
OnDestroy,
|
||||||
|
EventEmitter,
|
||||||
|
Output,
|
||||||
|
ChangeDetectorRef
|
||||||
|
} from '@angular/core';
|
||||||
|
import { RoomInfo, RoomType } from '@ucap/protocol-room';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'ucap-chat-room-list-item-02',
|
||||||
|
templateUrl: './room-list-item-02.component.html',
|
||||||
|
styleUrls: ['./room-list-item-02.component.scss'],
|
||||||
|
changeDetection: ChangeDetectionStrategy.OnPush
|
||||||
|
})
|
||||||
|
export class RoomListItem02Component implements OnInit, OnDestroy {
|
||||||
|
@Input()
|
||||||
|
roomInfo: RoomInfo;
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
profileImageRoot: string;
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
defaultProfileImage: string;
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
profileImage: string;
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
roomName: string;
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
checkable = false;
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
checked = false;
|
||||||
|
|
||||||
|
@Output()
|
||||||
|
toggleItem = new EventEmitter<{
|
||||||
|
checked: boolean;
|
||||||
|
roomInfo: RoomInfo;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
RoomType = RoomType;
|
||||||
|
|
||||||
|
constructor(private changeDetectorRef: ChangeDetectorRef) {}
|
||||||
|
|
||||||
|
ngOnInit(): void {}
|
||||||
|
|
||||||
|
ngOnDestroy(): void {}
|
||||||
|
|
||||||
|
onToggleItem(value: boolean): void {
|
||||||
|
this.toggleItem.emit({
|
||||||
|
checked: value,
|
||||||
|
roomInfo: this.roomInfo
|
||||||
|
});
|
||||||
|
|
||||||
|
this.changeDetectorRef.detectChanges();
|
||||||
|
}
|
||||||
|
}
|
530
documents/업무/6월/1째주/backup/room/effects.ts
Normal file
530
documents/업무/6월/1째주/backup/room/effects.ts
Normal file
|
@ -0,0 +1,530 @@
|
||||||
|
import { of } from 'rxjs';
|
||||||
|
import {
|
||||||
|
catchError,
|
||||||
|
map,
|
||||||
|
switchMap,
|
||||||
|
exhaustMap,
|
||||||
|
withLatestFrom,
|
||||||
|
tap,
|
||||||
|
debounceTime
|
||||||
|
} from 'rxjs/operators';
|
||||||
|
|
||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
|
||||||
|
import { Store, select } from '@ngrx/store';
|
||||||
|
import { Actions, ofType, createEffect } from '@ngrx/effects';
|
||||||
|
|
||||||
|
import {
|
||||||
|
OpenResponse as CreateResponse,
|
||||||
|
Open3Response as CreateTimerResponse,
|
||||||
|
ExitResponse as DeleteResponse,
|
||||||
|
ExitAllResponse as DeleteMultiResponse,
|
||||||
|
UpdateResponse,
|
||||||
|
InviteResponse,
|
||||||
|
ExitForcingResponse,
|
||||||
|
UpdateTimerSetResponse,
|
||||||
|
InfoRequest
|
||||||
|
} from '@ucap/protocol-room';
|
||||||
|
|
||||||
|
import { RoomProtocolService } from '@ucap/ng-protocol-room';
|
||||||
|
import { SyncProtocolService } from '@ucap/ng-protocol-sync';
|
||||||
|
|
||||||
|
import { LoginActions, LoginSelector } from '@ucap/ng-store-authentication';
|
||||||
|
import * as ChattingAction from '../Chatting/actions';
|
||||||
|
import { RoomSelector, ChattingSelector } from '../state';
|
||||||
|
|
||||||
|
import {
|
||||||
|
rooms,
|
||||||
|
room,
|
||||||
|
roomFailure,
|
||||||
|
inviteNotification,
|
||||||
|
exitNotification,
|
||||||
|
excludeUser,
|
||||||
|
excludeUserSuccess,
|
||||||
|
close,
|
||||||
|
delSuccess,
|
||||||
|
create,
|
||||||
|
createSuccess,
|
||||||
|
createFailure,
|
||||||
|
createTimer,
|
||||||
|
createTimerSuccess,
|
||||||
|
createTimerFailure,
|
||||||
|
del,
|
||||||
|
delFailure,
|
||||||
|
update,
|
||||||
|
updateSuccess,
|
||||||
|
updateFailure,
|
||||||
|
open,
|
||||||
|
openSuccess,
|
||||||
|
closeSuccess,
|
||||||
|
invite,
|
||||||
|
inviteSuccess,
|
||||||
|
inviteFailure,
|
||||||
|
expel,
|
||||||
|
expelSuccess,
|
||||||
|
expelFailure,
|
||||||
|
updateTimeRoomInterval,
|
||||||
|
updateTimeRoomIntervalSuccess,
|
||||||
|
updateTimeRoomIntervalFailure,
|
||||||
|
rooms2Success,
|
||||||
|
rooms2Failure,
|
||||||
|
delMulti,
|
||||||
|
delMultiSuccess,
|
||||||
|
delMultiFailure,
|
||||||
|
selectedRoom,
|
||||||
|
room2Success,
|
||||||
|
selectedRoomSuccess,
|
||||||
|
clearSelectedRoom
|
||||||
|
} from './actions';
|
||||||
|
import { LocaleCode } from '@ucap/core';
|
||||||
|
import { PresenceActions } from '@ucap/ng-store-organization';
|
||||||
|
import { I18nService } from '@ucap/ng-i18n';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class Effects {
|
||||||
|
sessionCreatedForRooms$ = createEffect(() => {
|
||||||
|
return this.actions$.pipe(
|
||||||
|
ofType(LoginActions.sessionCreated),
|
||||||
|
map((action) => rooms({ localeCode: action.loginSession.localeCode }))
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
selectedRoom$ = createEffect(
|
||||||
|
() => {
|
||||||
|
return this.actions$.pipe(
|
||||||
|
ofType(selectedRoom),
|
||||||
|
debounceTime(300),
|
||||||
|
tap((action) => {
|
||||||
|
const req: InfoRequest = {
|
||||||
|
...action,
|
||||||
|
isDetail: false
|
||||||
|
};
|
||||||
|
|
||||||
|
// retrieve room info
|
||||||
|
this.roomProtocolService
|
||||||
|
.info2(req)
|
||||||
|
.pipe(
|
||||||
|
map((res) => {
|
||||||
|
let isJoinRoom = true;
|
||||||
|
if (!res.roomInfo || !res.roomInfo.isJoinRoom) {
|
||||||
|
isJoinRoom = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!!isJoinRoom) {
|
||||||
|
this.store.dispatch(
|
||||||
|
selectedRoomSuccess({
|
||||||
|
roomId: req.roomId,
|
||||||
|
roomInfo2Res: res
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
// Buddy Presence
|
||||||
|
const targetUserInfos = req.isDetail
|
||||||
|
? res.roomUserInfo.userInfoList.map(
|
||||||
|
(userInfo) => userInfo.seq + ''
|
||||||
|
)
|
||||||
|
: res.roomUserInfo.userInfoShortList.map(
|
||||||
|
(userInfo) => userInfo.seq + ''
|
||||||
|
);
|
||||||
|
if (!!targetUserInfos && targetUserInfos.length > 0) {
|
||||||
|
this.store.dispatch(
|
||||||
|
PresenceActions.bulkInfo({
|
||||||
|
divCd: 'roomBulk',
|
||||||
|
userSeqs: targetUserInfos
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// is not join room. so, redirect chat main.
|
||||||
|
this.store.dispatch(
|
||||||
|
clearSelectedRoom({ roomId: req.roomId })
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
catchError((error) => of(roomFailure({ error })))
|
||||||
|
)
|
||||||
|
.subscribe();
|
||||||
|
|
||||||
|
// retrieve event info >> chatting.effect.selectedRoom$
|
||||||
|
})
|
||||||
|
);
|
||||||
|
},
|
||||||
|
{ dispatch: false }
|
||||||
|
);
|
||||||
|
|
||||||
|
selectedRoomSuccess$ = createEffect(
|
||||||
|
() => {
|
||||||
|
return this.actions$.pipe(
|
||||||
|
ofType(selectedRoomSuccess),
|
||||||
|
tap((action) => {
|
||||||
|
// room info success reduce.
|
||||||
|
this.store.dispatch(
|
||||||
|
room2Success({
|
||||||
|
roomInfo: action.roomInfo2Res.roomInfo,
|
||||||
|
roomUserInfo: action.roomInfo2Res.roomUserInfo
|
||||||
|
})
|
||||||
|
);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
},
|
||||||
|
{ dispatch: false }
|
||||||
|
);
|
||||||
|
|
||||||
|
rooms$ = createEffect(() => {
|
||||||
|
return this.actions$.pipe(
|
||||||
|
ofType(rooms),
|
||||||
|
withLatestFrom(this.store.pipe(select(RoomSelector.roomsSyncDate))),
|
||||||
|
switchMap(([action, syncDate]) => {
|
||||||
|
// // CASE :: RoomUser Data 중 Detail data 만 수집.
|
||||||
|
// return this.syncProtocolService
|
||||||
|
// .room({ syncDate, localeCode: action.localeCode })
|
||||||
|
// .pipe(
|
||||||
|
// map((res) => {
|
||||||
|
// return roomsSuccess({
|
||||||
|
// roomList: res.roomList,
|
||||||
|
// roomUserInfoMap: res.roomUserInfoMap,
|
||||||
|
// syncDate: res.res.syncDate
|
||||||
|
// });
|
||||||
|
// }),
|
||||||
|
// catchError((error) => of(roomsFailure({ error })))
|
||||||
|
// );
|
||||||
|
|
||||||
|
// CASE :: RoomUser Data 중 Detail data, Short data 수집.
|
||||||
|
return this.syncProtocolService
|
||||||
|
.room2({ syncDate, localeCode: action.localeCode })
|
||||||
|
.pipe(
|
||||||
|
map((res) => {
|
||||||
|
return rooms2Success({
|
||||||
|
roomList: res.roomList,
|
||||||
|
roomUserInfoMap: res.roomUserInfoMap,
|
||||||
|
syncDate: res.res.syncDate
|
||||||
|
});
|
||||||
|
}),
|
||||||
|
catchError((error) => of(rooms2Failure({ error })))
|
||||||
|
);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
room$ = createEffect(() => {
|
||||||
|
return this.actions$.pipe(
|
||||||
|
ofType(room),
|
||||||
|
switchMap((action) => {
|
||||||
|
const req = action.req;
|
||||||
|
// // CASE :: RoomUser Data 중 Detail data 만 수집.
|
||||||
|
// return this.roomProtocolService.info(req).pipe(
|
||||||
|
// map((res) =>
|
||||||
|
// roomSuccess({
|
||||||
|
// roomInfo: res.roomInfo,
|
||||||
|
// userInfoList: res.userInfoList
|
||||||
|
// })
|
||||||
|
// ),
|
||||||
|
// catchError((error) => of(roomFailure({ error })))
|
||||||
|
// );
|
||||||
|
|
||||||
|
// CASE :: RoomUser Data 중 Detail data, Short data 수집.
|
||||||
|
return this.roomProtocolService.info2(req).pipe(
|
||||||
|
map((res) =>
|
||||||
|
room2Success({
|
||||||
|
roomInfo: res.roomInfo,
|
||||||
|
roomUserInfo: res.roomUserInfo
|
||||||
|
})
|
||||||
|
),
|
||||||
|
catchError((error) => of(roomFailure({ error })))
|
||||||
|
);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
create$ = createEffect(
|
||||||
|
() => {
|
||||||
|
return this.actions$.pipe(
|
||||||
|
ofType(create),
|
||||||
|
map((action) => action.req),
|
||||||
|
exhaustMap((req) => {
|
||||||
|
return this.roomProtocolService.open(req).pipe(
|
||||||
|
map((res: CreateResponse) => {
|
||||||
|
this.store.dispatch(createSuccess({ res }));
|
||||||
|
|
||||||
|
// this.router.navigate(
|
||||||
|
// [
|
||||||
|
// 'chat',
|
||||||
|
// {
|
||||||
|
// outlets: { content: 'chatroom' }
|
||||||
|
// }
|
||||||
|
// ],
|
||||||
|
// {
|
||||||
|
// queryParams: { roomId: res.roomId }
|
||||||
|
// }
|
||||||
|
// );
|
||||||
|
|
||||||
|
// if (!res.newRoom) {
|
||||||
|
// } else {
|
||||||
|
// }
|
||||||
|
}),
|
||||||
|
catchError((error) => of(createFailure({ error })))
|
||||||
|
);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
},
|
||||||
|
{ dispatch: false }
|
||||||
|
);
|
||||||
|
|
||||||
|
createTimer$ = createEffect(() =>
|
||||||
|
this.actions$.pipe(
|
||||||
|
ofType(createTimer),
|
||||||
|
map((action) => action.req),
|
||||||
|
exhaustMap((req) => {
|
||||||
|
return this.roomProtocolService.open3(req).pipe(
|
||||||
|
map((res: CreateTimerResponse) => {
|
||||||
|
return createTimerSuccess({ res });
|
||||||
|
}),
|
||||||
|
catchError((error) => of(createTimerFailure({ error })))
|
||||||
|
);
|
||||||
|
})
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
del$ = createEffect(() =>
|
||||||
|
this.actions$.pipe(
|
||||||
|
ofType(del),
|
||||||
|
map((action) => action.req),
|
||||||
|
exhaustMap((req) => {
|
||||||
|
return this.roomProtocolService.exit(req).pipe(
|
||||||
|
switchMap((res: DeleteResponse) => [
|
||||||
|
// clear activeRoomId
|
||||||
|
clearSelectedRoom({ roomId: res.roomId }),
|
||||||
|
// close room, clear chatting
|
||||||
|
close({ roomIds: [res.roomId] }),
|
||||||
|
// clear room in rooms.
|
||||||
|
delSuccess({ res })
|
||||||
|
]),
|
||||||
|
catchError((error) => of(delFailure({ error })))
|
||||||
|
);
|
||||||
|
})
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
delMulti$ = createEffect(() =>
|
||||||
|
this.actions$.pipe(
|
||||||
|
ofType(delMulti),
|
||||||
|
map((action) => action.req),
|
||||||
|
withLatestFrom(this.store.pipe(select(ChattingSelector.activeRoomId))),
|
||||||
|
exhaustMap(([req, activeRoomId]) => {
|
||||||
|
const existActiveRoomId = req.roomIds.find(
|
||||||
|
(roomId) => roomId === activeRoomId
|
||||||
|
);
|
||||||
|
|
||||||
|
return this.roomProtocolService.exitAll(req).pipe(
|
||||||
|
switchMap((res: DeleteMultiResponse) => {
|
||||||
|
if (!!existActiveRoomId) {
|
||||||
|
return [
|
||||||
|
// clear selected room
|
||||||
|
clearSelectedRoom({ roomId: existActiveRoomId }),
|
||||||
|
// close room, clear chatting
|
||||||
|
close({ roomIds: res.roomIds }),
|
||||||
|
// clear room in rooms.
|
||||||
|
delMultiSuccess({ res })
|
||||||
|
];
|
||||||
|
} else {
|
||||||
|
return [
|
||||||
|
// close room, clear chatting
|
||||||
|
close({ roomIds: res.roomIds }),
|
||||||
|
// clear room in rooms.
|
||||||
|
delMultiSuccess({ res })
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
catchError((error) => of(delMultiFailure({ error })))
|
||||||
|
);
|
||||||
|
})
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
update$ = createEffect(() =>
|
||||||
|
this.actions$.pipe(
|
||||||
|
ofType(update),
|
||||||
|
map((action) => action.req),
|
||||||
|
exhaustMap((req) => {
|
||||||
|
return this.roomProtocolService.update(req).pipe(
|
||||||
|
map((res: UpdateResponse) => {
|
||||||
|
return updateSuccess({ res });
|
||||||
|
}),
|
||||||
|
catchError((error) => of(updateFailure({ error })))
|
||||||
|
);
|
||||||
|
})
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
excludeUser$ = createEffect(() => {
|
||||||
|
return this.actions$.pipe(
|
||||||
|
ofType(excludeUser),
|
||||||
|
map((action) =>
|
||||||
|
excludeUserSuccess({
|
||||||
|
roomId: action.roomId,
|
||||||
|
userSeqs: action.userSeqs
|
||||||
|
})
|
||||||
|
)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
open$ = createEffect(() => {
|
||||||
|
return this.actions$.pipe(
|
||||||
|
ofType(open),
|
||||||
|
map((action) => openSuccess({ roomIds: [...action.roomIds] }))
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
close$ = createEffect(() => {
|
||||||
|
return this.actions$.pipe(
|
||||||
|
ofType(close),
|
||||||
|
map((action) => closeSuccess({ roomIds: [...action.roomIds] }))
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
invite$ = createEffect(() =>
|
||||||
|
this.actions$.pipe(
|
||||||
|
ofType(invite),
|
||||||
|
exhaustMap((action) => {
|
||||||
|
const req = action.req;
|
||||||
|
const localeCode = action.localeCode;
|
||||||
|
|
||||||
|
return this.roomProtocolService.invite(req).pipe(
|
||||||
|
switchMap((res: InviteResponse) => {
|
||||||
|
return [
|
||||||
|
inviteSuccess({ res }),
|
||||||
|
room({
|
||||||
|
req: {
|
||||||
|
roomId: req.roomId,
|
||||||
|
isDetail: true,
|
||||||
|
localeCode
|
||||||
|
}
|
||||||
|
})
|
||||||
|
];
|
||||||
|
}),
|
||||||
|
catchError((error) => of(inviteFailure({ error })))
|
||||||
|
);
|
||||||
|
})
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
expel$ = createEffect(() =>
|
||||||
|
this.actions$.pipe(
|
||||||
|
ofType(expel),
|
||||||
|
map((action) => action.req),
|
||||||
|
exhaustMap((req) => {
|
||||||
|
return this.roomProtocolService.exitForcing(req).pipe(
|
||||||
|
map((res: ExitForcingResponse) => {
|
||||||
|
return expelSuccess({ res });
|
||||||
|
}),
|
||||||
|
catchError((error) => of(expelFailure({ error })))
|
||||||
|
);
|
||||||
|
})
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
updateTimeRoomInterval$ = createEffect(() =>
|
||||||
|
this.actions$.pipe(
|
||||||
|
ofType(updateTimeRoomInterval),
|
||||||
|
map((action) => action.req),
|
||||||
|
exhaustMap((req) => {
|
||||||
|
return this.roomProtocolService.updateTimerSet(req).pipe(
|
||||||
|
map((res: UpdateTimerSetResponse) => {
|
||||||
|
return updateTimeRoomIntervalSuccess({ res });
|
||||||
|
}),
|
||||||
|
catchError((error) => of(updateTimeRoomIntervalFailure({ error })))
|
||||||
|
);
|
||||||
|
})
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @discription Call by notifications case in SSVC_TYPE_ROOM_INVITE_RES, SSVC_TYPE_ROOM_INVITE_NOTI
|
||||||
|
* 1. roomlist 를 체크하여 없을경우 내가 초대된 경우라 간주하고 방 조회하여 갱신하지 않도록 한다.(첫 대화가 들어오면 그때 조회.)
|
||||||
|
* 2. roomlist 를 체크하여 있을 경우 기존방에 다른 인원이 추가되었을 경우이므로 방 조회하여 갱신한다.
|
||||||
|
*/
|
||||||
|
inviteNotification$ = createEffect(
|
||||||
|
() => {
|
||||||
|
return this.actions$.pipe(
|
||||||
|
ofType(inviteNotification),
|
||||||
|
withLatestFrom(this.store.pipe(select(RoomSelector.rooms))),
|
||||||
|
map(([action, roomList]) => {
|
||||||
|
const roomId = action.noti.roomId;
|
||||||
|
if (!!roomList && roomList.length > 0) {
|
||||||
|
if (roomList.some((roomInfo) => roomId === roomInfo.roomId)) {
|
||||||
|
this.store.dispatch(
|
||||||
|
room({
|
||||||
|
req: {
|
||||||
|
roomId,
|
||||||
|
isDetail: true,
|
||||||
|
localeCode: action.localeCode
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dispatch: false
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
exitNotification$ = createEffect(() => {
|
||||||
|
return this.actions$.pipe(
|
||||||
|
ofType(exitNotification),
|
||||||
|
withLatestFrom(this.store.pipe(select(LoginSelector.loginRes))),
|
||||||
|
switchMap(([action, loginRes]) => {
|
||||||
|
if (loginRes.userSeq + '' === action.senderSeq + '') {
|
||||||
|
return [
|
||||||
|
close({ roomIds: [action.roomId] }),
|
||||||
|
clearSelectedRoom({ roomId: action.roomId }),
|
||||||
|
delSuccess({
|
||||||
|
res: { roomId: action.roomId }
|
||||||
|
})
|
||||||
|
];
|
||||||
|
} else {
|
||||||
|
return [
|
||||||
|
excludeUser({
|
||||||
|
roomId: action.roomId,
|
||||||
|
userSeqs: [action.senderSeq]
|
||||||
|
})
|
||||||
|
];
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
/*******************************************************************
|
||||||
|
* [Chatting Action watching.]
|
||||||
|
*******************************************************************/
|
||||||
|
addEventSuccess$ = createEffect(
|
||||||
|
() => {
|
||||||
|
return this.actions$.pipe(
|
||||||
|
ofType(ChattingAction.addEventSuccess),
|
||||||
|
withLatestFrom(this.store.pipe(select(RoomSelector.rooms))),
|
||||||
|
map(([action, roomList]) => {
|
||||||
|
const roomId = action.roomId;
|
||||||
|
|
||||||
|
if (!roomList.find((roomInfo) => roomInfo.roomId === roomId)) {
|
||||||
|
this.store.dispatch(
|
||||||
|
rooms({
|
||||||
|
localeCode: this.i18nService.currentLng.toUpperCase() as LocaleCode
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
},
|
||||||
|
{ dispatch: false }
|
||||||
|
);
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private actions$: Actions,
|
||||||
|
private store: Store<any>,
|
||||||
|
private syncProtocolService: SyncProtocolService,
|
||||||
|
private roomProtocolService: RoomProtocolService,
|
||||||
|
private i18nService: I18nService
|
||||||
|
) {}
|
||||||
|
}
|
BIN
documents/업무/6월/1째주/backup/ucap-0605.zip
Normal file
BIN
documents/업무/6월/1째주/backup/ucap-0605.zip
Normal file
Binary file not shown.
BIN
documents/업무/6월/1째주/backup/ucap-angular-0605.zip
Normal file
BIN
documents/업무/6월/1째주/backup/ucap-angular-0605.zip
Normal file
Binary file not shown.
BIN
documents/업무/6월/1째주/backup/ucap-lg-web-0605.zip
Normal file
BIN
documents/업무/6월/1째주/backup/ucap-lg-web-0605.zip
Normal file
Binary file not shown.
15
documents/업무/6월/1째주/todo
Normal file
15
documents/업무/6월/1째주/todo
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
버그
|
||||||
|
동료 삭제, 그룹 삭제 시 프로토콜 절차 정상적으로 진행되나 새로고침 시 기존 데이터가 다시 로드됨
|
||||||
|
팝업 테넌트 검색 시 결과에 대한 체크박스 체크 후 다시 검색 시 체크가 됨
|
||||||
|
|
||||||
|
추가 기능
|
||||||
|
그룹
|
||||||
|
팝업 조직도 사용자 선택
|
||||||
|
팝업 사용자 선택 창 사이즈 조절 시 위치 변경
|
||||||
|
그룹 추가 팝업 "그룹지정 완료" 시
|
||||||
|
사용자 선택 x
|
||||||
|
그룹 선택 x
|
||||||
|
완료 버튼 비활성화
|
||||||
|
채팅
|
||||||
|
노티피케이션 연동
|
||||||
|
|
0
documents/업무/6월/2째주/0608.txt
Normal file
0
documents/업무/6월/2째주/0608.txt
Normal file
BIN
weekly-report/6월/주간보고_박병은_2020.0605.pptx
Normal file
BIN
weekly-report/6월/주간보고_박병은_2020.0605.pptx
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user