Browse Source

Merge pull request #1008 from jitsi/page_reload_overlay

Page reload overlay
j8
hristoterezov 8 years ago
parent
commit
3dca6f2354

+ 23
- 0
app.js View File

@@ -24,6 +24,7 @@ import RoomnameGenerator from './modules/util/RoomnameGenerator';
24 24
 import UI from "./modules/UI/UI";
25 25
 import settings from "./modules/settings/Settings";
26 26
 import conference from './conference';
27
+import ConferenceUrl from './modules/URL/ConferenceUrl';
27 28
 import API from './modules/API/API';
28 29
 
29 30
 import UIEvents from './service/UI/UIEvents';
@@ -47,6 +48,18 @@ function pushHistoryState(roomName, URL) {
47 48
     return null;
48 49
 }
49 50
 
51
+/**
52
+ * Replaces current history state(replaces the URL displayed by the browser).
53
+ * @param {string} newUrl the URL string which is to be displayed by the browser
54
+ * to the user.
55
+ */
56
+function replaceHistoryState (newUrl) {
57
+    if (window.history
58
+        && typeof window.history.replaceState === 'function') {
59
+        window.history.replaceState({}, document.title, newUrl);
60
+    }
61
+}
62
+
50 63
 /**
51 64
  * Builds and returns the room name.
52 65
  */
