openvidu-components: Fixed layout when is webcomponent

When webcomponent, the layout need more time for initilizating and showing the videos.
pull/707/head
csantosm 2022-03-09 12:34:10 +01:00
parent e0de51921c
commit a3d5a9c98f
10 changed files with 68 additions and 29 deletions

View File

@ -1,9 +1,19 @@
import { AfterViewInit, ChangeDetectionStrategy, ChangeDetectorRef, Component, ContentChild, OnDestroy, OnInit, TemplateRef } from '@angular/core'; import {
AfterViewInit,
ChangeDetectionStrategy,
ChangeDetectorRef,
Component,
ContentChild,
OnDestroy,
OnInit,
TemplateRef
} 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';
import { ParticipantAbstractModel } from '../../models/participant.model'; import { ParticipantAbstractModel } from '../../models/participant.model';
import { LayoutService } from '../../services/layout/layout.service'; import { LayoutService } from '../../services/layout/layout.service';
import { StreamDirective } from '../../directives/template/openvidu-angular.directive'; import { StreamDirective } from '../../directives/template/openvidu-angular.directive';
import { OpenViduAngularConfigService } from '../../services/config/openvidu-angular.config.service';
@Component({ @Component({
selector: 'ov-layout', selector: 'ov-layout',
@ -15,10 +25,10 @@ export class LayoutComponent implements OnInit, OnDestroy, AfterViewInit {
@ContentChild('stream', { read: TemplateRef }) streamTemplate: TemplateRef<any>; @ContentChild('stream', { read: TemplateRef }) streamTemplate: TemplateRef<any>;
@ContentChild(StreamDirective) @ContentChild(StreamDirective)
set externalStream (externalStream: StreamDirective) { set externalStream(externalStream: StreamDirective) {
// This directive will has value only when STREAM component tagget with '*ovStream' directive // This directive will has value only when STREAM component tagget with '*ovStream' directive
// is inside of the layout component tagged with '*ovLayout' directive // is inside of the layout component tagged with '*ovLayout' directive
if(externalStream) { if (externalStream) {
this.streamTemplate = externalStream.template; this.streamTemplate = externalStream.template;
} }
} }
@ -28,15 +38,25 @@ export class LayoutComponent implements OnInit, OnDestroy, AfterViewInit {
protected localParticipantSubs: Subscription; protected localParticipantSubs: Subscription;
protected remoteParticipantsSubs: Subscription; protected remoteParticipantsSubs: Subscription;
constructor(protected layoutService: LayoutService, protected participantService: ParticipantService, private cd: ChangeDetectorRef) {} constructor(
protected layoutService: LayoutService,
protected participantService: ParticipantService,
private libService: OpenViduAngularConfigService,
private cd: ChangeDetectorRef
) {}
ngOnInit(): void { ngOnInit(): void {
this.subscribeToParticipants(); this.subscribeToParticipants();
} }
ngAfterViewInit() { ngAfterViewInit() {
this.layoutService.initialize(); let timeout: number = null;
this.layoutService.update(); if (this.libService.isWebcomponent()) {
timeout = 0;
}
this.layoutService.initialize(timeout);
this.layoutService.update(timeout);
} }
ngOnDestroy() { ngOnDestroy() {

View File

@ -15,7 +15,7 @@
align-items: center; align-items: center;
} }
#media-buttons-container { #media-buttons-container {
max-height: 100%; max-height: 100% !important;
} }
#media-buttons-container > *, ::ng-deep #media-buttons-container > * { #media-buttons-container > *, ::ng-deep #media-buttons-container > * {

View File

@ -1,6 +1,7 @@
export interface OpenViduAngularConfig { export interface OpenViduAngularConfig {
production?: boolean, production?: boolean,
participantFactory?: ParticipantFactoryFunction, participantFactory?: ParticipantFactoryFunction,
webcomponent?: boolean
} }

View File

@ -141,7 +141,7 @@ export class OpenViduLayout {
} }
getLayoutContainer(): HTMLElement { getLayoutContainer(): HTMLElement {
return this.layoutContainer return this.layoutContainer;
} }
/** /**

View File

@ -70,6 +70,10 @@ export class OpenViduAngularConfigService {
return this.configuration?.production; return this.configuration?.production;
} }
isWebcomponent(): boolean {
return this.configuration?.webcomponent;
}
hasParticipantFactory(): boolean { hasParticipantFactory(): boolean {
return typeof this.getConfig().participantFactory === "function"; return typeof this.getConfig().participantFactory === "function";
} }

View File

@ -17,23 +17,25 @@ export class LayoutService {
} }
initialize(timeout: number = null) { initialize(timeout: number = null) {
if (!!timeout) { if (typeof timeout === 'number' && timeout >= 0) {
setTimeout(() => { setTimeout(() => {
this._initialize(); this._initialize();
this.sendLayoutWidthEvent();
}, timeout); }, timeout);
} else { } else {
this._initialize(); this._initialize();
this.sendLayoutWidthEvent();
} }
this.sendLayoutWidthEvent();
} }
private _initialize() { private _initialize() {
this.openviduLayout = new OpenViduLayout(); this.openviduLayout = new OpenViduLayout();
this.openviduLayoutOptions = this.getOptions(); this.openviduLayoutOptions = this.getOptions();
this.openviduLayout.initLayoutContainer(document.getElementById('layout'), this.openviduLayoutOptions); const element = document.getElementById('layout');
this.openviduLayout.initLayoutContainer(element, this.openviduLayoutOptions);
} }
getOptions(): OpenViduLayoutOptions { private getOptions(): OpenViduLayoutOptions {
const options = { const options = {
maxRatio: 3 / 2, // The narrowest ratio that will be used (default 2x3) maxRatio: 3 / 2, // The narrowest ratio that will be used (default 2x3)
minRatio: 9 / 16, // The widest ratio that will be used (default 16x9) minRatio: 9 / 16, // The widest ratio that will be used (default 16x9)
@ -51,16 +53,17 @@ export class LayoutService {
return options; return options;
} }
update(timeout?: number) { update(timeout: number = null) {
if (!!this.openviduLayout) { const updateAux = () => {
if (!timeout) { if (!!this.openviduLayout) {
this.openviduLayout.updateLayout(); this.openviduLayout.updateLayout();
} else { this.sendLayoutWidthEvent();
setTimeout(() => {
this.openviduLayout.updateLayout();
}, timeout);
} }
this.sendLayoutWidthEvent(); };
if (typeof timeout === 'number' && timeout >= 0) {
setTimeout(() => updateAux(), timeout);
} else {
updateAux();
} }
} }
@ -74,10 +77,10 @@ export class LayoutService {
private sendLayoutWidthEvent() { private sendLayoutWidthEvent() {
const sidenavLayoutElement = this.documentService.getHTMLElementByClassName( const sidenavLayoutElement = this.documentService.getHTMLElementByClassName(
this.openviduLayout.getLayoutContainer(), this.openviduLayout?.getLayoutContainer(),
LayoutClass.SIDENAV_CONTAINER LayoutClass.SIDENAV_CONTAINER
); );
if(sidenavLayoutElement && sidenavLayoutElement.clientWidth) { if (sidenavLayoutElement && sidenavLayoutElement.clientWidth) {
this._layoutWidthObs.next(sidenavLayoutElement.clientWidth); this._layoutWidthObs.next(sidenavLayoutElement.clientWidth);
} }
} }

View File

@ -74,3 +74,10 @@ $openvidu-components-theme: mat.define-light-theme((
html, body { height: 100%; overflow: hidden;} html, body { height: 100%; overflow: hidden;}
body { margin: 0; font-family: 'Roboto','RobotoDraft',Helvetica,Arial,sans-serif;} body { margin: 0; font-family: 'Roboto','RobotoDraft',Helvetica,Arial,sans-serif;}
#poster-text {
padding: 0px !important;
}
ov-chat-panel .text-info {
margin: 3px auto !important;
}

View File

@ -5,23 +5,23 @@ import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { OpenviduWebComponentComponent } from './openvidu-webcomponent.component'; import { OpenviduWebComponentComponent } from './openvidu-webcomponent.component';
import { OpenviduAngularModule, VideoconferenceComponent } from 'openvidu-angular'; import { OpenViduAngularModule, VideoconferenceComponent } from 'openvidu-angular';
import { environment } from '../../environments/environment'; import { environment } from '../../environments/environment';
import { createCustomElement } from '@angular/elements'; import { createCustomElement } from '@angular/elements';
@NgModule({ @NgModule({
declarations: [OpenviduWebComponentComponent], declarations: [OpenviduWebComponentComponent],
imports: [CommonModule, BrowserModule, BrowserAnimationsModule, OpenviduAngularModule.forRoot(environment)], imports: [CommonModule, BrowserModule, BrowserAnimationsModule, OpenViduAngularModule.forRoot(environment)],
// exports: [OpenviduWebComponentComponent], // exports: [OpenviduWebComponentComponent],
providers: [{ provide: APP_BASE_HREF, useValue: '/' }, VideoconferenceComponent] providers: [{ provide: APP_BASE_HREF, useValue: '/' }, VideoconferenceComponent],
}) })
export class OpenviduWebComponentModule implements DoBootstrap { export class OpenviduWebComponentModule implements DoBootstrap {
constructor(private injector: Injector) {} constructor(private injector: Injector) {}
ngDoBootstrap(): void { ngDoBootstrap(): void {
const element = createCustomElement(OpenviduWebComponentComponent, { const element = createCustomElement(OpenviduWebComponentComponent, {
injector: this.injector injector: this.injector,
}); });
customElements.define('openvidu-webcomponent', element); customElements.define('openvidu-webcomponent', element);

View File

@ -1,3 +1,6 @@
export const environment = { export const environment = {
production: true production: true,
// The webcomponent build will use this environment.
// Wee need this flag for settings a delay in the layout for correct behaviour
webcomponent: true
}; };

View File

@ -3,7 +3,8 @@
// The list of file replacements can be found in `angular.json`. // The list of file replacements can be found in `angular.json`.
export const environment = { export const environment = {
production: false production: false,
webcomponent: true
}; };
/* /*