ov-components: Add directive for injecting custom elements into settings panel

master
Carlos Santos 2025-11-24 12:45:38 +01:00
parent e59ed89a0b
commit 171a5104ae
7 changed files with 108 additions and 8 deletions

View File

@ -93,6 +93,12 @@
</mat-list>
</div>
}
<!-- Additional elements injected via directive -->
@if (generalAdditionalElementsTemplate) {
<div class="additional-elements-section">
<ng-container *ngTemplateOutlet="generalAdditionalElementsTemplate"></ng-container>
</div>
}
</div>
<div *ngIf="showCameraButton && selectedOption === settingsOptions.VIDEO" class="video-settings">
<ov-video-devices-select

View File

@ -1,4 +1,4 @@
import { Component, EventEmitter, OnInit, Output } from '@angular/core';
import { Component, ContentChild, EventEmitter, OnInit, Output, TemplateRef } from '@angular/core';
import { Subject, takeUntil } from 'rxjs';
import { PanelStatusInfo, PanelSettingsOptions, PanelType } from '../../../models/panel.model';
import { OpenViduComponentsConfigService } from '../../../services/config/directive-config.service';
@ -7,6 +7,7 @@ import { PlatformService } from '../../../services/platform/platform.service';
import { ViewportService } from '../../../services/viewport/viewport.service';
import { CustomDevice } from '../../../models/device.model';
import { LangOption } from '../../../models/lang.model';
import { SettingsPanelGeneralAdditionalElementsDirective } from '../../../directives/template/internals.directive';
/**
* @internal
@ -23,6 +24,14 @@ export class SettingsPanelComponent implements OnInit {
@Output() onAudioEnabledChanged = new EventEmitter<boolean>();
@Output() onAudioDeviceChanged = new EventEmitter<CustomDevice>();
@Output() onLangChanged = new EventEmitter<LangOption>();
/**
* @internal
* ContentChild for custom elements in general section
*/
@ContentChild(SettingsPanelGeneralAdditionalElementsDirective)
externalGeneralAdditionalElements!: SettingsPanelGeneralAdditionalElementsDirective;
settingsOptions: typeof PanelSettingsOptions = PanelSettingsOptions;
selectedOption: PanelSettingsOptions = PanelSettingsOptions.GENERAL;
showCameraButton: boolean = true;
@ -32,6 +41,14 @@ export class SettingsPanelComponent implements OnInit {
isMobile: boolean = false;
private destroy$ = new Subject<void>();
/**
* @internal
* Gets the template for additional elements in general section
*/
get generalAdditionalElementsTemplate(): TemplateRef<any> | undefined {
return this.externalGeneralAdditionalElements?.template;
}
constructor(
private panelService: PanelService,
private platformService: PlatformService,

View File

@ -127,7 +127,11 @@
(onAudioDeviceChanged)="onAudioDeviceChanged.emit($event)"
(onAudioEnabledChanged)="onAudioEnabledChanged.emit($event)"
(onLangChanged)="onLangChanged.emit($event)"
></ov-settings-panel>
>
<ng-container *ovSettingsPanelGeneralAdditionalElements>
<ng-container *ngTemplateOutlet="ovSettingsPanelGeneralAdditionalElementsTemplate"></ng-container>
</ng-container>
</ov-settings-panel>
</ng-template>
<ng-template #activitiesPanel>

View File

@ -62,7 +62,8 @@ import {
LayoutAdditionalElementsDirective,
ParticipantPanelAfterLocalParticipantDirective,
PreJoinDirective,
LeaveButtonDirective
LeaveButtonDirective,
SettingsPanelGeneralAdditionalElementsDirective
} from '../../directives/template/internals.directive';
import { OpenViduThemeService } from '../../services/theme/theme.service';
import { E2eeService } from '../../services/e2ee/e2ee.service';
@ -375,6 +376,22 @@ export class VideoconferenceComponent implements OnDestroy, AfterViewInit {
return this._externalLayoutAdditionalElements;
}
private _externalSettingsPanelGeneralAdditionalElements?: SettingsPanelGeneralAdditionalElementsDirective;
/**
* @internal
*/
@ContentChild(SettingsPanelGeneralAdditionalElementsDirective)
set externalSettingsPanelGeneralAdditionalElements(value: SettingsPanelGeneralAdditionalElementsDirective) {
this._externalSettingsPanelGeneralAdditionalElements = value;
this.setupTemplates();
}
/**
* @internal
*/
get externalSettingsPanelGeneralAdditionalElements(): SettingsPanelGeneralAdditionalElementsDirective | undefined {
return this._externalSettingsPanelGeneralAdditionalElements;
}
/**
* @internal
*/
@ -477,6 +494,10 @@ export class VideoconferenceComponent implements OnDestroy, AfterViewInit {
* @internal
*/
ovLayoutAdditionalElementsTemplate: TemplateRef<any>;
/**
* @internal
*/
ovSettingsPanelGeneralAdditionalElementsTemplate: TemplateRef<any>;
/**
* @internal
@ -786,7 +807,8 @@ export class VideoconferenceComponent implements OnDestroy, AfterViewInit {
layout: this.externalLayout,
stream: this.externalStream,
preJoin: this.externalPreJoin,
layoutAdditionalElements: this.externalLayoutAdditionalElements
layoutAdditionalElements: this.externalLayoutAdditionalElements,
settingsPanelGeneralAdditionalElements: this.externalSettingsPanelGeneralAdditionalElements
};
const defaultTemplates: DefaultTemplates = {
@ -861,6 +883,9 @@ export class VideoconferenceComponent implements OnDestroy, AfterViewInit {
if (this.templateConfig.layoutAdditionalElementsTemplate) {
assignIfChanged('ovLayoutAdditionalElementsTemplate', this.templateConfig.layoutAdditionalElementsTemplate);
}
if (this.templateConfig.settingsPanelGeneralAdditionalElementsTemplate) {
assignIfChanged('ovSettingsPanelGeneralAdditionalElementsTemplate', this.templateConfig.settingsPanelGeneralAdditionalElementsTemplate);
}
}
/**

View File

@ -308,3 +308,38 @@ export class ParticipantPanelParticipantBadgeDirective {
public container: ViewContainerRef
) {}
}
/**
* The ***ovSettingsPanelGeneralAdditionalElements** directive allows you to inject custom HTML or Angular templates
* into the general section of the settings panel.
* This enables you to add custom controls, information, or UI elements to extend the settings panel functionality.
*
* Usage example:
* ```html
* <ov-videoconference>
* <ng-container *ovSettingsPanelGeneralAdditionalElements>
* <div class="custom-settings-section">
* <mat-list>
* <mat-list-item>
* <mat-icon matListItemIcon>tune</mat-icon>
* <div matListItemTitle>Custom Setting</div>
* <mat-slide-toggle matListItemMeta [(ngModel)]="customSetting"></mat-slide-toggle>
* </mat-list-item>
* </mat-list>
* </div>
* </ng-container>
* </ov-videoconference>
* ```
*
* @internal
*/
@Directive({
selector: '[ovSettingsPanelGeneralAdditionalElements]',
standalone: false
})
export class SettingsPanelGeneralAdditionalElementsDirective {
constructor(
public template: TemplateRef<any>,
public container: ViewContainerRef
) {}
}

View File

@ -19,7 +19,8 @@ import {
ParticipantPanelAfterLocalParticipantDirective,
ParticipantPanelParticipantBadgeDirective,
PreJoinDirective,
LeaveButtonDirective
LeaveButtonDirective,
SettingsPanelGeneralAdditionalElementsDirective
} from './internals.directive';
@NgModule({
@ -40,7 +41,8 @@ import {
PreJoinDirective,
ParticipantPanelAfterLocalParticipantDirective,
LayoutAdditionalElementsDirective,
ParticipantPanelParticipantBadgeDirective
ParticipantPanelParticipantBadgeDirective,
SettingsPanelGeneralAdditionalElementsDirective
// BackgroundEffectsPanelDirective
],
exports: [
@ -60,7 +62,8 @@ import {
PreJoinDirective,
ParticipantPanelAfterLocalParticipantDirective,
LayoutAdditionalElementsDirective,
ParticipantPanelParticipantBadgeDirective
ParticipantPanelParticipantBadgeDirective,
SettingsPanelGeneralAdditionalElementsDirective
// BackgroundEffectsPanelDirective
]
})

View File

@ -19,7 +19,8 @@ import {
PreJoinDirective,
ParticipantPanelAfterLocalParticipantDirective,
LayoutAdditionalElementsDirective,
LeaveButtonDirective
LeaveButtonDirective,
SettingsPanelGeneralAdditionalElementsDirective
} from '../../directives/template/internals.directive';
/**
@ -49,6 +50,9 @@ export interface TemplateConfiguration {
streamTemplate: TemplateRef<any>;
layoutAdditionalElementsTemplate?: TemplateRef<any>;
// Settings panel templates
settingsPanelGeneralAdditionalElementsTemplate?: TemplateRef<any>;
// PreJoin template
preJoinTemplate?: TemplateRef<any>;
}
@ -126,6 +130,7 @@ export interface ExternalDirectives {
stream?: StreamDirective;
preJoin?: PreJoinDirective;
layoutAdditionalElements?: LayoutAdditionalElementsDirective;
settingsPanelGeneralAdditionalElements?: SettingsPanelGeneralAdditionalElementsDirective;
}
/**
@ -208,6 +213,11 @@ export class TemplateManagerService {
config.layoutAdditionalElementsTemplate = externalDirectives.layoutAdditionalElements.template;
}
if (externalDirectives.settingsPanelGeneralAdditionalElements) {
this.log.v('Setting EXTERNAL SETTINGS PANEL GENERAL ADDITIONAL ELEMENTS');
config.settingsPanelGeneralAdditionalElementsTemplate = externalDirectives.settingsPanelGeneralAdditionalElements.template;
}
this.log.v('Template setup completed', config);
return config;
}