ov-components: replace @Input decorators with input() for toolbar media buttons

master
CSantosM 2026-03-17 16:26:55 +01:00
parent ebac5b30c2
commit 2d2da5a659
2 changed files with 94 additions and 94 deletions

View File

@ -4,14 +4,14 @@
id="camera-btn" id="camera-btn"
mat-icon-button mat-icon-button
(click)="onCameraToggle()" (click)="onCameraToggle()"
[disabled]="isConnectionLost || !hasVideoDevices || cameraMuteChanging" [disabled]="isConnectionLost() || !hasVideoDevices() || cameraMuteChanging()"
[class.disabled]="!isCameraEnabled" [class.disabled]="!isCameraEnabled()"
[class.mobile-btn]="isMobileView()" [class.mobile-btn]="isMobileView()"
[matTooltip]="isCameraEnabled ? ('TOOLBAR.STOP_VIDEO' | translate) : ('TOOLBAR.START_VIDEO' | translate)" [matTooltip]="isCameraEnabled() ? ('TOOLBAR.STOP_VIDEO' | translate) : ('TOOLBAR.START_VIDEO' | translate)"
[matTooltipDisabled]="!hasVideoDevices" [matTooltipDisabled]="!hasVideoDevices()"
> >
<mat-icon [id]="isCameraEnabled ? 'videocam' : 'videocam_off'"> <mat-icon [id]="isCameraEnabled() ? 'videocam' : 'videocam_off'">
{{ isCameraEnabled ? 'videocam' : 'videocam_off' }} {{ isCameraEnabled() ? 'videocam' : 'videocam_off' }}
</mat-icon> </mat-icon>
</button> </button>
} }
@ -22,28 +22,28 @@
id="mic-btn" id="mic-btn"
mat-icon-button mat-icon-button
(click)="onMicrophoneToggle()" (click)="onMicrophoneToggle()"
[disabled]="isConnectionLost || !hasAudioDevices || microphoneMuteChanging" [disabled]="isConnectionLost() || !hasAudioDevices() || microphoneMuteChanging()"
[class.disabled]="!isMicrophoneEnabled" [class.disabled]="!isMicrophoneEnabled()"
[class.mobile-btn]="isMobileView()" [class.mobile-btn]="isMobileView()"
[matTooltip]="isMicrophoneEnabled ? ('TOOLBAR.MUTE_AUDIO' | translate) : ('TOOLBAR.UNMUTE_AUDIO' | translate)" [matTooltip]="isMicrophoneEnabled() ? ('TOOLBAR.MUTE_AUDIO' | translate) : ('TOOLBAR.UNMUTE_AUDIO' | translate)"
[matTooltipDisabled]="!hasAudioDevices" [matTooltipDisabled]="!hasAudioDevices()"
> >
<mat-icon [id]="isMicrophoneEnabled ? 'mic' : 'mic_off'"> <mat-icon [id]="isMicrophoneEnabled() ? 'mic' : 'mic_off'">
{{ isMicrophoneEnabled ? 'mic' : 'mic_off' }} {{ isMicrophoneEnabled() ? 'mic' : 'mic_off' }}
</mat-icon> </mat-icon>
</button> </button>
} }
<!-- Screenshare button - Only visible on tablet+ or when active --> <!-- Screenshare button - Only visible on tablet+ or when active -->
@if (showScreenshareButtonDirect()) { @if (showScreenshareButtonDirect()) {
@if (isFirefoxBrowser) { @if (isFirefoxBrowser()) {
<button <button
mat-icon-button mat-icon-button
id="screenshare-btn" id="screenshare-btn"
[disabled]="isConnectionLost" [disabled]="isConnectionLost()"
[class.active-btn]="isScreenShareEnabled" [class.active-btn]="isScreenShareEnabled()"
[class.mobile-btn]="isMobileView()" [class.mobile-btn]="isMobileView()"
matTooltip="{{ isScreenShareEnabled ? ('TOOLBAR.DISABLE_SCREEN' | translate) : ('TOOLBAR.ENABLE_SCREEN' | translate) }}" matTooltip="{{ isScreenShareEnabled() ? ('TOOLBAR.DISABLE_SCREEN' | translate) : ('TOOLBAR.ENABLE_SCREEN' | translate) }}"
(click)="onScreenShareToggle()" (click)="onScreenShareToggle()"
> >
<mat-icon>screen_share</mat-icon> <mat-icon>screen_share</mat-icon>
@ -52,12 +52,12 @@
<button <button
mat-icon-button mat-icon-button
id="screenshare-btn" id="screenshare-btn"
[matMenuTriggerFor]="isScreenShareEnabled ? screenshareMenu : null" [matMenuTriggerFor]="isScreenShareEnabled() ? screenshareMenu : null"
[disabled]="isConnectionLost" [disabled]="isConnectionLost()"
[class.active-btn]="isScreenShareEnabled" [class.active-btn]="isScreenShareEnabled()"
[class.mobile-btn]="isMobileView()" [class.mobile-btn]="isMobileView()"
matTooltip="{{ isScreenShareEnabled ? ('TOOLBAR.DISABLE_SCREEN' | translate) : ('TOOLBAR.ENABLE_SCREEN' | translate) }}" matTooltip="{{ isScreenShareEnabled() ? ('TOOLBAR.DISABLE_SCREEN' | translate) : ('TOOLBAR.ENABLE_SCREEN' | translate) }}"
(click)="!isScreenShareEnabled && onScreenShareToggle()" (click)="!isScreenShareEnabled() && onScreenShareToggle()"
> >
<mat-icon>screen_share</mat-icon> <mat-icon>screen_share</mat-icon>
</button> </button>
@ -78,8 +78,8 @@
} }
<!-- Additional buttons injection from parent component (desktop/tablet only) --> <!-- Additional buttons injection from parent component (desktop/tablet only) -->
@if (showAdditionalButtonsOutside() && additionalButtonsPosition === 'beforeMenu') { @if (showAdditionalButtonsOutside() && additionalButtonsPosition() === 'beforeMenu') {
<ng-container *ngTemplateOutlet="toolbarAdditionalButtonsTemplate; context: { $implicit: additionalButtonsPosition }"></ng-container> <ng-container *ngTemplateOutlet="toolbarAdditionalButtonsTemplate(); context: { $implicit: additionalButtonsPosition() }"></ng-container>
} }
<!-- More options button --> <!-- More options button -->
@ -88,7 +88,7 @@
mat-icon-button mat-icon-button
id="more-options-btn" id="more-options-btn"
[matMenuTriggerFor]="settingsMenu" [matMenuTriggerFor]="settingsMenu"
[disabled]="isConnectionLost" [disabled]="isConnectionLost()"
[class.mobile-btn]="isMobileView()" [class.mobile-btn]="isMobileView()"
matTooltip="{{ 'TOOLBAR.MORE_OPTIONS' | translate }}" matTooltip="{{ 'TOOLBAR.MORE_OPTIONS' | translate }}"
> >
@ -96,38 +96,38 @@
</button> </button>
<mat-menu #settingsMenu="matMenu" id="more-options-menu"> <mat-menu #settingsMenu="matMenu" id="more-options-menu">
<!-- Additional buttons injection inside menu (mobile only) --> <!-- Additional buttons injection inside menu (mobile only) -->
@if (showAdditionalButtonsInsideMenu() && additionalButtonsPosition === 'beforeMenu') { @if (showAdditionalButtonsInsideMenu() && additionalButtonsPosition() === 'beforeMenu') {
<ng-container *ngTemplateOutlet="toolbarAdditionalButtonsTemplate; context: { $implicit: additionalButtonsPosition }"> <ng-container *ngTemplateOutlet="toolbarAdditionalButtonsTemplate(); context: { $implicit: additionalButtonsPosition() }">
</ng-container> </ng-container>
} }
<!-- Fullscreen button --> <!-- Fullscreen button -->
@if (showFullscreenButton) { @if (showFullscreenButton()) {
<button mat-menu-item id="fullscreen-btn" (click)="onFullscreenToggle()"> <button mat-menu-item id="fullscreen-btn" (click)="onFullscreenToggle()">
<mat-icon>{{ isFullscreenActive ? 'fullscreen_exit' : 'fullscreen' }}</mat-icon> <mat-icon>{{ isFullscreenActive() ? 'fullscreen_exit' : 'fullscreen' }}</mat-icon>
<span>{{ isFullscreenActive ? ('TOOLBAR.EXIT_FULLSCREEN' | translate) : ('TOOLBAR.FULLSCREEN' | translate) }}</span> <span>{{ isFullscreenActive() ? ('TOOLBAR.EXIT_FULLSCREEN' | translate) : ('TOOLBAR.FULLSCREEN' | translate) }}</span>
</button> </button>
} }
<!-- Recording button --> <!-- Recording button -->
@if (showRecordingButton) { @if (showRecordingButton()) {
<button <button
mat-menu-item mat-menu-item
id="recording-btn" id="recording-btn"
[disabled]=" [disabled]="
recordingStatus === _recordingStatus.STARTING || recordingStatus() === _recordingStatus.STARTING ||
recordingStatus === _recordingStatus.STOPPING || recordingStatus() === _recordingStatus.STOPPING ||
!hasRoomTracksPublished !hasRoomTracksPublished()
" "
[matTooltip]="!hasRoomTracksPublished ? ('TOOLBAR.NO_TRACKS_PUBLISHED' | translate) : ''" [matTooltip]="!hasRoomTracksPublished() ? ('TOOLBAR.NO_TRACKS_PUBLISHED' | translate) : ''"
(click)="onRecordingToggle()" (click)="onRecordingToggle()"
> >
<mat-icon color="warn">radio_button_checked</mat-icon> <mat-icon color="warn">radio_button_checked</mat-icon>
<span> <span>
{{ {{
recordingStatus === _recordingStatus.STOPPED || recordingStatus() === _recordingStatus.STOPPED ||
recordingStatus === _recordingStatus.STOPPING || recordingStatus() === _recordingStatus.STOPPING ||
recordingStatus === _recordingStatus.FAILED recordingStatus() === _recordingStatus.FAILED
? ('TOOLBAR.START_RECORDING' | translate) ? ('TOOLBAR.START_RECORDING' | translate)
: ('TOOLBAR.STOP_RECORDING' | translate) : ('TOOLBAR.STOP_RECORDING' | translate)
}} }}
@ -136,7 +136,7 @@
} }
<!-- View recordings button --> <!-- View recordings button -->
@if (showViewRecordingsButton) { @if (showViewRecordingsButton()) {
<button mat-menu-item id="view-recordings-btn" (click)="onViewRecordingsClick()"> <button mat-menu-item id="view-recordings-btn" (click)="onViewRecordingsClick()">
<mat-icon>video_library</mat-icon> <mat-icon>video_library</mat-icon>
<span>{{ 'TOOLBAR.VIEW_RECORDINGS' | translate }}</span> <span>{{ 'TOOLBAR.VIEW_RECORDINGS' | translate }}</span>
@ -144,19 +144,19 @@
} }
<!-- Broadcasting button --> <!-- Broadcasting button -->
@if (showBroadcastingButton) { @if (showBroadcastingButton()) {
<button <button
mat-menu-item mat-menu-item
id="toolbar-broadcasting-btn" id="toolbar-broadcasting-btn"
[disabled]="broadcastingStatus === _broadcastingStatus.STARTING || recordingStatus === _broadcastingStatus.STOPPING" [disabled]="broadcastingStatus() === _broadcastingStatus.STARTING || recordingStatus() === _broadcastingStatus.STOPPING"
(click)="onBroadcastingToggle()" (click)="onBroadcastingToggle()"
> >
<mat-icon>sensors</mat-icon> <mat-icon>sensors</mat-icon>
<span> <span>
{{ {{
broadcastingStatus === _broadcastingStatus.STOPPED || broadcastingStatus() === _broadcastingStatus.STOPPED ||
broadcastingStatus === _broadcastingStatus.STOPPING || broadcastingStatus() === _broadcastingStatus.STOPPING ||
broadcastingStatus === _broadcastingStatus.FAILED broadcastingStatus() === _broadcastingStatus.FAILED
? ('PANEL.STREAMING.START' | translate) ? ('PANEL.STREAMING.START' | translate)
: ('PANEL.STREAMING.STOP' | translate) : ('PANEL.STREAMING.STOP' | translate)
}} }}
@ -165,8 +165,8 @@
} }
<!-- Virtual background button --> <!-- Virtual background button -->
@if (showBackgroundEffectsButton) { @if (showBackgroundEffectsButton()) {
<button mat-menu-item id="virtual-bg-btn" [disabled]="!isCameraEnabled" (click)="onBackgroundEffectsToggle()"> <button mat-menu-item id="virtual-bg-btn" [disabled]="!isCameraEnabled()" (click)="onBackgroundEffectsToggle()">
<mat-icon><span class="material-symbols-outlined">background_replace</span></mat-icon> <mat-icon><span class="material-symbols-outlined">background_replace</span></mat-icon>
<span>{{ 'TOOLBAR.BACKGROUND' | translate }}</span> <span>{{ 'TOOLBAR.BACKGROUND' | translate }}</span>
</button> </button>
@ -186,8 +186,8 @@
</button> --> </button> -->
<!-- Additional buttons injection inside menu (mobile only) --> <!-- Additional buttons injection inside menu (mobile only) -->
@if (showAdditionalButtonsInsideMenu() && additionalButtonsPosition === 'afterMenu') { @if (showAdditionalButtonsInsideMenu() && additionalButtonsPosition() === 'afterMenu') {
<ng-container *ngTemplateOutlet="toolbarAdditionalButtonsTemplate; context: { $implicit: additionalButtonsPosition }"> <ng-container *ngTemplateOutlet="toolbarAdditionalButtonsTemplate(); context: { $implicit: additionalButtonsPosition() }">
</ng-container> </ng-container>
} }
@ -197,12 +197,12 @@
} }
<!-- Divider before settings --> <!-- Divider before settings -->
@if (showSettingsButton) { @if (showSettingsButton()) {
<mat-divider class="divider"></mat-divider> <mat-divider class="divider"></mat-divider>
} }
<!-- Settings button --> <!-- Settings button -->
@if (showSettingsButton) { @if (showSettingsButton()) {
<button mat-menu-item id="toolbar-settings-btn" (click)="onSettingsToggle()"> <button mat-menu-item id="toolbar-settings-btn" (click)="onSettingsToggle()">
<mat-icon>settings</mat-icon> <mat-icon>settings</mat-icon>
<span>{{ 'TOOLBAR.SETTINGS' | translate }}</span> <span>{{ 'TOOLBAR.SETTINGS' | translate }}</span>
@ -212,12 +212,12 @@
} }
<!-- Additional buttons injection from parent component (desktop/tablet only) --> <!-- Additional buttons injection from parent component (desktop/tablet only) -->
@if (showAdditionalButtonsOutside() && additionalButtonsPosition === 'afterMenu') { @if (showAdditionalButtonsOutside() && additionalButtonsPosition() === 'afterMenu') {
<ng-container *ngTemplateOutlet="toolbarAdditionalButtonsTemplate"></ng-container> <ng-container *ngTemplateOutlet="toolbarAdditionalButtonsTemplate()"></ng-container>
} }
<!-- Leave session button --> <!-- Leave session button -->
@if (showLeaveButton) { @if (showLeaveButton()) {
<button <button
mat-icon-button mat-icon-button
(click)="onLeaveClick()" (click)="onLeaveClick()"
@ -229,6 +229,6 @@
</button> </button>
} }
@if (toolbarLeaveButtonTemplate) { @if (toolbarLeaveButtonTemplate()) {
<ng-container *ngTemplateOutlet="toolbarLeaveButtonTemplate"></ng-container> <ng-container *ngTemplateOutlet="toolbarLeaveButtonTemplate()"></ng-container>
} }

View File

@ -1,4 +1,4 @@
import { Component, ContentChild, EventEmitter, Input, Output, TemplateRef, computed, inject } from '@angular/core'; import { Component, ContentChild, EventEmitter, Output, TemplateRef, computed, inject, input } from '@angular/core';
import { RecordingStatus } from '../../../models/recording.model'; import { RecordingStatus } from '../../../models/recording.model';
import { BroadcastingStatus } from '../../../models/broadcasting.model'; import { BroadcastingStatus } from '../../../models/broadcasting.model';
import { ToolbarAdditionalButtonsPosition } from '../../../models/toolbar.model'; import { ToolbarAdditionalButtonsPosition } from '../../../models/toolbar.model';
@ -16,62 +16,62 @@ import { ToolbarMoreOptionsAdditionalMenuItemsDirective } from '../../../directi
}) })
export class ToolbarMediaButtonsComponent { export class ToolbarMediaButtonsComponent {
// Camera related inputs // Camera related inputs
@Input() showCameraButton: boolean = true; showCameraButton = input<boolean>(true);
@Input() isCameraEnabled: boolean = true; isCameraEnabled = input<boolean>(true);
@Input() cameraMuteChanging: boolean = false; cameraMuteChanging = input<boolean>(false);
// Microphone related inputs // Microphone related inputs
@Input() showMicrophoneButton: boolean = true; showMicrophoneButton = input<boolean>(true);
@Input() isMicrophoneEnabled: boolean = true; isMicrophoneEnabled = input<boolean>(true);
@Input() microphoneMuteChanging: boolean = false; microphoneMuteChanging = input<boolean>(false);
// Screenshare related inputs // Screenshare related inputs
@Input() showScreenshareButton: boolean = true; showScreenshareButton = input<boolean>(true);
@Input() isScreenShareEnabled: boolean = false; isScreenShareEnabled = input<boolean>(false);
@Input() isFirefoxBrowser: boolean = false; isFirefoxBrowser = input<boolean>(false);
// Device availability inputs // Device availability inputs
@Input() hasVideoDevices: boolean = true; hasVideoDevices = input<boolean>(true);
@Input() hasAudioDevices: boolean = true; hasAudioDevices = input<boolean>(true);
// Connection state inputs // Connection state inputs
@Input() isConnectionLost: boolean = false; isConnectionLost = input<boolean>(false);
// UI state inputs // UI state inputs
@Input() isMinimal: boolean = false; isMinimal = input<boolean>(false);
// More options menu inputs // More options menu inputs
@Input() showMoreOptionsButton: boolean = true; showMoreOptionsButton = input<boolean>(true);
@Input() showFullscreenButton: boolean = true; showFullscreenButton = input<boolean>(true);
@Input() showRecordingButton: boolean = true; showRecordingButton = input<boolean>(true);
@Input() showViewRecordingsButton: boolean = false; showViewRecordingsButton = input<boolean>(false);
@Input() showBroadcastingButton: boolean = true; showBroadcastingButton = input<boolean>(true);
@Input() showBackgroundEffectsButton: boolean = true; showBackgroundEffectsButton = input<boolean>(true);
@Input() showCaptionsButton: boolean = true; showCaptionsButton = input<boolean>(true);
@Input() showSettingsButton: boolean = true; showSettingsButton = input<boolean>(true);
// Fullscreen state // Fullscreen state
@Input() isFullscreenActive: boolean = false; isFullscreenActive = input<boolean>(false);
// Recording related inputs // Recording related inputs
@Input() recordingStatus: RecordingStatus = RecordingStatus.STOPPED; recordingStatus = input<RecordingStatus>(RecordingStatus.STOPPED);
@Input() hasRoomTracksPublished: boolean = false; hasRoomTracksPublished = input<boolean>(false);
// Broadcasting related inputs // Broadcasting related inputs
@Input() broadcastingStatus: BroadcastingStatus = BroadcastingStatus.STOPPED; broadcastingStatus = input<BroadcastingStatus>(BroadcastingStatus.STOPPED);
// Captions // Captions
@Input() captionsEnabled: boolean = false; captionsEnabled = input<boolean>(false);
// Leave button // Leave button
@Input() showLeaveButton: boolean = true; showLeaveButton = input<boolean>(true);
// Additional buttons template // Additional buttons template
@Input() toolbarAdditionalButtonsTemplate: TemplateRef<any> | null = null; toolbarAdditionalButtonsTemplate = input<TemplateRef<any> | null>(null);
@Input() additionalButtonsPosition: ToolbarAdditionalButtonsPosition | undefined; additionalButtonsPosition = input<ToolbarAdditionalButtonsPosition | undefined>(undefined);
// Leave button template // Leave button template
@Input() toolbarLeaveButtonTemplate: TemplateRef<any> | null = null; toolbarLeaveButtonTemplate = input<TemplateRef<any> | null>(null);
/** /**
* @internal * @internal
@ -101,34 +101,34 @@ export class ToolbarMediaButtonsComponent {
readonly isDesktopView = computed(() => this.viewportService.isDesktop()); readonly isDesktopView = computed(() => this.viewportService.isDesktop());
// Essential buttons that always stay visible // Essential buttons that always stay visible
readonly showCameraButtonDirect = computed(() => this.showCameraButton && !this.isMinimal); readonly showCameraButtonDirect = computed(() => this.showCameraButton() && !this.isMinimal());
readonly showMicrophoneButtonDirect = computed(() => this.showMicrophoneButton && !this.isMinimal); readonly showMicrophoneButtonDirect = computed(() => this.showMicrophoneButton() && !this.isMinimal());
// Screenshare button - visible on tablet+ or when already active // Screenshare button - visible on tablet+ or when already active
readonly showScreenshareButtonDirect = computed( readonly showScreenshareButtonDirect = computed(
() => this.showScreenshareButton && !this.isMinimal && (!this.isMobileView() || this.isScreenShareEnabled) () => this.showScreenshareButton() && !this.isMinimal() && (!this.isMobileView() || this.isScreenShareEnabled())
); );
// More options button - always visible when not minimal // More options button - always visible when not minimal
readonly showMoreOptionsButtonDirect = computed(() => this.showMoreOptionsButton && !this.isMinimal); readonly showMoreOptionsButtonDirect = computed(() => this.showMoreOptionsButton() && !this.isMinimal());
// Check if there are active features that should show a badge on More Options // Check if there are active features that should show a badge on More Options
readonly hasActiveFeatures = computed( readonly hasActiveFeatures = computed(
() => () =>
this.isScreenShareEnabled || this.isScreenShareEnabled() ||
this.recordingStatus === this._recordingStatus.STARTED || this.recordingStatus() === this._recordingStatus.STARTED ||
this.broadcastingStatus === this._broadcastingStatus.STARTED this.broadcastingStatus() === this._broadcastingStatus.STARTED
); );
// Check if additional buttons should be shown outside (desktop/tablet) or inside More Options (mobile) // Check if additional buttons should be shown outside (desktop/tablet) or inside More Options (mobile)
readonly showAdditionalButtonsOutside = computed(() => { readonly showAdditionalButtonsOutside = computed(() => {
return !this.isMobileView() && this.toolbarAdditionalButtonsTemplate; return !this.isMobileView() && this.toolbarAdditionalButtonsTemplate();
}); });
// Check if additional buttons should be shown inside More Options menu (mobile only) // Check if additional buttons should be shown inside More Options menu (mobile only)
readonly showAdditionalButtonsInsideMenu = computed(() => { readonly showAdditionalButtonsInsideMenu = computed(() => {
return this.isMobileView() && this.toolbarAdditionalButtonsTemplate; return this.isMobileView() && this.toolbarAdditionalButtonsTemplate();
}); });
// Media button outputs // Media button outputs