@@ -82,6 +95,12 @@ const APP = {
82 95
     UI,
83 96
     settings,
84 97
     conference,
98
+    /**
99
+     * After the APP has been initialized provides utility methods for dealing
100
+     * with the conference room URL(address).
101
+     * @type ConferenceUrl
102
+     */
103
+    ConferenceUrl : null,
85 104
     connection: null,
86 105
     API,
87 106
     init () {
@@ -107,6 +126,10 @@ function setTokenData() {
107 126
 
108 127
 function init() {
109 128
     setTokenData();
129
+    // Initialize the conference URL handler
130
+    APP.ConferenceUrl = new ConferenceUrl(window.location);
131
+    // Clean up the URL displayed by the browser
132
+    replaceHistoryState(APP.ConferenceUrl.getInviteUrl());
110 133
     var isUIReady = APP.UI.start();
111 134
     if (isUIReady) {
112 135
         APP.conference.init({roomName: buildRoomName()}).then(function () {

+ 14
- 5
conference.js View File

@@ -329,10 +329,6 @@ class ConferenceConnector {
329 329
             }
330 330
             break;
331 331
 
332
-        case ConferenceErrors.VIDEOBRIDGE_NOT_AVAILABLE:
333
-            APP.UI.notifyBridgeDown();
334
-            break;
335
-
336 332
             // not enough rights to create conference
337 333
         case ConferenceErrors.AUTHENTICATION_REQUIRED:
338 334
             // schedule reconnect to check if someone else created the room
@@ -367,6 +363,10 @@ class ConferenceConnector {
367 363
             }
368 364
             break;
369 365
 
366
+            // FIXME FOCUS_DISCONNECTED is confusing event name.
367
+            // What really happens there is that the library is not ready yet,
368
+            // because Jicofo is not available, but it is going to give
369
+            // it another try.
370 370
         case ConferenceErrors.FOCUS_DISCONNECTED:
371 371
             {
372 372
                 let [focus, retrySec] = params;
@@ -375,8 +375,17 @@ class ConferenceConnector {
375 375
             break;
376 376
 
377 377
         case ConferenceErrors.FOCUS_LEFT:
378
+        case ConferenceErrors.VIDEOBRIDGE_NOT_AVAILABLE:
379
+            // Log the page reload event
380
+            // FIXME (CallStats - issue) this event will not make it to
381
+            // the CallStats, because the log queue is not flushed, before
382
+            // "fabric terminated" is sent to the backed
383
+            APP.conference.logEvent('page.reload');
384
+            // FIXME the conference should be stopped by the library and not by
385
+            // the app. Both the errors above are unrecoverable from the library
386
+            // perspective.
378 387
             room.leave().then(() => connection.disconnect());
379
-            APP.UI.notifyFocusLeft();
388
+            APP.UI.showPageReloadOverlay();
380 389
             break;
381 390
 
382 391
         case ConferenceErrors.CONFERENCE_MAX_USERS:

+ 2
- 1
css/_variables.scss View File

@@ -84,8 +84,9 @@ $sidebarWidth: 200px;
84 84
  */
85 85
 $tooltipsZ: 901;
86 86
 $toolbarZ: 900;
87
-$overlayZ: 800;
87
+$overlayZ: 902;
88 88
 $notificationZ: 1012;
89
+$ringingZ: 800;
89 90
 
90 91
 /**
91 92
  * Font Colors TODO: Change colors when general dialogs are implemented.

+ 1
- 0
css/main.scss View File

@@ -38,6 +38,7 @@
38 38
 @import 'toastr';
39 39
 @import 'base';
40 40
 @import 'overlay/overlay';
41
+@import 'reload_overlay/reload_overlay';
41 42
 @import 'modals/dialog';
42 43
 @import 'modals/feedback/feedback';
43 44
 @import 'videolayout_default';

+ 5
- 23
css/overlay/_overlay.scss View File

@@ -1,48 +1,30 @@
1
-.overlay {
2
-    position: fixed;
3
-    left: 0;
4
-    top: 0;
5
-    width: 100%;
6
-    height: 100%;
7
-    z-index: $overlayZ;
8
-    background: #21B9FC; /* Old browsers */
9
-    opacity: 0.75;
10
-    display: block;
11
-}
12
-
13
-.overlay_transparent {
14
-    background: rgba(22, 185, 252, .9);
15
-}
16
-
17 1
 .overlay_container {
2
+    top: 0;
3
+    left: 0;
18 4
     width: 100%;
19 5
     height: 100%;
20 6
     position: fixed;
21 7
     z-index: $overlayZ;
8
+    background: rgba(22, 185, 252, .9);
22 9
 }
23 10
 
24 11
 .overlay_content {
25 12
     color: #fff;
26
-    font-weight: normal;
27
-    font-size: 20px;
28 13
     text-align: center;
29 14
     width: 400px;
30 15
     height: 250px;
31 16
     top: 50%;
32 17
     left: 50%;
33
-    position:absolute;
18
+    position: absolute;
34 19
     margin-top: -125px;
35 20
     margin-left: -200px;
36 21
 }
37 22
 
38
-
39 23
 .overlay_text_small {
24
+    display: block;
40 25
     font-size: 18px;
41 26
 }
42 27
 
43 28
 .overlay_icon {
44
-    position: relative;
45
-    z-index: 1013;
46
-    float: none;
47 29
     font-size: 100px;
48 30
 }

+ 17
- 0
css/reload_overlay/_reload_overlay.scss View File

@@ -0,0 +1,17 @@
1
+.reload_overlay_title {
2
+    display: block;
3
+    font-size: 16px;
4
+    line-height: 20px;
5
+}
6
+
7
+.reload_overlay_msg {
8
+    display: block;
9
+    font-size: 12px;
10
+    line-height: 30px;
11
+}
12
+
13
+#reloadProgressBar {
14
+    width: 180px;
15
+    margin: 5px auto;
16
+}
17
+

+ 1
- 1
css/ringing/_ringing.scss View File

@@ -5,7 +5,7 @@
5 5
     width: 100%;
6 6
     height: 100%;
7 7
     position: fixed;
8
-    z-index: $overlayZ;
8
+    z-index: $ringingZ;
9 9
     background: linear-gradient(transparent, #000);
10 10
     opacity: 0.8;
11 11
 

+ 3
- 2
lang/main.json View File

@@ -202,8 +202,9 @@
202 202
         "detectext": "Error when trying to detect desktopsharing extension.",
203 203
         "failtoinstall": "Failed to install desktop sharing extension",
204 204
         "failedpermissions": "Failed to obtain permissions to use the local microphone and/or camera.",
205
-        "bridgeUnavailable": "Jitsi Videobridge is currently unavailable. Please try again later!",
206
-        "jicofoUnavailable": "Jicofo is currently unavailable. Please try again later!",
205
+        "conferenceReloadTitle": "Unfortunately, something went wrong",
206
+        "conferenceReloadMsg": "We're trying to fix this",
207
+        "conferenceReloadTimeLeft": "__seconds__ sec.",
207 208
         "maxUsersLimitReached": "The limit for maximum number of participants in the conference has been reached. The conference is full. Please try again later!",
208 209
         "lockTitle": "Lock failed",
209 210
         "lockMessage": "Failed to lock the conference.",

+ 17
- 39
modules/UI/UI.js View File

@@ -14,12 +14,12 @@ import Recording from "./recording/Recording";
14 14
 import GumPermissionsOverlay
15 15
     from './gum_overlay/UserMediaPermissionsGuidanceOverlay';
16 16
 
17
+import PageReloadOverlay from './reload_overlay/PageReloadOverlay';
17 18
 import VideoLayout from "./videolayout/VideoLayout";
18 19
 import FilmStrip from "./videolayout/FilmStrip";
19 20
 import SettingsMenu from "./side_pannels/settings/SettingsMenu";
20 21
 import Profile from "./side_pannels/profile/Profile";
21 22
 import Settings from "./../settings/Settings";
22
-import { reload } from '../util/helpers';
23 23
 import RingOverlay from "./ring_overlay/RingOverlay";
24 24
 import UIErrors from './UIErrors';
25 25
 
@@ -195,13 +195,6 @@ UI.notifyConferenceDestroyed = function (reason) {
195 195
     messageHandler.openDialog(title, reason, true, {}, () => false);
196 196
 };
197 197
 
198
-/**
199
- * Notify user that Jitsi Videobridge is not accessible.
200
- */
201
- UI.notifyBridgeDown = function () {
202
-    messageHandler.showError("dialog.error", "dialog.bridgeUnavailable");
203
-};
204
-
205 198
 /**
206 199
  * Show chat error.
207 200
  * @param err the Error
@@ -265,19 +258,6 @@ UI.setLocalRaisedHandStatus = (raisedHandStatus) => {
265 258
  */
266 259
 UI.initConference = function () {
267 260
     let id = APP.conference.getMyUserId();
268
-
269
-    // Do not include query parameters in the invite URL
270
-    // "https:" + "//" + "example.com:8888" + "/SomeConference1245"
271
-    var inviteURL = window.location.protocol + "//" +
272
-        window.location.host + window.location.pathname;
273
-
274
-    this.emitEvent(UIEvents.INVITE_URL_INITIALISED, inviteURL);
275
-
276
-    // Clean up the URL displayed by the browser
277
-    if (window.history && typeof window.history.replaceState === 'function') {
278
-        window.history.replaceState({}, document.title, inviteURL);
279
-    }
280
-
281 261
     // Add myself to the contact list.
282 262
     UI.ContactList.addContact(id, true);
283 263
 
@@ -1119,25 +1099,11 @@ UI.notifyFocusDisconnected = function (focus, retrySec) {
1119 1099
 };
1120 1100
 
1121 1101
 /**
1122
- * Notify user that focus left the conference so page should be reloaded.
1102
+ * Notify the user that the video conferencing service is badly broken and
1103
+ * the page should be reloaded.
1123 1104
  */
1124
-UI.notifyFocusLeft = function () {
1125
-    let title = APP.translation.generateTranslationHTML(
1126
-        'dialog.serviceUnavailable'
1127
-    );
1128
-    let msg = APP.translation.generateTranslationHTML(
1129
-        'dialog.jicofoUnavailable'
1130
-    );
1131
-    messageHandler.openDialog(
1132
-        title,
1133
-        msg,
1134
-        true, // persistent
1135
-        [{title: 'retry'}],
1136
-        function () {
1137
-            reload();
1138
-            return false;
1139
-        }
1140
-    );
1105
+UI.showPageReloadOverlay = function () {
1106
+    PageReloadOverlay.show(15 /* will reload in 15 seconds */);
1141 1107
 };
1142 1108
 
1143 1109
 /**
@@ -1475,6 +1441,18 @@ UI.hideRingOverLay = function () {
1475 1441
     FilmStrip.toggleFilmStrip(true);
1476 1442
 };
1477 1443
 
1444
+/**
1445
+ * Indicates if any the "top" overlays are currently visible. The check includes
1446
+ * the call overlay, GUM permissions overlay and a page reload overlay.
1447
+ *
1448
+ * @returns {*|boolean} {true} if the overlay is visible, {false} otherwise
1449
+ */
1450
+UI.isOverlayVisible = function () {
1451
+    return RingOverlay.isVisible()
1452
+        || PageReloadOverlay.isVisible()
1453
+        || GumPermissionsOverlay.isVisible();
1454
+};
1455
+
1478 1456
 /**
1479 1457
  * Indicates if the ring overlay is currently visible.
1480 1458
  *

+ 44
- 22
modules/UI/gum_overlay/UserMediaPermissionsGuidanceOverlay.js View File

@@ -1,29 +1,50 @@
1
-/* global $, APP */
1
+/* global */
2 2
 
3
-let $overlay;
3
+import Overlay from '../overlay/Overlay';
4 4
 
5 5
 /**
6
- * Internal function that constructs overlay with guidance how to proceed with
7
- * gUM prompt.
8
- * @param {string} browser - name of browser for which to construct the
9
- *      guidance overlay.
6
+ * An overlay with guidance how to proceed with gUM prompt.
10 7
  */
11
-function buildOverlayHtml(browser) {
12
-    $overlay = $(`
13
-        <div class='overlay_container'>
14
-            <div class='overlay overlay_transparent' />
15
-            <div class='overlay_content'>
16
-                <span class="overlay_icon icon-microphone"></span>
17
-                <span class="overlay_icon icon-camera"></span>
18
-                <span data-i18n='[html]userMedia.${browser}GrantPermissions' 
19
-                    class='overlay_text overlay_text_small'></span>
20
-            </div>
21
-        </div>`);
8
+class GUMOverlayImpl extends Overlay {
22 9
 
23
-    APP.translation.translateElement($overlay);
10
+    /**
11
+     * Constructs overlay with guidance how to proceed with gUM prompt.
12
+     * @param {string} browser - name of browser for which to construct the
13
+     *     guidance overlay.
14
+     * @override
15
+     */
16
+    constructor(browser) {
17
+        super();
18
+        this.browser = browser;
19
+    }
20
+
21
+    /**
22
+     * @inheritDoc
23
+     */
24
+    _buildOverlayContent() {
25
+        return `
26
+            <span class="overlay_icon icon-microphone"></span>
27
+            <span class="overlay_icon icon-camera"></span>
28
+            <span data-i18n='[html]userMedia.${this.browser}GrantPermissions' 
29
+                  class='overlay_text_small'></span>`;
30
+    }
24 31
 }
25 32
 
33
+/**
34
+ * Stores GUM overlay instance.
35
+ * @type {GUMOverlayImpl}
36
+ */
37
+let overlay;
38
+
26 39
 export default {
40
+    /**
41
+     * Checks whether the overlay is currently visible.
42
+     * @return {boolean} <tt>true</tt> if the overlay is visible
43
+     * or <tt>false</tt> otherwise.
44
+     */
45
+    isVisible () {
46
+        return overlay && overlay.isVisible();
47
+    },
27 48
     /**
28 49
      * Shows browser-specific overlay with guidance how to proceed with
29 50
      * gUM prompt.
@@ -31,9 +52,10 @@ export default {
31 52
      *      guidance overlay.
32 53
      */
33 54
     show(browser) {
34
-        !$overlay && buildOverlayHtml(browser);
35
-
36
-        !$overlay.parents('body').length && $overlay.appendTo('body');
55
+        if (!overlay) {
56
+            overlay = new GUMOverlayImpl(browser);
57
+        }
58
+        overlay.show();
37 59
     },
38 60
 
39 61
     /**
@@ -41,6 +63,6 @@ export default {
41 63
      * gUM prompt.
42 64
      */
43 65
     hide() {
44
-        $overlay && $overlay.detach();
66
+        overlay && overlay.hide();
45 67
     }
46 68
 };

+ 1
- 13
modules/UI/invite/Invite.js View File

@@ -14,6 +14,7 @@ const ConferenceEvents = JitsiMeetJS.events.conference;
14 14
 class Invite {
15 15
     constructor(conference) {
16 16
         this.conference = conference;
17
+        this.inviteUrl = APP.ConferenceUrl.getInviteUrl();
17 18
         this.createRoomLocker(conference);
18 19
         this.registerListeners();
19 20
     }
@@ -48,11 +49,6 @@ class Invite {
48 49
         APP.UI.addListener( UIEvents.INVITE_CLICKED,
49 50
                             () => { this.openLinkDialog(); });
50 51
 
51
-        APP.UI.addListener( UIEvents.INVITE_URL_INITIALISED,
52
-                            (inviteUrl) => {
53
-                                this.updateInviteUrl(inviteUrl);
54
-                            });
55
-
56 52
         APP.UI.addListener( UIEvents.PASSWORD_REQUIRED,
57 53
             () => {
58 54
                 this.setLockedFromElsewhere(true);
@@ -172,14 +168,6 @@ class Invite {
172 168
         }
173 169
     }
174 170
 
175
-    /**
176
-     * Updates the room invite url.
177
-     */
178
-    updateInviteUrl (newInviteUrl) {
179
-        this.inviteUrl = newInviteUrl;
180
-        this.updateView();
181
-    }
182
-
183 171
     /**
184 172
      * Helper method for encoding
185 173
      * Invite URL

+ 82
- 0
modules/UI/overlay/Overlay.js View File

@@ -0,0 +1,82 @@
1
+/* global $, APP */
2
+
3
+/**
4
+ * Base class for overlay components - the components which are displayed on
5
+ * top of the application with semi-transparent background covering the whole
6
+ * screen.
7
+ */
8
+export default class Overlay{
9
+    /**
10
+     * Creates new <tt>Overlay</tt> instance.
11
+     */
12
+    constructor() {
13
+        /**
14
+         *
15
+         * @type {jQuery}
16
+         */
17
+        this.$overlay = null;
18
+    }
19
+    /**
20
+     * Template method which should be used by subclasses to provide the overlay
21
+     * content. The contents provided by this method are later subject to
22
+     * the translation using {@link APP.translation.translateElement}.
23
+     * @return {string} HTML representation of the overlay dialog contents.
24
+     * @private
25
+     */
26
+    _buildOverlayContent() {
27
+        return '';
28
+    }
29
+    /**
30
+     * Constructs the HTML body of the overlay dialog.
31
+     */
32
+    buildOverlayHtml() {
33
+
34
+        let overlayContent = this._buildOverlayContent();
35
+
36
+        this.$overlay = $(`
37
+            <div class='overlay_container'>
38
+                <div class='overlay_content'>
39
+                    ${overlayContent}
40
+                </div>
41
+            </div>`);
42
+
43
+        APP.translation.translateElement(this.$overlay);
44
+    }
45
+    /**
46
+     * Checks whether the page reload overlay has been displayed.
47
+     * @return {boolean} <tt>true</tt> if the page reload overlay is currently
48
+     * visible or <tt>false</tt> otherwise.
49
+     */
50
+    isVisible() {
51
+        return this.$overlay && this.$overlay.parents('body').length > 0;
52
+    }
53
+    /**
54
+     * Template method called just after the overlay is displayed for the first
55
+     * time.
56
+     * @private
57
+     */
58
+    _onShow() {
59
+        // To be overridden by subclasses.
60
+    }
61
+    /**
62
+     * Shows the overlay dialog adn attaches the underlying HTML representation
63
+     * to the DOM.
64
+     */
65
+    show() {
66
+
67
+        !this.$overlay && this.buildOverlayHtml();
68
+
69
+        if (!this.isVisible()) {
70
+            this.$overlay.appendTo('body');
71
+            this._onShow();
72
+        }
73
+    }
74
+
75
+    /**
76
+     * Hides the overlay dialog and detaches it's HTML representation from
77
+     * the DOM.
78
+     */
79
+    hide() {
80
+        this.$overlay && this.$overlay.detach();
81
+    }
82
+}

+ 122
- 0
modules/UI/reload_overlay/PageReloadOverlay.js View File

@@ -0,0 +1,122 @@
1
+/* global $, APP, AJS */
2
+
3
+import Overlay from '../overlay/Overlay';
4
+
5
+/**
6
+ * An overlay dialog which is shown before the conference is reloaded. Shows
7
+ * a warning message and counts down towards the reload.
8
+ */
9
+class PageReloadOverlayImpl extends Overlay{
10
+    /**
11
+     * Creates new <tt>PageReloadOverlayImpl</tt>
12
+     * @param {number} timeoutSeconds how long the overlay dialog will be
13
+     * displayed, before the conference will be reloaded.
14
+     */
15
+    constructor(timeoutSeconds) {
16
+        super();
17
+        /**
18
+         * Conference reload counter in seconds.
19
+         * @type {number}
20
+         */
21
+        this.timeLeft = timeoutSeconds;
22
+        /**
23
+         * Conference reload timeout in seconds.
24
+         * @type {number}
25
+         */
26
+        this.timeout = timeoutSeconds;
27
+    }
28
+    /**
29
+     * Constructs overlay body with the warning message and count down towards
30
+     * the conference reload.
31
+     * @override
32
+     */
33
+    _buildOverlayContent() {
34
+        return `
35
+            <span data-i18n='dialog.conferenceReloadTitle' 
36
+                  class='reload_overlay_title'></span>
37
+            <span data-i18n='dialog.conferenceReloadMsg' 
38
+                  class='reload_overlay_msg'></span>
39
+            <div>
40
+                <div id='reloadProgressBar' class="aui-progress-indicator">
41
+                    <span class="aui-progress-indicator-value"></span>
42
+                </div>
43
+                <span id='reloadSecRemaining' class='reload_overlay_msg'>
44
+                </span>
45
+            </div>`;
46
+    }
47
+
48
+    /**
49
+     * Updates the progress indicator position and the label with the time left.
50
+     */
51
+    updateDisplay() {
52
+
53
+        const timeLeftTxt
54
+            = APP.translation.translateString(
55
+                "dialog.conferenceReloadTimeLeft",
56
+                { seconds: this.timeLeft });
57
+        $("#reloadSecRemaining").text(timeLeftTxt);
58
+
59
+        const ratio = (this.timeout - this.timeLeft) / this.timeout;
60
+        AJS.progressBars.update("#reloadProgressBar", ratio);
61
+    }
62
+
63
+    /**
64
+     * Starts the reload countdown with the animation.
65
+     * @override
66
+     */
67
+    _onShow() {
68
+
69
+        // Initialize displays
70
+        this.updateDisplay();
71
+
72
+        var intervalId = window.setInterval(function() {
73
+
74
+            if (this.timeLeft >= 1) {
75
+                this.timeLeft -= 1;
76
+            }
77
+
78
+            this.updateDisplay();
79
+
80
+            if (this.timeLeft === 0) {
81
+                window.clearInterval(intervalId);
82
+                APP.ConferenceUrl.reload();
83
+            }
84
+        }.bind(this), 1000);
85
+
86
+        console.info(
87
+            "The conference will be reloaded after "
88
+                + this.timeLeft + " seconds.");
89
+    }
90
+}
91
+
92
+/**
93
+ * Holds the page reload overlay instance.
94
+ *
95
+ * {@type PageReloadOverlayImpl}
96
+ */
97
+let overlay;
98
+
99
+export default {
100
+    /**
101
+     * Checks whether the page reload overlay has been displayed.
102
+     * @return {boolean} <tt>true</tt> if the page reload overlay is currently
103
+     * visible or <tt>false</tt> otherwise.
104
+     */
105
+    isVisible() {
106
+        return overlay && overlay.isVisible();
107
+    },
108
+    /**
109
+     * Shows the page reload overlay which will do the conference reload after
110
+     * the given amount of time.
111
+     *
112
+     * @param {number} timeoutSeconds how many seconds before the conference
113
+     * reload will happen.
114
+     */
115
+    show(timeoutSeconds) {
116
+
117
+        if (!overlay) {
118
+            overlay = new PageReloadOverlayImpl(timeoutSeconds);
119
+        }
120
+        overlay.show();
121
+    }
122
+};

+ 4
- 3
modules/UI/toolbars/ToolbarToggler.js View File

@@ -34,9 +34,10 @@ function hideToolbar(force) { // eslint-disable-line no-unused-vars
34 34
     clearTimeout(toolbarTimeoutObject);
35 35
     toolbarTimeoutObject = null;
36 36
 
37
-    if (Toolbar.isHovered()
38
-            || APP.UI.isRingOverlayVisible()
39
-            || SideContainerToggler.isVisible()) {
37
+    if (force !== true &&
38
+            (Toolbar.isHovered()
39
+                || APP.UI.isRingOverlayVisible()
40
+                || SideContainerToggler.isVisible())) {
40 41
         toolbarTimeoutObject = setTimeout(hideToolbar, toolbarTimeout);
41 42
     } else {
42 43
         Toolbar.hide();

+ 1
- 1
modules/UI/util/MessageHandler.js View File

@@ -333,7 +333,7 @@ var messageHandler = {
333 333
                      messageArguments, options) {
334 334
 
335 335
         // If we're in ringing state we skip all toaster notifications.
336
-        if(!notificationsEnabled || APP.UI.isRingOverlayVisible())
336
+        if(!notificationsEnabled || APP.UI.isOverlayVisible())
337 337
             return;
338 338
 
339 339
         var displayNameSpan = '<span class="nickname" ';

+ 73
- 0
modules/URL/ConferenceUrl.js View File

@@ -0,0 +1,73 @@
1
+/* global console */
2
+
3
+import { redirect } from '../util/helpers';
4
+
5
+/**
6
+ * The modules stores information about the URL used to start the conference and
7
+ * provides utility methods for dealing with conference URL and reloads.
8
+ */
9
+export default class ConferenceUrl {
10
+    /**
11
+     * Initializes the module.
12
+     *
13
+     * @param location an object which stores provides the info about conference
14
+     * URL(would be 'window.location' for the Web app). The params below are
15
+     * described based on the following example URL:
16
+     *
17
+     * https://example.com:8888/SomeConference1245?opt=1#somehash
18
+     *
19
+     * @param location.href full URL with all parameters, would be the whole URL
20
+     * from the example string above.
21
+     *
22
+     * @param location.host the host part of the URL, 'example.com' from
23
+     * the sample URL above.
24
+     *
25
+     * @param location.pathname the path part of the URL, would be
26
+     * '/SomeConference1245' from the example above.
27
+     *
28
+     * @param location.protocol the protocol part of the URL, would be 'https:'
29
+     * from the sample URL.
30
+     */
31
+    constructor(location) {
32
+        /**
33
+         * Stores the original conference room URL with all parameters.
34
+         * Example:
35
+         * https://example.com:8888/SomeConference1245?jwt=a5sbc2#blablahash
36
+         * @type {string}
37
+         */
38
+        this.originalURL = location.href;
39
+        /**
40
+         * A simplified version of the conference URL stripped out of
41
+         * the parameters which should be used for sending invites.
42
+         * Example:
43
+         * https://example.com:8888/SomeConference1245
44
+         * @type {string}
45
+         */
46
+        this.inviteURL
47
+            = location.protocol + "//" + location.host + location.pathname;
48
+        console.info("Stored original conference URL: " + this.originalURL);
49
+        console.info("Conference URL for invites: " + this.inviteURL);
50
+    }
51
+    /**
52
+     * Obtains the conference invite URL.
53
+     * @return {string} the URL pointing o the conference which is mean to be
54
+     * used to invite new participants.
55
+     */
56
+    getInviteUrl() {
57
+        return this.inviteURL;
58
+    }
59
+    /**
60
+     * Obtains full conference URL with all original parameters.
61
+     * @return {string} the original URL used to open the current conference.
62
+     */
63
+    getOriginalUrl() {
64
+        return this.originalURL;
65
+    }
66
+    /**
67
+     * Reloads the conference using original URL with all of the parameters.
68
+     */
69
+    reload() {
70
+        console.info("Reloading the conference using URL: " + this.originalURL);
71
+        redirect(this.originalURL);
72
+    }
73
+}

+ 9
- 0
modules/util/helpers.js View File

@@ -20,6 +20,15 @@ export function reload () {
20 20
     window.location.reload();
21 21
 }
22 22
 
23
+/**
24
+ * Redirects to new URL.
25
+ * @param {string} url the URL pointing to the location where the user should
26
+ * be redirected to.
27
+ */
28
+export function redirect (url) {
29
+    window.location.replace(url);
30
+}
31
+
23 32
 /**
24 33
  * Prints the error and reports it to the global error handler.
25 34
  * @param e {Error} the error

+ 0
- 5
service/UI/UIEvents.js View File

@@ -145,11 +145,6 @@ export default {
145 145
      */
146 146
     DISPLAY_NAME_CHANGED: "UI.display_name_changed",
147 147
 
148
-    /**
149
-     * Indicates that the invite url has been initialised.
150
-     */
151
-    INVITE_URL_INITIALISED: "UI.invite_url_initialised",
152
-
153 148
     /**
154 149
      * Indicates that a password is required for the call.
155 150
      */

Loading…
Cancel
Save