openvidu-components: Allowed custom captions lang options

pull/772/head
csantosm 2022-11-23 23:57:58 +01:00 committed by Carlos Santos
parent c0d8f24533
commit 370b3af37e
10 changed files with 388 additions and 185 deletions

View File

@ -16,6 +16,10 @@ export class OpenViduComponentsPO {
); );
} }
async getNumberOfElements(selector: string){
return (await this.browser.findElements(By.css(selector))).length;
}
async isPresent(selector: string): Promise<boolean> { async isPresent(selector: string): Promise<boolean> {
const elements = await this.browser.findElements(By.css(selector)); const elements = await this.browser.findElements(By.css(selector));
return elements.length > 0; return elements.length > 0;

View File

@ -1,7 +1,7 @@
var MINIMAL; var MINIMAL;
var LANG; var LANG;
var CAPTIONS_LANG; var CAPTIONS_LANG;
var CUSTOM_CAPTIONS_LANG_OPTIONS;
var PREJOIN; var PREJOIN;
var VIDEO_MUTED; var VIDEO_MUTED;
var AUDIO_MUTED; var AUDIO_MUTED;
@ -30,43 +30,54 @@ var SESSION_NAME;
var PARTICIPANT_NAME; var PARTICIPANT_NAME;
$(document).ready(() => { $(document).ready(() => {
var url = new URL(window.location.href); var url = new URL(window.location.href);
SINGLE_TOKEN = url.searchParams.get("singleToken") === null ? false : url.searchParams.get("singleToken") === 'true'; SINGLE_TOKEN = url.searchParams.get('singleToken') === null ? false : url.searchParams.get('singleToken') === 'true';
// Directives // Directives
MINIMAL = url.searchParams.get("minimal") === null ? false : url.searchParams.get("minimal") === 'true'; MINIMAL = url.searchParams.get('minimal') === null ? false : url.searchParams.get('minimal') === 'true';
LANG = url.searchParams.get("lang") || 'en'; LANG = url.searchParams.get('lang') || 'en';
CAPTIONS_LANG = url.searchParams.get("captionsLang") || 'en-US'; CAPTIONS_LANG = url.searchParams.get('captionsLang') || 'en-US';
PARTICIPANT_NAME = url.searchParams.get("participantName") || 'TEST_USER'; CUSTOM_CAPTIONS_LANG_OPTIONS =
PREJOIN = url.searchParams.get("prejoin") === null ? true : url.searchParams.get("prejoin") === 'true'; url.searchParams.get('captionsLangOptions') === null ? false : url.searchParams.get('captionsLangOptions') === 'true';
VIDEO_MUTED = url.searchParams.get("videoMuted") === null ? false : url.searchParams.get("videoMuted") === 'true'; PARTICIPANT_NAME = url.searchParams.get('participantName') || 'TEST_USER';
AUDIO_MUTED = url.searchParams.get("audioMuted") === null ? false : url.searchParams.get("audioMuted") === 'true'; PREJOIN = url.searchParams.get('prejoin') === null ? true : url.searchParams.get('prejoin') === 'true';
SCREENSHARE_BUTTON = url.searchParams.get("screenshareBtn") === null ? true : url.searchParams.get("screenshareBtn") === 'true'; VIDEO_MUTED = url.searchParams.get('videoMuted') === null ? false : url.searchParams.get('videoMuted') === 'true';
RECORDING_BUTTON = url.searchParams.get("recordingBtn") === null ? true : url.searchParams.get("recordingBtn") === 'true'; AUDIO_MUTED = url.searchParams.get('audioMuted') === null ? false : url.searchParams.get('audioMuted') === 'true';
FULLSCREEN_BUTTON = url.searchParams.get("fullscreenBtn") === null ? true : url.searchParams.get("fullscreenBtn") === 'true'; SCREENSHARE_BUTTON = url.searchParams.get('screenshareBtn') === null ? true : url.searchParams.get('screenshareBtn') === 'true';
TOOLBAR_SETTINGS_BUTTON = url.searchParams.get("toolbarSettingsBtn") === null ? true : url.searchParams.get("toolbarSettingsBtn") === 'true'; RECORDING_BUTTON = url.searchParams.get('recordingBtn') === null ? true : url.searchParams.get('recordingBtn') === 'true';
CAPTIONS_BUTTON = url.searchParams.get("toolbarCaptionsBtn") === null ? true : url.searchParams.get("toolbarCaptionsBtn") === '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';
CAPTIONS_BUTTON = url.searchParams.get('toolbarCaptionsBtn') === null ? true : url.searchParams.get('toolbarCaptionsBtn') === 'true';
LEAVE_BUTTON = url.searchParams.get("leaveBtn") === null ? true : url.searchParams.get("leaveBtn") === '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'; ACTIVITIES_PANEL_BUTTON =
CHAT_PANEL_BUTTON = url.searchParams.get("chatPanelBtn") === null ? true : url.searchParams.get("chatPanelBtn") === 'true'; url.searchParams.get('activitiesPanelBtn') === null ? true : url.searchParams.get('activitiesPanelBtn') === 'true';
PARTICIPANTS_PANEL_BUTTON = url.searchParams.get("participantsPanelBtn") === null ? true : url.searchParams.get("participantsPanelBtn") === 'true'; CHAT_PANEL_BUTTON = url.searchParams.get('chatPanelBtn') === null ? true : url.searchParams.get('chatPanelBtn') === 'true';
ACTIVITIES_RECORDING_ACTIVITY = url.searchParams.get("activitiesPanelRecordingActivity") === null ? true : url.searchParams.get("activitiesPanelRecordingActivity") === 'true'; PARTICIPANTS_PANEL_BUTTON =
if(url.searchParams.get("recordingError") !== null) { url.searchParams.get('participantsPanelBtn') === null ? true : url.searchParams.get('participantsPanelBtn') === 'true';
RECORDING_ERROR = url.searchParams.get("recordingError"); ACTIVITIES_RECORDING_ACTIVITY =
url.searchParams.get('activitiesPanelRecordingActivity') === null
? true
: url.searchParams.get('activitiesPanelRecordingActivity') === 'true';
if (url.searchParams.get('recordingError') !== null) {
RECORDING_ERROR = url.searchParams.get('recordingError');
} }
DISPLAY_LOGO = url.searchParams.get("displayLogo") === null ? true : url.searchParams.get("displayLogo") === 'true'; DISPLAY_LOGO = url.searchParams.get('displayLogo') === null ? true : url.searchParams.get('displayLogo') === 'true';
DISPLAY_SESSION_NAME = url.searchParams.get("displaySessionName") === null ? true : url.searchParams.get("displaySessionName") === 'true'; DISPLAY_SESSION_NAME =
DISPLAY_PARTICIPANT_NAME = url.searchParams.get("displayParticipantName") === null ? true : url.searchParams.get("displayParticipantName") === 'true'; url.searchParams.get('displaySessionName') === null ? true : url.searchParams.get('displaySessionName') === 'true';
DISPLAY_AUDIO_DETECTION = url.searchParams.get("displayAudioDetection") === null ? true : url.searchParams.get("displayAudioDetection") === 'true'; DISPLAY_PARTICIPANT_NAME =
SETTINGS_BUTTON = url.searchParams.get("settingsBtn") === null ? true : url.searchParams.get("settingsBtn") === 'true'; url.searchParams.get('displayParticipantName') === null ? true : url.searchParams.get('displayParticipantName') === 'true';
PARTICIPANT_MUTE_BUTTON = url.searchParams.get("participantMuteBtn") === null ? true : url.searchParams.get("participantMuteBtn") === 'true'; DISPLAY_AUDIO_DETECTION =
url.searchParams.get('displayAudioDetection') === null ? true : url.searchParams.get('displayAudioDetection') === 'true';
SETTINGS_BUTTON = url.searchParams.get('settingsBtn') === null ? true : url.searchParams.get('settingsBtn') === 'true';
PARTICIPANT_MUTE_BUTTON =
url.searchParams.get('participantMuteBtn') === null ? true : url.searchParams.get('participantMuteBtn') === 'true';
SESSION_NAME =
SESSION_NAME = url.searchParams.get("sessionName") === null ? `E2ESession${Math.floor(Date.now())}` : url.searchParams.get("sessionName"); url.searchParams.get('sessionName') === null ? `E2ESession${Math.floor(Date.now())}` : url.searchParams.get('sessionName');
var webComponent = document.querySelector('openvidu-webcomponent'); var webComponent = document.querySelector('openvidu-webcomponent');
@ -75,16 +86,19 @@ $(document).ready(() => {
webComponent.addEventListener('onToolbarCameraButtonClicked', (event) => appendElement('onToolbarCameraButtonClicked')); webComponent.addEventListener('onToolbarCameraButtonClicked', (event) => appendElement('onToolbarCameraButtonClicked'));
webComponent.addEventListener('onToolbarMicrophoneButtonClicked', (event) => appendElement('onToolbarMicrophoneButtonClicked')); webComponent.addEventListener('onToolbarMicrophoneButtonClicked', (event) => appendElement('onToolbarMicrophoneButtonClicked'));
webComponent.addEventListener('onToolbarScreenshareButtonClicked', (event) => appendElement('onToolbarScreenshareButtonClicked')); webComponent.addEventListener('onToolbarScreenshareButtonClicked', (event) => appendElement('onToolbarScreenshareButtonClicked'));
webComponent.addEventListener('onToolbarParticipantsPanelButtonClicked', (event) => appendElement('onToolbarParticipantsPanelButtonClicked')); webComponent.addEventListener('onToolbarParticipantsPanelButtonClicked', (event) =>
appendElement('onToolbarParticipantsPanelButtonClicked')
);
webComponent.addEventListener('onToolbarChatPanelButtonClicked', (event) => appendElement('onToolbarChatPanelButtonClicked')); webComponent.addEventListener('onToolbarChatPanelButtonClicked', (event) => appendElement('onToolbarChatPanelButtonClicked'));
webComponent.addEventListener('onToolbarActivitiesPanelButtonClicked', (event) => appendElement('onToolbarActivitiesPanelButtonClicked')); webComponent.addEventListener('onToolbarActivitiesPanelButtonClicked', (event) =>
appendElement('onToolbarActivitiesPanelButtonClicked')
);
webComponent.addEventListener('onToolbarFullscreenButtonClicked', (event) => appendElement('onToolbarFullscreenButtonClicked')); webComponent.addEventListener('onToolbarFullscreenButtonClicked', (event) => appendElement('onToolbarFullscreenButtonClicked'));
webComponent.addEventListener('onToolbarStartRecordingClicked', async (event) => { webComponent.addEventListener('onToolbarStartRecordingClicked', async (event) => {
appendElement('onToolbarStartRecordingClicked'); appendElement('onToolbarStartRecordingClicked');
// Can't test the recording // Can't test the recording
// RECORDING_ID = await startRecording(SESSION_NAME); // RECORDING_ID = await startRecording(SESSION_NAME);
}); });
// Can't test the recording // Can't test the recording
// webComponent.addEventListener('onToolbarStopRecordingClicked', async (event) => { // webComponent.addEventListener('onToolbarStopRecordingClicked', async (event) => {
@ -103,13 +117,14 @@ $(document).ready(() => {
// await stopRecording(RECORDING_ID); // await stopRecording(RECORDING_ID);
// }); // });
webComponent.addEventListener('onActivitiesPanelDeleteRecordingClicked', (event) => appendElement('onActivitiesPanelDeleteRecordingClicked')); webComponent.addEventListener('onActivitiesPanelDeleteRecordingClicked', (event) =>
appendElement('onActivitiesPanelDeleteRecordingClicked')
);
webComponent.addEventListener('onSessionCreated', (event) => { webComponent.addEventListener('onSessionCreated', (event) => {
var session = event.detail; var session = event.detail;
appendElement('onSessionCreated'); appendElement('onSessionCreated');
// You can see the session documentation here // You can see the session documentation here
// https://docs.openvidu.io/en/stable/api/openvidu-browser/classes/session.html // https://docs.openvidu.io/en/stable/api/openvidu-browser/classes/session.html
@ -127,7 +142,6 @@ $(document).ready(() => {
webComponent.addEventListener('onParticipantCreated', (event) => { webComponent.addEventListener('onParticipantCreated', (event) => {
var participant = event.detail; var participant = event.detail;
appendElement(`${participant.nickname}-onParticipantCreated`); appendElement(`${participant.nickname}-onParticipantCreated`);
}); });
// webComponent.addEventListener('error', (event) => { // webComponent.addEventListener('error', (event) => {
@ -137,12 +151,11 @@ $(document).ready(() => {
joinSession(SESSION_NAME, PARTICIPANT_NAME); joinSession(SESSION_NAME, PARTICIPANT_NAME);
}); });
function appendElement(id) { function appendElement(id) {
var eventsDiv = document.getElementById('events'); var eventsDiv = document.getElementById('events');
var element = document.createElement('div'); var element = document.createElement('div');
element.setAttribute("id", id); element.setAttribute('id', id);
element.setAttribute("style", "height: 1px;"); element.setAttribute('style', 'height: 1px;');
eventsDiv.appendChild(element); eventsDiv.appendChild(element);
} }
@ -150,16 +163,17 @@ async function joinSession(sessionName, participantName) {
var webComponent = document.querySelector('openvidu-webcomponent'); var webComponent = document.querySelector('openvidu-webcomponent');
var tokens; var tokens;
if (SINGLE_TOKEN) { if (SINGLE_TOKEN) {
tokens = await getToken(sessionName); tokens = await getToken(sessionName);
} else { } else {
tokens = { webcam: await getToken(sessionName), screen: await getToken(sessionName) }; tokens = { webcam: await getToken(sessionName), screen: await getToken(sessionName) };
} }
webComponent.minimal = MINIMAL; webComponent.minimal = MINIMAL;
webComponent.lang = LANG; webComponent.lang = LANG;
webComponent.captionsLang = CAPTIONS_LANG; webComponent.captionsLang = CAPTIONS_LANG;
if (CUSTOM_CAPTIONS_LANG_OPTIONS) {
webComponent.captionsLangOptions = [{ name: 'Esp', ISO: 'es-ES' }, { name: 'Eng', ISO: 'en-US' }];
}
webComponent.prejoin = PREJOIN; webComponent.prejoin = PREJOIN;
webComponent.videoMuted = VIDEO_MUTED; webComponent.videoMuted = VIDEO_MUTED;
webComponent.audioMuted = AUDIO_MUTED; webComponent.audioMuted = AUDIO_MUTED;
@ -200,14 +214,15 @@ async function joinSession(sessionName, participantName) {
* 3) Configure OpenVidu Web Component in your client side with the token * 3) Configure OpenVidu Web Component in your client side with the token
*/ */
var OPENVIDU_SERVER_URL = "http://localhost:4443" ; var OPENVIDU_SERVER_URL = 'http://localhost:4443';
var OPENVIDU_SERVER_SECRET = 'MY_SECRET'; var OPENVIDU_SERVER_SECRET = 'MY_SECRET';
function getToken(sessionName) { function getToken(sessionName) {
return createSession(sessionName).then((sessionId) => createToken(sessionId)); return createSession(sessionName).then((sessionId) => createToken(sessionId));
} }
function createSession(sessionName) { // See https://docs.openvidu.io/en/stable/reference-docs/REST-API/#post-apisessions function createSession(sessionName) {
// See https://docs.openvidu.io/en/stable/reference-docs/REST-API/#post-apisessions
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
$.ajax({ $.ajax({
type: 'POST', type: 'POST',
@ -215,7 +230,7 @@ function createSession(sessionName) { // See https://docs.openvidu.io/en/stable/
data: JSON.stringify({ customSessionId: sessionName }), data: JSON.stringify({ customSessionId: sessionName }),
headers: { headers: {
Authorization: 'Basic ' + btoa('OPENVIDUAPP:' + OPENVIDU_SERVER_SECRET), Authorization: 'Basic ' + btoa('OPENVIDUAPP:' + OPENVIDU_SERVER_SECRET),
'Content-Type': 'application/json', 'Content-Type': 'application/json'
}, },
success: (response) => resolve(response.id), success: (response) => resolve(response.id),
error: (error) => { error: (error) => {
@ -230,13 +245,13 @@ function createSession(sessionName) { // See https://docs.openvidu.io/en/stable/
'"\n\nClick OK to navigate and accept it. ' + '"\n\nClick OK to navigate and accept it. ' +
'If no certificate warning is shown, then check that your OpenVidu Server is up and running at "' + 'If no certificate warning is shown, then check that your OpenVidu Server is up and running at "' +
OPENVIDU_SERVER_URL + OPENVIDU_SERVER_URL +
'"', '"'
) )
) { ) {
location.assign(OPENVIDU_SERVER_URL + '/openvidu/accept-certificate'); location.assign(OPENVIDU_SERVER_URL + '/openvidu/accept-certificate');
} }
} }
}, }
}); });
}); });
} }
@ -250,12 +265,12 @@ function createToken(sessionId) {
data: JSON.stringify({ session: sessionId, role: 'MODERATOR' }), data: JSON.stringify({ session: sessionId, role: 'MODERATOR' }),
headers: { headers: {
Authorization: 'Basic ' + btoa('OPENVIDUAPP:' + OPENVIDU_SERVER_SECRET), Authorization: 'Basic ' + btoa('OPENVIDUAPP:' + OPENVIDU_SERVER_SECRET),
'Content-Type': 'application/json', 'Content-Type': 'application/json'
}, },
success: (response) => { success: (response) => {
resolve(response.token); resolve(response.token);
}, },
error: (error) => reject(error), error: (error) => reject(error)
}); });
}); });
} }

