diff --git a/package-lock.json b/package-lock.json index 91ac6f15..d8308330 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "ucap-webmessenger", - "version": "0.0.9", + "version": "0.0.10", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -3870,6 +3870,15 @@ "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", "dev": true }, + "angular-animations": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/angular-animations/-/angular-animations-0.0.10.tgz", + "integrity": "sha512-UKKWRZDDXl3m+bcS1PfW5xZ2WoyM9ixfdLS7OG9lDrWm5KkIYEIrZvC+r5nfU3C5ovltHId5e2BlwYqL18kxOA==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, "angular-split": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/angular-split/-/angular-split-3.0.2.tgz", diff --git a/package.json b/package.json index 5262793f..a92fe136 100644 --- a/package.json +++ b/package.json @@ -99,6 +99,7 @@ "@types/webpack": "^4.41.2", "@types/webpack-merge": "^4.1.5", "@types/webpack-node-externals": "^1.7.0", + "angular-animations": "^0.0.10", "angular-split": "^3.0.2", "autolinker": "^3.11.1", "awesome-node-loader": "^1.1.1", diff --git a/projects/ucap-webmessenger-ui-chat/src/lib/components/message-box.component.html b/projects/ucap-webmessenger-ui-chat/src/lib/components/message-box.component.html index fc61065c..ca0a78ab 100644 --- a/projects/ucap-webmessenger-ui-chat/src/lib/components/message-box.component.html +++ b/projects/ucap-webmessenger-ui-chat/src/lib/components/message-box.component.html @@ -22,7 +22,13 @@ > -
+
, - private logger: NGXLogger, - private datePipe: DatePipe + private changeDetectorRef: ChangeDetectorRef, + private logger: NGXLogger ) {} ngOnInit() { @@ -186,4 +189,13 @@ export class MessageBoxComponent implements OnInit, AfterViewInit { this.contextMenu.emit({ event, message }); } } + + shake() { + this.shakeIt = false; + this.changeDetectorRef.detectChanges(); + setTimeout(() => { + this.shakeIt = true; + this.changeDetectorRef.detectChanges(); + }, 1); + } } diff --git a/projects/ucap-webmessenger-ui-chat/src/lib/components/messages.component.html b/projects/ucap-webmessenger-ui-chat/src/lib/components/messages.component.html index 6a5fe2c7..3c3d3af3 100644 --- a/projects/ucap-webmessenger-ui-chat/src/lib/components/messages.component.html +++ b/projects/ucap-webmessenger-ui-chat/src/lib/components/messages.component.html @@ -5,7 +5,7 @@ fxFlexFill #psChatContent [bufferAmount]="5" - [compareItems]="" + [compareItems]="compareItemsFunc" (psScrollUp)="onScrollup($event)" (psYReachStart)="onYReachStart($event)" (psYReachEnd)="onYReachEnd($event)" @@ -53,6 +53,7 @@
; + storedScrollItem: Info; // 이전대화를 불러올 경우 현재 스크롤 포지션 유지를 위한 값. 0 이면 초기로딩. scrollUpInitalized = false; // ps 에서 초기 로딩시 scroll reach start 이벤트 발생 버그를 우회하기 위한 init 값으로 scrollUp 에 의해 true 로 된다. firstCheckReadHere = true; @@ -142,12 +147,10 @@ export class MessagesComponent implements OnInit, OnDestroy { readToHereEvent: Info; existReadToHereEvent = true; - swapped = false; hidden = false; constructor( private logger: NGXLogger, - private datePipe: DatePipe, private changeDetectorRef: ChangeDetectorRef, private translateService: TranslateService ) {} @@ -390,14 +393,13 @@ export class MessagesComponent implements OnInit, OnDestroy { ]; } - swapScroll( + scrollTo( to: Info, preCallback: () => void, postCallback: () => void, - useHide: boolean, - useSwap: boolean + useHide: boolean ) { - this.preSwapScroll(useHide, useSwap); + this.preSwapScroll(useHide); if (!!preCallback) { preCallback(); } @@ -406,33 +408,19 @@ export class MessagesComponent implements OnInit, OnDestroy { if (!!postCallback) { postCallback(); } - this.postSwapScroll(useHide, useSwap); - }, 100); + this.postSwapScroll(useHide); + }); }); } - preSwapScroll(useHide: boolean, useSwap: boolean) { - // if (useSwap && !this.swapped) { - // this.chatMessagesBuffer.nativeElement.innerHTML = this.chatMessagesContainer.nativeElement.innerHTML; - // this.chatMessagesBuffer.nativeElement.scrollTop = this.chatMessagesContainer.nativeElement.scrollTop; - // this.chatMessagesBuffer.nativeElement.classList.remove('disappear'); - // this.swapped = true; - // } - + preSwapScroll(useHide: boolean) { if (useHide && !this.hidden) { this.chatMessagesContainer.nativeElement.classList.add('hide'); this.hidden = true; } } - postSwapScroll(useHide: boolean, useSwap: boolean) { - // if (useSwap && this.swapped) { - // this.chatMessagesBuffer.nativeElement.innerHTML = ''; - // this.chatMessagesBuffer.nativeElement.scrollTop = 0; - // this.chatMessagesBuffer.nativeElement.classList.add('disappear'); - // this.swapped = false; - // } - + postSwapScroll(useHide: boolean) { if (useHide && this.hidden) { this.chatMessagesContainer.nativeElement.classList.remove('hide'); this.hidden = false; @@ -443,27 +431,29 @@ export class MessagesComponent implements OnInit, OnDestroy { this.scrollToBottom(); } - scrollToBottom(speed?: number): void { + scrollToBottom(): void { if (!!this.storedScrollItem) { if (!!this.readToHereEvent && this.firstCheckReadHere) { - this.swapScroll( + this.scrollTo( this.readToHereEvent, () => {}, () => { this.firstCheckReadHere = false; }, - true, true ); } else { - this.swapScroll( - this.storedScrollItem, + const index = this.eventList.findIndex( + i => i.seq === this.storedScrollItem.seq + ); + + this.scrollTo( + 1 <= index ? this.eventList[index - 1] : this.eventList[0], () => {}, () => { this.storedScrollItem = undefined; }, - true, - true + false ); } } else if (this.scrollUpInitalized) { @@ -473,16 +463,13 @@ export class MessagesComponent implements OnInit, OnDestroy { ); } } else { - speed = speed || 0; - if (!!this.readToHereEvent && this.firstCheckReadHere) { - this.swapScroll( + this.scrollTo( this.readToHereEvent, () => {}, () => { this.firstCheckReadHere = false; }, - true, true ); } else { @@ -490,20 +477,18 @@ export class MessagesComponent implements OnInit, OnDestroy { this.virtualScroller.viewPortInfo.endIndex === this.eventList.length - 2 ) { - this.swapScroll( + this.scrollTo( this.eventList[this.eventList.length - 1], () => {}, () => {}, - false, false ); } else { - this.swapScroll( + this.scrollTo( this.eventList[this.eventList.length - 1], () => {}, () => {}, - true, - false + true ); } } @@ -520,8 +505,21 @@ export class MessagesComponent implements OnInit, OnDestroy { gotoPosition(eventSeq: number) { if (!!this.virtualScroller) { - const e = this.eventList.find(v => v.seq === eventSeq); - this.virtualScroller.scrollInto(e, true, 0, 0, () => {}); + 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 chatMessageBox = this.chatMessageBoxList.find( + el => el.message.seq === eventSeq + ); + if (!!chatMessageBox) { + chatMessageBox.shake(); + } + } + ); } } @@ -536,7 +534,7 @@ export class MessagesComponent implements OnInit, OnDestroy { if (this.scrollUpInitalized && this.eventRemained) { this.storeScrollPosition(); - this.preSwapScroll(false, false); + this.preSwapScroll(false); this.moreEvent.emit(this.eventList[0].seq); @@ -612,5 +610,5 @@ export class MessagesComponent implements OnInit, OnDestroy { item1: Info, item2: Info // tslint:disable-next-line: semicolon - ): boolean => item1.seq === item2.seq; + ): boolean => !!item1 && !!item2 && item1.seq === item2.seq; } diff --git a/projects/ucap-webmessenger-ui/src/public-api.ts b/projects/ucap-webmessenger-ui/src/public-api.ts index 4ad82c07..347d3eb2 100644 --- a/projects/ucap-webmessenger-ui/src/public-api.ts +++ b/projects/ucap-webmessenger-ui/src/public-api.ts @@ -2,7 +2,7 @@ * Public API Surface of ucap-webmessenger-ui */ -export * from './lib/animations'; +export * from './lib/animations/index'; export * from './lib/components/file-viewer/document-viewer.component'; export * from './lib/components/file-viewer/image-viewer.component';