Show overlay with guidance for gUM permission prompts

This commit is contained in:
tsareg 2016-06-21 12:08:32 +03:00
parent 72d38ad202
commit 9d3b2aee02
5 changed files with 110 additions and 7 deletions

View File

@ -27,6 +27,8 @@ let room, connection, localAudio, localVideo, roomLocker;
import {VIDEO_CONTAINER_TYPE} from "./modules/UI/videolayout/LargeVideo"; import {VIDEO_CONTAINER_TYPE} from "./modules/UI/videolayout/LargeVideo";
const USER_MEDIA_PERMISSIONS_GUIDANCE_OVERLAY_TIMEOUT = 500;
/** /**
* Known custom conference commands. * Known custom conference commands.
*/ */
@ -427,10 +429,12 @@ export default {
}; };
} }
let audioAndVideoError, audioOnlyError; let audioAndVideoError,
audioOnlyError,
tracksCreated;
return JitsiMeetJS.init(config).then(() => { return JitsiMeetJS.init(config).then(() => {
return Promise.all([ let tryCreateLocalTracks =
// try to retrieve audio and video // try to retrieve audio and video
createLocalTracks(['audio', 'video']) createLocalTracks(['audio', 'video'])
// if failed then try to retrieve only audio // if failed then try to retrieve only audio
@ -442,10 +446,25 @@ export default {
.catch(err => { .catch(err => {
audioOnlyError = err; audioOnlyError = err;
return []; return [];
}), })
.then(tracks => {
tracksCreated = true;
return tracks;
});
window.setTimeout(() => {
if (!audioAndVideoError && !audioOnlyError && !tracksCreated) {
APP.UI.showUserMediaPermissionsGuidanceOverlay();
}
}, USER_MEDIA_PERMISSIONS_GUIDANCE_OVERLAY_TIMEOUT);
return Promise.all([
tryCreateLocalTracks,
connect(options.roomName) connect(options.roomName)
]); ]);
}).then(([tracks, con]) => { }).then(([tracks, con]) => {
APP.UI.hideUserMediaPermissionsGuidanceOverlay();
if (audioAndVideoError) { if (audioAndVideoError) {
if (audioOnlyError) { if (audioOnlyError) {
// If both requests for 'audio' + 'video' and 'audio' only // If both requests for 'audio' + 'video' and 'audio' only

View File

@ -11,6 +11,10 @@
display: block; display: block;
} }
.overlay_transparent {
background: none;
}
.overlay_container { .overlay_container {
width: 100%; width: 100%;
height: 100%; height: 100%;
@ -49,3 +53,14 @@
margin-top: 20px; margin-top: 20px;
float: left; float: left;
} }
.overlay_text_small {
font-size: 18px;
}
.overlay_icon {
position: relative;
z-index: 1013;
float: none;
font-size: 100px;
}

View File

@ -11,6 +11,15 @@
"defaultNickname": "ex. Jane Pink", "defaultNickname": "ex. Jane Pink",
"defaultLink": "e.g. __url__", "defaultLink": "e.g. __url__",
"calling": "Calling __name__ ...", "calling": "Calling __name__ ...",
"userMedia": {
"react-nativeGrantPermissions": "Please grant permissions to use your camera and microphone by pressing <i>Allow</i> button",
"chromeGrantPermissions": "Please grant permissions to use your camera and microphone by pressing <i>Allow</i> button",
"firefoxGrantPermissions": "Please grant permissions to use your camera and microphone by pressing <i>Share Selected Device</i> button",
"operaGrantPermissions": "Please grant permissions to use your camera and microphone by pressing <i>Allow</i> button",
"iexplorerGrantPermissions": "Please grant permissions to use your camera and microphone by pressing <i>OK</i> button",
"safariGrantPermissions": "Please grant permissions to use your camera and microphone by pressing <i>OK</i> button",
"nwjsGrantPermissions": "Please grant permissions to use your camera and microphone"
},
"keyboardShortcuts": { "keyboardShortcuts": {
"keyboardShortcuts": "Keyboard shortcuts:", "keyboardShortcuts": "Keyboard shortcuts:",
"raiseHand": "Raise your hand.", "raiseHand": "Raise your hand.",
@ -245,11 +254,11 @@
"cameraErrorPresent": "There was an error connecting to your camera.", "cameraErrorPresent": "There was an error connecting to your camera.",
"cameraUnsupportedResolutionError": "Your camera does not support required video resolution.", "cameraUnsupportedResolutionError": "Your camera does not support required video resolution.",
"cameraUnknownError": "Cannot use camera for a unknown reason.", "cameraUnknownError": "Cannot use camera for a unknown reason.",
"cameraPermissionDeniedError": "You have not granted permission to use your camera.", "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.",
"cameraNotFoundError": "Requested camera was not found.", "cameraNotFoundError": "Requested camera was not found.",
"cameraConstraintFailedError": "Yor camera does not satisfy some of required constraints.", "cameraConstraintFailedError": "Yor camera does not satisfy some of required constraints.",
"micUnknownError": "Cannot use microphone for a unknown reason.", "micUnknownError": "Cannot use microphone for a unknown reason.",
"micPermissionDeniedError": "You have not granted permission to use your microphone.", "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.",
"micNotFoundError": "Requested microphone was not found.", "micNotFoundError": "Requested microphone was not found.",
"micConstraintFailedError": "Yor microphone does not satisfy some of required constraints." "micConstraintFailedError": "Yor microphone does not satisfy some of required constraints."
}, },

View File

@ -15,6 +15,7 @@ import CQEvents from '../../service/connectionquality/CQEvents';
import EtherpadManager from './etherpad/Etherpad'; import EtherpadManager from './etherpad/Etherpad';
import SharedVideoManager from './shared_video/SharedVideo'; import SharedVideoManager from './shared_video/SharedVideo';
import Recording from "./recording/Recording"; import Recording from "./recording/Recording";
import GumPermissionsOverlay from './gum_overlay/UserMediaPermissionsGuidanceOverlay';
import VideoLayout from "./videolayout/VideoLayout"; import VideoLayout from "./videolayout/VideoLayout";
import FilmStrip from "./videolayout/FilmStrip"; import FilmStrip from "./videolayout/FilmStrip";
@ -1385,6 +1386,20 @@ UI.hideRingOverLay = function () {
FilmStrip.toggleFilmStrip(true); FilmStrip.toggleFilmStrip(true);
}; };
/**
* Shows browser-specific overlay with guidance how to proceed with gUM prompt.
*/
UI.showUserMediaPermissionsGuidanceOverlay = function () {
GumPermissionsOverlay.show();
};
/**
* Hides browser-specific overlay with guidance how to proceed with gUM prompt.
*/
UI.hideUserMediaPermissionsGuidanceOverlay = function () {
GumPermissionsOverlay.hide();
};
/** /**
* Shows or hides the keyboard shortcuts panel.' * Shows or hides the keyboard shortcuts panel.'
*/ */

View File

@ -0,0 +1,45 @@
/* global $, APP, JitsiMeetJS */
let $overlay;
/**
* Internal function that constructs overlay with guidance how to proceed with
* gUM prompt.
*/
function buildOverlayHtml() {
let browser = JitsiMeetJS.environment.getBrowserType()
.split('rtc_browser.')[1] || 'chrome';
$overlay = $(`
<div class='overlay_container'>
<div class='overlay overlay_transparent' />
<div class='overlay_content'>
<span class="overlay_icon icon-microphone"></span>
<span class="overlay_icon icon-camera"></span>
<span data-i18n='[html]userMedia.${browser}GrantPermissions'
class='overlay_text overlay_text_small'></span>
</div>
</div>`);
APP.translation.translateElement($overlay);
}
export default {
/**
* Shows browser-specific overlay with guidance how to proceed with
* gUM prompt.
*/
show() {
!$overlay && buildOverlayHtml();
$overlay && $overlay.appendTo('body');
},
/**
* Hides browser-specific overlay with guidance how to proceed with
* gUM prompt.
*/
hide() {
$overlay && $overlay.detach();
}
};