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>
|
</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">
|
||||||
|
@ -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();
|
||||||
|
@ -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,
|
||||||
|
|
||||||
|
@ -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>
|
||||||
|
@ -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 {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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,
|
||||||
|
@ -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>
|
||||||
|
@ -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 {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user