ov-componentes: Added ovToolbarAdditionalButtonsPosition directive

pull/839/head
Carlos Santos 2024-08-22 11:17:02 +02:00
parent 9f0246db2f
commit a82b2189bc
6 changed files with 112 additions and 4 deletions

View File

@ -91,6 +91,10 @@
</button>
</mat-menu>
<ng-container *ngIf="toolbarAdditionalButtonsTemplate && additionalButtonsPosition && additionalButtonsPosition === 'beforeMenu'">
<ng-container *ngTemplateOutlet="toolbarAdditionalButtonsTemplate"></ng-container>
</ng-container>
<!-- More options button -->
<button
mat-icon-button
@ -187,7 +191,7 @@
</mat-menu>
<!-- External additional buttons -->
<ng-container *ngIf="toolbarAdditionalButtonsTemplate">
<ng-container *ngIf="toolbarAdditionalButtonsTemplate && additionalButtonsPosition && additionalButtonsPosition === 'afterMenu'">
<ng-container *ngTemplateOutlet="toolbarAdditionalButtonsTemplate"></ng-container>
</ng-container>

View File

@ -48,6 +48,7 @@ import { TranslateService } from '../../services/translate/translate.service';
import { CdkOverlayService } from '../../services/cdk-overlay/cdk-overlay.service';
import { ParticipantModel } from '../../models/participant.model';
import { Room, RoomEvent } from 'livekit-client';
import { ToolbarAdditionalButtonsPosition } from '../../models/toolbar.model';
/**
* The **ToolbarComponent** is hosted inside of the {@link VideoconferenceComponent}.
@ -75,7 +76,7 @@ export class ToolbarComponent implements OnInit, OnDestroy, AfterViewInit {
*/
@ContentChild(ToolbarAdditionalButtonsDirective)
set externalAdditionalButtons(externalAdditionalButtons: ToolbarAdditionalButtonsDirective) {
// This directive will has value only when ADDITIONAL BUTTONS component tagget with '*ovToolbarAdditionalButtons' directive
// This directive will has value only when ADDITIONAL BUTTONS component (tagged with '*ovToolbarAdditionalButtons' directive)
// is inside of the TOOLBAR component tagged with '*ovToolbar' directive
if (externalAdditionalButtons) {
this.toolbarAdditionalButtonsTemplate = externalAdditionalButtons.template;
@ -87,7 +88,7 @@ export class ToolbarComponent implements OnInit, OnDestroy, AfterViewInit {
*/
@ContentChild(ToolbarAdditionalPanelButtonsDirective)
set externalAdditionalPanelButtons(externalAdditionalPanelButtons: ToolbarAdditionalPanelButtonsDirective) {
// This directive will has value only when ADDITIONAL PANEL BUTTONS component tagget with '*ovToolbarAdditionalPanelButtons' directive
// This directive will has value only when ADDITIONAL PANEL BUTTONS component tagged with '*ovToolbarAdditionalPanelButtons' directive
// is inside of the TOOLBAR component tagged with '*ovToolbar' directive
if (externalAdditionalPanelButtons) {
this.toolbarAdditionalPanelButtonsTemplate = externalAdditionalPanelButtons.template;
@ -266,6 +267,11 @@ export class ToolbarComponent implements OnInit, OnDestroy, AfterViewInit {
*/
showCaptionsButton: boolean = true;
/**
* @ignore
*/
additionalButtonsPosition: ToolbarAdditionalButtonsPosition;
/**
* @ignore
*/
@ -333,6 +339,7 @@ export class ToolbarComponent implements OnInit, OnDestroy, AfterViewInit {
private displayRoomNameSub: Subscription;
private settingsButtonSub: Subscription;
private captionsSubs: Subscription;
private additionalButtonsPositionSub: Subscription;
private fullscreenChangeSubscription: Subscription;
private currentWindowHeight = window.innerHeight;
@ -427,6 +434,7 @@ export class ToolbarComponent implements OnInit, OnDestroy, AfterViewInit {
if (this.settingsButtonSub) this.settingsButtonSub.unsubscribe();
if (this.captionsSubs) this.captionsSubs.unsubscribe();
if (this.fullscreenChangeSubscription) this.fullscreenChangeSubscription.unsubscribe();
if (this.additionalButtonsPositionSub) this.additionalButtonsPositionSub.unsubscribe();
this.isFullscreenActive = false;
this.cdkOverlayService.setSelector('body');
}
@ -744,6 +752,20 @@ export class ToolbarComponent implements OnInit, OnDestroy, AfterViewInit {
this.showCaptionsButton = value;
this.cd.markForCheck();
});
this.additionalButtonsPositionSub = this.libService.toolbarAdditionalButtonsPosition$.subscribe(
(value: ToolbarAdditionalButtonsPosition) => {
// Using Promise.resolve() to defer change detection until the next microtask.
// This ensures that Angular's change detection has the latest value before updating the view.
// Without this, Angular's OnPush strategy might not immediately reflect the change,
// due to asynchronous operations affecting the timing of the detection cycle.
Promise.resolve().then(() => {
this.additionalButtonsPosition = value;
this.cd.markForCheck();
});
}
);
}
private subscribeToCaptionsToggling() {

View File

@ -21,7 +21,8 @@ import {
ToolbarParticipantsPanelButtonDirective,
ToolbarRecordingButtonDirective,
ToolbarScreenshareButtonDirective,
ToolbarSettingsButtonDirective
ToolbarSettingsButtonDirective,
ToolbarAdditionalButtonsPossitionDirective
} from './toolbar.directive';
import {
AudioEnabledDirective,
@ -65,6 +66,7 @@ import {
ToolbarDisplayRoomNameDirective,
ToolbarDisplayLogoDirective,
ToolbarSettingsButtonDirective,
ToolbarAdditionalButtonsPossitionDirective,
StreamDisplayParticipantNameDirective,
StreamDisplayAudioDetectionDirective,
StreamVideoControlsDirective,
@ -101,6 +103,7 @@ import {
ToolbarDisplayRoomNameDirective,
ToolbarDisplayLogoDirective,
ToolbarSettingsButtonDirective,
ToolbarAdditionalButtonsPossitionDirective,
StreamDisplayParticipantNameDirective,
StreamDisplayAudioDetectionDirective,
StreamVideoControlsDirective,

View File

@ -1,5 +1,6 @@
import { AfterViewInit, Directive, ElementRef, Input, OnDestroy } from '@angular/core';
import { OpenViduComponentsConfigService } from '../../services/config/openvidu-components-angular.config.service';
import { ToolbarAdditionalButtonsPosition } from '../../models/toolbar.model';
/**
* The **screenshareButton** directive allows show/hide the screenshare toolbar button.
@ -812,3 +813,59 @@ export class ToolbarDisplayLogoDirective implements AfterViewInit, OnDestroy {
}
}
}
/**
* The **ovToolbarAdditionalButtonsPosition** defines the position where the additional buttons should be inserted.
*
* The possible values are: {@link ToolbarAdditionalButtonsPosition}
* Default: `afterMenu`
*
* It can be used in the any element which contains the structural directive {@link ToolbarAdditionalButtonsDirective}.
*
* @example
* <div *ovToolbarAdditionalButtons [ovToolbarAdditionalButtonsPosition]="'beforeMenu'"></div>
*
*/
@Directive({
selector: '[ovToolbarAdditionalButtonsPosition]'
})
export class ToolbarAdditionalButtonsPossitionDirective implements AfterViewInit, OnDestroy {
/**
* @ignore
*/
@Input() set ovToolbarAdditionalButtonsPosition(value: ToolbarAdditionalButtonsPosition) {
if (!value) return;
if (!Object.values(ToolbarAdditionalButtonsPosition).includes(value)) return;
this.additionalButtonsPosition = value;
this.update(this.additionalButtonsPosition);
}
private additionalButtonsPosition: ToolbarAdditionalButtonsPosition = ToolbarAdditionalButtonsPosition.AFTER_MENU;
/**
* @ignore
*/
constructor(
public elementRef: ElementRef,
private libService: OpenViduComponentsConfigService
) {}
ngAfterViewInit() {
this.update(this.additionalButtonsPosition);
}
ngOnDestroy(): void {
this.clear();
}
private clear() {
this.additionalButtonsPosition = ToolbarAdditionalButtonsPosition.AFTER_MENU;
this.update(ToolbarAdditionalButtonsPosition.AFTER_MENU);
}
private update(value: ToolbarAdditionalButtonsPosition) {
if (this.libService.getToolbarAdditionalButtonsPosition() !== value) {
this.libService.setToolbarAdditionalButtonsPosition(value);
}
}
}

View File

@ -0,0 +1,7 @@
/**
* Enum representing the position of additional buttons in a toolbar.
*/
export enum ToolbarAdditionalButtonsPosition {
BEFORE_MENU = 'beforeMenu',
AFTER_MENU = 'afterMenu'
}

View File

@ -3,6 +3,7 @@ import { BehaviorSubject, Observable } from 'rxjs';
import { OpenViduComponentsConfig, ParticipantFactoryFunction } from '../../config/openvidu-components-angular.config';
import { RecordingInfo } from '../../models/recording.model';
import { DOCUMENT } from '@angular/common';
import { ToolbarAdditionalButtonsPosition } from '../../models/toolbar.model';
// import { version } from '../../../../package.json';
@ -60,6 +61,12 @@ export class OpenViduComponentsConfigService {
private displayLogo = <BehaviorSubject<boolean>>new BehaviorSubject(true);
displayLogo$: Observable<boolean>;
private toolbarAdditionalButtonsPosition = <BehaviorSubject<ToolbarAdditionalButtonsPosition>>(
new BehaviorSubject(ToolbarAdditionalButtonsPosition.AFTER_MENU)
);
toolbarAdditionalButtonsPosition$: Observable<ToolbarAdditionalButtonsPosition>;
private displayParticipantName = <BehaviorSubject<boolean>>new BehaviorSubject(true);
displayParticipantName$: Observable<boolean>;
private displayAudioDetection = <BehaviorSubject<boolean>>new BehaviorSubject(true);
@ -114,6 +121,7 @@ export class OpenViduComponentsConfigService {
this.broadcastingButton$ = this.broadcastingButton.asObservable();
this.toolbarSettingsButton$ = this.toolbarSettingsButton.asObservable();
this.captionsButton$ = this.captionsButton.asObservable();
this.toolbarAdditionalButtonsPosition$ = this.toolbarAdditionalButtonsPosition.asObservable();
//Stream observables
this.displayParticipantName$ = this.displayParticipantName.asObservable();
this.displayAudioDetection$ = this.displayAudioDetection.asObservable();
@ -261,6 +269,13 @@ export class OpenViduComponentsConfigService {
showLogo(): boolean {
return this.displayLogo.getValue();
}
getToolbarAdditionalButtonsPosition(): ToolbarAdditionalButtonsPosition {
return this.toolbarAdditionalButtonsPosition.getValue();
}
setToolbarAdditionalButtonsPosition(toolbarAdditionalButtonsPosition: ToolbarAdditionalButtonsPosition) {
this.toolbarAdditionalButtonsPosition.next(toolbarAdditionalButtonsPosition);
}
setRecordingButton(recordingButton: boolean) {
this.recordingButton.next(recordingButton);