diff --git a/openvidu-components-angular/e2e/utils.po.test.ts b/openvidu-components-angular/e2e/utils.po.test.ts index 7139abe1..f3955522 100644 --- a/openvidu-components-angular/e2e/utils.po.test.ts +++ b/openvidu-components-angular/e2e/utils.po.test.ts @@ -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 { const elements = await this.browser.findElements(By.css(selector)); return elements.length > 0; diff --git a/openvidu-components-angular/e2e/webcomponent-app/app.js b/openvidu-components-angular/e2e/webcomponent-app/app.js index 6c1e5a27..8ac36a66 100644 --- a/openvidu-components-angular/e2e/webcomponent-app/app.js +++ b/openvidu-components-angular/e2e/webcomponent-app/app.js @@ -1,7 +1,7 @@ - var MINIMAL; var LANG; var CAPTIONS_LANG; +var CUSTOM_CAPTIONS_LANG_OPTIONS; var PREJOIN; var VIDEO_MUTED; var AUDIO_MUTED; @@ -30,147 +30,161 @@ var SESSION_NAME; var PARTICIPANT_NAME; $(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 - 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'; - 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'; + 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'; + CHAT_PANEL_BUTTON = url.searchParams.get('chatPanelBtn') === null ? true : url.searchParams.get('chatPanelBtn') === 'true'; + PARTICIPANTS_PANEL_BUTTON = + url.searchParams.get('participantsPanelBtn') === null ? true : url.searchParams.get('participantsPanelBtn') === 'true'; + 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'); + } - 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'; - CHAT_PANEL_BUTTON = url.searchParams.get("chatPanelBtn") === null ? true : url.searchParams.get("chatPanelBtn") === 'true'; - PARTICIPANTS_PANEL_BUTTON = url.searchParams.get("participantsPanelBtn") === null ? true : url.searchParams.get("participantsPanelBtn") === 'true'; - 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_SESSION_NAME = + url.searchParams.get('displaySessionName') === null ? true : url.searchParams.get('displaySessionName') === 'true'; + 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'; - 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_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'; + SESSION_NAME = + url.searchParams.get('sessionName') === null ? `E2ESession${Math.floor(Date.now())}` : url.searchParams.get('sessionName'); + 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('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')); + webComponent.addEventListener('onActivitiesPanelStartRecordingClicked', async (event) => { + appendElement('onActivitiesPanelStartRecordingClicked'); + // RECORDING_ID = await startRecording(SESSION_NAME); + }); - 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('onActivitiesPanelStopRecordingClicked', async (event) => { + // appendElement('onActivitiesPanelStopRecordingClicked'); + // await stopRecording(RECORDING_ID); + // }); - }); - // Can't test the recording - // webComponent.addEventListener('onToolbarStopRecordingClicked', async (event) => { - // appendElement('onToolbarStopRecordingClicked'); - // await stopRecording(RECORDING_ID); - // }); + webComponent.addEventListener('onActivitiesPanelDeleteRecordingClicked', (event) => + appendElement('onActivitiesPanelDeleteRecordingClicked') + ); - webComponent.addEventListener('onActivitiesPanelStartRecordingClicked', async (event) => { - appendElement('onActivitiesPanelStartRecordingClicked'); - // RECORDING_ID = await startRecording(SESSION_NAME); - }); + webComponent.addEventListener('onSessionCreated', (event) => { + var session = event.detail; + appendElement('onSessionCreated'); - // Can't test the recording - // webComponent.addEventListener('onActivitiesPanelStopRecordingClicked', async (event) => { - // appendElement('onActivitiesPanelStopRecordingClicked'); - // await stopRecording(RECORDING_ID); - // }); + // You can see the session documentation here + // https://docs.openvidu.io/en/stable/api/openvidu-browser/classes/session.html - 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) => { - var session = event.detail; - appendElement('onSessionCreated'); + 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`); + }); - // You can see the session documentation here - // https://docs.openvidu.io/en/stable/api/openvidu-browser/classes/session.html + // webComponent.addEventListener('error', (event) => { + // console.log('Error event', event.detail); + // }); - session.on('connectionCreated', (e) => { - 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); + joinSession(SESSION_NAME, PARTICIPANT_NAME); }); - function appendElement(id) { - var eventsDiv = document.getElementById('events'); - var element = document.createElement('div'); - element.setAttribute("id", id); - element.setAttribute("style", "height: 1px;"); - eventsDiv.appendChild(element); + var eventsDiv = document.getElementById('events'); + var element = document.createElement('div'); + element.setAttribute('id', id); + element.setAttribute('style', 'height: 1px;'); + eventsDiv.appendChild(element); } async function joinSession(sessionName, participantName) { - var webComponent = document.querySelector('openvidu-webcomponent'); - var tokens; - if (SINGLE_TOKEN){ + var webComponent = document.querySelector('openvidu-webcomponent'); + var tokens; + if (SINGLE_TOKEN) { + tokens = await getToken(sessionName); + } else { + tokens = { webcam: await getToken(sessionName), screen: await getToken(sessionName) }; + } - tokens = await getToken(sessionName); - } else { - tokens = {webcam: await getToken(sessionName), screen: await getToken(sessionName)}; + webComponent.minimal = MINIMAL; + webComponent.lang = 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.videoMuted = VIDEO_MUTED; + webComponent.audioMuted = AUDIO_MUTED; + webComponent.toolbarScreenshareButton = SCREENSHARE_BUTTON; - } - - webComponent.minimal = MINIMAL; - 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.toolbarFullscreenButton = FULLSCREEN_BUTTON; + webComponent.toolbarSettingsButton = TOOLBAR_SETTINGS_BUTTON; + webComponent.toolbarCaptionsButton = CAPTIONS_BUTTON; webComponent.toolbarLeaveButton = LEAVE_BUTTON; - webComponent.toolbarRecordingButton = RECORDING_BUTTON; - webComponent.toolbarActivitiesPanelButton = ACTIVITIES_PANEL_BUTTON; + webComponent.toolbarRecordingButton = RECORDING_BUTTON; + webComponent.toolbarActivitiesPanelButton = ACTIVITIES_PANEL_BUTTON; webComponent.toolbarChatPanelButton = CHAT_PANEL_BUTTON; webComponent.toolbarParticipantsPanelButton = PARTICIPANTS_PANEL_BUTTON; webComponent.toolbarDisplayLogo = DISPLAY_LOGO; @@ -180,12 +194,12 @@ async function joinSession(sessionName, participantName) { webComponent.streamSettingsButton = SETTINGS_BUTTON; webComponent.participantPanelItemMuteButton = PARTICIPANT_MUTE_BUTTON; - webComponent.recordingActivityRecordingsList = [{status: 'ready'}]; - webComponent.activitiesPanelRecordingActivity = ACTIVITIES_RECORDING_ACTIVITY; - webComponent.recordingActivityRecordingError = RECORDING_ERROR; + webComponent.recordingActivityRecordingsList = [{ status: 'ready' }]; + webComponent.activitiesPanelRecordingActivity = ACTIVITIES_RECORDING_ACTIVITY; + webComponent.recordingActivityRecordingError = RECORDING_ERROR; - webComponent.participantName = participantName; - webComponent.tokens = tokens; + webComponent.participantName = participantName; + webComponent.tokens = tokens; } /** @@ -200,64 +214,65 @@ async function joinSession(sessionName, participantName) { * 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'; 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 - return new Promise((resolve, reject) => { - $.ajax({ - type: 'POST', - url: OPENVIDU_SERVER_URL + '/openvidu/api/sessions', - data: JSON.stringify({ customSessionId: sessionName }), - headers: { - Authorization: 'Basic ' + btoa('OPENVIDUAPP:' + OPENVIDU_SERVER_SECRET), - 'Content-Type': 'application/json', - }, - success: (response) => resolve(response.id), - error: (error) => { - if (error.status === 409) { - resolve(sessionName); - } else { - console.warn('No connection to OpenVidu Server. This may be a certificate error at ' + OPENVIDU_SERVER_URL); - if ( - window.confirm( - 'No connection to OpenVidu Server. This may be a certificate error at "' + - OPENVIDU_SERVER_URL + - '"\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 "' + - OPENVIDU_SERVER_URL + - '"', - ) - ) { - location.assign(OPENVIDU_SERVER_URL + '/openvidu/accept-certificate'); - } - } - }, - }); - }); +function createSession(sessionName) { + // See https://docs.openvidu.io/en/stable/reference-docs/REST-API/#post-apisessions + return new Promise((resolve, reject) => { + $.ajax({ + type: 'POST', + url: OPENVIDU_SERVER_URL + '/openvidu/api/sessions', + data: JSON.stringify({ customSessionId: sessionName }), + headers: { + Authorization: 'Basic ' + btoa('OPENVIDUAPP:' + OPENVIDU_SERVER_SECRET), + 'Content-Type': 'application/json' + }, + success: (response) => resolve(response.id), + error: (error) => { + if (error.status === 409) { + resolve(sessionName); + } else { + console.warn('No connection to OpenVidu Server. This may be a certificate error at ' + OPENVIDU_SERVER_URL); + if ( + window.confirm( + 'No connection to OpenVidu Server. This may be a certificate error at "' + + OPENVIDU_SERVER_URL + + '"\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 "' + + OPENVIDU_SERVER_URL + + '"' + ) + ) { + location.assign(OPENVIDU_SERVER_URL + '/openvidu/accept-certificate'); + } + } + } + }); + }); } function createToken(sessionId) { - // See https://docs.openvidu.io/en/stable/reference-docs/REST-API/#post-apitokens - return new Promise((resolve, reject) => { - $.ajax({ - type: 'POST', - url: `${OPENVIDU_SERVER_URL}/openvidu/api/sessions/${sessionId}/connection`, - data: JSON.stringify({ session: sessionId, role: 'MODERATOR' }), - headers: { - Authorization: 'Basic ' + btoa('OPENVIDUAPP:' + OPENVIDU_SERVER_SECRET), - 'Content-Type': 'application/json', - }, - success: (response) => { - resolve(response.token); - }, - error: (error) => reject(error), - }); - }); + // See https://docs.openvidu.io/en/stable/reference-docs/REST-API/#post-apitokens + return new Promise((resolve, reject) => { + $.ajax({ + type: 'POST', + url: `${OPENVIDU_SERVER_URL}/openvidu/api/sessions/${sessionId}/connection`, + data: JSON.stringify({ session: sessionId, role: 'MODERATOR' }), + headers: { + Authorization: 'Basic ' + btoa('OPENVIDUAPP:' + OPENVIDU_SERVER_SECRET), + 'Content-Type': 'application/json' + }, + success: (response) => { + resolve(response.token); + }, + error: (error) => reject(error) + }); + }); } // function startRecording(sessionId) { diff --git a/openvidu-components-angular/e2e/webcomponent.test.ts b/openvidu-components-angular/e2e/webcomponent.test.ts index 9def9355..cceb6d1c 100644 --- a/openvidu-components-angular/e2e/webcomponent.test.ts +++ b/openvidu-components-angular/e2e/webcomponent.test.ts @@ -149,7 +149,54 @@ describe('Testing API Directives', () => { // expect(await utils.isPresent('.captions-container')).to.be.true; // 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 () => { diff --git a/openvidu-components-angular/projects/openvidu-angular/src/lib/components/videoconference/videoconference.component.ts b/openvidu-components-angular/projects/openvidu-angular/src/lib/components/videoconference/videoconference.component.ts index b4703575..c234b388 100644 --- a/openvidu-components-angular/projects/openvidu-angular/src/lib/components/videoconference/videoconference.component.ts +++ b/openvidu-components-angular/projects/openvidu-angular/src/lib/components/videoconference/videoconference.component.ts @@ -56,6 +56,7 @@ import { TranslateService } from '../../services/translate/translate.service'; * | **minimal** | `boolean` | {@link MinimalDirective} | * | **lang** | `string` | {@link LangDirective} | * | **captionsLang** | `string` | {@link CaptionsLangDirective} | + * | **captionsLangOprions** | `CaptionsLangOption []` | {@link CaptionsLangOptionsDirective} | * | **prejoin** | `boolean` | {@link PrejoinDirective} | * | **participantName** | `string` | {@link ParticipantNameDirective} | * | **videoMuted** | `boolean` | {@link VideoMutedDirective} | @@ -302,7 +303,6 @@ export class VideoconferenceComponent implements OnInit, OnDestroy, AfterViewIni } this.start(); - } /** diff --git a/openvidu-components-angular/projects/openvidu-angular/src/lib/directives/api/api.directive.module.ts b/openvidu-components-angular/projects/openvidu-angular/src/lib/directives/api/api.directive.module.ts index 55d7370f..c390fee9 100644 --- a/openvidu-components-angular/projects/openvidu-angular/src/lib/directives/api/api.directive.module.ts +++ b/openvidu-components-angular/projects/openvidu-angular/src/lib/directives/api/api.directive.module.ts @@ -25,9 +25,7 @@ import { } from './toolbar.directive'; import { AudioMutedDirective, - CaptionsLangDirective, - LangDirective, - MinimalDirective, + CaptionsLangDirective, CaptionsLangOptionsDirective, LangDirective, MinimalDirective, ParticipantNameDirective, PrejoinDirective, VideoMutedDirective @@ -37,6 +35,7 @@ import { declarations: [ MinimalDirective, LangDirective, + CaptionsLangOptionsDirective, CaptionsLangDirective, PrejoinDirective, VideoMutedDirective, @@ -68,6 +67,7 @@ import { exports: [ MinimalDirective, LangDirective, + CaptionsLangOptionsDirective, CaptionsLangDirective, PrejoinDirective, VideoMutedDirective, diff --git a/openvidu-components-angular/projects/openvidu-angular/src/lib/directives/api/videoconference.directive.ts b/openvidu-components-angular/projects/openvidu-angular/src/lib/directives/api/videoconference.directive.ts index 3aeea03a..b4648f26 100644 --- a/openvidu-components-angular/projects/openvidu-angular/src/lib/directives/api/videoconference.directive.ts +++ b/openvidu-components-angular/projects/openvidu-angular/src/lib/directives/api/videoconference.directive.ts @@ -1,4 +1,5 @@ import { Directive, ElementRef, Input, OnDestroy, OnInit } from '@angular/core'; +import { CaptionsLangOption } from '../../models/caption.model'; import { CaptionService } from '../../services/caption/caption.service'; import { OpenViduAngularConfigService } from '../../services/config/openvidu-angular.config.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}. * @@ -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 + * + */ + @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. diff --git a/openvidu-components-angular/projects/openvidu-angular/src/lib/models/caption.model.ts b/openvidu-components-angular/projects/openvidu-angular/src/lib/models/caption.model.ts index 64d9a723..95869623 100644 --- a/openvidu-components-angular/projects/openvidu-angular/src/lib/models/caption.model.ts +++ b/openvidu-components-angular/projects/openvidu-angular/src/lib/models/caption.model.ts @@ -1,4 +1,7 @@ +/** + * @internal + */ export interface CaptionModel { connectionId: string; @@ -8,3 +11,10 @@ export interface CaptionModel { text: string; } +export interface CaptionsLangOption { + + name: string; + ISO: string; + +} + diff --git a/openvidu-components-angular/projects/openvidu-angular/src/lib/services/caption/caption.service.ts b/openvidu-components-angular/projects/openvidu-angular/src/lib/services/caption/caption.service.ts index af721baf..9366ae83 100644 --- a/openvidu-components-angular/projects/openvidu-angular/src/lib/services/caption/caption.service.ts +++ b/openvidu-components-angular/projects/openvidu-angular/src/lib/services/caption/caption.service.ts @@ -1,5 +1,6 @@ import { Injectable } from '@angular/core'; import { Observable, Subject } from 'rxjs'; +import { CaptionsLangOption } from '../../models/caption.model'; import { StorageService } from '../storage/storage.service'; /** @@ -9,7 +10,7 @@ import { StorageService } from '../storage/storage.service'; providedIn: 'root' }) export class CaptionService { - private langs = [ + private langs: CaptionsLangOption [] = [ { name: 'English', ISO: 'en-US' }, { name: 'Español', ISO: 'es-ES' }, { name: 'Deutsch', ISO: 'de-DE' }, @@ -20,20 +21,22 @@ export class CaptionService { { name: 'やまと', ISO: 'jp-JP' }, { 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 }>; private _captionLang: Subject<{ name: string; ISO: string }> = new Subject(); private captionsEnabled: boolean = false; constructor(private storageService: StorageService) { - 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]; - } + this.updateLangSelected(); this.captionLangObs = this._captionLang.asObservable(); + + } + + setLanguageOptions(options: CaptionsLangOption [] | undefined) { + if(options && options.length > 0) { + this.langs = options; + this.updateLangSelected(); + } } setCaptionsEnabled(value: boolean) { @@ -60,4 +63,14 @@ export class CaptionService { getCaptionLanguages(): { name: string; ISO: string }[] { 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]; + } + } } diff --git a/openvidu-components-angular/src/app/openvidu-webcomponent/openvidu-webcomponent.component.html b/openvidu-components-angular/src/app/openvidu-webcomponent/openvidu-webcomponent.component.html index 98a2bf42..61c39314 100644 --- a/openvidu-components-angular/src/app/openvidu-webcomponent/openvidu-webcomponent.component.html +++ b/openvidu-components-angular/src/app/openvidu-webcomponent/openvidu-webcomponent.component.html @@ -5,6 +5,7 @@ [minimal]="_minimal" [lang]="_lang" [captionsLang]="_captionsLang" + [captionsLangOptions]="_captionsLangOptions" [prejoin]="_prejoin" [videoMuted]="_videoMuted" [audioMuted]="_audioMuted" diff --git a/openvidu-components-angular/src/app/openvidu-webcomponent/openvidu-webcomponent.component.ts b/openvidu-components-angular/src/app/openvidu-webcomponent/openvidu-webcomponent.component.ts index 04336c66..dbc7f944 100644 --- a/openvidu-components-angular/src/app/openvidu-webcomponent/openvidu-webcomponent.component.ts +++ b/openvidu-components-angular/src/app/openvidu-webcomponent/openvidu-webcomponent.component.ts @@ -1,6 +1,7 @@ import { Component, ElementRef, EventEmitter, Input, OnInit, Output } from '@angular/core'; import { OpenViduService, ParticipantAbstractModel, RecordingInfo, TokenModel } from 'openvidu-angular'; 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 */ _minimal: boolean = false; + /** + * @internal + */ + /** * @internal */ _lang: string = ''; + /** * @internal */ _captionsLang: string = ''; + /** + * @internal + */ + _captionsLangOptions: CaptionsLangOption; + /** * @internal */ @@ -157,6 +168,30 @@ export class OpenviduWebComponentComponent implements OnInit { @Input() set captionsLang(value: string) { 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 + * + */ + @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. * @@ -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}].' + ); + } + } }