From 229a3b4418947bdb5ae0ab64686e1ff9e65bf3f1 Mon Sep 17 00:00:00 2001 From: paweldomas Date: Thu, 6 Oct 2016 13:30:00 -0500 Subject: [PATCH 01/21] fix(conference): disconnect on VIDEOBRIDGE_NOT_AVAILABLE error Will disconnect on ConferenceErrors.VIDEOBRIDGE_NOT_AVAILABLE. Show the same message when either JVB is not available or Jicofo disconnects. --- conference.js | 14 +++++++++----- lang/main.json | 3 +-- modules/UI/UI.js | 14 ++++---------- 3 files changed, 14 insertions(+), 17 deletions(-) diff --git a/conference.js b/conference.js index cd2eef4c2..00c129799 100644 --- a/conference.js +++ b/conference.js @@ -329,10 +329,6 @@ class ConferenceConnector { } break; - case ConferenceErrors.VIDEOBRIDGE_NOT_AVAILABLE: - APP.UI.notifyBridgeDown(); - break; - // not enough rights to create conference case ConferenceErrors.AUTHENTICATION_REQUIRED: // schedule reconnect to check if someone else created the room @@ -367,6 +363,10 @@ class ConferenceConnector { } break; + // FIXME FOCUS_DISCONNECTED is confusing event name. + // What really happens there is that the library is not ready yet, + // because Jicofo is not available, but it is going to give + // it another try. case ConferenceErrors.FOCUS_DISCONNECTED: { let [focus, retrySec] = params; @@ -375,8 +375,12 @@ class ConferenceConnector { break; case ConferenceErrors.FOCUS_LEFT: + case ConferenceErrors.VIDEOBRIDGE_NOT_AVAILABLE: + // FIXME the conference should be stopped by the library and not by + // the app. Both the errors above are unrecoverable from the library + // perspective. room.leave().then(() => connection.disconnect()); - APP.UI.notifyFocusLeft(); + APP.UI.notifyVideoConferencingNotAvailable(); break; case ConferenceErrors.CONFERENCE_MAX_USERS: diff --git a/lang/main.json b/lang/main.json index 0c6d1ac73..7600f1539 100644 --- a/lang/main.json +++ b/lang/main.json @@ -202,8 +202,7 @@ "detectext": "Error when trying to detect desktopsharing extension.", "failtoinstall": "Failed to install desktop sharing extension", "failedpermissions": "Failed to obtain permissions to use the local microphone and/or camera.", - "bridgeUnavailable": "Jitsi Videobridge is currently unavailable. Please try again later!", - "jicofoUnavailable": "Jicofo is currently unavailable. Please try again later!", + "serviceUnavailableMsg": "The video conferencing service is currently unavailable. Please try again later!", "maxUsersLimitReached": "The limit for maximum number of participants in the conference has been reached. The conference is full. Please try again later!", "lockTitle": "Lock failed", "lockMessage": "Failed to lock the conference.", diff --git a/modules/UI/UI.js b/modules/UI/UI.js index a8f542d01..a2b6d1f73 100644 --- a/modules/UI/UI.js +++ b/modules/UI/UI.js @@ -195,13 +195,6 @@ UI.notifyConferenceDestroyed = function (reason) { messageHandler.openDialog(title, reason, true, {}, () => false); }; -/** - * Notify user that Jitsi Videobridge is not accessible. - */ - UI.notifyBridgeDown = function () { - messageHandler.showError("dialog.error", "dialog.bridgeUnavailable"); -}; - /** * Show chat error. * @param err the Error @@ -1114,14 +1107,15 @@ UI.notifyFocusDisconnected = function (focus, retrySec) { }; /** - * Notify user that focus left the conference so page should be reloaded. + * Notify the user that the video conferencing service is badly broken and + * the page should be reloaded. */ -UI.notifyFocusLeft = function () { +UI.notifyVideoConferencingNotAvailable = function () { let title = APP.translation.generateTranslationHTML( 'dialog.serviceUnavailable' ); let msg = APP.translation.generateTranslationHTML( - 'dialog.jicofoUnavailable' + 'dialog.serviceUnavailableMsg' ); messageHandler.openDialog( title, From c473178dfe95261cdee90a6d707ffb8aca836e9d Mon Sep 17 00:00:00 2001 From: paweldomas Date: Tue, 11 Oct 2016 15:33:49 -0500 Subject: [PATCH 02/21] fix(UserMediaPermissionsGuidanceOverlay): broken display --- css/overlay/_overlay.scss | 28 ++++--------------- .../UserMediaPermissionsGuidanceOverlay.js | 3 +- 2 files changed, 6 insertions(+), 25 deletions(-) diff --git a/css/overlay/_overlay.scss b/css/overlay/_overlay.scss index f440b5ab2..3152c460f 100644 --- a/css/overlay/_overlay.scss +++ b/css/overlay/_overlay.scss @@ -1,48 +1,30 @@ -.overlay { - position: fixed; - left: 0; - top: 0; - width: 100%; - height: 100%; - z-index: $overlayZ; - background: #21B9FC; /* Old browsers */ - opacity: 0.75; - display: block; -} - -.overlay_transparent { - background: rgba(22, 185, 252, .9); -} - .overlay_container { + top: 0; + left: 0; width: 100%; height: 100%; position: fixed; z-index: $overlayZ; + background: rgba(22, 185, 252, .9); } .overlay_content { color: #fff; - font-weight: normal; - font-size: 20px; text-align: center; width: 400px; height: 250px; top: 50%; left: 50%; - position:absolute; + position: absolute; margin-top: -125px; margin-left: -200px; } - .overlay_text_small { + display: block; font-size: 18px; } .overlay_icon { - position: relative; - z-index: 1013; - float: none; font-size: 100px; } diff --git a/modules/UI/gum_overlay/UserMediaPermissionsGuidanceOverlay.js b/modules/UI/gum_overlay/UserMediaPermissionsGuidanceOverlay.js index db0d977e4..55b3bf902 100644 --- a/modules/UI/gum_overlay/UserMediaPermissionsGuidanceOverlay.js +++ b/modules/UI/gum_overlay/UserMediaPermissionsGuidanceOverlay.js @@ -11,12 +11,11 @@ let $overlay; function buildOverlayHtml(browser) { $overlay = $(`
-
+ class='overlay_text_small'>
`); From d2690444ac98c7c34211a8c04340b1220ba8bf28 Mon Sep 17 00:00:00 2001 From: paweldomas Date: Wed, 12 Oct 2016 14:57:53 -0500 Subject: [PATCH 03/21] fix(overlay): bring overlay on top of the toolbars --- css/_variables.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/css/_variables.scss b/css/_variables.scss index fa560b004..764eeeb66 100644 --- a/css/_variables.scss +++ b/css/_variables.scss @@ -89,7 +89,7 @@ $sidebarWidth: 200px; */ $tooltipsZ: 901; $toolbarZ: 900; -$overlayZ: 800; +$overlayZ: 902; $notificationZ: 1012; /** From 2a5b4dde31d315a8375e4219bd2cdb430558fc80 Mon Sep 17 00:00:00 2001 From: paweldomas Date: Wed, 12 Oct 2016 15:11:14 -0500 Subject: [PATCH 04/21] feat: implement PageReloadOverlay --- conference.js | 2 +- lang/main.json | 3 +- modules/UI/UI.js | 21 +--- .../UI/reload_overlay/PageReloadOverlay.js | 105 ++++++++++++++++++ 4 files changed, 111 insertions(+), 20 deletions(-) create mode 100644 modules/UI/reload_overlay/PageReloadOverlay.js diff --git a/conference.js b/conference.js index 00c129799..a15cca2c8 100644 --- a/conference.js +++ b/conference.js @@ -380,7 +380,7 @@ class ConferenceConnector { // the app. Both the errors above are unrecoverable from the library // perspective. room.leave().then(() => connection.disconnect()); - APP.UI.notifyVideoConferencingNotAvailable(); + APP.UI.showPageReloadOverlay(); break; case ConferenceErrors.CONFERENCE_MAX_USERS: diff --git a/lang/main.json b/lang/main.json index 7600f1539..74d9e3ed0 100644 --- a/lang/main.json +++ b/lang/main.json @@ -202,7 +202,8 @@ "detectext": "Error when trying to detect desktopsharing extension.", "failtoinstall": "Failed to install desktop sharing extension", "failedpermissions": "Failed to obtain permissions to use the local microphone and/or camera.", - "serviceUnavailableMsg": "The video conferencing service is currently unavailable. Please try again later!", + "conferenceReloadMsg": "Something went wrong we'll try to reload the conference in...", + "conferenceReloadTimeLeft": "__seconds__ sec.", "maxUsersLimitReached": "The limit for maximum number of participants in the conference has been reached. The conference is full. Please try again later!", "lockTitle": "Lock failed", "lockMessage": "Failed to lock the conference.", diff --git a/modules/UI/UI.js b/modules/UI/UI.js index a2b6d1f73..ea289baef 100644 --- a/modules/UI/UI.js +++ b/modules/UI/UI.js @@ -14,12 +14,12 @@ import Recording from "./recording/Recording"; import GumPermissionsOverlay from './gum_overlay/UserMediaPermissionsGuidanceOverlay'; +import PageReloadOverlay from './reload_overlay/PageReloadOverlay'; import VideoLayout from "./videolayout/VideoLayout"; import FilmStrip from "./videolayout/FilmStrip"; import SettingsMenu from "./side_pannels/settings/SettingsMenu"; import Profile from "./side_pannels/profile/Profile"; import Settings from "./../settings/Settings"; -import { reload } from '../util/helpers'; import RingOverlay from "./ring_overlay/RingOverlay"; import UIErrors from './UIErrors'; @@ -1110,23 +1110,8 @@ UI.notifyFocusDisconnected = function (focus, retrySec) { * Notify the user that the video conferencing service is badly broken and * the page should be reloaded. */ -UI.notifyVideoConferencingNotAvailable = function () { - let title = APP.translation.generateTranslationHTML( - 'dialog.serviceUnavailable' - ); - let msg = APP.translation.generateTranslationHTML( - 'dialog.serviceUnavailableMsg' - ); - messageHandler.openDialog( - title, - msg, - true, // persistent - [{title: 'retry'}], - function () { - reload(); - return false; - } - ); +UI.showPageReloadOverlay = function () { + PageReloadOverlay.show(15 /* will reload in 15 seconds */); }; /** diff --git a/modules/UI/reload_overlay/PageReloadOverlay.js b/modules/UI/reload_overlay/PageReloadOverlay.js new file mode 100644 index 000000000..21edbbd5e --- /dev/null +++ b/modules/UI/reload_overlay/PageReloadOverlay.js @@ -0,0 +1,105 @@ +/* global $, APP, AJS */ + +import { reload } from '../../util/helpers'; + +let $overlay; + +/** + * Conference reload counter in seconds. + * @type {number} + */ +let timeLeft; + +/** + * Conference reload timeout in seconds. + * @type {number} + */ +let timeout; + +/** + * Internal function that constructs overlay with the warning message and count + * down towards the conference reload. + */ +function buildReloadOverlayHtml() { + $overlay = $(` +
+
+ + +
+
+ +
+ + +
+
+
`); + + APP.translation.translateElement($overlay); +} + +/** + * Updates the progress indicator position and the label with the time left. + */ +function updateDisplay() { + + const timeLeftTxt + = APP.translation.translateString( + "dialog.conferenceReloadTimeLeft", + { seconds: timeLeft }); + $("#reloadSecRemaining").text(timeLeftTxt); + + const ratio = (timeout-timeLeft)/timeout; + AJS.progressBars.update("#reloadProgressBar", ratio); +} + +/** + * Starts the reload countdown with the animation. + * @param {number} timeoutSeconds how many seconds before the conference + * reload will happen. + */ +function start(timeoutSeconds) { + + timeLeft = timeout = timeoutSeconds; + + // Initialize displays + updateDisplay(); + + var intervalId = window.setInterval(function() { + + if (timeLeft >= 1) { + timeLeft -= 1; + console.info("Reloading in " + timeLeft + " seconds..."); + } + + updateDisplay(); + + if (timeLeft === 0) { + console.info("Reloading!"); + window.clearInterval(intervalId); + reload(); + } + }, 1000); +} + +export default { + /** + * Shows the page reload overlay which will do the conference reload after + * the given amount of time. + * + * @param {number} timeoutSeconds how many seconds before the conference + * reload will happen. + */ + show(timeoutSeconds) { + + !$overlay && buildReloadOverlayHtml(); + + if (!$overlay.parents('body').length) { + $overlay.appendTo('body'); + start(timeoutSeconds); + } + } +}; From 0053c4df498f0aaf6d76cb2fd4d5e91314b78dbb Mon Sep 17 00:00:00 2001 From: paweldomas Date: Wed, 12 Oct 2016 15:51:12 -0500 Subject: [PATCH 05/21] feat(PageReloadOverlay): log the reload event --- conference.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/conference.js b/conference.js index a15cca2c8..ed18b1bf8 100644 --- a/conference.js +++ b/conference.js @@ -376,6 +376,11 @@ class ConferenceConnector { case ConferenceErrors.FOCUS_LEFT: case ConferenceErrors.VIDEOBRIDGE_NOT_AVAILABLE: + // Log the page reload event + // FIXME (CallStats - issue) this event will not make it to + // the CallStats, because the log queue is not flushed, before + // "fabric terminated" is sent to the backed + APP.conference.logEvent('page.reload'); // FIXME the conference should be stopped by the library and not by // the app. Both the errors above are unrecoverable from the library // perspective. From 687b0cad8e1a7593f8d2ac3ba44da3ce704973d8 Mon Sep 17 00:00:00 2001 From: paweldomas Date: Thu, 13 Oct 2016 10:32:32 -0500 Subject: [PATCH 06/21] fix(ToolbarToggler): remove call overlay from the timeout check Remove check for the call overlay being visible in postponing the toolbar being hidden, as we don't want to have it displayed at all when the overlay is there. --- modules/UI/toolbars/ToolbarToggler.js | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/UI/toolbars/ToolbarToggler.js b/modules/UI/toolbars/ToolbarToggler.js index c353d898e..2fb000cb1 100644 --- a/modules/UI/toolbars/ToolbarToggler.js +++ b/modules/UI/toolbars/ToolbarToggler.js @@ -35,7 +35,6 @@ function hideToolbar(force) { // eslint-disable-line no-unused-vars toolbarTimeoutObject = null; if (Toolbar.isHovered() - || APP.UI.isRingOverlayVisible() || SideContainerToggler.isVisible()) { toolbarTimeoutObject = setTimeout(hideToolbar, toolbarTimeout); } else { From 52344ff74111345aedc2cf493b7137654d7b4e73 Mon Sep 17 00:00:00 2001 From: paweldomas Date: Thu, 13 Oct 2016 10:34:32 -0500 Subject: [PATCH 07/21] fix(ToolbarToggler): restore 'force' arg in timeout logic --- modules/UI/toolbars/ToolbarToggler.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/modules/UI/toolbars/ToolbarToggler.js b/modules/UI/toolbars/ToolbarToggler.js index 2fb000cb1..f53e54b5c 100644 --- a/modules/UI/toolbars/ToolbarToggler.js +++ b/modules/UI/toolbars/ToolbarToggler.js @@ -34,8 +34,9 @@ function hideToolbar(force) { // eslint-disable-line no-unused-vars clearTimeout(toolbarTimeoutObject); toolbarTimeoutObject = null; - if (Toolbar.isHovered() - || SideContainerToggler.isVisible()) { + if (true !== force && + (Toolbar.isHovered() + || SideContainerToggler.isVisible())) { toolbarTimeoutObject = setTimeout(hideToolbar, toolbarTimeout); } else { Toolbar.hide(); From 210605d8f3a7c9897dc90cfd6f4d8d5fc32b847d Mon Sep 17 00:00:00 2001 From: paweldomas Date: Thu, 13 Oct 2016 11:14:56 -0500 Subject: [PATCH 08/21] fix(MessageHandler): suppress the notifications on top of the overlay --- modules/UI/UI.js | 11 +++++++---- .../UserMediaPermissionsGuidanceOverlay.js | 10 +++++++++- modules/UI/reload_overlay/PageReloadOverlay.js | 10 +++++++++- modules/UI/util/MessageHandler.js | 2 +- 4 files changed, 26 insertions(+), 7 deletions(-) diff --git a/modules/UI/UI.js b/modules/UI/UI.js index ea289baef..144fef378 100644 --- a/modules/UI/UI.js +++ b/modules/UI/UI.js @@ -1450,12 +1450,15 @@ UI.hideRingOverLay = function () { }; /** - * Indicates if the ring overlay is currently visible. + * Indicates if any the "top" overlays are currently visible. The check includes + * the call overlay, GUM permissions overlay and a page reload overlay. * - * @returns {*|boolean} {true} if the ring overlay is visible, {false} otherwise + * @returns {*|boolean} {true} if the overlay is visible, {false} otherwise */ -UI.isRingOverlayVisible = function () { - return RingOverlay.isVisible(); +UI.isOverlayVisible = function () { + return RingOverlay.isVisible() + || PageReloadOverlay.isVisible() + || GumPermissionsOverlay.isVisible(); }; /** diff --git a/modules/UI/gum_overlay/UserMediaPermissionsGuidanceOverlay.js b/modules/UI/gum_overlay/UserMediaPermissionsGuidanceOverlay.js index 55b3bf902..d25880ba2 100644 --- a/modules/UI/gum_overlay/UserMediaPermissionsGuidanceOverlay.js +++ b/modules/UI/gum_overlay/UserMediaPermissionsGuidanceOverlay.js @@ -23,6 +23,14 @@ function buildOverlayHtml(browser) { } export default { + /** + * Checks whether the overlay is currently visible. + * @return {boolean} true if the overlay is visible + * or false otherwise. + */ + isVisible () { + return $overlay && $overlay.parents('body').length > 0; + }, /** * Shows browser-specific overlay with guidance how to proceed with * gUM prompt. @@ -32,7 +40,7 @@ export default { show(browser) { !$overlay && buildOverlayHtml(browser); - !$overlay.parents('body').length && $overlay.appendTo('body'); + !this.isVisible() && $overlay.appendTo('body'); }, /** diff --git a/modules/UI/reload_overlay/PageReloadOverlay.js b/modules/UI/reload_overlay/PageReloadOverlay.js index 21edbbd5e..15436597b 100644 --- a/modules/UI/reload_overlay/PageReloadOverlay.js +++ b/modules/UI/reload_overlay/PageReloadOverlay.js @@ -86,6 +86,14 @@ function start(timeoutSeconds) { } export default { + /** + * Checks whether the page reload overlay has been displayed. + * @return {boolean} true if the page reload overlay is currently + * visible or false otherwise. + */ + isVisible() { + return $overlay && $overlay.parents('body').length > 0; + }, /** * Shows the page reload overlay which will do the conference reload after * the given amount of time. @@ -97,7 +105,7 @@ export default { !$overlay && buildReloadOverlayHtml(); - if (!$overlay.parents('body').length) { + if (!this.isVisible()) { $overlay.appendTo('body'); start(timeoutSeconds); } diff --git a/modules/UI/util/MessageHandler.js b/modules/UI/util/MessageHandler.js index 319a459e3..0a478a599 100644 --- a/modules/UI/util/MessageHandler.js +++ b/modules/UI/util/MessageHandler.js @@ -333,7 +333,7 @@ var messageHandler = { messageArguments, options) { // If we're in ringing state we skip all toaster notifications. - if(!notificationsEnabled || APP.UI.isRingOverlayVisible()) + if(!notificationsEnabled || APP.UI.isOverlayVisible()) return; var displayNameSpan = ' Date: Thu, 13 Oct 2016 12:42:59 -0500 Subject: [PATCH 09/21] feat: introduce ConferenceUrl module We need to make sure that on the page reload all original parameters used to load the conference are preserved. New modules helps to manage different types of conference URLs like the one used for invites and the one for reloading the page. --- app.js | 17 +++++ modules/UI/UI.js | 13 ---- modules/UI/invite/Invite.js | 7 +- .../UI/reload_overlay/PageReloadOverlay.js | 5 +- modules/URL/ConferenceUrl.js | 73 +++++++++++++++++++ modules/util/helpers.js | 9 +++ service/UI/UIEvents.js | 5 -- 7 files changed, 103 insertions(+), 26 deletions(-) create mode 100644 modules/URL/ConferenceUrl.js diff --git a/app.js b/app.js index 49b4b1059..cdf8abb57 100644 --- a/app.js +++ b/app.js @@ -19,6 +19,7 @@ import 'aui-experimental-css'; window.toastr = require("toastr"); import URLProcessor from "./modules/config/URLProcessor"; +import ConferenceUrl from './modules/URL/ConferenceUrl'; import RoomnameGenerator from './modules/util/RoomnameGenerator'; import UI from "./modules/UI/UI"; @@ -47,6 +48,18 @@ function pushHistoryState(roomName, URL) { return null; } +/** + * Replaces current history state(replaces the URL displayed by the browser). + * @param {string} newUrl the URL string which is to be displayed by the browser + * to the user. + */ +function replaceHistoryState (newUrl) { + if (window.history + && typeof window.history.replaceState === 'function') { + window.history.replaceState({}, document.title, newUrl); + } +} + /** * Builds and returns the room name. */ @@ -107,6 +120,10 @@ function setTokenData() { function init() { setTokenData(); + // Initialize the conference URL handler + ConferenceUrl.init(window.location); + // Clean up the URL displayed by the browser + replaceHistoryState(ConferenceUrl.getInviteUrl()); var isUIReady = APP.UI.start(); if (isUIReady) { APP.conference.init({roomName: buildRoomName()}).then(function () { diff --git a/modules/UI/UI.js b/modules/UI/UI.js index 144fef378..94292d447 100644 --- a/modules/UI/UI.js +++ b/modules/UI/UI.js @@ -258,19 +258,6 @@ UI.setLocalRaisedHandStatus = (raisedHandStatus) => { */ UI.initConference = function () { let id = APP.conference.getMyUserId(); - - // Do not include query parameters in the invite URL - // "https:" + "//" + "example.com:8888" + "/SomeConference1245" - var inviteURL = window.location.protocol + "//" + - window.location.host + window.location.pathname; - - this.emitEvent(UIEvents.INVITE_URL_INITIALISED, inviteURL); - - // Clean up the URL displayed by the browser - if (window.history && typeof window.history.replaceState === 'function') { - window.history.replaceState({}, document.title, inviteURL); - } - // Add myself to the contact list. UI.ContactList.addContact(id, true); diff --git a/modules/UI/invite/Invite.js b/modules/UI/invite/Invite.js index 0d5ecdf11..24708fe2e 100644 --- a/modules/UI/invite/Invite.js +++ b/modules/UI/invite/Invite.js @@ -3,6 +3,7 @@ import InviteDialogView from './InviteDialogView'; import createRoomLocker from './RoomLocker'; import UIEvents from '../../../service/UI/UIEvents'; +import ConferenceUrl from '../../URL/ConferenceUrl'; const ConferenceEvents = JitsiMeetJS.events.conference; @@ -14,6 +15,7 @@ const ConferenceEvents = JitsiMeetJS.events.conference; class Invite { constructor(conference) { this.conference = conference; + this.inviteUrl = ConferenceUrl.getInviteUrl(); this.createRoomLocker(conference); this.registerListeners(); } @@ -48,11 +50,6 @@ class Invite { APP.UI.addListener( UIEvents.INVITE_CLICKED, () => { this.openLinkDialog(); }); - APP.UI.addListener( UIEvents.INVITE_URL_INITIALISED, - (inviteUrl) => { - this.updateInviteUrl(inviteUrl); - }); - APP.UI.addListener( UIEvents.PASSWORD_REQUIRED, () => { this.setLockedFromElsewhere(true); diff --git a/modules/UI/reload_overlay/PageReloadOverlay.js b/modules/UI/reload_overlay/PageReloadOverlay.js index 15436597b..bb1621670 100644 --- a/modules/UI/reload_overlay/PageReloadOverlay.js +++ b/modules/UI/reload_overlay/PageReloadOverlay.js @@ -1,6 +1,6 @@ /* global $, APP, AJS */ -import { reload } from '../../util/helpers'; +import ConferenceUrl from '../../URL/ConferenceUrl'; let $overlay; @@ -78,9 +78,8 @@ function start(timeoutSeconds) { updateDisplay(); if (timeLeft === 0) { - console.info("Reloading!"); window.clearInterval(intervalId); - reload(); + ConferenceUrl.reload(); } }, 1000); } diff --git a/modules/URL/ConferenceUrl.js b/modules/URL/ConferenceUrl.js new file mode 100644 index 000000000..dab1abbef --- /dev/null +++ b/modules/URL/ConferenceUrl.js @@ -0,0 +1,73 @@ + +import { redirect } from '../util/helpers'; + +/** + * Stores the original conference room URL with all parameters. + * @type {string} + */ +let originalURL; + +/** + * A simplified version of the conference URL stripped out of the parameters + * which should be used for sending invites. + * @type {string} + */ +let inviteURL; + +/** + * The modules stores information about the URL used to start the conference and + * provides utility methods for dealing with conference URL and reloads. + */ +export default { + /** + * Initializes the module. + * + * @param location an object which stores provides the info about conference + * URL(would be 'window.location' for the Web app). The params below are + * described based on the following example URL: + * + * https://example.com:8888/SomeConference1245?opt=1#somehash + * + * @param location.href full URL with all parameters, would be the whole URL + * from the example string above. + * + * @param location.host the host part of the URL, 'example.com' from + * the sample URL above. + * + * @param location.pathname the path part of the URL, would be + * '/SomeConference1245' from the example above. + * + * @param location.protocol the protocol part of the URL, would be 'https:' + * from the sample URL. + */ + init(location) { + originalURL = location.href; + // "https:" + "//" + "example.com:8888" + "/SomeConference1245" + inviteURL + = location.protocol + "//" + location.host + location.pathname; + console.info("Stored original conference URL: " + originalURL); + console.info("Conference URL for invites: " + inviteURL); + }, + /** + * Obtains the conference invite URL. + * @return {string} the URL pointing o the conference which is mean to be + * used to invite new participants. + */ + getInviteUrl() { + return inviteURL; + }, + /** + * Obtains full conference URL with all original parameters. + * @return {string} the original URL used to open the current conference. + */ + getOriginalUrl() { + return originalURL; + }, + /** + * Reloads the conference using original URL with all of the parameters. + */ + reload() { + console.info("Reloading the conference using URL: " + originalURL); + redirect(originalURL); + } +}; diff --git a/modules/util/helpers.js b/modules/util/helpers.js index 9d74d1ccc..6296b0973 100644 --- a/modules/util/helpers.js +++ b/modules/util/helpers.js @@ -20,6 +20,15 @@ export function reload () { window.location.reload(); } +/** + * Redirects to new URL. + * @param {string} url the URL pointing to the location where the user should + * be redirected to. + */ +export function redirect (url) { + window.location.replace(url); +} + /** * Prints the error and reports it to the global error handler. * @param e {Error} the error diff --git a/service/UI/UIEvents.js b/service/UI/UIEvents.js index ed2b492e5..28ba05535 100644 --- a/service/UI/UIEvents.js +++ b/service/UI/UIEvents.js @@ -145,11 +145,6 @@ export default { */ DISPLAY_NAME_CHANGED: "UI.display_name_changed", - /** - * Indicates that the invite url has been initialised. - */ - INVITE_URL_INITIALISED: "UI.invite_url_initialised", - /** * Indicates that a password is required for the call. */ From 88be44b47285670ce731ef9092c4fda00616919c Mon Sep 17 00:00:00 2001 From: Maxim Voloshin Date: Wed, 19 Oct 2016 15:31:13 +0300 Subject: [PATCH 10/21] Relocated "HD" label --- css/_variables.scss | 2 ++ css/_videolayout_default.scss | 24 ++++++++++++++++-------- index.html | 2 +- 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/css/_variables.scss b/css/_variables.scss index 0c8a54d33..b923e3745 100644 --- a/css/_variables.scss +++ b/css/_variables.scss @@ -46,6 +46,8 @@ $dominantSpeakerBg: #165ecc; $raiseHandBg: #D6D61E; $audioLevelBg: #44A5FF; $audioLevelShadow: rgba(9, 36, 77, 0.9); +$videoStateIndicatorColor: $defaultColor; +$videoStateIndicatorBackground: $tooltipBg; /** * Feedback Modal diff --git a/css/_videolayout_default.scss b/css/_videolayout_default.scss index 71879a7a8..8f4f59984 100644 --- a/css/_videolayout_default.scss +++ b/css/_videolayout_default.scss @@ -546,16 +546,24 @@ 0px 0px 1px rgba(0,0,0,0.3); } +.video-state-indicator { + background: $videoStateIndicatorBackground; + color: $videoStateIndicatorColor; + font-size: 13px; + line-height: 1.4; + text-align: center; + display: block; + min-width: 37px; + padding: 10px 0; + border-radius: 50%; +} + #videoResolutionLabel { display: none; position: absolute; - top: 5px; - right: 5px; - background: rgba(0,0,0,.5); - padding: 10px; - color: rgba(255,255,255,.5); + top: 30px; + right: 30px; z-index: 1011; - border-radius: 50%; } .centeredVideoLabel { @@ -580,8 +588,8 @@ } .moveToCorner { - top: 5px; - right: 50px; /*leave free space for the HD label*/ + top: 30px; + right: 80px; /*leave free space for the HD label*/ margin-right: 0px; margin-left: auto; background: rgba(0,0,0,.3); diff --git a/index.html b/index.html index 1bb4941a5..3d6c68348 100644 --- a/index.html +++ b/index.html @@ -240,7 +240,7 @@
- HD + HD From d09a8b18964ebb2e7f51548dd68338ffad918e03 Mon Sep 17 00:00:00 2001 From: Maxim Voloshin Date: Wed, 19 Oct 2016 19:36:10 +0300 Subject: [PATCH 11/21] Adjusted styles for "Live Streaming" indicator. --- css/_recording.scss | 2 +- css/_toolbars.scss | 2 +- css/_variables.scss | 3 ++- css/_videolayout_default.scss | 46 +++++++++++++---------------------- index.html | 4 +-- 5 files changed, 23 insertions(+), 34 deletions(-) diff --git a/css/_recording.scss b/css/_recording.scss index 0f58bb789..aa56227a7 100644 --- a/css/_recording.scss +++ b/css/_recording.scss @@ -1,4 +1,4 @@ .recordingSpinner { display: none; - vertical-align: text-bottom; + vertical-align: top; } \ No newline at end of file diff --git a/css/_toolbars.scss b/css/_toolbars.scss index f8d000e2f..22ac3f049 100644 --- a/css/_toolbars.scss +++ b/css/_toolbars.scss @@ -1,5 +1,5 @@ .toolbar { - background-color: rgba(0,0,0,0.5); + background-color: $toolbarBackground; position: relative; z-index: $toolbarZ; height: 100%; diff --git a/css/_variables.scss b/css/_variables.scss index b923e3745..8d32abb26 100644 --- a/css/_variables.scss +++ b/css/_variables.scss @@ -27,6 +27,7 @@ $defaultBackground: #474747; $tooltipBg: rgba(0,0,0, 0.7); // Toolbar +$toolbarBackground: rgba(0, 0, 0, 0.5); $toolbarSelectBackground: rgba(0, 0, 0, .6); $toolbarBadgeBackground: #165ECC; $toolbarBadgeColor: #FFFFFF; @@ -47,7 +48,7 @@ $raiseHandBg: #D6D61E; $audioLevelBg: #44A5FF; $audioLevelShadow: rgba(9, 36, 77, 0.9); $videoStateIndicatorColor: $defaultColor; -$videoStateIndicatorBackground: $tooltipBg; +$videoStateIndicatorBackground: $toolbarBackground; /** * Feedback Modal diff --git a/css/_videolayout_default.scss b/css/_videolayout_default.scss index 8f4f59984..5bfc3f5e7 100644 --- a/css/_videolayout_default.scss +++ b/css/_videolayout_default.scss @@ -550,51 +550,39 @@ background: $videoStateIndicatorBackground; color: $videoStateIndicatorColor; font-size: 13px; - line-height: 1.4; + line-height: 20px; text-align: center; - display: block; - min-width: 37px; - padding: 10px 0; + min-width: 40px; + height: 40px; + padding: 10px 5px; border-radius: 50%; + position: absolute; + box-sizing: border-box; } -#videoResolutionLabel { +#videoResolutionLabel, +.centeredVideoLabel { display: none; - position: absolute; - top: 30px; - right: 30px; z-index: 1011; } .centeredVideoLabel { - display: none; - position: absolute; bottom: 45%; - top: auto; - right: auto; - left: auto; - line-height: 28px; - height: 28px; - width: auto; - padding: 5px; - margin-right: auto; - margin-left: auto; - background: rgba(0,0,0,.5); - color: #FFF; - z-index: 1011; border-radius: 2px; -webkit-transition: all 2s 2s linear; transition: all 2s 2s linear; + + &.moveToCorner { + bottom: auto; + } } .moveToCorner { + position: absolute; top: 30px; - right: 80px; /*leave free space for the HD label*/ - margin-right: 0px; - margin-left: auto; - background: rgba(0,0,0,.3); - color: rgba(255,255,255,.5); + right: 30px; } -.hidden { -} +.moveToCorner + .moveToCorner { + right: 80px; +} \ No newline at end of file diff --git a/index.html b/index.html index 3d6c68348..db8160e88 100644 --- a/index.html +++ b/index.html @@ -240,8 +240,8 @@ - HD - + HD + From ecfc56461ed397206a9808e6d980b1e26e76fb44 Mon Sep 17 00:00:00 2001 From: paweldomas Date: Fri, 21 Oct 2016 09:20:17 -0500 Subject: [PATCH 12/21] fix(ToolbarToggler): remove Yoda condition Is not very readable and is not used across the project --- modules/UI/toolbars/ToolbarToggler.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/UI/toolbars/ToolbarToggler.js b/modules/UI/toolbars/ToolbarToggler.js index f53e54b5c..a45d46fb5 100644 --- a/modules/UI/toolbars/ToolbarToggler.js +++ b/modules/UI/toolbars/ToolbarToggler.js @@ -34,7 +34,7 @@ function hideToolbar(force) { // eslint-disable-line no-unused-vars clearTimeout(toolbarTimeoutObject); toolbarTimeoutObject = null; - if (true !== force && + if (force !== true && (Toolbar.isHovered() || SideContainerToggler.isVisible())) { toolbarTimeoutObject = setTimeout(hideToolbar, toolbarTimeout); From d342f93547ee52e603f78c3e80c7765fb0f908bc Mon Sep 17 00:00:00 2001 From: paweldomas Date: Fri, 21 Oct 2016 09:25:14 -0500 Subject: [PATCH 13/21] fix(Invite): remove unused 'updateInviteUrl' --- modules/UI/invite/Invite.js | 8 -------- 1 file changed, 8 deletions(-) diff --git a/modules/UI/invite/Invite.js b/modules/UI/invite/Invite.js index 24708fe2e..2247d8691 100644 --- a/modules/UI/invite/Invite.js +++ b/modules/UI/invite/Invite.js @@ -169,14 +169,6 @@ class Invite { } } - /** - * Updates the room invite url. - */ - updateInviteUrl (newInviteUrl) { - this.inviteUrl = newInviteUrl; - this.updateView(); - } - /** * Helper method for encoding * Invite URL From 8f8b1385fa23c4c63c1a27c4742a463de4583860 Mon Sep 17 00:00:00 2001 From: paweldomas Date: Fri, 21 Oct 2016 09:46:09 -0500 Subject: [PATCH 14/21] ref(ConferenceUrl): converts to class and binds instance to global APP Converts ConferenceUrl to a class and binds an instance to the global APP variable, as requested by HTerezov. --- app.js | 12 +++- modules/UI/invite/Invite.js | 3 +- .../UI/reload_overlay/PageReloadOverlay.js | 4 +- modules/URL/ConferenceUrl.js | 56 +++++++++---------- 4 files changed, 39 insertions(+), 36 deletions(-) diff --git a/app.js b/app.js index cdf8abb57..2b6e21982 100644 --- a/app.js +++ b/app.js @@ -19,12 +19,12 @@ import 'aui-experimental-css'; window.toastr = require("toastr"); import URLProcessor from "./modules/config/URLProcessor"; -import ConferenceUrl from './modules/URL/ConferenceUrl'; import RoomnameGenerator from './modules/util/RoomnameGenerator'; import UI from "./modules/UI/UI"; import settings from "./modules/settings/Settings"; import conference from './conference'; +import ConferenceUrl from './modules/URL/ConferenceUrl'; import API from './modules/API/API'; import UIEvents from './service/UI/UIEvents'; @@ -95,6 +95,12 @@ const APP = { UI, settings, conference, + /** + * After the APP has been initialized provides utility methods for dealing + * with the conference room URL(address). + * @type ConferenceUrl + */ + ConferenceUrl : null, connection: null, API, init () { @@ -121,9 +127,9 @@ function setTokenData() { function init() { setTokenData(); // Initialize the conference URL handler - ConferenceUrl.init(window.location); + APP.ConferenceUrl = new ConferenceUrl(window.location); // Clean up the URL displayed by the browser - replaceHistoryState(ConferenceUrl.getInviteUrl()); + replaceHistoryState(APP.ConferenceUrl.getInviteUrl()); var isUIReady = APP.UI.start(); if (isUIReady) { APP.conference.init({roomName: buildRoomName()}).then(function () { diff --git a/modules/UI/invite/Invite.js b/modules/UI/invite/Invite.js index 2247d8691..df5774088 100644 --- a/modules/UI/invite/Invite.js +++ b/modules/UI/invite/Invite.js @@ -3,7 +3,6 @@ import InviteDialogView from './InviteDialogView'; import createRoomLocker from './RoomLocker'; import UIEvents from '../../../service/UI/UIEvents'; -import ConferenceUrl from '../../URL/ConferenceUrl'; const ConferenceEvents = JitsiMeetJS.events.conference; @@ -15,7 +14,7 @@ const ConferenceEvents = JitsiMeetJS.events.conference; class Invite { constructor(conference) { this.conference = conference; - this.inviteUrl = ConferenceUrl.getInviteUrl(); + this.inviteUrl = APP.ConferenceUrl.getInviteUrl(); this.createRoomLocker(conference); this.registerListeners(); } diff --git a/modules/UI/reload_overlay/PageReloadOverlay.js b/modules/UI/reload_overlay/PageReloadOverlay.js index bb1621670..1806ce209 100644 --- a/modules/UI/reload_overlay/PageReloadOverlay.js +++ b/modules/UI/reload_overlay/PageReloadOverlay.js @@ -1,7 +1,5 @@ /* global $, APP, AJS */ -import ConferenceUrl from '../../URL/ConferenceUrl'; - let $overlay; /** @@ -79,7 +77,7 @@ function start(timeoutSeconds) { if (timeLeft === 0) { window.clearInterval(intervalId); - ConferenceUrl.reload(); + APP.ConferenceUrl.reload(); } }, 1000); } diff --git a/modules/URL/ConferenceUrl.js b/modules/URL/ConferenceUrl.js index dab1abbef..6546f7cd6 100644 --- a/modules/URL/ConferenceUrl.js +++ b/modules/URL/ConferenceUrl.js @@ -1,24 +1,12 @@ +/* global console */ import { redirect } from '../util/helpers'; -/** - * Stores the original conference room URL with all parameters. - * @type {string} - */ -let originalURL; - -/** - * A simplified version of the conference URL stripped out of the parameters - * which should be used for sending invites. - * @type {string} - */ -let inviteURL; - /** * The modules stores information about the URL used to start the conference and * provides utility methods for dealing with conference URL and reloads. */ -export default { +export default class ConferenceUrl { /** * Initializes the module. * @@ -40,34 +28,46 @@ export default { * @param location.protocol the protocol part of the URL, would be 'https:' * from the sample URL. */ - init(location) { - originalURL = location.href; - // "https:" + "//" + "example.com:8888" + "/SomeConference1245" - inviteURL + constructor(location) { + /** + * Stores the original conference room URL with all parameters. + * Example: + * https://example.com:8888/SomeConference1245?jwt=a5sbc2#blablahash + * @type {string} + */ + this.originalURL = location.href; + /** + * A simplified version of the conference URL stripped out of + * the parameters which should be used for sending invites. + * Example: + * https://example.com:8888/SomeConference1245 + * @type {string} + */ + this.inviteURL = location.protocol + "//" + location.host + location.pathname; - console.info("Stored original conference URL: " + originalURL); - console.info("Conference URL for invites: " + inviteURL); - }, + console.info("Stored original conference URL: " + this.originalURL); + console.info("Conference URL for invites: " + this.inviteURL); + } /** * Obtains the conference invite URL. * @return {string} the URL pointing o the conference which is mean to be * used to invite new participants. */ getInviteUrl() { - return inviteURL; - }, + return this.inviteURL; + } /** * Obtains full conference URL with all original parameters. * @return {string} the original URL used to open the current conference. */ getOriginalUrl() { - return originalURL; - }, + return this.originalURL; + } /** * Reloads the conference using original URL with all of the parameters. */ reload() { - console.info("Reloading the conference using URL: " + originalURL); - redirect(originalURL); + console.info("Reloading the conference using URL: " + this.originalURL); + redirect(this.originalURL); } -}; +} From 5bc727804fb23e465f6cb82e67befba9446f8e72 Mon Sep 17 00:00:00 2001 From: paweldomas Date: Fri, 21 Oct 2016 10:17:01 -0500 Subject: [PATCH 15/21] fix(PageReloadOverlay): do not log message every second --- modules/UI/reload_overlay/PageReloadOverlay.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/UI/reload_overlay/PageReloadOverlay.js b/modules/UI/reload_overlay/PageReloadOverlay.js index 1806ce209..cf58e67b2 100644 --- a/modules/UI/reload_overlay/PageReloadOverlay.js +++ b/modules/UI/reload_overlay/PageReloadOverlay.js @@ -70,7 +70,6 @@ function start(timeoutSeconds) { if (timeLeft >= 1) { timeLeft -= 1; - console.info("Reloading in " + timeLeft + " seconds..."); } updateDisplay(); @@ -80,6 +79,9 @@ function start(timeoutSeconds) { APP.ConferenceUrl.reload(); } }, 1000); + + console.info( + "The conference will be reloaded after " + timeLeft + " seconds."); } export default { From 8c426e8bb75bb467cadb17ab61193bf733636c2f Mon Sep 17 00:00:00 2001 From: paweldomas Date: Fri, 21 Oct 2016 10:27:10 -0500 Subject: [PATCH 16/21] fix(ToolbarToggle): restore call overlay to the timeout check --- modules/UI/UI.js | 9 +++++++++ modules/UI/toolbars/ToolbarToggler.js | 1 + 2 files changed, 10 insertions(+) diff --git a/modules/UI/UI.js b/modules/UI/UI.js index 94292d447..ea157e8b3 100644 --- a/modules/UI/UI.js +++ b/modules/UI/UI.js @@ -1448,6 +1448,15 @@ UI.isOverlayVisible = function () { || GumPermissionsOverlay.isVisible(); }; +/** + * Indicates if the ring overlay is currently visible. + * + * @returns {*|boolean} {true} if the ring overlay is visible, {false} otherwise + */ +UI.isRingOverlayVisible = function () { + return RingOverlay.isVisible(); +}; + /** * Shows browser-specific overlay with guidance how to proceed with gUM prompt. * @param {string} browser - name of browser for which to show the guidance diff --git a/modules/UI/toolbars/ToolbarToggler.js b/modules/UI/toolbars/ToolbarToggler.js index a45d46fb5..05ff316fb 100644 --- a/modules/UI/toolbars/ToolbarToggler.js +++ b/modules/UI/toolbars/ToolbarToggler.js @@ -36,6 +36,7 @@ function hideToolbar(force) { // eslint-disable-line no-unused-vars if (force !== true && (Toolbar.isHovered() + || APP.UI.isRingOverlayVisible() || SideContainerToggler.isVisible())) { toolbarTimeoutObject = setTimeout(hideToolbar, toolbarTimeout); } else { From 98de4c90b543b95d5ba5e481e4180f6d32462528 Mon Sep 17 00:00:00 2001 From: paweldomas Date: Fri, 21 Oct 2016 10:45:45 -0500 Subject: [PATCH 17/21] fix(RingOverlay): puts the "ring overlay" back below the toolbars --- css/_variables.scss | 1 + css/ringing/_ringing.scss | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/css/_variables.scss b/css/_variables.scss index 764eeeb66..53481da1b 100644 --- a/css/_variables.scss +++ b/css/_variables.scss @@ -91,6 +91,7 @@ $tooltipsZ: 901; $toolbarZ: 900; $overlayZ: 902; $notificationZ: 1012; +$ringingZ: 800; /** * Font Colors TODO: Change colors when general dialogs are implemented. diff --git a/css/ringing/_ringing.scss b/css/ringing/_ringing.scss index b973bd41a..b04093a78 100644 --- a/css/ringing/_ringing.scss +++ b/css/ringing/_ringing.scss @@ -5,7 +5,7 @@ width: 100%; height: 100%; position: fixed; - z-index: $overlayZ; + z-index: $ringingZ; background: linear-gradient(transparent, #000); opacity: 0.8; From 3c0c823a37c7d9c204746bb49c85fdf6390ff22c Mon Sep 17 00:00:00 2001 From: paweldomas Date: Fri, 21 Oct 2016 13:01:30 -0500 Subject: [PATCH 18/21] ref(Overlay): introduce base class --- .../UserMediaPermissionsGuidanceOverlay.js | 59 +++--- modules/UI/overlay/Overlay.js | 82 +++++++++ .../UI/reload_overlay/PageReloadOverlay.js | 170 +++++++++--------- 3 files changed, 209 insertions(+), 102 deletions(-) create mode 100644 modules/UI/overlay/Overlay.js diff --git a/modules/UI/gum_overlay/UserMediaPermissionsGuidanceOverlay.js b/modules/UI/gum_overlay/UserMediaPermissionsGuidanceOverlay.js index d25880ba2..11c9fd2d3 100644 --- a/modules/UI/gum_overlay/UserMediaPermissionsGuidanceOverlay.js +++ b/modules/UI/gum_overlay/UserMediaPermissionsGuidanceOverlay.js @@ -1,27 +1,41 @@ -/* global $, APP */ +/* global */ -let $overlay; +import Overlay from '../overlay/Overlay'; /** - * Internal function that constructs overlay with guidance how to proceed with - * gUM prompt. - * @param {string} browser - name of browser for which to construct the - * guidance overlay. + * An overlay with guidance how to proceed with gUM prompt. */ -function buildOverlayHtml(browser) { - $overlay = $(` -
-
- - - -
-
`); +class GUMOverlayImpl extends Overlay { - APP.translation.translateElement($overlay); + /** + * Constructs overlay with guidance how to proceed with gUM prompt. + * @param {string} browser - name of browser for which to construct the + * guidance overlay. + * @override + */ + constructor(browser) { + super(); + this.browser = browser; + } + + /** + * @inheritDoc + */ + _buildOverlayContent() { + return ` + + + `; + } } +/** + * Stores GUM overlay instance. + * @type {GUMOverlayImpl} + */ +let overlay; + export default { /** * Checks whether the overlay is currently visible. @@ -29,7 +43,7 @@ export default { * or false otherwise. */ isVisible () { - return $overlay && $overlay.parents('body').length > 0; + return overlay && overlay.isVisible(); }, /** * Shows browser-specific overlay with guidance how to proceed with @@ -38,9 +52,10 @@ export default { * guidance overlay. */ show(browser) { - !$overlay && buildOverlayHtml(browser); - - !this.isVisible() && $overlay.appendTo('body'); + if (!overlay) { + overlay = new GUMOverlayImpl(browser); + } + overlay.show(); }, /** @@ -48,6 +63,6 @@ export default { * gUM prompt. */ hide() { - $overlay && $overlay.detach(); + overlay && overlay.hide(); } }; diff --git a/modules/UI/overlay/Overlay.js b/modules/UI/overlay/Overlay.js new file mode 100644 index 000000000..babdc587a --- /dev/null +++ b/modules/UI/overlay/Overlay.js @@ -0,0 +1,82 @@ +/* global $, APP */ + +/** + * Base class for overlay components - the components which are displayed on + * top of the application with semi-transparent background covering the whole + * screen. + */ +export default class Overlay{ + /** + * Creates new Overlay instance. + */ + constructor() { + /** + * + * @type {jQuery} + */ + this.$overlay = null; + } + /** + * Template method which should be used by subclasses to provide the overlay + * content. The contents provided by this method are later subject to + * the translation using {@link APP.translation.translateElement}. + * @return {string} HTML representation of the overlay dialog contents. + * @private + */ + _buildOverlayContent() { + return ''; + } + /** + * Constructs the HTML body of the overlay dialog. + */ + buildOverlayHtml() { + + let overlayContent = this._buildOverlayContent(); + + this.$overlay = $(` +
+
+ ${overlayContent} +
+
`); + + APP.translation.translateElement(this.$overlay); + } + /** + * Checks whether the page reload overlay has been displayed. + * @return {boolean} true if the page reload overlay is currently + * visible or false otherwise. + */ + isVisible() { + return this.$overlay && this.$overlay.parents('body').length > 0; + } + /** + * Template method called just after the overlay is displayed for the first + * time. + * @private + */ + _onShow() { + // To be overridden by subclasses. + } + /** + * Shows the overlay dialog adn attaches the underlying HTML representation + * to the DOM. + */ + show() { + + !this.$overlay && this.buildOverlayHtml(); + + if (!this.isVisible()) { + this.$overlay.appendTo('body'); + this._onShow(); + } + } + + /** + * Hides the overlay dialog and detaches it's HTML representation from + * the DOM. + */ + hide() { + this.$overlay && this.$overlay.detach(); + } +} diff --git a/modules/UI/reload_overlay/PageReloadOverlay.js b/modules/UI/reload_overlay/PageReloadOverlay.js index cf58e67b2..03c1368ec 100644 --- a/modules/UI/reload_overlay/PageReloadOverlay.js +++ b/modules/UI/reload_overlay/PageReloadOverlay.js @@ -1,88 +1,100 @@ /* global $, APP, AJS */ -let $overlay; +import Overlay from '../overlay/Overlay'; /** - * Conference reload counter in seconds. - * @type {number} + * An overlay dialog which is shown before the conference is reloaded. Shows + * a warning message and counts down towards the reload. */ -let timeLeft; - -/** - * Conference reload timeout in seconds. - * @type {number} - */ -let timeout; - -/** - * Internal function that constructs overlay with the warning message and count - * down towards the conference reload. - */ -function buildReloadOverlayHtml() { - $overlay = $(` -
-
- - -
-
- -
- - +class PageReloadOverlayImpl extends Overlay{ + /** + * Creates new PageReloadOverlayImpl + * @param {number} timeoutSeconds how long the overlay dialog will be + * displayed, before the conference will be reloaded. + */ + constructor(timeoutSeconds) { + super(); + /** + * Conference reload counter in seconds. + * @type {number} + */ + this.timeLeft = timeoutSeconds; + /** + * Conference reload timeout in seconds. + * @type {number} + */ + this.timeout = timeoutSeconds; + } + /** + * Constructs overlay body with the warning message and count down towards + * the conference reload. + * @override + */ + _buildOverlayContent() { + return ` + + +
+
+
-
-
`); + + +
`; + } - APP.translation.translateElement($overlay); + /** + * Updates the progress indicator position and the label with the time left. + */ + updateDisplay() { + + const timeLeftTxt + = APP.translation.translateString( + "dialog.conferenceReloadTimeLeft", + { seconds: this.timeLeft }); + $("#reloadSecRemaining").text(timeLeftTxt); + + const ratio = (this.timeout - this.timeLeft) / this.timeout; + AJS.progressBars.update("#reloadProgressBar", ratio); + } + + /** + * Starts the reload countdown with the animation. + * @override + */ + _onShow() { + + // Initialize displays + this.updateDisplay(); + + var intervalId = window.setInterval(function() { + + if (this.timeLeft >= 1) { + this.timeLeft -= 1; + } + + this.updateDisplay(); + + if (this.timeLeft === 0) { + window.clearInterval(intervalId); + APP.ConferenceUrl.reload(); + } + }.bind(this), 1000); + + console.info( + "The conference will be reloaded after " + + this.timeLeft + " seconds."); + } } /** - * Updates the progress indicator position and the label with the time left. + * Holds the page reload overlay instance. + * + * {@type PageReloadOverlayImpl} */ -function updateDisplay() { - - const timeLeftTxt - = APP.translation.translateString( - "dialog.conferenceReloadTimeLeft", - { seconds: timeLeft }); - $("#reloadSecRemaining").text(timeLeftTxt); - - const ratio = (timeout-timeLeft)/timeout; - AJS.progressBars.update("#reloadProgressBar", ratio); -} - -/** - * Starts the reload countdown with the animation. - * @param {number} timeoutSeconds how many seconds before the conference - * reload will happen. - */ -function start(timeoutSeconds) { - - timeLeft = timeout = timeoutSeconds; - - // Initialize displays - updateDisplay(); - - var intervalId = window.setInterval(function() { - - if (timeLeft >= 1) { - timeLeft -= 1; - } - - updateDisplay(); - - if (timeLeft === 0) { - window.clearInterval(intervalId); - APP.ConferenceUrl.reload(); - } - }, 1000); - - console.info( - "The conference will be reloaded after " + timeLeft + " seconds."); -} +let overlay; export default { /** @@ -91,7 +103,7 @@ export default { * visible or false otherwise. */ isVisible() { - return $overlay && $overlay.parents('body').length > 0; + return overlay && overlay.isVisible(); }, /** * Shows the page reload overlay which will do the conference reload after @@ -102,11 +114,9 @@ export default { */ show(timeoutSeconds) { - !$overlay && buildReloadOverlayHtml(); - - if (!this.isVisible()) { - $overlay.appendTo('body'); - start(timeoutSeconds); + if (!overlay) { + overlay = new PageReloadOverlayImpl(timeoutSeconds); } + overlay.show(); } }; From a61564993396fbe2a83ebabc70fe818fdb1f1129 Mon Sep 17 00:00:00 2001 From: paweldomas Date: Fri, 21 Oct 2016 13:46:23 -0500 Subject: [PATCH 19/21] fix(PageReloadOverlay): changes text and adjusts style --- css/main.scss | 1 + css/reload_overlay/_reload_overlay.scss | 17 +++++++++++++++++ lang/main.json | 3 ++- modules/UI/reload_overlay/PageReloadOverlay.js | 8 ++++---- 4 files changed, 24 insertions(+), 5 deletions(-) create mode 100644 css/reload_overlay/_reload_overlay.scss diff --git a/css/main.scss b/css/main.scss index c65ff91d9..7fb71d2df 100644 --- a/css/main.scss +++ b/css/main.scss @@ -38,6 +38,7 @@ @import 'toastr'; @import 'base'; @import 'overlay/overlay'; +@import 'reload_overlay/reload_overlay'; @import 'modals/dialog'; @import 'modals/feedback/feedback'; @import 'videolayout_default'; diff --git a/css/reload_overlay/_reload_overlay.scss b/css/reload_overlay/_reload_overlay.scss new file mode 100644 index 000000000..15c8fdbd4 --- /dev/null +++ b/css/reload_overlay/_reload_overlay.scss @@ -0,0 +1,17 @@ +.reload_overlay_title { + display: block; + font-size: 16px; + line-height: 20px; +} + +.reload_overlay_msg { + display: block; + font-size: 12px; + line-height: 30px; +} + +#reloadProgressBar { + width: 180px; + margin: 5px auto; +} + diff --git a/lang/main.json b/lang/main.json index 74d9e3ed0..86de9cc2d 100644 --- a/lang/main.json +++ b/lang/main.json @@ -202,7 +202,8 @@ "detectext": "Error when trying to detect desktopsharing extension.", "failtoinstall": "Failed to install desktop sharing extension", "failedpermissions": "Failed to obtain permissions to use the local microphone and/or camera.", - "conferenceReloadMsg": "Something went wrong we'll try to reload the conference in...", + "conferenceReloadTitle": "Unfortunately, something went wrong", + "conferenceReloadMsg": "We're trying to fix this", "conferenceReloadTimeLeft": "__seconds__ sec.", "maxUsersLimitReached": "The limit for maximum number of participants in the conference has been reached. The conference is full. Please try again later!", "lockTitle": "Lock failed", diff --git a/modules/UI/reload_overlay/PageReloadOverlay.js b/modules/UI/reload_overlay/PageReloadOverlay.js index 03c1368ec..4529ab478 100644 --- a/modules/UI/reload_overlay/PageReloadOverlay.js +++ b/modules/UI/reload_overlay/PageReloadOverlay.js @@ -32,15 +32,15 @@ class PageReloadOverlayImpl extends Overlay{ */ _buildOverlayContent() { return ` - + + class='reload_overlay_msg'>
- +
`; } From bf5a1d1f8e3bafd845cc72703ff1cc62ffa3e6ec Mon Sep 17 00:00:00 2001 From: paweldomas Date: Fri, 21 Oct 2016 14:03:34 -0500 Subject: [PATCH 20/21] fix(videolayout css): reduce conn problem msg z-index For small window sizes and many video thumbnails the message may go on top of the thumbnails. --- css/_videolayout_default.scss | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/css/_videolayout_default.scss b/css/_videolayout_default.scss index 71879a7a8..98b430208 100644 --- a/css/_videolayout_default.scss +++ b/css/_videolayout_default.scss @@ -511,7 +511,7 @@ display: none; position: absolute; width: auto; - z-index: 1011; + z-index: 2; font-weight: 600; font-size: 14px; text-align: center; @@ -534,7 +534,7 @@ position: absolute; width: 100%; top:50%; - z-index: 1011; + z-index: 2; font-weight: 600; font-size: 14px; text-align: center; From 15bc3b9ad444743ca0ef40512342f0db0e24a653 Mon Sep 17 00:00:00 2001 From: Konstantyn Pahsura Date: Mon, 24 Oct 2016 19:30:47 +0300 Subject: [PATCH 21/21] dropdown color changes --- css/_variables.scss | 6 +++--- css/aui-components/dropdown.scss | 16 +++++----------- 2 files changed, 8 insertions(+), 14 deletions(-) diff --git a/css/_variables.scss b/css/_variables.scss index f7eb7a2f7..7e0ec2c19 100644 --- a/css/_variables.scss +++ b/css/_variables.scss @@ -110,6 +110,6 @@ $linkHoverFontColor: #287ade; /** * Forms */ -$inputBg: #505F79; -$inputBgHover: #505F79; -$inputFontColor: #ECEEF1; \ No newline at end of file +$inputBg: $inputSemiBackground; +$inputBgHover: $inputSemiBackground; +$inputFontColor: $defaultDarkFontColor; \ No newline at end of file diff --git a/css/aui-components/dropdown.scss b/css/aui-components/dropdown.scss index 930cfebe0..1ef7a531c 100644 --- a/css/aui-components/dropdown.scss +++ b/css/aui-components/dropdown.scss @@ -3,6 +3,10 @@ form.aui { background-color: transparent; > a { + background-color: $inputBg !important; + color: $inputFontColor !important; + border-color: $inputBg !important; + text-shadow: none !important; margin: 0 auto !important; width: 100% !important; } @@ -32,17 +36,7 @@ form.aui { z-index: 900; } -//Dark theme -form.aui{ - //Placeholder - .aui-select2-container.input-container-dark { - a.select2-choice { - text-shadow: none; - } - } -} - .aui-dropdown2.aui-style-default.dropdown-dark { background-color: $defaultBackground; border-color: transparent; -} +} \ No newline at end of file