Merge branch 'master' of https://git.loafle.net/ucap-web/next-ucap-messenger
This commit is contained in:
commit
04409d2546
|
@ -88,14 +88,15 @@
|
|||
</cdk-virtual-scroll-viewport>
|
||||
</div>
|
||||
<div *ngIf="isShowSearch" class="search-result">
|
||||
<cdk-virtual-scroll-viewport
|
||||
#cvsvDeptSearchUser
|
||||
itemSize="60"
|
||||
<virtual-scroller
|
||||
#vsDeptSearchUser
|
||||
[items]="searchUserInfos"
|
||||
perfectScrollbar
|
||||
fxFlexFill
|
||||
>
|
||||
<ucap-profile-user-list-item
|
||||
*cdkVirtualFor="let userInfo of searchUserInfos"
|
||||
style="height: 60px;"
|
||||
*ngFor="let userInfo of vsDeptSearchUser.viewPortItems"
|
||||
[userInfo]="userInfo"
|
||||
[checkable]="userInfo.seq !== loginRes.userSeq"
|
||||
[sessionVerinfo]="sessionVerinfo"
|
||||
|
@ -110,7 +111,7 @@
|
|||
matTooltipPosition="after"
|
||||
>
|
||||
</ucap-profile-user-list-item>
|
||||
</cdk-virtual-scroll-viewport>
|
||||
</virtual-scroller>
|
||||
</div>
|
||||
</div>
|
||||
<div *ngIf="!isUserSelect" class="btn-box">
|
||||
|
|
|
@ -66,6 +66,7 @@ import {
|
|||
} from '../../dialogs/organization/selected-user-list.dialog.component';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { StringFormatterPhonePipe } from 'projects/ucap-webmessenger-ui/src/lib/pipes/string.pipe';
|
||||
import { VirtualScrollerComponent } from 'ngx-virtual-scroller';
|
||||
|
||||
@Component({
|
||||
selector: 'app-layout-chat-left-sidenav-organization',
|
||||
|
@ -120,8 +121,9 @@ export class OrganizationComponent
|
|||
|
||||
@ViewChild('cvsvDeptUser', { static: false })
|
||||
cvsvDeptUser: CdkVirtualScrollViewport;
|
||||
@ViewChild('cvsvDeptSearchUser', { static: false })
|
||||
cvsvDeptSearchUser: CdkVirtualScrollViewport;
|
||||
|
||||
@ViewChild('vsDeptSearchUser', { static: false })
|
||||
private vsDeptSearchUser: VirtualScrollerComponent;
|
||||
|
||||
@ViewChild(PerfectScrollbarDirective, { static: false })
|
||||
psDirectiveRef?: PerfectScrollbarDirective;
|
||||
|
@ -306,8 +308,8 @@ export class OrganizationComponent
|
|||
this.searchUserInfos = searchUserInfos;
|
||||
this.selectedDepartmentProcessing = false;
|
||||
|
||||
if (!!this.cvsvDeptSearchUser) {
|
||||
this.cvsvDeptSearchUser.scrollToOffset(0);
|
||||
if (!!this.vsDeptSearchUser) {
|
||||
this.vsDeptSearchUser.scrollToIndex(0);
|
||||
}
|
||||
if (!!this.psDirectiveRef) {
|
||||
this.psDirectiveRef.update();
|
||||
|
|
|
@ -39,6 +39,7 @@ import { MatListModule } from '@angular/material/list';
|
|||
import { MatChipsModule } from '@angular/material/chips';
|
||||
|
||||
import { PerfectScrollbarModule } from 'ngx-perfect-scrollbar';
|
||||
import { VirtualScrollerModule } from 'ngx-virtual-scroller';
|
||||
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
|
||||
|
@ -93,6 +94,7 @@ import { DIALOGS } from './dialogs';
|
|||
MatSidenavModule,
|
||||
|
||||
PerfectScrollbarModule,
|
||||
VirtualScrollerModule,
|
||||
|
||||
TranslateModule,
|
||||
|
||||
|
|
|
@ -82,7 +82,9 @@
|
|||
</virtual-scroller>
|
||||
|
||||
<div
|
||||
#chatMessagesBuffer
|
||||
#chatMessagesBufferContainer
|
||||
fxFlexFill
|
||||
class="chat-messages-buffer disappear"
|
||||
></div>
|
||||
class="chat-messages-buffer-container disappear"
|
||||
>
|
||||
<div #chatMessagesBuffer fxFlexFill class="chat-messages-buffer"></div>
|
||||
</div>
|
||||
|
|
|
@ -164,10 +164,12 @@ $tablet-l-width: 1024px;
|
|||
display: none !important;
|
||||
}
|
||||
|
||||
.chat-messages-buffer {
|
||||
.chat-messages-buffer-container {
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
overflow-y: hidden !important;
|
||||
padding: 30px 40px;
|
||||
padding: 2vh 2vw;
|
||||
flex-direction: column;
|
||||
.chat-messages-buffer {
|
||||
}
|
||||
}
|
||||
|
|
|
@ -112,6 +112,9 @@ export class MessagesComponent implements OnInit, OnDestroy {
|
|||
@ViewChild('chatMessagesBuffer', { static: false })
|
||||
chatMessagesBuffer: ElementRef<HTMLElement>;
|
||||
|
||||
@ViewChild('chatMessagesBufferContainer', { static: false })
|
||||
chatMessagesBufferContainer: ElementRef<HTMLElement>;
|
||||
|
||||
@ViewChild(VirtualScrollerComponent, { static: false })
|
||||
private virtualScroller: VirtualScrollerComponent;
|
||||
|
||||
|
@ -148,6 +151,7 @@ export class MessagesComponent implements OnInit, OnDestroy {
|
|||
readToHereEvent: Info<EventJson>;
|
||||
existReadToHereEvent = true;
|
||||
hidden = false;
|
||||
swapped = false;
|
||||
|
||||
constructor(
|
||||
private logger: NGXLogger,
|
||||
|
@ -393,13 +397,14 @@ export class MessagesComponent implements OnInit, OnDestroy {
|
|||
];
|
||||
}
|
||||
|
||||
scrollTo(
|
||||
swapScrollTo(
|
||||
to: Info<EventJson>,
|
||||
preCallback: () => void,
|
||||
postCallback: () => void,
|
||||
useHide: boolean
|
||||
useHide: boolean,
|
||||
useSwap: boolean
|
||||
) {
|
||||
this.preSwapScroll(useHide);
|
||||
this.preSwapScroll(useHide, useSwap);
|
||||
if (!!preCallback) {
|
||||
preCallback();
|
||||
}
|
||||
|
@ -408,19 +413,35 @@ export class MessagesComponent implements OnInit, OnDestroy {
|
|||
if (!!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) {
|
||||
this.chatMessagesContainer.nativeElement.classList.add('hide');
|
||||
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) {
|
||||
this.chatMessagesContainer.nativeElement.classList.remove('hide');
|
||||
this.hidden = false;
|
||||
|
@ -434,12 +455,13 @@ export class MessagesComponent implements OnInit, OnDestroy {
|
|||
scrollToBottom(): void {
|
||||
if (!!this.storedScrollItem) {
|
||||
if (!!this.readToHereEvent && this.firstCheckReadHere) {
|
||||
this.scrollTo(
|
||||
this.swapScrollTo(
|
||||
this.readToHereEvent,
|
||||
() => {},
|
||||
() => {
|
||||
this.firstCheckReadHere = false;
|
||||
},
|
||||
true,
|
||||
true
|
||||
);
|
||||
} else {
|
||||
|
@ -447,13 +469,14 @@ export class MessagesComponent implements OnInit, OnDestroy {
|
|||
i => i.seq === this.storedScrollItem.seq
|
||||
);
|
||||
|
||||
this.scrollTo(
|
||||
this.swapScrollTo(
|
||||
1 <= index ? this.eventList[index - 1] : this.eventList[0],
|
||||
() => {},
|
||||
() => {
|
||||
this.storedScrollItem = undefined;
|
||||
},
|
||||
false
|
||||
true,
|
||||
true
|
||||
);
|
||||
}
|
||||
} else if (this.scrollUpInitalized) {
|
||||
|
@ -464,31 +487,34 @@ export class MessagesComponent implements OnInit, OnDestroy {
|
|||
}
|
||||
} else {
|
||||
if (!!this.readToHereEvent && this.firstCheckReadHere) {
|
||||
this.scrollTo(
|
||||
this.swapScrollTo(
|
||||
this.readToHereEvent,
|
||||
() => {},
|
||||
() => {
|
||||
this.firstCheckReadHere = false;
|
||||
},
|
||||
true
|
||||
true,
|
||||
false
|
||||
);
|
||||
} else {
|
||||
if (
|
||||
this.virtualScroller.viewPortInfo.endIndex ===
|
||||
this.eventList.length - 2
|
||||
) {
|
||||
this.scrollTo(
|
||||
this.swapScrollTo(
|
||||
this.eventList[this.eventList.length - 1],
|
||||
() => {},
|
||||
() => {},
|
||||
true,
|
||||
false
|
||||
);
|
||||
} else {
|
||||
this.scrollTo(
|
||||
this.swapScrollTo(
|
||||
this.eventList[this.eventList.length - 1],
|
||||
() => {},
|
||||
() => {},
|
||||
true
|
||||
true,
|
||||
false
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -534,7 +560,7 @@ export class MessagesComponent implements OnInit, OnDestroy {
|
|||
if (this.scrollUpInitalized && this.eventRemained) {
|
||||
this.storeScrollPosition();
|
||||
|
||||
this.preSwapScroll(false);
|
||||
this.preSwapScroll(true, true);
|
||||
|
||||
this.moreEvent.emit(this.eventList[0].seq);
|
||||
|
||||
|
|
|
@ -4,9 +4,6 @@ import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
|||
|
||||
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 { MatFormFieldModule } from '@angular/material/form-field';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
|
@ -78,9 +75,6 @@ const PROVIDERS = [DatePipe];
|
|||
ReactiveFormsModule,
|
||||
FlexLayoutModule,
|
||||
|
||||
ScrollingModule,
|
||||
ExperimentalScrollingModule,
|
||||
|
||||
MatFormFieldModule,
|
||||
MatIconModule,
|
||||
MatInputModule,
|
||||
|
|
|
@ -86,14 +86,22 @@
|
|||
</div>
|
||||
<div class="ucap-video-viewer-body">
|
||||
<div
|
||||
#videoContainer
|
||||
class="ucap-video-viewer-video-icon"
|
||||
fxLayout="row"
|
||||
fxLayout.xs="column"
|
||||
fxLayoutAlign="center center"
|
||||
>
|
||||
<video
|
||||
[src]="fileDownloadUrl"
|
||||
#audioPlayer
|
||||
[src]="fileDownloadUrl"
|
||||
[style.width]="'auto'"
|
||||
[style.height]="
|
||||
videoHeight > videoContainer.clientHeight
|
||||
? ((videoContainer.clientHeight - 20) / videoHeight) * videoHeight +
|
||||
'px'
|
||||
: videoHeight + 'px'
|
||||
"
|
||||
(playing)="onPlayingVideo()"
|
||||
(pause)="onPauseVideo()"
|
||||
(timeupdate)="onTimeUpdateVideo()"
|
||||
|
@ -124,7 +132,7 @@
|
|||
fxLayout.xs="column"
|
||||
>
|
||||
<div class="ucap-video-viewer-video-time-current">
|
||||
{{ currentTime | ucapSecondsToMinutes }}
|
||||
{{ Math.floor(currentTime) | ucapSecondsToMinutes }}
|
||||
</div>
|
||||
<span class="ucap-video-viewer-spacer"></span>
|
||||
<button
|
||||
|
@ -148,7 +156,7 @@
|
|||
</button>
|
||||
<span class="ucap-video-viewer-spacer"></span>
|
||||
<div class="ucap-video-viewer-video-time-total">
|
||||
{{ duration | ucapSecondsToMinutes }}
|
||||
{{ Math.floor(duration) | ucapSecondsToMinutes }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -5,12 +5,14 @@ import {
|
|||
Output,
|
||||
EventEmitter,
|
||||
ViewChild,
|
||||
ElementRef
|
||||
ElementRef,
|
||||
ChangeDetectorRef
|
||||
} from '@angular/core';
|
||||
import { ucapAnimations } from '../../animations';
|
||||
import { FileEventJson } from '@ucap-webmessenger/protocol-event';
|
||||
import { MatSlider, MatSliderChange } from '@angular/material';
|
||||
import { FileDownloadItem } from '@ucap-webmessenger/api';
|
||||
import { NGXLogger } from 'ngx-logger';
|
||||
|
||||
@Component({
|
||||
selector: 'ucap-video-viewer',
|
||||
|
@ -38,13 +40,21 @@ export class VideoViewerComponent implements OnInit {
|
|||
timeSlider: MatSlider;
|
||||
|
||||
playing = false;
|
||||
duration = 0.01;
|
||||
currentTime = 0;
|
||||
duration = 0.0;
|
||||
currentTime = 0.0;
|
||||
volume = 0.1;
|
||||
loading = false;
|
||||
fileDownloadItem: FileDownloadItem;
|
||||
|
||||
constructor() {}
|
||||
videoWidth = 0;
|
||||
videoHeight = 0;
|
||||
|
||||
Math = Math;
|
||||
|
||||
constructor(
|
||||
private changeDetectorRef: ChangeDetectorRef,
|
||||
private logger: NGXLogger
|
||||
) {}
|
||||
|
||||
ngOnInit() {}
|
||||
|
||||
|
@ -74,11 +84,11 @@ export class VideoViewerComponent implements OnInit {
|
|||
}
|
||||
|
||||
onTimeUpdateVideo(): void {
|
||||
this.currentTime = Math.floor(this.audioPlayer.nativeElement.currentTime);
|
||||
this.currentTime = this.audioPlayer.nativeElement.currentTime;
|
||||
}
|
||||
|
||||
onVolumeChangeVideo(): void {
|
||||
this.volume = Math.floor(this.audioPlayer.nativeElement.volume);
|
||||
this.volume = this.audioPlayer.nativeElement.volume;
|
||||
}
|
||||
|
||||
onLoadStartVideo(): void {
|
||||
|
@ -87,7 +97,10 @@ export class VideoViewerComponent implements OnInit {
|
|||
|
||||
onLoadedDataVideo(): void {
|
||||
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 {
|
||||
|
|
Loading…
Reference in New Issue
Block a user