animation of chat search is added

This commit is contained in:
richard-loafle 2020-01-30 14:12:51 +09:00
parent dd23462374
commit d23efa7b8e
7 changed files with 83 additions and 56 deletions

11
package-lock.json generated
View File

@ -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",

View File

@ -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",

View File

@ -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

View File

@ -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);
}
}

View File

@ -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"

View File

@ -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;
}

View File

@ -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';