From 7cd9170d543b415e5a9a1411bf76e1cf42e9b6ca Mon Sep 17 00:00:00 2001 From: pabloFuente Date: Wed, 20 Mar 2019 16:01:56 +0100 Subject: [PATCH] Recording layouts refactoring (prepare other layouts) --- .../angular/frontend/src/app/app.module.ts | 29 ++-- .../angular/frontend/src/app/app.routing.ts | 23 ++- .../layout-base.component.css} | 0 .../layout-base.component.html} | 0 .../layout-base.component.spec.ts} | 12 +- .../layout-base/layout-base.component.ts | 148 ++++++++++++++++++ .../layout-best-fit.component.ts | 134 +--------------- ...ayout-horizontal-presentation.component.ts | 34 ++++ .../layout-vertical-presentation.component.ts | 34 ++++ .../app/components/layouts/openvidu-layout.ts | 38 +++-- 10 files changed, 293 insertions(+), 159 deletions(-) rename openvidu-server/src/angular/frontend/src/app/components/layouts/{layout-best-fit/layout-best-fit.component.css => layout-base/layout-base.component.css} (100%) rename openvidu-server/src/angular/frontend/src/app/components/layouts/{layout-best-fit/layout-best-fit.component.html => layout-base/layout-base.component.html} (100%) rename openvidu-server/src/angular/frontend/src/app/components/layouts/{layout-best-fit/layout-best-fit.component.spec.ts => layout-base/layout-base.component.spec.ts} (52%) create mode 100644 openvidu-server/src/angular/frontend/src/app/components/layouts/layout-base/layout-base.component.ts create mode 100644 openvidu-server/src/angular/frontend/src/app/components/layouts/layout-horizontal-presentation/layout-horizontal-presentation.component.ts create mode 100644 openvidu-server/src/angular/frontend/src/app/components/layouts/layout-vertical-presentation/layout-vertical-presentation.component.ts diff --git a/openvidu-server/src/angular/frontend/src/app/app.module.ts b/openvidu-server/src/angular/frontend/src/app/app.module.ts index d83de238..bc7adea2 100644 --- a/openvidu-server/src/angular/frontend/src/app/app.module.ts +++ b/openvidu-server/src/angular/frontend/src/app/app.module.ts @@ -1,23 +1,22 @@ -import { BrowserModule } from '@angular/platform-browser'; -import { FlexLayoutModule } from '@angular/flex-layout'; import { NgModule } from '@angular/core'; +import { FlexLayoutModule } from '@angular/flex-layout'; import { FormsModule } from '@angular/forms'; import { HttpModule } from '@angular/http'; +import { BrowserModule } from '@angular/platform-browser'; import 'hammerjs'; - -import { routing } from './app.routing'; +import { AppComponent } from './app.component'; import { AppMaterialModule } from './app.material.module'; - +import { routing } from './app.routing'; +import { CredentialsDialogComponent } from './components/dashboard/credentials-dialog.component'; +import { DashboardComponent } from './components/dashboard/dashboard.component'; +import { LayoutBestFitComponent } from './components/layouts/layout-best-fit/layout-best-fit.component'; +import { LayoutHorizontalPresentationComponent } from './components/layouts/layout-horizontal-presentation/layout-horizontal-presentation.component'; +import { LayoutVerticalPresentationComponent } from './components/layouts/layout-vertical-presentation/layout-vertical-presentation.component'; +import { OpenViduVideoComponent } from './components/layouts/ov-video.component'; +import { SessionDetailsComponent } from './components/session-details/session-details.component'; import { InfoService } from './services/info.service'; import { RestService } from './services/rest.service'; -import { AppComponent } from './app.component'; -import { DashboardComponent } from './components/dashboard/dashboard.component'; -import { SessionDetailsComponent } from './components/session-details/session-details.component'; -import { CredentialsDialogComponent } from './components/dashboard/credentials-dialog.component'; -import { LayoutBestFitComponent } from './components/layouts/layout-best-fit/layout-best-fit.component'; -import { OpenViduVideoComponent } from './components/layouts/ov-video.component'; - @NgModule({ declarations: [ AppComponent, @@ -25,7 +24,9 @@ import { OpenViduVideoComponent } from './components/layouts/ov-video.component' SessionDetailsComponent, CredentialsDialogComponent, LayoutBestFitComponent, - OpenViduVideoComponent, + LayoutVerticalPresentationComponent, + LayoutHorizontalPresentationComponent, + OpenViduVideoComponent ], imports: [ BrowserModule, @@ -36,7 +37,7 @@ import { OpenViduVideoComponent } from './components/layouts/ov-video.component' FlexLayoutModule ], entryComponents: [ - CredentialsDialogComponent, + CredentialsDialogComponent ], providers: [InfoService, RestService], bootstrap: [AppComponent] diff --git a/openvidu-server/src/angular/frontend/src/app/app.routing.ts b/openvidu-server/src/angular/frontend/src/app/app.routing.ts index 5955d489..041b7f1f 100644 --- a/openvidu-server/src/angular/frontend/src/app/app.routing.ts +++ b/openvidu-server/src/angular/frontend/src/app/app.routing.ts @@ -1,9 +1,10 @@ import { ModuleWithProviders } from '@angular/core'; -import { Routes, RouterModule } from '@angular/router'; - +import { RouterModule, Routes } from '@angular/router'; import { DashboardComponent } from 'app/components/dashboard/dashboard.component'; -import { SessionDetailsComponent } from 'app/components/session-details/session-details.component'; import { LayoutBestFitComponent } from 'app/components/layouts/layout-best-fit/layout-best-fit.component'; +import { SessionDetailsComponent } from 'app/components/session-details/session-details.component'; +import { LayoutHorizontalPresentationComponent } from './components/layouts/layout-horizontal-presentation/layout-horizontal-presentation.component'; +import { LayoutVerticalPresentationComponent } from './components/layouts/layout-vertical-presentation/layout-vertical-presentation.component'; const appRoutes: Routes = [ { @@ -21,6 +22,22 @@ const appRoutes: Routes = [ { path: 'layout-best-fit/:sessionId/:secret/:onlyVideo', component: LayoutBestFitComponent + }, + { + path: 'layout-vertical-presentation/:sessionId/:secret', + component: LayoutVerticalPresentationComponent + }, + { + path: 'layout-vertical-presentation/:sessionId/:secret/:onlyVideo', + component: LayoutVerticalPresentationComponent + }, + { + path: 'layout-horizontal-presentation/:sessionId/:secret', + component: LayoutHorizontalPresentationComponent + }, + { + path: 'layout-horizontal-presentation/:sessionId/:secret/:onlyVideo', + component: LayoutHorizontalPresentationComponent } ]; diff --git a/openvidu-server/src/angular/frontend/src/app/components/layouts/layout-best-fit/layout-best-fit.component.css b/openvidu-server/src/angular/frontend/src/app/components/layouts/layout-base/layout-base.component.css similarity index 100% rename from openvidu-server/src/angular/frontend/src/app/components/layouts/layout-best-fit/layout-best-fit.component.css rename to openvidu-server/src/angular/frontend/src/app/components/layouts/layout-base/layout-base.component.css diff --git a/openvidu-server/src/angular/frontend/src/app/components/layouts/layout-best-fit/layout-best-fit.component.html b/openvidu-server/src/angular/frontend/src/app/components/layouts/layout-base/layout-base.component.html similarity index 100% rename from openvidu-server/src/angular/frontend/src/app/components/layouts/layout-best-fit/layout-best-fit.component.html rename to openvidu-server/src/angular/frontend/src/app/components/layouts/layout-base/layout-base.component.html diff --git a/openvidu-server/src/angular/frontend/src/app/components/layouts/layout-best-fit/layout-best-fit.component.spec.ts b/openvidu-server/src/angular/frontend/src/app/components/layouts/layout-base/layout-base.component.spec.ts similarity index 52% rename from openvidu-server/src/angular/frontend/src/app/components/layouts/layout-best-fit/layout-best-fit.component.spec.ts rename to openvidu-server/src/angular/frontend/src/app/components/layouts/layout-base/layout-base.component.spec.ts index 51db2584..0aafa469 100644 --- a/openvidu-server/src/angular/frontend/src/app/components/layouts/layout-best-fit/layout-best-fit.component.spec.ts +++ b/openvidu-server/src/angular/frontend/src/app/components/layouts/layout-base/layout-base.component.spec.ts @@ -1,20 +1,20 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; -import { LayoutBestFitComponent } from './layout-best-fit.component'; +import { LayoutBaseComponent } from './layout-base.component'; -describe('SessionDetailsComponent', () => { - let component: LayoutBestFitComponent; - let fixture: ComponentFixture; +describe('LayoutBaseComponent', () => { + let component: LayoutBaseComponent; + let fixture: ComponentFixture; beforeEach(async(() => { TestBed.configureTestingModule({ - declarations: [ LayoutBestFitComponent ] + declarations: [ LayoutBaseComponent ] }) .compileComponents(); })); beforeEach(() => { - fixture = TestBed.createComponent(LayoutBestFitComponent); + fixture = TestBed.createComponent(LayoutBaseComponent); component = fixture.componentInstance; fixture.detectChanges(); }); diff --git a/openvidu-server/src/angular/frontend/src/app/components/layouts/layout-base/layout-base.component.ts b/openvidu-server/src/angular/frontend/src/app/components/layouts/layout-base/layout-base.component.ts new file mode 100644 index 00000000..ba56d6c8 --- /dev/null +++ b/openvidu-server/src/angular/frontend/src/app/components/layouts/layout-base/layout-base.component.ts @@ -0,0 +1,148 @@ +import { + ApplicationRef, + Component, + HostListener, + OnDestroy, + OnInit, + ViewEncapsulation +} from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; +import { + OpenVidu, + Session, + StreamEvent, + StreamManagerEvent, + Subscriber +} from 'openvidu-browser'; +import { OpenViduLayout, OpenViduLayoutOptions } from '../openvidu-layout'; + + +@Component({ + selector: 'app-layout-base', + templateUrl: './layout-base.component.html', + styleUrls: ['./layout-base.component.css'], + encapsulation: ViewEncapsulation.None +}) +export class LayoutBaseComponent implements OnInit, OnDestroy { + + openviduLayout: OpenViduLayout; + sessionId: string; + secret: string; + onlyVideo = false; + + session: Session; + subscribers: Subscriber[] = []; + + layout: any; + resizeTimeout; + numberOfScreenStreams = 0; + + layoutOptions: OpenViduLayoutOptions; + + constructor(private route: ActivatedRoute, private appRef: ApplicationRef) { + this.route.params.subscribe(params => { + this.sessionId = params.sessionId; + this.secret = params.secret; + if (params.onlyVideo != null) { + this.onlyVideo = JSON.parse(params.onlyVideo); + } + }); + } + + @HostListener('window:beforeunload') + beforeunloadHandler() { + this.leaveSession(); + } + + @HostListener('window:resize', ['$event']) + sizeChange(event) { + clearTimeout(this.resizeTimeout); + this.resizeTimeout = setTimeout(() => { + this.openviduLayout.updateLayout(); + }, 20); + } + + ngOnDestroy() { + this.leaveSession(); + } + + ngOnInit() { + const OV = new OpenVidu(); + this.session = OV.initSession(); + + this.session.on('streamCreated', (event: StreamEvent) => { + if (!(this.onlyVideo && !event.stream.hasVideo)) { + let changeFixedRatio = false; + if (event.stream.typeOfVideo === 'SCREEN') { + this.numberOfScreenStreams++; + changeFixedRatio = true; + } + const subscriber: Subscriber = this.session.subscribe( + event.stream, + undefined, + { subscribeToAudio: event.stream.hasAudio && !this.onlyVideo } + ); + subscriber.on('streamPlaying', (e: StreamManagerEvent) => { + const video: HTMLVideoElement = subscriber.videos[0].video; + video.parentElement.parentElement.classList.remove('custom-class'); + this.updateLayout(changeFixedRatio); + }); + this.addSubscriber(subscriber); + } + }); + + this.session.on('streamDestroyed', (event: StreamEvent) => { + let changeFixedRatio = false; + if (event.stream.typeOfVideo === 'SCREEN') { + this.numberOfScreenStreams--; + changeFixedRatio = true; + } + this.deleteSubscriber(event.stream.streamManager); + this.updateLayout(changeFixedRatio); + }); + + const port = !!location.port ? (':' + location.port) : ''; + const token = 'wss://' + location.hostname + port + '?sessionId=' + this.sessionId + '&secret=' + this.secret + '&recorder=true'; + this.session.connect(token) + .catch(error => { + console.error(error); + }) + + this.openviduLayout = new OpenViduLayout(); + this.openviduLayout.initLayoutContainer(document.getElementById('layout'), this.layoutOptions); + } + + private addSubscriber(subscriber: Subscriber): void { + this.subscribers.push(subscriber); + this.appRef.tick(); + } + + private deleteSubscriber(subscriber: Subscriber): void { + let index = -1; + for (let i = 0; i < this.subscribers.length; i++) { + if (this.subscribers[i] === subscriber) { + index = i; + break; + } + } + if (index > -1) { + this.subscribers.splice(index, 1); + } + this.appRef.tick(); + } + + leaveSession() { + if (this.session) { this.session.disconnect(); }; + this.subscribers = []; + this.session = null; + } + + updateLayout(changeFixedRatio: boolean) { + if (changeFixedRatio) { + this.layoutOptions.fixedRatio = this.numberOfScreenStreams > 0; + this.openviduLayout.setLayoutOptions(this.layoutOptions); + } + this.openviduLayout.updateLayout(); + } + +} diff --git a/openvidu-server/src/angular/frontend/src/app/components/layouts/layout-best-fit/layout-best-fit.component.ts b/openvidu-server/src/angular/frontend/src/app/components/layouts/layout-best-fit/layout-best-fit.component.ts index 54b1481f..bf0a0505 100644 --- a/openvidu-server/src/angular/frontend/src/app/components/layouts/layout-best-fit/layout-best-fit.component.ts +++ b/openvidu-server/src/angular/frontend/src/app/components/layouts/layout-best-fit/layout-best-fit.component.ts @@ -1,28 +1,13 @@ -import { Component, OnInit, OnDestroy, HostListener, ViewEncapsulation, ApplicationRef } from '@angular/core'; -import { ActivatedRoute } from '@angular/router'; -import { OpenVidu, Session, Subscriber, StreamEvent, StreamManagerEvent } from 'openvidu-browser'; - -import { OpenViduLayout } from '../openvidu-layout'; +import { Component, ViewEncapsulation } from '@angular/core'; +import { LayoutBaseComponent } from '../layout-base/layout-base.component'; @Component({ selector: 'app-layout-best-fit', - templateUrl: './layout-best-fit.component.html', - styleUrls: ['./layout-best-fit.component.css'], + templateUrl: '../layout-base/layout-base.component.html', + styleUrls: ['../layout-base/layout-base.component.css'], encapsulation: ViewEncapsulation.None }) -export class LayoutBestFitComponent implements OnInit, OnDestroy { - - openviduLayout: OpenViduLayout; - sessionId: string; - secret: string; - onlyVideo = false; - - session: Session; - subscribers: Subscriber[] = []; - - layout: any; - resizeTimeout; - numberOfScreenStreams = 0; +export class LayoutBestFitComponent extends LayoutBaseComponent { layoutOptions = { maxRatio: 3 / 2, // The narrowest ratio that will be used (default 2x3) @@ -35,113 +20,8 @@ export class LayoutBestFitComponent implements OnInit, OnDestroy { bigMaxRatio: 3 / 2, // The narrowest ratio to use for the big elements (default 2x3) bigMinRatio: 9 / 16, // The widest ratio to use for the big elements (default 16x9) bigFirst: true, // Whether to place the big one in the top left (true) or bottom right - animate: true // Whether you want to animate the transitions + animate: true, // Whether you want to animate the transitions + vertical: undefined // Whether to show small videos at the side or at the bottom }; - constructor(private route: ActivatedRoute, private appRef: ApplicationRef) { - this.route.params.subscribe(params => { - this.sessionId = params.sessionId; - this.secret = params.secret; - if (params.onlyVideo !== null) { - this.onlyVideo = JSON.parse(params.onlyVideo); - } - }); - } - - @HostListener('window:beforeunload') - beforeunloadHandler() { - this.leaveSession(); - } - - @HostListener('window:resize', ['$event']) - sizeChange(event) { - clearTimeout(this.resizeTimeout); - this.resizeTimeout = setTimeout(() => { - this.openviduLayout.updateLayout(); - }, 20); - } - - ngOnDestroy() { - this.leaveSession(); - } - - ngOnInit() { - const OV = new OpenVidu(); - this.session = OV.initSession(); - - this.session.on('streamCreated', (event: StreamEvent) => { - if (!(this.onlyVideo && !event.stream.hasVideo)) { - let changeFixedRatio = false; - if (event.stream.typeOfVideo === 'SCREEN') { - this.numberOfScreenStreams++; - changeFixedRatio = true; - } - const subscriber: Subscriber = this.session.subscribe( - event.stream, - undefined, - { subscribeToAudio: event.stream.hasAudio && !this.onlyVideo } - ); - subscriber.on('streamPlaying', (e: StreamManagerEvent) => { - const video: HTMLVideoElement = subscriber.videos[0].video; - video.parentElement.parentElement.classList.remove('custom-class'); - this.updateLayout(changeFixedRatio); - }); - this.addSubscriber(subscriber); - } - }); - - this.session.on('streamDestroyed', (event: StreamEvent) => { - let changeFixedRatio = false; - if (event.stream.typeOfVideo === 'SCREEN') { - this.numberOfScreenStreams--; - changeFixedRatio = true; - } - this.deleteSubscriber(event.stream.streamManager); - this.updateLayout(changeFixedRatio); - }); - - const port = !!location.port ? (':' + location.port) : ''; - const token = 'wss://' + location.hostname + port + '?sessionId=' + this.sessionId + '&secret=' + this.secret + '&recorder=true'; - this.session.connect(token) - .catch(error => { - console.error(error); - }) - - this.openviduLayout = new OpenViduLayout(); - this.openviduLayout.initLayoutContainer(document.getElementById('layout'), this.layoutOptions); - } - - private addSubscriber(subscriber: Subscriber): void { - this.subscribers.push(subscriber); - this.appRef.tick(); - } - - private deleteSubscriber(subscriber: Subscriber): void { - let index = -1; - for (let i = 0; i < this.subscribers.length; i++) { - if (this.subscribers[i] === subscriber) { - index = i; - break; - } - } - if (index > -1) { - this.subscribers.splice(index, 1); - } - this.appRef.tick(); - } - - leaveSession() { - if (this.session) { this.session.disconnect(); }; - this.subscribers = []; - this.session = null; - } - - updateLayout(changeFixedRatio: boolean) { - if (changeFixedRatio) { - this.layoutOptions.fixedRatio = this.numberOfScreenStreams > 0; - this.openviduLayout.setLayoutOptions(this.layoutOptions); - } - this.openviduLayout.updateLayout(); - } - } diff --git a/openvidu-server/src/angular/frontend/src/app/components/layouts/layout-horizontal-presentation/layout-horizontal-presentation.component.ts b/openvidu-server/src/angular/frontend/src/app/components/layouts/layout-horizontal-presentation/layout-horizontal-presentation.component.ts new file mode 100644 index 00000000..e0deaeba --- /dev/null +++ b/openvidu-server/src/angular/frontend/src/app/components/layouts/layout-horizontal-presentation/layout-horizontal-presentation.component.ts @@ -0,0 +1,34 @@ +import { Component, ViewEncapsulation, OnInit } from '@angular/core'; +import { LayoutBaseComponent } from '../layout-base/layout-base.component'; + +@Component({ + selector: 'app-layout-horizontal-presentation', + templateUrl: '../layout-base/layout-base.component.html', + styleUrls: ['../layout-base/layout-base.component.css'], + encapsulation: ViewEncapsulation.None +}) +export class LayoutHorizontalPresentationComponent extends LayoutBaseComponent implements OnInit { + + layoutOptions = { + maxRatio: 3 / 2, // The narrowest ratio that will be used (default 2x3) + minRatio: 9 / 16, // The widest ratio that will be used (default 16x9) + fixedRatio: false, /* If this is true then the aspect ratio of the video is maintained + and minRatio and maxRatio are ignored (default false) */ + bigClass: 'OV_big', // The class to add to elements that should be sized bigger + bigPercentage: 0.8, // The maximum percentage of space the big ones should take up + bigFixedRatio: false, // fixedRatio for the big ones + bigMaxRatio: 3 / 2, // The narrowest ratio to use for the big elements (default 2x3) + bigMinRatio: 9 / 16, // The widest ratio to use for the big elements (default 16x9) + bigFirst: true, // Whether to place the big one in the top left (true) or bottom right + animate: true, // Whether you want to animate the transitions + vertical: false // Whether to show small videos at the side or at the bottom + }; + + ngOnInit() { + super.ngOnInit(); + this.session.on('signal:update-stream-layouts', event => { + // TODO: Add or remove class OV_big accordingly to each Subscriber video + }); + } + +} diff --git a/openvidu-server/src/angular/frontend/src/app/components/layouts/layout-vertical-presentation/layout-vertical-presentation.component.ts b/openvidu-server/src/angular/frontend/src/app/components/layouts/layout-vertical-presentation/layout-vertical-presentation.component.ts new file mode 100644 index 00000000..e34975f2 --- /dev/null +++ b/openvidu-server/src/angular/frontend/src/app/components/layouts/layout-vertical-presentation/layout-vertical-presentation.component.ts @@ -0,0 +1,34 @@ +import { Component, ViewEncapsulation, OnInit } from '@angular/core'; +import { LayoutBaseComponent } from '../layout-base/layout-base.component'; + +@Component({ + selector: 'app-layout-vertical-presentation', + templateUrl: '../layout-base/layout-base.component.html', + styleUrls: ['../layout-base/layout-base.component.css'], + encapsulation: ViewEncapsulation.None +}) +export class LayoutVerticalPresentationComponent extends LayoutBaseComponent implements OnInit { + + layoutOptions = { + maxRatio: 3 / 2, // The narrowest ratio that will be used (default 2x3) + minRatio: 9 / 16, // The widest ratio that will be used (default 16x9) + fixedRatio: false, /* If this is true then the aspect ratio of the video is maintained + and minRatio and maxRatio are ignored (default false) */ + bigClass: 'OV_big', // The class to add to elements that should be sized bigger + bigPercentage: 0.8, // The maximum percentage of space the big ones should take up + bigFixedRatio: false, // fixedRatio for the big ones + bigMaxRatio: 3 / 2, // The narrowest ratio to use for the big elements (default 2x3) + bigMinRatio: 9 / 16, // The widest ratio to use for the big elements (default 16x9) + bigFirst: false, // Whether to place the big one in the top left (true) or bottom right + animate: true, // Whether you want to animate the transitions + vertical: true // Whether to show small videos at the side or at the bottom + }; + + ngOnInit() { + super.ngOnInit(); + this.session.on('signal:update-stream-layouts', event => { + // TODO: Add or remove class OV_big accordingly to each Subscriber video + }); + } + +} diff --git a/openvidu-server/src/angular/frontend/src/app/components/layouts/openvidu-layout.ts b/openvidu-server/src/angular/frontend/src/app/components/layouts/openvidu-layout.ts index 85d0872c..14b65aac 100644 --- a/openvidu-server/src/angular/frontend/src/app/components/layouts/openvidu-layout.ts +++ b/openvidu-server/src/angular/frontend/src/app/components/layouts/openvidu-layout.ts @@ -10,7 +10,8 @@ export interface OpenViduLayoutOptions { bigFixedRatio: any; bigMaxRatio: any; bigMinRatio: any; - bigFirst: any; + bigFirst: boolean; + vertical: boolean; } export class OpenViduLayout { @@ -41,7 +42,7 @@ export class OpenViduLayout { this.fixAspectRatio(elem, width); - if (animate && $) { + if (!!animate && $) { $(elem).stop(); $(elem).animate(targetPosition, animate.duration || 200, animate.easing || 'swing', () => { @@ -296,21 +297,39 @@ export class OpenViduLayout { if (bigOnes.length > 0 && smallOnes.length > 0) { let bigWidth, bigHeight; - if (availableRatio > this.getVideoRatio(bigOnes[0])) { - // We are tall, going to take up the whole width and arrange small - // guys at the bottom + const horizontal = () => { bigWidth = WIDTH; bigHeight = Math.floor(HEIGHT * this.opts.bigPercentage); offsetTop = bigHeight; bigOffsetTop = HEIGHT - offsetTop; - } else { - // We are wide, going to take up the whole height and arrange the small - // guys on the right + } + const vertical = () => { bigHeight = HEIGHT; bigWidth = Math.floor(WIDTH * this.opts.bigPercentage); offsetLeft = bigWidth; bigOffsetLeft = WIDTH - offsetLeft; } + if (this.opts.vertical != null) { + if (!this.opts.vertical) { + // Horizontal presentation + horizontal(); + } else { + // Vertical presentation + vertical(); + } + } else { + // Dynamic presentation + if (availableRatio > this.getVideoRatio(bigOnes[0])) { + // We are tall, going to take up the whole width and arrange small + // guys at the bottom + horizontal(); + } else { + // We are wide, going to take up the whole height and arrange the small + // guys on the right + vertical(); + } + } + if (this.opts.bigFirst) { this.arrange(bigOnes, bigWidth, bigHeight, 0, 0, this.opts.bigFixedRatio, this.opts.bigMinRatio, this.opts.bigMaxRatio, this.opts.animate); @@ -344,7 +363,8 @@ export class OpenViduLayout { bigFixedRatio: (opts.bigFixedRatio != null) ? opts.bigFixedRatio : false, bigMaxRatio: (opts.bigMaxRatio != null) ? opts.bigMaxRatio : 3 / 2, bigMinRatio: (opts.bigMinRatio != null) ? opts.bigMinRatio : 9 / 16, - bigFirst: (opts.bigFirst != null) ? opts.bigFirst : true + bigFirst: (opts.bigFirst != null) ? opts.bigFirst : true, + vertical: opts.vertical }; this.layoutContainer = typeof (container) === 'string' ? $(container) : container; }