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,147 +30,161 @@ 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
MINIMAL = url.searchParams.get('minimal') === null ? false : url.searchParams.get('minimal') === 'true';
LANG = url.searchParams.get('lang') || 'en';
CAPTIONS_LANG = url.searchParams.get('captionsLang') || 'en-US';
CUSTOM_CAPTIONS_LANG_OPTIONS =
url.searchParams.get('captionsLangOptions') === null ? false : url.searchParams.get('captionsLangOptions') === 'true';
PARTICIPANT_NAME = url.searchParams.get('participantName') || 'TEST_USER';
PREJOIN = url.searchParams.get('prejoin') === null ? true : url.searchParams.get('prejoin') === 'true';
VIDEO_MUTED = url.searchParams.get('videoMuted') === null ? false : url.searchParams.get('videoMuted') === 'true';
AUDIO_MUTED = url.searchParams.get('audioMuted') === null ? false : url.searchParams.get('audioMuted') === 'true';
SCREENSHARE_BUTTON = url.searchParams.get('screenshareBtn') === null ? true : url.searchParams.get('screenshareBtn') === 'true';
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';
CAPTIONS_BUTTON = url.searchParams.get('toolbarCaptionsBtn') === null ? true : url.searchParams.get('toolbarCaptionsBtn') === 'true';
// Directives LEAVE_BUTTON = url.searchParams.get('leaveBtn') === null ? true : url.searchParams.get('leaveBtn') === 'true';
MINIMAL = url.searchParams.get("minimal") === null ? false : url.searchParams.get("minimal") === 'true'; ACTIVITIES_PANEL_BUTTON =
LANG = url.searchParams.get("lang") || 'en'; url.searchParams.get('activitiesPanelBtn') === null ? true : url.searchParams.get('activitiesPanelBtn') === 'true';
CAPTIONS_LANG = url.searchParams.get("captionsLang") || 'en-US'; CHAT_PANEL_BUTTON = url.searchParams.get('chatPanelBtn') === null ? true : url.searchParams.get('chatPanelBtn') === 'true';
PARTICIPANT_NAME = url.searchParams.get("participantName") || 'TEST_USER'; PARTICIPANTS_PANEL_BUTTON =
PREJOIN = url.searchParams.get("prejoin") === null ? true : url.searchParams.get("prejoin") === 'true'; url.searchParams.get('participantsPanelBtn') === null ? true : url.searchParams.get('participantsPanelBtn') === 'true';
VIDEO_MUTED = url.searchParams.get("videoMuted") === null ? false : url.searchParams.get("videoMuted") === 'true'; ACTIVITIES_RECORDING_ACTIVITY =
AUDIO_MUTED = url.searchParams.get("audioMuted") === null ? false : url.searchParams.get("audioMuted") === 'true'; url.searchParams.get('activitiesPanelRecordingActivity') === null
SCREENSHARE_BUTTON = url.searchParams.get("screenshareBtn") === null ? true : url.searchParams.get("screenshareBtn") === 'true'; ? true
RECORDING_BUTTON = url.searchParams.get("recordingBtn") === null ? true : url.searchParams.get("recordingBtn") === 'true'; : url.searchParams.get('activitiesPanelRecordingActivity') === 'true';
FULLSCREEN_BUTTON = url.searchParams.get("fullscreenBtn") === null ? true : url.searchParams.get("fullscreenBtn") === 'true'; if (url.searchParams.get('recordingError') !== null) {
TOOLBAR_SETTINGS_BUTTON = url.searchParams.get("toolbarSettingsBtn") === null ? true : url.searchParams.get("toolbarSettingsBtn") === 'true'; RECORDING_ERROR = url.searchParams.get('recordingError');
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'; DISPLAY_LOGO = url.searchParams.get('displayLogo') === null ? true : url.searchParams.get('displayLogo') === 'true';
ACTIVITIES_PANEL_BUTTON = url.searchParams.get("activitiesPanelBtn") === null ? true : url.searchParams.get("activitiesPanelBtn") === 'true'; DISPLAY_SESSION_NAME =
CHAT_PANEL_BUTTON = url.searchParams.get("chatPanelBtn") === null ? true : url.searchParams.get("chatPanelBtn") === 'true'; url.searchParams.get('displaySessionName') === null ? true : url.searchParams.get('displaySessionName') === 'true';
PARTICIPANTS_PANEL_BUTTON = url.searchParams.get("participantsPanelBtn") === null ? true : url.searchParams.get("participantsPanelBtn") === 'true'; DISPLAY_PARTICIPANT_NAME =
ACTIVITIES_RECORDING_ACTIVITY = url.searchParams.get("activitiesPanelRecordingActivity") === null ? true : url.searchParams.get("activitiesPanelRecordingActivity") === 'true'; url.searchParams.get('displayParticipantName') === null ? true : url.searchParams.get('displayParticipantName') === 'true';
if(url.searchParams.get("recordingError") !== null) { DISPLAY_AUDIO_DETECTION =
RECORDING_ERROR = url.searchParams.get("recordingError"); 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';
DISPLAY_LOGO = url.searchParams.get("displayLogo") === null ? true : url.searchParams.get("displayLogo") === 'true'; SESSION_NAME =
DISPLAY_SESSION_NAME = url.searchParams.get("displaySessionName") === null ? true : url.searchParams.get("displaySessionName") === 'true'; url.searchParams.get('sessionName') === null ? `E2ESession${Math.floor(Date.now())}` : url.searchParams.get('sessionName');
DISPLAY_PARTICIPANT_NAME = url.searchParams.get("displayParticipantName") === null ? true : url.searchParams.get("displayParticipantName") === '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';
var webComponent = document.querySelector('openvidu-webcomponent');
SESSION_NAME = url.searchParams.get("sessionName") === null ? `E2ESession${Math.floor(Date.now())}` : url.searchParams.get("sessionName"); webComponent.addEventListener('onJoinButtonClicked', (event) => appendElement('onJoinButtonClicked'));
webComponent.addEventListener('onToolbarLeaveButtonClicked', (event) => appendElement('onToolbarLeaveButtonClicked'));
webComponent.addEventListener('onToolbarCameraButtonClicked', (event) => appendElement('onToolbarCameraButtonClicked'));
webComponent.addEventListener('onToolbarMicrophoneButtonClicked', (event) => appendElement('onToolbarMicrophoneButtonClicked'));
webComponent.addEventListener('onToolbarScreenshareButtonClicked', (event) => appendElement('onToolbarScreenshareButtonClicked'));
webComponent.addEventListener('onToolbarParticipantsPanelButtonClicked', (event) =>
appendElement('onToolbarParticipantsPanelButtonClicked')
);
webComponent.addEventListener('onToolbarChatPanelButtonClicked', (event) => appendElement('onToolbarChatPanelButtonClicked'));
webComponent.addEventListener('onToolbarActivitiesPanelButtonClicked', (event) =>
appendElement('onToolbarActivitiesPanelButtonClicked')
);
webComponent.addEventListener('onToolbarFullscreenButtonClicked', (event) => appendElement('onToolbarFullscreenButtonClicked'));
var webComponent = document.querySelector('openvidu-webcomponent'); webComponent.addEventListener('onToolbarStartRecordingClicked', async (event) => {
appendElement('onToolbarStartRecordingClicked');
// Can't test the recording
// RECORDING_ID = await startRecording(SESSION_NAME);
});
// Can't test the recording
// webComponent.addEventListener('onToolbarStopRecordingClicked', async (event) => {
// appendElement('onToolbarStopRecordingClicked');
// await stopRecording(RECORDING_ID);
// });
webComponent.addEventListener('onJoinButtonClicked', (event) => appendElement('onJoinButtonClicked')); webComponent.addEventListener('onActivitiesPanelStartRecordingClicked', async (event) => {
webComponent.addEventListener('onToolbarLeaveButtonClicked', (event) => appendElement('onToolbarLeaveButtonClicked')); appendElement('onActivitiesPanelStartRecordingClicked');
webComponent.addEventListener('onToolbarCameraButtonClicked', (event) => appendElement('onToolbarCameraButtonClicked')); // RECORDING_ID = await startRecording(SESSION_NAME);
webComponent.addEventListener('onToolbarMicrophoneButtonClicked', (event) => appendElement('onToolbarMicrophoneButtonClicked')); });
webComponent.addEventListener('onToolbarScreenshareButtonClicked', (event) => appendElement('onToolbarScreenshareButtonClicked'));
webComponent.addEventListener('onToolbarParticipantsPanelButtonClicked', (event) => appendElement('onToolbarParticipantsPanelButtonClicked'));
webComponent.addEventListener('onToolbarChatPanelButtonClicked', (event) => appendElement('onToolbarChatPanelButtonClicked'));
webComponent.addEventListener('onToolbarActivitiesPanelButtonClicked', (event) => appendElement('onToolbarActivitiesPanelButtonClicked'));
webComponent.addEventListener('onToolbarFullscreenButtonClicked', (event) => appendElement('onToolbarFullscreenButtonClicked'));
webComponent.addEventListener('onToolbarStartRecordingClicked', async (event) => { // Can't test the recording
appendElement('onToolbarStartRecordingClicked'); // webComponent.addEventListener('onActivitiesPanelStopRecordingClicked', async (event) => {
// Can't test the recording // appendElement('onActivitiesPanelStopRecordingClicked');
// RECORDING_ID = await startRecording(SESSION_NAME); // await stopRecording(RECORDING_ID);
// });
}); webComponent.addEventListener('onActivitiesPanelDeleteRecordingClicked', (event) =>
// Can't test the recording appendElement('onActivitiesPanelDeleteRecordingClicked')
// webComponent.addEventListener('onToolbarStopRecordingClicked', async (event) => { );
// appendElement('onToolbarStopRecordingClicked');
// await stopRecording(RECORDING_ID);
// });
webComponent.addEventListener('onActivitiesPanelStartRecordingClicked', async (event) => { webComponent.addEventListener('onSessionCreated', (event) => {
appendElement('onActivitiesPanelStartRecordingClicked'); var session = event.detail;
// RECORDING_ID = await startRecording(SESSION_NAME); appendElement('onSessionCreated');
});
// Can't test the recording // You can see the session documentation here
// webComponent.addEventListener('onActivitiesPanelStopRecordingClicked', async (event) => { // https://docs.openvidu.io/en/stable/api/openvidu-browser/classes/session.html
// appendElement('onActivitiesPanelStopRecordingClicked');
// await stopRecording(RECORDING_ID);
// });
webComponent.addEventListener('onActivitiesPanelDeleteRecordingClicked', (event) => appendElement('onActivitiesPanelDeleteRecordingClicked')); session.on('connectionCreated', (e) => {
var user = JSON.parse(e.connection.data).clientData;
appendElement(`${user}-connectionCreated`);
});
webComponent.addEventListener('onSessionCreated', (event) => { session.on('sessionDisconnected', (e) => {
var session = event.detail; var user = JSON.parse(e.target.connection.data).clientData;
appendElement('onSessionCreated'); appendElement(user + '-sessionDisconnected');
});
});
webComponent.addEventListener('onParticipantCreated', (event) => {
var participant = event.detail;
appendElement(`${participant.nickname}-onParticipantCreated`);
});
// You can see the session documentation here // webComponent.addEventListener('error', (event) => {
// https://docs.openvidu.io/en/stable/api/openvidu-browser/classes/session.html // console.log('Error event', event.detail);
// });
session.on('connectionCreated', (e) => { joinSession(SESSION_NAME, PARTICIPANT_NAME);
var user = JSON.parse(e.connection.data).clientData;
appendElement(`${user}-connectionCreated`);
});
session.on('sessionDisconnected', (e) => {
var user = JSON.parse(e.target.connection.data).clientData;
appendElement(user + '-sessionDisconnected');
});
});
webComponent.addEventListener('onParticipantCreated', (event) => {
var participant = event.detail;
appendElement(`${participant.nickname}-onParticipantCreated`);
});
// webComponent.addEventListener('error', (event) => {
// console.log('Error event', event.detail);
// });
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);
} }
async function joinSession(sessionName, participantName) { 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);
} else {
tokens = { webcam: await getToken(sessionName), screen: await getToken(sessionName) };
}
tokens = await getToken(sessionName); webComponent.minimal = MINIMAL;
} else { webComponent.lang = LANG;
tokens = {webcam: await getToken(sessionName), screen: await getToken(sessionName)}; 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.videoMuted = VIDEO_MUTED;
webComponent.audioMuted = AUDIO_MUTED;
webComponent.toolbarScreenshareButton = SCREENSHARE_BUTTON;
} webComponent.toolbarFullscreenButton = FULLSCREEN_BUTTON;
webComponent.toolbarSettingsButton = TOOLBAR_SETTINGS_BUTTON;
webComponent.minimal = MINIMAL; webComponent.toolbarCaptionsButton = CAPTIONS_BUTTON;
webComponent.lang = LANG;
webComponent.captionsLang = CAPTIONS_LANG;
webComponent.prejoin = PREJOIN;
webComponent.videoMuted = VIDEO_MUTED;
webComponent.audioMuted = AUDIO_MUTED;
webComponent.toolbarScreenshareButton = SCREENSHARE_BUTTON;
webComponent.toolbarFullscreenButton = FULLSCREEN_BUTTON;
webComponent.toolbarSettingsButton = TOOLBAR_SETTINGS_BUTTON;
webComponent.toolbarCaptionsButton = CAPTIONS_BUTTON;
webComponent.toolbarLeaveButton = LEAVE_BUTTON; webComponent.toolbarLeaveButton = LEAVE_BUTTON;
webComponent.toolbarRecordingButton = RECORDING_BUTTON; webComponent.toolbarRecordingButton = RECORDING_BUTTON;
webComponent.toolbarActivitiesPanelButton = ACTIVITIES_PANEL_BUTTON; webComponent.toolbarActivitiesPanelButton = ACTIVITIES_PANEL_BUTTON;
webComponent.toolbarChatPanelButton = CHAT_PANEL_BUTTON; webComponent.toolbarChatPanelButton = CHAT_PANEL_BUTTON;
webComponent.toolbarParticipantsPanelButton = PARTICIPANTS_PANEL_BUTTON; webComponent.toolbarParticipantsPanelButton = PARTICIPANTS_PANEL_BUTTON;
webComponent.toolbarDisplayLogo = DISPLAY_LOGO; webComponent.toolbarDisplayLogo = DISPLAY_LOGO;
@ -180,12 +194,12 @@ async function joinSession(sessionName, participantName) {
webComponent.streamSettingsButton = SETTINGS_BUTTON; webComponent.streamSettingsButton = SETTINGS_BUTTON;
webComponent.participantPanelItemMuteButton = PARTICIPANT_MUTE_BUTTON; webComponent.participantPanelItemMuteButton = PARTICIPANT_MUTE_BUTTON;
webComponent.recordingActivityRecordingsList = [{status: 'ready'}]; webComponent.recordingActivityRecordingsList = [{ status: 'ready' }];
webComponent.activitiesPanelRecordingActivity = ACTIVITIES_RECORDING_ACTIVITY; webComponent.activitiesPanelRecordingActivity = ACTIVITIES_RECORDING_ACTIVITY;
webComponent.recordingActivityRecordingError = RECORDING_ERROR; webComponent.recordingActivityRecordingError = RECORDING_ERROR;
webComponent.participantName = participantName; webComponent.participantName = participantName;
webComponent.tokens = tokens; webComponent.tokens = tokens;
} }
/** /**
@ -200,64 +214,65 @@ 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) {
return new Promise((resolve, reject) => { // See https://docs.openvidu.io/en/stable/reference-docs/REST-API/#post-apisessions
$.ajax({ return new Promise((resolve, reject) => {
type: 'POST', $.ajax({
url: OPENVIDU_SERVER_URL + '/openvidu/api/sessions', type: 'POST',
data: JSON.stringify({ customSessionId: sessionName }), url: OPENVIDU_SERVER_URL + '/openvidu/api/sessions',
headers: { data: JSON.stringify({ customSessionId: sessionName }),
Authorization: 'Basic ' + btoa('OPENVIDUAPP:' + OPENVIDU_SERVER_SECRET), headers: {
'Content-Type': 'application/json', Authorization: 'Basic ' + btoa('OPENVIDUAPP:' + OPENVIDU_SERVER_SECRET),
}, 'Content-Type': 'application/json'
success: (response) => resolve(response.id), },
error: (error) => { success: (response) => resolve(response.id),
if (error.status === 409) { error: (error) => {
resolve(sessionName); if (error.status === 409) {
} else { resolve(sessionName);
console.warn('No connection to OpenVidu Server. This may be a certificate error at ' + OPENVIDU_SERVER_URL); } else {
if ( console.warn('No connection to OpenVidu Server. This may be a certificate error at ' + OPENVIDU_SERVER_URL);
window.confirm( if (
'No connection to OpenVidu Server. This may be a certificate error at "' + window.confirm(
OPENVIDU_SERVER_URL + 'No connection to OpenVidu Server. This may be a certificate error at "' +
'"\n\nClick OK to navigate and accept it. ' + OPENVIDU_SERVER_URL +
'If no certificate warning is shown, then check that your OpenVidu Server is up and running at "' + '"\n\nClick OK to navigate and accept it. ' +
OPENVIDU_SERVER_URL + 'If no certificate warning is shown, then check that your OpenVidu Server is up and running at "' +
'"', OPENVIDU_SERVER_URL +
) '"'
) { )
location.assign(OPENVIDU_SERVER_URL + '/openvidu/accept-certificate'); ) {
} location.assign(OPENVIDU_SERVER_URL + '/openvidu/accept-certificate');
} }
}, }
}); }
}); });
});
} }
function createToken(sessionId) { function createToken(sessionId) {
// See https://docs.openvidu.io/en/stable/reference-docs/REST-API/#post-apitokens // See https://docs.openvidu.io/en/stable/reference-docs/REST-API/#post-apitokens
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
$.ajax({ $.ajax({
type: 'POST', type: 'POST',
url: `${OPENVIDU_SERVER_URL}/openvidu/api/sessions/${sessionId}/connection`, url: `${OPENVIDU_SERVER_URL}/openvidu/api/sessions/${sessionId}/connection`,
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)
}); });
}); });
} }
// function startRecording(sessionId) { // function startRecording(sessionId) {

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}].'
);
}
}
} }