# 이슈처리

184 1:1대화방 상대방이 방 나가기 시대화 상대 없음 으로 표시됨
185 회의중, 상태메시지 입력 후 X버튼 후 편집버튼 선택 시 오류
186 그룹대화방 생성 후 메시지 발신 시 여기까지 읽음 기능 표시됨
187 그룹 대화방 읽음 표시 카운트 오류
This commit is contained in:
leejinho 2020-01-28 13:26:32 +09:00
parent 1d94b4d1eb
commit 77bc91aa39
11 changed files with 207 additions and 59 deletions

View File

@ -467,6 +467,11 @@ export class MessagesComponent implements OnInit, OnDestroy, AfterViewInit {
} }
get _roomUserInfos() { get _roomUserInfos() {
if (this.roomInfoSubject.value.roomType === RoomType.Single) {
return this.userInfoListSubject.value.filter(roomUserInfo => {
return this.loginResSubject.value.userSeq !== roomUserInfo.seq;
});
} else {
return this.userInfoListSubject.value return this.userInfoListSubject.value
.filter(roomUserInfo => { .filter(roomUserInfo => {
return ( return (
@ -476,6 +481,7 @@ export class MessagesComponent implements OnInit, OnDestroy, AfterViewInit {
}) })
.sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0)); .sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0));
} }
}
getRoomNameByRoomUser(roomUserInfos: (UserInfo | UserInfoShort)[]) { getRoomNameByRoomUser(roomUserInfos: (UserInfo | UserInfoShort)[]) {
let roomName = new TranslatePipe( let roomName = new TranslatePipe(

View File

@ -361,7 +361,10 @@
onApplyStatusMessage(1, statusMessage1.value) onApplyStatusMessage(1, statusMessage1.value)
" "
(edit)="$event.stopPropagation()" (edit)="$event.stopPropagation()"
(cancel)="$event.stopPropagation()" (cancel)="
$event.stopPropagation();
statusMessage1.value = loginRes?.statusMessage1
"
class="form-eidt" class="form-eidt"
> >
<span ucapInlineEditInput="view">{{ loginRes?.statusMessage1 }}</span> <span ucapInlineEditInput="view">{{ loginRes?.statusMessage1 }}</span>
@ -386,7 +389,10 @@
onApplyStatusMessage(2, statusMessage2.value) onApplyStatusMessage(2, statusMessage2.value)
" "
(edit)="$event.stopPropagation()" (edit)="$event.stopPropagation()"
(cancel)="$event.stopPropagation()" (cancel)="
$event.stopPropagation();
statusMessage2.value = loginRes?.statusMessage2
"
class="form-eidt" class="form-eidt"
> >
<span ucapInlineEditInput="view">{{ loginRes?.statusMessage2 }}</span> <span ucapInlineEditInput="view">{{ loginRes?.statusMessage2 }}</span>
@ -411,7 +417,10 @@
onApplyStatusMessage(3, statusMessage3.value) onApplyStatusMessage(3, statusMessage3.value)
" "
(edit)="$event.stopPropagation()" (edit)="$event.stopPropagation()"
(cancel)="$event.stopPropagation()" (cancel)="
$event.stopPropagation();
statusMessage3.value = loginRes?.statusMessage3
"
class="form-eidt" class="form-eidt"
> >
<span ucapInlineEditInput="view">{{ loginRes?.statusMessage3 }}</span> <span ucapInlineEditInput="view">{{ loginRes?.statusMessage3 }}</span>

View File

@ -11,7 +11,8 @@ import {
AuthenticationProtocolService, AuthenticationProtocolService,
LogoutResponse, LogoutResponse,
LogoutRemoteNotification, LogoutRemoteNotification,
LogoutNotification LogoutNotification,
LoginResponse
} from '@ucap-webmessenger/protocol-authentication'; } from '@ucap-webmessenger/protocol-authentication';
import { NGXLogger } from 'ngx-logger'; import { NGXLogger } from 'ngx-logger';
@ -446,7 +447,15 @@ export class AppNotificationService {
.subscribe(); .subscribe();
this.roomProtocolService.notification$ this.roomProtocolService.notification$
.pipe( .pipe(
tap(notiOrRes => { withLatestFrom(
this.store.pipe(
select(
(state: any) =>
state.account.authentication.loginRes as LoginResponse
)
)
),
tap(([notiOrRes, loginResInfo]) => {
switch (notiOrRes.SSVC_TYPE) { switch (notiOrRes.SSVC_TYPE) {
case SSVC_TYPE_ROOM_INVITE_RES: case SSVC_TYPE_ROOM_INVITE_RES:
{ {
@ -506,11 +515,29 @@ export class AppNotificationService {
'Notification::roomProtocolService::ExitNotification', 'Notification::roomProtocolService::ExitNotification',
noti noti
); );
if (noti.SENDER_SEQ === loginResInfo.userSeq) {
this.store.dispatch( this.store.dispatch(
RoomStore.exitNotification({ RoomStore.exitNotification({
noti noti
}) })
); );
} else {
this.store.dispatch(
RoomStore.exitNotificationOthers({
noti
})
);
if (!!noti && !!noti.SENDER_SEQ) {
this.store.dispatch(
SyncStore.clearRoomUsers({
roomSeq: noti.roomSeq,
userSeqs: [noti.SENDER_SEQ]
})
);
}
}
} }
break; break;
case SSVC_TYPE_ROOM_EXIT_FORCING_RES: case SSVC_TYPE_ROOM_EXIT_FORCING_RES:

View File

@ -42,6 +42,11 @@ export const infoFailure = createAction(
props<{ error: any }>() props<{ error: any }>()
); );
export const clearRoomUser = createAction(
'[Messenger::Room] clear room users',
props<{ userSeqs: number[] }>()
);
export const inviteNotification = createAction( export const inviteNotification = createAction(
'[Messenger::Room] Invite Notification', '[Messenger::Room] Invite Notification',
props<{ noti: InviteNotification }>() props<{ noti: InviteNotification }>()
@ -51,6 +56,10 @@ export const exitNotification = createAction(
'[Messenger::Room] Exit Notification', '[Messenger::Room] Exit Notification',
props<{ noti: ExitNotification }>() props<{ noti: ExitNotification }>()
); );
export const exitNotificationOthers = createAction(
'[Messenger::Room] Exit Notification By Others',
props<{ noti: ExitNotification }>()
);
export const exitForcing = createAction( export const exitForcing = createAction(
'[Messenger::Room] Exit Forcing', '[Messenger::Room] Exit Forcing',

View File

@ -67,7 +67,9 @@ import {
updateTimeRoomIntervalFailure, updateTimeRoomIntervalFailure,
exitForcing, exitForcing,
exitForcingFailure, exitForcingFailure,
exitForcingSuccess exitForcingSuccess,
exitNotificationOthers,
clearRoomUser
} from './actions'; } from './actions';
import { SessionStorageService } from '@ucap-webmessenger/web-storage'; import { SessionStorageService } from '@ucap-webmessenger/web-storage';
import { LoginInfo, KEY_LOGIN_INFO } from '@app/types'; import { LoginInfo, KEY_LOGIN_INFO } from '@app/types';
@ -340,6 +342,31 @@ export class Effects {
}, },
{ dispatch: false } { dispatch: false }
); );
exitNotificationOthers$ = createEffect(
() => {
return this.actions$.pipe(
ofType(exitNotificationOthers),
withLatestFrom(
this.store.pipe(
select((state: any) => state.messenger.room.roomInfo as RoomInfo)
)
),
tap(([action, roomInfo]) => {
if (
!!roomInfo &&
roomInfo.roomSeq === action.noti.roomSeq &&
!!action.noti &&
!!action.noti.SENDER_SEQ
) {
this.store.dispatch(
clearRoomUser({ userSeqs: [action.noti.SENDER_SEQ] })
);
}
})
);
},
{ dispatch: false }
);
updateFontNotification$ = createEffect( updateFontNotification$ = createEffect(
() => { () => {

View File

@ -4,7 +4,8 @@ import {
infoSuccess, infoSuccess,
updateSuccess, updateSuccess,
updateRoomUserLastReadSeq, updateRoomUserLastReadSeq,
updateTimeRoomIntervalSuccess updateTimeRoomIntervalSuccess,
clearRoomUser
} from './actions'; } from './actions';
import * as AuthenticationStore from '@app/store/account/authentication'; import * as AuthenticationStore from '@app/store/account/authentication';
@ -26,6 +27,18 @@ export const reducer = createReducer(
}; };
}), }),
on(clearRoomUser, (state, action) => {
return {
...state,
userInfoList: adapterUserInfo.removeMany(action.userSeqs, {
...state.userInfoList
}),
userInfoShortList: adapterUserInfoShort.removeMany(action.userSeqs, {
...state.userInfoShortList
})
};
}),
on(updateSuccess, (state, action) => { on(updateSuccess, (state, action) => {
return { return {
...state, ...state,

View File

@ -263,3 +263,9 @@ export const delGroupFailure = createAction(
'[Messenger::Sync] Group Del Failure', '[Messenger::Sync] Group Del Failure',
props<{ error: any }>() props<{ error: any }>()
); );
/** 방 인원 클리어 */
export const clearRoomUsers = createAction(
'[Messenger::Sync] Clear room users.',
props<{ roomSeq: string; userSeqs: number[] }>()
);

View File

@ -17,7 +17,8 @@ import {
createGroupSuccess, createGroupSuccess,
delBuddySuccess, delBuddySuccess,
delGroupSuccess, delGroupSuccess,
updateBuddySuccess updateBuddySuccess,
clearRoomUsers
} from './actions'; } from './actions';
import { import {
RoomUserDetailData, RoomUserDetailData,
@ -101,6 +102,52 @@ export const reducer = createReducer(
}; };
}), }),
on(clearRoomUsers, (state, action) => {
let roomUserList: RoomUserDetailData = {
...state.roomUser.entities[action.roomSeq]
};
if (
!!roomUserList &&
!!roomUserList.userInfos &&
roomUserList.userInfos.length > 0
) {
const userInfos = roomUserList.userInfos.filter(
userInfo => action.userSeqs.indexOf(userInfo.seq) < 0
);
roomUserList = {
...roomUserList,
userInfos
};
}
let roomUserShortList: RoomUserData = {
...state.roomUserShort.entities[action.roomSeq]
};
if (
!!roomUserShortList &&
!!roomUserShortList.userInfos &&
roomUserShortList.userInfos.length > 0
) {
const userInfos = roomUserShortList.userInfos.filter(
userInfo => action.userSeqs.indexOf(userInfo.seq) < 0
);
roomUserShortList = {
...roomUserShortList,
userInfos
};
}
return {
...state,
roomUser: adapterRoomUser.upsertOne(roomUserList, {
...state.roomUser
}),
roomUserShort: adapterRoomUserShort.upsertOne(roomUserShortList, {
...state.roomUserShort
})
};
}),
on(updateRoomForNewEventMessage, (state, action) => { on(updateRoomForNewEventMessage, (state, action) => {
const finalEventMessage: const finalEventMessage:
| string | string

View File

@ -141,6 +141,7 @@ export class MessagesComponent implements OnInit, OnDestroy {
moment = moment; moment = moment;
readToHereEvent: Info<EventJson>; readToHereEvent: Info<EventJson>;
existReadToHereEvent = true;
swapped = false; swapped = false;
hidden = false; hidden = false;
@ -168,15 +169,26 @@ export class MessagesComponent implements OnInit, OnDestroy {
this.initEventMore(); this.initEventMore();
this.roomInfo = roomInfo; this.roomInfo = roomInfo;
/** [S] initializing by changed room */
// reset :: roomLastEventSeq
if (!!roomInfo && !!roomInfo.finalEventSeq) {
this.initRoomLastEventSeq = roomInfo.finalEventSeq;
}
// clear :: readToHearEvent object
this.readToHereEvent = undefined;
this.existReadToHereEvent = true;
/** [E] initializing by changed room */
}); });
this.eventListSubscription = this.eventList$.subscribe(eventList => { this.eventListSubscription = this.eventList$.subscribe(eventList => {
if (!!eventList && eventList.length > 0 && this.baseEventSeq === 0) { this.eventList = eventList;
this.initRoomLastEventSeq = eventList[eventList.length - 1].seq;
if (!!eventList && eventList.length > 0) {
if (!this.readToHereEvent && this.existReadToHereEvent) {
this.readToHereEvent = this.getReadHere();
} }
if ( if (
!!eventList &&
eventList.length > 0 &&
this.baseEventSeq > 0 && this.baseEventSeq > 0 &&
!!this.roomInfo && !!this.roomInfo &&
!!this.roomInfo.lastReadEventSeq && !!this.roomInfo.lastReadEventSeq &&
@ -185,10 +197,9 @@ export class MessagesComponent implements OnInit, OnDestroy {
// 기존 대화 내용이 있는 상태에서 추가로 조회된 내용중에 read here 가 있을 경우. // 기존 대화 내용이 있는 상태에서 추가로 조회된 내용중에 read here 가 있을 경우.
this.firstCheckReadHere = false; this.firstCheckReadHere = false;
} }
} else {
this.eventList = eventList; this.readToHereEvent = undefined;
}
this.readToHereEvent = this.getReadHere();
this.changeDetectorRef.detectChanges(); this.changeDetectorRef.detectChanges();
@ -298,13 +309,9 @@ export class MessagesComponent implements OnInit, OnDestroy {
// if (!this.userInfos || 0 === this.userInfos.length) { // if (!this.userInfos || 0 === this.userInfos.length) {
// return ''; // return '';
// } // }
const unreadCnt = this.userInfos.filter(user => { const unreadCnt = this.userInfos
if (message.senderSeq === user.seq) { .filter(user => user.isJoinRoom && user.seq !== message.senderSeq)
// 본인 글은 unreadCount 에 포함하지 않는다. .filter(user => user.lastReadEventSeq < message.seq).length;
return false;
}
return user.lastReadEventSeq < message.seq;
}).length;
return unreadCnt === 0 ? '' : unreadCnt; return unreadCnt === 0 ? '' : unreadCnt;
} }
@ -363,6 +370,8 @@ export class MessagesComponent implements OnInit, OnDestroy {
); );
} }
} }
} else {
this.existReadToHereEvent = false;
} }
return undefined; return undefined;
} }

View File

@ -73,7 +73,9 @@
$event.stopPropagation(); onApplyIntroMessage(introMessage.value) $event.stopPropagation(); onApplyIntroMessage(introMessage.value)
" "
(edit)="$event.stopPropagation()" (edit)="$event.stopPropagation()"
(cancel)="$event.stopPropagation()" (cancel)="
$event.stopPropagation(); introMessage.value = userInfo.intro
"
class="form-eidt" class="form-eidt"
> >
<span ucapInlineEditInput="view">{{ userInfo.intro }}</span> <span ucapInlineEditInput="view">{{ userInfo.intro }}</span>
@ -167,20 +169,6 @@
<mat-card-content> <mat-card-content>
<ul class="userInfo-list"> <ul class="userInfo-list">
<!--기존 삭제해주세요
<li>
<dt class="division">사업장</dt>
<dd>{{ userInfo.workplace }}</dd>
</li>
<li>
<dt class="division">담당업무/근무지</dt>
<dd>{{ userInfo.responsibilities }}</dd>
</li>
<li>
<dt class="division">사원직무/거래처</dt>
<dd>가나다라마바사아자차카타파하</dd>
</li>
-->
<li class="company"> <li class="company">
<dt class="division">{{ 'profile.fieldCompany' | translate }}</dt> <dt class="division">{{ 'profile.fieldCompany' | translate }}</dt>
<dd>{{ userInfo.companyName | ucapStringEmptycheck }}</dd> <dd>{{ userInfo.companyName | ucapStringEmptycheck }}</dd>

View File

@ -94,14 +94,21 @@ export class ListItemComponent implements OnInit {
} }
get _roomUserInfos() { get _roomUserInfos() {
if (this.roomInfo.roomType === RoomType.Single) {
return this.roomUserInfo.filter(roomUserInfo => {
return this.loginRes.userSeq !== roomUserInfo.seq;
});
} else {
return this.roomUserInfo return this.roomUserInfo
.filter(roomUserInfo => { .filter(roomUserInfo => {
return ( return (
this.loginRes.userSeq !== roomUserInfo.seq && roomUserInfo.isJoinRoom this.loginRes.userSeq !== roomUserInfo.seq &&
roomUserInfo.isJoinRoom
); );
}) })
.sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0)); .sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0));
} }
}
getRoomNameByRoomUser(roomUserInfos: (RoomUserInfo | UserInfoShort)[]) { getRoomNameByRoomUser(roomUserInfos: (RoomUserInfo | UserInfoShort)[]) {
let roomName = new TranslatePipe( let roomName = new TranslatePipe(