animation of chat search is added
This commit is contained in:
parent
dd23462374
commit
d23efa7b8e
11
package-lock.json
generated
11
package-lock.json
generated
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -22,7 +22,13 @@
|
|||
>
|
||||
</ucap-chat-message-box-date-splitter>
|
||||
|
||||
<div class="chat-row">
|
||||
<div
|
||||
class="chat-row"
|
||||
[@shake]="{
|
||||
value: shakeIt,
|
||||
params: { duration: 1000, delay: 0, translate: '5px' }
|
||||
}"
|
||||
>
|
||||
<div *ngIf="isInformation(message); then information; else contents"></div>
|
||||
<ng-template #information>
|
||||
<ng-container
|
||||
|
|
|
@ -6,9 +6,12 @@ import {
|
|||
Output,
|
||||
AfterViewInit,
|
||||
ElementRef,
|
||||
ViewChild
|
||||
ViewChild,
|
||||
ChangeDetectorRef
|
||||
} from '@angular/core';
|
||||
|
||||
import { shakeAnimation } from 'angular-animations';
|
||||
|
||||
import {
|
||||
Info,
|
||||
EventType,
|
||||
|
@ -18,14 +21,14 @@ import {
|
|||
MassTranslationEventJson
|
||||
} from '@ucap-webmessenger/protocol-event';
|
||||
import { NGXLogger } from 'ngx-logger';
|
||||
import { DatePipe } from '@angular/common';
|
||||
import moment from 'moment';
|
||||
import { FileDownloadItem } from '@ucap-webmessenger/api';
|
||||
|
||||
@Component({
|
||||
selector: 'ucap-chat-message-box',
|
||||
templateUrl: './message-box.component.html',
|
||||
styleUrls: ['./message-box.component.scss']
|
||||
styleUrls: ['./message-box.component.scss'],
|
||||
animations: [shakeAnimation()]
|
||||
})
|
||||
export class MessageBoxComponent implements OnInit, AfterViewInit {
|
||||
@Input()
|
||||
|
@ -99,11 +102,11 @@ export class MessageBoxComponent implements OnInit, AfterViewInit {
|
|||
|
||||
firstEventSeq = 0;
|
||||
existReadHere = false;
|
||||
shakeIt = false;
|
||||
|
||||
constructor(
|
||||
private elementRef: ElementRef<HTMLElement>,
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
fxFlexFill
|
||||
#psChatContent
|
||||
[bufferAmount]="5"
|
||||
[compareItems]=""
|
||||
[compareItems]="compareItemsFunc"
|
||||
(psScrollUp)="onScrollup($event)"
|
||||
(psYReachStart)="onYReachStart($event)"
|
||||
(psYReachEnd)="onYReachEnd($event)"
|
||||
|
@ -53,6 +53,7 @@
|
|||
<!-- MESSAGE -->
|
||||
<div #container>
|
||||
<ucap-chat-message-box
|
||||
#chatMessageBox
|
||||
*ngFor="let message of scroll.viewPortItems; trackBy: trackByEvent"
|
||||
[id]="message.seq"
|
||||
[message]="message"
|
||||
|
|
|
@ -8,7 +8,9 @@ import {
|
|||
OnDestroy,
|
||||
ChangeDetectionStrategy,
|
||||
ElementRef,
|
||||
ChangeDetectorRef
|
||||
ChangeDetectorRef,
|
||||
ViewChildren,
|
||||
QueryList
|
||||
} from '@angular/core';
|
||||
|
||||
import {
|
||||
|
@ -23,12 +25,12 @@ import { LoginResponse } from '@ucap-webmessenger/protocol-authentication';
|
|||
import { UserInfo, RoomInfo, RoomType } from '@ucap-webmessenger/protocol-room';
|
||||
import { NGXLogger } from 'ngx-logger';
|
||||
import { VersionInfo2Response } from '@ucap-webmessenger/api-public';
|
||||
import { DatePipe } from '@angular/common';
|
||||
import moment from 'moment';
|
||||
import { FileDownloadItem } from '@ucap-webmessenger/api';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { Observable, Subscription } from 'rxjs';
|
||||
import { VirtualScrollerComponent, IPageInfo } from 'ngx-virtual-scroller';
|
||||
import { MessageBoxComponent } from './message-box.component';
|
||||
|
||||
@Component({
|
||||
selector: 'ucap-chat-messages',
|
||||
|
@ -113,6 +115,9 @@ export class MessagesComponent implements OnInit, OnDestroy {
|
|||
@ViewChild(VirtualScrollerComponent, { static: false })
|
||||
private virtualScroller: VirtualScrollerComponent;
|
||||
|
||||
@ViewChildren('chatMessageBox')
|
||||
chatMessageBoxList: QueryList<MessageBoxComponent>;
|
||||
|
||||
storedScrollItem: Info<EventJson>; // 이전대화를 불러올 경우 현재 스크롤 포지션 유지를 위한 값. 0 이면 초기로딩.
|
||||
scrollUpInitalized = false; // ps 에서 초기 로딩시 scroll reach start 이벤트 발생 버그를 우회하기 위한 init 값으로 scrollUp 에 의해 true 로 된다.
|
||||
firstCheckReadHere = true;
|
||||
|
@ -142,12 +147,10 @@ export class MessagesComponent implements OnInit, OnDestroy {
|
|||
|
||||
readToHereEvent: Info<EventJson>;
|
||||
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<EventJson>,
|
||||
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<EventJson>,
|
||||
item2: Info<EventJson>
|
||||
// tslint:disable-next-line: semicolon
|
||||
): boolean => item1.seq === item2.seq;
|
||||
): boolean => !!item1 && !!item2 && item1.seq === item2.seq;
|
||||
}
|
||||
|
|
|
@ -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';
|
||||
|
|
Loading…
Reference in New Issue
Block a user