Bladeren bron

Show overlay with guidance for gUM permission prompts

j8
tsareg 9 jaren geleden
bovenliggende
commit
9d3b2aee02
5 gewijzigde bestanden met toevoegingen van 110 en 7 verwijderingen
  1. 24
    5
      conference.js
  2. 15
    0
      css/overlay.css
  3. 11
    2
      lang/main.json
  4. 15
    0
      modules/UI/UI.js
  5. 45
    0
      modules/UI/gum_overlay/UserMediaPermissionsGuidanceOverlay.js

+ 24
- 5
conference.js Bestand weergeven

@@ -27,6 +27,8 @@ let room, connection, localAudio, localVideo, roomLocker;
27 27
 
28 28
 import {VIDEO_CONTAINER_TYPE} from "./modules/UI/videolayout/LargeVideo";
29 29
 
30
+const USER_MEDIA_PERMISSIONS_GUIDANCE_OVERLAY_TIMEOUT = 500;
31
+
30 32
 /**
31 33
  * Known custom conference commands.
32 34
  */
@@ -427,25 +429,42 @@ export default {
427 429
             };
428 430
         }
429 431
 
430
-        let audioAndVideoError, audioOnlyError;
432
+        let audioAndVideoError,
433
+            audioOnlyError,
434
+            tracksCreated;
431 435
 
