]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
FS-8205 [verto_communicator] Add splash screen feature
authorStefan Yohansson <stefan@evolux.net.br>
Thu, 24 Sep 2015 13:27:00 +0000 (10:27 -0300)
committerKen Rice <krice@freeswitch.org>
Fri, 25 Sep 2015 15:08:09 +0000 (10:08 -0500)
14 files changed:
html5/verto/js/src/jquery.verto.js
html5/verto/verto_communicator/src/css/verto.css
html5/verto/verto_communicator/src/index.html
html5/verto/verto_communicator/src/partials/splash_screen.html [new file with mode: 0644]
html5/verto/verto_communicator/src/storageService/services/splash_screen.js [new file with mode: 0644]
html5/verto/verto_communicator/src/vertoApp/vertoApp.module.js
html5/verto/verto_communicator/src/vertoControllers/controllers/DialPadController.js
html5/verto/verto_communicator/src/vertoControllers/controllers/InCallController.js
html5/verto/verto_communicator/src/vertoControllers/controllers/LoginController.js
html5/verto/verto_communicator/src/vertoControllers/controllers/MainController.js
html5/verto/verto_communicator/src/vertoControllers/controllers/SplashScreenController.js [new file with mode: 0644]
html5/verto/verto_communicator/src/vertoControllers/vertoControllers.module.js
html5/verto/verto_communicator/src/vertoService/services/configService.js [new file with mode: 0644]
html5/verto/verto_communicator/src/vertoService/services/vertoService.js

index ee88a8f5070e1b70876ddca3a31911467335ad5a..640cecca067eb7229f145e1d3d29d6f366abfb86 100644 (file)
                
                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 */
                    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);
                });
        }
 
        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);
     }
 
index df7efea2f713883581668d1dcf77eab788613d81..4f383700d23fbcf5ec51c4fbc9d550ba2ee7d821 100644 (file)
@@ -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 --- */
 
index 5945f72fe506868985f3da7f041560d40c16eff8..79c6a9cc8baa7081da48283dfadda9fd9f0c54aa 100644 (file)
@@ -98,6 +98,7 @@
     <script type="text/javascript" src="src/vertoApp/vertoApp.module.js"></script>
 
     <script type="text/javascript" src="src/vertoControllers/vertoControllers.module.js"></script>
+    <script type="text/javascript" src="src/vertoControllers/controllers/SplashScreenController.js"></script>
     <script type="text/javascript" src="src/vertoControllers/controllers/BrowserUpgradeController.js"></script>
     <script type="text/javascript" src="src/vertoControllers/controllers/ChatController.js"></script>
     <script type="text/javascript" src="src/vertoControllers/controllers/ContributorsController.js"></script>
 
     <script type="text/javascript" src="src/vertoService/vertoService.module.js"></script>
     <script type="text/javascript" src="src/vertoService/services/vertoService.js"></script>
+    <script type="text/javascript" src="src/vertoService/services/configService.js"></script>
 
     <script type="text/javascript" src="src/storageService/storageService.module.js"></script>
     <script type="text/javascript" src="src/storageService/services/storage.js"></script>
     <script type="text/javascript" src="src/storageService/services/call_history.js"></script>
+    <script type="text/javascript" src="src/storageService/services/splash_screen.js"></script>
     <!-- endbuild -->
 
 
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 (file)
index 0000000..993999e
--- /dev/null
@@ -0,0 +1,21 @@
+<div class="centered-block-frame" id="splash_screen"> 
+  <div class="col-md-6 centered-block">
+    <div class="card">
+      <div class="card-body text-center">
+       <h2>Loading</h2>
+       <div class="progress progress-striped active">
+         <div class="progress-bar" ng-class="{'progress-bar-danger': interrupt_next}" style="width: {{ progress_percentage }}%"></div>
+       </div>
+       <div ng-bind="message"></div>
+       
+       <div class="splash-errors" ng-if="errors.length">
+         <h4>Errors</h4>
+         <ul ng-repeat="error in errors">
+           <li>{{ ::error }}</li>
+         </ul>
+       </div>
+      </div>
+    </div>
+  </div>
+</div>
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 (file)
index 0000000..917becf
--- /dev/null
@@ -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
+        };
+
+      }]);
index 2c7cffc38146e6d18e0aca25f92adc92f66625b2..351dee8733bfbe1d2de8459a37e9b93b73df811e 100644 (file)
   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 = {
         $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,
index 8c7589c93de19c953979d03cf1744c8cff64ddb0..2cc4c983124fcb4efa5730b98e8eb008ed37db52 100644 (file)
@@ -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;
index 47eb987a28ab1ad4bd899425b0fd368cbfb3224b..84d8894b28a52f0a3afb2c6cfad23a67ece2fae9 100644 (file)
@@ -10,7 +10,6 @@
 
         console.debug('Executing InCallController.');
         $scope.layout = null;
-        $scope.checkBrowser();
         $rootScope.dialpadNumber = '';
         $scope.callTemplate = 'partials/phone_call.html';
         $scope.dialpadTemplate = '';
index c9f3e5b74ea639a21caf43e9b996ee9e951f323d..3dda64de89029a23e22fc9f905a00649edde4df8 100644 (file)
@@ -12,7 +12,6 @@
         }
         preRoute();
 
-
         verto.data.name = $scope.storage.data.name;
         verto.data.email = $scope.storage.data.email;
 
index 0363d91f27551eeec94ee2e631649bdbc7baed48..ac7fde0f7ebc321439b26a6fe1f031ed91314e2c 100644 (file)
        * @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
       $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 (file)
index 0000000..a26ead6
--- /dev/null
@@ -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();
+
+    }]);
+
+})();
index f27923b322dc4df942598fb46a6bd8e67a2b5cae..a20bb2cfee760c3707bd8add87bcf81e89f4902f 100644 (file)
@@ -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 (file)
index 0000000..ee573ad
--- /dev/null
@@ -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
+    };
+  }]);
+
index 940ae1059d0d4d11aa0daab1957c5e2e90574fb5..229bc8b7fc46759a8e4d9bac5f574084b517558e 100644 (file)
@@ -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);
       },
 
       /**