Merge branch 'master' of https://git.loafle.net/ucap-web/next-ucap-messenger
This commit is contained in:
commit
7438d1d691
|
@ -126,7 +126,7 @@
|
|||
|
||||
.file-drop-zone {
|
||||
position: absolute;
|
||||
padding: 10px 10px 0 10px;
|
||||
padding: 10px;
|
||||
background-color: rgb(54, 54, 54, 0.8);
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
|
|
|
@ -1772,10 +1772,13 @@ export class MessagesComponent implements OnInit, OnDestroy, AfterViewInit {
|
|||
// CASE :: searching text after retrieve All event Infos.
|
||||
this.store.dispatch(
|
||||
EventStore.infoAll({
|
||||
roomSeq: this.roomInfoSubject.value.roomSeq,
|
||||
baseSeq: this.eventListSubject.value[0].seq,
|
||||
requestCount:
|
||||
environment.productConfig.CommonSetting.eventRequestDefaultCount * 2
|
||||
req: {
|
||||
roomSeq: this.roomInfoSubject.value.roomSeq,
|
||||
baseSeq: this.eventListSubject.value[0].seq,
|
||||
requestCount:
|
||||
environment.productConfig.CommonSetting.eventRequestDefaultCount * 2
|
||||
},
|
||||
infoList: undefined
|
||||
})
|
||||
);
|
||||
|
||||
|
|
|
@ -50,7 +50,7 @@ export const infoForSearchEnd = createAction(
|
|||
|
||||
export const infoAll = createAction(
|
||||
'[Messenger::Event] Info All',
|
||||
props<InfoRequest>()
|
||||
props<{ req: InfoRequest; infoList: Info<EventJson>[] }>()
|
||||
);
|
||||
|
||||
export const fileInfo = createAction(
|
||||
|
|
|
@ -412,7 +412,10 @@ export class Effects {
|
|||
)
|
||||
)
|
||||
),
|
||||
switchMap(([req, processing]) => {
|
||||
switchMap(([params, processing]) => {
|
||||
const req = params.req;
|
||||
const mergedInfoList = params.infoList;
|
||||
|
||||
return this.eventProtocolService.info(req).pipe(
|
||||
map(async res => {
|
||||
switch (res.SSVC_TYPE) {
|
||||
|
@ -421,31 +424,39 @@ export class Effects {
|
|||
break;
|
||||
case SSVC_TYPE_EVENT_INFO_RES:
|
||||
{
|
||||
this.store.dispatch(
|
||||
infoMoreSuccess({
|
||||
infoList,
|
||||
res: res as InfoResponse,
|
||||
remainInfo:
|
||||
infoList.length === req.requestCount ? true : false
|
||||
})
|
||||
);
|
||||
|
||||
if (infoList.length > 0) {
|
||||
if (infoList.length === req.requestCount && processing) {
|
||||
// 재귀
|
||||
this.store.dispatch(
|
||||
infoAll({
|
||||
if (!!infoList && 0 < infoList.length) {
|
||||
infoList = infoList.sort((a, b) => a.seq - b.seq);
|
||||
}
|
||||
if (
|
||||
infoList.length > 0 &&
|
||||
infoList.length >= req.requestCount &&
|
||||
processing
|
||||
) {
|
||||
// 재귀
|
||||
this.store.dispatch(
|
||||
infoAll({
|
||||
req: {
|
||||
roomSeq: req.roomSeq,
|
||||
baseSeq: infoList[0].seq,
|
||||
requestCount: req.requestCount
|
||||
})
|
||||
);
|
||||
} else {
|
||||
if (infoList.length < req.requestCount) {
|
||||
this.store.dispatch(infoForSearchEnd({}));
|
||||
}
|
||||
}
|
||||
},
|
||||
infoList: !!mergedInfoList
|
||||
? [...infoList, ...mergedInfoList]
|
||||
: infoList
|
||||
})
|
||||
);
|
||||
} else {
|
||||
this.store.dispatch(
|
||||
infoMoreSuccess({
|
||||
infoList: !!mergedInfoList
|
||||
? [...infoList, ...mergedInfoList]
|
||||
: infoList,
|
||||
res: res as InfoResponse,
|
||||
remainInfo:
|
||||
infoList.length === req.requestCount ? true : false
|
||||
})
|
||||
);
|
||||
|
||||
this.store.dispatch(infoForSearchEnd({}));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
</ucap-chat-message-box-date-splitter>
|
||||
|
||||
<div
|
||||
#mbChatRow
|
||||
class="chat-row"
|
||||
[@shake]="{
|
||||
value: shakeIt,
|
||||
|
|
|
@ -96,6 +96,9 @@ export class MessageBoxComponent implements OnInit, AfterViewInit {
|
|||
@ViewChild('mbContainer', { static: true })
|
||||
mbContainer: ElementRef<HTMLElement>;
|
||||
|
||||
@ViewChild('mbChatRow', { static: true })
|
||||
mbChatRow: ElementRef<HTMLElement>;
|
||||
|
||||
EventType = EventType;
|
||||
|
||||
moment = moment;
|
||||
|
@ -104,7 +107,12 @@ export class MessageBoxComponent implements OnInit, AfterViewInit {
|
|||
existReadHere = false;
|
||||
shakeIt = false;
|
||||
|
||||
get offsetTop() {
|
||||
return this.mbChatRow.nativeElement.offsetTop;
|
||||
}
|
||||
|
||||
constructor(
|
||||
private elementRef: ElementRef<HTMLElement>,
|
||||
private changeDetectorRef: ChangeDetectorRef,
|
||||
private logger: NGXLogger
|
||||
) {}
|
||||
|
@ -114,14 +122,12 @@ export class MessageBoxComponent implements OnInit, AfterViewInit {
|
|||
}
|
||||
|
||||
ngAfterViewInit(): void {
|
||||
// this.logger.debug(
|
||||
// 'offsetHeight' + this.message.seq,
|
||||
// this.mbContainer.nativeElement.offsetHeight
|
||||
// );
|
||||
// this.elementRef.nativeElement.style.height = `${this.mbContainer
|
||||
// .nativeElement.offsetHeight + 20}px`;
|
||||
// this.elementRef.nativeElement.style.maxHeight = `${this.mbContainer
|
||||
// .nativeElement.offsetHeight + 20}px`;
|
||||
this.logger.debug(
|
||||
'offsetHeight' + this.message.seq,
|
||||
this.mbContainer.nativeElement.offsetHeight
|
||||
);
|
||||
this.elementRef.nativeElement.style.height = `${this.mbContainer.nativeElement.offsetHeight}px`;
|
||||
this.elementRef.nativeElement.style.maxHeight = `${this.mbContainer.nativeElement.offsetHeight}px`;
|
||||
this.mbContainer.nativeElement.classList.remove('hide');
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
$tablet-s-width: 768px;
|
||||
|
||||
.bubble-main {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
|
|
@ -6,10 +6,10 @@
|
|||
background-color: rgba(0, 0, 0, 0.4);
|
||||
padding: 6px 20px;
|
||||
color: #ffffff;
|
||||
border-radius: 100px;
|
||||
border-radius: 20px;
|
||||
justify-content: center;
|
||||
justify-items: center;
|
||||
margin: 10px 0 20px;
|
||||
font-size: 0.9em;
|
||||
line-height:1.2em
|
||||
line-height: 1.2em;
|
||||
}
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
$tablet-s-width: 768px;
|
||||
|
||||
.bubble-main {
|
||||
display:flex;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
padding: 14px;
|
||||
.file-thumbimg{
|
||||
display:inline-flex;
|
||||
.file-thumbimg {
|
||||
display: inline-flex;
|
||||
img {
|
||||
height:140px;
|
||||
height: 140px;
|
||||
padding-right: 20px;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
@ -15,8 +17,8 @@
|
|||
flex-direction: column;
|
||||
text-align: left;
|
||||
line-height: 1.6em;
|
||||
min-width:100px;
|
||||
margin-top:10px;
|
||||
min-width: 100px;
|
||||
margin-top: 10px;
|
||||
.file-name {
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
|
@ -41,29 +43,35 @@
|
|||
width: 100%;
|
||||
li {
|
||||
width: 50%;
|
||||
height:100%;
|
||||
height: 100%;
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
align-items: center;
|
||||
font-size: 13px;
|
||||
border-right: 1px solid #dddddd;
|
||||
@media screen and (max-width: #{$tablet-s-width}) {
|
||||
width: 30%;
|
||||
}
|
||||
&:last-child {
|
||||
border-right: none;
|
||||
@media screen and (max-width: #{$tablet-s-width}) {
|
||||
width: 70%;
|
||||
}
|
||||
}
|
||||
.mat-button {
|
||||
width: 100%;
|
||||
height:100%;
|
||||
height: 100%;
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
&.expired{
|
||||
li{
|
||||
width:100%;
|
||||
white-space: nowrap;
|
||||
color:#999999;
|
||||
align-items: center;
|
||||
line-height:40px;
|
||||
&.expired {
|
||||
li {
|
||||
width: 100%;
|
||||
white-space: nowrap;
|
||||
color: #999999;
|
||||
align-items: center;
|
||||
line-height: 40px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@ import { TranslateService } from '@ngx-translate/core';
|
|||
import { Observable, Subscription } from 'rxjs';
|
||||
import { VirtualScrollerComponent, IPageInfo } from 'ngx-virtual-scroller';
|
||||
import { MessageBoxComponent } from './message-box.component';
|
||||
import { PerfectScrollbarDirective } from 'ngx-perfect-scrollbar';
|
||||
|
||||
@Component({
|
||||
selector: 'ucap-chat-messages',
|
||||
|
@ -122,6 +123,7 @@ export class MessagesComponent implements OnInit, OnDestroy {
|
|||
chatMessageBoxList: QueryList<MessageBoxComponent>;
|
||||
|
||||
storedScrollItem: Info<EventJson>; // 이전대화를 불러올 경우 현재 스크롤 포지션 유지를 위한 값. 0 이면 초기로딩.
|
||||
storedScrollItemOffsetTop: number | undefined;
|
||||
scrollUpInitalized = false; // ps 에서 초기 로딩시 scroll reach start 이벤트 발생 버그를 우회하기 위한 init 값으로 scrollUp 에 의해 true 로 된다.
|
||||
firstCheckReadHere = true;
|
||||
initRoomLastEventSeq: number;
|
||||
|
@ -395,6 +397,19 @@ export class MessagesComponent implements OnInit, OnDestroy {
|
|||
this.storedScrollItem = this.eventList[
|
||||
this.virtualScroller.viewPortInfo.startIndex
|
||||
];
|
||||
|
||||
const chatMessageBox = this.chatMessageBoxList.find(
|
||||
el =>
|
||||
el.message.seq ===
|
||||
this.eventList[this.virtualScroller.viewPortInfo.startIndex].seq
|
||||
);
|
||||
if (!!chatMessageBox) {
|
||||
this.storedScrollItemOffsetTop =
|
||||
chatMessageBox.offsetTop -
|
||||
this.virtualScroller.viewPortInfo.scrollStartPosition;
|
||||
} else {
|
||||
this.storedScrollItemOffsetTop = 0;
|
||||
}
|
||||
}
|
||||
|
||||
swapScrollTo(
|
||||
|
@ -402,20 +417,32 @@ export class MessagesComponent implements OnInit, OnDestroy {
|
|||
preCallback: () => void,
|
||||
postCallback: () => void,
|
||||
useHide: boolean,
|
||||
useSwap: boolean
|
||||
useSwap: boolean,
|
||||
addtionalOffset?: number
|
||||
) {
|
||||
this.preSwapScroll(useHide, useSwap);
|
||||
if (!!preCallback) {
|
||||
preCallback();
|
||||
}
|
||||
this.virtualScroller.scrollInto(to, true, 0, 0, () => {
|
||||
setTimeout(() => {
|
||||
if (!!postCallback) {
|
||||
postCallback();
|
||||
}
|
||||
this.postSwapScroll(useHide, useSwap);
|
||||
});
|
||||
});
|
||||
|
||||
this.virtualScroller.scrollInto(
|
||||
to,
|
||||
true,
|
||||
undefined !== this.storedScrollItemOffsetTop
|
||||
? -this.storedScrollItemOffsetTop
|
||||
: undefined !== addtionalOffset
|
||||
? -addtionalOffset
|
||||
: 0,
|
||||
0,
|
||||
() => {
|
||||
setTimeout(() => {
|
||||
if (!!postCallback) {
|
||||
postCallback();
|
||||
}
|
||||
this.postSwapScroll(useHide, useSwap);
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
preSwapScroll(useHide: boolean, useSwap: boolean) {
|
||||
|
@ -465,15 +492,12 @@ export class MessagesComponent implements OnInit, OnDestroy {
|
|||
true
|
||||
);
|
||||
} else {
|
||||
const index = this.eventList.findIndex(
|
||||
i => i.seq === this.storedScrollItem.seq
|
||||
);
|
||||
|
||||
this.swapScrollTo(
|
||||
1 <= index ? this.eventList[index - 1] : this.eventList[0],
|
||||
this.storedScrollItem,
|
||||
() => {},
|
||||
() => {
|
||||
this.storedScrollItem = undefined;
|
||||
this.storedScrollItemOffsetTop = undefined;
|
||||
},
|
||||
true,
|
||||
true
|
||||
|
@ -525,18 +549,21 @@ export class MessagesComponent implements OnInit, OnDestroy {
|
|||
// 방정보가 바뀌면 이전대화 보기 관련 값들을 초기화 한다.
|
||||
this.scrollUpInitalized = false;
|
||||
this.storedScrollItem = undefined;
|
||||
this.storedScrollItemOffsetTop = undefined;
|
||||
}
|
||||
|
||||
clear() {}
|
||||
|
||||
gotoPosition(eventSeq: number) {
|
||||
const viewPortItemIndex = this.virtualScroller.viewPortItems.findIndex(
|
||||
v => v.seq === eventSeq
|
||||
);
|
||||
|
||||
if (!!this.virtualScroller) {
|
||||
const index = this.eventList.findIndex(v => v.seq === eventSeq);
|
||||
this.virtualScroller.scrollInto(
|
||||
1 <= index ? this.eventList[index - 1] : this.eventList[0],
|
||||
true,
|
||||
0,
|
||||
100,
|
||||
const e = this.eventList.find(v => v.seq === eventSeq);
|
||||
this.swapScrollTo(
|
||||
e,
|
||||
() => {},
|
||||
() => {
|
||||
const chatMessageBox = this.chatMessageBoxList.find(
|
||||
el => el.message.seq === eventSeq
|
||||
|
@ -544,7 +571,10 @@ export class MessagesComponent implements OnInit, OnDestroy {
|
|||
if (!!chatMessageBox) {
|
||||
chatMessageBox.shake();
|
||||
}
|
||||
}
|
||||
},
|
||||
-1 === viewPortItemIndex,
|
||||
-1 === viewPortItemIndex,
|
||||
50
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -558,13 +588,14 @@ export class MessagesComponent implements OnInit, OnDestroy {
|
|||
event.stopPropagation();
|
||||
|
||||
if (this.scrollUpInitalized && this.eventRemained) {
|
||||
this.virtualScroller.scrollToPosition(0);
|
||||
this.virtualScroller.invalidateCachedMeasurementAtIndex(0);
|
||||
|
||||
this.storeScrollPosition();
|
||||
|
||||
this.preSwapScroll(true, true);
|
||||
|
||||
this.moreEvent.emit(this.eventList[0].seq);
|
||||
|
||||
this.virtualScroller.invalidateCachedMeasurementAtIndex(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -114,5 +114,5 @@ textarea {
|
|||
}
|
||||
|
||||
.mat-error {
|
||||
font-size: 0.8em;
|
||||
font-size: 0.84em;
|
||||
}
|
||||
|
|
|
@ -34,6 +34,8 @@ mat-icon {
|
|||
border: none;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
justify-items: center;
|
||||
justify-content: center;
|
||||
i {
|
||||
font-family: 'material-outline-icons';
|
||||
font-size: 20px;
|
||||
|
|
|
@ -34,8 +34,11 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div *ngIf="uploadItems" fxLayout="column">
|
||||
<div>{{ 'common.file.dropZoneForUpload' | translate }}</div>
|
||||
<div *ngIf="uploadItems" fxLayout="column" class="uploadItems">
|
||||
<div class="msg-guide">
|
||||
<span class="icon-img"><i class="mid mdi-arrow-expand-all"></i></span
|
||||
>{{ 'common.file.dropZoneForUpload' | translate }}
|
||||
</div>
|
||||
<div></div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -38,4 +38,18 @@
|
|||
padding: 6px 10px;
|
||||
}
|
||||
}
|
||||
.uploadItems {
|
||||
width: 100%;
|
||||
font-size: 0.9em;
|
||||
.msg-guide {
|
||||
display: flex;
|
||||
flex: row;
|
||||
color: #ffffff;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
.icon-img {
|
||||
margin-right: 6px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user