mirror of https://github.com/OpenVidu/openvidu.git
ov-components: Add layout additional elements directive for customizable UI extensions
parent
e9ecceeb77
commit
4bf351b2df
|
@ -19,6 +19,11 @@
|
|||
<ng-container *ngTemplateOutlet="streamTemplate; context: { $implicit: track }"></ng-container>
|
||||
</div>
|
||||
|
||||
<!-- Render additional layout elements injected via ovAdditionalLayoutElement -->
|
||||
@if (layoutAdditionalElementsTemplate) {
|
||||
<ng-container *ngTemplateOutlet="layoutAdditionalElementsTemplate"></ng-container>
|
||||
}
|
||||
|
||||
<div
|
||||
*ngFor="let track of remoteParticipants | tracks; trackBy: trackParticipantElement"
|
||||
class="remote-participant"
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import { LayoutAdditionalElementsDirective } from '../../directives/template/internals.directive';
|
||||
|
||||
import {
|
||||
AfterViewInit,
|
||||
ChangeDetectionStrategy,
|
||||
|
@ -20,6 +22,7 @@ import { CdkDrag } from '@angular/cdk/drag-drop';
|
|||
import { PanelService } from '../../services/panel/panel.service';
|
||||
import { GlobalConfigService } from '../../services/config/global-config.service';
|
||||
import { OpenViduComponentsConfigService } from '../../services/config/directive-config.service';
|
||||
import { LayoutTemplateConfiguration, TemplateManagerService } from '../../services/template/template-manager.service';
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -39,6 +42,11 @@ export class LayoutComponent implements OnInit, OnDestroy, AfterViewInit {
|
|||
*/
|
||||
@ContentChild('stream', { read: TemplateRef }) streamTemplate: TemplateRef<any>;
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
@ContentChild('layoutAdditionalElements', { read: TemplateRef }) layoutAdditionalElementsTemplate: TemplateRef<any>;
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
|
@ -62,9 +70,27 @@ export class LayoutComponent implements OnInit, OnDestroy, AfterViewInit {
|
|||
// is inside of the layout component tagged with '*ovLayout' directive
|
||||
if (externalStream) {
|
||||
this.streamTemplate = externalStream.template;
|
||||
this.updateTemplatesAndMarkForCheck();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
@ContentChild(LayoutAdditionalElementsDirective) set externalAdditionalElements(
|
||||
externalAdditionalElements: LayoutAdditionalElementsDirective
|
||||
) {
|
||||
if (externalAdditionalElements) {
|
||||
this._externalLayoutAdditionalElements = externalAdditionalElements;
|
||||
this.updateTemplatesAndMarkForCheck();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
templateConfig: LayoutTemplateConfiguration = {};
|
||||
|
||||
localParticipant: ParticipantModel | undefined;
|
||||
remoteParticipants: ParticipantModel[] = [];
|
||||
/**
|
||||
|
@ -72,6 +98,9 @@ export class LayoutComponent implements OnInit, OnDestroy, AfterViewInit {
|
|||
*/
|
||||
captionsEnabled = true;
|
||||
|
||||
private _externalStream?: StreamDirective;
|
||||
private _externalLayoutAdditionalElements?: LayoutAdditionalElementsDirective;
|
||||
|
||||
private destroy$ = new Subject<void>();
|
||||
private resizeObserver: ResizeObserver;
|
||||
private resizeTimeout: NodeJS.Timeout;
|
||||
|
@ -87,10 +116,13 @@ export class LayoutComponent implements OnInit, OnDestroy, AfterViewInit {
|
|||
private participantService: ParticipantService,
|
||||
private globalService: GlobalConfigService,
|
||||
private directiveService: OpenViduComponentsConfigService,
|
||||
private cd: ChangeDetectorRef
|
||||
private cd: ChangeDetectorRef,
|
||||
private templateManagerService: TemplateManagerService
|
||||
) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.setupTemplates();
|
||||
|
||||
this.subscribeToParticipants();
|
||||
this.subscribeToCaptions();
|
||||
}
|
||||
|
@ -121,34 +153,55 @@ export class LayoutComponent implements OnInit, OnDestroy, AfterViewInit {
|
|||
return track;
|
||||
}
|
||||
|
||||
private setupTemplates() {
|
||||
this.templateConfig = this.templateManagerService.setupLayoutTemplates(
|
||||
this._externalStream,
|
||||
this._externalLayoutAdditionalElements
|
||||
);
|
||||
|
||||
// Apply templates to component properties for backward compatibility
|
||||
this.applyTemplateConfiguration();
|
||||
}
|
||||
|
||||
private applyTemplateConfiguration() {
|
||||
if (this.templateConfig.layoutStreamTemplate) {
|
||||
this.streamTemplate = this.templateConfig.layoutStreamTemplate;
|
||||
}
|
||||
if (this.templateConfig.layoutAdditionalElementsTemplate) {
|
||||
this.layoutAdditionalElementsTemplate = this.templateConfig.layoutAdditionalElementsTemplate;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* Updates templates and triggers change detection
|
||||
*/
|
||||
private updateTemplatesAndMarkForCheck(): void {
|
||||
this.setupTemplates();
|
||||
this.cd.markForCheck();
|
||||
}
|
||||
|
||||
private subscribeToCaptions() {
|
||||
this.layoutService.captionsTogglingObs
|
||||
.pipe(takeUntil(this.destroy$))
|
||||
.subscribe((value: boolean) => {
|
||||
this.captionsEnabled = value;
|
||||
this.cd.markForCheck();
|
||||
this.layoutService.update();
|
||||
});
|
||||
this.layoutService.captionsTogglingObs.pipe(takeUntil(this.destroy$)).subscribe((value: boolean) => {
|
||||
this.captionsEnabled = value;
|
||||
this.cd.markForCheck();
|
||||
this.layoutService.update();
|
||||
});
|
||||
}
|
||||
|
||||
private subscribeToParticipants() {
|
||||
this.participantService.localParticipant$
|
||||
.pipe(takeUntil(this.destroy$))
|
||||
.subscribe((p) => {
|
||||
if (p) {
|
||||
this.localParticipant = p;
|
||||
if (!this.localParticipant?.isMinimized) {
|
||||
this.videoIsAtRight = false;
|
||||
}
|
||||
this.layoutService.update();
|
||||
this.cd.markForCheck();
|
||||
this.participantService.localParticipant$.pipe(takeUntil(this.destroy$)).subscribe((p) => {
|
||||
if (p) {
|
||||
this.localParticipant = p;
|
||||
if (!this.localParticipant?.isMinimized) {
|
||||
this.videoIsAtRight = false;
|
||||
}
|
||||
});
|
||||
this.layoutService.update();
|
||||
this.cd.markForCheck();
|
||||
}
|
||||
});
|
||||
|
||||
combineLatest([
|
||||
this.participantService.remoteParticipants$,
|
||||
this.directiveService.layoutRemoteParticipants$
|
||||
])
|
||||
combineLatest([this.participantService.remoteParticipants$, this.directiveService.layoutRemoteParticipants$])
|
||||
.pipe(
|
||||
map(([serviceParticipants, directiveParticipants]) =>
|
||||
directiveParticipants !== undefined ? directiveParticipants : serviceParticipants
|
||||
|
@ -219,9 +272,7 @@ export class LayoutComponent implements OnInit, OnDestroy, AfterViewInit {
|
|||
}
|
||||
};
|
||||
|
||||
this.cdkDrag.released
|
||||
.pipe(takeUntil(this.destroy$))
|
||||
.subscribe(handler);
|
||||
this.cdkDrag.released.pipe(takeUntil(this.destroy$)).subscribe(handler);
|
||||
|
||||
if (this.globalService.isProduction()) return;
|
||||
// Just for allow E2E testing with drag and drop
|
||||
|
|
|
@ -100,7 +100,7 @@ export class PreJoinComponent implements OnInit, OnDestroy {
|
|||
this.cdkSrv.setSelector('body');
|
||||
|
||||
if (this.shouldRemoveTracksWhenComponentIsDestroyed) {
|
||||
this.tracks.forEach((track) => {
|
||||
this.tracks?.forEach((track) => {
|
||||
track.stop();
|
||||
});
|
||||
}
|
||||
|
|
|
@ -173,6 +173,10 @@
|
|||
<ng-template #stream let-track>
|
||||
<ng-container *ngTemplateOutlet="openviduAngularStreamTemplate; context: { $implicit: track }"></ng-container>
|
||||
</ng-template>
|
||||
|
||||
<ng-template #layoutAdditionalElements>
|
||||
<ng-container *ngTemplateOutlet="ovLayoutAdditionalElementsTemplate"></ng-container>
|
||||
</ng-template>
|
||||
</ov-layout>
|
||||
</ng-template>
|
||||
|
||||
|
|
|
@ -1,5 +1,16 @@
|
|||
import { animate, style, transition, trigger } from '@angular/animations';
|
||||
import { AfterViewInit, ChangeDetectionStrategy, ChangeDetectorRef, Component, ContentChild, EventEmitter, OnDestroy, Output, TemplateRef, ViewChild } from '@angular/core';
|
||||
import {
|
||||
AfterViewInit,
|
||||
ChangeDetectionStrategy,
|
||||
ChangeDetectorRef,
|
||||
Component,
|
||||
ContentChild,
|
||||
EventEmitter,
|
||||
OnDestroy,
|
||||
Output,
|
||||
TemplateRef,
|
||||
ViewChild
|
||||
} from '@angular/core';
|
||||
import { Subject, filter, skip, take, takeUntil } from 'rxjs';
|
||||
import {
|
||||
ActivitiesPanelDirective,
|
||||
|
@ -23,7 +34,12 @@ import { DeviceService } from '../../services/device/device.service';
|
|||
import { LoggerService } from '../../services/logger/logger.service';
|
||||
import { OpenViduService } from '../../services/openvidu/openvidu.service';
|
||||
import { StorageService } from '../../services/storage/storage.service';
|
||||
import { TemplateManagerService, TemplateConfiguration, ExternalDirectives, DefaultTemplates } from '../../services/template/template-manager.service';
|
||||
import {
|
||||
TemplateManagerService,
|
||||
TemplateConfiguration,
|
||||
ExternalDirectives,
|
||||
DefaultTemplates
|
||||
} from '../../services/template/template-manager.service';
|
||||
import { Room } from 'livekit-client';
|
||||
import { ParticipantLeftEvent, ParticipantModel } from '../../models/participant.model';
|
||||
import { CustomDevice } from '../../models/device.model';
|
||||
|
@ -42,7 +58,11 @@ import {
|
|||
} from '../../models/recording.model';
|
||||
import { BroadcastingStartRequestedEvent, BroadcastingStopRequestedEvent } from '../../models/broadcasting.model';
|
||||
import { LangOption } from '../../models/lang.model';
|
||||
import { ParticipantPanelAfterLocalParticipantDirective, PreJoinDirective } from '../../directives/template/internals.directive';
|
||||
import {
|
||||
LayoutAdditionalElementsDirective,
|
||||
ParticipantPanelAfterLocalParticipantDirective,
|
||||
PreJoinDirective
|
||||
} from '../../directives/template/internals.directive';
|
||||
|
||||
/**
|
||||
* The **VideoconferenceComponent** is the parent of all OpenVidu components.
|
||||
|
@ -54,18 +74,21 @@ import { ParticipantPanelAfterLocalParticipantDirective, PreJoinDirective } from
|
|||
styleUrls: ['./videoconference.component.scss'],
|
||||
animations: [
|
||||
trigger('inOutAnimation', [
|
||||
transition(':enter', [style({ opacity: 0 }), animate(`${VideoconferenceComponent.ANIMATION_DURATION_MS}ms ease-out`, style({ opacity: 1 }))])
|
||||
transition(':enter', [
|
||||
style({ opacity: 0 }),
|
||||
animate(`${VideoconferenceComponent.ANIMATION_DURATION_MS}ms ease-out`, style({ opacity: 1 }))
|
||||
])
|
||||
// transition(':leave', [style({ opacity: 1 }), animate('50ms ease-in', style({ opacity: 0.9 }))])
|
||||
])
|
||||
],
|
||||
standalone: false
|
||||
})
|
||||
export class VideoconferenceComponent implements OnDestroy, AfterViewInit {
|
||||
|
||||
// Constants
|
||||
private static readonly PARTICIPANT_NAME_TIMEOUT_MS = 1000;
|
||||
private static readonly ANIMATION_DURATION_MS = 300;
|
||||
private static readonly MATERIAL_ICONS_URL = 'https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined&icon_names=background_replace,keep_off';
|
||||
private static readonly MATERIAL_ICONS_URL =
|
||||
'https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined&icon_names=background_replace,keep_off';
|
||||
private static readonly MATERIAL_ICONS_SELECTOR = 'link[href*="Material+Symbols+Outlined"]';
|
||||
private static readonly SPINNER_DIAMETER = 50;
|
||||
// *** Toolbar ***
|
||||
|
@ -133,7 +156,12 @@ export class VideoconferenceComponent implements OnDestroy, AfterViewInit {
|
|||
* @internal
|
||||
*
|
||||
*/
|
||||
@ContentChild(ParticipantPanelAfterLocalParticipantDirective) externalParticipantPanelAfterLocalParticipant: ParticipantPanelAfterLocalParticipantDirective;
|
||||
@ContentChild(ParticipantPanelAfterLocalParticipantDirective)
|
||||
externalParticipantPanelAfterLocalParticipant: ParticipantPanelAfterLocalParticipantDirective;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
@ContentChild(LayoutAdditionalElementsDirective) externalLayoutAdditionalElements: LayoutAdditionalElementsDirective;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
|
@ -227,6 +255,10 @@ export class VideoconferenceComponent implements OnDestroy, AfterViewInit {
|
|||
* @internal
|
||||
*/
|
||||
openviduAngularPreJoinTemplate: TemplateRef<any>;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
ovLayoutAdditionalElementsTemplate: TemplateRef<any>;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
|
@ -530,7 +562,8 @@ export class VideoconferenceComponent implements OnDestroy, AfterViewInit {
|
|||
participantPanelItemElements: this.externalParticipantPanelItemElements,
|
||||
layout: this.externalLayout,
|
||||
stream: this.externalStream,
|
||||
preJoin: this.externalPreJoin
|
||||
preJoin: this.externalPreJoin,
|
||||
layoutAdditionalElements: this.externalLayoutAdditionalElements
|
||||
};
|
||||
|
||||
const defaultTemplates: DefaultTemplates = {
|
||||
|
@ -576,7 +609,8 @@ export class VideoconferenceComponent implements OnDestroy, AfterViewInit {
|
|||
this.openviduAngularAdditionalPanelsTemplate = this.templateConfig.additionalPanelsTemplate;
|
||||
}
|
||||
if (this.templateConfig.participantPanelAfterLocalParticipantTemplate) {
|
||||
this.openviduAngularParticipantPanelAfterLocalParticipantTemplate = this.templateConfig.participantPanelAfterLocalParticipantTemplate;
|
||||
this.openviduAngularParticipantPanelAfterLocalParticipantTemplate =
|
||||
this.templateConfig.participantPanelAfterLocalParticipantTemplate;
|
||||
}
|
||||
if (this.templateConfig.participantPanelItemElementsTemplate) {
|
||||
this.openviduAngularParticipantPanelItemElementsTemplate = this.templateConfig.participantPanelItemElementsTemplate;
|
||||
|
@ -584,6 +618,9 @@ export class VideoconferenceComponent implements OnDestroy, AfterViewInit {
|
|||
if (this.templateConfig.preJoinTemplate) {
|
||||
this.openviduAngularPreJoinTemplate = this.templateConfig.preJoinTemplate;
|
||||
}
|
||||
if (this.templateConfig.layoutAdditionalElementsTemplate) {
|
||||
this.ovLayoutAdditionalElementsTemplate = this.templateConfig.layoutAdditionalElementsTemplate;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -624,7 +661,7 @@ export class VideoconferenceComponent implements OnDestroy, AfterViewInit {
|
|||
this.log.w('No participant name available when requesting token');
|
||||
// Wait a bit and try again in case name is still propagating
|
||||
setTimeout(() => {
|
||||
const retryName = this.libService.getCurrentParticipantName()|| this.latestParticipantName;
|
||||
const retryName = this.libService.getCurrentParticipantName() || this.latestParticipantName;
|
||||
if (retryName) {
|
||||
this.log.d(`Retrying token request for participant: ${retryName}`);
|
||||
this.onTokenRequested.emit(retryName);
|
||||
|
@ -774,9 +811,11 @@ export class VideoconferenceComponent implements OnDestroy, AfterViewInit {
|
|||
this.storageSrv.setParticipantName(name);
|
||||
|
||||
// If we're waiting for a participant name to proceed with joining, do it now
|
||||
if (this.componentState.state === VideoconferenceState.JOINING &&
|
||||
if (
|
||||
this.componentState.state === VideoconferenceState.JOINING &&
|
||||
this.componentState.isRoomReady &&
|
||||
!this.componentState.showPrejoin) {
|
||||
!this.componentState.showPrejoin
|
||||
) {
|
||||
this.log.d('Participant name received, proceeding to join');
|
||||
this.updateComponentState({
|
||||
state: VideoconferenceState.READY_TO_CONNECT,
|
||||
|
@ -786,4 +825,4 @@ export class VideoconferenceComponent implements OnDestroy, AfterViewInit {
|
|||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -196,7 +196,7 @@ export class PreJoinDirective {
|
|||
|
||||
|
||||
/**
|
||||
* The **ovParticipantPanelAfterLocalParticipant** directive allows you to inject custom HTML or Angular templates
|
||||
* The ***ovParticipantPanelAfterLocalParticipant** directive allows you to inject custom HTML or Angular templates
|
||||
* immediately after the local participant item in the participant panel.
|
||||
* This enables you to extend the participant panel with additional controls, information, or UI elements.
|
||||
*
|
||||
|
@ -221,4 +221,32 @@ export class ParticipantPanelAfterLocalParticipantDirective {
|
|||
public template: TemplateRef<any>,
|
||||
public container: ViewContainerRef
|
||||
) {}
|
||||
}
|
||||
|
||||
/**
|
||||
* The ***ovLayoutAdditionalElements** directive allows you to inject custom HTML or Angular templates
|
||||
* as additional layout elements within the videoconference UI.
|
||||
* This enables you to extend the layout with extra controls, banners, or any custom UI.
|
||||
*
|
||||
* Usage example:
|
||||
* ```html
|
||||
* <ov-videoconference>
|
||||
* <ng-container *ovLayoutAdditionalElements>
|
||||
* <div class="my-custom-layout-element">
|
||||
* <!-- Your custom HTML here -->
|
||||
* <span>Extra layout element</span>
|
||||
* </div>
|
||||
* </ng-container>
|
||||
* </ov-videoconference>
|
||||
* ```
|
||||
*/
|
||||
@Directive({
|
||||
selector: '[ovLayoutAdditionalElements]',
|
||||
standalone: false
|
||||
})
|
||||
export class LayoutAdditionalElementsDirective {
|
||||
constructor(
|
||||
public template: TemplateRef<any>,
|
||||
public container: ViewContainerRef
|
||||
) {}
|
||||
}
|
|
@ -14,7 +14,7 @@ import {
|
|||
ActivitiesPanelDirective,
|
||||
BackgroundEffectsPanelDirective
|
||||
} from './openvidu-components-angular.directive';
|
||||
import { ParticipantPanelAfterLocalParticipantDirective, PreJoinDirective } from './internals.directive';
|
||||
import { LayoutAdditionalElementsDirective, ParticipantPanelAfterLocalParticipantDirective, PreJoinDirective } from './internals.directive';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
|
@ -31,7 +31,8 @@ import { ParticipantPanelAfterLocalParticipantDirective, PreJoinDirective } from
|
|||
ParticipantPanelItemElementsDirective,
|
||||
ActivitiesPanelDirective,
|
||||
PreJoinDirective,
|
||||
ParticipantPanelAfterLocalParticipantDirective
|
||||
ParticipantPanelAfterLocalParticipantDirective,
|
||||
LayoutAdditionalElementsDirective
|
||||
// BackgroundEffectsPanelDirective
|
||||
],
|
||||
exports: [
|
||||
|
@ -48,7 +49,8 @@ import { ParticipantPanelAfterLocalParticipantDirective, PreJoinDirective } from
|
|||
ParticipantPanelItemElementsDirective,
|
||||
ActivitiesPanelDirective,
|
||||
PreJoinDirective,
|
||||
ParticipantPanelAfterLocalParticipantDirective
|
||||
ParticipantPanelAfterLocalParticipantDirective,
|
||||
LayoutAdditionalElementsDirective
|
||||
// BackgroundEffectsPanelDirective
|
||||
]
|
||||
})
|
||||
|
|
|
@ -15,7 +15,11 @@ import {
|
|||
ToolbarAdditionalPanelButtonsDirective,
|
||||
ToolbarDirective
|
||||
} from '../../directives/template/openvidu-components-angular.directive';
|
||||
import { PreJoinDirective, ParticipantPanelAfterLocalParticipantDirective } from '../../directives/template/internals.directive';
|
||||
import {
|
||||
PreJoinDirective,
|
||||
ParticipantPanelAfterLocalParticipantDirective,
|
||||
LayoutAdditionalElementsDirective
|
||||
} from '../../directives/template/internals.directive';
|
||||
|
||||
/**
|
||||
* Configuration object for all templates in the videoconference component
|
||||
|
@ -41,6 +45,7 @@ export interface TemplateConfiguration {
|
|||
// Layout templates
|
||||
layoutTemplate: TemplateRef<any>;
|
||||
streamTemplate: TemplateRef<any>;
|
||||
layoutAdditionalElementsTemplate?: TemplateRef<any>;
|
||||
|
||||
// PreJoin template
|
||||
preJoinTemplate?: TemplateRef<any>;
|
||||
|
@ -66,6 +71,14 @@ export interface ToolbarTemplateConfiguration {
|
|||
toolbarAdditionalPanelButtonsTemplate?: TemplateRef<any>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configuration object for layout component templates
|
||||
*/
|
||||
export interface LayoutTemplateConfiguration {
|
||||
layoutStreamTemplate?: TemplateRef<any>;
|
||||
layoutAdditionalElementsTemplate?: TemplateRef<any>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configuration object for participants panel component templates
|
||||
*/
|
||||
|
@ -108,6 +121,7 @@ export interface ExternalDirectives {
|
|||
layout?: LayoutDirective;
|
||||
stream?: StreamDirective;
|
||||
preJoin?: PreJoinDirective;
|
||||
layoutAdditionalElements?: LayoutAdditionalElementsDirective;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -180,6 +194,11 @@ export class TemplateManagerService {
|
|||
this.log.d('Setting EXTERNAL PARTICIPANT PANEL ITEM ELEMENTS');
|
||||
}
|
||||
|
||||
if (externalDirectives.layoutAdditionalElements) {
|
||||
this.log.d('Setting EXTERNAL ADDITIONAL LAYOUT ELEMENTS');
|
||||
config.layoutAdditionalElementsTemplate = externalDirectives.layoutAdditionalElements.template;
|
||||
}
|
||||
|
||||
this.log.d('Template setup completed', config);
|
||||
return config;
|
||||
}
|
||||
|
@ -349,6 +368,21 @@ export class TemplateManagerService {
|
|||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up templates for the LayoutComponent
|
||||
*/
|
||||
setupLayoutTemplates(
|
||||
externalStream?: StreamDirective,
|
||||
externalLayoutAdditionalElements?: LayoutAdditionalElementsDirective
|
||||
): LayoutTemplateConfiguration {
|
||||
this.log.d('Setting up layout templates...');
|
||||
|
||||
return {
|
||||
layoutStreamTemplate: externalStream?.template,
|
||||
layoutAdditionalElementsTemplate: externalLayoutAdditionalElements?.template
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up templates for the ParticipantsPanelComponent
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue