mirror of https://github.com/OpenVidu/openvidu.git
openvidu-components: Added preliminary subtitles
parent
fc7b961010
commit
0b74590252
|
@ -20,6 +20,7 @@ var PARTICIPANTS_PANEL_BUTTON;
|
|||
var ACTIVITIES_RECORDING_ACTIVITY;
|
||||
var RECORDING_ERROR;
|
||||
var TOOLBAR_SETTINGS_BUTTON;
|
||||
var SUBTITLES_BUTTON;
|
||||
|
||||
var SESSION_NAME;
|
||||
|
||||
|
@ -37,6 +38,7 @@ $(document).ready(() => {
|
|||
RECORDING_BUTTON = url.searchParams.get("recordingBtn") === null ? true : url.searchParams.get("recordingBtn") === 'true';
|
||||
FULLSCREEN_BUTTON = url.searchParams.get("fullscreenBtn") === null ? true : url.searchParams.get("fullscreenBtn") === 'true';
|
||||
TOOLBAR_SETTINGS_BUTTON = url.searchParams.get("toolbarSettingsBtn") === null ? true : url.searchParams.get("toolbarSettingsBtn") === 'true';
|
||||
SUBTITLES_BUTTON = url.searchParams.get("toolbarSubtitlesBtn") === null ? true : url.searchParams.get("toolbarSubtitlesBtn") === 'true';
|
||||
|
||||
LEAVE_BUTTON = url.searchParams.get("leaveBtn") === null ? true : url.searchParams.get("leaveBtn") === 'true';
|
||||
ACTIVITIES_PANEL_BUTTON = url.searchParams.get("activitiesPanelBtn") === null ? true : url.searchParams.get("activitiesPanelBtn") === 'true';
|
||||
|
@ -147,6 +149,7 @@ async function joinSession(sessionName, participantName) {
|
|||
|
||||
webComponent.toolbarFullscreenButton = FULLSCREEN_BUTTON;
|
||||
webComponent.toolbarSettingsButton = TOOLBAR_SETTINGS_BUTTON;
|
||||
webComponent.toolbarSubtitlesButton = SUBTITLES_BUTTON;
|
||||
webComponent.toolbarLeaveButton = LEAVE_BUTTON;
|
||||
webComponent.toolbarRecordingButton = RECORDING_BUTTON;
|
||||
webComponent.toolbarActivitiesPanelButton = ACTIVITIES_PANEL_BUTTON;
|
||||
|
|
|
@ -252,6 +252,41 @@ describe('Testing API Directives', () => {
|
|||
expect(element.length).equals(0);
|
||||
});
|
||||
|
||||
it('should HIDE the SUBTITLES button', async () => {
|
||||
let element;
|
||||
await browser.get(`${url}?prejoin=false&toolbarSubtitlesBtn=false`);
|
||||
element = await browser.wait(until.elementLocated(By.id('session-container')), TIMEOUT);
|
||||
expect(await element.isDisplayed()).to.be.true;
|
||||
|
||||
// Checking if toolbar is present
|
||||
element = await browser.wait(until.elementLocated(By.id('media-buttons-container')), TIMEOUT);
|
||||
expect(await element.isDisplayed()).to.be.true;
|
||||
|
||||
// Open more options menu
|
||||
element = await browser.wait(until.elementLocated(By.id('more-options-btn')), TIMEOUT);
|
||||
await element.click();
|
||||
|
||||
await browser.sleep(500);
|
||||
|
||||
// Checking if subtitles button is not present
|
||||
element = await browser.wait(until.elementLocated(By.className('mat-menu-content')), TIMEOUT);
|
||||
expect(await element.isDisplayed()).to.be.true;
|
||||
element = await browser.findElements(By.id('subtitles-btn'));
|
||||
expect(element.length).equals(0);
|
||||
|
||||
element = await browser.findElements(By.id('toolbar-settings-btn'));
|
||||
expect(element.length).equals(1);
|
||||
await element[0].click();
|
||||
|
||||
await browser.sleep(500);
|
||||
|
||||
element = await browser.wait(until.elementLocated(By.className('settings-container')), TIMEOUT);
|
||||
expect(await element.isDisplayed()).to.be.true;
|
||||
element = await browser.findElements(By.id('subtitles-opt'));
|
||||
expect(element.length).equals(0);
|
||||
|
||||
});
|
||||
|
||||
it('should HIDE the TOOLBAR SETTINGS button', async () => {
|
||||
let element;
|
||||
await browser.get(`${url}?prejoin=false&toolbarSettingsBtn=false`);
|
||||
|
|
|
@ -30,7 +30,7 @@ export class AudioWaveComponent implements OnInit, OnDestroy {
|
|||
if (this.streamManager) {
|
||||
this.streamManager.on('streamPropertyChanged', (event: StreamPropertyChangedEvent) => {
|
||||
if (event.reason === 'trackReplaced' && event.changedProperty === 'audioActive') {
|
||||
// FIXUP: When the audio track is replaced, the startSpeakingEvents is not fired by openvidu-browser
|
||||
// TODO: When the audio track is replaced, the startSpeakingEvents is not fired by openvidu-browser
|
||||
this.unsubscribeSpeakingEvents();
|
||||
this.subscribeSpeakingEvents();
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,18 +1,18 @@
|
|||
<div id="layout" class="layout">
|
||||
<div
|
||||
class="OT_root OT_publisher"
|
||||
*ngFor="let stream of localParticipant | streams"
|
||||
[ngClass]="{ OV_big: stream.videoEnlarged }"
|
||||
>
|
||||
<ng-container *ngTemplateOutlet="streamTemplate; context: { $implicit: stream }"></ng-container>
|
||||
<div class="container" [class.withSubtitles]="subtitlesEnabled">
|
||||
<div id="layout" class="layout">
|
||||
<div class="OT_root OT_publisher" *ngFor="let stream of localParticipant | streams" [ngClass]="{ OV_big: stream.videoEnlarged }">
|
||||
<ng-container *ngTemplateOutlet="streamTemplate; context: { $implicit: stream }"></ng-container>
|
||||
</div>
|
||||
|
||||
<div
|
||||
*ngFor="let stream of remoteParticipants | streams"
|
||||
class="OT_root OT_publisher"
|
||||
id="remote-participant"
|
||||
[ngClass]="{ OV_big: stream.videoEnlarged }"
|
||||
>
|
||||
<ng-container *ngTemplateOutlet="streamTemplate; context: { $implicit: stream }"></ng-container>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
*ngFor="let stream of remoteParticipants | streams"
|
||||
class="OT_root OT_publisher"
|
||||
id="remote-participant"
|
||||
[ngClass]="{ OV_big: stream.videoEnlarged }"
|
||||
>
|
||||
<ng-container *ngTemplateOutlet="streamTemplate; context: { $implicit: stream }"></ng-container>
|
||||
</div>
|
||||
<ov-subtitles *ngIf="subtitlesEnabled" class="OV_ignored"></ov-subtitles>
|
||||
</div>
|
||||
|
|
|
@ -73,8 +73,14 @@ export class LayoutComponent implements OnInit, OnDestroy, AfterViewInit {
|
|||
|
||||
localParticipant: ParticipantAbstractModel;
|
||||
remoteParticipants: ParticipantAbstractModel[] = [];
|
||||
protected localParticipantSubs: Subscription;
|
||||
protected remoteParticipantsSubs: Subscription;
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
subtitlesEnabled = true;
|
||||
|
||||
private localParticipantSubs: Subscription;
|
||||
private remoteParticipantsSubs: Subscription;
|
||||
private subtitlesSubs: Subscription;
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
|
@ -83,10 +89,11 @@ export class LayoutComponent implements OnInit, OnDestroy, AfterViewInit {
|
|||
|
||||
ngOnInit(): void {
|
||||
this.subscribeToParticipants();
|
||||
this.subscribeToSubtitles();
|
||||
}
|
||||
|
||||
ngAfterViewInit() {
|
||||
let timeout: number = 0;
|
||||
let timeout: number = 100;
|
||||
this.layoutService.initialize(timeout);
|
||||
this.layoutService.update(timeout);
|
||||
}
|
||||
|
@ -96,9 +103,18 @@ export class LayoutComponent implements OnInit, OnDestroy, AfterViewInit {
|
|||
this.remoteParticipants = [];
|
||||
if (this.localParticipantSubs) this.localParticipantSubs.unsubscribe();
|
||||
if (this.remoteParticipantsSubs) this.remoteParticipantsSubs.unsubscribe();
|
||||
if (this.subtitlesSubs) this.subtitlesSubs.unsubscribe();
|
||||
this.layoutService.clear();
|
||||
}
|
||||
|
||||
private subscribeToSubtitles() {
|
||||
this.subtitlesSubs = this.layoutService.subtitlesTogglingObs.subscribe((value: boolean) => {
|
||||
this.subtitlesEnabled = value;
|
||||
this.cd.markForCheck();
|
||||
this.layoutService.update();
|
||||
});
|
||||
}
|
||||
|
||||
private subscribeToParticipants() {
|
||||
this.localParticipantSubs = this.participantService.localParticipantObs.subscribe((p) => {
|
||||
this.localParticipant = p;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<div class="panel-container" id="background-effects-container" fxLayout="column" fxLayoutAlign="space-evenly none">
|
||||
<div class="panel-container" id="settings-container" fxLayout="column" fxLayoutAlign="space-evenly none">
|
||||
<div class="panel-header-container" fxFlex="55px" fxLayoutAlign="start center">
|
||||
<h3 class="panel-title">{{ 'PANEL.SETTINGS.TITLE' | translate }}</h3>
|
||||
<button class="panel-close-button" mat-icon-button matTooltip="{{ 'PANEL.CLOSE' | translate }}" (click)="close()">
|
||||
|
@ -8,26 +8,35 @@
|
|||
|
||||
<div class="settings-container" fxFlex="100%" fxLayoutAlign="space-evenly none">
|
||||
<div class="item-menu">
|
||||
<mat-selection-list #settings [multiple]="false">
|
||||
<mat-list-option class="option" [selected]="true" value="general">
|
||||
<mat-selection-list (selectionChange)="onSelectionChanged($event)" [multiple]="false">
|
||||
<mat-list-option class="option" id="general-opt" [selected]="selectedOption === settingsOptions.GENERAL" [value]="settingsOptions.GENERAL">
|
||||
<mat-icon mat-list-icon>manage_accounts</mat-icon>
|
||||
<div mat-line>{{ 'PANEL.SETTINGS.GENERAL' | translate }}</div>
|
||||
</mat-list-option>
|
||||
<mat-list-option class="option" value="video">
|
||||
<mat-list-option class="option" id="video-opt" [selected]="selectedOption === settingsOptions.VIDEO" [value]="settingsOptions.VIDEO">
|
||||
<mat-icon mat-list-icon>videocam</mat-icon>
|
||||
<div mat-line>{{ 'PANEL.SETTINGS.VIDEO' | translate }}</div>
|
||||
</mat-list-option>
|
||||
<mat-list-option class="option" value="audio">
|
||||
<mat-list-option class="option" id="audio-opt" [selected]="selectedOption === settingsOptions.AUDIO" [value]="settingsOptions.AUDIO">
|
||||
<mat-icon mat-list-icon>mic</mat-icon>
|
||||
<div mat-line>{{ 'PANEL.SETTINGS.AUDIO' | translate }}</div>
|
||||
</mat-list-option>
|
||||
<mat-list-option
|
||||
*ngIf="showSubtitles"
|
||||
class="option"
|
||||
[selected]="selectedOption === settingsOptions.SUBTITLES"
|
||||
[value]="settingsOptions.SUBTITLES"
|
||||
id="subtitles-opt"
|
||||
>
|
||||
<mat-icon mat-list-icon>closed_caption</mat-icon>
|
||||
<div mat-line>{{ 'PANEL.SETTINGS.SUBTITLE' | translate }}</div>
|
||||
</mat-list-option>
|
||||
</mat-selection-list>
|
||||
</div>
|
||||
|
||||
<div class="item-content">
|
||||
<div *ngIf="settings.selectedOptions.selected[0]?.value === 'general'">
|
||||
<div *ngIf="selectedOption === settingsOptions.GENERAL">
|
||||
<ov-nickname-input></ov-nickname-input>
|
||||
|
||||
<mat-list>
|
||||
<mat-list-item>
|
||||
<mat-icon mat-list-icon>language</mat-icon>
|
||||
|
@ -36,8 +45,9 @@
|
|||
</mat-list-item>
|
||||
</mat-list>
|
||||
</div>
|
||||
<ov-video-devices-select *ngIf="settings.selectedOptions.selected[0]?.value === 'video'"></ov-video-devices-select>
|
||||
<ov-audio-devices-select *ngIf="settings.selectedOptions.selected[0]?.value === 'audio'"></ov-audio-devices-select>
|
||||
<ov-video-devices-select *ngIf="selectedOption === settingsOptions.VIDEO"></ov-video-devices-select>
|
||||
<ov-audio-devices-select *ngIf="selectedOption === settingsOptions.AUDIO"></ov-audio-devices-select>
|
||||
<ov-subtitles-settings *ngIf="selectedOption === settingsOptions.SUBTITLES && showSubtitles"></ov-subtitles-settings>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import { Component, HostListener, OnInit } from '@angular/core';
|
||||
import { MatOptionSelectionChange } from '@angular/material/core';
|
||||
import { PanelType } from '../../../models/panel.model';
|
||||
import { PanelService } from '../../../services/panel/panel.service';
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { Subscription } from 'rxjs';
|
||||
import { PanelSettingsOptions, PanelType } from '../../../models/panel.model';
|
||||
import { OpenViduAngularConfigService } from '../../../services/config/openvidu-angular.config.service';
|
||||
import { PanelEvent, PanelService } from '../../../services/panel/panel.service';
|
||||
|
||||
@Component({
|
||||
selector: 'ov-settings-panel',
|
||||
|
@ -9,12 +10,41 @@ import { PanelService } from '../../../services/panel/panel.service';
|
|||
styleUrls: ['../panel.component.css', './settings-panel.component.css']
|
||||
})
|
||||
export class SettingsPanelComponent implements OnInit {
|
||||
settingsOptions: typeof PanelSettingsOptions = PanelSettingsOptions;
|
||||
selectedOption: PanelSettingsOptions = PanelSettingsOptions.GENERAL;
|
||||
showSubtitles: boolean = true;
|
||||
private subtitlesSubs: Subscription;
|
||||
panelSubscription: Subscription;
|
||||
constructor(private panelService: PanelService, private libService: OpenViduAngularConfigService) {}
|
||||
ngOnInit() {
|
||||
this.subscribeToPanelToggling();
|
||||
this.subscribeToDirectives();
|
||||
}
|
||||
|
||||
selectedOption: string;
|
||||
constructor(private panelService: PanelService) {}
|
||||
ngOnInit() {}
|
||||
ngOnDestroy() {
|
||||
if (this.subtitlesSubs) this.subtitlesSubs.unsubscribe();
|
||||
}
|
||||
|
||||
close() {
|
||||
this.panelService.togglePanel(PanelType.SETTINGS);
|
||||
}
|
||||
onSelectionChanged(e: any){
|
||||
this.selectedOption = e.option.value;
|
||||
}
|
||||
|
||||
private subscribeToDirectives() {
|
||||
this.subtitlesSubs = this.libService.subtitlesButtonObs.subscribe((value: boolean) => {
|
||||
this.showSubtitles = value;
|
||||
});
|
||||
}
|
||||
|
||||
private subscribeToPanelToggling() {
|
||||
this.panelSubscription = this.panelService.panelOpenedObs.subscribe(
|
||||
(ev: PanelEvent) => {
|
||||
if (ev.type === PanelType.SETTINGS && !!ev.expand) {
|
||||
this.selectedOption = ev.expand as PanelSettingsOptions;
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
position: relative;
|
||||
height: calc(100% - 70px);
|
||||
min-height: calc(100% - 70px);
|
||||
padding-top: 10px;
|
||||
padding-top: 0px;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
|
||||
::ng-deep .mat-slide-toggle.mat-checked .mat-slide-toggle-bar {
|
||||
background-color: var(--ov-tertiary-color);
|
||||
}
|
||||
|
||||
::ng-deep .mat-slide-toggle.mat-checked .mat-slide-toggle-thumb{
|
||||
background-color: var(--ov-light-color);
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
<mat-list>
|
||||
<mat-list-item>
|
||||
<div mat-line>{{ 'PANEL.SETTINGS.SUBTITLE' | translate }}</div>
|
||||
<mat-slide-toggle (change)="toggleSubtitles()" [checked]="subtitlesEnabled" [disableRipple]="true"></mat-slide-toggle>
|
||||
</mat-list-item>
|
||||
<mat-list-item>
|
||||
<div mat-line>{{ 'PANEL.SETTINGS.LANGUAGE' | translate }}:</div>
|
||||
<button mat-flat-button [matMenuTriggerFor]="menu" class="lang-button" [disabled]="true">
|
||||
<span>{{langSelected}}</span>
|
||||
<mat-icon>expand_more</mat-icon>
|
||||
</button>
|
||||
<mat-menu #menu="matMenu">
|
||||
<button mat-menu-item *ngFor="let lang of languagesAvailable" (click)="onLangSelected(lang)">
|
||||
<span>{{lang}}</span>
|
||||
</button>
|
||||
</mat-menu>
|
||||
</mat-list-item>
|
||||
</mat-list>
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { SubtitlesComponent } from './subtitles.component';
|
||||
|
||||
describe('SubtitlesComponent', () => {
|
||||
let component: SubtitlesComponent;
|
||||
let fixture: ComponentFixture<SubtitlesComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ SubtitlesComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(SubtitlesComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,40 @@
|
|||
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||
import { Subscription } from 'rxjs';
|
||||
import { LayoutService } from '../../../services/layout/layout.service';
|
||||
|
||||
@Component({
|
||||
selector: 'ov-subtitles-settings',
|
||||
templateUrl: './subtitles.component.html',
|
||||
styleUrls: ['./subtitles.component.css']
|
||||
})
|
||||
export class SubtitlesSettingComponent implements OnInit, OnDestroy {
|
||||
subtitlesEnabled: boolean;
|
||||
languagesAvailable = [];
|
||||
subtitlesSubs: Subscription;
|
||||
langSelected: string = 'English';
|
||||
|
||||
constructor(private layoutService: LayoutService) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.subscribeToSubtitles();
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
if (this.subtitlesSubs) this.subtitlesSubs.unsubscribe();
|
||||
}
|
||||
|
||||
onLangSelected(lang: string){
|
||||
this.langSelected = lang;
|
||||
}
|
||||
|
||||
toggleSubtitles() {
|
||||
this.layoutService.toggleSubtitles();
|
||||
}
|
||||
|
||||
private subscribeToSubtitles() {
|
||||
this.subtitlesSubs = this.layoutService.subtitlesTogglingObs.subscribe((value: boolean) => {
|
||||
this.subtitlesEnabled = value;
|
||||
// this.cd.markForCheck();
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
.subtitles-container {
|
||||
/* padding: 5px; */
|
||||
display: flex;
|
||||
height: 75px;
|
||||
}
|
||||
.subtitles-offset {
|
||||
height: 75px;
|
||||
width: 115px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.subtitles-main-container {
|
||||
flex-grow: 1;
|
||||
text-align: center;
|
||||
align-self: center;
|
||||
}
|
||||
|
||||
.subtitles-offset + .subtitles-offset {
|
||||
margin-left: 2%;
|
||||
}
|
||||
#subtitle-settings-btn {
|
||||
color: var(--ov-text-color);
|
||||
background-color: var(--ov-secondary-color);
|
||||
}
|
||||
#subtitle-settings-icon {
|
||||
font-size: 15px;
|
||||
height: 15px;
|
||||
width: 15px;
|
||||
padding-right: 5px;
|
||||
}
|
||||
|
||||
#subtitle-text {
|
||||
color: var(--ov-text-color);
|
||||
background-color: var(--ov-logo-background-color);
|
||||
font-size: 18px;
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
padding: 4.5px;
|
||||
line-height: 1.6;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.small-text {
|
||||
font-size: 14px !important;
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
<div class="subtitles-container">
|
||||
<div *ngIf="screenSize !== 'sm' && screenSize !== 'xs' && !settingsPanelOpened" class="subtitles-offset">
|
||||
<button (click)="onSettingsCliked()" id="subtitle-settings-btn" mat-flat-button>
|
||||
<mat-icon id="subtitle-settings-icon">settings</mat-icon>
|
||||
<span>English</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="subtitles-main-container">
|
||||
<span id="subtitle-text" [class.small-text]="screenSize === 'xs' ">(Demo preview): {{ subtitleText }}</span>
|
||||
</div>
|
||||
<div class="subtitles-offset" *ngIf="screenSize !== 'sm' && screenSize !== 'xs' && !settingsPanelOpened"></div>
|
||||
</div>
|
|
@ -0,0 +1,25 @@
|
|||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { SubtitlesComponent } from './subtitles.component';
|
||||
|
||||
describe('SubtitlesComponent', () => {
|
||||
let component: SubtitlesComponent;
|
||||
let fixture: ComponentFixture<SubtitlesComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ SubtitlesComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(SubtitlesComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,78 @@
|
|||
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnInit } from '@angular/core';
|
||||
import { Subscription } from 'rxjs';
|
||||
import { PanelSettingsOptions, PanelType } from '../../models/panel.model';
|
||||
import { PanelEvent, PanelService } from '../../services/panel/panel.service';
|
||||
import { DocumentService } from '../../services/document/document.service';
|
||||
import { MediaChange } from '@angular/flex-layout';
|
||||
|
||||
//TODO: BORRAR
|
||||
import { LoremIpsum } from 'lorem-ipsum';
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
@Component({
|
||||
selector: 'ov-subtitles',
|
||||
templateUrl: './subtitles.component.html',
|
||||
styleUrls: ['./subtitles.component.css'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush
|
||||
})
|
||||
export class SubtitlesComponent implements OnInit {
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
subtitleText: string;
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
screenSize: string;
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
settingsPanelOpened: boolean;
|
||||
private screenSizeSub: Subscription;
|
||||
private panelTogglingSubscription: Subscription;
|
||||
interval: NodeJS.Timer;
|
||||
|
||||
constructor(private documentService: DocumentService, private panelService: PanelService, private cd: ChangeDetectorRef) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.subscribeToScreenSize();
|
||||
this.subscribeToPanelToggling();
|
||||
|
||||
//TODO: Subscribe to openvidu-browser subtitle event
|
||||
// TODO: REMOVE ------------------
|
||||
const lorem = new LoremIpsum();
|
||||
this.interval = setInterval(() => {
|
||||
this.subtitleText = lorem.generateSentences(1);
|
||||
this.cd.markForCheck();
|
||||
}, 3000);
|
||||
// TODO: REMOVE ------------------
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
if (this.screenSizeSub) this.screenSizeSub.unsubscribe();
|
||||
if(this.panelTogglingSubscription) this.panelTogglingSubscription.unsubscribe();
|
||||
//TODO: Unsubscribe to openvidu-browser subtitle event
|
||||
clearInterval(this.interval);
|
||||
}
|
||||
|
||||
onSettingsCliked() {
|
||||
this.panelService.togglePanel(PanelType.SETTINGS, PanelSettingsOptions.SUBTITLES);
|
||||
}
|
||||
|
||||
private subscribeToPanelToggling() {
|
||||
this.panelTogglingSubscription = this.panelService.panelOpenedObs.subscribe((ev: PanelEvent) => {
|
||||
this.settingsPanelOpened = ev.opened;
|
||||
this.cd.markForCheck();
|
||||
});
|
||||
}
|
||||
|
||||
private subscribeToScreenSize() {
|
||||
this.screenSizeSub = this.documentService.screenSizeObs.subscribe((change: MediaChange[]) => {
|
||||
this.screenSize = change[0].mqAlias;
|
||||
console.log(this.screenSize);
|
||||
this.cd.markForCheck();
|
||||
});
|
||||
}
|
||||
}
|
|
@ -103,6 +103,19 @@
|
|||
<span>{{ 'TOOLBAR.BACKGROUND' | translate }}</span>
|
||||
</button>
|
||||
|
||||
<!-- Subtitles button -->
|
||||
<button
|
||||
*ngIf="!isMinimal && showSubtitlesButton"
|
||||
[disabled]="isConnectionLost"
|
||||
mat-menu-item
|
||||
id="subtitles-btn"
|
||||
(click)="toggleSubtitles()"
|
||||
>
|
||||
<mat-icon>closed_caption</mat-icon>
|
||||
<span *ngIf="subtitlesEnabled">{{ 'TOOLBAR.DISABLE_SUBTITLES' | translate }}</span>
|
||||
<span *ngIf="!subtitlesEnabled">{{ 'TOOLBAR.ENABLE_SUBTITLES' | translate }}</span>
|
||||
</button>
|
||||
|
||||
<mat-divider class="divider" *ngIf="!isMinimal && showSettingsButton"></mat-divider>
|
||||
|
||||
<!-- Settings button -->
|
||||
|
|
|
@ -39,6 +39,7 @@ import { RecordingService } from '../../services/recording/recording.service';
|
|||
import { RecordingInfo, RecordingStatus } from '../../models/recording.model';
|
||||
import { TranslateService } from '../../services/translate/translate.service';
|
||||
import { MediaChange } from '@angular/flex-layout';
|
||||
import { LayoutService } from '../../services/layout/layout.service';
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -303,6 +304,17 @@ export class ToolbarComponent implements OnInit, OnDestroy, AfterViewInit {
|
|||
* @ignore
|
||||
*/
|
||||
showSessionName: boolean = true;
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
showSubtitlesButton: boolean = true;
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
subtitlesEnabled: boolean;
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
|
@ -350,6 +362,7 @@ export class ToolbarComponent implements OnInit, OnDestroy, AfterViewInit {
|
|||
private displaySessionNameSub: Subscription;
|
||||
private screenSizeSub: Subscription;
|
||||
private settingsButtonSub: Subscription;
|
||||
private subtitlesSubs: Subscription;
|
||||
private currentWindowHeight = window.innerHeight;
|
||||
|
||||
/**
|
||||
|
@ -365,6 +378,7 @@ export class ToolbarComponent implements OnInit, OnDestroy, AfterViewInit {
|
|||
protected oVDevicesService: DeviceService,
|
||||
protected actionService: ActionService,
|
||||
protected loggerSrv: LoggerService,
|
||||
private layoutService: LayoutService,
|
||||
private cd: ChangeDetectorRef,
|
||||
private libService: OpenViduAngularConfigService,
|
||||
private platformService: PlatformService,
|
||||
|
@ -411,6 +425,7 @@ export class ToolbarComponent implements OnInit, OnDestroy, AfterViewInit {
|
|||
this.subscribeToChatMessages();
|
||||
this.subscribeToRecordingStatus();
|
||||
this.subscribeToScreenSize();
|
||||
this.subscribeToSubtitlesToggling();
|
||||
}
|
||||
|
||||
ngAfterViewInit() {
|
||||
|
@ -438,6 +453,7 @@ export class ToolbarComponent implements OnInit, OnDestroy, AfterViewInit {
|
|||
if (this.recordingSubscription) this.recordingSubscription.unsubscribe();
|
||||
if (this.screenSizeSub) this.screenSizeSub.unsubscribe();
|
||||
if (this.settingsButtonSub) this.settingsButtonSub.unsubscribe();
|
||||
if (this.subtitlesSubs) this.subtitlesSubs.unsubscribe();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -528,6 +544,13 @@ export class ToolbarComponent implements OnInit, OnDestroy, AfterViewInit {
|
|||
this.panelService.togglePanel(PanelType.BACKGROUND_EFFECTS);
|
||||
}
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
toggleSubtitles() {
|
||||
this.layoutService.toggleSubtitles();
|
||||
}
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
|
@ -674,6 +697,10 @@ export class ToolbarComponent implements OnInit, OnDestroy, AfterViewInit {
|
|||
this.showSessionName = value;
|
||||
this.cd.markForCheck();
|
||||
});
|
||||
this.subtitlesSubs = this.libService.subtitlesButtonObs.subscribe((value: boolean) => {
|
||||
this.showSubtitlesButton = value;
|
||||
this.cd.markForCheck();
|
||||
});
|
||||
}
|
||||
|
||||
private subscribeToScreenSize() {
|
||||
|
@ -682,6 +709,13 @@ export class ToolbarComponent implements OnInit, OnDestroy, AfterViewInit {
|
|||
});
|
||||
}
|
||||
|
||||
private subscribeToSubtitlesToggling() {
|
||||
this.subtitlesSubs = this.layoutService.subtitlesTogglingObs.subscribe((value: boolean) => {
|
||||
this.subtitlesEnabled = value;
|
||||
this.cd.markForCheck();
|
||||
});
|
||||
}
|
||||
|
||||
private checkDisplayMoreOptions() {
|
||||
this.showMoreOptionsButton =
|
||||
this.showFullscreenButton || this.showBackgroundEffectsButton || this.showRecordingButton || this.showSettingsButton;
|
||||
|
|
|
@ -20,7 +20,8 @@ import {
|
|||
ToolbarActivitiesPanelButtonDirective,
|
||||
ToolbarBackgroundEffectsButtonDirective,
|
||||
ToolbarRecordingButtonDirective,
|
||||
ToolbarSettingsButtonDirective
|
||||
ToolbarSettingsButtonDirective,
|
||||
ToolbarSubtitleButtonDirective
|
||||
} from './toolbar.directive';
|
||||
import {
|
||||
AudioMutedDirective,
|
||||
|
@ -41,6 +42,7 @@ import {
|
|||
ToolbarScreenshareButtonDirective,
|
||||
ToolbarFullscreenButtonDirective,
|
||||
ToolbarBackgroundEffectsButtonDirective,
|
||||
ToolbarSubtitleButtonDirective,
|
||||
ToolbarLeaveButtonDirective,
|
||||
ToolbarRecordingButtonDirective,
|
||||
ToolbarParticipantsPanelButtonDirective,
|
||||
|
@ -70,6 +72,7 @@ import {
|
|||
ToolbarScreenshareButtonDirective,
|
||||
ToolbarFullscreenButtonDirective,
|
||||
ToolbarBackgroundEffectsButtonDirective,
|
||||
ToolbarSubtitleButtonDirective,
|
||||
ToolbarLeaveButtonDirective,
|
||||
ToolbarRecordingButtonDirective,
|
||||
ToolbarParticipantsPanelButtonDirective,
|
||||
|
|
|
@ -242,6 +242,65 @@ export class ToolbarBackgroundEffectsButtonDirective implements AfterViewInit, O
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The **subtitleButton** directive allows show/hide the subtitle toolbar button.
|
||||
*
|
||||
* Default: `true`
|
||||
*
|
||||
* It can be used in the parent element {@link VideoconferenceComponent} specifying the name of the `toolbar` component:
|
||||
*
|
||||
* @example
|
||||
* <ov-videoconference [toolbarSubtitleButton]="false"></ov-videoconference>
|
||||
*
|
||||
* \
|
||||
* And it also can be used in the {@link ToolbarComponent}.
|
||||
* @example
|
||||
* <ov-toolbar [subtitleButton]="false"></ov-toolbar>
|
||||
*/
|
||||
@Directive({
|
||||
selector: 'ov-videoconference[toolbarSubtitlesButton], ov-toolbar[subtitlesButton]'
|
||||
})
|
||||
export class ToolbarSubtitleButtonDirective implements AfterViewInit, OnDestroy {
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
@Input() set toolbarSubtitlesButton(value: boolean) {
|
||||
this.subtitlesButtonValue = value;
|
||||
this.update(this.subtitlesButtonValue);
|
||||
}
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
@Input() set subtitlesButton(value: boolean) {
|
||||
this.subtitlesButtonValue = value;
|
||||
this.update(this.subtitlesButtonValue);
|
||||
}
|
||||
|
||||
private subtitlesButtonValue: boolean = true;
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
constructor(public elementRef: ElementRef, private libService: OpenViduAngularConfigService) {}
|
||||
|
||||
ngAfterViewInit() {
|
||||
this.update(this.subtitlesButtonValue);
|
||||
}
|
||||
ngOnDestroy(): void {
|
||||
this.clear();
|
||||
}
|
||||
private clear() {
|
||||
this.subtitlesButtonValue = true;
|
||||
this.update(true);
|
||||
}
|
||||
|
||||
private update(value: boolean) {
|
||||
if (this.libService.subtitlesButton.getValue() !== value) {
|
||||
this.libService.subtitlesButton.next(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The **settingsButton** directive allows show/hide the settings toolbar button.
|
||||
*
|
||||
|
|
|
@ -34,6 +34,8 @@
|
|||
"MORE_OPTIONS":"更多选项",
|
||||
"FULLSCREEN":"全屏",
|
||||
"EXIT_FULLSCREEN": "退出全屏",
|
||||
"ENABLE_SUBTITLES": "启用字幕",
|
||||
"DISABLE_SUBTITLES": "禁用字幕",
|
||||
"BACKGROUND":"背景效果",
|
||||
"START_RECORDING": "开始录音",
|
||||
"STOP_RECORDING": "停止录制",
|
||||
|
@ -70,7 +72,8 @@
|
|||
"GENERAL": "一般的",
|
||||
"VIDEO": "视频",
|
||||
"AUDIO": "声音的",
|
||||
"LANGUAGE": "语"
|
||||
"LANGUAGE": "语",
|
||||
"SUBTITLE": "字幕"
|
||||
},
|
||||
"BACKGROUND": {
|
||||
"TITLE": "背景效果",
|
||||
|
|
|
@ -34,6 +34,8 @@
|
|||
"MORE_OPTIONS": "Weitere Optionen",
|
||||
"FULLSCREEN": "Vollbild",
|
||||
"EXIT_FULLSCREEN": "Vollbildmodus beenden",
|
||||
"ENABLE_SUBTITLES": "Untertitel aktivieren",
|
||||
"DISABLE_SUBTITLES": "Untertitel deaktivieren",
|
||||
"BACKGROUND": "Hintergrund-Effekte",
|
||||
"START_RECORDING": "Aufzeichnung starten",
|
||||
"STOP_RECORDING": "Aufzeichnung stoppen",
|
||||
|
@ -70,7 +72,8 @@
|
|||
"GENERAL": "Allgemein",
|
||||
"VIDEO": "Video",
|
||||
"AUDIO": "Audio",
|
||||
"LANGUAGE": "Sprache"
|
||||
"LANGUAGE": "Sprache",
|
||||
"SUBTITLE": "Untertitel"
|
||||
},
|
||||
"BACKGROUND": {
|
||||
"TITLE": "Hintergrund-Effekte",
|
||||
|
|
|
@ -35,6 +35,8 @@
|
|||
"MORE_OPTIONS": "More options",
|
||||
"FULLSCREEN": "Fullscreen",
|
||||
"EXIT_FULLSCREEN": "Exit fullscreen",
|
||||
"ENABLE_SUBTITLES": "Enable subtitles",
|
||||
"DISABLE_SUBTITLES": "Disable subtitles",
|
||||
"BACKGROUND": "Background effects",
|
||||
"START_RECORDING": "Start recording",
|
||||
"STOP_RECORDING": "Stop recording",
|
||||
|
@ -71,7 +73,8 @@
|
|||
"GENERAL": "General",
|
||||
"VIDEO": "Video",
|
||||
"AUDIO": "Audio",
|
||||
"LANGUAGE": "Language"
|
||||
"LANGUAGE": "Language",
|
||||
"SUBTITLE": "Subtitles"
|
||||
},
|
||||
"BACKGROUND": {
|
||||
"TITLE": "Background effects",
|
||||
|
|
|
@ -34,6 +34,8 @@
|
|||
"MORE_OPTIONS": "Más opciones",
|
||||
"EXIT_FULLSCREEN": "Quitar pantalla completa",
|
||||
"FULLSCREEN": "Pantalla completa",
|
||||
"ENABLE_SUBTITLES": "Activar subtítulos",
|
||||
"DISABLE_SUBTITLES": "Desactivar subtítulos",
|
||||
"BACKGROUND": "Efectos de fondo",
|
||||
"START_RECORDING": "Iniciar grabación",
|
||||
"STOP_RECORDING": "Detener grabación",
|
||||
|
@ -70,7 +72,8 @@
|
|||
"GENERAL": "General",
|
||||
"VIDEO": "Video",
|
||||
"AUDIO": "Audio",
|
||||
"LANGUAGE": "Idioma"
|
||||
"LANGUAGE": "Idioma",
|
||||
"SUBTITLE": "Subtítulos"
|
||||
},
|
||||
"BACKGROUND": {
|
||||
"TITLE": "Efectos de fondo",
|
||||
|
|
|
@ -34,6 +34,8 @@
|
|||
"MORE_OPTIONS": "Plus d'options",
|
||||
"FULLSCREEN": "Plein écran",
|
||||
"EXIT_FULLSCREEN": "Quitter le plein écran",
|
||||
"ENABLE_SUBTITLES": "Activer les sous-titres",
|
||||
"DISABLE_SUBTITLES": "Désactiver les sous-titres",
|
||||
"BACKGROUND": "Effets de fond",
|
||||
"START_RECORDING": "démarrer l'enregistrement",
|
||||
"STOP_RECORDING": "Arrêter l'enregistrement",
|
||||
|
@ -70,7 +72,8 @@
|
|||
"GENERAL": "Général",
|
||||
"VIDEO": "Vidéo",
|
||||
"AUDIO": "l'audio",
|
||||
"LANGUAGE": "Langue"
|
||||
"LANGUAGE": "Langue",
|
||||
"SUBTITLE": "Les sous-titres"
|
||||
},
|
||||
"BACKGROUND": {
|
||||
"TITLE": "Effets de fond",
|
||||
|
|
|
@ -34,6 +34,8 @@
|
|||
"MORE_OPTIONS": "अधिक विकल्प",
|
||||
"FULLSCREEN": "पूर्ण स्क्रीन",
|
||||
"EXIT_FULLSCREEN": "पूर्ण स्क्रीन से बाहर निकलें",
|
||||
"ENABLE_SUBTITLES": "उपशीर्षक सक्षम करें",
|
||||
"DISABLE_SUBTITLES": "उपशीर्षक अक्षम करें",
|
||||
"BACKGROUND": "पृष्ठभूमि प्रभाव",
|
||||
"START_RECORDING": "रिकॉर्डिंग प्रारंभ करें",
|
||||
"STOP_RECORDING": "रिकॉर्डिंग रोकें",
|
||||
|
@ -70,7 +72,8 @@
|
|||
"GENERAL": "सामान्य",
|
||||
"VIDEO": "वीडियो",
|
||||
"AUDIO": "ऑडियो",
|
||||
"LANGUAGE": "भाषा"
|
||||
"LANGUAGE": "भाषा",
|
||||
"SUBTITLE": "उपशीर्षक"
|
||||
},
|
||||
"BACKGROUND": {
|
||||
"TITLE": "पृष्ठभूमि प्रभाव",
|
||||
|
|
|
@ -34,6 +34,8 @@
|
|||
"MORE_OPTIONS": "Altre opzioni",
|
||||
"FULLSCREEN": "Schermo intero",
|
||||
"EXIT_FULLSCREEN": "Esci dallo schermo intero",
|
||||
"ENABLE_SUBTITLES": "Abilita i sottotitoli",
|
||||
"DISABLE_SUBTITLES": "Disabilita i sottotitoli",
|
||||
"BACKGROUND": "Effetti di sfondo",
|
||||
"START_RECORDING": "Avvia registrazione",
|
||||
"STOP_RECORDING": "Interrompi registrazione",
|
||||
|
@ -70,7 +72,8 @@
|
|||
"GENERAL": "Generale",
|
||||
"VIDEO": "video",
|
||||
"AUDIO": "Audio",
|
||||
"LANGUAGE":"Lingua"
|
||||
"LANGUAGE":"Lingua",
|
||||
"SUBTITLE": "Sottotitoli"
|
||||
},
|
||||
"BACKGROUND": {
|
||||
"TITLE": "Effetti di sfondo",
|
||||
|
|
|
@ -34,6 +34,8 @@
|
|||
"MORE_OPTIONS": "その他のオプション",
|
||||
"FULLSCREEN": "フルスクリーン",
|
||||
"EXIT_FULLSCREEN": "フルスクリーンを終了する",
|
||||
"ENABLE_SUBTITLES": "字幕を有効にする",
|
||||
"DISABLE_SUBTITLES": "字幕を無効にする",
|
||||
"BACKGROUND": "背景効果",
|
||||
"START_RECORDING": "録画開始",
|
||||
"STOP_RECORDING": "録画の停止",
|
||||
|
@ -70,7 +72,8 @@
|
|||
"GENERAL": "全般的",
|
||||
"VIDEO": "ビデオ",
|
||||
"AUDIO": "オーディオ",
|
||||
"LANGUAGE":"言語"
|
||||
"LANGUAGE":"言語",
|
||||
"SUBTITLE": "字幕"
|
||||
},
|
||||
"BACKGROUND": {
|
||||
"TITLE": "背景効果",
|
||||
|
|
|
@ -34,6 +34,8 @@
|
|||
"MORE_OPTIONS": "Meer opties",
|
||||
"FULLSCREEN": "Volledig scherm",
|
||||
"EXIT_FULLSCREEN": "Volledig scherm verlaten",
|
||||
"ENABLE_SUBTITLES": "Ondertiteling inschakelen",
|
||||
"DISABLE_SUBTITLES": "Ondertiteling uitschakelen",
|
||||
"BACKGROUND": "Achtergrondeffecten",
|
||||
"START_RECORDING": "Start opname",
|
||||
"STOP_RECORDING": "Stop opname",
|
||||
|
@ -70,7 +72,8 @@
|
|||
"GENERAL": "Algemeen",
|
||||
"VIDEO": "Video",
|
||||
"AUDIO": "Audio",
|
||||
"LANGUAGE":"Taal"
|
||||
"LANGUAGE":"Taal",
|
||||
"SUBTITLE": "Ondertitels"
|
||||
},
|
||||
"BACKGROUND": {
|
||||
"TITLE": "Achtergrondeffecten",
|
||||
|
|
|
@ -34,6 +34,8 @@
|
|||
"MORE_OPTIONS": "Mais opções",
|
||||
"FULLSCREEN": "Tela cheia",
|
||||
"EXIT_FULLSCREEN": "Sair da tela cheia",
|
||||
"ENABLE_SUBTITLES": "Ativar legendas",
|
||||
"DISABLE_SUBTITLES": "Desativar legendas",
|
||||
"BACKGROUND": "Efeitos de fundo",
|
||||
"START_RECORDING": "Iniciar_gravação",
|
||||
"STOP_RECORDING": "Parar de gravar",
|
||||
|
@ -70,7 +72,8 @@
|
|||
"GENERAL": "Em geral",
|
||||
"VIDEO": "Vídeo",
|
||||
"AUDIO": "Áudio",
|
||||
"LANGUAGE":"Linguagem"
|
||||
"LANGUAGE":"Linguagem",
|
||||
"SUBTITLE": "Legendas"
|
||||
},
|
||||
"BACKGROUND": {
|
||||
"TITLE": "Efeitos de fundo",
|
||||
|
|
|
@ -5,4 +5,11 @@ export enum PanelType {
|
|||
ACTIVITIES = 'activities',
|
||||
SETTINGS = 'settings'
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
export enum PanelSettingsOptions {
|
||||
GENERAL = 'general',
|
||||
AUDIO = 'audio',
|
||||
VIDEO = 'video',
|
||||
SUBTITLES = 'subtitles'
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ import { MatMenuModule } from '@angular/material/menu';
|
|||
import { MatListModule } from '@angular/material/list';
|
||||
import { MatDividerModule } from '@angular/material/divider';
|
||||
import { MatExpansionModule } from '@angular/material/expansion';
|
||||
import {MatSlideToggleModule} from '@angular/material/slide-toggle';
|
||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { NgModule } from '@angular/core';
|
||||
|
||||
|
@ -47,6 +48,7 @@ import { NgModule } from '@angular/core';
|
|||
MatDividerModule,
|
||||
MatListModule,
|
||||
MatExpansionModule,
|
||||
MatSlideToggleModule
|
||||
]
|
||||
})
|
||||
export class AppMaterialModule { }
|
||||
|
|
|
@ -58,6 +58,8 @@ import { VideoDevicesComponent } from './components/settings/video-devices/video
|
|||
import { AudioDevicesComponent } from './components/settings/audio-devices/audio-devices.component';
|
||||
import { NicknameInputComponent } from './components/settings/nickname-input/nickname-input.component';
|
||||
import { LangSelectorComponent } from './components/settings/lang-selector/lang-selector.component';
|
||||
import { SubtitlesSettingComponent } from './components/settings/subtitles/subtitles.component';
|
||||
import { SubtitlesComponent } from './components/subtitles/subtitles.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
|
@ -66,6 +68,7 @@ import { LangSelectorComponent } from './components/settings/lang-selector/lang-
|
|||
ChatPanelComponent,
|
||||
SessionComponent,
|
||||
LayoutComponent,
|
||||
SubtitlesComponent,
|
||||
StreamComponent,
|
||||
DialogTemplateComponent,
|
||||
RecordingDialogComponent,
|
||||
|
@ -87,6 +90,7 @@ import { LangSelectorComponent } from './components/settings/lang-selector/lang-
|
|||
AudioDevicesComponent,
|
||||
NicknameInputComponent,
|
||||
LangSelectorComponent,
|
||||
SubtitlesSettingComponent,
|
||||
BackgroundEffectsPanelComponent,
|
||||
SettingsPanelComponent,
|
||||
ActivitiesPanelComponent,
|
||||
|
|
|
@ -28,6 +28,9 @@ export class OpenViduAngularConfigService {
|
|||
fullscreenButton = <BehaviorSubject<boolean>>new BehaviorSubject(true);
|
||||
fullscreenButtonObs: Observable<boolean>;
|
||||
|
||||
subtitlesButton = <BehaviorSubject<boolean>>new BehaviorSubject(true);
|
||||
subtitlesButtonObs: Observable<boolean>;
|
||||
|
||||
toolbarSettingsButton = <BehaviorSubject<boolean>>new BehaviorSubject(true);
|
||||
toolbarSettingsButtonObs: Observable<boolean>;
|
||||
|
||||
|
@ -92,6 +95,7 @@ export class OpenViduAngularConfigService {
|
|||
this.displayLogoObs = this.displayLogo.asObservable();
|
||||
this.recordingButtonObs = this.recordingButton.asObservable();
|
||||
this.toolbarSettingsButtonObs = this.toolbarSettingsButton.asObservable();
|
||||
this.subtitlesButtonObs = this.subtitlesButton.asObservable();
|
||||
//Stream observables
|
||||
this.displayParticipantNameObs = this.displayParticipantName.asObservable();
|
||||
this.displayAudioDetectionObs = this.displayAudioDetection.asObservable();
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
import { BehaviorSubject, Observable } from 'rxjs';
|
||||
import { LayoutClass, OpenViduLayout, OpenViduLayoutOptions } from '../../models/layout.model';
|
||||
import { LayoutAlignment, LayoutClass, OpenViduLayout, OpenViduLayoutOptions } from '../../models/layout.model';
|
||||
import { DocumentService } from '../document/document.service';
|
||||
|
||||
/**
|
||||
|
@ -10,13 +10,19 @@ import { DocumentService } from '../document/document.service';
|
|||
providedIn: 'root'
|
||||
})
|
||||
export class LayoutService {
|
||||
|
||||
layoutContainer: HTMLElement | null = null;
|
||||
layoutWidthObs: Observable<number>;
|
||||
private _layoutWidthObs: BehaviorSubject<number> = new BehaviorSubject(0);
|
||||
subtitlesTogglingObs: Observable<boolean>;
|
||||
private layoutWidth: BehaviorSubject<number> = new BehaviorSubject(0);
|
||||
private openviduLayout: OpenViduLayout;
|
||||
private openviduLayoutOptions: OpenViduLayoutOptions;
|
||||
private subtitlesToggling: BehaviorSubject<boolean> = new BehaviorSubject(false);
|
||||
|
||||
|
||||
constructor(private documentService: DocumentService) {
|
||||
this.layoutWidthObs = this._layoutWidthObs.asObservable();
|
||||
this.layoutWidthObs = this.layoutWidth.asObservable();
|
||||
this.subtitlesTogglingObs = this.subtitlesToggling.asObservable();
|
||||
}
|
||||
|
||||
initialize(timeout: number = null) {
|
||||
|
@ -34,8 +40,10 @@ export class LayoutService {
|
|||
private _initialize() {
|
||||
this.openviduLayout = new OpenViduLayout();
|
||||
this.openviduLayoutOptions = this.getOptions();
|
||||
const element = document.getElementById('layout');
|
||||
this.openviduLayout.initLayoutContainer(element, this.openviduLayoutOptions);
|
||||
this.layoutContainer = document.getElementById('layout');
|
||||
if(this.layoutContainer){
|
||||
this.openviduLayout.initLayoutContainer(this.layoutContainer, this.openviduLayoutOptions);
|
||||
}
|
||||
}
|
||||
|
||||
private getOptions(): OpenViduLayoutOptions {
|
||||
|
@ -46,20 +54,37 @@ export class LayoutService {
|
|||
and minRatio and maxRatio are ignored (default false) */,
|
||||
bigClass: LayoutClass.BIG_ELEMENT, // The class to add to elements that should be sized bigger
|
||||
smallClass: LayoutClass.SMALL_ELEMENT,
|
||||
ignoredClass: LayoutClass.IGNORED_ELEMENT,
|
||||
bigPercentage: 0.8, // The maximum percentage of space the big ones should take up
|
||||
minBigPercentage: 0, // If this is set then it will scale down the big space if there is left over whitespace down to this minimum size
|
||||
bigFixedRatio: false, // fixedRatio for the big ones
|
||||
bigMaxRatio: 9 / 16, // The narrowest ratio to use for the big elements (default 2x3)
|
||||
bigMinRatio: 9 / 16, // The widest ratio to use for the big elements (default 16x9)
|
||||
bigFirst: true, // Whether to place the big one in the top left (true) or bottom right
|
||||
animate: true // Whether you want to animate the transitions. Deprecated property, to disable it remove the transaction property on OT_publisher css class
|
||||
animate: true, // Whether you want to animate the transitions. Deprecated property, to disable it remove the transaction property on OT_publisher css class
|
||||
alignItems: LayoutAlignment.CENTER,
|
||||
bigAlignItems: LayoutAlignment.CENTER,
|
||||
smallAlignItems: LayoutAlignment.CENTER,
|
||||
maxWidth: Infinity, // The maximum width of the elements
|
||||
maxHeight: Infinity, // The maximum height of the elements
|
||||
smallMaxWidth: Infinity,
|
||||
smallMaxHeight: Infinity,
|
||||
bigMaxWidth: Infinity,
|
||||
bigMaxHeight: Infinity,
|
||||
scaleLastRow: true,
|
||||
bigScaleLastRow: true
|
||||
};
|
||||
return options;
|
||||
}
|
||||
|
||||
toggleSubtitles() {
|
||||
this.subtitlesToggling.next(!this.subtitlesToggling.getValue());
|
||||
}
|
||||
|
||||
update(timeout: number = null) {
|
||||
const updateAux = () => {
|
||||
if (!!this.openviduLayout) {
|
||||
this.openviduLayout.updateLayout();
|
||||
this.openviduLayout.updateLayout(this.layoutContainer, this.openviduLayoutOptions);
|
||||
this.sendLayoutWidthEvent();
|
||||
}
|
||||
};
|
||||
|
@ -84,7 +109,7 @@ export class LayoutService {
|
|||
LayoutClass.SIDENAV_CONTAINER
|
||||
);
|
||||
if (sidenavLayoutElement && sidenavLayoutElement.clientWidth) {
|
||||
this._layoutWidthObs.next(sidenavLayoutElement.clientWidth);
|
||||
this.layoutWidth.next(sidenavLayoutElement.clientWidth);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
import { BehaviorSubject, Observable } from 'rxjs';
|
||||
import { ILogger } from '../../models/logger.model';
|
||||
import { PanelType } from '../../models/panel.model';
|
||||
import { PanelSettingsOptions, PanelType } from '../../models/panel.model';
|
||||
import { LoggerService } from '../logger/logger.service';
|
||||
|
||||
export interface PanelEvent {
|
||||
|
@ -38,7 +38,7 @@ export class PanelService {
|
|||
* Open or close the panel type received. Calling this method with the panel opened and the same type panel, will close the panel.
|
||||
* If the type is differente, it will switch to the properly panel.
|
||||
*/
|
||||
togglePanel(type: PanelType | string, expand?: string) {
|
||||
togglePanel(type: PanelType | string, expand?: PanelSettingsOptions | string) {
|
||||
let nextOpenedValue: boolean = false;
|
||||
if (this.panelMap.has(type)) {
|
||||
this.log.d(`Toggling ${type} menu`);
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
[toolbarParticipantsPanelButton]="_toolbarParticipantsPanelButton"
|
||||
[toolbarDisplayLogo]="_toolbarDisplayLogo"
|
||||
[toolbarDisplaySessionName]="_toolbarDisplaySessionName"
|
||||
[toolbarSubtitlesButton]="_toolbarSubtitlesButton"
|
||||
[streamDisplayParticipantName]="_streamDisplayParticipantName"
|
||||
[streamDisplayAudioDetection]="_streamDisplayAudioDetection"
|
||||
[streamSettingsButton]="_streamSettingsButton"
|
||||
|
|
|
@ -79,6 +79,10 @@ export class OpenviduWebComponentComponent implements OnInit {
|
|||
* @internal
|
||||
*/
|
||||
_toolbarDisplaySessionName: boolean = true;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
_toolbarSubtitlesButton: boolean = true;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
|
@ -330,6 +334,20 @@ export class OpenviduWebComponentComponent implements OnInit {
|
|||
@Input() set toolbarDisplaySessionName(value: string | boolean) {
|
||||
this._toolbarDisplaySessionName = this.castToBoolean(value);
|
||||
}
|
||||
/**
|
||||
* The **toolbarDisplaySessionName** attribute allows show/hide the session name.
|
||||
*
|
||||
* Default: `true`
|
||||
*
|
||||
* <div class="warn-container">
|
||||
* <span>WARNING</span>: If you want to use this parameter to OpenVidu Web Component statically, you have to replace the <strong>camelCase</strong> with a <strong>hyphen between words</strong>.</div>
|
||||
*
|
||||
* @example
|
||||
* <openvidu-webcomponent toolbar-display-session-name="false"></openvidu-webcomponent>
|
||||
*/
|
||||
@Input() set toolbarSubtitlesButton(value: string | boolean) {
|
||||
this._toolbarSubtitlesButton = this.castToBoolean(value);
|
||||
}
|
||||
/**
|
||||
* The **streamDisplayParticipantName** attribute allows show/hide the participants name in stream component.
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue