This commit is contained in:
leejinho 2020-01-30 17:16:40 +09:00
commit 04409d2546
9 changed files with 95 additions and 45 deletions

View File

@ -88,14 +88,15 @@
</cdk-virtual-scroll-viewport> </cdk-virtual-scroll-viewport>
</div> </div>
<div *ngIf="isShowSearch" class="search-result"> <div *ngIf="isShowSearch" class="search-result">
<cdk-virtual-scroll-viewport <virtual-scroller
#cvsvDeptSearchUser #vsDeptSearchUser
itemSize="60" [items]="searchUserInfos"
perfectScrollbar perfectScrollbar
fxFlexFill fxFlexFill
> >
<ucap-profile-user-list-item <ucap-profile-user-list-item
*cdkVirtualFor="let userInfo of searchUserInfos" style="height: 60px;"
*ngFor="let userInfo of vsDeptSearchUser.viewPortItems"
[userInfo]="userInfo" [userInfo]="userInfo"
[checkable]="userInfo.seq !== loginRes.userSeq" [checkable]="userInfo.seq !== loginRes.userSeq"
[sessionVerinfo]="sessionVerinfo" [sessionVerinfo]="sessionVerinfo"
@ -110,7 +111,7 @@
matTooltipPosition="after" matTooltipPosition="after"
> >
</ucap-profile-user-list-item> </ucap-profile-user-list-item>
</cdk-virtual-scroll-viewport> </virtual-scroller>
</div> </div>
</div> </div>
<div *ngIf="!isUserSelect" class="btn-box"> <div *ngIf="!isUserSelect" class="btn-box">

View File

