From bd6ba5550405bcdbf51a0df14c7acb8b490ddfa4 Mon Sep 17 00:00:00 2001 From: Carlos Santos <4a.santos@gmail.com> Date: Wed, 4 Sep 2024 12:19:13 +0200 Subject: [PATCH] ov-components: Refactored and improved config --- .../lib/components/layout/layout.component.ts | 26 ++++-- .../components/pre-join/pre-join.component.ts | 3 - .../components/session/session.component.ts | 7 +- .../settings/captions/captions.component.ts | 6 +- .../lib/components/stream/stream.component.ts | 12 +-- .../components/toolbar/toolbar.component.ts | 5 +- .../openvidu-components-angular.config.ts | 7 +- .../directives/api/api.directive.module.ts | 8 +- .../lib/directives/api/internals.directive.ts | 36 +++++++- .../lib/openvidu-components-angular.module.ts | 17 ++-- .../config/directive-config.service.ts | 16 +++- .../services/config/global-config.service.ts | 3 + .../services/config/service-config.service.ts | 40 +++++++++ .../src/lib/services/layout/layout.service.ts | 82 ++++++++++--------- .../src/public-api.ts | 2 + 15 files changed, 199 insertions(+), 71 deletions(-) create mode 100644 openvidu-components-angular/projects/openvidu-components-angular/src/lib/services/config/service-config.service.ts diff --git a/openvidu-components-angular/projects/openvidu-components-angular/src/lib/components/layout/layout.component.ts b/openvidu-components-angular/projects/openvidu-components-angular/src/lib/components/layout/layout.component.ts index 41666a10be..68f8c661f6 100644 --- a/openvidu-components-angular/projects/openvidu-components-angular/src/lib/components/layout/layout.component.ts +++ b/openvidu-components-angular/projects/openvidu-components-angular/src/lib/components/layout/layout.component.ts @@ -11,7 +11,7 @@ import { ViewChild, ViewContainerRef } from '@angular/core'; -import { Subscription } from 'rxjs'; +import { combineLatest, map, Subscription } from 'rxjs'; import { StreamDirective } from '../../directives/template/openvidu-components-angular.directive'; import { ParticipantTrackPublication, ParticipantModel } from '../../models/participant.model'; import { LayoutService } from '../../services/layout/layout.service'; @@ -19,6 +19,8 @@ import { ParticipantService } from '../../services/participant/participant.servi import { CdkDrag } from '@angular/cdk/drag-drop'; import { PanelService } from '../../services/panel/panel.service'; import { GlobalConfigService } from '../../services/config/global-config.service'; +import { ServiceConfigService } from '../../services/config/service-config.service'; +import { OpenViduComponentsConfigService } from '../../services/config/directive-config.service'; /** * @@ -78,17 +80,21 @@ export class LayoutComponent implements OnInit, OnDestroy, AfterViewInit { private resizeTimeout: NodeJS.Timeout; private videoIsAtRight: boolean = false; private lastLayoutWidth: number = 0; + private layoutService: LayoutService; /** * @ignore */ constructor( - private layoutService: LayoutService, + private serviceConfig: ServiceConfigService, private panelService: PanelService, private participantService: ParticipantService, private globalService: GlobalConfigService, + private directiveService: OpenViduComponentsConfigService, private cd: ChangeDetectorRef - ) {} + ) { + this.layoutService = this.serviceConfig.getLayoutService(); + } ngOnInit(): void { this.subscribeToParticipants(); @@ -96,6 +102,7 @@ export class LayoutComponent implements OnInit, OnDestroy, AfterViewInit { } ngAfterViewInit() { + console.log('LayoutComponent.ngAfterViewInit'); this.layoutService.initialize(this.layoutContainer.element.nativeElement); this.lastLayoutWidth = this.layoutContainer.element.nativeElement.getBoundingClientRect().width; this.listenToResizeLayout(); @@ -142,11 +149,20 @@ export class LayoutComponent implements OnInit, OnDestroy, AfterViewInit { } }); - this.remoteParticipantsSubs = this.participantService.remoteParticipants$.subscribe((participants) => { + this.remoteParticipantsSubs = combineLatest([ + this.participantService.remoteParticipants$, + this.directiveService.layoutRemoteParticipants$ + ]) + .pipe( + map(([serviceParticipants, directiveParticipants]) => + directiveParticipants !== undefined ? directiveParticipants : serviceParticipants + ) + ) + .subscribe((participants) => { this.remoteParticipants = participants; this.layoutService.update(); this.cd.markForCheck(); - }); + }); } private listenToResizeLayout() { diff --git a/openvidu-components-angular/projects/openvidu-components-angular/src/lib/components/pre-join/pre-join.component.ts b/openvidu-components-angular/projects/openvidu-components-angular/src/lib/components/pre-join/pre-join.component.ts index 97192b0702..ef9e791814 100644 --- a/openvidu-components-angular/projects/openvidu-components-angular/src/lib/components/pre-join/pre-join.component.ts +++ b/openvidu-components-angular/projects/openvidu-components-angular/src/lib/components/pre-join/pre-join.component.ts @@ -3,7 +3,6 @@ import { Subscription } from 'rxjs'; import { ILogger } from '../../models/logger.model'; import { CdkOverlayService } from '../../services/cdk-overlay/cdk-overlay.service'; import { OpenViduComponentsConfigService } from '../../services/config/directive-config.service'; -import { LayoutService } from '../../services/layout/layout.service'; import { LoggerService } from '../../services/logger/logger.service'; import { OpenViduService } from '../../services/openvidu/openvidu.service'; import { TranslateService } from '../../services/translate/translate.service'; @@ -55,11 +54,9 @@ export class PreJoinComponent implements OnInit, OnDestroy { @HostListener('window:resize') sizeChange() { this.windowSize = window.innerWidth; - this.layoutService.update(); } constructor( - private layoutService: LayoutService, private loggerSrv: LoggerService, private libService: OpenViduComponentsConfigService, private cdkSrv: CdkOverlayService, diff --git a/openvidu-components-angular/projects/openvidu-components-angular/src/lib/components/session/session.component.ts b/openvidu-components-angular/projects/openvidu-components-angular/src/lib/components/session/session.component.ts index b895473824..033aa129e6 100644 --- a/openvidu-components-angular/projects/openvidu-components-angular/src/lib/components/session/session.component.ts +++ b/openvidu-components-angular/projects/openvidu-components-angular/src/lib/components/session/session.component.ts @@ -47,6 +47,7 @@ import { Track } from 'livekit-client'; import { ParticipantModel } from '../../models/participant.model'; +import { ServiceConfigService } from '../../services/config/service-config.service'; /** * @internal @@ -88,15 +89,16 @@ export class SessionComponent implements OnInit, OnDestroy { private updateLayoutInterval: NodeJS.Timeout; private captionLanguageSubscription: Subscription; private log: ILogger; + private layoutService: LayoutService; constructor( + private serviceConfig: ServiceConfigService, private actionService: ActionService, private openviduService: OpenViduService, private participantService: ParticipantService, private loggerSrv: LoggerService, private chatService: ChatService, private libService: OpenViduComponentsConfigService, - private layoutService: LayoutService, private panelService: PanelService, private recordingService: RecordingService, private broadcastingService: BroadcastingService, @@ -106,6 +108,7 @@ export class SessionComponent implements OnInit, OnDestroy { private cd: ChangeDetectorRef ) { this.log = this.loggerSrv.get('SessionComponent'); + this.layoutService = this.serviceConfig.getLayoutService(); } @HostListener('window:beforeunload') @@ -205,7 +208,7 @@ export class SessionComponent implements OnInit, OnDestroy { } async ngOnDestroy() { - if(this.shouldDisconnectRoomWhenComponentIsDestroyed) { + if (this.shouldDisconnectRoomWhenComponentIsDestroyed) { await this.disconnectRoom(); } this.room.removeAllListeners(); diff --git a/openvidu-components-angular/projects/openvidu-components-angular/src/lib/components/settings/captions/captions.component.ts b/openvidu-components-angular/projects/openvidu-components-angular/src/lib/components/settings/captions/captions.component.ts index 14d6a3d5ea..f094d79bdf 100644 --- a/openvidu-components-angular/projects/openvidu-components-angular/src/lib/components/settings/captions/captions.component.ts +++ b/openvidu-components-angular/projects/openvidu-components-angular/src/lib/components/settings/captions/captions.component.ts @@ -4,6 +4,7 @@ import { CaptionsLangOption } from '../../../models/caption.model'; import { CaptionService } from '../../../services/caption/caption.service'; import { LayoutService } from '../../../services/layout/layout.service'; import { OpenViduService } from '../../../services/openvidu/openvidu.service'; +import { ServiceConfigService } from '../../../services/config/service-config.service'; /** * @internal @@ -22,8 +23,11 @@ export class CaptionsSettingComponent implements OnInit, OnDestroy { private captionsStatusSubs: Subscription; private sttStatusSubs: Subscription; + private layoutService: LayoutService; - constructor(private layoutService: LayoutService, private captionService: CaptionService, private openviduService: OpenViduService) {} + constructor(private serviceConfig: ServiceConfigService, private captionService: CaptionService, private openviduService: OpenViduService) { + this.layoutService = this.serviceConfig.getLayoutService(); + } ngOnInit(): void { // this.isOpenViduPro = this.openviduService.isOpenViduPro(); diff --git a/openvidu-components-angular/projects/openvidu-components-angular/src/lib/components/stream/stream.component.ts b/openvidu-components-angular/projects/openvidu-components-angular/src/lib/components/stream/stream.component.ts index c406b9f104..e5e7748159 100644 --- a/openvidu-components-angular/projects/openvidu-components-angular/src/lib/components/stream/stream.component.ts +++ b/openvidu-components-angular/projects/openvidu-components-angular/src/lib/components/stream/stream.component.ts @@ -4,11 +4,10 @@ import { Subscription } from 'rxjs'; import { CdkOverlayService } from '../../services/cdk-overlay/cdk-overlay.service'; import { OpenViduComponentsConfigService } from '../../services/config/directive-config.service'; import { LayoutService } from '../../services/layout/layout.service'; -import { OpenViduService } from '../../services/openvidu/openvidu.service'; import { ParticipantService } from '../../services/participant/participant.service'; -import { StorageService } from '../../services/storage/storage.service'; import { Track } from 'livekit-client'; import { ParticipantTrackPublication } from '../../models/participant.model'; +import { ServiceConfigService } from '../../services/config/service-config.service'; /** * The **StreamComponent** is hosted inside of the {@link LayoutComponent}. @@ -99,17 +98,18 @@ export class StreamComponent implements OnInit, OnDestroy { private videoControlsSub: Subscription; private readonly HOVER_TIMEOUT = 3000; + private layoutService: LayoutService; /** * @ignore */ constructor( - private openviduService: OpenViduService, - private layoutService: LayoutService, + private serviceConfig: ServiceConfigService, private participantService: ParticipantService, - private storageService: StorageService, private cdkSrv: CdkOverlayService, private libService: OpenViduComponentsConfigService - ) {} + ) { + this.layoutService = this.serviceConfig.getLayoutService(); + } ngOnInit() { this.subscribeToStreamDirectives(); diff --git a/openvidu-components-angular/projects/openvidu-components-angular/src/lib/components/toolbar/toolbar.component.ts b/openvidu-components-angular/projects/openvidu-components-angular/src/lib/components/toolbar/toolbar.component.ts index f86a326d53..7f4af0f060 100644 --- a/openvidu-components-angular/projects/openvidu-components-angular/src/lib/components/toolbar/toolbar.component.ts +++ b/openvidu-components-angular/projects/openvidu-components-angular/src/lib/components/toolbar/toolbar.component.ts @@ -49,6 +49,7 @@ import { CdkOverlayService } from '../../services/cdk-overlay/cdk-overlay.servic import { ParticipantModel } from '../../models/participant.model'; import { Room, RoomEvent } from 'livekit-client'; import { ToolbarAdditionalButtonsPosition } from '../../models/toolbar.model'; +import { ServiceConfigService } from '../../services/config/service-config.service'; /** * The **ToolbarComponent** is hosted inside of the {@link VideoconferenceComponent}. @@ -342,11 +343,13 @@ export class ToolbarComponent implements OnInit, OnDestroy, AfterViewInit { private additionalButtonsPositionSub: Subscription; private fullscreenChangeSubscription: Subscription; private currentWindowHeight = window.innerHeight; + private layoutService: LayoutService; /** * @ignore */ constructor( + private serviceConfig: ServiceConfigService, private documentService: DocumentService, private chatService: ChatService, private panelService: PanelService, @@ -355,7 +358,6 @@ export class ToolbarComponent implements OnInit, OnDestroy, AfterViewInit { private oVDevicesService: DeviceService, private actionService: ActionService, private loggerSrv: LoggerService, - private layoutService: LayoutService, private cd: ChangeDetectorRef, private libService: OpenViduComponentsConfigService, private platformService: PlatformService, @@ -366,6 +368,7 @@ export class ToolbarComponent implements OnInit, OnDestroy, AfterViewInit { private cdkOverlayService: CdkOverlayService ) { this.log = this.loggerSrv.get('ToolbarComponent'); + this.layoutService = this.serviceConfig.getLayoutService(); } /** * @ignore diff --git a/openvidu-components-angular/projects/openvidu-components-angular/src/lib/config/openvidu-components-angular.config.ts b/openvidu-components-angular/projects/openvidu-components-angular/src/lib/config/openvidu-components-angular.config.ts index 3554bf9bf2..7f5bdb67b0 100644 --- a/openvidu-components-angular/projects/openvidu-components-angular/src/lib/config/openvidu-components-angular.config.ts +++ b/openvidu-components-angular/projects/openvidu-components-angular/src/lib/config/openvidu-components-angular.config.ts @@ -1,8 +1,9 @@ import { ParticipantProperties } from '../models/participant.model'; export interface OpenViduComponentsConfig { - production?: boolean, - participantFactory?: ParticipantFactoryFunction, + production?: boolean; + participantFactory?: ParticipantFactoryFunction; + services?: any; } -export type ParticipantFactoryFunction = (props: ParticipantProperties) => any; \ No newline at end of file +export type ParticipantFactoryFunction = (props: ParticipantProperties) => any; diff --git a/openvidu-components-angular/projects/openvidu-components-angular/src/lib/directives/api/api.directive.module.ts b/openvidu-components-angular/projects/openvidu-components-angular/src/lib/directives/api/api.directive.module.ts index f93c564b63..9117a6427d 100644 --- a/openvidu-components-angular/projects/openvidu-components-angular/src/lib/directives/api/api.directive.module.ts +++ b/openvidu-components-angular/projects/openvidu-components-angular/src/lib/directives/api/api.directive.module.ts @@ -1,7 +1,7 @@ import { NgModule } from '@angular/core'; import { ActivitiesPanelBroadcastingActivityDirective, ActivitiesPanelRecordingActivityDirective } from './activities-panel.directive'; import { AdminLoginErrorDirective, AdminDashboardRecordingsListDirective } from './admin.directive'; -import { LogoDirective } from './internals.directive'; +import { LayoutRemoteParticipantsDirective, LogoDirective } from './internals.directive'; import { ParticipantPanelItemMuteButtonDirective } from './participant-panel-item.directive'; import { StreamDisplayAudioDetectionDirective, @@ -76,7 +76,8 @@ import { ActivitiesPanelRecordingActivityDirective, ActivitiesPanelBroadcastingActivityDirective, AdminDashboardRecordingsListDirective, - AdminLoginErrorDirective + AdminLoginErrorDirective, + LayoutRemoteParticipantsDirective ], exports: [ LivekitUrlDirective, @@ -113,7 +114,8 @@ import { ActivitiesPanelRecordingActivityDirective, ActivitiesPanelBroadcastingActivityDirective, AdminDashboardRecordingsListDirective, - AdminLoginErrorDirective + AdminLoginErrorDirective, + LayoutRemoteParticipantsDirective ] }) export class ApiDirectiveModule {} diff --git a/openvidu-components-angular/projects/openvidu-components-angular/src/lib/directives/api/internals.directive.ts b/openvidu-components-angular/projects/openvidu-components-angular/src/lib/directives/api/internals.directive.ts index d4be4f3c04..9426ae4fd6 100644 --- a/openvidu-components-angular/projects/openvidu-components-angular/src/lib/directives/api/internals.directive.ts +++ b/openvidu-components-angular/projects/openvidu-components-angular/src/lib/directives/api/internals.directive.ts @@ -1,6 +1,8 @@ -// * Private directives * +// * Internal directives * import { Directive, ElementRef, HostListener, Input } from '@angular/core'; +import { ParticipantModel } from '../../models/participant.model'; +import { OpenViduComponentsConfigService } from '../../services/config/directive-config.service'; /** * Load default OpenVidu logo if custom one is not exist @@ -21,3 +23,35 @@ export class LogoDirective { element.src = this.ovLogo || this.defaultLogo; } } + +/** + * @internal + */ +@Directive({ + selector: 'ov-layout[ovRemoteParticipants]' +}) +export class LayoutRemoteParticipantsDirective { + @Input() set ovRemoteParticipants(value: ParticipantModel[] | undefined) { + this.update(value); + } + constructor( + public elementRef: ElementRef, + private directiveService: OpenViduComponentsConfigService + ) {} + + ngOnDestroy(): void { + this.clear(); + } + + ngAfterViewInit() { + this.update(this.ovRemoteParticipants); + } + + update(value: ParticipantModel[] | undefined) { + this.directiveService.setLayoutRemoteParticipants(value); + } + + clear() { + this.update(undefined); + } +} diff --git a/openvidu-components-angular/projects/openvidu-components-angular/src/lib/openvidu-components-angular.module.ts b/openvidu-components-angular/projects/openvidu-components-angular/src/lib/openvidu-components-angular.module.ts index 6cff3937e6..3270e77ff3 100644 --- a/openvidu-components-angular/projects/openvidu-components-angular/src/lib/openvidu-components-angular.module.ts +++ b/openvidu-components-angular/projects/openvidu-components-angular/src/lib/openvidu-components-angular.module.ts @@ -1,7 +1,7 @@ import { OverlayContainer } from '@angular/cdk/overlay'; import { CommonModule } from '@angular/common'; import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; -import { ModuleWithProviders, NgModule } from '@angular/core'; +import { ModuleWithProviders, NgModule, Provider } from '@angular/core'; import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { DeleteDialogComponent } from './components/dialogs/delete-recording.component'; @@ -25,7 +25,6 @@ import { CdkOverlayContainer } from './config/custom-cdk-overlay'; import { OpenViduComponentsConfig } from './config/openvidu-components-angular.config'; import { ActionService } from './services/action/action.service'; import { ChatService } from './services/chat/chat.service'; -import { OpenViduComponentsConfigService } from './services/config/directive-config.service'; import { DeviceService } from './services/device/device.service'; import { DocumentService } from './services/document/document.service'; import { LayoutService } from './services/layout/layout.service'; @@ -65,6 +64,8 @@ import { AppMaterialModule } from './openvidu-components-angular.material.module import { VirtualBackgroundService } from './services/virtual-background/virtual-background.service'; import { BroadcastingService } from './services/broadcasting/broadcasting.service'; import { TranslateService } from './services/translate/translate.service'; +import { GlobalConfigService } from './services/config/global-config.service'; +import { OpenViduComponentsConfigService } from './services/config/directive-config.service'; const publicComponents = [ AdminDashboardComponent, @@ -131,6 +132,8 @@ const privateComponents = [ DragDropModule ], providers: [ + GlobalConfigService, + OpenViduComponentsConfigService, ActionService, BroadcastingService, // CaptionService, @@ -139,7 +142,7 @@ const privateComponents = [ ChatService, DeviceService, DocumentService, - LayoutService, + // LayoutService, LoggerService, OpenViduService, PanelService, @@ -153,12 +156,12 @@ const privateComponents = [ ] }) export class OpenViduComponentsModule { - static forRoot(config): ModuleWithProviders { - // console.log(`${library.name} config: ${environment}`); - const libConfig: OpenViduComponentsConfig = config; + static forRoot(config: OpenViduComponentsConfig): ModuleWithProviders { + const providers: Provider[] = [{ provide: 'OPENVIDU_COMPONENTS_CONFIG', useValue: config }]; + return { ngModule: OpenViduComponentsModule, - providers: [OpenViduComponentsConfigService, { provide: 'OPENVIDU_COMPONENTS_CONFIG', useValue: libConfig }] + providers }; } } diff --git a/openvidu-components-angular/projects/openvidu-components-angular/src/lib/services/config/directive-config.service.ts b/openvidu-components-angular/projects/openvidu-components-angular/src/lib/services/config/directive-config.service.ts index 2b312db529..55b0f6c96c 100644 --- a/openvidu-components-angular/projects/openvidu-components-angular/src/lib/services/config/directive-config.service.ts +++ b/openvidu-components-angular/projects/openvidu-components-angular/src/lib/services/config/directive-config.service.ts @@ -2,11 +2,14 @@ import { Injectable } from '@angular/core'; import { BehaviorSubject, Observable } from 'rxjs'; import { RecordingInfo } from '../../models/recording.model'; import { ToolbarAdditionalButtonsPosition } from '../../models/toolbar.model'; +import { ParticipantModel } from '../../models/participant.model'; /** * @internal */ -@Injectable() +@Injectable({ + providedIn: 'root' +}) export class OpenViduComponentsConfigService { private token = >new BehaviorSubject(''); token$: Observable; @@ -87,6 +90,10 @@ export class OpenViduComponentsConfigService { private adminLoginError = >new BehaviorSubject(null); adminLoginError$: Observable; + // Internals + private layoutRemoteParticipants: BehaviorSubject = new BehaviorSubject(undefined); + layoutRemoteParticipants$: Observable; + constructor() { this.token$ = this.token.asObservable(); this.livekitUrl$ = this.livekitUrl.asObservable(); @@ -124,6 +131,8 @@ export class OpenViduComponentsConfigService { // Admin dashboard this.adminRecordingsList$ = this.adminRecordingsList.asObservable(); this.adminLoginError$ = this.adminLoginError.asObservable(); + // Internals + this.layoutRemoteParticipants$ = this.layoutRemoteParticipants.asObservable(); } setToken(token: string) { @@ -364,4 +373,9 @@ export class OpenViduComponentsConfigService { isBroadcastingEnabled(): boolean { return this.broadcastingButton.getValue() && this.broadcastingActivity.getValue(); } + + // Internals + setLayoutRemoteParticipants(participants: ParticipantModel[] | undefined) { + this.layoutRemoteParticipants.next(participants); + } } diff --git a/openvidu-components-angular/projects/openvidu-components-angular/src/lib/services/config/global-config.service.ts b/openvidu-components-angular/projects/openvidu-components-angular/src/lib/services/config/global-config.service.ts index 0ab1292d54..caa4174ce1 100644 --- a/openvidu-components-angular/projects/openvidu-components-angular/src/lib/services/config/global-config.service.ts +++ b/openvidu-components-angular/projects/openvidu-components-angular/src/lib/services/config/global-config.service.ts @@ -2,6 +2,9 @@ import { DOCUMENT } from '@angular/common'; import { Inject, Injectable} from '@angular/core'; import { ParticipantFactoryFunction, OpenViduComponentsConfig } from '../../config/openvidu-components-angular.config'; +/** + * @internal + */ @Injectable({ providedIn: 'root' }) diff --git a/openvidu-components-angular/projects/openvidu-components-angular/src/lib/services/config/service-config.service.ts b/openvidu-components-angular/projects/openvidu-components-angular/src/lib/services/config/service-config.service.ts new file mode 100644 index 0000000000..cc53be43b0 --- /dev/null +++ b/openvidu-components-angular/projects/openvidu-components-angular/src/lib/services/config/service-config.service.ts @@ -0,0 +1,40 @@ +import { Injectable, Inject, Injector, Type, Optional } from '@angular/core'; +import { LayoutService } from '../layout/layout.service'; +import { OpenViduComponentsConfig } from '../../config/openvidu-components-angular.config'; + +/** + * @internal + */ +@Injectable({ + providedIn: 'root' +}) +export class ServiceConfigService { + private configuration: OpenViduComponentsConfig; + + constructor( + @Optional() private injector: Injector, + @Inject('OPENVIDU_COMPONENTS_CONFIG') config: OpenViduComponentsConfig + ) { + this.configuration = config; + } + + getLayoutService(): LayoutService { + return this.getServiceSafely('LayoutService', LayoutService); + } + + private getService(key: string): T { + const service = this.configuration.services ? this.configuration.services[key] : null; + if (!service) { + throw new Error(`No service registered with key ${key}`); + } + return this.injector.get(service) as T; + } + + private getServiceSafely(key: string, fallback: new (...args: any[]) => T): T { + try { + return this.getService(key); + } catch { + return this.injector.get(fallback); + } + } +} diff --git a/openvidu-components-angular/projects/openvidu-components-angular/src/lib/services/layout/layout.service.ts b/openvidu-components-angular/projects/openvidu-components-angular/src/lib/services/layout/layout.service.ts index 5c6d9812d0..5a68e14ed4 100644 --- a/openvidu-components-angular/projects/openvidu-components-angular/src/lib/services/layout/layout.service.ts +++ b/openvidu-components-angular/projects/openvidu-components-angular/src/lib/services/layout/layout.service.ts @@ -1,6 +1,8 @@ import { Injectable } from '@angular/core'; import { BehaviorSubject, Observable } from 'rxjs'; import { LayoutAlignment, LayoutClass, OpenViduLayout, OpenViduLayoutOptions } from '../../models/layout.model'; +import { ILogger } from '../../models/logger.model'; +import { LoggerService } from '../logger/logger.service'; /** * @internal @@ -9,17 +11,19 @@ import { LayoutAlignment, LayoutClass, OpenViduLayout, OpenViduLayoutOptions } f providedIn: 'root' }) export class LayoutService { - layoutContainer: HTMLElement | null = null; + layoutContainer: HTMLElement | undefined = undefined; layoutWidthObs: Observable; captionsTogglingObs: Observable; - private layoutWidth: BehaviorSubject = new BehaviorSubject(0); - private openviduLayout: OpenViduLayout; - private openviduLayoutOptions: OpenViduLayoutOptions; - private captionsToggling: BehaviorSubject = new BehaviorSubject(false); + protected layoutWidth: BehaviorSubject = new BehaviorSubject(0); + protected openviduLayout: OpenViduLayout | undefined; + protected openviduLayoutOptions: OpenViduLayoutOptions; + protected captionsToggling: BehaviorSubject = new BehaviorSubject(false); + protected log: ILogger; - constructor() { + constructor(protected loggerSrv: LoggerService) { this.layoutWidthObs = this.layoutWidth.asObservable(); this.captionsTogglingObs = this.captionsToggling.asObservable(); + this.log = this.loggerSrv.get('LayoutService'); } initialize(container: HTMLElement) { @@ -32,7 +36,33 @@ export class LayoutService { this.sendLayoutWidthEvent(); } - private getOptions(): OpenViduLayoutOptions { + toggleCaptions() { + this.captionsToggling.next(!this.captionsToggling.getValue()); + } + + update(timeout: number | undefined = undefined) { + const updateAux = () => { + if (this.openviduLayout && this.layoutContainer) { + this.openviduLayout.updateLayout(this.layoutContainer, this.openviduLayoutOptions); + this.sendLayoutWidthEvent(); + } + }; + if (typeof timeout === 'number' && timeout >= 0) { + setTimeout(() => updateAux(), timeout); + } else { + updateAux(); + } + } + + getLayout() { + return this.openviduLayout; + } + + clear() { + this.openviduLayout = undefined; + } + + protected getOptions(): OpenViduLayoutOptions { const options = { maxRatio: 3 / 2, // The narrowest ratio that will be used (default 2x3) minRatio: 9 / 16, // The widest ratio that will be used (default 16x9) @@ -63,43 +93,19 @@ export class LayoutService { return options; } - toggleCaptions() { - this.captionsToggling.next(!this.captionsToggling.getValue()); - } - - update(timeout: number = null) { - const updateAux = () => { - if (!!this.openviduLayout) { - this.openviduLayout.updateLayout(this.layoutContainer, this.openviduLayoutOptions); - this.sendLayoutWidthEvent(); - } - }; - if (typeof timeout === 'number' && timeout >= 0) { - setTimeout(() => updateAux(), timeout); - } else { - updateAux(); + protected sendLayoutWidthEvent() { + const layoutContainer = this.openviduLayout?.getLayoutContainer(); + if (!layoutContainer) { + this.log.e('Layout container not found. Cannot send layout width event'); + return; } - } - - getLayout() { - return this.openviduLayout; - } - - clear() { - this.openviduLayout = null; - } - - private sendLayoutWidthEvent() { - const sidenavLayoutElement = this.getHTMLElementByClassName( - this.openviduLayout?.getLayoutContainer(), - LayoutClass.SIDENAV_CONTAINER - ); + const sidenavLayoutElement = this.getHTMLElementByClassName(layoutContainer, LayoutClass.SIDENAV_CONTAINER); if (sidenavLayoutElement && sidenavLayoutElement.clientWidth) { this.layoutWidth.next(sidenavLayoutElement.clientWidth); } } - private getHTMLElementByClassName(element: HTMLElement | null, className: string): HTMLElement | null { + protected getHTMLElementByClassName(element: HTMLElement | null, className: string): HTMLElement | null { while (!!element && element !== document.body) { if (element.className.includes(className)) { return element; diff --git a/openvidu-components-angular/projects/openvidu-components-angular/src/public-api.ts b/openvidu-components-angular/projects/openvidu-components-angular/src/public-api.ts index 2b1c6a062e..c1fce355e4 100644 --- a/openvidu-components-angular/projects/openvidu-components-angular/src/public-api.ts +++ b/openvidu-components-angular/projects/openvidu-components-angular/src/public-api.ts @@ -36,6 +36,7 @@ export * from './lib/models/recording.model'; export * from './lib/models/data-topic.model'; export * from './lib/models/room.model'; export * from './lib/models/toolbar.model'; +export * from './lib/models/logger.model' export * from './lib/openvidu-components-angular.module'; // Pipes export * from './lib/pipes/participant.pipe'; @@ -50,5 +51,6 @@ export * from './lib/services/panel/panel.service'; export * from './lib/services/participant/participant.service'; export * from './lib/services/recording/recording.service'; export * from './lib/services/config/global-config.service'; +export * from './lib/services/logger/logger.service'; export * from 'livekit-client';