mirror of https://github.com/OpenVidu/openvidu.git
openvidu-components: Updated layout elements transitons
parent
4fd2fc8595
commit
25972260ac
|
@ -1,6 +1,6 @@
|
||||||
<div class="container" [class.withSubtitles]="subtitlesEnabled">
|
<div class="container" [class.withSubtitles]="subtitlesEnabled">
|
||||||
<div id="layout" class="layout">
|
<div id="layout" class="layout" #layout>
|
||||||
<div class="OT_root OT_publisher" *ngFor="let stream of localParticipant | streams" [ngClass]="{ OV_big: stream.videoEnlarged }">
|
<div *ngFor="let stream of localParticipant | streams" [ngClass]="{ OV_big: stream.videoEnlarged }" class="OT_root OT_publisher">
|
||||||
<ng-container *ngTemplateOutlet="streamTemplate; context: { $implicit: stream }"></ng-container>
|
<ng-container *ngTemplateOutlet="streamTemplate; context: { $implicit: stream }"></ng-container>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,9 @@ import {
|
||||||
ContentChild,
|
ContentChild,
|
||||||
OnDestroy,
|
OnDestroy,
|
||||||
OnInit,
|
OnInit,
|
||||||
TemplateRef
|
TemplateRef,
|
||||||
|
ViewChild,
|
||||||
|
ViewContainerRef
|
||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
import { Subscription } from 'rxjs';
|
import { Subscription } from 'rxjs';
|
||||||
import { ParticipantService } from '../../services/participant/participant.service';
|
import { ParticipantService } from '../../services/participant/participant.service';
|
||||||
|
@ -59,6 +61,10 @@ export class LayoutComponent implements OnInit, OnDestroy, AfterViewInit {
|
||||||
*/
|
*/
|
||||||
@ContentChild('stream', { read: TemplateRef }) streamTemplate: TemplateRef<any>;
|
@ContentChild('stream', { read: TemplateRef }) streamTemplate: TemplateRef<any>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ignore
|
||||||
|
*/
|
||||||
|
@ViewChild('layout', { static: false, read: ViewContainerRef }) layoutContainer: ViewContainerRef;
|
||||||
/**
|
/**
|
||||||
* @ignore
|
* @ignore
|
||||||
*/
|
*/
|
||||||
|
@ -93,9 +99,7 @@ export class LayoutComponent implements OnInit, OnDestroy, AfterViewInit {
|
||||||
}
|
}
|
||||||
|
|
||||||
ngAfterViewInit() {
|
ngAfterViewInit() {
|
||||||
let timeout: number = 100;
|
this.layoutService.initialize(this.layoutContainer.element.nativeElement);
|
||||||
this.layoutService.initialize(timeout);
|
|
||||||
this.layoutService.update(timeout);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnDestroy() {
|
ngOnDestroy() {
|
||||||
|
|
|
@ -107,7 +107,7 @@
|
||||||
height: 100%;
|
height: 100%;
|
||||||
position: relative;
|
position: relative;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
background-color: #000000;
|
background-color: transparent;
|
||||||
border-radius: var(--ov-video-radius);
|
border-radius: var(--ov-video-radius);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
<div
|
<div
|
||||||
*ngIf="this._stream"
|
*ngIf="this._stream"
|
||||||
class="OV_stream no-size"
|
class="OV_stream"
|
||||||
|
[ngClass]="{'no-size': !showVideo}"
|
||||||
[id]="'container-' + this._stream.streamManager?.stream?.streamId"
|
[id]="'container-' + this._stream.streamManager?.stream?.streamId"
|
||||||
#streamContainer
|
#streamContainer
|
||||||
>
|
>
|
||||||
|
@ -65,14 +66,6 @@
|
||||||
<mat-icon *ngIf="_stream.participant.isMutedForcibly">volume_off</mat-icon>
|
<mat-icon *ngIf="_stream.participant.isMutedForcibly">volume_off</mat-icon>
|
||||||
<span *ngIf="_stream.participant.isMutedForcibly">{{ 'STREAM.UNMUTE_SOUND' | translate }}</span>
|
<span *ngIf="_stream.participant.isMutedForcibly">{{ 'STREAM.UNMUTE_SOUND' | translate }}</span>
|
||||||
</button>
|
</button>
|
||||||
<!-- <button mat-menu-item *ngIf="this._stream.streamManager?.stream?.videoActive" id="fullscreenButton" (click)="toggleFullscreen()">
|
|
||||||
<mat-icon *ngIf="!isFullscreenEnabled">fullscreen</mat-icon>
|
|
||||||
<span *ngIf="!isFullscreenEnabled">Fullscreen</span>
|
|
||||||
|
|
||||||
<mat-icon *ngIf="isFullscreenEnabled">fullscreen_exit</mat-icon>
|
|
||||||
<span *ngIf="isFullscreenEnabled">Exit fullscreen</span>
|
|
||||||
</button> -->
|
|
||||||
|
|
||||||
<button
|
<button
|
||||||
mat-menu-item
|
mat-menu-item
|
||||||
(click)="replaceScreenTrack()"
|
(click)="replaceScreenTrack()"
|
||||||
|
|
|
@ -3,7 +3,6 @@ import { Subscription } from 'rxjs';
|
||||||
import { MatMenuPanel, MatMenuTrigger } from '@angular/material/menu';
|
import { MatMenuPanel, MatMenuTrigger } from '@angular/material/menu';
|
||||||
import { VideoSizeIcon } from '../../models/icon.model';
|
import { VideoSizeIcon } from '../../models/icon.model';
|
||||||
import { ScreenType, VideoType } from '../../models/video-type.model';
|
import { ScreenType, VideoType } from '../../models/video-type.model';
|
||||||
import { DocumentService } from '../../services/document/document.service';
|
|
||||||
import { CdkOverlayService } from '../../services/cdk-overlay/cdk-overlay.service';
|
import { CdkOverlayService } from '../../services/cdk-overlay/cdk-overlay.service';
|
||||||
import { OpenViduService } from '../../services/openvidu/openvidu.service';
|
import { OpenViduService } from '../../services/openvidu/openvidu.service';
|
||||||
import { LayoutService } from '../../services/layout/layout.service';
|
import { LayoutService } from '../../services/layout/layout.service';
|
||||||
|
@ -109,6 +108,7 @@ export class StreamComponent implements OnInit {
|
||||||
* @ignore
|
* @ignore
|
||||||
*/
|
*/
|
||||||
showSettingsButton: boolean = true;
|
showSettingsButton: boolean = true;
|
||||||
|
showVideo: boolean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ignore
|
* @ignore
|
||||||
|
@ -118,9 +118,10 @@ export class StreamComponent implements OnInit {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if (streamContainer) {
|
if (streamContainer) {
|
||||||
this._streamContainer = streamContainer;
|
this._streamContainer = streamContainer;
|
||||||
// Remove 'no-size' css class for showing the element in the view.
|
|
||||||
// This is a workaround for fixing a layout bug which provide a bad UX with each new elements created.
|
// This is a workaround for fixing a layout bug which provide a bad UX with each new elements created.
|
||||||
this.documentService.removeNoSizeElementClass(this._streamContainer.nativeElement);
|
setTimeout(() => {
|
||||||
|
this.showVideo = true;
|
||||||
|
}, 100);
|
||||||
}
|
}
|
||||||
}, 0);
|
}, 0);
|
||||||
}
|
}
|
||||||
|
@ -154,7 +155,6 @@ export class StreamComponent implements OnInit {
|
||||||
* @ignore
|
* @ignore
|
||||||
*/
|
*/
|
||||||
constructor(
|
constructor(
|
||||||
protected documentService: DocumentService,
|
|
||||||
protected openviduService: OpenViduService,
|
protected openviduService: OpenViduService,
|
||||||
protected layoutService: LayoutService,
|
protected layoutService: LayoutService,
|
||||||
protected participantService: ParticipantService,
|
protected participantService: ParticipantService,
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
#call-container, #session-container {
|
#call-container, #session-container {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
#session-container {
|
||||||
|
background-color: var(--ov-primary-color);
|
||||||
|
}
|
||||||
|
|
||||||
#pre-join-container {
|
#pre-join-container {
|
||||||
height: inherit;
|
height: inherit;
|
||||||
|
|
|
@ -1,20 +1,20 @@
|
||||||
<div id="call-container">
|
<div id="call-container">
|
||||||
|
|
||||||
<div id="pre-join-container" *ngIf="showPrejoin && tokensReceived && participantReady">
|
<div id="spinner" *ngIf="loading" >
|
||||||
<ov-pre-join (onJoinButtonClicked)="_onJoinButtonClicked()"></ov-pre-join>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="spinner" *ngIf="!participantReady && !streamPlaying && !error">
|
|
||||||
<mat-spinner [diameter]="50"></mat-spinner>
|
<mat-spinner [diameter]="50"></mat-spinner>
|
||||||
<span>{{ 'PREJOIN.PREPARING' | translate }}</span>
|
<span>{{ 'PREJOIN.PREPARING' | translate }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="spinner" *ngIf="!participantReady && error">
|
<div [@inOutAnimation] id="pre-join-container" *ngIf="showPrejoin && participantReady && !loading">
|
||||||
|
<ov-pre-join (onJoinButtonClicked)="_onJoinButtonClicked()"></ov-pre-join>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="spinner" *ngIf="!loading && error">
|
||||||
<mat-icon class="error-icon">error</mat-icon>
|
<mat-icon class="error-icon">error</mat-icon>
|
||||||
<span>{{ errorMessage }}</span>
|
<span>{{ errorMessage }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="session-container" *ngIf="showVideoconference || (!showPrejoin && participantReady && tokensReceived && !error)">
|
<div [@inOutAnimation] id="session-container" *ngIf="showVideoconference || (!showPrejoin && !loading && !error)">
|
||||||
<ov-session (onSessionCreated)="_onSessionCreated($event)">
|
<ov-session (onSessionCreated)="_onSessionCreated($event)">
|
||||||
<ng-template #toolbar>
|
<ng-template #toolbar>
|
||||||
<ng-container *ngIf="openviduAngularToolbarTemplate">
|
<ng-container *ngIf="openviduAngularToolbarTemplate">
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { trigger, state, style, transition, animate } from '@angular/animations';
|
||||||
import {
|
import {
|
||||||
AfterViewInit,
|
AfterViewInit,
|
||||||
Component,
|
Component,
|
||||||
|
@ -110,7 +111,13 @@ import { TranslateService } from '../../services/translate/translate.service';
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ov-videoconference',
|
selector: 'ov-videoconference',
|
||||||
templateUrl: './videoconference.component.html',
|
templateUrl: './videoconference.component.html',
|
||||||
styleUrls: ['./videoconference.component.css']
|
styleUrls: ['./videoconference.component.css'],
|
||||||
|
animations: [
|
||||||
|
trigger('inOutAnimation', [
|
||||||
|
transition(':enter', [style({ opacity: 0 }), animate('300ms ease-out', style({ opacity: 1 }))]),
|
||||||
|
// transition(':leave', [style({ opacity: 1 }), animate('50ms ease-in', style({ opacity: 0.9 }))])
|
||||||
|
])
|
||||||
|
]
|
||||||
})
|
})
|
||||||
export class VideoconferenceComponent implements OnInit, OnDestroy, AfterViewInit {
|
export class VideoconferenceComponent implements OnInit, OnDestroy, AfterViewInit {
|
||||||
// *** Toolbar ***
|
// *** Toolbar ***
|
||||||
|
@ -186,7 +193,6 @@ export class VideoconferenceComponent implements OnInit, OnDestroy, AfterViewIni
|
||||||
*/
|
*/
|
||||||
@ViewChild('defaultParticipantsPanel', { static: false, read: TemplateRef }) defaultParticipantsPanelTemplate: TemplateRef<any>;
|
@ViewChild('defaultParticipantsPanel', { static: false, read: TemplateRef }) defaultParticipantsPanelTemplate: TemplateRef<any>;
|
||||||
/**
|
/**
|
||||||
* TODO: WIP
|
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
@ViewChild('defaultActivitiesPanel', { static: false, read: TemplateRef })
|
@ViewChild('defaultActivitiesPanel', { static: false, read: TemplateRef })
|
||||||
|
@ -214,7 +220,6 @@ export class VideoconferenceComponent implements OnInit, OnDestroy, AfterViewIni
|
||||||
*/
|
*/
|
||||||
openviduAngularToolbarAdditionalButtonsTemplate: TemplateRef<any>;
|
openviduAngularToolbarAdditionalButtonsTemplate: TemplateRef<any>;
|
||||||
/**
|
/**
|
||||||
* TODO: WIP
|
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
openviduAngularActivitiesPanelTemplate: TemplateRef<any>;
|
openviduAngularActivitiesPanelTemplate: TemplateRef<any>;
|
||||||
|
@ -281,7 +286,7 @@ export class VideoconferenceComponent implements OnInit, OnDestroy, AfterViewIni
|
||||||
} else {
|
} else {
|
||||||
this.log.w('No screen token found. Screenshare feature will be disabled');
|
this.log.w('No screen token found. Screenshare feature will be disabled');
|
||||||
}
|
}
|
||||||
this.tokensReceived = true;
|
this.loading = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -382,10 +387,7 @@ export class VideoconferenceComponent implements OnInit, OnDestroy, AfterViewIni
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
participantReady: boolean = false;
|
participantReady: boolean = false;
|
||||||
/**
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
tokensReceived: boolean = false;
|
|
||||||
/**
|
/**
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
|
@ -399,7 +401,10 @@ export class VideoconferenceComponent implements OnInit, OnDestroy, AfterViewIni
|
||||||
*/
|
*/
|
||||||
showPrejoin: boolean = true;
|
showPrejoin: boolean = true;
|
||||||
|
|
||||||
streamPlaying = false;
|
/**
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
loading = true;
|
||||||
private externalParticipantName: string;
|
private externalParticipantName: string;
|
||||||
private prejoinSub: Subscription;
|
private prejoinSub: Subscription;
|
||||||
private participantNameSub: Subscription;
|
private participantNameSub: Subscription;
|
||||||
|
@ -449,7 +454,7 @@ export class VideoconferenceComponent implements OnInit, OnDestroy, AfterViewIni
|
||||||
await this.handlePublisherSuccess();
|
await this.handlePublisherSuccess();
|
||||||
this.participantReady = true;
|
this.participantReady = true;
|
||||||
});
|
});
|
||||||
publisher.once('streamPlaying', () => (this.streamPlaying = true));
|
// publisher.once('streamPlaying', () => (this.streamPlaying = true));
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.actionService.openDialog(error.name.replace(/_/g, ' '), error.message, true);
|
this.actionService.openDialog(error.name.replace(/_/g, ' '), error.message, true);
|
||||||
|
|
|
@ -233,6 +233,7 @@ export class OpenViduLayout {
|
||||||
// });
|
// });
|
||||||
this.opts = opts;
|
this.opts = opts;
|
||||||
this.layoutContainer = container;
|
this.layoutContainer = container;
|
||||||
|
this.updateLayout(container, opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
getLayoutContainer(): HTMLElement {
|
getLayoutContainer(): HTMLElement {
|
||||||
|
@ -243,9 +244,9 @@ export class OpenViduLayout {
|
||||||
* Set the layout configuration
|
* Set the layout configuration
|
||||||
* @param options
|
* @param options
|
||||||
*/
|
*/
|
||||||
private setLayoutOptions(options: OpenViduLayoutOptions) {
|
// private setLayoutOptions(options: OpenViduLayoutOptions) {
|
||||||
this.opts = options;
|
// this.opts = options;
|
||||||
}
|
// }
|
||||||
|
|
||||||
private css(el: HTMLVideoElement | HTMLElement, propertyName: any, value?: string) {
|
private css(el: HTMLVideoElement | HTMLElement, propertyName: any, value?: string) {
|
||||||
if (!!value) {
|
if (!!value) {
|
||||||
|
|
|
@ -58,10 +58,6 @@ export class DocumentService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
removeNoSizeElementClass(element: HTMLElement | Element) {
|
|
||||||
element?.classList.remove(LayoutClass.NO_SIZE_ELEMENT);
|
|
||||||
}
|
|
||||||
|
|
||||||
isSmallElement(element: HTMLElement | Element): boolean {
|
isSmallElement(element: HTMLElement | Element): boolean {
|
||||||
return element?.className.includes(LayoutClass.SMALL_ELEMENT);
|
return element?.className.includes(LayoutClass.SMALL_ELEMENT);
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,25 +25,14 @@ export class LayoutService {
|
||||||
this.subtitlesTogglingObs = this.subtitlesToggling.asObservable();
|
this.subtitlesTogglingObs = this.subtitlesToggling.asObservable();
|
||||||
}
|
}
|
||||||
|
|
||||||
initialize(timeout: number = null) {
|
initialize(container: HTMLElement) {
|
||||||
if (typeof timeout === 'number' && timeout >= 0) {
|
this.layoutContainer = container;
|
||||||
setTimeout(() => {
|
|
||||||
this._initialize();
|
|
||||||
this.sendLayoutWidthEvent();
|
|
||||||
}, timeout);
|
|
||||||
} else {
|
|
||||||
this._initialize();
|
|
||||||
this.sendLayoutWidthEvent();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private _initialize() {
|
|
||||||
this.openviduLayout = new OpenViduLayout();
|
this.openviduLayout = new OpenViduLayout();
|
||||||
this.openviduLayoutOptions = this.getOptions();
|
this.openviduLayoutOptions = this.getOptions();
|
||||||
this.layoutContainer = document.getElementById('layout');
|
|
||||||
if(this.layoutContainer){
|
if(this.layoutContainer){
|
||||||
this.openviduLayout.initLayoutContainer(this.layoutContainer, this.openviduLayoutOptions);
|
this.openviduLayout.initLayoutContainer(this.layoutContainer, this.openviduLayoutOptions);
|
||||||
}
|
}
|
||||||
|
this.sendLayoutWidthEvent();
|
||||||
}
|
}
|
||||||
|
|
||||||
private getOptions(): OpenViduLayoutOptions {
|
private getOptions(): OpenViduLayoutOptions {
|
||||||
|
|
Loading…
Reference in New Issue