View File

@ -149,7 +149,54 @@ describe('Testing API Directives', () => {
// expect(await utils.isPresent('.captions-container')).to.be.true; // expect(await utils.isPresent('.captions-container')).to.be.true;
// const element = await utils.waitForElement('.lang-button'); // const element = await utils.waitForElement('.lang-button');
// expect(await element.getText()).equal('Españolexpand_more') // expect(await element.getText()).equal('Españolexpand_more');
// });
/**
* TODO:
* This test is only available with OpenVidu PRO
*/
// it('should override the CAPTIONS LANG OPTIONS', async () => {
// await browser.get(`${url}?prejoin=false&captionsLangOptions=true`);
// await utils.checkSessionIsPresent();
// // Checking if toolbar is present
// await utils.checkToolbarIsPresent();
// // Open more options menu
// await utils.clickOn('#more-options-btn');
// await browser.sleep(500);
// // Checking if button panel is present
// await utils.waitForElement('.mat-menu-content');
// expect(await utils.isPresent('.mat-menu-content')).to.be.true;
// // Checking if captions button is present
// await utils.waitForElement('#captions-btn');
// expect(await utils.isPresent('#captions-btn')).to.be.true;
// await utils.clickOn('#captions-btn');
// await utils.waitForElement('.captions-container');
// await utils.waitForElement('#caption-settings-btn');
// await utils.clickOn('#caption-settings-btn');
// await browser.sleep(500);
// await utils.waitForElement('.settings-container');
// expect(await utils.isPresent('.settings-container')).to.be.true;
// await utils.waitForElement('ov-captions-settings');
// expect(await utils.isPresent('.captions-container')).to.be.true;
// const element = await utils.waitForElement('.lang-button');
// expect(await element.getText()).equal('Espexpand_more');
// await element.click();
// expect(await utils.getNumberOfElements('.mat-menu-item')).equals(2);
// }); // });
it('should show the PREJOIN page', async () => { it('should show the PREJOIN page', async () => {

View File

@ -56,6 +56,7 @@ import { TranslateService } from '../../services/translate/translate.service';
* | **minimal** | `boolean` | {@link MinimalDirective} | * | **minimal** | `boolean` | {@link MinimalDirective} |
* | **lang** | `string` | {@link LangDirective} | * | **lang** | `string` | {@link LangDirective} |
* | **captionsLang** | `string` | {@link CaptionsLangDirective} | * | **captionsLang** | `string` | {@link CaptionsLangDirective} |
* | **captionsLangOprions** | `CaptionsLangOption []` | {@link CaptionsLangOptionsDirective} |
* | **prejoin** | `boolean` | {@link PrejoinDirective} | * | **prejoin** | `boolean` | {@link PrejoinDirective} |
* | **participantName** | `string` | {@link ParticipantNameDirective} | * | **participantName** | `string` | {@link ParticipantNameDirective} |
* | **videoMuted** | `boolean` | {@link VideoMutedDirective} | * | **videoMuted** | `boolean` | {@link VideoMutedDirective} |
@ -302,7 +303,6 @@ export class VideoconferenceComponent implements OnInit, OnDestroy, AfterViewIni
} }
this.start(); this.start();
} }
/** /**

View File

@ -25,9 +25,7 @@ import {
} from './toolbar.directive'; } from './toolbar.directive';
import { import {
AudioMutedDirective, AudioMutedDirective,
CaptionsLangDirective, CaptionsLangDirective, CaptionsLangOptionsDirective, LangDirective, MinimalDirective,
LangDirective,
MinimalDirective,
ParticipantNameDirective, ParticipantNameDirective,
PrejoinDirective, PrejoinDirective,
VideoMutedDirective VideoMutedDirective
@ -37,6 +35,7 @@ import {
declarations: [ declarations: [
MinimalDirective, MinimalDirective,
LangDirective, LangDirective,
CaptionsLangOptionsDirective,
CaptionsLangDirective, CaptionsLangDirective,
PrejoinDirective, PrejoinDirective,
VideoMutedDirective, VideoMutedDirective,
@ -68,6 +67,7 @@ import {
exports: [ exports: [
MinimalDirective, MinimalDirective,
LangDirective, LangDirective,
CaptionsLangOptionsDirective,
CaptionsLangDirective, CaptionsLangDirective,
PrejoinDirective, PrejoinDirective,
VideoMutedDirective, VideoMutedDirective,

View File

@ -1,4 +1,5 @@
import { Directive, ElementRef, Input, OnDestroy, OnInit } from '@angular/core'; import { Directive, ElementRef, Input, OnDestroy, OnInit } from '@angular/core';
import { CaptionsLangOption } from '../../models/caption.model';
import { CaptionService } from '../../services/caption/caption.service'; import { CaptionService } from '../../services/caption/caption.service';
import { OpenViduAngularConfigService } from '../../services/config/openvidu-angular.config.service'; import { OpenViduAngularConfigService } from '../../services/config/openvidu-angular.config.service';
import { TranslateService } from '../../services/translate/translate.service'; import { TranslateService } from '../../services/translate/translate.service';
@ -116,7 +117,7 @@ export class LangDirective implements OnDestroy {
} }
/** /**
* The **captions-lang** directive allows specify the language of room's members * The **captionsLang** directive allows specify the deafult language that OpenVidu will try to recognise.
* *
* It is only available for {@link VideoconferenceComponent}. * It is only available for {@link VideoconferenceComponent}.
* *
@ -178,6 +179,67 @@ export class CaptionsLangDirective implements OnDestroy {
} }
} }
/**
* The **captionsLangOptions** directive allows to set the language options for the captions.
* It will override the languages provided by default.
* This propety is an array of objects which must comply with the {@link CaptionsLangOption} interface.
*
* It is only available for {@link VideoconferenceComponent}.
*
* Default: ```
* [
* { name: 'English', ISO: 'en-US' },
* { name: 'Español', ISO: 'es-ES' },
* { name: 'Deutsch', ISO: 'de-DE' },
* { name: 'Français', ISO: 'fr-FR' },
* { name: '中国', ISO: 'zh-CN' },
* { name: 'हिन्दी', ISO: 'hi-IN' },
* { name: 'Italiano', ISO: 'it-IT' },
* { name: 'やまと', ISO: 'jp-JP' },
* { name: 'Português', ISO: 'pt-PT' }
* ]```
*
* @example
* <ov-videoconference [captionsLangOptions]="[{name:'Spanish', ISO: 'es-ES'}]"></ov-videoconference>
*/
@Directive({
selector: 'ov-videoconference[captionsLangOptions]'
})
export class CaptionsLangOptionsDirective implements OnDestroy {
/**
* @ignore
*/
@Input() set captionsLangOptions(value: CaptionsLangOption []) {
this.update(value);
}
/**
* @ignore
*/
constructor(public elementRef: ElementRef, private captionService: CaptionService) {}
/**
* @ignore
*/
ngOnDestroy(): void {
this.clear();
}
/**
* @ignore
*/
clear() {
this.update(undefined);
}
/**
* @ignore
*/
update(value: CaptionsLangOption [] | undefined) {
this.captionService.setLanguageOptions(value);
}
}
/** /**
* The **participantName** directive sets the participant name. It can be useful for aplications which doesn't need the prejoin page. * The **participantName** directive sets the participant name. It can be useful for aplications which doesn't need the prejoin page.

View File

@ -1,4 +1,7 @@
/**
* @internal
*/
export interface CaptionModel { export interface CaptionModel {
connectionId: string; connectionId: string;
@ -8,3 +11,10 @@ export interface CaptionModel {
text: string; text: string;
} }
export interface CaptionsLangOption {
name: string;
ISO: string;
}

View File

@ -1,5 +1,6 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { Observable, Subject } from 'rxjs'; import { Observable, Subject } from 'rxjs';
import { CaptionsLangOption } from '../../models/caption.model';
import { StorageService } from '../storage/storage.service'; import { StorageService } from '../storage/storage.service';
/** /**
@ -9,7 +10,7 @@ import { StorageService } from '../storage/storage.service';
providedIn: 'root' providedIn: 'root'
}) })
export class CaptionService { export class CaptionService {
private langs = [ private langs: CaptionsLangOption [] = [
{ name: 'English', ISO: 'en-US' }, { name: 'English', ISO: 'en-US' },
{ name: 'Español', ISO: 'es-ES' }, { name: 'Español', ISO: 'es-ES' },
{ name: 'Deutsch', ISO: 'de-DE' }, { name: 'Deutsch', ISO: 'de-DE' },
@ -20,20 +21,22 @@ export class CaptionService {
{ name: 'やまと', ISO: 'jp-JP' }, { name: 'やまと', ISO: 'jp-JP' },
{ name: 'Português', ISO: 'pt-PT' } { name: 'Português', ISO: 'pt-PT' }
]; ];
captionLangSelected: { name: string; ISO: string } = { name: 'English', ISO: 'en-US' }; captionLangSelected: { name: string; ISO: string };
captionLangObs: Observable<{ name: string; ISO: string }>; captionLangObs: Observable<{ name: string; ISO: string }>;
private _captionLang: Subject<{ name: string; ISO: string }> = new Subject(); private _captionLang: Subject<{ name: string; ISO: string }> = new Subject();
private captionsEnabled: boolean = false; private captionsEnabled: boolean = false;
constructor(private storageService: StorageService) { constructor(private storageService: StorageService) {
const iso = this.storageService.getCaptionsLang(); this.updateLangSelected();
const lang = this.langs.find((lang) => lang.ISO === iso);
if (iso && lang) {
this.captionLangSelected = lang;
} else {
this.captionLangSelected = this.langs[0];
}
this.captionLangObs = this._captionLang.asObservable(); this.captionLangObs = this._captionLang.asObservable();
}
setLanguageOptions(options: CaptionsLangOption [] | undefined) {
if(options && options.length > 0) {
this.langs = options;
this.updateLangSelected();
}
} }
setCaptionsEnabled(value: boolean) { setCaptionsEnabled(value: boolean) {
@ -60,4 +63,14 @@ export class CaptionService {
getCaptionLanguages(): { name: string; ISO: string }[] { getCaptionLanguages(): { name: string; ISO: string }[] {
return this.langs; return this.langs;
} }
private updateLangSelected(): void {
const iso = this.storageService.getCaptionsLang();
const lang = this.langs.find((lang) => lang.ISO === iso);
if (iso && lang) {
this.captionLangSelected = lang;
} else {
this.captionLangSelected = this.langs[0];
}
}
} }

View File

@ -5,6 +5,7 @@
[minimal]="_minimal" [minimal]="_minimal"
[lang]="_lang" [lang]="_lang"
[captionsLang]="_captionsLang" [captionsLang]="_captionsLang"
[captionsLangOptions]="_captionsLangOptions"
[prejoin]="_prejoin" [prejoin]="_prejoin"
[videoMuted]="_videoMuted" [videoMuted]="_videoMuted"
[audioMuted]="_audioMuted" [audioMuted]="_audioMuted"

View File

@ -1,6 +1,7 @@
import { Component, ElementRef, EventEmitter, Input, OnInit, Output } from '@angular/core'; import { Component, ElementRef, EventEmitter, Input, OnInit, Output } from '@angular/core';
import { OpenViduService, ParticipantAbstractModel, RecordingInfo, TokenModel } from 'openvidu-angular'; import { OpenViduService, ParticipantAbstractModel, RecordingInfo, TokenModel } from 'openvidu-angular';
import { Session } from 'openvidu-browser'; import { Session } from 'openvidu-browser';
import { CaptionsLangOption } from '../../../projects/openvidu-angular/src/lib/models/caption.model';
/** /**
* *
@ -19,15 +20,25 @@ export class OpenviduWebComponentComponent implements OnInit {
* @internal * @internal
*/ */
_minimal: boolean = false; _minimal: boolean = false;
/**
* @internal
*/
/** /**
* @internal * @internal
*/ */
_lang: string = ''; _lang: string = '';
/** /**
* @internal * @internal
*/ */
_captionsLang: string = ''; _captionsLang: string = '';
/**
* @internal
*/
_captionsLangOptions: CaptionsLangOption;
/** /**
* @internal * @internal
*/ */
@ -157,6 +168,30 @@ export class OpenviduWebComponentComponent implements OnInit {
@Input() set captionsLang(value: string) { @Input() set captionsLang(value: string) {
this._captionsLang = value; this._captionsLang = value;
} }
/**
* The captionsLangOptions attribute sets the language options for the captions.
* It will override the languages provided by default.
* This propety is an array of objects which must comply with the {@link CaptionsLangOption} interface.
*
* Default: ```
* [
* { name: 'English', ISO: 'en-US' },
* { name: 'Español', ISO: 'es-ES' },
* { name: 'Deutsch', ISO: 'de-DE' },
* { name: 'Français', ISO: 'fr-FR' },
* { name: '中国', ISO: 'zh-CN' },
* { name: 'हिन्दी', ISO: 'hi-IN' },
* { name: 'Italiano', ISO: 'it-IT' },
* { name: 'やまと', ISO: 'jp-JP' },
* { name: 'Português', ISO: 'pt-PT' }
* ]```
*
* @example
* <openvidu-webcomponent captions-lang-options="[{name:'Spanish', ISO: 'es-ES'}]"></openvidu-webcomponent>
*/
@Input() set captionsLangOptions(value: string | CaptionsLangOption []) {
this._captionsLangOptions = this.castToArray(value);
}
/** /**
* The **participantName** attribute sets the participant name. It can be useful for aplications which doesn't need the prejoin page. * The **participantName** attribute sets the participant name. It can be useful for aplications which doesn't need the prejoin page.
* *
@ -742,4 +777,20 @@ export class OpenviduWebComponentComponent implements OnInit {
); );
} }
} }
private castToArray(value: CaptionsLangOption [] | string) {
if (typeof value === 'string') {
try {
return JSON.parse(value);
} catch (error) {
throw 'Unexpected JSON' + error;
}
} else if (typeof value === 'object' && value.length > 0) {
return value;
} else {
throw new Error(
'Parameter has not a valid type. The parameters must to be string or CaptionsLangOptions [] [{name:string, ISO: string}].'
);
}
}
} }