From 171a5104aed00f41cb969dbb5653efac3cffbf81 Mon Sep 17 00:00:00 2001
From: Carlos Santos <4a.santos@gmail.com>
Date: Mon, 24 Nov 2025 12:45:38 +0100
Subject: [PATCH] ov-components: Add directive for injecting custom elements
into settings panel
---
.../settings-panel.component.html | 6 ++++
.../settings-panel.component.ts | 19 +++++++++-
.../videoconference.component.html | 6 +++-
.../videoconference.component.ts | 29 +++++++++++++--
.../template/internals.directive.ts | 35 +++++++++++++++++++
...idu-components-angular.directive.module.ts | 9 +++--
.../template/template-manager.service.ts | 12 ++++++-
7 files changed, 108 insertions(+), 8 deletions(-)
diff --git a/openvidu-components-angular/projects/openvidu-components-angular/src/lib/components/panel/settings-panel/settings-panel.component.html b/openvidu-components-angular/projects/openvidu-components-angular/src/lib/components/panel/settings-panel/settings-panel.component.html
index 662e1594e..452e5121d 100644
--- a/openvidu-components-angular/projects/openvidu-components-angular/src/lib/components/panel/settings-panel/settings-panel.component.html
+++ b/openvidu-components-angular/projects/openvidu-components-angular/src/lib/components/panel/settings-panel/settings-panel.component.html
@@ -93,6 +93,12 @@
}
+
+ @if (generalAdditionalElementsTemplate) {
+
+
+
+ }
();
@Output() onAudioDeviceChanged = new EventEmitter();
@Output() onLangChanged = new EventEmitter();
+
+ /**
+ * @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();
+ /**
+ * @internal
+ * Gets the template for additional elements in general section
+ */
+ get generalAdditionalElementsTemplate(): TemplateRef | undefined {
+ return this.externalGeneralAdditionalElements?.template;
+ }
+
constructor(
private panelService: PanelService,
private platformService: PlatformService,
diff --git a/openvidu-components-angular/projects/openvidu-components-angular/src/lib/components/videoconference/videoconference.component.html b/openvidu-components-angular/projects/openvidu-components-angular/src/lib/components/videoconference/videoconference.component.html
index 93f69b0c1..55f5ca2a8 100644
--- a/openvidu-components-angular/projects/openvidu-components-angular/src/lib/components/videoconference/videoconference.component.html
+++ b/openvidu-components-angular/projects/openvidu-components-angular/src/lib/components/videoconference/videoconference.component.html
@@ -127,7 +127,11 @@
(onAudioDeviceChanged)="onAudioDeviceChanged.emit($event)"
(onAudioEnabledChanged)="onAudioEnabledChanged.emit($event)"
(onLangChanged)="onLangChanged.emit($event)"
- >
+ >
+
+
+
+
diff --git a/openvidu-components-angular/projects/openvidu-components-angular/src/lib/components/videoconference/videoconference.component.ts b/openvidu-components-angular/projects/openvidu-components-angular/src/lib/components/videoconference/videoconference.component.ts
index 9302578d2..73e15d4ae 100644
--- a/openvidu-components-angular/projects/openvidu-components-angular/src/lib/components/videoconference/videoconference.component.ts
+++ b/openvidu-components-angular/projects/openvidu-components-angular/src/lib/components/videoconference/videoconference.component.ts
@@ -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;
+ /**
+ * @internal
+ */
+ ovSettingsPanelGeneralAdditionalElementsTemplate: TemplateRef;
/**
* @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);
+ }
}
/**
diff --git a/openvidu-components-angular/projects/openvidu-components-angular/src/lib/directives/template/internals.directive.ts b/openvidu-components-angular/projects/openvidu-components-angular/src/lib/directives/template/internals.directive.ts
index c2d5bf4c8..e5314fbdc 100644
--- a/openvidu-components-angular/projects/openvidu-components-angular/src/lib/directives/template/internals.directive.ts
+++ b/openvidu-components-angular/projects/openvidu-components-angular/src/lib/directives/template/internals.directive.ts
@@ -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
+ *
+ *
+ *
+ *
+ *
+ * tune
+ * Custom Setting
+ *
+ *
+ *
+ *
+ *
+ *
+ * ```
+ *
+ * @internal
+ */
+@Directive({
+ selector: '[ovSettingsPanelGeneralAdditionalElements]',
+ standalone: false
+})
+export class SettingsPanelGeneralAdditionalElementsDirective {
+ constructor(
+ public template: TemplateRef,
+ public container: ViewContainerRef
+ ) {}
+}
diff --git a/openvidu-components-angular/projects/openvidu-components-angular/src/lib/directives/template/openvidu-components-angular.directive.module.ts b/openvidu-components-angular/projects/openvidu-components-angular/src/lib/directives/template/openvidu-components-angular.directive.module.ts
index 89f0aa90a..c7496309f 100644
--- a/openvidu-components-angular/projects/openvidu-components-angular/src/lib/directives/template/openvidu-components-angular.directive.module.ts
+++ b/openvidu-components-angular/projects/openvidu-components-angular/src/lib/directives/template/openvidu-components-angular.directive.module.ts
@@ -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
]
})
diff --git a/openvidu-components-angular/projects/openvidu-components-angular/src/lib/services/template/template-manager.service.ts b/openvidu-components-angular/projects/openvidu-components-angular/src/lib/services/template/template-manager.service.ts
index 15a3c91f6..d0d3df252 100644
--- a/openvidu-components-angular/projects/openvidu-components-angular/src/lib/services/template/template-manager.service.ts
+++ b/openvidu-components-angular/projects/openvidu-components-angular/src/lib/services/template/template-manager.service.ts
@@ -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;
layoutAdditionalElementsTemplate?: TemplateRef;
+ // Settings panel templates
+ settingsPanelGeneralAdditionalElementsTemplate?: TemplateRef;
+
// PreJoin template
preJoinTemplate?: TemplateRef;
}
@@ -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;
}