diff --git a/openvidu-components-angular/e2e/webcomponent-app/app.js b/openvidu-components-angular/e2e/webcomponent-app/app.js index c8fdc9cf..262fc9fb 100644 --- a/openvidu-components-angular/e2e/webcomponent-app/app.js +++ b/openvidu-components-angular/e2e/webcomponent-app/app.js @@ -20,6 +20,7 @@ var PARTICIPANTS_PANEL_BUTTON; var ACTIVITIES_RECORDING_ACTIVITY; var RECORDING_ERROR; var TOOLBAR_SETTINGS_BUTTON; +var SUBTITLES_BUTTON; var SESSION_NAME; @@ -37,6 +38,7 @@ $(document).ready(() => { RECORDING_BUTTON = url.searchParams.get("recordingBtn") === null ? true : url.searchParams.get("recordingBtn") === 'true'; FULLSCREEN_BUTTON = url.searchParams.get("fullscreenBtn") === null ? true : url.searchParams.get("fullscreenBtn") === 'true'; TOOLBAR_SETTINGS_BUTTON = url.searchParams.get("toolbarSettingsBtn") === null ? true : url.searchParams.get("toolbarSettingsBtn") === 'true'; + SUBTITLES_BUTTON = url.searchParams.get("toolbarSubtitlesBtn") === null ? true : url.searchParams.get("toolbarSubtitlesBtn") === 'true'; LEAVE_BUTTON = url.searchParams.get("leaveBtn") === null ? true : url.searchParams.get("leaveBtn") === 'true'; ACTIVITIES_PANEL_BUTTON = url.searchParams.get("activitiesPanelBtn") === null ? true : url.searchParams.get("activitiesPanelBtn") === 'true'; @@ -147,6 +149,7 @@ async function joinSession(sessionName, participantName) { webComponent.toolbarFullscreenButton = FULLSCREEN_BUTTON; webComponent.toolbarSettingsButton = TOOLBAR_SETTINGS_BUTTON; + webComponent.toolbarSubtitlesButton = SUBTITLES_BUTTON; webComponent.toolbarLeaveButton = LEAVE_BUTTON; webComponent.toolbarRecordingButton = RECORDING_BUTTON; webComponent.toolbarActivitiesPanelButton = ACTIVITIES_PANEL_BUTTON; diff --git a/openvidu-components-angular/e2e/webcomponent.test.ts b/openvidu-components-angular/e2e/webcomponent.test.ts index d29725f9..4bf9d826 100644 --- a/openvidu-components-angular/e2e/webcomponent.test.ts +++ b/openvidu-components-angular/e2e/webcomponent.test.ts @@ -252,6 +252,41 @@ describe('Testing API Directives', () => { expect(element.length).equals(0); }); + it('should HIDE the SUBTITLES button', async () => { + let element; + await browser.get(`${url}?prejoin=false&toolbarSubtitlesBtn=false`); + element = await browser.wait(until.elementLocated(By.id('session-container')), TIMEOUT); + expect(await element.isDisplayed()).to.be.true; + + // Checking if toolbar is present + element = await browser.wait(until.elementLocated(By.id('media-buttons-container')), TIMEOUT); + expect(await element.isDisplayed()).to.be.true; + + // Open more options menu + element = await browser.wait(until.elementLocated(By.id('more-options-btn')), TIMEOUT); + await element.click(); + + await browser.sleep(500); + + // Checking if subtitles button is not present + element = await browser.wait(until.elementLocated(By.className('mat-menu-content')), TIMEOUT); + expect(await element.isDisplayed()).to.be.true; + element = await browser.findElements(By.id('subtitles-btn')); + expect(element.length).equals(0); + + element = await browser.findElements(By.id('toolbar-settings-btn')); + expect(element.length).equals(1); + await element[0].click(); + + await browser.sleep(500); + + element = await browser.wait(until.elementLocated(By.className('settings-container')), TIMEOUT); + expect(await element.isDisplayed()).to.be.true; + element = await browser.findElements(By.id('subtitles-opt')); + expect(element.length).equals(0); + + }); + it('should HIDE the TOOLBAR SETTINGS button', async () => { let element; await browser.get(`${url}?prejoin=false&toolbarSettingsBtn=false`); diff --git a/openvidu-components-angular/projects/openvidu-angular/src/lib/components/audio-wave/audio-wave.component.ts b/openvidu-components-angular/projects/openvidu-angular/src/lib/components/audio-wave/audio-wave.component.ts index ed5e1735..a84d9a50 100644 --- a/openvidu-components-angular/projects/openvidu-angular/src/lib/components/audio-wave/audio-wave.component.ts +++ b/openvidu-components-angular/projects/openvidu-angular/src/lib/components/audio-wave/audio-wave.component.ts @@ -30,7 +30,7 @@ export class AudioWaveComponent implements OnInit, OnDestroy { if (this.streamManager) { this.streamManager.on('streamPropertyChanged', (event: StreamPropertyChangedEvent) => { if (event.reason === 'trackReplaced' && event.changedProperty === 'audioActive') { - // FIXUP: When the audio track is replaced, the startSpeakingEvents is not fired by openvidu-browser + // TODO: When the audio track is replaced, the startSpeakingEvents is not fired by openvidu-browser this.unsubscribeSpeakingEvents(); this.subscribeSpeakingEvents(); } diff --git a/openvidu-components-angular/projects/openvidu-angular/src/lib/components/layout/layout.component.css b/openvidu-components-angular/projects/openvidu-angular/src/lib/components/layout/layout.component.css index d3c1eafd..04902f07 100644 --- a/openvidu-components-angular/projects/openvidu-angular/src/lib/components/layout/layout.component.css +++ b/openvidu-components-angular/projects/openvidu-angular/src/lib/components/layout/layout.component.css @@ -2,6 +2,12 @@ height: 100%; } +.container { + height: 100%; +} +.withSubtitles { + height: calc(100% - 75px) !important; +} .layout { position: relative; @@ -16,40 +22,39 @@ height: -moz-available; } - /*! +/*! * Copyright (c) 2017 TokBox, Inc. * Released under the MIT license * http://opensource.org/licenses/MIT */ - - /** +/** * OT Base styles */ - /* Root OT object, this is where our CSS reset happens */ - .OT_root, - .OT_root * { +/* Root OT object, this is where our CSS reset happens */ +.OT_root, +.OT_root * { color: #ffffff; margin: 0; padding: 0; border: 0; font-size: 100%; vertical-align: baseline; - } +} - .OT_dialog-centering { +.OT_dialog-centering { display: table; width: 100%; height: 100%; - } +} - .OT_dialog-centering-child { +.OT_dialog-centering-child { display: table-cell; vertical-align: middle; - } +} - .OT_dialog { +.OT_dialog { position: relative; -webkit-box-sizing: border-box; box-sizing: border-box; @@ -60,15 +65,15 @@ font-family: 'Ubuntu', sans-serif; font-size: 13px; line-height: 1.4; - } +} - .OT_dialog * { +.OT_dialog * { font-family: inherit; -webkit-box-sizing: inherit; box-sizing: inherit; - } +} - .OT_closeButton { +.OT_closeButton { color: #999999; cursor: pointer; font-size: 32px; @@ -76,37 +81,37 @@ position: absolute; right: 18px; top: 0; - } +} - .OT_dialog-messages { +.OT_dialog-messages { text-align: center; - } +} - .OT_dialog-messages-main { +.OT_dialog-messages-main { margin-bottom: 36px; line-height: 36px; font-weight: 300; font-size: 24px; - } +} - .OT_dialog-messages-minor { +.OT_dialog-messages-minor { margin-bottom: 18px; font-size: 13px; line-height: 18px; color: #a4a4a4; - } +} - .OT_dialog-messages-minor strong { +.OT_dialog-messages-minor strong { color: #ffffff; - } +} - .OT_dialog-actions-card { +.OT_dialog-actions-card { display: inline-block; - } +} - .OT_dialog-button-title { +.OT_dialog-button-title { margin-bottom: 18px; line-height: 18px; @@ -114,24 +119,24 @@ text-align: center; font-size: 14px; color: #999999; - } - .OT_dialog-button-title label { +} +.OT_dialog-button-title label { color: #999999; - } +} - .OT_dialog-button-title a, - .OT_dialog-button-title a:link, - .OT_dialog-button-title a:active { +.OT_dialog-button-title a, +.OT_dialog-button-title a:link, +.OT_dialog-button-title a:active { color: #02a1de; - } +} - .OT_dialog-button-title strong { +.OT_dialog-button-title strong { color: #ffffff; font-weight: 100; display: block; - } +} - .OT_dialog-button { +.OT_dialog-button { display: inline-block; margin-bottom: 18px; @@ -140,23 +145,23 @@ background-color: #1ca3dc; text-align: center; cursor: pointer; - } +} - .OT_dialog-button:disabled { +.OT_dialog-button:disabled { cursor: not-allowed; opacity: 0.5; - } +} - .OT_dialog-button-large { +.OT_dialog-button-large { line-height: 36px; padding-top: 9px; padding-bottom: 9px; font-weight: 100; font-size: 24px; - } +} - .OT_dialog-button-small { +.OT_dialog-button-small { line-height: 18px; padding-top: 9px; padding-bottom: 9px; @@ -164,9 +169,9 @@ background-color: #444444; color: #999999; font-size: 16px; - } +} - .OT_dialog-progress-bar { +.OT_dialog-progress-bar { display: inline-block; /* prevents margin collapse */ width: 100%; margin-top: 5px; @@ -174,85 +179,85 @@ border: 1px solid #4e4e4e; height: 8px; - } +} - .OT_dialog-progress-bar-fill { +.OT_dialog-progress-bar-fill { height: 100%; background-color: #29a4da; - } +} - .OT_dialog-plugin-upgrading .OT_dialog-plugin-upgrade-percentage { +.OT_dialog-plugin-upgrading .OT_dialog-plugin-upgrade-percentage { line-height: 54px; font-size: 48px; font-weight: 100; - } +} - /* Helpers */ +/* Helpers */ - .OT_centered { +.OT_centered { position: fixed; left: 50%; top: 50%; margin: 0; - } +} - .OT_dialog-hidden { +.OT_dialog-hidden { display: none; - } +} - .OT_dialog-button-block { +.OT_dialog-button-block { display: block; - } +} - .OT_dialog-no-natural-margin { +.OT_dialog-no-natural-margin { margin-bottom: 0; - } +} - /* Publisher and Subscriber styles */ +/* Publisher and Subscriber styles */ - .OT_publisher, - .OT_subscriber { +.OT_publisher, +.OT_subscriber { position: relative; min-width: 0px; min-height: 0px; - margin: 3px; + padding: 3px; transition-duration: 0.1s; transition-timing-function: ease-in-out; - } +} - .OT_publisher .OT_video-element, - .OT_subscriber .OT_video-element { +.OT_publisher .OT_video-element, +.OT_subscriber .OT_video-element { display: block; position: absolute; width: 100%; height: 100%; -webkit-transform-origin: 0 0; transform-origin: 0 0; - } +} - .OT_subscriber_error { +.OT_subscriber_error { background-color: #000; color: #fff; text-align: center; - } +} - .OT_subscriber_error > p { +.OT_subscriber_error > p { padding: 20px; - } +} - /* The publisher/subscriber name/mute background */ - .OT_publisher .OT_bar, - .OT_subscriber .OT_bar, - .OT_publisher .OT_name, - .OT_subscriber .OT_name, - .OT_publisher .OT_archiving, - .OT_subscriber .OT_archiving, - .OT_publisher .OT_archiving-status, - .OT_subscriber .OT_archiving-status, - .OT_publisher .OT_archiving-light-box, - .OT_subscriber .OT_archiving-light-box { +/* The publisher/subscriber name/mute background */ +.OT_publisher .OT_bar, +.OT_subscriber .OT_bar, +.OT_publisher .OT_name, +.OT_subscriber .OT_name, +.OT_publisher .OT_archiving, +.OT_subscriber .OT_archiving, +.OT_publisher .OT_archiving-status, +.OT_subscriber .OT_archiving-status, +.OT_publisher .OT_archiving-light-box, +.OT_subscriber .OT_archiving-light-box { -webkit-box-sizing: border-box; -ms-box-sizing: border-box; box-sizing: border-box; @@ -262,31 +267,31 @@ display: block; height: 34px; position: absolute; - } +} - .OT_publisher .OT_bar, - .OT_subscriber .OT_bar { +.OT_publisher .OT_bar, +.OT_subscriber .OT_bar { background: rgba(0, 0, 0, 0.4); - } +} - .OT_publisher .OT_edge-bar-item, - .OT_subscriber .OT_edge-bar-item { +.OT_publisher .OT_edge-bar-item, +.OT_subscriber .OT_edge-bar-item { z-index: 1; /* required to get audio level meter underneath */ - } +} - /* The publisher/subscriber name panel/archiving status bar */ - .OT_publisher .OT_name, - .OT_subscriber .OT_name { +/* The publisher/subscriber name panel/archiving status bar */ +.OT_publisher .OT_name, +.OT_subscriber .OT_name { background-color: transparent; color: #ffffff; font-size: 15px; line-height: 34px; font-weight: normal; padding: 0 4px 0 36px; - } +} - .OT_publisher .OT_archiving-status, - .OT_subscriber .OT_archiving-status { +.OT_publisher .OT_archiving-status, +.OT_subscriber .OT_archiving-status { background: rgba(0, 0, 0, 0.4); top: auto; bottom: 0; @@ -296,26 +301,26 @@ font-size: 15px; line-height: 34px; font-weight: normal; - } +} - .OT_micro .OT_archiving-status, - .OT_micro:hover .OT_archiving-status, - .OT_mini .OT_archiving-status, - .OT_mini:hover .OT_archiving-status { +.OT_micro .OT_archiving-status, +.OT_micro:hover .OT_archiving-status, +.OT_mini .OT_archiving-status, +.OT_mini:hover .OT_archiving-status { display: none; - } +} - .OT_publisher .OT_archiving-light-box, - .OT_subscriber .OT_archiving-light-box { +.OT_publisher .OT_archiving-light-box, +.OT_subscriber .OT_archiving-light-box { background: rgba(0, 0, 0, 0.4); top: auto; bottom: 0; right: auto; width: 34px; height: 34px; - } +} - .OT_archiving-light { +.OT_archiving-light { width: 7px; height: 7px; border-radius: 30px; @@ -325,9 +330,9 @@ background-color: #575757; -webkit-box-shadow: 0 0 5px 1px #575757; box-shadow: 0 0 5px 1px #575757; - } +} - .OT_archiving-light.OT_active { +.OT_archiving-light.OT_active { background-color: #970d13; animation: OT_pulse 1.3s ease-in; -webkit-animation: OT_pulse 1.3s ease-in; @@ -337,85 +342,85 @@ -webkit-animation-iteration-count: infinite; -moz-animation-iteration-count: infinite; -webkit-animation-iteration-count: infinite; - } - @-webkit-keyframes OT_pulse { +} +@-webkit-keyframes OT_pulse { 0% { - -webkit-box-shadow: 0 0 0px 0px #c70019; - box-shadow: 0 0 0px 0px #c70019; + -webkit-box-shadow: 0 0 0px 0px #c70019; + box-shadow: 0 0 0px 0px #c70019; } 30% { - -webkit-box-shadow: 0 0 5px 1px #c70019; - box-shadow: 0 0 5px 1px #c70019; + -webkit-box-shadow: 0 0 5px 1px #c70019; + box-shadow: 0 0 5px 1px #c70019; } 50% { - -webkit-box-shadow: 0 0 5px 1px #c70019; - box-shadow: 0 0 5px 1px #c70019; + -webkit-box-shadow: 0 0 5px 1px #c70019; + box-shadow: 0 0 5px 1px #c70019; } 80% { - -webkit-box-shadow: 0 0 0px 0px #c70019; - box-shadow: 0 0 0px 0px #c70019; + -webkit-box-shadow: 0 0 0px 0px #c70019; + box-shadow: 0 0 0px 0px #c70019; } 100% { - -webkit-box-shadow: 0 0 0px 0px #c70019; - box-shadow: 0 0 0px 0px #c70019; + -webkit-box-shadow: 0 0 0px 0px #c70019; + box-shadow: 0 0 0px 0px #c70019; } - } +} - @-webkit-keyframes OT_pulse { +@-webkit-keyframes OT_pulse { 0% { - -webkit-box-shadow: 0 0 0px 0px #c70019; - box-shadow: 0 0 0px 0px #c70019; + -webkit-box-shadow: 0 0 0px 0px #c70019; + box-shadow: 0 0 0px 0px #c70019; } 30% { - -webkit-box-shadow: 0 0 5px 1px #c70019; - box-shadow: 0 0 5px 1px #c70019; + -webkit-box-shadow: 0 0 5px 1px #c70019; + box-shadow: 0 0 5px 1px #c70019; } 50% { - -webkit-box-shadow: 0 0 5px 1px #c70019; - box-shadow: 0 0 5px 1px #c70019; + -webkit-box-shadow: 0 0 5px 1px #c70019; + box-shadow: 0 0 5px 1px #c70019; } 80% { - -webkit-box-shadow: 0 0 0px 0px #c70019; - box-shadow: 0 0 0px 0px #c70019; + -webkit-box-shadow: 0 0 0px 0px #c70019; + box-shadow: 0 0 0px 0px #c70019; } 100% { - -webkit-box-shadow: 0 0 0px 0px #c70019; - box-shadow: 0 0 0px 0px #c70019; + -webkit-box-shadow: 0 0 0px 0px #c70019; + box-shadow: 0 0 0px 0px #c70019; } - } +} - .OT_mini .OT_bar, - .OT_bar.OT_mode-mini, - .OT_bar.OT_mode-mini-auto { +.OT_mini .OT_bar, +.OT_bar.OT_mode-mini, +.OT_bar.OT_mode-mini-auto { bottom: 0; height: auto; - } +} - .OT_mini .OT_name.OT_mode-off, - .OT_mini .OT_name.OT_mode-on, - .OT_mini .OT_name.OT_mode-auto, - .OT_mini:hover .OT_name.OT_mode-auto { +.OT_mini .OT_name.OT_mode-off, +.OT_mini .OT_name.OT_mode-on, +.OT_mini .OT_name.OT_mode-auto, +.OT_mini:hover .OT_name.OT_mode-auto { display: none; - } +} - .OT_publisher .OT_name, - .OT_subscriber .OT_name { +.OT_publisher .OT_name, +.OT_subscriber .OT_name { left: 10px; right: 37px; height: 34px; padding-left: 0; - } +} - .OT_publisher .OT_mute, - .OT_subscriber .OT_mute { +.OT_publisher .OT_mute, +.OT_subscriber .OT_mute { border: none; cursor: pointer; display: block; @@ -424,127 +429,127 @@ text-indent: -9999em; background-color: transparent; background-repeat: no-repeat; - } +} - .OT_publisher .OT_mute, - .OT_subscriber .OT_mute { +.OT_publisher .OT_mute, +.OT_subscriber .OT_mute { right: 0; top: 0; border-left: 1px solid rgba(255, 255, 255, 0.2); height: 36px; width: 37px; - } +} - .OT_mini .OT_mute, - .OT_publisher.OT_mini .OT_mute.OT_mode-auto.OT_mode-on-hold, - .OT_subscriber.OT_mini .OT_mute.OT_mode-auto.OT_mode-on-hold { +.OT_mini .OT_mute, +.OT_publisher.OT_mini .OT_mute.OT_mode-auto.OT_mode-on-hold, +.OT_subscriber.OT_mini .OT_mute.OT_mode-auto.OT_mode-on-hold { top: 50%; left: 50%; right: auto; margin-top: -18px; margin-left: -18.5px; border-left: none; - } +} - .OT_publisher .OT_mute { +.OT_publisher .OT_mute { background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAAcCAMAAAC02HQrAAAA1VBMVEUAAAD3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pn3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pn3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj39/j3+Pj3+Pn4+Pk/JRMlAAAAQ3RSTlMABAUHCQoLDhAQERwdHiAjLjAxOD9ASFBRVl1mbnZ6fH2LjI+QkaWqrrC1uLzAwcXJycrL1NXj5Ofo6u3w9fr7/P3+d4M3+QAAAQBJREFUGBlVwYdCglAABdCLlr5Unijm3hMUtBzlBLSr//9JgUToOQgVJgceJgU8aHgMeA38K50ZOpcQmTPwcyXn+JM8M3JJIqQypiIkeXelTyIkGZPwKS1NMia1lgKTVkaE3oQQGYsmHNqSMWnTgUFbMiZtGlD2dpaxrL1XgM0i4ZK8MeAmFhsAs29MGZniawagS63oMOQUNXYB5D0D1RMDpyoMLw/fiE2og/V+PVDR5AiBl0/2Uwik+vx4xV3a5G5Ye68Nd1czjUjZckm6VhmPciRzeCZICjwTJAViQq+3e+St167rAoHK8sLYZVkBYPCZAZ/eGa+2R5LH7Wrc0YFf/O9J3yBDFaoAAAAASUVORK5CYII=); background-position: 9px 5px; - } +} - .OT_publisher .OT_mute.OT_active { +.OT_publisher .OT_mute.OT_active { background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABUAAAAdCAYAAABFRCf7AAADcElEQVRIiaWVXWhcRRTHf7NNd2aDtUKMIjTpg4ufFIuiUOmDEWm0Vi3VYhXRqIggQh4sWJFSig9+oOhTKSpIRUWMIBIr2kptoTbgU6ooxCiIjR+14kcJmf9sNceHnd3ebnc3Uv9wuXfOzPzmnDMz5zozGwdWAbc65w5RUJQ8cC2wDJgFJioh/MJCMrNxq2vOzK4HmIvRRemxKP0RJWt53o7S+d2Yzsx6gQ+AIUDAnUqpBLzXZd4RYFUlhB/bdZacc3PAOmAcCMC7wfvFwLNdoAPAyx09bXyYWRl4E7gDmAdGlNKFwLYu8GolhO9O87RJd64GbMrgEvB68P4osMWdXLtVV7czlooNpVRWSs8DO7NpR/B+3rBHsvetCgtCMTxwQCm9BbyQrc8F7/uBex3uRCeXO0PrUZ4NfKyUPgWeyj3bg/crDNsIRGwBaJQGorQ3Svdn2wHgc2BUKb0DPJHtjwfvbwRucc7tz+N+i9LFUdoXpfVN36I0CVwBTFI/q9e1LPxT8P4qYEdu70q12mYzWw1MYQzjeJF6zq+shHC4B7jklOBPP/TzSunh4P0DwKvAfb5c9krpe+CcwsEoZdbhEvBM9wxRAl5RShcA9wAngE3B+8tLpdLuwrhp4MNmK0pfRWkySr7NXS8+L5nZbWZWy/Vin1IaitJnUTqvwevJ71lgSSWEFKUfHG7Q2m/xqFJaGry/GXgfGPLl8mJgrXPur2JoUC8Qy3OpG+sAbGhEKT0ErAWOA6uBPWbW1wr9BOgFbgKezot0kAPYqJQA1gC/A9cA+82svzksSn1R+jNKX0SpnM/e1x3yqig92JhrZivM7FjO8bSZLSuCR/Ok16K0KMNHojQWpYko7Y7S1igN5PE3ROl4lNaZ2UVmNpPBU01orvZvZPCeKFXbBR+lEKVtUapFaSZKg9njqpl9aWYTrmXCImA7sCWb9lK/jj9TrwkrgA1AH3AQuKsSwkzbrLfxpgpsBtYDxf/R3xm2ExirhNCuHHZXTsmRwiat+S/zSt06eysVA/4pmGr/G3qm6ik28v29FKgCg8BS6pvS0KNRGgZ+Bb4FpsxsOkfUlMuwDcBWYOUZOHYM2AU8WQmhBifDv70O7PjX7KZ+4G7g3FM8zd6uBIaBy4AqxnIcZwFLCovPAhE4Sj38b4BDwEeVEFKD9S94Khjn486v3QAAAABJRU5ErkJggg==); background-position: 9px 4px; - } +} - .OT_subscriber .OT_mute { +.OT_subscriber .OT_mute { background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABcAAAATCAYAAAB7u5a2AAABx0lEQVQ4jaWUv48NURiGn3ONmCs32ZBd28ht1gqyZAkF21ylQkEiSp2ehpDlD1BoFGqqVdJohYKI7MaPxMoVNghCWMF+7ybLUewnOXfcMWO9yeQ857zne8+XmZOBGjJpr0kvTIomvTZpS526UCO4DUwD64FjwCFgqZnnR+oc8LfgzKQ73vGsr42ZtGjSQFV9o8KfBCacZwCaef4YmAf2rzjcpN3A2WSpm/AssKcqPDNpDBjs410CViXzTwk/A7b1C4wxDgOngAsZcAXY2buDfp/6S4F3lDS8DjgBzDWAjX/Y/e/QgYS/AhsKHa+OMQ6GEJ4Cj4BOAxgq6aCowyZtdf4OtAr+FHDO+R4wWnVbihr3cQnICt4boO38GWj9a/icjwOACt4m4K3zEPA+AxaAtTWCnwN3lzHkEL8V/OPAGud9wK2GF9XR1Wae/1zG2AI+pGYI4VUIoRtjHAc2A9cz4LRPevYCZ+i9/4sJt4GXJU10gaPAzdI2TTro/5Tfz8XEe2LSZGmxq/SDNvP8BnA5WRrx4BwYBe6vONx1EnjovGvBLAAd4Adwuyq8UiaNmDTvr+a8SQ9MuvbfwckBHZPe+QEfTdpep+4XZmPBHiHgz74AAAAASUVORK5CYII=); background-position: 8px 7px; - } +} - .OT_subscriber .OT_mute.OT_active { +.OT_subscriber .OT_mute.OT_active { background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAUCAYAAACXtf2DAAACtklEQVQ4jZ2VSYiURxTHf+/T9Nc9iRrBuYySmIsXUU9iFMEFERRBvAjJLUQi5ioiHvSScfTmgqC4XAT1ZIgLuJHkICaaQAgKI2hAUBT30bjUq7bbv4eukXK029F3+eqtv/fqK6qQdEnSNUmT6CDB/bvgfjO4N9zj2RD8007xg1IABkwEzkma0qb4PGAPMBZYLtSD8eNwAEjqTlNI0gNJM4YU7w7ut4O7gvuhZFsR3C8NC5BBLiTIY0mzM8AvqbiC++pk+zLpE95XuwAws3vAQuBPYDRwWtL84P4tsDSLv5oaug4EYOawAMF9jMdoLxqNZcDvQA04UVYqL4G/svj7AF21mhJscrvCksYBFO7xc2AAGGg2mrdjvf4rcAyomNn+slLZmUEGBgsYdh945xZJmgvckDSrEJpK6ySBgV6q12O8ABwGPjGzfWWlsjdN9rpjoSfA+DYDXARGAksK4Is3XC1Ub4z1f4CDQGFmu6tleQSYk0U+p7WVeefLJc00s4fAeWB6Qeunvj0m2ugx9gO7kmlrtSxvBfcy6fXUZS6rgG/S+jLQUwCVNmMC9HqM14EtSe+rluWazN8YEv8IqKZ1E1qnaIDO0ucx3gX6kv6TpM3AM+D/IbGjgP60/gq4WQA33gMA2OQxPgHWJX1ttSwL4FAeZGYLgB2SasBs4A8L7qOBf9M0uXQB3a+TMYSmVctyDrA9mfcBK82smSdKWgCcAaa1bTm4fxbc/8uuCQX3RanAD5Ka6Wo5IGnE0HxJPZ03pQX5Org3MsD3AO5xXLPZXJ9BjkrqdFg6QjZkgG3Jtsw93pG0VFI9QU5K6voYQBHcTydAfwheBI9HgvvPAJIWS3qeIL9JGvUxkO7gfi1BrqTvwkG/pPmSnibIqTzXPgAyEVgBjAEu1qrVPbk/PVTHgb/NbPGg/RVIzOQqzSTBaQAAAABJRU5ErkJggg==); background-position: 7px 7px; - } +} - /** +/** * Styles for display modes * * Note: It's important that these completely control the display and opacity * attributes, no other selectors should atempt to change them. */ - /* Default display mode transitions for various chrome elements */ - .OT_publisher .OT_edge-bar-item, - .OT_subscriber .OT_edge-bar-item { +/* Default display mode transitions for various chrome elements */ +.OT_publisher .OT_edge-bar-item, +.OT_subscriber .OT_edge-bar-item { -webkit-transition-property: top, bottom, opacity; transition-property: top, bottom, opacity; -webkit-transition-duration: 0.5s; transition-duration: 0.5s; -webkit-transition-timing-function: ease-in; transition-timing-function: ease-in; - } +} - .OT_publisher .OT_edge-bar-item.OT_mode-off, - .OT_subscriber .OT_edge-bar-item.OT_mode-off, - .OT_publisher .OT_edge-bar-item.OT_mode-auto, - .OT_subscriber .OT_edge-bar-item.OT_mode-auto, - .OT_publisher .OT_edge-bar-item.OT_mode-mini-auto, - .OT_subscriber .OT_edge-bar-item.OT_mode-mini-auto { +.OT_publisher .OT_edge-bar-item.OT_mode-off, +.OT_subscriber .OT_edge-bar-item.OT_mode-off, +.OT_publisher .OT_edge-bar-item.OT_mode-auto, +.OT_subscriber .OT_edge-bar-item.OT_mode-auto, +.OT_publisher .OT_edge-bar-item.OT_mode-mini-auto, +.OT_subscriber .OT_edge-bar-item.OT_mode-mini-auto { top: -25px; opacity: 0; - } +} - .OT_publisher .OT_edge-bar-item.OT_mode-off, - .OT_subscriber .OT_edge-bar-item.OT_mode-off { +.OT_publisher .OT_edge-bar-item.OT_mode-off, +.OT_subscriber .OT_edge-bar-item.OT_mode-off { display: none; - } +} - .OT_mini .OT_mute.OT_mode-auto, - .OT_publisher .OT_mute.OT_mode-mini-auto, - .OT_subscriber .OT_mute.OT_mode-mini-auto { +.OT_mini .OT_mute.OT_mode-auto, +.OT_publisher .OT_mute.OT_mode-mini-auto, +.OT_subscriber .OT_mute.OT_mode-mini-auto { top: 50%; - } +} - .OT_publisher .OT_edge-bar-item.OT_edge-bottom.OT_mode-off, - .OT_subscriber .OT_edge-bar-item.OT_edge-bottom.OT_mode-off, - .OT_publisher .OT_edge-bar-item.OT_edge-bottom.OT_mode-auto, - .OT_subscriber .OT_edge-bar-item.OT_edge-bottom.OT_mode-auto, - .OT_publisher .OT_edge-bar-item.OT_edge-bottom.OT_mode-mini-auto, - .OT_subscriber .OT_edge-bar-item.OT_edge-bottom.OT_mode-mini-auto { +.OT_publisher .OT_edge-bar-item.OT_edge-bottom.OT_mode-off, +.OT_subscriber .OT_edge-bar-item.OT_edge-bottom.OT_mode-off, +.OT_publisher .OT_edge-bar-item.OT_edge-bottom.OT_mode-auto, +.OT_subscriber .OT_edge-bar-item.OT_edge-bottom.OT_mode-auto, +.OT_publisher .OT_edge-bar-item.OT_edge-bottom.OT_mode-mini-auto, +.OT_subscriber .OT_edge-bar-item.OT_edge-bottom.OT_mode-mini-auto { top: auto; bottom: -25px; - } +} - .OT_publisher .OT_edge-bar-item.OT_mode-on, - .OT_subscriber .OT_edge-bar-item.OT_mode-on, - .OT_publisher .OT_edge-bar-item.OT_mode-auto.OT_mode-on-hold, - .OT_subscriber .OT_edge-bar-item.OT_mode-auto.OT_mode-on-hold, - .OT_publisher:hover .OT_edge-bar-item.OT_mode-auto, - .OT_subscriber:hover .OT_edge-bar-item.OT_mode-auto, - .OT_publisher:hover .OT_edge-bar-item.OT_mode-mini-auto, - .OT_subscriber:hover .OT_edge-bar-item.OT_mode-mini-auto { +.OT_publisher .OT_edge-bar-item.OT_mode-on, +.OT_subscriber .OT_edge-bar-item.OT_mode-on, +.OT_publisher .OT_edge-bar-item.OT_mode-auto.OT_mode-on-hold, +.OT_subscriber .OT_edge-bar-item.OT_mode-auto.OT_mode-on-hold, +.OT_publisher:hover .OT_edge-bar-item.OT_mode-auto, +.OT_subscriber:hover .OT_edge-bar-item.OT_mode-auto, +.OT_publisher:hover .OT_edge-bar-item.OT_mode-mini-auto, +.OT_subscriber:hover .OT_edge-bar-item.OT_mode-mini-auto { top: 0; opacity: 1; - } +} - .OT_mini .OT_mute.OT_mode-on, - .OT_mini:hover .OT_mute.OT_mode-auto, - .OT_mute.OT_mode-mini, - .OT_root:hover .OT_mute.OT_mode-mini-auto { +.OT_mini .OT_mute.OT_mode-on, +.OT_mini:hover .OT_mute.OT_mode-auto, +.OT_mute.OT_mode-mini, +.OT_root:hover .OT_mute.OT_mode-mini-auto { top: 50%; - } +} - .OT_publisher .OT_edge-bar-item.OT_edge-bottom.OT_mode-on, - .OT_subscriber .OT_edge-bar-item.OT_edge-bottom.OT_mode-on, - .OT_publisher:hover .OT_edge-bar-item.OT_edge-bottom.OT_mode-auto, - .OT_subscriber:hover .OT_edge-bar-item.OT_edge-bottom.OT_mode-auto { +.OT_publisher .OT_edge-bar-item.OT_edge-bottom.OT_mode-on, +.OT_subscriber .OT_edge-bar-item.OT_edge-bottom.OT_mode-on, +.OT_publisher:hover .OT_edge-bar-item.OT_edge-bottom.OT_mode-auto, +.OT_subscriber:hover .OT_edge-bar-item.OT_edge-bottom.OT_mode-auto { top: auto; bottom: 0; opacity: 1; - } +} - /* Load animation */ - .OT_root .OT_video-loading { +/* Load animation */ +.OT_root .OT_video-loading { position: absolute; z-index: 1; width: 100%; @@ -552,11 +557,11 @@ display: none; background-color: rgba(0, 0, 0, 0.75); - } +} - .OT_root .OT_video-loading .OT_video-loading-spinner { +.OT_root .OT_video-loading .OT_video-loading-spinner { background: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9Ii0yMCAtMjAgMjQwIDI0MCI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJhIiB4Mj0iMCIgeTI9IjEiPjxzdG9wIG9mZnNldD0iMCIgc3RvcC1jb2xvcj0iI2ZmZiIgc3RvcC1vcGFjaXR5PSIwIi8+PHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjZmZmIiBzdG9wLW9wYWNpdHk9IjAiLz48L2xpbmVhckdyYWRpZW50PjxsaW5lYXJHcmFkaWVudCBpZD0iYiIgeDE9IjEiIHgyPSIwIiB5Mj0iMSI+PHN0b3Agb2Zmc2V0PSIwIiBzdG9wLWNvbG9yPSIjZmZmIiBzdG9wLW9wYWNpdHk9IjAiLz48c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiNmZmYiIHN0b3Atb3BhY2l0eT0iLjA4Ii8+PC9saW5lYXJHcmFkaWVudD48bGluZWFyR3JhZGllbnQgaWQ9ImMiIHgxPSIxIiB4Mj0iMCIgeTE9IjEiPjxzdG9wIG9mZnNldD0iMCIgc3RvcC1jb2xvcj0iI2ZmZiIgc3RvcC1vcGFjaXR5PSIuMDgiLz48c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiNmZmYiIHN0b3Atb3BhY2l0eT0iLjE2Ii8+PC9saW5lYXJHcmFkaWVudD48bGluZWFyR3JhZGllbnQgaWQ9ImQiIHgyPSIwIiB5MT0iMSI+PHN0b3Agb2Zmc2V0PSIwIiBzdG9wLWNvbG9yPSIjZmZmIiBzdG9wLW9wYWNpdHk9Ii4xNiIvPjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iI2ZmZiIgc3RvcC1vcGFjaXR5PSIuMzMiLz48L2xpbmVhckdyYWRpZW50PjxsaW5lYXJHcmFkaWVudCBpZD0iZSIgeDI9IjEiIHkxPSIxIj48c3RvcCBvZmZzZXQ9IjAiIHN0b3AtY29sb3I9IiNmZmYiIHN0b3Atb3BhY2l0eT0iLjMzIi8+PHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjZmZmIiBzdG9wLW9wYWNpdHk9Ii42NiIvPjwvbGluZWFyR3JhZGllbnQ+PGxpbmVhckdyYWRpZW50IGlkPSJmIiB4Mj0iMSIgeTI9IjEiPjxzdG9wIG9mZnNldD0iMCIgc3RvcC1jb2xvcj0iI2ZmZiIgc3RvcC1vcGFjaXR5PSIuNjYiLz48c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiNmZmYiLz48L2xpbmVhckdyYWRpZW50PjxtYXNrIGlkPSJnIj48ZyBmaWxsPSJub25lIiBzdHJva2Utd2lkdGg9IjQwIj48cGF0aCBzdHJva2U9InVybCgjYSkiIGQ9Ik04Ni42LTUwYTEwMCAxMDAgMCAwIDEgMCAxMDAiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDEwMCAxMDApIi8+PHBhdGggc3Ryb2tlPSJ1cmwoI2IpIiBkPSJNODYuNiA1MEExMDAgMTAwIDAgMCAxIDAgMTAwIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxMDAgMTAwKSIvPjxwYXRoIHN0cm9rZT0idXJsKCNjKSIgZD0iTTAgMTAwYTEwMCAxMDAgMCAwIDEtODYuNi01MCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTAwIDEwMCkiLz48cGF0aCBzdHJva2U9InVybCgjZCkiIGQ9Ik0tODYuNiA1MGExMDAgMTAwIDAgMCAxIDAtMTAwIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxMDAgMTAwKSIvPjxwYXRoIHN0cm9rZT0idXJsKCNlKSIgZD0iTS04Ni42LTUwQTEwMCAxMDAgMCAwIDEgMC0xMDAiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDEwMCAxMDApIi8+PHBhdGggc3Ryb2tlPSJ1cmwoI2YpIiBkPSJNMC0xMDBhMTAwIDEwMCAwIDAgMSA4Ni42IDUwIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxMDAgMTAwKSIvPjwvZz48L21hc2s+PC9kZWZzPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIHg9Ii0yMCIgeT0iLTIwIiBtYXNrPSJ1cmwoI2cpIiBmaWxsPSIjZmZmIi8+PC9zdmc+) - no-repeat; + no-repeat; position: absolute; width: 32px; height: 32px; @@ -566,36 +571,36 @@ margin-top: -16px; -webkit-animation: OT_spin 2s linear infinite; animation: OT_spin 2s linear infinite; - } - @-webkit-keyframes OT_spin { +} +@-webkit-keyframes OT_spin { 100% { - -webkit-transform: rotate(360deg); + -webkit-transform: rotate(360deg); } - } - @keyframes OT_spin { +} +@keyframes OT_spin { 100% { - -webkit-transform: rotate(360deg); - transform: rotate(360deg); + -webkit-transform: rotate(360deg); + transform: rotate(360deg); } - } +} - .OT_publisher.OT_loading .OT_video-loading, - .OT_subscriber.OT_loading .OT_video-loading { +.OT_publisher.OT_loading .OT_video-loading, +.OT_subscriber.OT_loading .OT_video-loading { display: block; - } +} - .OT_video-centering { +.OT_video-centering { display: table; width: 100%; height: 100%; - } +} - .OT_video-container { +.OT_video-container { display: table-cell; vertical-align: middle; - } +} - .OT_video-poster { +.OT_video-poster { position: absolute; z-index: 1; width: 100%; @@ -607,36 +612,36 @@ background-repeat: no-repeat; background-image: url(data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgNDcxIDQ2NCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48bGluZWFyR3JhZGllbnQgaWQ9ImEiIHgyPSIwIiB5Mj0iMSI+PHN0b3Agb2Zmc2V0PSI2Ni42NiUiIHN0b3AtY29sb3I9IiNmZmYiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNmZmYiIHN0b3Atb3BhY2l0eT0iMCIvPjwvbGluZWFyR3JhZGllbnQ+PHBhdGggZmlsbD0idXJsKCNhKSIgZD0iTTc5IDMwOGMxNC4yNS02LjUgNTQuMjUtMTkuNzUgNzEtMjkgOS0zLjI1IDI1LTIxIDI1LTIxczMuNzUtMTMgMy0yMmMtMS43NS02Ljc1LTE1LTQzLTE1LTQzLTIuNSAzLTQuNzQxIDMuMjU5LTcgMS0zLjI1LTcuNS0yMC41LTQ0LjUtMTYtNTcgMS4yNS03LjUgMTAtNiAxMC02LTExLjI1LTMzLjc1LTgtNjctOC02N3MuMDczLTcuMzQ2IDYtMTVjLTMuNDguNjM3LTkgNC05IDQgMi41NjMtMTEuNzI3IDE1LTIxIDE1LTIxIC4xNDgtLjMxMi0xLjMyMS0xLjQ1NC0xMCAxIDEuNS0yLjc4IDE2LjY3NS04LjY1NCAzMC0xMSAzLjc4Ny05LjM2MSAxMi43ODItMTcuMzk4IDIyLTIyLTIuMzY1IDMuMTMzLTMgNi0zIDZzMTUuNjQ3LTguMDg4IDQxLTZjLTE5Ljc1IDItMjQgNi0yNCA2czc0LjUtMTAuNzUgMTA0IDM3YzcuNSA5LjUgMjQuNzUgNTUuNzUgMTAgODkgMy43NS0xLjUgNC41LTQuNSA5IDEgLjI1IDE0Ljc1LTExLjUgNjMtMTkgNjItMi43NSAxLTQtMy00LTMtMTAuNzUgMjkuNS0xNCAzOC0xNCAzOC0yIDQuMjUtMy43NSAxOC41LTEgMjIgMS4yNSA0LjUgMjMgMjMgMjMgMjNsMTI3IDUzYzM3IDM1IDIzIDEzNSAyMyAxMzVMMCA0NjRzLTMtOTYuNzUgMTQtMTIwYzUuMjUtNi4yNSAyMS43NS0xOS43NSA2NS0zNnoiLz48L3N2Zz4=); background-size: auto 76%; - } +} - .OT_fit-mode-cover .OT_video-element { +.OT_fit-mode-cover .OT_video-element { -o-object-fit: cover; object-fit: cover; - } +} - /* Workaround for iOS freezing issue when cropping videos */ - /* https://bugs.webkit.org/show_bug.cgi?id=176439 */ - @media only screen and (orientation: portrait) { +/* Workaround for iOS freezing issue when cropping videos */ +/* https://bugs.webkit.org/show_bug.cgi?id=176439 */ +@media only screen and (orientation: portrait) { .OT_subscriber.OT_ForceContain.OT_fit-mode-cover .OT_video-element { - -o-object-fit: contain !important; - object-fit: contain !important; + -o-object-fit: contain !important; + object-fit: contain !important; } - } +} - .OT_fit-mode-contain .OT_video-element { +.OT_fit-mode-contain .OT_video-element { -o-object-fit: contain; object-fit: contain; - } +} - .OT_fit-mode-cover .OT_video-poster { +.OT_fit-mode-cover .OT_video-poster { background-position: center bottom; - } +} - .OT_fit-mode-contain .OT_video-poster { +.OT_fit-mode-contain .OT_video-poster { background-position: center; - } +} - .OT_audio-level-meter { +.OT_audio-level-meter { position: absolute; width: 25%; max-width: 224px; @@ -644,16 +649,16 @@ top: 0; right: 0; overflow: hidden; - } +} - .OT_audio-level-meter:before { +.OT_audio-level-meter:before { /* makes the height of the container equals its width */ content: ''; display: block; padding-top: 100%; - } +} - .OT_audio-level-meter__bar { +.OT_audio-level-meter__bar { position: absolute; width: 192%; /* meter value can overflow of 8% */ height: 192%; @@ -662,9 +667,9 @@ border-radius: 50%; background-color: rgba(0, 0, 0, 0.8); - } +} - .OT_audio-level-meter__audio-only-img { +.OT_audio-level-meter__audio-only-img { position: absolute; top: 22%; right: 15%; @@ -673,37 +678,37 @@ opacity: 0.7; background: url(data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgNzkgODYiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGcgZmlsbD0iI2ZmZiI+PHBhdGggZD0iTTkuNzU3IDQwLjkyNGMzLjczOC01LjE5MSAxMi43MTEtNC4zMDggMTIuNzExLTQuMzA4IDIuMjIzIDMuMDE0IDUuMTI2IDI0LjU4NiAzLjYyNCAyOC43MTgtMS40MDEgMS4zMDEtMTEuNjExIDEuNjI5LTEzLjM4LTEuNDM2LTEuMjI2LTguODA0LTIuOTU1LTIyLjk3NS0yLjk1NS0yMi45NzV6bTU4Ljc4NSAwYy0zLjczNy01LjE5MS0xMi43MTEtNC4zMDgtMTIuNzExLTQuMzA4LTIuMjIzIDMuMDE0LTUuMTI2IDI0LjU4Ni0zLjYyNCAyOC43MTggMS40MDEgMS4zMDEgMTEuNjExIDEuNjI5IDEzLjM4LTEuNDM2IDEuMjI2LTguODA0IDIuOTU1LTIyLjk3NSAyLjk1NS0yMi45NzV6Ii8+PHBhdGggZD0iTTY4LjY0NyA1OC42Yy43MjktNC43NTMgMi4zOC05LjU2MSAyLjM4LTE0LjgwNCAwLTIxLjQxMi0xNC4xMTUtMzguNzctMzEuNTI4LTM4Ljc3LTE3LjQxMiAwLTMxLjUyNyAxNy4zNTgtMzEuNTI3IDM4Ljc3IDAgNC41NDEuNTE1IDguOTM2IDEuODAyIDEyLjk1IDEuNjk4IDUuMjk1LTUuNTQyIDYuOTkxLTYuNjE2IDIuMDczQzIuNDEgNTUuMzk0IDAgNTEuNzg3IDAgNDguMTAzIDAgMjEuNTM2IDE3LjY4NSAwIDM5LjUgMCA2MS4zMTYgMCA3OSAyMS41MzYgNzkgNDguMTAzYzAgLjcxOC0yLjg5OSA5LjY5My0zLjI5MiAxMS40MDgtLjc1NCAzLjI5My03Ljc1MSAzLjU4OS03LjA2MS0uOTEyeiIvPjxwYXRoIGQ9Ik01LjA4NCA1MS4zODVjLS44MDQtMy43ODIuNTY5LTcuMzM1IDMuMTM0LTcuOTIxIDIuNjM2LS42MDMgNS40ODUgMi4xNSA2LjI4OSA2LjEzMi43OTcgMy45NDgtLjc1MiA3LjQ1Ny0zLjM4OCA3Ljg1OS0yLjU2Ni4zOTEtNS4yMzctMi4zMTgtNi4wMzQtNi4wN3ptNjguODM0IDBjLjgwNC0zLjc4Mi0uNTY4LTcuMzM1LTMuMTMzLTcuOTIxLTIuNjM2LS42MDMtNS40ODUgMi4xNS02LjI4OSA2LjEzMi0uNzk3IDMuOTQ4Ljc1MiA3LjQ1NyAzLjM4OSA3Ljg1OSAyLjU2NS4zOTEgNS4yMzctMi4zMTggNi4wMzQtNi4wN3ptLTIuMDM4IDguMjg4Yy0uOTI2IDE5LjY1OS0xNS4xMTIgMjQuNzU5LTI1Ljg1OSAyMC40NzUtNS40MDUtLjYwNi0zLjAzNCAxLjI2Mi0zLjAzNCAxLjI2MiAxMy42NjEgMy41NjIgMjYuMTY4IDMuNDk3IDMxLjI3My0yMC41NDktLjU4NS00LjUxMS0yLjM3OS0xLjE4Ny0yLjM3OS0xLjE4N3oiLz48cGF0aCBkPSJNNDEuNjYyIDc4LjQyMmw3LjU1My41NWMxLjE5Mi4xMDcgMi4xMiAxLjE1MyAyLjA3MiAyLjMzNWwtLjEwOSAyLjczOGMtLjA0NyAxLjE4Mi0xLjA1MSAyLjA1NC0yLjI0MyAxLjk0NmwtNy41NTMtLjU1Yy0xLjE5MS0uMTA3LTIuMTE5LTEuMTUzLTIuMDcyLTIuMzM1bC4xMDktMi43MzdjLjA0Ny0xLjE4MiAxLjA1Mi0yLjA1NCAyLjI0My0xLjk0N3oiLz48L2c+PC9zdmc+) - no-repeat center; - } + no-repeat center; +} - .OT_audio-level-meter__audio-only-img:before { +.OT_audio-level-meter__audio-only-img:before { /* makes the height of the container equals its width */ content: ''; display: block; padding-top: 100%; - } +} - .OT_audio-level-meter__value { +.OT_audio-level-meter__value { position: absolute; border-radius: 50%; background-image: radial-gradient(circle, rgba(151, 206, 0, 1) 0%, rgba(151, 206, 0, 0) 100%); - } +} - .OT_audio-level-meter.OT_mode-off { +.OT_audio-level-meter.OT_mode-off { display: none; - } +} - .OT_audio-level-meter.OT_mode-on, - .OT_audio-only .OT_audio-level-meter.OT_mode-auto { +.OT_audio-level-meter.OT_mode-on, +.OT_audio-only .OT_audio-level-meter.OT_mode-auto { display: block; - } +} - .OT_audio-only.OT_publisher .OT_video-element, - .OT_audio-only.OT_subscriber .OT_video-element { +.OT_audio-only.OT_publisher .OT_video-element, +.OT_audio-only.OT_subscriber .OT_video-element { display: none; - } +} - .OT_video-disabled-indicator { +.OT_video-disabled-indicator { opacity: 1; border: none; display: none; @@ -716,23 +721,23 @@ left: 0; bottom: 3px; right: 3px; - } +} - .OT_video-disabled { +.OT_video-disabled { background-image: url(data:image/png;base64,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); background-size: 33px auto; - } +} - .OT_video-disabled-warning { +.OT_video-disabled-warning { background-image: url(data:image/png;base64,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); background-size: 33px auto; - } +} - .OT_video-disabled-indicator.OT_active { +.OT_video-disabled-indicator.OT_active { display: block; - } +} - .OT_audio-blocked-indicator { +.OT_audio-blocked-indicator { opacity: 1; border: none; display: none; @@ -745,30 +750,30 @@ left: 0; bottom: 0; right: 0; - } +} - .OT_audio-blocked { +.OT_audio-blocked { background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iMTUwIiBoZWlnaHQ9IjkwIj48ZGVmcz48cGF0aCBkPSJNNjcgMTJMNi40NDggNzIuNTUyIDAgMzFWMThMMjYgMGw0MSAxMnptMyA3bDYgNDctMjkgMTgtMzUuNTAyLTYuNDk4TDcwIDE5eiIgaWQ9ImEiLz48L2RlZnM+PHJlY3Qgd2lkdGg9IjE1MCIgaGVpZ2h0PSI5MCIgcng9IjM1IiByeT0iNDUiIG9wYWNpdHk9Ii41Ii8+PGcgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIj48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgzNikiPjxtYXNrIGlkPSJiIiBmaWxsPSIjZmZmIj48dXNlIHhsaW5rOmhyZWY9IiNhIi8+PC9tYXNrPjxwYXRoIGQ9Ik0zOS4yNDkgNTEuMzEyYy42OTcgMTAuMzcgMi43ODUgMTcuODk3IDUuMjUxIDE3Ljg5NyAzLjAzOCAwIDUuNS0xMS40MTcgNS41LTI1LjVzLTIuNDYyLTI1LjUtNS41LTI1LjVjLTIuNTEgMC00LjYyOCA3Ljc5Ny01LjI4NyAxOC40NTNBOC45ODkgOC45ODkgMCAwIDEgNDMgNDRhOC45ODggOC45ODggMCAwIDEtMy43NTEgNy4zMTJ6TTIwLjk4NSAzMi4yMjRsMTUuNzQ2LTE2Ljg3N2E3LjM4NSA3LjM4NSAwIDAgMSAxMC4zNzQtLjQyQzUxLjcwMiAxOS4xMTQgNTQgMjkuMjA4IDU0IDQ1LjIwOGMwIDE0LjUyNy0yLjM0MyAyMy44OC03LjAzIDI4LjA1OGE3LjI4IDcuMjggMCAwIDEtMTAuMTY4LS40NjhMMjAuNDA1IDU1LjIyNEgxMmE1IDUgMCAwIDEtNS01di0xM2E1IDUgMCAwIDEgNS01aDguOTg1eiIgZmlsbD0iI0ZGRiIgbWFzaz0idXJsKCNiKSIvPjwvZz48cGF0aCBkPSJNMTA2LjUgMTMuNUw0NC45OTggNzUuMDAyIiBzdHJva2U9IiNGRkYiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIi8+PC9nPjwvc3ZnPg==); background-size: 90px auto; - } +} - .OT_container-audio-blocked { +.OT_container-audio-blocked { cursor: pointer; - } +} - .OT_container-audio-blocked.OT_mini .OT_edge-bar-item { +.OT_container-audio-blocked.OT_mini .OT_edge-bar-item { display: none; - } +} - .OT_container-audio-blocked .OT_mute { +.OT_container-audio-blocked .OT_mute { display: none; - } +} - .OT_audio-blocked-indicator.OT_active { +.OT_audio-blocked-indicator.OT_active { display: block; - } +} - .OT_video-unsupported { +.OT_video-unsupported { opacity: 1; border: none; display: none; @@ -784,9 +789,9 @@ bottom: 0; right: 0; margin-top: -30px; - } +} - .OT_video-unsupported-bar { +.OT_video-unsupported-bar { display: none; position: absolute; width: 192%; /* copy the size of the audio meter bar for symmetry */ @@ -796,9 +801,9 @@ border-radius: 50%; background-color: rgba(0, 0, 0, 0.8); - } +} - .OT_video-unsupported-img { +.OT_video-unsupported-img { display: none; position: absolute; top: 11%; @@ -809,16 +814,16 @@ background-repeat: no-repeat; background-position: center; background-size: 100% auto; - } +} - .OT_video-unsupported-img:before { +.OT_video-unsupported-img:before { /* makes the height of the container 93% of its width (90/97 px) */ content: ''; display: block; padding-top: 93%; - } +} - .OT_video-unsupported-text { +.OT_video-unsupported-text { display: -webkit-box; display: -ms-flexbox; display: flex; @@ -831,4 +836,4 @@ text-align: center; height: 100%; margin-top: 40px; - } +} diff --git a/openvidu-components-angular/projects/openvidu-angular/src/lib/components/layout/layout.component.html b/openvidu-components-angular/projects/openvidu-angular/src/lib/components/layout/layout.component.html index 1a7e39a5..a5a59642 100644 --- a/openvidu-components-angular/projects/openvidu-angular/src/lib/components/layout/layout.component.html +++ b/openvidu-components-angular/projects/openvidu-angular/src/lib/components/layout/layout.component.html @@ -1,18 +1,18 @@ -
-
- +
+
+
+ +
+ +
+ +
-
- -
+
diff --git a/openvidu-components-angular/projects/openvidu-angular/src/lib/components/layout/layout.component.ts b/openvidu-components-angular/projects/openvidu-angular/src/lib/components/layout/layout.component.ts index e7f06d1a..5eafadc2 100644 --- a/openvidu-components-angular/projects/openvidu-angular/src/lib/components/layout/layout.component.ts +++ b/openvidu-components-angular/projects/openvidu-angular/src/lib/components/layout/layout.component.ts @@ -73,8 +73,14 @@ export class LayoutComponent implements OnInit, OnDestroy, AfterViewInit { localParticipant: ParticipantAbstractModel; remoteParticipants: ParticipantAbstractModel[] = []; - protected localParticipantSubs: Subscription; - protected remoteParticipantsSubs: Subscription; + /** + * @ignore + */ + subtitlesEnabled = true; + + private localParticipantSubs: Subscription; + private remoteParticipantsSubs: Subscription; + private subtitlesSubs: Subscription; /** * @ignore @@ -83,10 +89,11 @@ export class LayoutComponent implements OnInit, OnDestroy, AfterViewInit { ngOnInit(): void { this.subscribeToParticipants(); + this.subscribeToSubtitles(); } ngAfterViewInit() { - let timeout: number = 0; + let timeout: number = 100; this.layoutService.initialize(timeout); this.layoutService.update(timeout); } @@ -96,9 +103,18 @@ export class LayoutComponent implements OnInit, OnDestroy, AfterViewInit { this.remoteParticipants = []; if (this.localParticipantSubs) this.localParticipantSubs.unsubscribe(); if (this.remoteParticipantsSubs) this.remoteParticipantsSubs.unsubscribe(); + if (this.subtitlesSubs) this.subtitlesSubs.unsubscribe(); this.layoutService.clear(); } + private subscribeToSubtitles() { + this.subtitlesSubs = this.layoutService.subtitlesTogglingObs.subscribe((value: boolean) => { + this.subtitlesEnabled = value; + this.cd.markForCheck(); + this.layoutService.update(); + }); + } + private subscribeToParticipants() { this.localParticipantSubs = this.participantService.localParticipantObs.subscribe((p) => { this.localParticipant = p; diff --git a/openvidu-components-angular/projects/openvidu-angular/src/lib/components/panel/settings-panel/settings-panel.component.html b/openvidu-components-angular/projects/openvidu-angular/src/lib/components/panel/settings-panel/settings-panel.component.html index 92d824bc..13511048 100644 --- a/openvidu-components-angular/projects/openvidu-angular/src/lib/components/panel/settings-panel/settings-panel.component.html +++ b/openvidu-components-angular/projects/openvidu-angular/src/lib/components/panel/settings-panel/settings-panel.component.html @@ -1,4 +1,4 @@ -
+

{{ 'PANEL.SETTINGS.TITLE' | translate }}

+ + + + + + + + diff --git a/openvidu-components-angular/projects/openvidu-angular/src/lib/components/settings/subtitles/subtitles.component.spec.ts b/openvidu-components-angular/projects/openvidu-angular/src/lib/components/settings/subtitles/subtitles.component.spec.ts new file mode 100644 index 00000000..4c6d1353 --- /dev/null +++ b/openvidu-components-angular/projects/openvidu-angular/src/lib/components/settings/subtitles/subtitles.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { SubtitlesComponent } from './subtitles.component'; + +describe('SubtitlesComponent', () => { + let component: SubtitlesComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ SubtitlesComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(SubtitlesComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/openvidu-components-angular/projects/openvidu-angular/src/lib/components/settings/subtitles/subtitles.component.ts b/openvidu-components-angular/projects/openvidu-angular/src/lib/components/settings/subtitles/subtitles.component.ts new file mode 100644 index 00000000..7488fc23 --- /dev/null +++ b/openvidu-components-angular/projects/openvidu-angular/src/lib/components/settings/subtitles/subtitles.component.ts @@ -0,0 +1,40 @@ +import { Component, OnDestroy, OnInit } from '@angular/core'; +import { Subscription } from 'rxjs'; +import { LayoutService } from '../../../services/layout/layout.service'; + +@Component({ + selector: 'ov-subtitles-settings', + templateUrl: './subtitles.component.html', + styleUrls: ['./subtitles.component.css'] +}) +export class SubtitlesSettingComponent implements OnInit, OnDestroy { + subtitlesEnabled: boolean; + languagesAvailable = []; + subtitlesSubs: Subscription; + langSelected: string = 'English'; + + constructor(private layoutService: LayoutService) {} + + ngOnInit(): void { + this.subscribeToSubtitles(); + } + + ngOnDestroy() { + if (this.subtitlesSubs) this.subtitlesSubs.unsubscribe(); + } + + onLangSelected(lang: string){ + this.langSelected = lang; + } + + toggleSubtitles() { + this.layoutService.toggleSubtitles(); + } + + private subscribeToSubtitles() { + this.subtitlesSubs = this.layoutService.subtitlesTogglingObs.subscribe((value: boolean) => { + this.subtitlesEnabled = value; + // this.cd.markForCheck(); + }); + } +} diff --git a/openvidu-components-angular/projects/openvidu-angular/src/lib/components/subtitles/subtitles.component.css b/openvidu-components-angular/projects/openvidu-angular/src/lib/components/subtitles/subtitles.component.css new file mode 100644 index 00000000..cdd21bd2 --- /dev/null +++ b/openvidu-components-angular/projects/openvidu-angular/src/lib/components/subtitles/subtitles.component.css @@ -0,0 +1,44 @@ +.subtitles-container { + /* padding: 5px; */ + display: flex; + height: 75px; +} +.subtitles-offset { + height: 75px; + width: 115px; + text-align: center; +} + +.subtitles-main-container { + flex-grow: 1; + text-align: center; + align-self: center; +} + +.subtitles-offset + .subtitles-offset { + margin-left: 2%; +} +#subtitle-settings-btn { + color: var(--ov-text-color); + background-color: var(--ov-secondary-color); +} +#subtitle-settings-icon { + font-size: 15px; + height: 15px; + width: 15px; + padding-right: 5px; +} + +#subtitle-text { + color: var(--ov-text-color); + background-color: var(--ov-logo-background-color); + font-size: 18px; + font-family: Arial, Helvetica, sans-serif; + padding: 4.5px; + line-height: 1.6; + word-break: break-word; +} + +.small-text { + font-size: 14px !important; +} diff --git a/openvidu-components-angular/projects/openvidu-angular/src/lib/components/subtitles/subtitles.component.html b/openvidu-components-angular/projects/openvidu-angular/src/lib/components/subtitles/subtitles.component.html new file mode 100644 index 00000000..5b8951ab --- /dev/null +++ b/openvidu-components-angular/projects/openvidu-angular/src/lib/components/subtitles/subtitles.component.html @@ -0,0 +1,12 @@ +
+
+ +
+
+ (Demo preview): {{ subtitleText }} +
+
+
diff --git a/openvidu-components-angular/projects/openvidu-angular/src/lib/components/subtitles/subtitles.component.spec.ts b/openvidu-components-angular/projects/openvidu-angular/src/lib/components/subtitles/subtitles.component.spec.ts new file mode 100644 index 00000000..4c6d1353 --- /dev/null +++ b/openvidu-components-angular/projects/openvidu-angular/src/lib/components/subtitles/subtitles.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { SubtitlesComponent } from './subtitles.component'; + +describe('SubtitlesComponent', () => { + let component: SubtitlesComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ SubtitlesComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(SubtitlesComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/openvidu-components-angular/projects/openvidu-angular/src/lib/components/subtitles/subtitles.component.ts b/openvidu-components-angular/projects/openvidu-angular/src/lib/components/subtitles/subtitles.component.ts new file mode 100644 index 00000000..0deaffeb --- /dev/null +++ b/openvidu-components-angular/projects/openvidu-angular/src/lib/components/subtitles/subtitles.component.ts @@ -0,0 +1,78 @@ +import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnInit } from '@angular/core'; +import { Subscription } from 'rxjs'; +import { PanelSettingsOptions, PanelType } from '../../models/panel.model'; +import { PanelEvent, PanelService } from '../../services/panel/panel.service'; +import { DocumentService } from '../../services/document/document.service'; +import { MediaChange } from '@angular/flex-layout'; + +//TODO: BORRAR +import { LoremIpsum } from 'lorem-ipsum'; + +/** + * @internal + */ +@Component({ + selector: 'ov-subtitles', + templateUrl: './subtitles.component.html', + styleUrls: ['./subtitles.component.css'], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class SubtitlesComponent implements OnInit { + /** + * @ignore + */ + subtitleText: string; + /** + * @ignore + */ + screenSize: string; + /** + * @ignore + */ + settingsPanelOpened: boolean; + private screenSizeSub: Subscription; + private panelTogglingSubscription: Subscription; + interval: NodeJS.Timer; + + constructor(private documentService: DocumentService, private panelService: PanelService, private cd: ChangeDetectorRef) {} + + ngOnInit(): void { + this.subscribeToScreenSize(); + this.subscribeToPanelToggling(); + + //TODO: Subscribe to openvidu-browser subtitle event + // TODO: REMOVE ------------------ + const lorem = new LoremIpsum(); + this.interval = setInterval(() => { + this.subtitleText = lorem.generateSentences(1); + this.cd.markForCheck(); + }, 3000); + // TODO: REMOVE ------------------ + } + + ngOnDestroy() { + if (this.screenSizeSub) this.screenSizeSub.unsubscribe(); + if(this.panelTogglingSubscription) this.panelTogglingSubscription.unsubscribe(); + //TODO: Unsubscribe to openvidu-browser subtitle event + clearInterval(this.interval); + } + + onSettingsCliked() { + this.panelService.togglePanel(PanelType.SETTINGS, PanelSettingsOptions.SUBTITLES); + } + + private subscribeToPanelToggling() { + this.panelTogglingSubscription = this.panelService.panelOpenedObs.subscribe((ev: PanelEvent) => { + this.settingsPanelOpened = ev.opened; + this.cd.markForCheck(); + }); + } + + private subscribeToScreenSize() { + this.screenSizeSub = this.documentService.screenSizeObs.subscribe((change: MediaChange[]) => { + this.screenSize = change[0].mqAlias; + console.log(this.screenSize); + this.cd.markForCheck(); + }); + } +} diff --git a/openvidu-components-angular/projects/openvidu-angular/src/lib/components/toolbar/toolbar.component.html b/openvidu-components-angular/projects/openvidu-angular/src/lib/components/toolbar/toolbar.component.html index a87a5727..b3842379 100644 --- a/openvidu-components-angular/projects/openvidu-angular/src/lib/components/toolbar/toolbar.component.html +++ b/openvidu-components-angular/projects/openvidu-angular/src/lib/components/toolbar/toolbar.component.html @@ -103,6 +103,19 @@ {{ 'TOOLBAR.BACKGROUND' | translate }} + + + diff --git a/openvidu-components-angular/projects/openvidu-angular/src/lib/components/toolbar/toolbar.component.ts b/openvidu-components-angular/projects/openvidu-angular/src/lib/components/toolbar/toolbar.component.ts index a4865707..b810ed5c 100644 --- a/openvidu-components-angular/projects/openvidu-angular/src/lib/components/toolbar/toolbar.component.ts +++ b/openvidu-components-angular/projects/openvidu-angular/src/lib/components/toolbar/toolbar.component.ts @@ -39,6 +39,7 @@ import { RecordingService } from '../../services/recording/recording.service'; import { RecordingInfo, RecordingStatus } from '../../models/recording.model'; import { TranslateService } from '../../services/translate/translate.service'; import { MediaChange } from '@angular/flex-layout'; +import { LayoutService } from '../../services/layout/layout.service'; /** * @@ -303,6 +304,17 @@ export class ToolbarComponent implements OnInit, OnDestroy, AfterViewInit { * @ignore */ showSessionName: boolean = true; + + /** + * @ignore + */ + showSubtitlesButton: boolean = true; + + /** + * @ignore + */ + subtitlesEnabled: boolean; + /** * @ignore */ @@ -350,6 +362,7 @@ export class ToolbarComponent implements OnInit, OnDestroy, AfterViewInit { private displaySessionNameSub: Subscription; private screenSizeSub: Subscription; private settingsButtonSub: Subscription; + private subtitlesSubs: Subscription; private currentWindowHeight = window.innerHeight; /** @@ -365,6 +378,7 @@ export class ToolbarComponent implements OnInit, OnDestroy, AfterViewInit { protected oVDevicesService: DeviceService, protected actionService: ActionService, protected loggerSrv: LoggerService, + private layoutService: LayoutService, private cd: ChangeDetectorRef, private libService: OpenViduAngularConfigService, private platformService: PlatformService, @@ -411,6 +425,7 @@ export class ToolbarComponent implements OnInit, OnDestroy, AfterViewInit { this.subscribeToChatMessages(); this.subscribeToRecordingStatus(); this.subscribeToScreenSize(); + this.subscribeToSubtitlesToggling(); } ngAfterViewInit() { @@ -438,6 +453,7 @@ export class ToolbarComponent implements OnInit, OnDestroy, AfterViewInit { if (this.recordingSubscription) this.recordingSubscription.unsubscribe(); if (this.screenSizeSub) this.screenSizeSub.unsubscribe(); if (this.settingsButtonSub) this.settingsButtonSub.unsubscribe(); + if (this.subtitlesSubs) this.subtitlesSubs.unsubscribe(); } /** @@ -528,6 +544,13 @@ export class ToolbarComponent implements OnInit, OnDestroy, AfterViewInit { this.panelService.togglePanel(PanelType.BACKGROUND_EFFECTS); } + /** + * @ignore + */ + toggleSubtitles() { + this.layoutService.toggleSubtitles(); + } + /** * @ignore */ @@ -674,6 +697,10 @@ export class ToolbarComponent implements OnInit, OnDestroy, AfterViewInit { this.showSessionName = value; this.cd.markForCheck(); }); + this.subtitlesSubs = this.libService.subtitlesButtonObs.subscribe((value: boolean) => { + this.showSubtitlesButton = value; + this.cd.markForCheck(); + }); } private subscribeToScreenSize() { @@ -682,6 +709,13 @@ export class ToolbarComponent implements OnInit, OnDestroy, AfterViewInit { }); } + private subscribeToSubtitlesToggling() { + this.subtitlesSubs = this.layoutService.subtitlesTogglingObs.subscribe((value: boolean) => { + this.subtitlesEnabled = value; + this.cd.markForCheck(); + }); + } + private checkDisplayMoreOptions() { this.showMoreOptionsButton = this.showFullscreenButton || this.showBackgroundEffectsButton || this.showRecordingButton || this.showSettingsButton; 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 95e96c15..2285ee18 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 @@ -20,7 +20,8 @@ import { ToolbarActivitiesPanelButtonDirective, ToolbarBackgroundEffectsButtonDirective, ToolbarRecordingButtonDirective, - ToolbarSettingsButtonDirective + ToolbarSettingsButtonDirective, + ToolbarSubtitleButtonDirective } from './toolbar.directive'; import { AudioMutedDirective, @@ -41,6 +42,7 @@ import { ToolbarScreenshareButtonDirective, ToolbarFullscreenButtonDirective, ToolbarBackgroundEffectsButtonDirective, + ToolbarSubtitleButtonDirective, ToolbarLeaveButtonDirective, ToolbarRecordingButtonDirective, ToolbarParticipantsPanelButtonDirective, @@ -70,6 +72,7 @@ import { ToolbarScreenshareButtonDirective, ToolbarFullscreenButtonDirective, ToolbarBackgroundEffectsButtonDirective, + ToolbarSubtitleButtonDirective, ToolbarLeaveButtonDirective, ToolbarRecordingButtonDirective, ToolbarParticipantsPanelButtonDirective, diff --git a/openvidu-components-angular/projects/openvidu-angular/src/lib/directives/api/toolbar.directive.ts b/openvidu-components-angular/projects/openvidu-angular/src/lib/directives/api/toolbar.directive.ts index e15c4a8e..c1ffbcfa 100644 --- a/openvidu-components-angular/projects/openvidu-angular/src/lib/directives/api/toolbar.directive.ts +++ b/openvidu-components-angular/projects/openvidu-angular/src/lib/directives/api/toolbar.directive.ts @@ -242,6 +242,65 @@ export class ToolbarBackgroundEffectsButtonDirective implements AfterViewInit, O } } +/** + * The **subtitleButton** directive allows show/hide the subtitle toolbar button. + * + * Default: `true` + * + * It can be used in the parent element {@link VideoconferenceComponent} specifying the name of the `toolbar` component: + * + * @example + * + * + * \ + * And it also can be used in the {@link ToolbarComponent}. + * @example + * + */ + @Directive({ + selector: 'ov-videoconference[toolbarSubtitlesButton], ov-toolbar[subtitlesButton]' +}) +export class ToolbarSubtitleButtonDirective implements AfterViewInit, OnDestroy { + /** + * @ignore + */ + @Input() set toolbarSubtitlesButton(value: boolean) { + this.subtitlesButtonValue = value; + this.update(this.subtitlesButtonValue); + } + /** + * @ignore + */ + @Input() set subtitlesButton(value: boolean) { + this.subtitlesButtonValue = value; + this.update(this.subtitlesButtonValue); + } + + private subtitlesButtonValue: boolean = true; + + /** + * @ignore + */ + constructor(public elementRef: ElementRef, private libService: OpenViduAngularConfigService) {} + + ngAfterViewInit() { + this.update(this.subtitlesButtonValue); + } + ngOnDestroy(): void { + this.clear(); + } + private clear() { + this.subtitlesButtonValue = true; + this.update(true); + } + + private update(value: boolean) { + if (this.libService.subtitlesButton.getValue() !== value) { + this.libService.subtitlesButton.next(value); + } + } +} + /** * The **settingsButton** directive allows show/hide the settings toolbar button. * diff --git a/openvidu-components-angular/projects/openvidu-angular/src/lib/lang/cn.json b/openvidu-components-angular/projects/openvidu-angular/src/lib/lang/cn.json index 9f507d2a..5c2f6bf4 100644 --- a/openvidu-components-angular/projects/openvidu-angular/src/lib/lang/cn.json +++ b/openvidu-components-angular/projects/openvidu-angular/src/lib/lang/cn.json @@ -34,6 +34,8 @@ "MORE_OPTIONS":"更多选项", "FULLSCREEN":"全屏", "EXIT_FULLSCREEN": "退出全屏", + "ENABLE_SUBTITLES": "启用字幕", + "DISABLE_SUBTITLES": "禁用字幕", "BACKGROUND":"背景效果", "START_RECORDING": "开始录音", "STOP_RECORDING": "停止录制", @@ -70,7 +72,8 @@ "GENERAL": "一般的", "VIDEO": "视频", "AUDIO": "声音的", - "LANGUAGE": "语" + "LANGUAGE": "语", + "SUBTITLE": "字幕" }, "BACKGROUND": { "TITLE": "背景效果", diff --git a/openvidu-components-angular/projects/openvidu-angular/src/lib/lang/de.json b/openvidu-components-angular/projects/openvidu-angular/src/lib/lang/de.json index 4cb81d9d..a2347467 100644 --- a/openvidu-components-angular/projects/openvidu-angular/src/lib/lang/de.json +++ b/openvidu-components-angular/projects/openvidu-angular/src/lib/lang/de.json @@ -34,6 +34,8 @@ "MORE_OPTIONS": "Weitere Optionen", "FULLSCREEN": "Vollbild", "EXIT_FULLSCREEN": "Vollbildmodus beenden", + "ENABLE_SUBTITLES": "Untertitel aktivieren", + "DISABLE_SUBTITLES": "Untertitel deaktivieren", "BACKGROUND": "Hintergrund-Effekte", "START_RECORDING": "Aufzeichnung starten", "STOP_RECORDING": "Aufzeichnung stoppen", @@ -70,7 +72,8 @@ "GENERAL": "Allgemein", "VIDEO": "Video", "AUDIO": "Audio", - "LANGUAGE": "Sprache" + "LANGUAGE": "Sprache", + "SUBTITLE": "Untertitel" }, "BACKGROUND": { "TITLE": "Hintergrund-Effekte", diff --git a/openvidu-components-angular/projects/openvidu-angular/src/lib/lang/en.json b/openvidu-components-angular/projects/openvidu-angular/src/lib/lang/en.json index f98947c4..9edc79d1 100644 --- a/openvidu-components-angular/projects/openvidu-angular/src/lib/lang/en.json +++ b/openvidu-components-angular/projects/openvidu-angular/src/lib/lang/en.json @@ -35,6 +35,8 @@ "MORE_OPTIONS": "More options", "FULLSCREEN": "Fullscreen", "EXIT_FULLSCREEN": "Exit fullscreen", + "ENABLE_SUBTITLES": "Enable subtitles", + "DISABLE_SUBTITLES": "Disable subtitles", "BACKGROUND": "Background effects", "START_RECORDING": "Start recording", "STOP_RECORDING": "Stop recording", @@ -71,7 +73,8 @@ "GENERAL": "General", "VIDEO": "Video", "AUDIO": "Audio", - "LANGUAGE": "Language" + "LANGUAGE": "Language", + "SUBTITLE": "Subtitles" }, "BACKGROUND": { "TITLE": "Background effects", diff --git a/openvidu-components-angular/projects/openvidu-angular/src/lib/lang/es.json b/openvidu-components-angular/projects/openvidu-angular/src/lib/lang/es.json index 83de70b0..89083587 100644 --- a/openvidu-components-angular/projects/openvidu-angular/src/lib/lang/es.json +++ b/openvidu-components-angular/projects/openvidu-angular/src/lib/lang/es.json @@ -34,6 +34,8 @@ "MORE_OPTIONS": "Más opciones", "EXIT_FULLSCREEN": "Quitar pantalla completa", "FULLSCREEN": "Pantalla completa", + "ENABLE_SUBTITLES": "Activar subtítulos", + "DISABLE_SUBTITLES": "Desactivar subtítulos", "BACKGROUND": "Efectos de fondo", "START_RECORDING": "Iniciar grabación", "STOP_RECORDING": "Detener grabación", @@ -70,7 +72,8 @@ "GENERAL": "General", "VIDEO": "Video", "AUDIO": "Audio", - "LANGUAGE": "Idioma" + "LANGUAGE": "Idioma", + "SUBTITLE": "Subtítulos" }, "BACKGROUND": { "TITLE": "Efectos de fondo", diff --git a/openvidu-components-angular/projects/openvidu-angular/src/lib/lang/fr.json b/openvidu-components-angular/projects/openvidu-angular/src/lib/lang/fr.json index 526acd94..13e17cd1 100644 --- a/openvidu-components-angular/projects/openvidu-angular/src/lib/lang/fr.json +++ b/openvidu-components-angular/projects/openvidu-angular/src/lib/lang/fr.json @@ -34,6 +34,8 @@ "MORE_OPTIONS": "Plus d'options", "FULLSCREEN": "Plein écran", "EXIT_FULLSCREEN": "Quitter le plein écran", + "ENABLE_SUBTITLES": "Activer les sous-titres", + "DISABLE_SUBTITLES": "Désactiver les sous-titres", "BACKGROUND": "Effets de fond", "START_RECORDING": "démarrer l'enregistrement", "STOP_RECORDING": "Arrêter l'enregistrement", @@ -70,7 +72,8 @@ "GENERAL": "Général", "VIDEO": "Vidéo", "AUDIO": "l'audio", - "LANGUAGE": "Langue" + "LANGUAGE": "Langue", + "SUBTITLE": "Les sous-titres" }, "BACKGROUND": { "TITLE": "Effets de fond", diff --git a/openvidu-components-angular/projects/openvidu-angular/src/lib/lang/hi.json b/openvidu-components-angular/projects/openvidu-angular/src/lib/lang/hi.json index 2a03a3fe..9b9ad590 100644 --- a/openvidu-components-angular/projects/openvidu-angular/src/lib/lang/hi.json +++ b/openvidu-components-angular/projects/openvidu-angular/src/lib/lang/hi.json @@ -34,6 +34,8 @@ "MORE_OPTIONS": "अधिक विकल्प", "FULLSCREEN": "पूर्ण स्क्रीन", "EXIT_FULLSCREEN": "पूर्ण स्क्रीन से बाहर निकलें", + "ENABLE_SUBTITLES": "उपशीर्षक सक्षम करें", + "DISABLE_SUBTITLES": "उपशीर्षक अक्षम करें", "BACKGROUND": "पृष्ठभूमि प्रभाव", "START_RECORDING": "रिकॉर्डिंग प्रारंभ करें", "STOP_RECORDING": "रिकॉर्डिंग रोकें", @@ -70,7 +72,8 @@ "GENERAL": "सामान्य", "VIDEO": "वीडियो", "AUDIO": "ऑडियो", - "LANGUAGE": "भाषा" + "LANGUAGE": "भाषा", + "SUBTITLE": "उपशीर्षक" }, "BACKGROUND": { "TITLE": "पृष्ठभूमि प्रभाव", diff --git a/openvidu-components-angular/projects/openvidu-angular/src/lib/lang/it.json b/openvidu-components-angular/projects/openvidu-angular/src/lib/lang/it.json index 3704d216..a12c423b 100644 --- a/openvidu-components-angular/projects/openvidu-angular/src/lib/lang/it.json +++ b/openvidu-components-angular/projects/openvidu-angular/src/lib/lang/it.json @@ -34,6 +34,8 @@ "MORE_OPTIONS": "Altre opzioni", "FULLSCREEN": "Schermo intero", "EXIT_FULLSCREEN": "Esci dallo schermo intero", + "ENABLE_SUBTITLES": "Abilita i sottotitoli", + "DISABLE_SUBTITLES": "Disabilita i sottotitoli", "BACKGROUND": "Effetti di sfondo", "START_RECORDING": "Avvia registrazione", "STOP_RECORDING": "Interrompi registrazione", @@ -70,7 +72,8 @@ "GENERAL": "Generale", "VIDEO": "video", "AUDIO": "Audio", - "LANGUAGE":"Lingua" + "LANGUAGE":"Lingua", + "SUBTITLE": "Sottotitoli" }, "BACKGROUND": { "TITLE": "Effetti di sfondo", diff --git a/openvidu-components-angular/projects/openvidu-angular/src/lib/lang/ja.json b/openvidu-components-angular/projects/openvidu-angular/src/lib/lang/ja.json index 00dffe3f..1dbe11c3 100644 --- a/openvidu-components-angular/projects/openvidu-angular/src/lib/lang/ja.json +++ b/openvidu-components-angular/projects/openvidu-angular/src/lib/lang/ja.json @@ -34,6 +34,8 @@ "MORE_OPTIONS": "その他のオプション", "FULLSCREEN": "フルスクリーン", "EXIT_FULLSCREEN": "フルスクリーンを終了する", + "ENABLE_SUBTITLES": "字幕を有効にする", + "DISABLE_SUBTITLES": "字幕を無効にする", "BACKGROUND": "背景効果", "START_RECORDING": "録画開始", "STOP_RECORDING": "録画の停止", @@ -70,7 +72,8 @@ "GENERAL": "全般的", "VIDEO": "ビデオ", "AUDIO": "オーディオ", - "LANGUAGE":"言語" + "LANGUAGE":"言語", + "SUBTITLE": "字幕" }, "BACKGROUND": { "TITLE": "背景効果", diff --git a/openvidu-components-angular/projects/openvidu-angular/src/lib/lang/nl.json b/openvidu-components-angular/projects/openvidu-angular/src/lib/lang/nl.json index 51c0acb7..18ad397e 100644 --- a/openvidu-components-angular/projects/openvidu-angular/src/lib/lang/nl.json +++ b/openvidu-components-angular/projects/openvidu-angular/src/lib/lang/nl.json @@ -34,6 +34,8 @@ "MORE_OPTIONS": "Meer opties", "FULLSCREEN": "Volledig scherm", "EXIT_FULLSCREEN": "Volledig scherm verlaten", + "ENABLE_SUBTITLES": "Ondertiteling inschakelen", + "DISABLE_SUBTITLES": "Ondertiteling uitschakelen", "BACKGROUND": "Achtergrondeffecten", "START_RECORDING": "Start opname", "STOP_RECORDING": "Stop opname", @@ -70,7 +72,8 @@ "GENERAL": "Algemeen", "VIDEO": "Video", "AUDIO": "Audio", - "LANGUAGE":"Taal" + "LANGUAGE":"Taal", + "SUBTITLE": "Ondertitels" }, "BACKGROUND": { "TITLE": "Achtergrondeffecten", diff --git a/openvidu-components-angular/projects/openvidu-angular/src/lib/lang/pt.json b/openvidu-components-angular/projects/openvidu-angular/src/lib/lang/pt.json index 14791649..eac46ac1 100644 --- a/openvidu-components-angular/projects/openvidu-angular/src/lib/lang/pt.json +++ b/openvidu-components-angular/projects/openvidu-angular/src/lib/lang/pt.json @@ -34,6 +34,8 @@ "MORE_OPTIONS": "Mais opções", "FULLSCREEN": "Tela cheia", "EXIT_FULLSCREEN": "Sair da tela cheia", + "ENABLE_SUBTITLES": "Ativar legendas", + "DISABLE_SUBTITLES": "Desativar legendas", "BACKGROUND": "Efeitos de fundo", "START_RECORDING": "Iniciar_gravação", "STOP_RECORDING": "Parar de gravar", @@ -70,7 +72,8 @@ "GENERAL": "Em geral", "VIDEO": "Vídeo", "AUDIO": "Áudio", - "LANGUAGE":"Linguagem" + "LANGUAGE":"Linguagem", + "SUBTITLE": "Legendas" }, "BACKGROUND": { "TITLE": "Efeitos de fundo", diff --git a/openvidu-components-angular/projects/openvidu-angular/src/lib/models/panel.model.ts b/openvidu-components-angular/projects/openvidu-angular/src/lib/models/panel.model.ts index 45402f9a..2382ce05 100644 --- a/openvidu-components-angular/projects/openvidu-angular/src/lib/models/panel.model.ts +++ b/openvidu-components-angular/projects/openvidu-angular/src/lib/models/panel.model.ts @@ -5,4 +5,11 @@ export enum PanelType { ACTIVITIES = 'activities', SETTINGS = 'settings' -} \ No newline at end of file +} + +export enum PanelSettingsOptions { + GENERAL = 'general', + AUDIO = 'audio', + VIDEO = 'video', + SUBTITLES = 'subtitles' +} diff --git a/openvidu-components-angular/projects/openvidu-angular/src/lib/openvidu-angular.material.module.ts b/openvidu-components-angular/projects/openvidu-angular/src/lib/openvidu-angular.material.module.ts index 7a6462ab..506f406d 100644 --- a/openvidu-components-angular/projects/openvidu-angular/src/lib/openvidu-angular.material.module.ts +++ b/openvidu-components-angular/projects/openvidu-angular/src/lib/openvidu-angular.material.module.ts @@ -19,6 +19,7 @@ import { MatMenuModule } from '@angular/material/menu'; import { MatListModule } from '@angular/material/list'; import { MatDividerModule } from '@angular/material/divider'; import { MatExpansionModule } from '@angular/material/expansion'; +import {MatSlideToggleModule} from '@angular/material/slide-toggle'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { NgModule } from '@angular/core'; @@ -47,6 +48,7 @@ import { NgModule } from '@angular/core'; MatDividerModule, MatListModule, MatExpansionModule, + MatSlideToggleModule ] }) export class AppMaterialModule { } diff --git a/openvidu-components-angular/projects/openvidu-angular/src/lib/openvidu-angular.module.ts b/openvidu-components-angular/projects/openvidu-angular/src/lib/openvidu-angular.module.ts index a9716884..e1414b38 100644 --- a/openvidu-components-angular/projects/openvidu-angular/src/lib/openvidu-angular.module.ts +++ b/openvidu-components-angular/projects/openvidu-angular/src/lib/openvidu-angular.module.ts @@ -58,6 +58,8 @@ import { VideoDevicesComponent } from './components/settings/video-devices/video import { AudioDevicesComponent } from './components/settings/audio-devices/audio-devices.component'; import { NicknameInputComponent } from './components/settings/nickname-input/nickname-input.component'; import { LangSelectorComponent } from './components/settings/lang-selector/lang-selector.component'; +import { SubtitlesSettingComponent } from './components/settings/subtitles/subtitles.component'; +import { SubtitlesComponent } from './components/subtitles/subtitles.component'; @NgModule({ declarations: [ @@ -66,6 +68,7 @@ import { LangSelectorComponent } from './components/settings/lang-selector/lang- ChatPanelComponent, SessionComponent, LayoutComponent, + SubtitlesComponent, StreamComponent, DialogTemplateComponent, RecordingDialogComponent, @@ -87,6 +90,7 @@ import { LangSelectorComponent } from './components/settings/lang-selector/lang- AudioDevicesComponent, NicknameInputComponent, LangSelectorComponent, + SubtitlesSettingComponent, BackgroundEffectsPanelComponent, SettingsPanelComponent, ActivitiesPanelComponent, diff --git a/openvidu-components-angular/projects/openvidu-angular/src/lib/services/config/openvidu-angular.config.service.ts b/openvidu-components-angular/projects/openvidu-angular/src/lib/services/config/openvidu-angular.config.service.ts index 2c94b12a..8b7b50b0 100644 --- a/openvidu-components-angular/projects/openvidu-angular/src/lib/services/config/openvidu-angular.config.service.ts +++ b/openvidu-components-angular/projects/openvidu-angular/src/lib/services/config/openvidu-angular.config.service.ts @@ -28,6 +28,9 @@ export class OpenViduAngularConfigService { fullscreenButton = >new BehaviorSubject(true); fullscreenButtonObs: Observable; + subtitlesButton = >new BehaviorSubject(true); + subtitlesButtonObs: Observable; + toolbarSettingsButton = >new BehaviorSubject(true); toolbarSettingsButtonObs: Observable; @@ -92,6 +95,7 @@ export class OpenViduAngularConfigService { this.displayLogoObs = this.displayLogo.asObservable(); this.recordingButtonObs = this.recordingButton.asObservable(); this.toolbarSettingsButtonObs = this.toolbarSettingsButton.asObservable(); + this.subtitlesButtonObs = this.subtitlesButton.asObservable(); //Stream observables this.displayParticipantNameObs = this.displayParticipantName.asObservable(); this.displayAudioDetectionObs = this.displayAudioDetection.asObservable(); diff --git a/openvidu-components-angular/projects/openvidu-angular/src/lib/services/layout/layout.service.ts b/openvidu-components-angular/projects/openvidu-angular/src/lib/services/layout/layout.service.ts index 5db1276d..be72758e 100644 --- a/openvidu-components-angular/projects/openvidu-angular/src/lib/services/layout/layout.service.ts +++ b/openvidu-components-angular/projects/openvidu-angular/src/lib/services/layout/layout.service.ts @@ -1,6 +1,6 @@ import { Injectable } from '@angular/core'; import { BehaviorSubject, Observable } from 'rxjs'; -import { LayoutClass, OpenViduLayout, OpenViduLayoutOptions } from '../../models/layout.model'; +import { LayoutAlignment, LayoutClass, OpenViduLayout, OpenViduLayoutOptions } from '../../models/layout.model'; import { DocumentService } from '../document/document.service'; /** @@ -10,13 +10,19 @@ import { DocumentService } from '../document/document.service'; providedIn: 'root' }) export class LayoutService { + + layoutContainer: HTMLElement | null = null; layoutWidthObs: Observable; - private _layoutWidthObs: BehaviorSubject = new BehaviorSubject(0); + subtitlesTogglingObs: Observable; + private layoutWidth: BehaviorSubject = new BehaviorSubject(0); private openviduLayout: OpenViduLayout; private openviduLayoutOptions: OpenViduLayoutOptions; + private subtitlesToggling: BehaviorSubject = new BehaviorSubject(false); + constructor(private documentService: DocumentService) { - this.layoutWidthObs = this._layoutWidthObs.asObservable(); + this.layoutWidthObs = this.layoutWidth.asObservable(); + this.subtitlesTogglingObs = this.subtitlesToggling.asObservable(); } initialize(timeout: number = null) { @@ -34,8 +40,10 @@ export class LayoutService { private _initialize() { this.openviduLayout = new OpenViduLayout(); this.openviduLayoutOptions = this.getOptions(); - const element = document.getElementById('layout'); - this.openviduLayout.initLayoutContainer(element, this.openviduLayoutOptions); + this.layoutContainer = document.getElementById('layout'); + if(this.layoutContainer){ + this.openviduLayout.initLayoutContainer(this.layoutContainer, this.openviduLayoutOptions); + } } private getOptions(): OpenViduLayoutOptions { @@ -46,20 +54,37 @@ export class LayoutService { and minRatio and maxRatio are ignored (default false) */, bigClass: LayoutClass.BIG_ELEMENT, // The class to add to elements that should be sized bigger smallClass: LayoutClass.SMALL_ELEMENT, + ignoredClass: LayoutClass.IGNORED_ELEMENT, bigPercentage: 0.8, // The maximum percentage of space the big ones should take up + minBigPercentage: 0, // If this is set then it will scale down the big space if there is left over whitespace down to this minimum size bigFixedRatio: false, // fixedRatio for the big ones bigMaxRatio: 9 / 16, // The narrowest ratio to use for the big elements (default 2x3) bigMinRatio: 9 / 16, // The widest ratio to use for the big elements (default 16x9) bigFirst: true, // Whether to place the big one in the top left (true) or bottom right - animate: true // Whether you want to animate the transitions. Deprecated property, to disable it remove the transaction property on OT_publisher css class + animate: true, // Whether you want to animate the transitions. Deprecated property, to disable it remove the transaction property on OT_publisher css class + alignItems: LayoutAlignment.CENTER, + bigAlignItems: LayoutAlignment.CENTER, + smallAlignItems: LayoutAlignment.CENTER, + maxWidth: Infinity, // The maximum width of the elements + maxHeight: Infinity, // The maximum height of the elements + smallMaxWidth: Infinity, + smallMaxHeight: Infinity, + bigMaxWidth: Infinity, + bigMaxHeight: Infinity, + scaleLastRow: true, + bigScaleLastRow: true }; return options; } + toggleSubtitles() { + this.subtitlesToggling.next(!this.subtitlesToggling.getValue()); + } + update(timeout: number = null) { const updateAux = () => { if (!!this.openviduLayout) { - this.openviduLayout.updateLayout(); + this.openviduLayout.updateLayout(this.layoutContainer, this.openviduLayoutOptions); this.sendLayoutWidthEvent(); } }; @@ -84,7 +109,7 @@ export class LayoutService { LayoutClass.SIDENAV_CONTAINER ); if (sidenavLayoutElement && sidenavLayoutElement.clientWidth) { - this._layoutWidthObs.next(sidenavLayoutElement.clientWidth); + this.layoutWidth.next(sidenavLayoutElement.clientWidth); } } } diff --git a/openvidu-components-angular/projects/openvidu-angular/src/lib/services/panel/panel.service.ts b/openvidu-components-angular/projects/openvidu-angular/src/lib/services/panel/panel.service.ts index 46bec603..f8f1dcfd 100644 --- a/openvidu-components-angular/projects/openvidu-angular/src/lib/services/panel/panel.service.ts +++ b/openvidu-components-angular/projects/openvidu-angular/src/lib/services/panel/panel.service.ts @@ -1,7 +1,7 @@ import { Injectable } from '@angular/core'; import { BehaviorSubject, Observable } from 'rxjs'; import { ILogger } from '../../models/logger.model'; -import { PanelType } from '../../models/panel.model'; +import { PanelSettingsOptions, PanelType } from '../../models/panel.model'; import { LoggerService } from '../logger/logger.service'; export interface PanelEvent { @@ -38,7 +38,7 @@ export class PanelService { * Open or close the panel type received. Calling this method with the panel opened and the same type panel, will close the panel. * If the type is differente, it will switch to the properly panel. */ - togglePanel(type: PanelType | string, expand?: string) { + togglePanel(type: PanelType | string, expand?: PanelSettingsOptions | string) { let nextOpenedValue: boolean = false; if (this.panelMap.has(type)) { this.log.d(`Toggling ${type} menu`); 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 4111b919..ba32d050 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 @@ -17,6 +17,7 @@ [toolbarParticipantsPanelButton]="_toolbarParticipantsPanelButton" [toolbarDisplayLogo]="_toolbarDisplayLogo" [toolbarDisplaySessionName]="_toolbarDisplaySessionName" + [toolbarSubtitlesButton]="_toolbarSubtitlesButton" [streamDisplayParticipantName]="_streamDisplayParticipantName" [streamDisplayAudioDetection]="_streamDisplayAudioDetection" [streamSettingsButton]="_streamSettingsButton" 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 eb767858..81b342b3 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 @@ -79,6 +79,10 @@ export class OpenviduWebComponentComponent implements OnInit { * @internal */ _toolbarDisplaySessionName: boolean = true; + /** + * @internal + */ + _toolbarSubtitlesButton: boolean = true; /** * @internal */ @@ -330,6 +334,20 @@ export class OpenviduWebComponentComponent implements OnInit { @Input() set toolbarDisplaySessionName(value: string | boolean) { this._toolbarDisplaySessionName = this.castToBoolean(value); } + /** + * The **toolbarDisplaySessionName** attribute allows show/hide the session name. + * + * Default: `true` + * + *
+ * WARNING: If you want to use this parameter to OpenVidu Web Component statically, you have to replace the camelCase with a hyphen between words.
+ * + * @example + * + */ + @Input() set toolbarSubtitlesButton(value: string | boolean) { + this._toolbarSubtitlesButton = this.castToBoolean(value); + } /** * The **streamDisplayParticipantName** attribute allows show/hide the participants name in stream component. *