diff --git a/openvidu-components-angular/projects/openvidu-components-angular/src/lib/components/toolbar/toolbar-media-buttons/toolbar-media-buttons.component.html b/openvidu-components-angular/projects/openvidu-components-angular/src/lib/components/toolbar/toolbar-media-buttons/toolbar-media-buttons.component.html
index 25b9fdd0d..f2c3bba7e 100644
--- a/openvidu-components-angular/projects/openvidu-components-angular/src/lib/components/toolbar/toolbar-media-buttons/toolbar-media-buttons.component.html
+++ b/openvidu-components-angular/projects/openvidu-components-angular/src/lib/components/toolbar/toolbar-media-buttons/toolbar-media-buttons.component.html
@@ -177,6 +177,11 @@
}
+
+ @if (moreOptionsAdditionalMenuItemsTemplate) {
+
+ }
+
@if (showSettingsButton) {
diff --git a/openvidu-components-angular/projects/openvidu-components-angular/src/lib/components/toolbar/toolbar-media-buttons/toolbar-media-buttons.component.ts b/openvidu-components-angular/projects/openvidu-components-angular/src/lib/components/toolbar/toolbar-media-buttons/toolbar-media-buttons.component.ts
index 144017040..96baae5a1 100644
--- a/openvidu-components-angular/projects/openvidu-components-angular/src/lib/components/toolbar/toolbar-media-buttons/toolbar-media-buttons.component.ts
+++ b/openvidu-components-angular/projects/openvidu-components-angular/src/lib/components/toolbar/toolbar-media-buttons/toolbar-media-buttons.component.ts
@@ -1,8 +1,9 @@
-import { Component, EventEmitter, Input, Output, TemplateRef, computed, inject } from '@angular/core';
+import { Component, ContentChild, EventEmitter, Input, Output, TemplateRef, computed, inject } from '@angular/core';
import { RecordingStatus } from '../../../models/recording.model';
import { BroadcastingStatus } from '../../../models/broadcasting.model';
import { ToolbarAdditionalButtonsPosition } from '../../../models/toolbar.model';
import { ViewportService } from '../../../services/viewport/viewport.service';
+import { ToolbarMoreOptionsAdditionalMenuItemsDirective } from '../../../directives/template/internals.directive';
/**
* @internal
@@ -71,6 +72,21 @@ export class ToolbarMediaButtonsComponent {
// Leave button template
@Input() toolbarLeaveButtonTemplate: TemplateRef | null = null;
+ /**
+ * @internal
+ * ContentChild for custom menu items in more options menu
+ */
+ @ContentChild(ToolbarMoreOptionsAdditionalMenuItemsDirective)
+ externalMoreOptionsAdditionalMenuItems!: ToolbarMoreOptionsAdditionalMenuItemsDirective;
+
+ /**
+ * @internal
+ * Gets the template for additional menu items in more options
+ */
+ get moreOptionsAdditionalMenuItemsTemplate(): TemplateRef | undefined {
+ return this.externalMoreOptionsAdditionalMenuItems?.template;
+ }
+
// Status enums for template usage
_recordingStatus = RecordingStatus;
_broadcastingStatus = BroadcastingStatus;
diff --git a/openvidu-components-angular/projects/openvidu-components-angular/src/lib/components/toolbar/toolbar.component.html b/openvidu-components-angular/projects/openvidu-components-angular/src/lib/components/toolbar/toolbar.component.html
index ea8d3b84f..cdbe146fc 100644
--- a/openvidu-components-angular/projects/openvidu-components-angular/src/lib/components/toolbar/toolbar.component.html
+++ b/openvidu-components-angular/projects/openvidu-components-angular/src/lib/components/toolbar/toolbar.component.html
@@ -82,7 +82,12 @@
(captionsToggled)="onCaptionsToggle()"
(settingsToggled)="toggleSettings()"
(leaveClicked)="disconnect()"
- >
+ >
+
+
+
+
+
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 d9c0382e7..8673b5825 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
@@ -50,7 +50,7 @@ import { CdkOverlayService } from '../../services/cdk-overlay/cdk-overlay.servic
import { ParticipantLeftEvent, ParticipantLeftReason, ParticipantModel } from '../../models/participant.model';
import { Room, RoomEvent } from 'livekit-client';
import { ToolbarAdditionalButtonsPosition } from '../../models/toolbar.model';
-import { LeaveButtonDirective } from '../../directives/template/internals.directive';
+import { LeaveButtonDirective, ToolbarMoreOptionsAdditionalMenuItemsDirective } from '../../directives/template/internals.directive';
/**
* The **ToolbarComponent** is hosted inside of the {@link VideoconferenceComponent}.
@@ -80,6 +80,28 @@ export class ToolbarComponent implements OnInit, OnDestroy, AfterViewInit {
| TemplateRef
| undefined;
+ /**
+ * @internal
+ * Template for additional menu items in the more options menu
+ */
+ moreOptionsAdditionalMenuItemsTemplate: TemplateRef | undefined;
+
+ private _externalMoreOptionsAdditionalMenuItems?: ToolbarMoreOptionsAdditionalMenuItemsDirective;
+ /**
+ * @internal
+ */
+ @ContentChild(ToolbarMoreOptionsAdditionalMenuItemsDirective)
+ set externalMoreOptionsAdditionalMenuItems(value: ToolbarMoreOptionsAdditionalMenuItemsDirective) {
+ this._externalMoreOptionsAdditionalMenuItems = value;
+ this.setupTemplates();
+ }
+ /**
+ * @internal
+ */
+ get externalMoreOptionsAdditionalMenuItems(): ToolbarMoreOptionsAdditionalMenuItemsDirective | undefined {
+ return this._externalMoreOptionsAdditionalMenuItems;
+ }
+
/**
* @ignore
*/
@@ -494,7 +516,8 @@ export class ToolbarComponent implements OnInit, OnDestroy, AfterViewInit {
this.templateConfig = this.templateManagerService.setupToolbarTemplates(
this._externalAdditionalButtons,
this._externalAdditionalPanelButtons,
- this._externalLeaveButton
+ this._externalLeaveButton,
+ this._externalMoreOptionsAdditionalMenuItems
);
// Apply templates to component properties for backward compatibility
@@ -515,6 +538,9 @@ export class ToolbarComponent implements OnInit, OnDestroy, AfterViewInit {
if (this.templateConfig.toolbarLeaveButtonTemplate) {
this.toolbarLeaveButtonTemplate = this.templateConfig.toolbarLeaveButtonTemplate;
}
+ if (this.templateConfig.toolbarMoreOptionsAdditionalMenuItemsTemplate) {
+ this.moreOptionsAdditionalMenuItemsTemplate = this.templateConfig.toolbarMoreOptionsAdditionalMenuItemsTemplate;
+ }
}
/**
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 55f5ca2a8..0a64f08ef 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
@@ -96,6 +96,11 @@
+
+
+
+
+
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 73e15d4ae..5e20e5e53 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
@@ -63,7 +63,8 @@ import {
ParticipantPanelAfterLocalParticipantDirective,
PreJoinDirective,
LeaveButtonDirective,
- SettingsPanelGeneralAdditionalElementsDirective
+ SettingsPanelGeneralAdditionalElementsDirective,
+ ToolbarMoreOptionsAdditionalMenuItemsDirective
} from '../../directives/template/internals.directive';
import { OpenViduThemeService } from '../../services/theme/theme.service';
import { E2eeService } from '../../services/e2ee/e2ee.service';
@@ -392,6 +393,22 @@ export class VideoconferenceComponent implements OnDestroy, AfterViewInit {
return this._externalSettingsPanelGeneralAdditionalElements;
}
+ private _externalToolbarMoreOptionsAdditionalMenuItems?: ToolbarMoreOptionsAdditionalMenuItemsDirective;
+ /**
+ * @internal
+ */
+ @ContentChild(ToolbarMoreOptionsAdditionalMenuItemsDirective)
+ set externalToolbarMoreOptionsAdditionalMenuItems(value: ToolbarMoreOptionsAdditionalMenuItemsDirective) {
+ this._externalToolbarMoreOptionsAdditionalMenuItems = value;
+ this.setupTemplates();
+ }
+ /**
+ * @internal
+ */
+ get externalToolbarMoreOptionsAdditionalMenuItems(): ToolbarMoreOptionsAdditionalMenuItemsDirective | undefined {
+ return this._externalToolbarMoreOptionsAdditionalMenuItems;
+ }
+
/**
* @internal
*/
@@ -498,6 +515,10 @@ export class VideoconferenceComponent implements OnDestroy, AfterViewInit {
* @internal
*/
ovSettingsPanelGeneralAdditionalElementsTemplate: TemplateRef;
+ /**
+ * @internal
+ */
+ ovToolbarMoreOptionsAdditionalMenuItemsTemplate: TemplateRef;
/**
* @internal
@@ -808,7 +829,8 @@ export class VideoconferenceComponent implements OnDestroy, AfterViewInit {
stream: this.externalStream,
preJoin: this.externalPreJoin,
layoutAdditionalElements: this.externalLayoutAdditionalElements,
- settingsPanelGeneralAdditionalElements: this.externalSettingsPanelGeneralAdditionalElements
+ settingsPanelGeneralAdditionalElements: this.externalSettingsPanelGeneralAdditionalElements,
+ toolbarMoreOptionsAdditionalMenuItems: this.externalToolbarMoreOptionsAdditionalMenuItems
};
const defaultTemplates: DefaultTemplates = {
@@ -886,6 +908,9 @@ export class VideoconferenceComponent implements OnDestroy, AfterViewInit {
if (this.templateConfig.settingsPanelGeneralAdditionalElementsTemplate) {
assignIfChanged('ovSettingsPanelGeneralAdditionalElementsTemplate', this.templateConfig.settingsPanelGeneralAdditionalElementsTemplate);
}
+ if (this.templateConfig.toolbarMoreOptionsAdditionalMenuItemsTemplate) {
+ assignIfChanged('ovToolbarMoreOptionsAdditionalMenuItemsTemplate', this.templateConfig.toolbarMoreOptionsAdditionalMenuItemsTemplate);
+ }
}
/**
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 e5314fbdc..0b8999e31 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
@@ -343,3 +343,38 @@ export class SettingsPanelGeneralAdditionalElementsDirective {
public container: ViewContainerRef
) {}
}
+
+/**
+ * The ***ovToolbarMoreOptionsAdditionalMenuItems** directive allows you to inject custom HTML or Angular templates
+ * into the "more options" menu (three dots button) of the toolbar.
+ * This enables you to add custom menu items to extend the toolbar functionality.
+ *
+ * Usage example:
+ * ```html
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ * ```
+ *
+ * @internal
+ */
+@Directive({
+ selector: '[ovToolbarMoreOptionsAdditionalMenuItems]',
+ standalone: false
+})
+export class ToolbarMoreOptionsAdditionalMenuItemsDirective {
+ constructor(
+ public template: TemplateRef,
+ public container: ViewContainerRef
+ ) {}
+}
\ No newline at end of file
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 c7496309f..436a20783 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
@@ -20,7 +20,8 @@ import {
ParticipantPanelParticipantBadgeDirective,
PreJoinDirective,
LeaveButtonDirective,
- SettingsPanelGeneralAdditionalElementsDirective
+ SettingsPanelGeneralAdditionalElementsDirective,
+ ToolbarMoreOptionsAdditionalMenuItemsDirective
} from './internals.directive';
@NgModule({
@@ -42,7 +43,8 @@ import {
ParticipantPanelAfterLocalParticipantDirective,
LayoutAdditionalElementsDirective,
ParticipantPanelParticipantBadgeDirective,
- SettingsPanelGeneralAdditionalElementsDirective
+ SettingsPanelGeneralAdditionalElementsDirective,
+ ToolbarMoreOptionsAdditionalMenuItemsDirective
// BackgroundEffectsPanelDirective
],
exports: [
@@ -63,7 +65,8 @@ import {
ParticipantPanelAfterLocalParticipantDirective,
LayoutAdditionalElementsDirective,
ParticipantPanelParticipantBadgeDirective,
- SettingsPanelGeneralAdditionalElementsDirective
+ SettingsPanelGeneralAdditionalElementsDirective,
+ ToolbarMoreOptionsAdditionalMenuItemsDirective
// 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 d0d3df252..f3cbf2b00 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
@@ -20,7 +20,8 @@ import {
ParticipantPanelAfterLocalParticipantDirective,
LayoutAdditionalElementsDirective,
LeaveButtonDirective,
- SettingsPanelGeneralAdditionalElementsDirective
+ SettingsPanelGeneralAdditionalElementsDirective,
+ ToolbarMoreOptionsAdditionalMenuItemsDirective
} from '../../directives/template/internals.directive';
/**
@@ -53,6 +54,9 @@ export interface TemplateConfiguration {
// Settings panel templates
settingsPanelGeneralAdditionalElementsTemplate?: TemplateRef;
+ // Toolbar templates
+ toolbarMoreOptionsAdditionalMenuItemsTemplate?: TemplateRef;
+
// PreJoin template
preJoinTemplate?: TemplateRef;
}
@@ -76,6 +80,7 @@ export interface ToolbarTemplateConfiguration {
toolbarAdditionalButtonsTemplate?: TemplateRef;
toolbarAdditionalPanelButtonsTemplate?: TemplateRef;
toolbarLeaveButtonTemplate?: TemplateRef;
+ toolbarMoreOptionsAdditionalMenuItemsTemplate?: TemplateRef;
}
/**
@@ -131,6 +136,7 @@ export interface ExternalDirectives {
preJoin?: PreJoinDirective;
layoutAdditionalElements?: LayoutAdditionalElementsDirective;
settingsPanelGeneralAdditionalElements?: SettingsPanelGeneralAdditionalElementsDirective;
+ toolbarMoreOptionsAdditionalMenuItems?: ToolbarMoreOptionsAdditionalMenuItemsDirective;
}
/**
@@ -218,6 +224,11 @@ export class TemplateManagerService {
config.settingsPanelGeneralAdditionalElementsTemplate = externalDirectives.settingsPanelGeneralAdditionalElements.template;
}
+ if (externalDirectives.toolbarMoreOptionsAdditionalMenuItems) {
+ this.log.v('Setting EXTERNAL TOOLBAR MORE OPTIONS ADDITIONAL MENU ITEMS');
+ config.toolbarMoreOptionsAdditionalMenuItemsTemplate = externalDirectives.toolbarMoreOptionsAdditionalMenuItems.template;
+ }
+
this.log.v('Template setup completed', config);
return config;
}
@@ -378,14 +389,16 @@ export class TemplateManagerService {
setupToolbarTemplates(
externalAdditionalButtons?: ToolbarAdditionalButtonsDirective,
externalAdditionalPanelButtons?: ToolbarAdditionalPanelButtonsDirective,
- externalLeaveButton?: LeaveButtonDirective
+ externalLeaveButton?: LeaveButtonDirective,
+ externalMoreOptionsAdditionalMenuItems?: ToolbarMoreOptionsAdditionalMenuItemsDirective
): ToolbarTemplateConfiguration {
this.log.v('Setting up toolbar templates...');
return {
toolbarAdditionalButtonsTemplate: externalAdditionalButtons?.template,
toolbarAdditionalPanelButtonsTemplate: externalAdditionalPanelButtons?.template,
- toolbarLeaveButtonTemplate: externalLeaveButton?.template
+ toolbarLeaveButtonTemplate: externalLeaveButton?.template,
+ toolbarMoreOptionsAdditionalMenuItemsTemplate: externalMoreOptionsAdditionalMenuItems?.template
};
}