diff --git a/html5/verto/js/src/jquery.verto.js b/html5/verto/js/src/jquery.verto.js index ee88a8f507..640cecca06 100644 --- a/html5/verto/js/src/jquery.verto.js +++ b/html5/verto/js/src/jquery.verto.js @@ -2549,7 +2549,7 @@ console.info("Audio Devices", $.verto.audioInDevices); console.info("Video Devices", $.verto.videoDevices); - runtime(); + runtime(true); }); } else { /* of course it's a totally different API CALL with different element names for the same exact thing */ @@ -2586,12 +2586,12 @@ console.info("Audio IN Devices", $.verto.audioInDevices); console.info("Audio Out Devices", $.verto.audioOutDevices); console.info("Video Devices", $.verto.videoDevices); - runtime(); + runtime(true); }) .catch(function(err) { console.log(" Device Enumeration ERROR: " + err.name + ": " + err.message); - runtime(); + runtime(false); }); } @@ -2601,9 +2601,16 @@ checkDevices(runtime); } - $.verto.init = function(obj, runtime) { - $.FSRTC.checkPerms(function() { + $.verto.init = function(obj, runtime, check) { + if(check == undefined) { + check = true; + } + $.FSRTC.checkPerms(function(status) { + if(check) { checkDevices(runtime); + } else { + runtime(status); + } }, true, true); } diff --git a/html5/verto/verto_communicator/src/css/verto.css b/html5/verto/verto_communicator/src/css/verto.css index df7efea2f7..4f383700d2 100644 --- a/html5/verto/verto_communicator/src/css/verto.css +++ b/html5/verto/verto_communicator/src/css/verto.css @@ -223,6 +223,29 @@ button.btn i { } } +/* --- Splash Screen --- */ +.splash-errors { + background: rgba(249, 21, 21, 0.55); + color: white; + padding: 8px; + margin-top: 11px; +} + +.splash-errors ul { + padding-start: 0em; + -moz-padding-start: 0em; + -webkit-padding-start: 0em; + padding-start: 0em; +} + +.splash-errors li { + background-color: rgba(154, 36, 36, 0.28); + padding: 8px; + font-weight: bold; + list-style: none; +} +/* --- End of Splash Screen --- */ + /* --- Modal settings page --- */ diff --git a/html5/verto/verto_communicator/src/index.html b/html5/verto/verto_communicator/src/index.html index 5945f72fe5..79c6a9cc8b 100644 --- a/html5/verto/verto_communicator/src/index.html +++ b/html5/verto/verto_communicator/src/index.html @@ -98,6 +98,7 @@ + @@ -118,10 +119,12 @@ + + diff --git a/html5/verto/verto_communicator/src/partials/splash_screen.html b/html5/verto/verto_communicator/src/partials/splash_screen.html new file mode 100644 index 0000000000..993999ec3a --- /dev/null +++ b/html5/verto/verto_communicator/src/partials/splash_screen.html @@ -0,0 +1,21 @@ +
+
+
+
+

Loading

+
+
+
+
+ +
+

Errors

+
    +
  • {{ ::error }}
  • +
+
+
+
+
+
+ diff --git a/html5/verto/verto_communicator/src/storageService/services/splash_screen.js b/html5/verto/verto_communicator/src/storageService/services/splash_screen.js new file mode 100644 index 0000000000..917becfbcf --- /dev/null +++ b/html5/verto/verto_communicator/src/storageService/services/splash_screen.js @@ -0,0 +1,234 @@ +'use strict'; + + angular + .module('storageService') + .service('splashscreen', ['$rootScope', '$q', 'storage', 'config', 'verto', + function($rootScope, $q, storage, config, verto) { + + var checkBrowser = function() { + return $q(function(resolve, reject) { + var activity = 'browser-upgrade'; + var result = { + 'activity': activity, + 'soft': false, + 'status': 'success', + 'message': 'Checking browser compability.' + }; + + navigator.getUserMedia = navigator.getUserMedia || + navigator.webkitGetUserMedia || + navigator.mozGetUserMedia; + + if (!navigator.getUserMedia) { + result['status'] = 'error'; + result['message'] = 'Error: browser doesn\'t support WebRTC.'; + reject(result); + } + + resolve(result); + + }); + }; + + var checkMediaPerm = function() { + return $q(function(resolve, reject) { + var activity = 'media-perm'; + var result = { + 'activity': activity, + 'soft': false, + 'status': 'success', + 'message': 'Checking media permissions' + }; + + verto.mediaPerm(function(status) { + if(!status) { + result['status'] = 'error'; + result['message'] = 'Error: Media Permission Denied'; + verto.data.mediaPerm = false; + reject(result); + } + verto.data.mediaPerm = true; + resolve(result); + }); + }); + }; + + var refreshMediaDevices = function() { + return $q(function(resolve, reject) { + var activity = 'refresh-devices'; + var result = { + 'status': 'success', + 'soft': true, + 'activity': activity, + 'message': 'Refresh Media Devices.' + }; + + verto.refreshDevices(function(status) { + verto.refreshDevicesCallback(function() { + resolve(result); + }); + }); + + }); + }; + + var provisionConfig = function() { + return $q(function(resolve, reject) { + var activity = 'provision-config'; + var result = { + 'status': 'promise', + 'soft': true, + 'activity': activity, + 'message': 'Provisioning configuration.' + }; + + var configResponse = config.configure(); + + var configPromise = configResponse.then( + function(response) { + /** + * from angular docs: + * A response status code between 200 and 299 is considered a success status and will result in the success callback being called + */ + if(response.status >= 200 && response.status <= 299) { + return result; + } else { + result['status'] = 'error'; + result['message'] = 'Error: Provision failed.'; + return result; + } + }); + + result['promise'] = configPromise; + + resolve(result); + }); + }; + + var checkLogin = function() { + return $q(function(resolve, reject) { + var activity = 'check-login'; + var result = { + 'status': 'success', + 'soft': true, + 'activity': activity, + 'message': 'Checking login.' + }; + + if(verto.data.connecting || verto.data.connected) { + resolve(result); + }; + + var checkUserStored = function() { + /** + * if user data saved, use stored data for logon and not connecting + * not connecting prevent two connects + */ + if (storage.data.ui_connected && storage.data.ws_connected && !verto.data.connecting) { + verto.data.name = storage.data.name; + verto.data.email = storage.data.email; + verto.data.login = storage.data.login; + verto.data.password = storage.data.password; + + verto.data.connecting = true; + verto.connect(function(v, connected) { + verto.data.connecting = false; + resolve(result); + }); + }; + }; + + if(storage.data.ui_connected && storage.data.ws_connected) { + checkUserStored(); + } else { + resolve(result); + }; + }); + }; + + var progress = [ + checkBrowser, + checkMediaPerm, + refreshMediaDevices, + provisionConfig, + checkLogin + ]; + + var progress_message = [ + 'Checking browser compability.', + 'Checking media permissions', + 'Refresh Media Devices.', + 'Provisioning configuration.', + 'Checking login.' + ]; + + var getProgressMessage = function(current_progress) { + if(progress_message[current_progress] != undefined) { + return progress_message[current_progress]; + } else { + return 'Please wait...'; + } + }; + + var current_progress = -1; + var progress_percentage = 0; + + var calculateProgress = function(index) { + var _progress; + + _progress = index + 1; + progress_percentage = (_progress / progress.length) * 100; + return progress_percentage; + }; + + var nextProgress = function() { + var fn, fn_return, status, interrupt, activity, soft, message, promise; + interrupt = false; + current_progress++; + + if(current_progress >= progress.length) { + $rootScope.$emit('progress.complete', current_progress); + return; + } + + fn = progress[current_progress]; + fn_return = fn(); + + var emitNextProgress = function(fn_return) { + if(fn_return['promise'] != undefined) { + promise = fn_return['promise']; + } + + status = fn_return['status']; + soft = fn_return['soft']; + activity = fn_return['activity']; + message = fn_return['message']; + + if(status != 'success') { + interrupt = true; + } + + $rootScope.$emit('progress.next', current_progress, status, promise, activity, soft, interrupt, message); + + }; + + fn_return.then( + function(fn_return) { + emitNextProgress(fn_return); + }, + function(fn_return) { + emitNextProgress(fn_return); + } + ); + + }; + + return { + 'next': nextProgress, + 'getProgressMessage': getProgressMessage, + 'progress_percentage': progress_percentage, + 'calculate': calculateProgress + }; + + }]); + diff --git a/html5/verto/verto_communicator/src/vertoApp/vertoApp.module.js b/html5/verto/verto_communicator/src/vertoApp/vertoApp.module.js index 2c7cffc381..351dee8733 100644 --- a/html5/verto/verto_communicator/src/vertoApp/vertoApp.module.js +++ b/html5/verto/verto_communicator/src/vertoApp/vertoApp.module.js @@ -19,6 +19,11 @@ vertoApp.config(['$routeProvider', 'gravatarServiceProvider', function($routeProvider, gravatarServiceProvider) { $routeProvider. + when('/', { + title: 'Loading', + templateUrl: 'partials/splash_screen.html', + controller: 'SplashScreenController' + }). when('/login', { title: 'Login', templateUrl: 'partials/login.html', @@ -40,7 +45,7 @@ controller: 'BrowserUpgradeController' }). otherwise({ - redirectTo: '/login' + redirectTo: '/' }); gravatarServiceProvider.defaults = { @@ -61,17 +66,7 @@ $rootScope.safeProtocol = true; } - $rootScope.checkBrowser = function() { - navigator.getUserMedia = navigator.getUserMedia || - navigator.webkitGetUserMedia || - navigator.mozGetUserMedia; - - if (!navigator.getUserMedia) { - $location.path('/browser-upgrade'); - } - - }; - + $rootScope.promptInput = function(title, message, label, callback) { var ret = prompt({ title: title, diff --git a/html5/verto/verto_communicator/src/vertoControllers/controllers/DialPadController.js b/html5/verto/verto_communicator/src/vertoControllers/controllers/DialPadController.js index 8c7589c93d..2cc4c98312 100644 --- a/html5/verto/verto_communicator/src/vertoControllers/controllers/DialPadController.js +++ b/html5/verto/verto_communicator/src/vertoControllers/controllers/DialPadController.js @@ -7,7 +7,6 @@ '$http', '$location', 'toastr', 'verto', 'storage', 'CallHistory', function($rootScope, $scope, $http, $location, toastr, verto, storage, CallHistory) { console.debug('Executing DialPadController.'); - $scope.checkBrowser(); $scope.call_history = CallHistory.all(); $scope.history_control = CallHistory.all_control(); $scope.has_history = Object.keys($scope.call_history).length; diff --git a/html5/verto/verto_communicator/src/vertoControllers/controllers/InCallController.js b/html5/verto/verto_communicator/src/vertoControllers/controllers/InCallController.js index 47eb987a28..84d8894b28 100644 --- a/html5/verto/verto_communicator/src/vertoControllers/controllers/InCallController.js +++ b/html5/verto/verto_communicator/src/vertoControllers/controllers/InCallController.js @@ -10,7 +10,6 @@ console.debug('Executing InCallController.'); $scope.layout = null; - $scope.checkBrowser(); $rootScope.dialpadNumber = ''; $scope.callTemplate = 'partials/phone_call.html'; $scope.dialpadTemplate = ''; diff --git a/html5/verto/verto_communicator/src/vertoControllers/controllers/LoginController.js b/html5/verto/verto_communicator/src/vertoControllers/controllers/LoginController.js index c9f3e5b74e..3dda64de89 100644 --- a/html5/verto/verto_communicator/src/vertoControllers/controllers/LoginController.js +++ b/html5/verto/verto_communicator/src/vertoControllers/controllers/LoginController.js @@ -12,7 +12,6 @@ } preRoute(); - verto.data.name = $scope.storage.data.name; verto.data.email = $scope.storage.data.email; diff --git a/html5/verto/verto_communicator/src/vertoControllers/controllers/MainController.js b/html5/verto/verto_communicator/src/vertoControllers/controllers/MainController.js index 0363d91f27..ac7fde0f7e 100644 --- a/html5/verto/verto_communicator/src/vertoControllers/controllers/MainController.js +++ b/html5/verto/verto_communicator/src/vertoControllers/controllers/MainController.js @@ -24,33 +24,16 @@ * @type {string} */ $rootScope.dialpadNumber = ''; - - - /** - * if user data saved, use stored data for logon - */ - if (storage.data.ui_connected && storage.data.ws_connected) { - $scope.verto.data.name = storage.data.name; - $scope.verto.data.email = storage.data.email; - $scope.verto.data.login = storage.data.login; - $scope.verto.data.password = storage.data.password; - - verto.connect(function(v, connected) { - $scope.$apply(function() { - if (connected) { - toastr.success('Nice to see you again.', 'Welcome back'); - $location.path('/dialpad'); - } - }); - }); - - } - + // If verto is not connected, redirects to login page. if (!verto.data.connected) { console.debug('MainController: WebSocket not connected. Redirecting to login.'); - $location.path('/login'); + $location.path('/'); } + + $rootScope.$on('config.http.success', function(ev) { + $scope.login(); + }); /** * Login the user to verto server and @@ -59,23 +42,20 @@ $scope.login = function() { var connectCallback = function(v, connected) { $scope.$apply(function() { - if (connected) { - storage.data.ui_connected = verto.data.connected; - storage.data.ws_connected = verto.data.connected; - storage.data.name = verto.data.name; - storage.data.email = verto.data.email; - storage.data.login = verto.data.login; - storage.data.password = verto.data.password; - - console.debug('Redirecting to dialpad page.'); - toastr.success('Login successful.', 'Welcome'); - $location.path('/dialpad'); - } else { - toastr.error('There was an error while trying to login. Please try again.', 'Error'); - } + verto.data.connecting = false; + if (connected) { + storage.data.ui_connected = verto.data.connected; + storage.data.ws_connected = verto.data.connected; + storage.data.name = verto.data.name; + storage.data.email = verto.data.email; + storage.data.login = verto.data.login; + storage.data.password = verto.data.password; + $location.path('/dialpad'); + } }); }; - + + verto.data.connecting = true; verto.connect(connectCallback); }; diff --git a/html5/verto/verto_communicator/src/vertoControllers/controllers/SplashScreenController.js b/html5/verto/verto_communicator/src/vertoControllers/controllers/SplashScreenController.js new file mode 100644 index 0000000000..a26ead6be2 --- /dev/null +++ b/html5/verto/verto_communicator/src/vertoControllers/controllers/SplashScreenController.js @@ -0,0 +1,87 @@ +(function() { + 'use strict'; + + angular + .module('vertoControllers') + .controller('SplashScreenController', ['$scope', '$rootScope', '$location', '$timeout', 'splashscreen', 'prompt', 'verto', + function($scope, $rootScope, $location, $timeout, splashscreen, prompt, verto) { + console.debug('Executing SplashScreenController.'); + + $scope.progress_percentage = splashscreen.progress_percentage; + $scope.message = ''; + $scope.interrupt_next = false; + $scope.errors = []; + + var redirectTo = function(link, activity) { + if(activity) { + if(activity == 'browser-upgrade') { + link = activity; + } + } + + $location.path(link); + } + + var checkProgressState = function(current_progress, status, promise, activity, soft, interrupt, message) { + $scope.progress_percentage = splashscreen.calculate(current_progress); + $scope.message = message; + + if(interrupt && status == 'error') { + $scope.errors.push(message); + if(!soft) { + redirectTo('', activity); + return; + } else { + message = message + '. Continue?'; + }; + + if(!confirm(message)) { + $scope.interrupt_next = true; + }; + }; + + if($scope.interrupt_next) { + return; + }; + + $scope.message = splashscreen.getProgressMessage(current_progress+1); + + return true; + }; + + $rootScope.$on('progress.next', function(ev, current_progress, status, promise, activity, soft, interrupt, message) { + $timeout(function() { + if(promise) { + promise.then(function(response) { + message = response['message']; + status = response['status']; + if(checkProgressState(current_progress, status, promise, activity, soft, interrupt, message)) { + splashscreen.next(); + }; + }); + + return; + } + + if(!checkProgressState(current_progress, status, promise, activity, soft, interrupt, message)) { + return; + } + + splashscreen.next(); + }, 400); + }); + + $rootScope.$on('progress.complete', function(ev, current_progress) { + $scope.message = 'Complete'; + if(verto.data.connected) { + redirectTo('/dialpad'); + } else { + redirectTo('/login'); + } + }); + + splashscreen.next(); + + }]); + +})(); diff --git a/html5/verto/verto_communicator/src/vertoControllers/vertoControllers.module.js b/html5/verto/verto_communicator/src/vertoControllers/vertoControllers.module.js index f27923b322..a20bb2cfee 100644 --- a/html5/verto/verto_communicator/src/vertoControllers/vertoControllers.module.js +++ b/html5/verto/verto_communicator/src/vertoControllers/vertoControllers.module.js @@ -2,10 +2,10 @@ 'use strict'; var vertoControllers = angular.module('vertoControllers', [ - 'ui.bootstrap', + 'ui.bootstrap', 'vertoService', 'storageService', 'ui.gravatar' ]); -})(); \ No newline at end of file +})(); diff --git a/html5/verto/verto_communicator/src/vertoService/services/configService.js b/html5/verto/verto_communicator/src/vertoService/services/configService.js new file mode 100644 index 0000000000..ee573ad23d --- /dev/null +++ b/html5/verto/verto_communicator/src/vertoService/services/configService.js @@ -0,0 +1,78 @@ +'use strict'; + +var vertoService = angular.module('vertoService'); + +vertoService.service('config', ['$rootScope', '$http', '$location', 'storage', 'verto', + function($rootScope, $http, $location, storage, verto) { + var configure = function() { + /** + * Load stored user info into verto service + */ + if(storage.data.name) { + verto.data.name = storage.data.name; + } + if(storage.data.email) { + verto.data.email = storage.data.email; + } + if(storage.data.login) { + verto.data.login = storage.data.login; + } + if(storage.data.password) { + verto.data.password = storage.data.password; + } + + /* + * Load the Configs before logging in + * with cache buster + */ + var httpRequest = $http.get(window.location.pathname + '/config.json?cachebuster=' + Math.floor((Math.random()*1000000)+1)); + + var httpReturn = httpRequest.then(function(response) { + var data = response.data; + + /* save these for later as we're about to possibly over write them */ + var name = verto.data.name; + var email = verto.data.email; + + console.debug("googlelogin: " + data.googlelogin); + if (data.googlelogin){ + verto.data.googlelogin = data.googlelogin; + } + + angular.extend(verto.data, data); + + /** + * use stored data (localStorage) for login, allow config.json to take precedence + */ + + if (name != '' && data.name == '') { + verto.data.name = name; + } + if (email != '' && data.email == '') { + verto.data.email = email; + } + if (verto.data.login == '' && verto.data.password == '' && storage.data.login != '' && storage.data.password != '') { + verto.data.login = storage.data.login; + verto.data.password = storage.data.password; + } + + if (verto.data.autologin == "true" && !verto.data.autologin_done) { + console.debug("auto login per config.json"); + verto.data.autologin_done = true; + } + + $rootScope.$emit('config.http.success', data); + return response; + }, function(response) { + $rootScope.$emit('config.http.error', response); + return response; + }); + + return httpReturn; + }; + + return { + 'configure': configure + }; + }]); + diff --git a/html5/verto/verto_communicator/src/vertoService/services/vertoService.js b/html5/verto/verto_communicator/src/vertoService/services/vertoService.js index 940ae1059d..229bc8b7fc 100644 --- a/html5/verto/verto_communicator/src/vertoService/services/vertoService.js +++ b/html5/verto/verto_communicator/src/vertoService/services/vertoService.js @@ -198,7 +198,7 @@ vertoService.service('verto', ['$rootScope', '$cookieStore', '$location', 'stora videoResolution: videoResolution, bandwidth: bandwidth, - refreshDevicesCallback : function refreshDevicesCallback() { + refreshDevicesCallback : function refreshDevicesCallback(callback) { data.videoDevices = [{ id: 'none', label: 'No Camera' @@ -278,11 +278,19 @@ vertoService.service('verto', ['$rootScope', '$cookieStore', '$location', 'stora } else { data.canVideo = true; } + + if(callback) { + callback(); + } }, refreshDevices: function(callback) { console.debug('Attempting to refresh the devices.'); - jQuery.verto.refreshDevices(this.refreshDevicesCallback); + if(callback) { + jQuery.verto.refreshDevices(callback); + } else { + jQuery.verto.refreshDevices(this.refreshDevicesCallback); + } }, /** @@ -538,7 +546,6 @@ vertoService.service('verto', ['$rootScope', '$cookieStore', '$location', 'stora function ourBootstrap() { // Checking if we have a failed connection attempt before // connecting again. - that.refreshDevicesCallback(); if (data.instance && !data.instance.rpcClient.socketReady()) { clearTimeout(data.instance.rpcClient.to); data.instance.logout(); @@ -565,8 +572,16 @@ vertoService.service('verto', ['$rootScope', '$cookieStore', '$location', 'stora }); } + + if(data.mediaPerm) { + ourBootstrap(); + } else { + $.verto.init({}, ourBootstrap, false); + } + }, - $.verto.init({}, ourBootstrap); + mediaPerm: function(callback) { + $.verto.init({}, callback, false); }, /**