mirror of https://github.com/OpenVidu/openvidu.git
ov-components: add camera and microphone button visibility controls in toolbar and settings panel
parent
5fba250b1d
commit
2bf212ccfe
|
@ -25,6 +25,7 @@
|
|||
<div mat-line *ngIf="!isMobile">{{ 'PANEL.SETTINGS.GENERAL' | translate }}</div>
|
||||
</mat-list-option>
|
||||
<mat-list-option
|
||||
*ngIf="showCameraButton"
|
||||
class="option"
|
||||
id="video-opt"
|
||||
[selected]="selectedOption === settingsOptions.VIDEO"
|
||||
|
@ -34,6 +35,7 @@
|
|||
<div mat-line *ngIf="!isMobile">{{ 'PANEL.SETTINGS.VIDEO' | translate }}</div>
|
||||
</mat-list-option>
|
||||
<mat-list-option
|
||||
*ngIf="showMicrophoneButton"
|
||||
class="option"
|
||||
id="audio-opt"
|
||||
[selected]="selectedOption === settingsOptions.AUDIO"
|
||||
|
@ -68,12 +70,12 @@
|
|||
</mat-list>
|
||||
</div>
|
||||
<ov-video-devices-select
|
||||
*ngIf="selectedOption === settingsOptions.VIDEO"
|
||||
*ngIf="showCameraButton && selectedOption === settingsOptions.VIDEO"
|
||||
(onVideoDeviceChanged)="onVideoDeviceChanged.emit($event)"
|
||||
(onVideoEnabledChanged)="onVideoEnabledChanged.emit($event)"
|
||||
></ov-video-devices-select>
|
||||
<ov-audio-devices-select
|
||||
*ngIf="selectedOption === settingsOptions.AUDIO"
|
||||
*ngIf="showMicrophoneButton && selectedOption === settingsOptions.AUDIO"
|
||||
(onAudioDeviceChanged)="onAudioDeviceChanged.emit($event)"
|
||||
(onAudioEnabledChanged)="onAudioEnabledChanged.emit($event)"
|
||||
></ov-audio-devices-select>
|
||||
|
|
|
@ -23,9 +23,13 @@ export class SettingsPanelComponent implements OnInit {
|
|||
@Output() onLangChanged = new EventEmitter<LangOption>();
|
||||
settingsOptions: typeof PanelSettingsOptions = PanelSettingsOptions;
|
||||
selectedOption: PanelSettingsOptions = PanelSettingsOptions.GENERAL;
|
||||
showCameraButton: boolean = true;
|
||||
showMicrophoneButton: boolean = true;
|
||||
showCaptions: boolean = true;
|
||||
panelSubscription: Subscription;
|
||||
isMobile: boolean = false;
|
||||
private cameraButtonSub: Subscription;
|
||||
private microphoneButtonSub: Subscription;
|
||||
private captionsSubs: Subscription;
|
||||
constructor(
|
||||
private panelService: PanelService,
|
||||
|
@ -39,6 +43,9 @@ export class SettingsPanelComponent implements OnInit {
|
|||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
if (this.panelSubscription) this.panelSubscription.unsubscribe();
|
||||
if (this.cameraButtonSub) this.cameraButtonSub.unsubscribe();
|
||||
if (this.microphoneButtonSub) this.microphoneButtonSub.unsubscribe();
|
||||
if (this.captionsSubs) this.captionsSubs.unsubscribe();
|
||||
}
|
||||
|
||||
|
@ -50,9 +57,9 @@ export class SettingsPanelComponent implements OnInit {
|
|||
}
|
||||
|
||||
private subscribeToDirectives() {
|
||||
this.captionsSubs = this.libService.captionsButton$.subscribe((value: boolean) => {
|
||||
this.showCaptions = value;
|
||||
});
|
||||
this.cameraButtonSub = this.libService.cameraButton$.subscribe((value: boolean) => (this.showCameraButton = value));
|
||||
this.microphoneButtonSub = this.libService.microphoneButton$.subscribe((value: boolean) => (this.showMicrophoneButton = value));
|
||||
this.captionsSubs = this.libService.captionsButton$.subscribe((value: boolean) => (this.showCaptions = value));
|
||||
}
|
||||
|
||||
private subscribeToPanelToggling() {
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
|
||||
<div class="media-controls-container">
|
||||
<!-- Camera -->
|
||||
<div class="video-controls-container">
|
||||
<div class="video-controls-container" *ngIf="showCameraButton">
|
||||
<ov-video-devices-select
|
||||
(onVideoDeviceChanged)="onVideoDeviceChanged.emit($event)"
|
||||
(onVideoEnabledChanged)="videoEnabledChanged($event)"
|
||||
|
@ -32,7 +32,7 @@
|
|||
</div>
|
||||
|
||||
<!-- Microphone -->
|
||||
<div class="audio-controls-container">
|
||||
<div class="audio-controls-container" *ngIf="showMicrophoneButton">
|
||||
<ov-audio-devices-select
|
||||
(onAudioDeviceChanged)="onAudioDeviceChanged.emit($event)"
|
||||
(onAudioEnabledChanged)="audioEnabledChanged($event)"
|
||||
|
|
|
@ -40,13 +40,16 @@ export class PreJoinComponent implements OnInit, OnDestroy {
|
|||
* @ignore
|
||||
*/
|
||||
isMinimal: boolean = false;
|
||||
showCameraButton: boolean = true;
|
||||
showMicrophoneButton: boolean = true;
|
||||
showLogo: boolean = true;
|
||||
|
||||
videoTrack: LocalTrack | undefined;
|
||||
audioTrack: LocalTrack | undefined;
|
||||
private tracks: LocalTrack[];
|
||||
private log: ILogger;
|
||||
private screenShareStateSubscription: Subscription;
|
||||
private cameraButtonSub: Subscription;
|
||||
private microphoneButtonSub: Subscription;
|
||||
private minimalSub: Subscription;
|
||||
private displayLogoSub: Subscription;
|
||||
private shouldRemoveTracksWhenComponentIsDestroyed: boolean = true;
|
||||
|
@ -81,8 +84,9 @@ export class PreJoinComponent implements OnInit, OnDestroy {
|
|||
|
||||
async ngOnDestroy() {
|
||||
this.cdkSrv.setSelector('body');
|
||||
if (this.screenShareStateSubscription) this.screenShareStateSubscription.unsubscribe();
|
||||
if (this.minimalSub) this.minimalSub.unsubscribe();
|
||||
if (this.cameraButtonSub) this.cameraButtonSub.unsubscribe();
|
||||
if (this.microphoneButtonSub) this.microphoneButtonSub.unsubscribe();
|
||||
if (this.displayLogoSub) this.displayLogoSub.unsubscribe();
|
||||
|
||||
if (this.shouldRemoveTracksWhenComponentIsDestroyed) {
|
||||
|
@ -133,6 +137,12 @@ export class PreJoinComponent implements OnInit, OnDestroy {
|
|||
this.isMinimal = value;
|
||||
// this.cd.markForCheck();
|
||||
});
|
||||
this.cameraButtonSub = this.libService.cameraButton$.subscribe((value: boolean) => {
|
||||
this.showCameraButton = value;
|
||||
});
|
||||
this.microphoneButtonSub = this.libService.microphoneButton$.subscribe((value: boolean) => {
|
||||
this.showMicrophoneButton = value;
|
||||
});
|
||||
this.displayLogoSub = this.libService.displayLogo$.subscribe((value: boolean) => {
|
||||
this.showLogo = value;
|
||||
// this.cd.markForCheck();
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
<button
|
||||
id="camera-btn"
|
||||
mat-icon-button
|
||||
*ngIf="showCameraButton"
|
||||
(click)="toggleCamera()"
|
||||
[disabled]="isConnectionLost || !hasVideoDevices || cameraMuteChanging"
|
||||
[class.warn-btn]="!isCameraEnabled"
|
||||
|
@ -46,6 +47,7 @@
|
|||
<button
|
||||
id="mic-btn"
|
||||
mat-icon-button
|
||||
*ngIf="showMicrophoneButton"
|
||||
(click)="toggleMicrophone()"
|
||||
[disabled]="isConnectionLost || !hasAudioDevices || microphoneMuteChanging"
|
||||
[class.warn-btn]="!isMicrophoneEnabled"
|
||||
|
|
|
@ -201,6 +201,14 @@ export class ToolbarComponent implements OnInit, OnDestroy, AfterViewInit {
|
|||
* @ignore
|
||||
*/
|
||||
isMinimal: boolean = false;
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
showCameraButton: boolean = true;
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
showMicrophoneButton: boolean = true;
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
|
@ -329,6 +337,8 @@ export class ToolbarComponent implements OnInit, OnDestroy, AfterViewInit {
|
|||
private panelTogglingSubscription: Subscription;
|
||||
private chatMessagesSubscription: Subscription;
|
||||
private localParticipantSubscription: Subscription;
|
||||
private cameraButtonSub: Subscription;
|
||||
private microphoneButtonSub: Subscription;
|
||||
private screenshareButtonSub: Subscription;
|
||||
private fullscreenButtonSub: Subscription;
|
||||
private backgroundEffectsButtonSub: Subscription;
|
||||
|
@ -423,6 +433,8 @@ export class ToolbarComponent implements OnInit, OnDestroy, AfterViewInit {
|
|||
if (this.panelTogglingSubscription) this.panelTogglingSubscription.unsubscribe();
|
||||
if (this.chatMessagesSubscription) this.chatMessagesSubscription.unsubscribe();
|
||||
if (this.localParticipantSubscription) this.localParticipantSubscription.unsubscribe();
|
||||
if (this.cameraButtonSub) this.cameraButtonSub.unsubscribe();
|
||||
if (this.microphoneButtonSub) this.microphoneButtonSub.unsubscribe();
|
||||
if (this.screenshareButtonSub) this.screenshareButtonSub.unsubscribe();
|
||||
if (this.fullscreenButtonSub) this.fullscreenButtonSub.unsubscribe();
|
||||
if (this.backgroundEffectsButtonSub) this.backgroundEffectsButtonSub.unsubscribe();
|
||||
|
@ -712,6 +724,14 @@ export class ToolbarComponent implements OnInit, OnDestroy, AfterViewInit {
|
|||
this.brandingLogo = value;
|
||||
this.cd.markForCheck();
|
||||
});
|
||||
this.cameraButtonSub = this.libService.cameraButton$.subscribe((value: boolean) => {
|
||||
this.showCameraButton = value;
|
||||
this.cd.markForCheck();
|
||||
});
|
||||
this.microphoneButtonSub = this.libService.microphoneButton$.subscribe((value: boolean) => {
|
||||
this.showMicrophoneButton = value;
|
||||
this.cd.markForCheck();
|
||||
});
|
||||
this.screenshareButtonSub = this.libService.screenshareButton$.subscribe((value: boolean) => {
|
||||
this.showScreenshareButton = value && !this.platformService.isMobile();
|
||||
this.cd.markForCheck();
|
||||
|
|
|
@ -22,7 +22,9 @@ import {
|
|||
ToolbarRecordingButtonDirective,
|
||||
ToolbarScreenshareButtonDirective,
|
||||
ToolbarSettingsButtonDirective,
|
||||
ToolbarAdditionalButtonsPossitionDirective
|
||||
ToolbarAdditionalButtonsPossitionDirective,
|
||||
ToolbarCameraButtonDirective,
|
||||
ToolbarMicrophoneButtonDirective
|
||||
} from './toolbar.directive';
|
||||
import {
|
||||
AudioEnabledDirective,
|
||||
|
@ -53,6 +55,8 @@ import {
|
|||
PrejoinDirective,
|
||||
VideoEnabledDirective,
|
||||
AudioEnabledDirective,
|
||||
ToolbarCameraButtonDirective,
|
||||
ToolbarMicrophoneButtonDirective,
|
||||
ToolbarScreenshareButtonDirective,
|
||||
ToolbarFullscreenButtonDirective,
|
||||
ToolbarBackgroundEffectsButtonDirective,
|
||||
|
@ -94,6 +98,8 @@ import {
|
|||
PrejoinDirective,
|
||||
VideoEnabledDirective,
|
||||
AudioEnabledDirective,
|
||||
ToolbarCameraButtonDirective,
|
||||
ToolbarMicrophoneButtonDirective,
|
||||
ToolbarScreenshareButtonDirective,
|
||||
ToolbarFullscreenButtonDirective,
|
||||
ToolbarBackgroundEffectsButtonDirective,
|
||||
|
|
|
@ -2,6 +2,137 @@ import { AfterViewInit, Directive, ElementRef, Input, OnDestroy } from '@angular
|
|||
import { OpenViduComponentsConfigService } from '../../services/config/directive-config.service';
|
||||
import { ToolbarAdditionalButtonsPosition } from '../../models/toolbar.model';
|
||||
|
||||
/**
|
||||
* The **cameraButton** directive allows show/hide the camera toolbar button.
|
||||
*
|
||||
* Default: `true`
|
||||
*
|
||||
* It can be used in the parent element {@link VideoconferenceComponent} specifying the name of the `toolbar` component:
|
||||
*
|
||||
* @example
|
||||
* <ov-videoconference [toolbarCameraButton]="false"></ov-videoconference>
|
||||
*
|
||||
* \
|
||||
* And it also can be used in the {@link ToolbarComponent}.
|
||||
* @example
|
||||
* <ov-toolbar [cameraButton]="false"></ov-toolbar>
|
||||
*/
|
||||
@Directive({
|
||||
selector: 'ov-videoconference[toolbarCameraButton], ov-toolbar[cameraButton]'
|
||||
})
|
||||
export class ToolbarCameraButtonDirective implements AfterViewInit, OnDestroy {
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
@Input() set toolbarCameraButton(value: boolean) {
|
||||
this.cameraValue = value;
|
||||
this.update(this.cameraValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
@Input() set cameraButton(value: boolean) {
|
||||
this.cameraValue = value;
|
||||
this.update(this.cameraValue);
|
||||
}
|
||||
|
||||
private cameraValue: boolean = true;
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
constructor(
|
||||
public elementRef: ElementRef,
|
||||
private libService: OpenViduComponentsConfigService
|
||||
) {}
|
||||
|
||||
ngAfterViewInit() {
|
||||
this.update(this.cameraValue);
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
this.clear();
|
||||
}
|
||||
|
||||
private clear() {
|
||||
this.cameraValue = true;
|
||||
this.update(true);
|
||||
}
|
||||
|
||||
private update(value: boolean) {
|
||||
if (this.libService.showCameraButton() !== value) {
|
||||
this.libService.setCameraButton(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The **microphoneButton** directive allows show/hide the microphone toolbar button.
|
||||
*
|
||||
* Default: `true`
|
||||
*
|
||||
* It can be used in the parent element {@link VideoconferenceComponent} specifying the name of the `toolbar` component:
|
||||
*
|
||||
* @example
|
||||
* <ov-videoconference [toolbarMicrophoneButton]="false"></ov-videoconference>
|
||||
*
|
||||
* \
|
||||
* And it also can be used in the {@link ToolbarComponent}.
|
||||
* @example
|
||||
* <ov-toolbar [microphoneButton]="false"></ov-toolbar>
|
||||
*/
|
||||
@Directive({
|
||||
selector: 'ov-videoconference[toolbarMicrophoneButton], ov-toolbar[microphoneButton]'
|
||||
})
|
||||
export class ToolbarMicrophoneButtonDirective implements AfterViewInit, OnDestroy {
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
@Input() set toolbarMicrophoneButton(value: boolean) {
|
||||
this.microphoneValue = value;
|
||||
this.update(this.microphoneValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
@Input() set microphoneButton(value: boolean) {
|
||||
this.microphoneValue = value;
|
||||
this.update(this.microphoneValue);
|
||||
}
|
||||
|
||||
private microphoneValue: boolean = true;
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
constructor(
|
||||
public elementRef: ElementRef,
|
||||
private libService: OpenViduComponentsConfigService
|
||||
) {}
|
||||
|
||||
ngAfterViewInit() {
|
||||
this.update(this.microphoneValue);
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
this.clear();
|
||||
}
|
||||
|
||||
private clear() {
|
||||
this.microphoneValue = true;
|
||||
this.update(true);
|
||||
}
|
||||
|
||||
private update(value: boolean) {
|
||||
if (this.libService.showMicrophoneButton() !== value) {
|
||||
this.libService.setMicrophoneButton(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The **screenshareButton** directive allows show/hide the screenshare toolbar button.
|
||||
*
|
||||
|
|
|
@ -30,6 +30,14 @@ export class OpenViduComponentsConfigService {
|
|||
videoEnabled$: Observable<boolean>;
|
||||
private audioEnabled = <BehaviorSubject<boolean>>new BehaviorSubject(true);
|
||||
audioEnabled$: Observable<boolean>;
|
||||
|
||||
//Toolbar settings
|
||||
private cameraButton = <BehaviorSubject<boolean>>new BehaviorSubject(true);
|
||||
cameraButton$: Observable<boolean>;
|
||||
|
||||
private microphoneButton = <BehaviorSubject<boolean>>new BehaviorSubject(true);
|
||||
microphoneButton$: Observable<boolean>;
|
||||
|
||||
private screenshareButton = <BehaviorSubject<boolean>>new BehaviorSubject(true);
|
||||
screenshareButton$: Observable<boolean>;
|
||||
|
||||
|
@ -111,6 +119,8 @@ export class OpenViduComponentsConfigService {
|
|||
this.videoEnabled$ = this.videoEnabled.asObservable();
|
||||
this.audioEnabled$ = this.audioEnabled.asObservable();
|
||||
//Toolbar observables
|
||||
this.cameraButton$ = this.cameraButton.asObservable();
|
||||
this.microphoneButton$ = this.microphoneButton.asObservable();
|
||||
this.screenshareButton$ = this.screenshareButton.asObservable();
|
||||
this.fullscreenButton$ = this.fullscreenButton.asObservable();
|
||||
this.backgroundEffectsButton$ = this.backgroundEffectsButton.asObservable();
|
||||
|
@ -198,6 +208,23 @@ export class OpenViduComponentsConfigService {
|
|||
}
|
||||
|
||||
//Toolbar settings
|
||||
|
||||
setCameraButton(cameraButton: boolean) {
|
||||
this.cameraButton.next(cameraButton);
|
||||
}
|
||||
|
||||
showCameraButton(): boolean {
|
||||
return this.cameraButton.getValue();
|
||||
}
|
||||
|
||||
setMicrophoneButton(microphoneButton: boolean) {
|
||||
this.microphoneButton.next(microphoneButton);
|
||||
}
|
||||
|
||||
showMicrophoneButton(): boolean {
|
||||
return this.microphoneButton.getValue();
|
||||
}
|
||||
|
||||
setScreenshareButton(screenshareButton: boolean) {
|
||||
this.screenshareButton.next(screenshareButton);
|
||||
}
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
[participantName]="'Participant'"
|
||||
[videoEnabled]="true"
|
||||
[audioEnabled]="true"
|
||||
[toolbarCameraButton]="true"
|
||||
[toolbarMicrophoneButton]="true"
|
||||
[toolbarScreenshareButton]="true"
|
||||
[toolbarFullscreenButton]="true"
|
||||
[toolbarRecordingButton]="true"
|
||||
|
|
Loading…
Reference in New Issue