@ -66,6 +66,7 @@ import {
} from '../../dialogs/organization/selected-user-list.dialog.component'; } from '../../dialogs/organization/selected-user-list.dialog.component';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { StringFormatterPhonePipe } from 'projects/ucap-webmessenger-ui/src/lib/pipes/string.pipe'; import { StringFormatterPhonePipe } from 'projects/ucap-webmessenger-ui/src/lib/pipes/string.pipe';
import { VirtualScrollerComponent } from 'ngx-virtual-scroller';
@Component({ @Component({
selector: 'app-layout-chat-left-sidenav-organization', selector: 'app-layout-chat-left-sidenav-organization',
@ -120,8 +121,9 @@ export class OrganizationComponent
@ViewChild('cvsvDeptUser', { static: false }) @ViewChild('cvsvDeptUser', { static: false })
cvsvDeptUser: CdkVirtualScrollViewport; cvsvDeptUser: CdkVirtualScrollViewport;
@ViewChild('cvsvDeptSearchUser', { static: false })
cvsvDeptSearchUser: CdkVirtualScrollViewport; @ViewChild('vsDeptSearchUser', { static: false })
private vsDeptSearchUser: VirtualScrollerComponent;
@ViewChild(PerfectScrollbarDirective, { static: false }) @ViewChild(PerfectScrollbarDirective, { static: false })
psDirectiveRef?: PerfectScrollbarDirective; psDirectiveRef?: PerfectScrollbarDirective;
@ -306,8 +308,8 @@ export class OrganizationComponent
this.searchUserInfos = searchUserInfos; this.searchUserInfos = searchUserInfos;
this.selectedDepartmentProcessing = false; this.selectedDepartmentProcessing = false;
if (!!this.cvsvDeptSearchUser) { if (!!this.vsDeptSearchUser) {
this.cvsvDeptSearchUser.scrollToOffset(0); this.vsDeptSearchUser.scrollToIndex(0);
} }
if (!!this.psDirectiveRef) { if (!!this.psDirectiveRef) {
this.psDirectiveRef.update(); this.psDirectiveRef.update();

View File

@ -39,6 +39,7 @@ import { MatListModule } from '@angular/material/list';
import { MatChipsModule } from '@angular/material/chips'; import { MatChipsModule } from '@angular/material/chips';
import { PerfectScrollbarModule } from 'ngx-perfect-scrollbar'; import { PerfectScrollbarModule } from 'ngx-perfect-scrollbar';
import { VirtualScrollerModule } from 'ngx-virtual-scroller';
import { TranslateModule } from '@ngx-translate/core'; import { TranslateModule } from '@ngx-translate/core';
@ -93,6 +94,7 @@ import { DIALOGS } from './dialogs';
MatSidenavModule, MatSidenavModule,
PerfectScrollbarModule, PerfectScrollbarModule,
VirtualScrollerModule,
TranslateModule, TranslateModule,

View File

@ -82,7 +82,9 @@
</virtual-scroller> </virtual-scroller>
<div <div
#chatMessagesBuffer #chatMessagesBufferContainer
fxFlexFill fxFlexFill
class="chat-messages-buffer disappear" class="chat-messages-buffer-container disappear"
></div> >
<div #chatMessagesBuffer fxFlexFill class="chat-messages-buffer"></div>
</div>

View File

@ -164,10 +164,12 @@ $tablet-l-width: 1024px;
display: none !important; display: none !important;
} }
.chat-messages-buffer { .chat-messages-buffer-container {
position: absolute; position: absolute;
top: 0px; top: 0px;
overflow-y: hidden !important; overflow-y: hidden !important;
padding: 30px 40px; padding: 2vh 2vw;
flex-direction: column; flex-direction: column;
.chat-messages-buffer {
}
} }

View File

@ -112,6 +112,9 @@ export class MessagesComponent implements OnInit, OnDestroy {
@ViewChild('chatMessagesBuffer', { static: false }) @ViewChild('chatMessagesBuffer', { static: false })
chatMessagesBuffer: ElementRef<HTMLElement>; chatMessagesBuffer: ElementRef<HTMLElement>;
@ViewChild('chatMessagesBufferContainer', { static: false })
chatMessagesBufferContainer: ElementRef<HTMLElement>;
@ViewChild(VirtualScrollerComponent, { static: false }) @ViewChild(VirtualScrollerComponent, { static: false })
private virtualScroller: VirtualScrollerComponent; private virtualScroller: VirtualScrollerComponent;
@ -148,6 +151,7 @@ export class MessagesComponent implements OnInit, OnDestroy {
readToHereEvent: Info<EventJson>; readToHereEvent: Info<EventJson>;
existReadToHereEvent = true; existReadToHereEvent = true;
hidden = false; hidden = false;
swapped = false;
constructor( constructor(
private logger: NGXLogger, private logger: NGXLogger,
@ -393,13 +397,14 @@ export class MessagesComponent implements OnInit, OnDestroy {
]; ];
} }
scrollTo( swapScrollTo(
to: Info<EventJson>, to: Info<EventJson>,
preCallback: () => void, preCallback: () => void,
postCallback: () => void, postCallback: () => void,
useHide: boolean useHide: boolean,
useSwap: boolean
) { ) {
this.preSwapScroll(useHide); this.preSwapScroll(useHide, useSwap);
if (!!preCallback) { if (!!preCallback) {
preCallback(); preCallback();
} }
@ -408,19 +413,35 @@ export class MessagesComponent implements OnInit, OnDestroy {
if (!!postCallback) { if (!!postCallback) {
postCallback(); postCallback();
} }
this.postSwapScroll(useHide); this.postSwapScroll(useHide, useSwap);
}); });
}); });
} }
preSwapScroll(useHide: boolean) { 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.chatMessagesBufferContainer.nativeElement.classList.remove(
'disappear'
);
this.swapped = true;
}
if (useHide && !this.hidden) { if (useHide && !this.hidden) {
this.chatMessagesContainer.nativeElement.classList.add('hide'); this.chatMessagesContainer.nativeElement.classList.add('hide');
this.hidden = true; this.hidden = true;
} }
} }
postSwapScroll(useHide: boolean) { postSwapScroll(useHide: boolean, useSwap: boolean) {
if (useSwap && this.swapped) {
this.chatMessagesBuffer.nativeElement.innerHTML = '';
this.chatMessagesBuffer.nativeElement.scrollTop = 0;
this.chatMessagesBufferContainer.nativeElement.classList.add('disappear');
this.swapped = false;
}
if (useHide && this.hidden) { if (useHide && this.hidden) {
this.chatMessagesContainer.nativeElement.classList.remove('hide'); this.chatMessagesContainer.nativeElement.classList.remove('hide');
this.hidden = false; this.hidden = false;
@ -434,12 +455,13 @@ export class MessagesComponent implements OnInit, OnDestroy {
scrollToBottom(): void { scrollToBottom(): void {
if (!!this.storedScrollItem) { if (!!this.storedScrollItem) {
if (!!this.readToHereEvent && this.firstCheckReadHere) { if (!!this.readToHereEvent && this.firstCheckReadHere) {
this.scrollTo( this.swapScrollTo(
this.readToHereEvent, this.readToHereEvent,
() => {}, () => {},
() => { () => {
this.firstCheckReadHere = false; this.firstCheckReadHere = false;
}, },
true,
true true
); );
} else { } else {
@ -447,13 +469,14 @@ export class MessagesComponent implements OnInit, OnDestroy {
i => i.seq === this.storedScrollItem.seq i => i.seq === this.storedScrollItem.seq
); );
this.scrollTo( this.swapScrollTo(
1 <= index ? this.eventList[index - 1] : this.eventList[0], 1 <= index ? this.eventList[index - 1] : this.eventList[0],
() => {}, () => {},
() => { () => {
this.storedScrollItem = undefined; this.storedScrollItem = undefined;
}, },
false true,
true
); );
} }
} else if (this.scrollUpInitalized) { } else if (this.scrollUpInitalized) {
@ -464,31 +487,34 @@ export class MessagesComponent implements OnInit, OnDestroy {
} }
} else { } else {
if (!!this.readToHereEvent && this.firstCheckReadHere) { if (!!this.readToHereEvent && this.firstCheckReadHere) {
this.scrollTo( this.swapScrollTo(
this.readToHereEvent, this.readToHereEvent,
() => {}, () => {},
() => { () => {
this.firstCheckReadHere = false; this.firstCheckReadHere = false;
}, },
true true,
false
); );
} else { } else {
if ( if (
this.virtualScroller.viewPortInfo.endIndex === this.virtualScroller.viewPortInfo.endIndex ===
this.eventList.length - 2 this.eventList.length - 2
) { ) {
this.scrollTo( this.swapScrollTo(
this.eventList[this.eventList.length - 1], this.eventList[this.eventList.length - 1],
() => {}, () => {},
() => {}, () => {},
true,
false false
); );
} else { } else {
this.scrollTo( this.swapScrollTo(
this.eventList[this.eventList.length - 1], this.eventList[this.eventList.length - 1],
() => {}, () => {},
() => {}, () => {},
true true,
false
); );
} }
} }
@ -534,7 +560,7 @@ export class MessagesComponent implements OnInit, OnDestroy {
if (this.scrollUpInitalized && this.eventRemained) { if (this.scrollUpInitalized && this.eventRemained) {
this.storeScrollPosition(); this.storeScrollPosition();
this.preSwapScroll(false); this.preSwapScroll(true, true);
this.moreEvent.emit(this.eventList[0].seq); this.moreEvent.emit(this.eventList[0].seq);

View File

@ -4,9 +4,6 @@ import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { FlexLayoutModule } from '@angular/flex-layout'; import { FlexLayoutModule } from '@angular/flex-layout';
import { ScrollingModule } from '@angular/cdk/scrolling';
import { ScrollingModule as ExperimentalScrollingModule } from '@angular/cdk-experimental/scrolling';
import { MatTooltipModule } from '@angular/material'; import { MatTooltipModule } from '@angular/material';
import { MatFormFieldModule } from '@angular/material/form-field'; import { MatFormFieldModule } from '@angular/material/form-field';
import { MatIconModule } from '@angular/material/icon'; import { MatIconModule } from '@angular/material/icon';
@ -78,9 +75,6 @@ const PROVIDERS = [DatePipe];
ReactiveFormsModule, ReactiveFormsModule,
FlexLayoutModule, FlexLayoutModule,
ScrollingModule,
ExperimentalScrollingModule,
MatFormFieldModule, MatFormFieldModule,
MatIconModule, MatIconModule,
MatInputModule, MatInputModule,

View File

@ -86,14 +86,22 @@
</div> </div>
<div class="ucap-video-viewer-body"> <div class="ucap-video-viewer-body">
<div <div
#videoContainer
class="ucap-video-viewer-video-icon" class="ucap-video-viewer-video-icon"
fxLayout="row" fxLayout="row"
fxLayout.xs="column" fxLayout.xs="column"
fxLayoutAlign="center center" fxLayoutAlign="center center"
> >
<video <video
[src]="fileDownloadUrl"
#audioPlayer #audioPlayer
[src]="fileDownloadUrl"
[style.width]="'auto'"
[style.height]="
videoHeight > videoContainer.clientHeight
? ((videoContainer.clientHeight - 20) / videoHeight) * videoHeight +
'px'
: videoHeight + 'px'
"
(playing)="onPlayingVideo()" (playing)="onPlayingVideo()"
(pause)="onPauseVideo()" (pause)="onPauseVideo()"
(timeupdate)="onTimeUpdateVideo()" (timeupdate)="onTimeUpdateVideo()"
@ -124,7 +132,7 @@
fxLayout.xs="column" fxLayout.xs="column"
> >
<div class="ucap-video-viewer-video-time-current"> <div class="ucap-video-viewer-video-time-current">
{{ currentTime | ucapSecondsToMinutes }} {{ Math.floor(currentTime) | ucapSecondsToMinutes }}
</div> </div>
<span class="ucap-video-viewer-spacer"></span> <span class="ucap-video-viewer-spacer"></span>
<button <button
@ -148,7 +156,7 @@
</button> </button>
<span class="ucap-video-viewer-spacer"></span> <span class="ucap-video-viewer-spacer"></span>
<div class="ucap-video-viewer-video-time-total"> <div class="ucap-video-viewer-video-time-total">
{{ duration | ucapSecondsToMinutes }} {{ Math.floor(duration) | ucapSecondsToMinutes }}
</div> </div>
</div> </div>
</div> </div>

View File

@ -5,12 +5,14 @@ import {
Output, Output,
EventEmitter, EventEmitter,
ViewChild, ViewChild,
ElementRef ElementRef,
ChangeDetectorRef
} from '@angular/core'; } from '@angular/core';
import { ucapAnimations } from '../../animations'; import { ucapAnimations } from '../../animations';
import { FileEventJson } from '@ucap-webmessenger/protocol-event'; import { FileEventJson } from '@ucap-webmessenger/protocol-event';
import { MatSlider, MatSliderChange } from '@angular/material'; import { MatSlider, MatSliderChange } from '@angular/material';
import { FileDownloadItem } from '@ucap-webmessenger/api'; import { FileDownloadItem } from '@ucap-webmessenger/api';
import { NGXLogger } from 'ngx-logger';
@Component({ @Component({
selector: 'ucap-video-viewer', selector: 'ucap-video-viewer',
@ -38,13 +40,21 @@ export class VideoViewerComponent implements OnInit {
timeSlider: MatSlider; timeSlider: MatSlider;
playing = false; playing = false;
duration = 0.01; duration = 0.0;
currentTime = 0; currentTime = 0.0;
volume = 0.1; volume = 0.1;
loading = false; loading = false;
fileDownloadItem: FileDownloadItem; fileDownloadItem: FileDownloadItem;
constructor() {} videoWidth = 0;
videoHeight = 0;
Math = Math;
constructor(
private changeDetectorRef: ChangeDetectorRef,
private logger: NGXLogger
) {}
ngOnInit() {} ngOnInit() {}
@ -74,11 +84,11 @@ export class VideoViewerComponent implements OnInit {
} }
onTimeUpdateVideo(): void { onTimeUpdateVideo(): void {
this.currentTime = Math.floor(this.audioPlayer.nativeElement.currentTime); this.currentTime = this.audioPlayer.nativeElement.currentTime;
} }
onVolumeChangeVideo(): void { onVolumeChangeVideo(): void {
this.volume = Math.floor(this.audioPlayer.nativeElement.volume); this.volume = this.audioPlayer.nativeElement.volume;
} }
onLoadStartVideo(): void { onLoadStartVideo(): void {
@ -87,7 +97,10 @@ export class VideoViewerComponent implements OnInit {
onLoadedDataVideo(): void { onLoadedDataVideo(): void {
this.loading = false; this.loading = false;
this.duration = Math.floor(this.audioPlayer.nativeElement.duration); this.duration = this.audioPlayer.nativeElement.duration;
this.videoWidth = this.audioPlayer.nativeElement.videoWidth;
this.videoHeight = this.audioPlayer.nativeElement.videoHeight;
} }
onClickDownload(): void { onClickDownload(): void {