mirror of https://github.com/OpenVidu/openvidu.git
ov-components: add toolbar media buttons component
parent
0a49ca91d8
commit
c65b5c8a18
|
@ -0,0 +1,188 @@
|
|||
<!-- Camera button -->
|
||||
@if (showCameraButton) {
|
||||
<button
|
||||
id="camera-btn"
|
||||
mat-icon-button
|
||||
(click)="onCameraToggle()"
|
||||
[disabled]="isConnectionLost || !hasVideoDevices || cameraMuteChanging"
|
||||
[class.disabled]="!isCameraEnabled"
|
||||
[matTooltip]="isCameraEnabled ? ('TOOLBAR.STOP_VIDEO' | translate) : ('TOOLBAR.START_VIDEO' | translate)"
|
||||
[matTooltipDisabled]="!hasVideoDevices"
|
||||
>
|
||||
<mat-icon [id]="isCameraEnabled ? 'videocam' : 'videocam_off'">
|
||||
{{ isCameraEnabled ? 'videocam' : 'videocam_off' }}
|
||||
</mat-icon>
|
||||
</button>
|
||||
}
|
||||
|
||||
<!-- Microphone button -->
|
||||
@if (showMicrophoneButton) {
|
||||
<button
|
||||
id="mic-btn"
|
||||
mat-icon-button
|
||||
(click)="onMicrophoneToggle()"
|
||||
[disabled]="isConnectionLost || !hasAudioDevices || microphoneMuteChanging"
|
||||
[class.disabled]="!isMicrophoneEnabled"
|
||||
[matTooltip]="isMicrophoneEnabled ? ('TOOLBAR.MUTE_AUDIO' | translate) : ('TOOLBAR.UNMUTE_AUDIO' | translate)"
|
||||
[matTooltipDisabled]="!hasAudioDevices"
|
||||
>
|
||||
<mat-icon [id]="isMicrophoneEnabled ? 'mic' : 'mic_off'">
|
||||
{{ isMicrophoneEnabled ? 'mic' : 'mic_off' }}
|
||||
</mat-icon>
|
||||
</button>
|
||||
}
|
||||
|
||||
<!-- Enable Screenshare button -->
|
||||
@if (!isMinimal && showScreenshareButton) {
|
||||
<button
|
||||
mat-icon-button
|
||||
id="screenshare-btn"
|
||||
[matMenuTriggerFor]="isScreenShareEnabled ? screenshareMenu : null"
|
||||
[disabled]="isConnectionLost"
|
||||
[class.active-btn]="isScreenShareEnabled"
|
||||
matTooltip="{{ isScreenShareEnabled ? ('TOOLBAR.DISABLE_SCREEN' | translate) : ('TOOLBAR.ENABLE_SCREEN' | translate) }}"
|
||||
(click)="!isScreenShareEnabled && onScreenShareToggle()"
|
||||
>
|
||||
<mat-icon>screen_share</mat-icon>
|
||||
</button>
|
||||
|
||||
<!-- Screenshare button menu -->
|
||||
<mat-menu #screenshareMenu="matMenu" id="screenshare-menu">
|
||||
<button mat-menu-item (click)="onScreenTrackReplace()" id="replace-screen-button">
|
||||
<mat-icon>picture_in_picture</mat-icon>
|
||||
<span>{{ 'STREAM.REPLACE_SCREEN' | translate }}</span>
|
||||
</button>
|
||||
<mat-divider class="divider"></mat-divider>
|
||||
<button mat-menu-item (click)="onScreenShareToggle()" id="disable-screen-button">
|
||||
<mat-icon>stop_screen_share</mat-icon>
|
||||
<span>{{ 'TOOLBAR.DISABLE_SCREEN' | translate }}</span>
|
||||
</button>
|
||||
</mat-menu>
|
||||
}
|
||||
|
||||
<ng-container *ngIf="toolbarAdditionalButtonsTemplate && additionalButtonsPosition && additionalButtonsPosition === 'beforeMenu'">
|
||||
<ng-container *ngTemplateOutlet="toolbarAdditionalButtonsTemplate"></ng-container>
|
||||
</ng-container>
|
||||
|
||||
<!-- More options button -->
|
||||
@if (!isMinimal && showMoreOptionsButton) {
|
||||
<button
|
||||
mat-icon-button
|
||||
id="more-options-btn"
|
||||
[matMenuTriggerFor]="settingsMenu"
|
||||
[disabled]="isConnectionLost"
|
||||
matTooltip="{{ 'TOOLBAR.MORE_OPTIONS' | translate }}"
|
||||
>
|
||||
<mat-icon>more_vert</mat-icon>
|
||||
</button>
|
||||
<mat-menu #settingsMenu="matMenu" id="more-options-menu">
|
||||
<!-- Fullscreen button -->
|
||||
@if (showFullscreenButton) {
|
||||
<button mat-menu-item id="fullscreen-btn" (click)="onFullscreenToggle()">
|
||||
<mat-icon>{{ isFullscreenActive ? 'fullscreen_exit' : 'fullscreen' }}</mat-icon>
|
||||
<span>{{ isFullscreenActive ? ('TOOLBAR.EXIT_FULLSCREEN' | translate) : ('TOOLBAR.FULLSCREEN' | translate) }}</span>
|
||||
</button>
|
||||
}
|
||||
|
||||
<!-- Recording button -->
|
||||
@if (showRecordingButton) {
|
||||
<button
|
||||
mat-menu-item
|
||||
id="recording-btn"
|
||||
[disabled]="
|
||||
recordingStatus === _recordingStatus.STARTING ||
|
||||
recordingStatus === _recordingStatus.STOPPING ||
|
||||
!hasRoomTracksPublished
|
||||
"
|
||||
[matTooltip]="!hasRoomTracksPublished ? ('TOOLBAR.NO_TRACKS_PUBLISHED' | translate) : ''"
|
||||
(click)="onRecordingToggle()"
|
||||
>
|
||||
<mat-icon color="warn">radio_button_checked</mat-icon>
|
||||
<span>
|
||||
{{
|
||||
recordingStatus === _recordingStatus.STOPPED ||
|
||||
recordingStatus === _recordingStatus.STOPPING ||
|
||||
recordingStatus === _recordingStatus.FAILED
|
||||
? ('TOOLBAR.START_RECORDING' | translate)
|
||||
: ('TOOLBAR.STOP_RECORDING' | translate)
|
||||
}}
|
||||
</span>
|
||||
</button>
|
||||
}
|
||||
|
||||
<!-- View recordings button -->
|
||||
@if (showViewRecordingsButton) {
|
||||
<button mat-menu-item id="view-recordings-btn" (click)="onViewRecordingsClick()">
|
||||
<mat-icon>video_library</mat-icon>
|
||||
<span>{{ 'TOOLBAR.VIEW_RECORDINGS' | translate }}</span>
|
||||
</button>
|
||||
}
|
||||
|
||||
<!-- Broadcasting button -->
|
||||
@if (showBroadcastingButton) {
|
||||
<button
|
||||
mat-menu-item
|
||||
id="toolbar-broadcasting-btn"
|
||||
[disabled]="broadcastingStatus === _broadcastingStatus.STARTING || recordingStatus === _broadcastingStatus.STOPPING"
|
||||
(click)="onBroadcastingToggle()"
|
||||
>
|
||||
<mat-icon>sensors</mat-icon>
|
||||
<span>
|
||||
{{
|
||||
broadcastingStatus === _broadcastingStatus.STOPPED ||
|
||||
broadcastingStatus === _broadcastingStatus.STOPPING ||
|
||||
broadcastingStatus === _broadcastingStatus.FAILED
|
||||
? ('PANEL.STREAMING.START' | translate)
|
||||
: ('PANEL.STREAMING.STOP' | translate)
|
||||
}}
|
||||
</span>
|
||||
</button>
|
||||
}
|
||||
|
||||
<!-- Virtual background button -->
|
||||
@if (showBackgroundEffectsButton) {
|
||||
<button mat-menu-item id="virtual-bg-btn" [disabled]="!isCameraEnabled" (click)="onBackgroundEffectsToggle()">
|
||||
<mat-icon><span class="material-symbols-outlined">background_replace</span></mat-icon>
|
||||
<span>{{ 'TOOLBAR.BACKGROUND' | translate }}</span>
|
||||
</button>
|
||||
}
|
||||
|
||||
<!-- Captions button -->
|
||||
<!-- <button
|
||||
*ngIf="!isMinimal && showCaptionsButton"
|
||||
[disabled]="isConnectionLost"
|
||||
mat-menu-item
|
||||
id="captions-btn"
|
||||
(click)="onCaptionsToggle()"
|
||||
>
|
||||
<mat-icon>closed_caption</mat-icon>
|
||||
<span *ngIf="captionsEnabled">{{ 'TOOLBAR.DISABLE_CAPTIONS' | translate }}</span>
|
||||
<span *ngIf="!captionsEnabled">{{ 'TOOLBAR.ENABLE_CAPTIONS' | translate }}</span>
|
||||
</button> -->
|
||||
|
||||
<!-- Divider before settings -->
|
||||
@if (showSettingsButton) {
|
||||
<mat-divider class="divider"></mat-divider>
|
||||
}
|
||||
|
||||
<!-- Settings button -->
|
||||
@if (showSettingsButton) {
|
||||
<button mat-menu-item id="toolbar-settings-btn" (click)="onSettingsToggle()">
|
||||
<mat-icon>settings</mat-icon>
|
||||
<span>{{ 'TOOLBAR.SETTINGS' | translate }}</span>
|
||||
</button>
|
||||
}
|
||||
</mat-menu>
|
||||
}
|
||||
|
||||
<!-- External additional buttons -->
|
||||
<ng-container *ngIf="toolbarAdditionalButtonsTemplate && additionalButtonsPosition && additionalButtonsPosition === 'afterMenu'">
|
||||
<ng-container *ngTemplateOutlet="toolbarAdditionalButtonsTemplate"></ng-container>
|
||||
</ng-container>
|
||||
|
||||
<!-- Leave session button -->
|
||||
@if (showLeaveButton) {
|
||||
<button mat-icon-button (click)="onLeaveClick()" id="leave-btn" matTooltip="{{ 'TOOLBAR.LEAVE' | translate }}">
|
||||
<mat-icon>call_end</mat-icon>
|
||||
</button>
|
||||
}
|
|
@ -0,0 +1,123 @@
|
|||
:host {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
.mat-mdc-icon-button {
|
||||
--mat-mdc-button-persistent-ripple-color: transparent !important;
|
||||
--mat-mdc-button-ripple-color: transparent !important;
|
||||
}
|
||||
|
||||
mat-icon {
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
button {
|
||||
border-radius: var(--ov-toolbar-buttons-radius);
|
||||
color: var(--ov-secondary-action-color);
|
||||
|
||||
&.disabled {
|
||||
background-color: var(--ov-error-color) !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
}
|
||||
|
||||
button:not(mat-menu-item),
|
||||
button:not(.mat-mdc-menu-item) ::ng-deep button:not(mat-menu-item),
|
||||
::ng-deep button:not(#screenshare-menu) {
|
||||
background-color: var(--ov-primary-action-color);
|
||||
color: var(--ov-secondary-action-color);
|
||||
margin: 6px;
|
||||
}
|
||||
|
||||
#screenshare-menu {
|
||||
}
|
||||
|
||||
#disable-screen-button > mat-icon {
|
||||
color: var(--ov-error-color) !important;
|
||||
}
|
||||
|
||||
.active-btn,
|
||||
::ng-deep .active-btn {
|
||||
background-color: var(--ov-accent-action-color) !important;
|
||||
}
|
||||
|
||||
#leave-btn {
|
||||
background-color: var(--ov-error-color) !important;
|
||||
border-radius: var(--ov-leave-button-radius) !important;
|
||||
width: 65px !important;
|
||||
color: #ffffff !important;
|
||||
}
|
||||
|
||||
.mat-mdc-icon-button[disabled] {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.divider {
|
||||
margin: 8px 0px;
|
||||
}
|
||||
|
||||
.blink {
|
||||
animation: blinker 1.5s linear infinite;
|
||||
}
|
||||
|
||||
/* Animation for general blinking */
|
||||
@keyframes blinker {
|
||||
50% {
|
||||
opacity: 0.3;
|
||||
}
|
||||
}
|
||||
|
||||
::ng-deep .mat-badge-content {
|
||||
background-color: var(--ov-warn-color);
|
||||
}
|
||||
|
||||
::ng-deep .mat-mdc-menu-item {
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
color: var(--ov-text-surface-color) !important;
|
||||
}
|
||||
|
||||
::ng-deep .mat-mdc-menu-item mat-icon {
|
||||
color: var(--ov-text-surface-color) !important;
|
||||
}
|
||||
|
||||
::ng-deep #toolbar-broadcasting-btn > .mat-icon {
|
||||
color: var(--ov-broadcasting-color) !important;
|
||||
}
|
||||
|
||||
::ng-deep #recording-btn > .mat-icon {
|
||||
color: var(--ov-recording-color) !important;
|
||||
}
|
||||
|
||||
::ng-deep .mat-mdc-menu-panel {
|
||||
border-radius: var(--ov-surface-radius) !important;
|
||||
background-color: var(--ov-surface-color) !important;
|
||||
box-shadow: var(--ov-border-shadow) !important;
|
||||
}
|
||||
|
||||
/* Styles for XS screens */
|
||||
@media (max-width: 599px) {
|
||||
/* Animation for recording blinking */
|
||||
@keyframes blinker-recording {
|
||||
50% {
|
||||
background-color: var(--ov-recording-color);
|
||||
}
|
||||
}
|
||||
|
||||
/* Animation for broadcasting blinking */
|
||||
@keyframes blinker-broadcasting {
|
||||
50% {
|
||||
background-color: var(--ov-broadcasting-color);
|
||||
}
|
||||
}
|
||||
|
||||
/* Apply blinking animations to buttons */
|
||||
.blinking-broadcasting-button {
|
||||
animation: blinker-broadcasting 1.5s linear infinite;
|
||||
}
|
||||
.blinking-recording-button {
|
||||
animation: blinker-recording 1.5s linear infinite;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { ToolbarMediaButtonsComponent } from './toolbar-media-buttons.component';
|
||||
|
||||
describe('ToolbarMediaButtonsComponent', () => {
|
||||
let component: ToolbarMediaButtonsComponent;
|
||||
let fixture: ComponentFixture<ToolbarMediaButtonsComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ToolbarMediaButtonsComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(ToolbarMediaButtonsComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,140 @@
|
|||
import { Component, EventEmitter, Input, Output, TemplateRef } from '@angular/core';
|
||||
import { RecordingStatus } from '../../../models/recording.model';
|
||||
import { BroadcastingStatus } from '../../../models/broadcasting.model';
|
||||
import { ToolbarAdditionalButtonsPosition } from '../../../models/toolbar.model';
|
||||
|
||||
@Component({
|
||||
selector: 'ov-toolbar-media-buttons',
|
||||
templateUrl: './toolbar-media-buttons.component.html',
|
||||
styleUrl: './toolbar-media-buttons.component.scss',
|
||||
standalone: false
|
||||
})
|
||||
export class ToolbarMediaButtonsComponent {
|
||||
|
||||
// Camera related inputs
|
||||
@Input() showCameraButton: boolean = true;
|
||||
@Input() isCameraEnabled: boolean = true;
|
||||
@Input() cameraMuteChanging: boolean = false;
|
||||
|
||||
// Microphone related inputs
|
||||
@Input() showMicrophoneButton: boolean = true;
|
||||
@Input() isMicrophoneEnabled: boolean = true;
|
||||
@Input() microphoneMuteChanging: boolean = false;
|
||||
|
||||
// Screenshare related inputs
|
||||
@Input() showScreenshareButton: boolean = true;
|
||||
@Input() isScreenShareEnabled: boolean = false;
|
||||
|
||||
// Device availability inputs
|
||||
@Input() hasVideoDevices: boolean = true;
|
||||
@Input() hasAudioDevices: boolean = true;
|
||||
|
||||
// Connection state inputs
|
||||
@Input() isConnectionLost: boolean = false;
|
||||
|
||||
// UI state inputs
|
||||
@Input() isMinimal: boolean = false;
|
||||
|
||||
// More options menu inputs
|
||||
@Input() showMoreOptionsButton: boolean = true;
|
||||
@Input() showFullscreenButton: boolean = true;
|
||||
@Input() showRecordingButton: boolean = true;
|
||||
@Input() showViewRecordingsButton: boolean = false;
|
||||
@Input() showBroadcastingButton: boolean = true;
|
||||
@Input() showBackgroundEffectsButton: boolean = true;
|
||||
@Input() showCaptionsButton: boolean = true;
|
||||
@Input() showSettingsButton: boolean = true;
|
||||
|
||||
// Fullscreen state
|
||||
@Input() isFullscreenActive: boolean = false;
|
||||
|
||||
// Recording related inputs
|
||||
@Input() recordingStatus: RecordingStatus = RecordingStatus.STOPPED;
|
||||
@Input() hasRoomTracksPublished: boolean = false;
|
||||
|
||||
// Broadcasting related inputs
|
||||
@Input() broadcastingStatus: BroadcastingStatus = BroadcastingStatus.STOPPED;
|
||||
|
||||
// Captions
|
||||
@Input() captionsEnabled: boolean = false;
|
||||
|
||||
// Leave button
|
||||
@Input() showLeaveButton: boolean = true;
|
||||
|
||||
// Additional buttons template
|
||||
@Input() toolbarAdditionalButtonsTemplate: TemplateRef<any> | null = null;
|
||||
@Input() additionalButtonsPosition: ToolbarAdditionalButtonsPosition | undefined;
|
||||
|
||||
// Status enums for template usage
|
||||
_recordingStatus = RecordingStatus;
|
||||
_broadcastingStatus = BroadcastingStatus;
|
||||
|
||||
// Media button outputs
|
||||
@Output() cameraToggled = new EventEmitter<void>();
|
||||
@Output() microphoneToggled = new EventEmitter<void>();
|
||||
@Output() screenShareToggled = new EventEmitter<void>();
|
||||
@Output() screenTrackReplaced = new EventEmitter<void>();
|
||||
|
||||
// More options menu outputs
|
||||
@Output() fullscreenToggled = new EventEmitter<void>();
|
||||
@Output() recordingToggled = new EventEmitter<void>();
|
||||
@Output() viewRecordingsClicked = new EventEmitter<void>();
|
||||
@Output() broadcastingToggled = new EventEmitter<void>();
|
||||
@Output() backgroundEffectsToggled = new EventEmitter<void>();
|
||||
@Output() captionsToggled = new EventEmitter<void>();
|
||||
@Output() settingsToggled = new EventEmitter<void>();
|
||||
|
||||
// Leave button output
|
||||
@Output() leaveClicked = new EventEmitter<void>();
|
||||
|
||||
// Event handler methods
|
||||
onCameraToggle(): void {
|
||||
this.cameraToggled.emit();
|
||||
}
|
||||
|
||||
onMicrophoneToggle(): void {
|
||||
this.microphoneToggled.emit();
|
||||
}
|
||||
|
||||
onScreenShareToggle(): void {
|
||||
this.screenShareToggled.emit();
|
||||
}
|
||||
|
||||
onScreenTrackReplace(): void {
|
||||
this.screenTrackReplaced.emit();
|
||||
}
|
||||
|
||||
onFullscreenToggle(): void {
|
||||
this.fullscreenToggled.emit();
|
||||
}
|
||||
|
||||
onRecordingToggle(): void {
|
||||
this.recordingToggled.emit();
|
||||
}
|
||||
|
||||
onViewRecordingsClick(): void {
|
||||
this.viewRecordingsClicked.emit();
|
||||
}
|
||||
|
||||
onBroadcastingToggle(): void {
|
||||
this.broadcastingToggled.emit();
|
||||
}
|
||||
|
||||
onBackgroundEffectsToggle(): void {
|
||||
this.backgroundEffectsToggled.emit();
|
||||
}
|
||||
|
||||
onCaptionsToggle(): void {
|
||||
this.captionsToggled.emit();
|
||||
}
|
||||
|
||||
onSettingsToggle(): void {
|
||||
this.settingsToggled.emit();
|
||||
}
|
||||
|
||||
onLeaveClick(): void {
|
||||
this.leaveClicked.emit();
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -40,203 +40,48 @@
|
|||
|
||||
<!-- Media and menu buttons container -->
|
||||
<div class="media-buttons-container" id="media-buttons-container">
|
||||
<!-- Camera button -->
|
||||
<button
|
||||
id="camera-btn"
|
||||
mat-icon-button
|
||||
*ngIf="showCameraButton"
|
||||
(click)="toggleCamera()"
|
||||
[disabled]="isConnectionLost || !hasVideoDevices || cameraMuteChanging"
|
||||
[class.disabled]="!isCameraEnabled"
|
||||
[matTooltip]="isCameraEnabled ? ('TOOLBAR.STOP_VIDEO' | translate) : ('TOOLBAR.START_VIDEO' | translate)"
|
||||
[matTooltipDisabled]="!hasVideoDevices"
|
||||
>
|
||||
<mat-icon *ngIf="isCameraEnabled" id="videocam"> videocam </mat-icon>
|
||||
<mat-icon *ngIf="!isCameraEnabled" id="videocam_off"> videocam_off </mat-icon>
|
||||
</button>
|
||||
|
||||
<!-- Microphone button -->
|
||||
<button
|
||||
id="mic-btn"
|
||||
mat-icon-button
|
||||
*ngIf="showMicrophoneButton"
|
||||
(click)="toggleMicrophone()"
|
||||
[disabled]="isConnectionLost || !hasAudioDevices || microphoneMuteChanging"
|
||||
[class.disabled]="!isMicrophoneEnabled"
|
||||
[matTooltip]="isMicrophoneEnabled ? ('TOOLBAR.MUTE_AUDIO' | translate) : ('TOOLBAR.UNMUTE_AUDIO' | translate)"
|
||||
[matTooltipDisabled]="!hasAudioDevices"
|
||||
>
|
||||
<mat-icon *ngIf="isMicrophoneEnabled" id="mic"> mic </mat-icon>
|
||||
<mat-icon *ngIf="!isMicrophoneEnabled" id="mic_off"> mic_off </mat-icon>
|
||||
</button>
|
||||
|
||||
<!-- Enable Screenshare button -->
|
||||
<button
|
||||
mat-icon-button
|
||||
*ngIf="!isMinimal && showScreenshareButton && !isScreenShareEnabled"
|
||||
id="screenshare-btn"
|
||||
(click)="toggleScreenShare()"
|
||||
[disabled]="isConnectionLost"
|
||||
matTooltip="{{ 'TOOLBAR.ENABLE_SCREEN' | translate }}"
|
||||
>
|
||||
<mat-icon>screen_share</mat-icon>
|
||||
</button>
|
||||
<!-- Screenshare button menu -->
|
||||
<button
|
||||
mat-icon-button
|
||||
*ngIf="!isMinimal && showScreenshareButton && isScreenShareEnabled"
|
||||
id="screenshare-btn"
|
||||
[matMenuTriggerFor]="screenshareMenu"
|
||||
[disabled]="isConnectionLost"
|
||||
class="active-btn"
|
||||
matTooltip="{{ 'TOOLBAR.DISABLE_SCREEN' | translate }}"
|
||||
>
|
||||
<mat-icon>screen_share</mat-icon>
|
||||
</button>
|
||||
<mat-menu #screenshareMenu="matMenu" id="screenshare-menu">
|
||||
<button mat-menu-item (click)="replaceScreenTrack()" id="replace-screen-button">
|
||||
<mat-icon>picture_in_picture</mat-icon>
|
||||
<span>{{ 'STREAM.REPLACE_SCREEN' | translate }}</span>
|
||||
</button>
|
||||
<mat-divider class="divider"></mat-divider>
|
||||
<button mat-menu-item (click)="toggleScreenShare()" id="disable-screen-button">
|
||||
<mat-icon>stop_screen_share</mat-icon>
|
||||
<span>{{ 'TOOLBAR.DISABLE_SCREEN' | translate }}</span>
|
||||
</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
|
||||
id="more-options-btn"
|
||||
*ngIf="!isMinimal && showMoreOptionsButton"
|
||||
[matMenuTriggerFor]="settingsMenu"
|
||||
[disabled]="isConnectionLost"
|
||||
matTooltip="{{ 'TOOLBAR.MORE_OPTIONS' | translate }}"
|
||||
>
|
||||
<mat-icon>more_vert</mat-icon>
|
||||
</button>
|
||||
<mat-menu #settingsMenu="matMenu" id="more-options-menu">
|
||||
<!-- Fullscreen button -->
|
||||
<button *ngIf="showFullscreenButton" mat-menu-item id="fullscreen-btn" (click)="toggleFullscreen()">
|
||||
<mat-icon *ngIf="!isFullscreenActive">fullscreen</mat-icon>
|
||||
<span *ngIf="!isFullscreenActive">{{ 'TOOLBAR.FULLSCREEN' | translate }}</span>
|
||||
|
||||
<mat-icon *ngIf="isFullscreenActive">fullscreen_exit</mat-icon>
|
||||
<span *ngIf="isFullscreenActive">{{ 'TOOLBAR.EXIT_FULLSCREEN' | translate }}</span>
|
||||
</button>
|
||||
|
||||
<!-- Recording button -->
|
||||
<button
|
||||
*ngIf="!isMinimal && showRecordingButton"
|
||||
mat-menu-item
|
||||
id="recording-btn"
|
||||
[disabled]="
|
||||
recordingStatus === _recordingStatus.STARTING ||
|
||||
recordingStatus === _recordingStatus.STOPPING ||
|
||||
!hasRoomTracksPublished
|
||||
"
|
||||
[matTooltip]="!hasRoomTracksPublished ? ('TOOLBAR.NO_TRACKS_PUBLISHED' | translate) : ''"
|
||||
(click)="toggleRecording()"
|
||||
>
|
||||
<mat-icon color="warn">radio_button_checked</mat-icon>
|
||||
@if (
|
||||
recordingStatus === _recordingStatus.STOPPED ||
|
||||
recordingStatus === _recordingStatus.STOPPING ||
|
||||
recordingStatus === _recordingStatus.FAILED
|
||||
) {
|
||||
<span class="blink">
|
||||
{{ 'TOOLBAR.START_RECORDING' | translate }}
|
||||
</span>
|
||||
} @else if (recordingStatus === _recordingStatus.STARTED || recordingStatus === _recordingStatus.STARTING) {
|
||||
<span>{{ 'TOOLBAR.STOP_RECORDING' | translate }}</span>
|
||||
}
|
||||
</button>
|
||||
|
||||
<!-- View recordings button -->
|
||||
@if (!isMinimal && showViewRecordingsButton) {
|
||||
<button mat-menu-item id="view-recordings-btn" (click)="onViewRecordingsClicked.emit()">
|
||||
<mat-icon>video_library</mat-icon>
|
||||
<span>{{ 'TOOLBAR.VIEW_RECORDINGS' | translate }}</span>
|
||||
</button>
|
||||
}
|
||||
|
||||
<!-- Broadcasting button -->
|
||||
<button
|
||||
*ngIf="!isMinimal && showBroadcastingButton"
|
||||
mat-menu-item
|
||||
id="toolbar-broadcasting-btn"
|
||||
[disabled]="broadcastingStatus === _broadcastingStatus.STARTING || recordingStatus === _broadcastingStatus.STOPPING"
|
||||
(click)="toggleBroadcasting()"
|
||||
>
|
||||
<mat-icon>sensors</mat-icon>
|
||||
<span
|
||||
*ngIf="
|
||||
broadcastingStatus === _broadcastingStatus.STOPPED ||
|
||||
broadcastingStatus === _broadcastingStatus.STOPPING ||
|
||||
broadcastingStatus === _broadcastingStatus.FAILED
|
||||
"
|
||||
>
|
||||
{{ 'PANEL.STREAMING.START' | translate }}
|
||||
</span>
|
||||
<span *ngIf="broadcastingStatus === _broadcastingStatus.STARTED || broadcastingStatus === _broadcastingStatus.STARTING">
|
||||
{{ 'PANEL.STREAMING.STOP' | translate }}
|
||||
</span>
|
||||
</button>
|
||||
|
||||
<!-- Virtual background button -->
|
||||
<button
|
||||
*ngIf="!isMinimal && showBackgroundEffectsButton"
|
||||
[disabled]="!isCameraEnabled"
|
||||
mat-menu-item
|
||||
id="virtual-bg-btn"
|
||||
(click)="toggleBackgroundEffects()"
|
||||
>
|
||||
<mat-icon><span class="material-symbols-outlined"> background_replace </span></mat-icon>
|
||||
<span>{{ 'TOOLBAR.BACKGROUND' | translate }}</span>
|
||||
</button>
|
||||
|
||||
<!-- Captions button -->
|
||||
<!-- <button
|
||||
*ngIf="!isMinimal && showCaptionsButton"
|
||||
[disabled]="isConnectionLost"
|
||||
mat-menu-item
|
||||
id="captions-btn"
|
||||
(click)="toggleCaptions()"
|
||||
>
|
||||
<mat-icon>closed_caption</mat-icon>
|
||||
<span *ngIf="captionsEnabled">{{ 'TOOLBAR.DISABLE_CAPTIONS' | translate }}</span>
|
||||
<span *ngIf="!captionsEnabled">{{ 'TOOLBAR.ENABLE_CAPTIONS' | translate }}</span>
|
||||
</button> -->
|
||||
|
||||
<mat-divider class="divider" *ngIf="!isMinimal && showSettingsButton"></mat-divider>
|
||||
|
||||
<!-- Settings button -->
|
||||
<button *ngIf="!isMinimal && showSettingsButton" mat-menu-item id="toolbar-settings-btn" (click)="toggleSettings()">
|
||||
<mat-icon>settings</mat-icon>
|
||||
<span>{{ 'TOOLBAR.SETTINGS' | translate }}</span>
|
||||
</button>
|
||||
</mat-menu>
|
||||
|
||||
<!-- External additional buttons -->
|
||||
<ng-container *ngIf="toolbarAdditionalButtonsTemplate && additionalButtonsPosition && additionalButtonsPosition === 'afterMenu'">
|
||||
<ng-container *ngTemplateOutlet="toolbarAdditionalButtonsTemplate"></ng-container>
|
||||
</ng-container>
|
||||
|
||||
<!-- Leave session button -->
|
||||
<button
|
||||
mat-icon-button
|
||||
*ngIf="showLeaveButton"
|
||||
(click)="disconnect()"
|
||||
id="leave-btn"
|
||||
matTooltip="{{ 'TOOLBAR.LEAVE' | translate }}"
|
||||
>
|
||||
<mat-icon>call_end</mat-icon>
|
||||
</button>
|
||||
<ov-toolbar-media-buttons
|
||||
[showCameraButton]="showCameraButton"
|
||||
[isCameraEnabled]="isCameraEnabled"
|
||||
[cameraMuteChanging]="cameraMuteChanging"
|
||||
[showMicrophoneButton]="showMicrophoneButton"
|
||||
[isMicrophoneEnabled]="isMicrophoneEnabled"
|
||||
[microphoneMuteChanging]="microphoneMuteChanging"
|
||||
[showScreenshareButton]="showScreenshareButton"
|
||||
[isScreenShareEnabled]="isScreenShareEnabled"
|
||||
[hasVideoDevices]="hasVideoDevices"
|
||||
[hasAudioDevices]="hasAudioDevices"
|
||||
[isConnectionLost]="isConnectionLost"
|
||||
[isMinimal]="isMinimal"
|
||||
[showMoreOptionsButton]="showMoreOptionsButton"
|
||||
[showFullscreenButton]="showFullscreenButton"
|
||||
[showRecordingButton]="showRecordingButton"
|
||||
[showViewRecordingsButton]="showViewRecordingsButton"
|
||||
[showBroadcastingButton]="showBroadcastingButton"
|
||||
[showBackgroundEffectsButton]="showBackgroundEffectsButton"
|
||||
[showCaptionsButton]="showCaptionsButton"
|
||||
[showSettingsButton]="showSettingsButton"
|
||||
[isFullscreenActive]="isFullscreenActive"
|
||||
[recordingStatus]="recordingStatus"
|
||||
[hasRoomTracksPublished]="hasRoomTracksPublished"
|
||||
[broadcastingStatus]="broadcastingStatus"
|
||||
[captionsEnabled]="captionsEnabled"
|
||||
[showLeaveButton]="showLeaveButton"
|
||||
[toolbarAdditionalButtonsTemplate]="toolbarAdditionalButtonsTemplate"
|
||||
[additionalButtonsPosition]="additionalButtonsPosition"
|
||||
(cameraToggled)="toggleCamera()"
|
||||
(microphoneToggled)="toggleMicrophone()"
|
||||
(screenShareToggled)="toggleScreenShare()"
|
||||
(screenTrackReplaced)="replaceScreenTrack()"
|
||||
(fullscreenToggled)="toggleFullscreen()"
|
||||
(recordingToggled)="toggleRecording()"
|
||||
(viewRecordingsClicked)="onViewRecordingsClicked.emit()"
|
||||
(broadcastingToggled)="toggleBroadcasting()"
|
||||
(backgroundEffectsToggled)="toggleBackgroundEffects()"
|
||||
(captionsToggled)="onCaptionsToggle()"
|
||||
(settingsToggled)="toggleSettings()"
|
||||
(leaveClicked)="disconnect()"
|
||||
></ov-toolbar-media-buttons>
|
||||
</div>
|
||||
|
||||
<!-- Panel buttons (chat, participants, activities) -->
|
||||
|
|
|
@ -30,6 +30,13 @@
|
|||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
// ov-toolbar-media-buttons {
|
||||
// display: flex;
|
||||
// justify-content: center;
|
||||
// align-items: center;
|
||||
// flex: 1;
|
||||
// }
|
||||
}
|
||||
.menu-buttons-container {
|
||||
flex: 20%;
|
||||
|
@ -47,40 +54,9 @@
|
|||
max-height: 100% !important;
|
||||
}
|
||||
|
||||
#media-buttons-container mat-icon {
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
#media-buttons-container button,
|
||||
#menu-buttons-container button {
|
||||
border-radius: var(--ov-toolbar-buttons-radius);
|
||||
color: var(--ov-secondary-action-color);
|
||||
|
||||
&.disabled {
|
||||
background-color: var(--ov-error-color) !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
}
|
||||
|
||||
#media-buttons-container > button,
|
||||
::ng-deep #media-buttons-container > button,
|
||||
#media-buttons-container:not(#media-buttons-container > button) button,
|
||||
/* Applying css for external additional buttons*/
|
||||
::ng-deep #media-buttons-container:not(#media-buttons-container > button) button {
|
||||
// width: 40px;
|
||||
// height: 40px;
|
||||
background-color: var(--ov-primary-action-color);
|
||||
color: var(--ov-secondary-action-color);
|
||||
margin: 6px;
|
||||
}
|
||||
|
||||
#disable-screen-button > mat-icon {
|
||||
color: var(--ov-error-color) !important;
|
||||
}
|
||||
|
||||
.active-btn,
|
||||
::ng-deep .active-btn {
|
||||
background-color: var(--ov-accent-action-color) !important;
|
||||
}
|
||||
|
||||
#branding-logo {
|
||||
|
@ -146,34 +122,11 @@
|
|||
animation: blinker 1.5s linear infinite;
|
||||
}
|
||||
|
||||
#leave-btn {
|
||||
background-color: var(--ov-error-color) !important;
|
||||
border-radius: var(--ov-leave-button-radius) !important;
|
||||
width: 65px !important;
|
||||
color: #ffffff !important;
|
||||
}
|
||||
|
||||
.mat-mdc-icon-button[disabled] {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
::ng-deep .mat-badge-content {
|
||||
background-color: var(--ov-warn-color);
|
||||
}
|
||||
.divider {
|
||||
margin: 8px 0px;
|
||||
}
|
||||
::ng-deep .mat-mdc-menu-item {
|
||||
/* margin-bottom: 10px; */
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
}
|
||||
|
||||
/* Animation for general blinking */
|
||||
@keyframes blinker {
|
||||
50% {
|
||||
opacity: 0.3;
|
||||
}
|
||||
}
|
||||
|
||||
/* Styles for XS screens */
|
||||
@media (max-width: 599px) {
|
||||
|
|
|
@ -651,7 +651,7 @@ export class ToolbarComponent implements OnInit, OnDestroy, AfterViewInit {
|
|||
/**
|
||||
* @ignore
|
||||
*/
|
||||
// toggleCaptions() {
|
||||
onCaptionsToggle() {
|
||||
// if (this.openviduService.isOpenViduPro()) {
|
||||
// this.layoutService.toggleCaptions();
|
||||
// } else {
|
||||
|
@ -660,7 +660,7 @@ export class ToolbarComponent implements OnInit, OnDestroy, AfterViewInit {
|
|||
// this.translateService.translate('PANEL.PRO_FEATURE')
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
|
|
|
@ -11,6 +11,7 @@ import { ChatPanelComponent } from './components/panel/chat-panel/chat-panel.com
|
|||
import { SessionComponent } from './components/session/session.component';
|
||||
import { StreamComponent } from './components/stream/stream.component';
|
||||
import { ToolbarComponent } from './components/toolbar/toolbar.component';
|
||||
import { ToolbarMediaButtonsComponent } from './components/toolbar/toolbar-media-buttons/toolbar-media-buttons.component';
|
||||
import { MediaElementComponent } from './components/media-element/media-element.component';
|
||||
|
||||
import { LinkifyPipe } from './pipes/linkify.pipe';
|
||||
|
@ -76,7 +77,8 @@ const privateComponents = [
|
|||
VideoDevicesComponent,
|
||||
AudioDevicesComponent,
|
||||
ParticipantNameInputComponent,
|
||||
LangSelectorComponent
|
||||
LangSelectorComponent,
|
||||
ToolbarMediaButtonsComponent
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
|
|
|
@ -15,6 +15,7 @@ export * from './lib/components/panel/participants-panel/participant-panel-item/
|
|||
export * from './lib/components/panel/participants-panel/participants-panel/participants-panel.component';
|
||||
export * from './lib/components/stream/stream.component';
|
||||
export * from './lib/components/toolbar/toolbar.component';
|
||||
export * from './lib/components/toolbar/toolbar-media-buttons/toolbar-media-buttons.component';
|
||||
export * from './lib/components/videoconference/videoconference.component';
|
||||
export * from './lib/config/openvidu-components-angular.config';
|
||||
// Directives
|
||||
|
|
Loading…
Reference in New Issue