432 436
         return JitsiMeetJS.init(config).then(() => {
433
-            return Promise.all([
437
+            let tryCreateLocalTracks =
434 438
                 // try to retrieve audio and video
435 439
                 createLocalTracks(['audio', 'video'])
436
-                // if failed then try to retrieve only audio
440
+                    // if failed then try to retrieve only audio
437 441
                     .catch(err => {
438 442
                         audioAndVideoError = err;
439 443
                         return createLocalTracks(['audio']);
440 444
                     })
441
-                // if audio also failed then just return empty array
445
+                    // if audio also failed then just return empty array
442 446
                     .catch(err => {
443 447
                         audioOnlyError = err;
444 448
                         return [];
445
-                    }),
449
+                    })
450
+                    .then(tracks => {
451
+                        tracksCreated = true;
452
+                        return tracks;
453
+                    });
454
+
455
+            window.setTimeout(() => {
456
+                if (!audioAndVideoError && !audioOnlyError && !tracksCreated) {
457
+                    APP.UI.showUserMediaPermissionsGuidanceOverlay();
458
+                }
459
+            }, USER_MEDIA_PERMISSIONS_GUIDANCE_OVERLAY_TIMEOUT);
460
+
461
+            return Promise.all([
462
+                tryCreateLocalTracks,
446 463
                 connect(options.roomName)
447 464
             ]);
448 465
         }).then(([tracks, con]) => {
466
+            APP.UI.hideUserMediaPermissionsGuidanceOverlay();
467
+
449 468
             if (audioAndVideoError) {
450 469
                 if (audioOnlyError) {
451 470
                     // If both requests for 'audio' + 'video' and 'audio' only

+ 15
- 0
css/overlay.css Bestand weergeven

@@ -11,6 +11,10 @@
11 11
     display: block;
12 12
 }
13 13
 
14
+.overlay_transparent {
15
+    background: none;
16
+}
17
+
14 18
 .overlay_container {
15 19
     width: 100%;
16 20
     height: 100%;
@@ -49,3 +53,14 @@
49 53
     margin-top: 20px;
50 54
     float: left;
51 55
 }
56
+
57
+.overlay_text_small {
58
+    font-size: 18px;
59
+}
60
+
61
+.overlay_icon {
62
+    position: relative;
63
+    z-index: 1013;
64
+    float: none;
65
+    font-size: 100px;
66
+}

+ 11
- 2
lang/main.json Bestand weergeven

@@ -11,6 +11,15 @@
11 11
     "defaultNickname": "ex. Jane Pink",
12 12
     "defaultLink": "e.g. __url__",
13 13
     "calling": "Calling __name__ ...",
14
+    "userMedia": {
15
+      "react-nativeGrantPermissions": "Please grant permissions to use your camera and microphone by pressing <i>Allow</i> button",
16
+      "chromeGrantPermissions": "Please grant permissions to use your camera and microphone by pressing <i>Allow</i> button",
17
+      "firefoxGrantPermissions": "Please grant permissions to use your camera and microphone by pressing <i>Share Selected Device</i> button",
18
+      "operaGrantPermissions": "Please grant permissions to use your camera and microphone by pressing <i>Allow</i> button",
19
+      "iexplorerGrantPermissions": "Please grant permissions to use your camera and microphone by pressing <i>OK</i> button",
20
+      "safariGrantPermissions": "Please grant permissions to use your camera and microphone by pressing <i>OK</i> button",
21
+      "nwjsGrantPermissions": "Please grant permissions to use your camera and microphone"
22
+    },
14 23
     "keyboardShortcuts": {
15 24
         "keyboardShortcuts": "Keyboard shortcuts:",
16 25
         "raiseHand": "Raise your hand.",
@@ -245,11 +254,11 @@
245 254
         "cameraErrorPresent": "There was an error connecting to your camera.",
246 255
         "cameraUnsupportedResolutionError": "Your camera does not support required video resolution.",
247 256
         "cameraUnknownError": "Cannot use camera for a unknown reason.",
248
-        "cameraPermissionDeniedError": "You have not granted permission to use your camera.",
257
+        "cameraPermissionDeniedError": "You have not granted permission to use your camera. You can still join the conference but others won't see you. Use the camera button in the address bar to fix this.",
249 258
         "cameraNotFoundError": "Requested camera was not found.",
250 259
         "cameraConstraintFailedError": "Yor camera does not satisfy some of required constraints.",
251 260
         "micUnknownError": "Cannot use microphone for a unknown reason.",
252
-        "micPermissionDeniedError": "You have not granted permission to use your microphone.",
261
+        "micPermissionDeniedError": "You have not granted permission to use your microphone. You can still join the conference but others won't hear you. Use the camera button in the address bar to fix this.",
253 262
         "micNotFoundError": "Requested microphone was not found.",
254 263
         "micConstraintFailedError": "Yor microphone does not satisfy some of required constraints."
255 264
     },

+ 15
- 0
modules/UI/UI.js Bestand weergeven

@@ -15,6 +15,7 @@ import CQEvents from '../../service/connectionquality/CQEvents';
15 15
 import EtherpadManager from './etherpad/Etherpad';
16 16
 import SharedVideoManager from './shared_video/SharedVideo';
17 17
 import Recording from "./recording/Recording";
18
+import GumPermissionsOverlay from './gum_overlay/UserMediaPermissionsGuidanceOverlay';
18 19
 
19 20
 import VideoLayout from "./videolayout/VideoLayout";
20 21
 import FilmStrip from "./videolayout/FilmStrip";
@@ -1385,6 +1386,20 @@ UI.hideRingOverLay = function () {
1385 1386
     FilmStrip.toggleFilmStrip(true);
1386 1387
 };
1387 1388
 
1389
+/**
1390
+ * Shows browser-specific overlay with guidance how to proceed with gUM prompt.
1391
+ */
1392
+UI.showUserMediaPermissionsGuidanceOverlay = function () {
1393
+    GumPermissionsOverlay.show();
1394
+};
1395
+
1396
+/**
1397
+ * Hides browser-specific overlay with guidance how to proceed with gUM prompt.
1398
+ */
1399
+UI.hideUserMediaPermissionsGuidanceOverlay = function () {
1400
+    GumPermissionsOverlay.hide();
1401
+};
1402
+
1388 1403
 /**
1389 1404
  * Shows or hides the keyboard shortcuts panel.'
1390 1405
  */

+ 45
- 0
modules/UI/gum_overlay/UserMediaPermissionsGuidanceOverlay.js Bestand weergeven

@@ -0,0 +1,45 @@
1
+/* global $, APP, JitsiMeetJS */
2
+
3
+let $overlay;
4
+
5
+/**
6
+ * Internal function that constructs overlay with guidance how to proceed with
7
+ * gUM prompt.
8
+ */
9
+function buildOverlayHtml() {
10
+    let browser = JitsiMeetJS.environment.getBrowserType()
11
+            .split('rtc_browser.')[1] || 'chrome';
12
+
13
+    $overlay = $(`
14
+        <div class='overlay_container'>
15
+            <div class='overlay overlay_transparent' />
16
+            <div class='overlay_content'>
17
+                <span class="overlay_icon icon-microphone"></span>
18
+                <span class="overlay_icon icon-camera"></span>
19
+                <span data-i18n='[html]userMedia.${browser}GrantPermissions' 
20
+                    class='overlay_text overlay_text_small'></span>
21
+            </div>
22
+        </div>`);
23
+
24
+    APP.translation.translateElement($overlay);
25
+}
26
+
27
+export default {
28
+    /**
29
+     * Shows browser-specific overlay with guidance how to proceed with
30
+     * gUM prompt.
31
+     */
32
+    show() {
33
+        !$overlay && buildOverlayHtml();
34
+
35
+        $overlay && $overlay.appendTo('body');
36
+    },
37
+
38
+    /**
39
+     * Hides browser-specific overlay with guidance how to proceed with
40
+     * gUM prompt.
41
+     */
42
+    hide() {
43
+        $overlay && $overlay.detach();
44
+    }
45
+};

Laden…
Annuleren
Opslaan