sync
This commit is contained in:
parent
0c121ef1ad
commit
cc59886a40
|
@ -29,3 +29,14 @@ if (!!buddies && buddies.length > 0) {
|
|||
|
||||
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