mirror of
https://github.com/signalwire/freeswitch.git
synced 2026-10-23 11:44:14 +00:00
Merge pull request #435 in FS/freeswitch from ~JMESQUITA/freeswitch:bugfix/FS-8045-split-files-to-make-it-more-manageable to master
* commit 'aadb1fb3ddb1bee2bcc32e39620889feeab96d3e': FS-8045 [Verto-Communicator] Make the folder structure compliant with AngularJS best practices and adjust build system.
This commit is contained in:
commit
8eaca2afef
71 files changed
+1337
-1248
No files matched your search
@@ -1,18 +1,62 @@
|
||||
{
|
||||
"bitwise": true,
|
||||
"browser": true,
|
||||
"curly": true,
|
||||
"eqeqeq": true,
|
||||
"esnext": true,
|
||||
"latedef": true,
|
||||
"noarg": true,
|
||||
"node": true,
|
||||
"strict": true,
|
||||
"undef": true,
|
||||
"unused": true,
|
||||
"globals": {
|
||||
"angular": false,
|
||||
"jQuery": false,
|
||||
"$": false
|
||||
}
|
||||
"bitwise": true,
|
||||
"camelcase": true,
|
||||
"curly": true,
|
||||
"eqeqeq": true,
|
||||
"es3": false,
|
||||
"forin": true,
|
||||
"freeze": true,
|
||||
"immed": true,
|
||||
"indent": 4,
|
||||
"latedef": "nofunc",
|
||||
"newcap": true,
|
||||
"noarg": true,
|
||||
"noempty": true,
|
||||
"nonbsp": true,
|
||||
"nonew": true,
|
||||
"plusplus": false,
|
||||
"quotmark": "single",
|
||||
"undef": true,
|
||||
"unused": false,
|
||||
"strict": false,
|
||||
"maxparams": 10,
|
||||
"maxdepth": 5,
|
||||
"maxstatements": 40,
|
||||
"maxcomplexity": 8,
|
||||
"maxlen": 120,
|
||||
|
||||
"asi": false,
|
||||
"boss": false,
|
||||
"debug": false,
|
||||
"eqnull": true,
|
||||
"esnext": false,
|
||||
"evil": false,
|
||||
"expr": false,
|
||||
"funcscope": false,
|
||||
"globalstrict": false,
|
||||
"iterator": false,
|
||||
"lastsemic": false,
|
||||
"laxbreak": false,
|
||||
"laxcomma": false,
|
||||
"loopfunc": true,
|
||||
"maxerr": false,
|
||||
"moz": false,
|
||||
"multistr": false,
|
||||
"notypeof": false,
|
||||
"proto": false,
|
||||
"scripturl": false,
|
||||
"shadow": false,
|
||||
"sub": true,
|
||||
"supernew": false,
|
||||
"validthis": false,
|
||||
"noyield": false,
|
||||
|
||||
"browser": true,
|
||||
"node": true,
|
||||
|
||||
"globals": {
|
||||
"angular": false,
|
||||
"$": false,
|
||||
"jQuery": false
|
||||
}
|
||||
}
|
||||
@@ -16,7 +16,7 @@ module.exports = function (grunt) {
|
||||
|
||||
// Configurable paths
|
||||
var config = {
|
||||
app: '.',
|
||||
app: './src',
|
||||
dist: 'dist'
|
||||
};
|
||||
|
||||
@@ -33,10 +33,6 @@ module.exports = function (grunt) {
|
||||
files: ['bower.json'],
|
||||
tasks: ['wiredep']
|
||||
},
|
||||
js: {
|
||||
files: ['js/verto-service.js'],
|
||||
tasks: ['string-replace:dev']
|
||||
},
|
||||
styles: {
|
||||
files: ['<%= config.app %>/css/{,*/}*.css'],
|
||||
tasks: ['newer:copy:styles', 'postcss']
|
||||
@@ -46,25 +42,9 @@ module.exports = function (grunt) {
|
||||
}
|
||||
},
|
||||
|
||||
// Replace so we can have it properly passed from dev
|
||||
'string-replace': {
|
||||
dev: {
|
||||
files: {
|
||||
'.tmp/js/verto-service.js': '<%= config.app %>/js/verto-service.js'
|
||||
},
|
||||
options: {
|
||||
replacements: [
|
||||
{
|
||||
pattern: /window\.location\.hostname/gi,
|
||||
replacement: ip
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
wiredep: {
|
||||
app: {
|
||||
src: ['index.html'],
|
||||
src: ['src/index.html'],
|
||||
ignorePath: /\.\.\//
|
||||
}
|
||||
},
|
||||
@@ -94,24 +74,51 @@ module.exports = function (grunt) {
|
||||
notify: false,
|
||||
background: true,
|
||||
https: true,
|
||||
open: false
|
||||
open: false,
|
||||
// logLevel: "debug",
|
||||
ghostMode: false,
|
||||
logConnections: true,
|
||||
ui: false
|
||||
},
|
||||
livereload: {
|
||||
options: {
|
||||
files: [
|
||||
'<%= config.app %>/{,*/}*.html',
|
||||
'<%= config.app %>/**/*.html',
|
||||
'.tmp/styles/{,*/}*.css',
|
||||
'<%= config.app %>/images/{,*/}*',
|
||||
'.tmp/js/{,*/}*.js',
|
||||
'<%= config.app %>/js/**/*.js'
|
||||
'.tmp/**/*.js',
|
||||
'<%= config.app %>/**/*.js'
|
||||
],
|
||||
port: 9001,
|
||||
server: {
|
||||
baseDir: ['.tmp', '../js/src/', config.app],
|
||||
watchTask: true,
|
||||
baseDir: ['../js/src/', './js', '.'],
|
||||
index: 'src/index.html',
|
||||
middleware: [
|
||||
require("connect-logger")(),
|
||||
function(req, res, next) {
|
||||
if (ip) {
|
||||
var parsed = require("url").parse(req.url);
|
||||
if (!parsed.pathname.match(/vertoService\.js$/)) {
|
||||
next();
|
||||
return;
|
||||
} else {
|
||||
grunt.log.writeln('Providing replaced data.');
|
||||
var path = require('path');
|
||||
var theFilePath = path.resolve('./src', 'vertoService', 'services', 'vertoService.js');
|
||||
var f = require('fs').readFileSync(theFilePath).toString();
|
||||
res.setHeader('Content-Type', 'text/javascript');
|
||||
res.end(f.replace(/window\.location\.hostname/gi, ip));
|
||||
return;
|
||||
}
|
||||
}
|
||||
next();
|
||||
}
|
||||
],
|
||||
routes: {
|
||||
'/partials': 'src/partials',
|
||||
'/bower_components': './bower_components',
|
||||
'/js/src': '../js/src'
|
||||
'/js/src': '../js/src',
|
||||
'/js': './js'
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -137,7 +144,7 @@ module.exports = function (grunt) {
|
||||
all: {
|
||||
src: [
|
||||
'Gruntfile.js',
|
||||
'js/{,*/}*.js'
|
||||
'src/**/*.js'
|
||||
]
|
||||
}
|
||||
},
|
||||
@@ -151,8 +158,7 @@ module.exports = function (grunt) {
|
||||
'!dist/.git{,*/}*'
|
||||
]
|
||||
}]
|
||||
},
|
||||
server: '.tmp'
|
||||
}
|
||||
},
|
||||
// Renames files for browser caching purposes
|
||||
filerev: {
|
||||
@@ -184,7 +190,7 @@ module.exports = function (grunt) {
|
||||
'<%= config.dist %>/styles'
|
||||
]
|
||||
},
|
||||
html: ['<%= config.dist %>/{,*/}*.html'],
|
||||
html: ['<%= config.dist %>/**/*.html'],
|
||||
css: ['<%= config.dist %>/styles/{,*/}*.css']
|
||||
},
|
||||
|
||||
@@ -257,14 +263,15 @@ module.exports = function (grunt) {
|
||||
files: [{
|
||||
expand: true,
|
||||
dot: true,
|
||||
cwd: '',
|
||||
cwd: '<%= config.app %>',
|
||||
dest: 'dist',
|
||||
src: [
|
||||
'*.{ico,png,txt}',
|
||||
'*.html',
|
||||
'partials/**/*.html',
|
||||
'images/{,*/}*.{webp}',
|
||||
'css/fonts/{,*/}*.*'
|
||||
'css/fonts/{,*/}*.*',
|
||||
'sounds/*.*'
|
||||
]
|
||||
}, {
|
||||
expand: true,
|
||||
@@ -285,7 +292,7 @@ module.exports = function (grunt) {
|
||||
},
|
||||
styles: {
|
||||
expand: true,
|
||||
cwd: '/css',
|
||||
cwd: '<%= config.app %>/css',
|
||||
dest: '.tmp/css/',
|
||||
src: '{,*/}*.css'
|
||||
}
|
||||
@@ -304,19 +311,14 @@ module.exports = function (grunt) {
|
||||
});
|
||||
|
||||
grunt.registerTask('serve', function (target) {
|
||||
var tasks = ['clean:server',
|
||||
var tasks = [
|
||||
'wiredep',
|
||||
'concurrent:server',
|
||||
'postcss'];
|
||||
|
||||
if (ip) {
|
||||
tasks = tasks.concat(['string-replace:dev',
|
||||
'browserSync:livereload',
|
||||
'watch']);
|
||||
} else {
|
||||
tasks = tasks.concat(['browserSync:livereload',
|
||||
'watch']);
|
||||
}
|
||||
|
||||
tasks = tasks.concat(['browserSync:livereload',
|
||||
'watch']);
|
||||
|
||||
grunt.task.run(tasks);
|
||||
});
|
||||
|
||||
@@ -1,102 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
/* App Module */
|
||||
|
||||
var vertoApp = angular.module('vertoApp', [
|
||||
'timer',
|
||||
'ngRoute',
|
||||
'vertoControllers',
|
||||
'vertoDirectives',
|
||||
'vertoFilters',
|
||||
'ngStorage',
|
||||
'ngAnimate',
|
||||
'toastr',
|
||||
'FBAngular',
|
||||
'cgPrompt',
|
||||
'720kb.tooltips',
|
||||
'ui.gravatar',
|
||||
]);
|
||||
|
||||
vertoApp.config(['$routeProvider', 'gravatarServiceProvider', 'toastrConfig',
|
||||
function($routeProvider, gravatarServiceProvider, toastrConfig) {
|
||||
$routeProvider.
|
||||
when('/login', {
|
||||
title: 'Login',
|
||||
templateUrl: 'partials/login.html',
|
||||
controller: 'LoginController'
|
||||
}).
|
||||
when('/dialpad', {
|
||||
title: 'Dialpad',
|
||||
templateUrl: 'partials/dialpad.html',
|
||||
controller: 'DialPadController'
|
||||
}).
|
||||
when('/incall', {
|
||||
title: 'In a Call',
|
||||
templateUrl: 'partials/incall.html',
|
||||
controller: 'InCallController'
|
||||
}).
|
||||
/*when('/contributors', {
|
||||
title: 'Contributors',
|
||||
templateUrl: 'partials/contributors.html',
|
||||
controller: 'ContributorsController',
|
||||
}).*/
|
||||
when('/browser-upgrade', {
|
||||
title: '',
|
||||
templateUrl: 'partials/browser_upgrade.html',
|
||||
controller: 'BrowserUpgradeController'
|
||||
}).
|
||||
otherwise({
|
||||
redirectTo: '/login'
|
||||
});
|
||||
|
||||
gravatarServiceProvider.defaults = {
|
||||
default: 'mm' // Mystery man as default for missing avatars
|
||||
};
|
||||
|
||||
angular.extend(toastrConfig, {
|
||||
maxOpened: 4
|
||||
});
|
||||
}
|
||||
]);
|
||||
|
||||
vertoApp.run(['$rootScope', '$location', 'toastr', 'prompt',
|
||||
function($rootScope, $location, toastr, prompt) {
|
||||
$rootScope.$on('$routeChangeSuccess', function(event, current, previous) {
|
||||
$rootScope.title = current.$$route.title;
|
||||
});
|
||||
|
||||
$rootScope.safeProtocol = false;
|
||||
|
||||
if (window.location.protocol == 'https:') {
|
||||
$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,
|
||||
message: message,
|
||||
input: true,
|
||||
label: label
|
||||
}).then(function(ret) {
|
||||
if (angular.isFunction(callback)) {
|
||||
callback(ret);
|
||||
}
|
||||
}, function() {
|
||||
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
]);
|
||||
@@ -1,940 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
/* Controllers */
|
||||
|
||||
var vertoControllers = angular.module('vertoControllers', ['ui.bootstrap',
|
||||
'vertoService', 'storageService', 'ui.gravatar'
|
||||
]);
|
||||
|
||||
|
||||
vertoControllers.filter('gravatar',
|
||||
function() {
|
||||
return function(email, size) {
|
||||
if (angular.isUndefined(size)) {
|
||||
size = 40;
|
||||
}
|
||||
var hash = md5(email);
|
||||
return 'https://secure.gravatar.com/avatar/' + hash + '?s=' + size + '&d=mm';
|
||||
};
|
||||
});
|
||||
|
||||
|
||||
vertoControllers.controller('MainController', ['$scope', '$rootScope',
|
||||
'$location', '$modal', '$timeout', 'verto', 'storage', 'toastr',
|
||||
'Fullscreen', 'prompt',
|
||||
function($scope, $rootScope, $location, $modal,
|
||||
$timeout, verto, storage, toastr, Fullscreen, prompt) {
|
||||
console.debug('Executing MainController.');
|
||||
|
||||
var myVideo = document.getElementById("webcam");
|
||||
$scope.verto = verto;
|
||||
$scope.storage = storage;
|
||||
$scope.call_history = angular.element("#call_history").hasClass('active');
|
||||
$scope.chatStatus = angular.element('#wrapper').hasClass('toggled');
|
||||
|
||||
/**
|
||||
* (explanation) scope in another controller extends rootScope (singleton)
|
||||
*/
|
||||
$rootScope.chat_counter = 0;
|
||||
$rootScope.activePane = 'members';
|
||||
/**
|
||||
* The number that will be called.
|
||||
* @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');
|
||||
}
|
||||
|
||||
/**
|
||||
* Login the user to verto server and
|
||||
* redirects him to dialpad page.
|
||||
*/
|
||||
$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.');
|
||||
storage.changeData(verto);
|
||||
toastr.success('Login successful.', 'Welcome');
|
||||
$location.path('/dialpad');
|
||||
} else {
|
||||
toastr.error('There was an error while trying to login. Please try again.', 'Error');
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
verto.connect(connectCallback);
|
||||
};
|
||||
|
||||
/**
|
||||
* Logout the user from verto server and
|
||||
* redirects him to login page.
|
||||
*/
|
||||
$scope.logout = function() {
|
||||
var disconnect = function() {
|
||||
var disconnectCallback = function(v, connected) {
|
||||
console.debug('Redirecting to login page.');
|
||||
storage.reset();
|
||||
$location.path('/login');
|
||||
};
|
||||
|
||||
if (verto.data.call) {
|
||||
verto.hangup();
|
||||
}
|
||||
|
||||
$scope.closeChat();
|
||||
verto.disconnect(disconnectCallback);
|
||||
|
||||
verto.hangup();
|
||||
};
|
||||
|
||||
if (verto.data.call) {
|
||||
prompt({
|
||||
title: 'Oops, Active Call in Course.',
|
||||
message: 'It seems that you are in a call. Do you want to hang up?'
|
||||
}).then(function() {
|
||||
disconnect();
|
||||
});
|
||||
} else {
|
||||
disconnect();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Shows a modal with the settings.
|
||||
*/
|
||||
$scope.openModalSettings = function() {
|
||||
var modalInstance = $modal.open({
|
||||
animation: $scope.animationsEnabled,
|
||||
templateUrl: 'partials/modal_settings.html',
|
||||
controller: 'ModalSettingsController',
|
||||
});
|
||||
|
||||
modalInstance.result.then(
|
||||
function(result) {
|
||||
console.log(result);
|
||||
},
|
||||
function() {
|
||||
console.info('Modal dismissed at: ' + new Date());
|
||||
}
|
||||
);
|
||||
|
||||
modalInstance.rendered.then(
|
||||
function() {
|
||||
jQuery.material.init();
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
$scope.openModal = function(templateUrl, controller) {
|
||||
var modalInstance = $modal.open({
|
||||
animation: $scope.animationsEnabled,
|
||||
templateUrl: templateUrl,
|
||||
controller: controller,
|
||||
});
|
||||
|
||||
modalInstance.result.then(
|
||||
function(result) {
|
||||
console.log(result);
|
||||
},
|
||||
function() {
|
||||
console.info('Modal dismissed at: ' + new Date());
|
||||
}
|
||||
);
|
||||
|
||||
modalInstance.rendered.then(
|
||||
function() {
|
||||
jQuery.material.init();
|
||||
}
|
||||
);
|
||||
|
||||
};
|
||||
|
||||
$scope.showContributors = function() {
|
||||
$scope.openModal('partials/contributors.html', 'ContributorsController');
|
||||
};
|
||||
|
||||
/**
|
||||
* Updates the display adding the new number touched.
|
||||
*
|
||||
* @param {String} number - New touched number.
|
||||
*/
|
||||
$rootScope.dtmf = function(number) {
|
||||
$rootScope.dialpadNumber = $scope.dialpadNumber + number;
|
||||
if (verto.data.call) {
|
||||
verto.dtmf(number);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Removes the last character from the number.
|
||||
*/
|
||||
$rootScope.backspace = function() {
|
||||
var number = $rootScope.dialpadNumber;
|
||||
var len = number.length;
|
||||
$rootScope.dialpadNumber = number.substring(0, len - 1);
|
||||
};
|
||||
|
||||
|
||||
$scope.toggleCallHistory = function() {
|
||||
if (!$scope.call_history) {
|
||||
angular.element("#call_history").addClass('active');
|
||||
angular.element("#call-history-wrapper").addClass('active');
|
||||
} else {
|
||||
angular.element("#call_history").removeClass('active');
|
||||
angular.element("#call-history-wrapper").removeClass('active');
|
||||
}
|
||||
$scope.call_history = angular.element("#call_history").hasClass('active');
|
||||
};
|
||||
|
||||
$scope.clearCallHistory = function() {
|
||||
storage.data.call_history = [];
|
||||
};
|
||||
|
||||
$scope.toggleChat = function() {
|
||||
if ($scope.chatStatus && $rootScope.activePane === 'chat') {
|
||||
$rootScope.chat_counter = 0;
|
||||
}
|
||||
angular.element('#wrapper').toggleClass('toggled');
|
||||
$scope.chatStatus = angular.element('#wrapper').hasClass('toggled');
|
||||
};
|
||||
|
||||
$scope.openChat = function() {
|
||||
$scope.chatStatus = false;
|
||||
angular.element('#wrapper').removeClass('toggled');
|
||||
};
|
||||
|
||||
$scope.closeChat = function() {
|
||||
$scope.chatStatus = true;
|
||||
angular.element('#wrapper').addClass('toggled');
|
||||
};
|
||||
|
||||
$scope.goFullscreen = function() {
|
||||
if (storage.data.userStatus !== 'connected') {
|
||||
return;
|
||||
}
|
||||
$rootScope.fullscreenEnabled = !Fullscreen.isEnabled();
|
||||
if (Fullscreen.isEnabled()) {
|
||||
Fullscreen.cancel();
|
||||
} else {
|
||||
Fullscreen.enable(document.getElementsByTagName('body')[0]);
|
||||
}
|
||||
};
|
||||
|
||||
$rootScope.$on('call.video', function(event) {
|
||||
storage.data.videoCall = true;
|
||||
});
|
||||
|
||||
$rootScope.$on('call.hangup', function(event, data) {
|
||||
if (Fullscreen.isEnabled()) {
|
||||
Fullscreen.cancel();
|
||||
}
|
||||
|
||||
|
||||
console.log($scope.chatStatus);
|
||||
if (!$scope.chatStatus) {
|
||||
angular.element('#wrapper').toggleClass('toggled');
|
||||
$scope.chatStatus = angular.element('#wrapper').hasClass('toggled');
|
||||
}
|
||||
|
||||
$rootScope.dialpadNumber = '';
|
||||
console.debug('Redirecting to dialpad page.');
|
||||
$location.path('/dialpad');
|
||||
|
||||
try {
|
||||
$rootScope.$digest();
|
||||
} catch (e) {
|
||||
console.log('not digest');
|
||||
}
|
||||
});
|
||||
|
||||
$rootScope.$on('page.incall', function(event, data) {
|
||||
if (storage.data.askRecoverCall) {
|
||||
prompt({
|
||||
title: 'Oops, Active Call in Course.',
|
||||
message: 'It seems you were in a call before leaving the last time. Wanna go back to that?'
|
||||
}).then(function() {
|
||||
verto.changeData(storage);
|
||||
console.log('redirect to incall page');
|
||||
$location.path('/incall');
|
||||
}, function() {
|
||||
storage.data.userStatus = 'connecting';
|
||||
verto.hangup();
|
||||
});
|
||||
} else {
|
||||
verto.changeData(storage);
|
||||
console.log('redirect to incall page');
|
||||
$location.path('/incall');
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
$rootScope.callActive = function(data) {
|
||||
verto.data.mutedMic = storage.data.mutedMic;
|
||||
verto.data.mutedVideo = storage.data.mutedVideo;
|
||||
|
||||
if (!storage.data.cur_call) {
|
||||
storage.data.call_start = new Date();
|
||||
}
|
||||
storage.data.userStatus = 'connected';
|
||||
var call_start = new Date(storage.data.call_start);
|
||||
$rootScope.start_time = call_start;
|
||||
|
||||
$timeout(function() {
|
||||
$scope.$broadcast('timer-start');
|
||||
});
|
||||
myVideo.play();
|
||||
storage.data.calling = false;
|
||||
|
||||
storage.data.cur_call = 1;
|
||||
};
|
||||
|
||||
$rootScope.$on('call.active', function(event, data) {
|
||||
$rootScope.callActive(data);
|
||||
});
|
||||
|
||||
$rootScope.$on('call.calling', function(event, data) {
|
||||
storage.data.calling = true;
|
||||
});
|
||||
|
||||
$rootScope.$on('call.incoming', function(event, data) {
|
||||
console.log('Incoming call from: ' + data);
|
||||
|
||||
storage.data.cur_call = 0;
|
||||
$scope.incomingCall = true;
|
||||
storage.data.videoCall = false;
|
||||
storage.data.mutedVideo = false;
|
||||
storage.data.mutedMic = false;
|
||||
|
||||
prompt({
|
||||
title: 'Incoming Call',
|
||||
message: 'from ' + data
|
||||
}).then(function() {
|
||||
var call_start = new Date(storage.data.call_start);
|
||||
$rootScope.start_time = call_start;
|
||||
console.log($rootScope.start_time);
|
||||
|
||||
$scope.answerCall();
|
||||
storage.data.called_number = data;
|
||||
|
||||
storage.data.call_history.unshift({
|
||||
'number': data,
|
||||
'direction': 'inbound',
|
||||
'status': true,
|
||||
'call_start': Date()
|
||||
});
|
||||
$location.path('/incall');
|
||||
}, function() {
|
||||
$scope.declineCall();
|
||||
storage.data.call_history.unshift({
|
||||
'number': data,
|
||||
'direction': 'inbound',
|
||||
'status': false,
|
||||
'call_start': Date()
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
$scope.hold = function() {
|
||||
storage.data.onHold = !storage.data.onHold;
|
||||
verto.data.call.toggleHold();
|
||||
};
|
||||
|
||||
/**
|
||||
* Hangup the current call.
|
||||
*/
|
||||
$scope.hangup = function() {
|
||||
if (!verto.data.call) {
|
||||
toastr.warning('There is no call to hangup.');
|
||||
$location.path('/dialpad');
|
||||
}
|
||||
|
||||
//var hangupCallback = function(v, hangup) {
|
||||
// if (hangup) {
|
||||
// $location.path('/dialpad');
|
||||
// } else {
|
||||
// console.debug('The call could not be hangup.');
|
||||
// }
|
||||
//};
|
||||
//
|
||||
//verto.hangup(hangupCallback);
|
||||
|
||||
verto.hangup();
|
||||
};
|
||||
|
||||
$scope.answerCall = function() {
|
||||
storage.data.onHold = false;
|
||||
|
||||
verto.data.call.answer({
|
||||
useStereo: verto.data.useStereo,
|
||||
useCamera: verto.data.useCamera,
|
||||
useMic: verto.data.useMic,
|
||||
callee_id_name: verto.data.name,
|
||||
callee_id_number: verto.data.login
|
||||
});
|
||||
|
||||
|
||||
$location.path('/incall');
|
||||
};
|
||||
|
||||
$scope.declineCall = function() {
|
||||
$scope.hangup();
|
||||
$scope.incomingCall = false;
|
||||
};
|
||||
|
||||
$scope.screenshare = function() {
|
||||
if (verto.data.shareCall) {
|
||||
verto.screenshareHangup();
|
||||
return false;
|
||||
}
|
||||
verto.screenshare(storage.data.called_number);
|
||||
};
|
||||
|
||||
$scope.play = function() {
|
||||
var file = $scope.promptInput('Please, enter filename', '', 'File',
|
||||
function(file) {
|
||||
verto.data.conf.play(file);
|
||||
console.log('play file :', file);
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
$scope.stop = function() {
|
||||
verto.data.conf.stop();
|
||||
};
|
||||
|
||||
$scope.record = function() {
|
||||
var file = $scope.promptInput('Please, enter filename', '', 'File',
|
||||
function(file) {
|
||||
verto.data.conf.record(file);
|
||||
console.log('recording file :', file);
|
||||
});
|
||||
};
|
||||
|
||||
$scope.stopRecord = function() {
|
||||
verto.data.conf.stopRecord();
|
||||
};
|
||||
|
||||
$scope.snapshot = function() {
|
||||
var file = $scope.promptInput('Please, enter filename', '', 'File',
|
||||
function(file) {
|
||||
verto.data.conf.snapshot(file);
|
||||
console.log('snapshot file :', file);
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
]);
|
||||
|
||||
|
||||
vertoControllers.controller('ChatController', ['$scope', '$rootScope', '$http',
|
||||
'$location', '$anchorScroll', '$timeout', 'toastr', 'verto', 'storage', 'prompt',
|
||||
function($scope, $rootScope, $http, $location, $anchorScroll, $timeout,
|
||||
toastr, verto, storage, prompt) {
|
||||
console.debug('Executing ChatController.');
|
||||
|
||||
function scrollToChatBottom() {
|
||||
// Going to the bottom of chat messages.
|
||||
var obj = document.querySelector('.chat-messages');
|
||||
obj.scrollTop = obj.scrollHeight;
|
||||
//var chat_messages_top = jQuery('.chat-messages').scrollTop();
|
||||
//var marker_position = jQuery('#chat-message-bottom').position().top;
|
||||
//jQuery('.chat-messages').scrollTop(chat_messages_top + marker_position);
|
||||
}
|
||||
|
||||
var CLEAN_MESSAGE = '';
|
||||
|
||||
function clearConferenceChat() {
|
||||
$scope.members = [];
|
||||
$scope.messages = [];
|
||||
$scope.message = CLEAN_MESSAGE;
|
||||
}
|
||||
clearConferenceChat();
|
||||
|
||||
$scope.$watch('activePane', function() {
|
||||
if ($scope.activePane == 'chat') {
|
||||
$rootScope.chat_counter = 0;
|
||||
}
|
||||
$rootScope.activePane = $scope.activePane;
|
||||
});
|
||||
|
||||
$rootScope.$on('chat.newMessage', function(event, data) {
|
||||
data.created_at = new Date();
|
||||
console.log('chat.newMessage', data);
|
||||
|
||||
$scope.$apply(function() {
|
||||
$scope.messages.push(data);
|
||||
if(data.from != storage.data.name &&
|
||||
(angular.element('#wrapper').hasClass('toggled') ||
|
||||
$scope.activePane != 'chat')) {
|
||||
toastr.info(data.body, data.from, {onHidden: function(clicked) {
|
||||
if(clicked) {
|
||||
$scope.chatStatus = false;
|
||||
angular.element('#wrapper').removeClass('toggled');
|
||||
$rootScope.activePane = 'chat';
|
||||
$scope.activePane = 'chat';
|
||||
$scope.$apply();
|
||||
return true;
|
||||
}
|
||||
}});
|
||||
++$rootScope.chat_counter;
|
||||
return true;
|
||||
}
|
||||
$timeout(function() {
|
||||
scrollToChatBottom();
|
||||
}, 300);
|
||||
});
|
||||
});
|
||||
|
||||
$rootScope.$on('call.recovering', function(event){
|
||||
console.log('Our current call is recovering, clear the participant list.');
|
||||
$scope.members = [];
|
||||
});
|
||||
|
||||
function findMemberByUUID(uuid) {
|
||||
var found = false;
|
||||
for (var idx in $scope.members) {
|
||||
var member = $scope.members[idx];
|
||||
if (member.uuid == uuid) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found) {
|
||||
return idx;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
function translateMember(member) {
|
||||
return {
|
||||
'uuid': member[0],
|
||||
'id': member[1][0],
|
||||
'number': member[1][1],
|
||||
'name': member[1][2],
|
||||
'codec': member[1][3],
|
||||
'status': JSON.parse(member[1][4]),
|
||||
'email': member[1][5].email
|
||||
};
|
||||
}
|
||||
|
||||
function addMember(member) {
|
||||
$scope.members.push(translateMember(member));
|
||||
}
|
||||
|
||||
$rootScope.$on('members.boot', function(event, members) {
|
||||
console.log('members.boot', event, members);
|
||||
$scope.$apply(function() {
|
||||
clearConferenceChat();
|
||||
for (var idx in members) {
|
||||
var member = members[idx];
|
||||
addMember(member);
|
||||
console.log($scope.members);
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
$rootScope.$on('members.add', function(event, member) {
|
||||
$scope.$apply(function() {
|
||||
addMember(member);
|
||||
});
|
||||
});
|
||||
|
||||
$rootScope.$on('members.del', function(event, uuid) {
|
||||
$scope.$apply(function() {
|
||||
var memberIdx = findMemberByUUID(uuid);
|
||||
if (memberIdx != -1) {
|
||||
// Removing the member.
|
||||
$scope.members.splice(memberIdx, 1);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$rootScope.$on('members.update', function(event, member) {
|
||||
member = translateMember(member);
|
||||
var memberIdx = findMemberByUUID(member.uuid);
|
||||
if (memberIdx < 0) {
|
||||
console.log('Didn\'t find the member uuid ' + member.uuid);
|
||||
} else {
|
||||
$scope.$apply(function() {
|
||||
console.log('Updating', memberIdx, ' <', $scope.members[memberIdx],
|
||||
'> with <', member, '>');
|
||||
angular.extend($scope.members[memberIdx], member);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
$rootScope.$on('members.clear', function(event) {
|
||||
$scope.$apply(function() {
|
||||
clearConferenceChat();
|
||||
$scope.closeChat();
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Public methods.
|
||||
*/
|
||||
$scope.send = function() {
|
||||
verto.sendMessage($scope.message, function() {
|
||||
$scope.message = CLEAN_MESSAGE;
|
||||
});
|
||||
};
|
||||
|
||||
// Participants moderation.
|
||||
$scope.confKick = function(memberID) {
|
||||
console.log('$scope.confKick');
|
||||
verto.data.conf.kick(memberID);
|
||||
};
|
||||
|
||||
$scope.confMuteMic = function(memberID) {
|
||||
console.log('$scope.confMuteMic');
|
||||
verto.data.conf.muteMic(memberID);
|
||||
};
|
||||
|
||||
$scope.confMuteVideo = function(memberID) {
|
||||
console.log('$scope.confMuteVideo');
|
||||
verto.data.conf.muteVideo(memberID);
|
||||
};
|
||||
|
||||
$scope.confPresenter = function(memberID) {
|
||||
console.log('$scope.confPresenter');
|
||||
verto.data.conf.presenter(memberID);
|
||||
};
|
||||
|
||||
$scope.confVideoFloor = function(memberID) {
|
||||
console.log('$scope.confVideoFloor');
|
||||
verto.data.conf.videoFloor(memberID);
|
||||
};
|
||||
|
||||
$scope.confBanner = function(memberID) {
|
||||
console.log('$scope.confBanner');
|
||||
prompt({
|
||||
title: 'Participant banner',
|
||||
message: 'What would you like the banner to say?',
|
||||
input: true,
|
||||
label: 'Text',
|
||||
value: 'New text'
|
||||
}).then(function(text){
|
||||
verto.data.conf.banner(memberID, text);
|
||||
});
|
||||
};
|
||||
|
||||
$scope.confVolumeDown = function(memberID) {
|
||||
console.log('$scope.confVolumeDown');
|
||||
verto.data.conf.volumeDown(memberID);
|
||||
};
|
||||
|
||||
$scope.confVolumeUp = function(memberID) {
|
||||
console.log('$scope.confVolumeUp');
|
||||
verto.data.conf.volumeUp(memberID);
|
||||
};
|
||||
|
||||
$scope.confTransfer = function(memberID) {
|
||||
console.log('$scope.confTransfer');
|
||||
var exten = '1800';
|
||||
verto.data.conf.transfer(memberID, exten);
|
||||
};
|
||||
}
|
||||
]);
|
||||
|
||||
|
||||
vertoControllers.controller('MenuController', ['$scope', '$http', '$location',
|
||||
'verto', 'storage',
|
||||
function($scope, $http, $location, verto, storage) {
|
||||
console.debug('Executing MenuController.');
|
||||
}
|
||||
]);
|
||||
|
||||
|
||||
vertoControllers.controller('ModalSettingsController', ['$scope', '$http',
|
||||
'$location', '$modalInstance', 'verto', 'storage',
|
||||
function($scope, $http, $location, $modalInstance, verto, storage) {
|
||||
console.debug('Executing ModalSettingsController.');
|
||||
|
||||
verto.changeData(storage);
|
||||
$scope.verto = verto;
|
||||
$scope.storage = storage;
|
||||
|
||||
$scope.ok = function() {
|
||||
storage.changeData(verto);
|
||||
$modalInstance.close('Ok.');
|
||||
};
|
||||
|
||||
$scope.cancel = function() {
|
||||
$modalInstance.dismiss('cancel');
|
||||
};
|
||||
|
||||
$scope.refreshDeviceList = function() {
|
||||
return verto.refreshDevices();
|
||||
}
|
||||
}
|
||||
]);
|
||||
|
||||
vertoControllers.controller('ModalLoginInformationController', ['$scope',
|
||||
'$http', '$location', '$modalInstance', 'verto', 'storage',
|
||||
function($scope, $http, $location, $modalInstance, verto, storage) {
|
||||
console.debug('Executing ModalLoginInformationController.');
|
||||
|
||||
$scope.verto = verto;
|
||||
$scope.storage = storage;
|
||||
|
||||
$scope.ok = function() {
|
||||
$modalInstance.close('Ok.');
|
||||
};
|
||||
|
||||
$scope.cancel = function() {
|
||||
$modalInstance.dismiss('cancel');
|
||||
};
|
||||
|
||||
}
|
||||
]);
|
||||
|
||||
vertoControllers.controller('LoginController', ['$scope', '$http', '$location',
|
||||
'verto',
|
||||
function($scope, $http, $location, verto) {
|
||||
$scope.checkBrowser();
|
||||
|
||||
/**
|
||||
* using stored data (localStorage) for logon
|
||||
*/
|
||||
verto.data.name = $scope.storage.data.name;
|
||||
verto.data.email = $scope.storage.data.email;
|
||||
if ($scope.storage.data.login != '' && $scope.storage.data.password != '') {
|
||||
verto.data.login = $scope.storage.data.login;
|
||||
verto.data.password = $scope.storage.data.password;
|
||||
}
|
||||
|
||||
console.debug('Executing LoginController.');
|
||||
}
|
||||
]);
|
||||
|
||||
|
||||
vertoControllers.controller('DialPadController', ['$rootScope', '$scope',
|
||||
'$http', '$location', 'toastr', 'verto', 'storage',
|
||||
function($rootScope, $scope, $http, $location, toastr, verto, storage) {
|
||||
console.debug('Executing DialPadController.');
|
||||
|
||||
$scope.checkBrowser();
|
||||
storage.data.videoCall = false;
|
||||
storage.data.userStatus = 'connecting';
|
||||
storage.data.calling = false;
|
||||
|
||||
/**
|
||||
* fill dialpad via querystring [?autocall=\d+]
|
||||
*/
|
||||
if ($location.search().autocall) {
|
||||
$rootScope.dialpadNumber = $location.search().autocall;
|
||||
}
|
||||
|
||||
/**
|
||||
* used to bind click on number in call history to fill dialpad
|
||||
* 'cause inside a ng-repeat the angular isnt in ctrl scope
|
||||
*/
|
||||
$scope.fillDialpadNumber = function(number) {
|
||||
$rootScope.dialpadNumber = number;
|
||||
};
|
||||
|
||||
$rootScope.transfer = function() {
|
||||
if (!$rootScope.dialpadNumber) {
|
||||
return false;
|
||||
}
|
||||
verto.data.call.transfer($rootScope.dialpadNumber);
|
||||
};
|
||||
|
||||
/**
|
||||
* Call to the number in the $rootScope.dialpadNumber.
|
||||
*/
|
||||
$rootScope.call = function(extension) {
|
||||
storage.data.onHold = false;
|
||||
storage.data.cur_call = 0;
|
||||
$rootScope.dialpadNumber = extension;
|
||||
if (!$rootScope.dialpadNumber && storage.data.called_number) {
|
||||
$rootScope.dialpadNumber = storage.data.called_number;
|
||||
return false;
|
||||
} else if (!$rootScope.dialpadNumber && !storage.data.called_number) {
|
||||
toastr.warning('Enter an extension, please.');
|
||||
return false;
|
||||
}
|
||||
|
||||
if (verto.data.call) {
|
||||
console.debug('A call is already in progress.');
|
||||
return false;
|
||||
}
|
||||
|
||||
storage.data.mutedVideo = false;
|
||||
storage.data.mutedMic = false;
|
||||
|
||||
storage.data.videoCall = false;
|
||||
verto.call($rootScope.dialpadNumber);
|
||||
|
||||
storage.data.called_number = $rootScope.dialpadNumber;
|
||||
storage.data.call_history.unshift({
|
||||
'number': $rootScope.dialpadNumber,
|
||||
'direction': 'outbound',
|
||||
'call_start': Date()
|
||||
});
|
||||
$location.path('/incall');
|
||||
}
|
||||
}
|
||||
]);
|
||||
|
||||
|
||||
vertoControllers.controller('InCallController', ['$rootScope', '$scope',
|
||||
'$http', '$location', '$modal', '$timeout', 'toastr', 'verto', 'storage', 'prompt', 'Fullscreen',
|
||||
function($rootScope, $scope, $http, $location, $modal, $timeout, toatr,
|
||||
verto, storage, prompt, Fullscreen) {
|
||||
|
||||
console.debug('Executing InCallController.');
|
||||
$scope.layout = null;
|
||||
$scope.checkBrowser();
|
||||
$rootScope.dialpadNumber = '';
|
||||
$scope.callTemplate = 'partials/phone_call.html';
|
||||
$scope.dialpadTemplate = '';
|
||||
$scope.incall = true;
|
||||
|
||||
if (storage.data.videoCall) {
|
||||
$scope.callTemplate = 'partials/video_call.html';
|
||||
}
|
||||
|
||||
$rootScope.$on('call.video', function(event, data) {
|
||||
$timeout(function() {
|
||||
$scope.callTemplate = 'partials/video_call.html';
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* toggle dialpad in incall page
|
||||
*/
|
||||
$scope.toggleDialpad = function() {
|
||||
$scope.openModal('partials/dialpad_widget.html',
|
||||
'ModalDialpadController');
|
||||
|
||||
/*
|
||||
if(!$scope.dialpadTemplate) {
|
||||
$scope.dialpadTemplate = 'partials/dialpad_widget.html';
|
||||
} else {
|
||||
$scope.dialpadTemplate = '';
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: useless?
|
||||
*/
|
||||
$scope.videoCall = function() {
|
||||
prompt({
|
||||
title: 'Would you like to activate video for this call?',
|
||||
message: 'Video will be active during the next calls.'
|
||||
}).then(function() {
|
||||
storage.data.videoCall = true;
|
||||
$scope.callTemplate = 'partials/video_call.html';
|
||||
});
|
||||
};
|
||||
|
||||
$scope.cbMuteVideo = function(event, data) {
|
||||
storage.data.mutedVideo = !storage.data.mutedVideo;
|
||||
}
|
||||
|
||||
$scope.cbMuteMic = function(event, data) {
|
||||
storage.data.mutedMic = !storage.data.mutedMic;
|
||||
}
|
||||
|
||||
$scope.confChangeVideoLayout = function(layout) {
|
||||
verto.data.conf.setVideoLayout(layout);
|
||||
};
|
||||
|
||||
$scope.muteMic = verto.muteMic;
|
||||
$scope.muteVideo = verto.muteVideo;
|
||||
|
||||
$timeout(function() {
|
||||
console.log('broadcast time-start incall');
|
||||
$scope.$broadcast('timer-start');
|
||||
}, 1000);
|
||||
|
||||
}
|
||||
]);
|
||||
|
||||
vertoControllers.controller('ModalDialpadController', ['$scope',
|
||||
'$modalInstance',
|
||||
function($scope, $modalInstance) {
|
||||
|
||||
$scope.ok = function() {
|
||||
$modalInstance.close('Ok.');
|
||||
};
|
||||
|
||||
$scope.cancel = function() {
|
||||
$modalInstance.dismiss('cancel');
|
||||
};
|
||||
|
||||
}
|
||||
]);
|
||||
|
||||
vertoControllers.controller('BrowserUpgradeController', ['$scope', '$http',
|
||||
'$location', 'verto', 'storage', 'Fullscreen',
|
||||
function($scope, $http, $location, verto, storage, Fullscreen) {
|
||||
console.debug('Executing BrowserUpgradeController.');
|
||||
|
||||
}
|
||||
]);
|
||||
|
||||
vertoControllers.controller('ContributorsController', ['$scope', '$http',
|
||||
'toastr',
|
||||
function($scope, $http, toastr) {
|
||||
$http.get(window.location.pathname + '/contributors.txt')
|
||||
.success(function(data) {
|
||||
|
||||
var contributors = [];
|
||||
|
||||
angular.forEach(data, function(value, key) {
|
||||
var re = /(.*) <(.*)>/;
|
||||
var name = value.replace(re, "$1");
|
||||
var email = value.replace(re, "$2");
|
||||
|
||||
this.push({
|
||||
'name': name,
|
||||
'email': email
|
||||
});
|
||||
}, contributors);
|
||||
|
||||
$scope.contributors = contributors;
|
||||
})
|
||||
.error(function() {
|
||||
toastr.error('contributors not found.');
|
||||
});
|
||||
}
|
||||
]);
|
||||
@@ -1,109 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
/* Directives */
|
||||
|
||||
var vertoDirectives = angular.module('vertoDirectives', []);
|
||||
|
||||
/**
|
||||
* To RTC work properly we need to give a <video> tag as soon as possible
|
||||
* because it needs to attach the video and audio stream to the tag.
|
||||
*
|
||||
* This directive is responsible for moving the video tag from the body to
|
||||
* the right place when a call start and move back to the body when the
|
||||
* call ends. It also hides and display the tag when its convenient.
|
||||
*/
|
||||
vertoDirectives.directive('videoTag',
|
||||
function() {
|
||||
function link(scope, element, attrs) {
|
||||
// Moving the video tag to the new place inside the incall page.
|
||||
console.log('Moving the video to element.');
|
||||
jQuery('video').removeClass('hide').appendTo(element);
|
||||
jQuery('video').css('display', 'block');
|
||||
scope.callActive();
|
||||
|
||||
element.on('$destroy', function() {
|
||||
// Move the video back to the body.
|
||||
console.log('Moving the video back to body.');
|
||||
jQuery('video').addClass('hide').appendTo(jQuery('body'));
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
link: link
|
||||
}
|
||||
});
|
||||
|
||||
vertoDirectives.directive('userStatus',
|
||||
function() {
|
||||
var link = function(scope, element, attrs) {
|
||||
scope.$watch('condition', function(condition) {
|
||||
element.removeClass('connected');
|
||||
element.removeClass('disconnected');
|
||||
element.removeClass('connecting');
|
||||
|
||||
element.addClass(condition);
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
scope: {
|
||||
'condition': '='
|
||||
},
|
||||
link: link
|
||||
};
|
||||
|
||||
});
|
||||
|
||||
vertoDirectives.directive('showControls',
|
||||
function(Fullscreen) {
|
||||
var link = function(scope, element, attrs) {
|
||||
var i = null;
|
||||
jQuery('.video-footer').fadeIn('slow');
|
||||
jQuery('.video-hover-buttons').fadeIn('slow');
|
||||
element.parent().bind('mousemove', function() {
|
||||
if (Fullscreen.isEnabled()) {
|
||||
clearTimeout(i);
|
||||
jQuery('.video-footer').fadeIn('slow');
|
||||
jQuery('.video-hover-buttons').fadeIn(500);
|
||||
i = setTimeout(function() {
|
||||
if (Fullscreen.isEnabled()) {
|
||||
jQuery('.video-footer').fadeOut('slow');
|
||||
jQuery('.video-hover-buttons').fadeOut(500);
|
||||
}
|
||||
}, 3000);
|
||||
}
|
||||
});
|
||||
element.parent().bind('mouseleave', function() {
|
||||
jQuery('.video-footer').fadeIn();
|
||||
jQuery('.video-hover-buttons').fadeIn();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
return {
|
||||
link: link
|
||||
};
|
||||
});
|
||||
|
||||
/*
|
||||
Sometimes autofocus HTML5 directive just isn't enough with SPAs.
|
||||
This directive will force autofocus to work properly under those circumstances.
|
||||
*/
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
vertoDirectives.directive('autofocus', ['$timeout',
|
||||
function ($timeout) {
|
||||
return {
|
||||
restrict: 'A',
|
||||
link: function ($scope, $element) {
|
||||
$timeout(function () {
|
||||
console.log('Focusing...');
|
||||
$element[0].focus();
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
]);
|
||||
})();
|
||||
@@ -1,16 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
/* Filters */
|
||||
|
||||
var vertoFilters = angular.module('vertoFilters', []);
|
||||
|
||||
vertoFilters.filter('gravatar',
|
||||
function() {
|
||||
return function (email, size) {
|
||||
if (angular.isUndefined(size)) {
|
||||
size = 40;
|
||||
}
|
||||
var hash = md5(email);
|
||||
return 'https://secure.gravatar.com/avatar/' + hash + '?s=' + size + '&d=mm';
|
||||
}
|
||||
});
|
||||
@@ -5,6 +5,7 @@
|
||||
"devDependencies": {
|
||||
"autoprefixer-core": "^5.2.1",
|
||||
"browser-sync": "^2.8.2",
|
||||
"connect-logger": "0.0.1",
|
||||
"grunt": "^0.4.5",
|
||||
"grunt-browser-sync": "^2.1.2",
|
||||
"grunt-concurrent": "^1.0.0",
|
||||
@@ -21,7 +22,6 @@
|
||||
"grunt-newer": "^1.1.0",
|
||||
"grunt-ng-annotate": "^0.9.2",
|
||||
"grunt-postcss": "^0.5.3",
|
||||
"grunt-string-replace": "^1.2.0",
|
||||
"grunt-svgmin": "^2.0.0",
|
||||
"grunt-usemin": "^3.0.0",
|
||||
"grunt-wiredep": "^2.0.0",
|
||||
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
+31
-7
@@ -24,7 +24,7 @@
|
||||
|
||||
<!-- CSS -->
|
||||
<!-- build:css(.) css/verto.css -->
|
||||
<link rel="stylesheet" type="text/css" href="css/verto.css">
|
||||
<link rel="stylesheet" type="text/css" href="src/css/verto.css">
|
||||
<!-- endbuild -->
|
||||
|
||||
|
||||
@@ -86,17 +86,41 @@
|
||||
<!-- endbuild -->
|
||||
|
||||
<!-- build:js(.) scripts/scripts.js -->
|
||||
|
||||
<script type="text/javascript" src="../js/src/jquery.jsonrpcclient.js"></script>
|
||||
<script type="text/javascript" src="../js/src/jquery.FSRTC.js"></script>
|
||||
<script type="text/javascript" src="../js/src/jquery.verto.js"></script>
|
||||
|
||||
<script type="text/javascript" src="js/3rd-party/getScreenId.js"></script>
|
||||
<script type="text/javascript" src="js/3rd-party/md5.min.js"></script>
|
||||
<script type="text/javascript" src="js/filters.js"></script>
|
||||
<script type="text/javascript" src="js/verto-service.js"></script>
|
||||
<script type="text/javascript" src="js/storage-service.js"></script>
|
||||
<script type="text/javascript" src="js/app.js"></script>
|
||||
<script type="text/javascript" src="js/controllers.js"></script>
|
||||
<script type="text/javascript" src="js/directives.js"></script>
|
||||
|
||||
<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/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/vertoControllers/controllers/DialPadController.js"></script>
|
||||
<script type="text/javascript" src="src/vertoControllers/controllers/InCallController.js"></script>
|
||||
<script type="text/javascript" src="src/vertoControllers/controllers/LoginController.js"></script>
|
||||
<script type="text/javascript" src="src/vertoControllers/controllers/MainController.js"></script>
|
||||
<script type="text/javascript" src="src/vertoControllers/controllers/MenuController.js"></script>
|
||||
<script type="text/javascript" src="src/vertoControllers/controllers/ModalDialpadController.js"></script>
|
||||
<script type="text/javascript" src="src/vertoControllers/controllers/ModalLoginInformationController.js"></script>
|
||||
<script type="text/javascript" src="src/vertoControllers/controllers/ModalSettingsController.js"></script>
|
||||
|
||||
<script type="text/javascript" src="src/vertoDirectives/vertoDirectives.module.js"></script>
|
||||
<script type="text/javascript" src="src/vertoDirectives/directives/autofocus.js"></script>
|
||||
<script type="text/javascript" src="src/vertoDirectives/directives/showControls.js"></script>
|
||||
<script type="text/javascript" src="src/vertoDirectives/directives/userStatus.js"></script>
|
||||
<script type="text/javascript" src="src/vertoDirectives/directives/videoTag.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/storageService/storageService.module.js"></script>
|
||||
<script type="text/javascript" src="src/storageService/services/storage.js"></script>
|
||||
|
||||
<!-- endbuild -->
|
||||
|
||||
</body>
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
+3
-3
@@ -1,8 +1,8 @@
|
||||
'use strict';
|
||||
|
||||
var storageService = angular.module('storageService', ['ngStorage']);
|
||||
|
||||
storageService.service('storage', ['$rootScope', '$localStorage',
|
||||
angular
|
||||
.module('storageService')
|
||||
.service('storage', ['$rootScope', '$localStorage',
|
||||
function($rootScope, $localStorage) {
|
||||
var data = $localStorage;
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
(function() {
|
||||
'use strict';
|
||||
var vertoService = angular.module('storageService', ['ngStorage']);
|
||||
})();
|
||||
@@ -0,0 +1,98 @@
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
var vertoApp = angular.module('vertoApp', [
|
||||
'timer',
|
||||
'ngRoute',
|
||||
'vertoControllers',
|
||||
'vertoDirectives',
|
||||
'ngStorage',
|
||||
'ngAnimate',
|
||||
'toastr',
|
||||
'FBAngular',
|
||||
'cgPrompt',
|
||||
'720kb.tooltips',
|
||||
'ui.gravatar',
|
||||
]);
|
||||
|
||||
vertoApp.config(['$routeProvider', 'gravatarServiceProvider',
|
||||
function($routeProvider, gravatarServiceProvider) {
|
||||
$routeProvider.
|
||||
when('/login', {
|
||||
title: 'Login',
|
||||
templateUrl: 'partials/login.html',
|
||||
controller: 'LoginController'
|
||||
}).
|
||||
when('/dialpad', {
|
||||
title: 'Dialpad',
|
||||
templateUrl: 'partials/dialpad.html',
|
||||
controller: 'DialPadController'
|
||||
}).
|
||||
when('/incall', {
|
||||
title: 'In a Call',
|
||||
templateUrl: 'partials/incall.html',
|
||||
controller: 'InCallController'
|
||||
}).
|
||||
/*when('/contributors', {
|
||||
title: 'Contributors',
|
||||
templateUrl: 'partials/contributors.html',
|
||||
controller: 'ContributorsController',
|
||||
}).*/
|
||||
when('/browser-upgrade', {
|
||||
title: '',
|
||||
templateUrl: 'partials/browser_upgrade.html',
|
||||
controller: 'BrowserUpgradeController'
|
||||
}).
|
||||
otherwise({
|
||||
redirectTo: '/login'
|
||||
});
|
||||
|
||||
gravatarServiceProvider.defaults = {
|
||||
default: 'mm' // Mystery man as default for missing avatars
|
||||
};
|
||||
}
|
||||
]);
|
||||
|
||||
vertoApp.run(['$rootScope', '$location', 'toastr', 'prompt',
|
||||
function($rootScope, $location, toastr, prompt) {
|
||||
$rootScope.$on('$routeChangeSuccess', function(event, current, previous) {
|
||||
$rootScope.title = current.$$route.title;
|
||||
});
|
||||
|
||||
$rootScope.safeProtocol = false;
|
||||
|
||||
if (window.location.protocol == 'https:') {
|
||||
$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,
|
||||
message: message,
|
||||
input: true,
|
||||
label: label
|
||||
}).then(function(ret) {
|
||||
if (angular.isFunction(callback)) {
|
||||
callback(ret);
|
||||
}
|
||||
}, function() {
|
||||
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
]);
|
||||
|
||||
})();
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
angular
|
||||
.module('vertoControllers')
|
||||
.controller('BrowserUpgradeController', ['$scope', '$http',
|
||||
'$location', 'verto', 'storage', 'Fullscreen',
|
||||
function($scope, $http, $location, verto, storage, Fullscreen) {
|
||||
console.debug('Executing BrowserUpgradeController.');
|
||||
|
||||
}
|
||||
]);
|
||||
|
||||
})();
|
||||
@@ -0,0 +1,192 @@
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
angular
|
||||
.module('vertoControllers')
|
||||
.controller('ChatController', ['$scope', '$rootScope', '$http',
|
||||
'$location', '$anchorScroll', '$timeout', 'verto',
|
||||
function($scope, $rootScope, $http, $location, $anchorScroll, $timeout,
|
||||
verto) {
|
||||
console.debug('Executing ChatController.');
|
||||
|
||||
function scrollToChatBottom() {
|
||||
// Going to the bottom of chat messages.
|
||||
var obj = document.querySelector('.chat-messages');
|
||||
obj.scrollTop = obj.scrollHeight;
|
||||
//var chat_messages_top = jQuery('.chat-messages').scrollTop();
|
||||
//var marker_position = jQuery('#chat-message-bottom').position().top;
|
||||
//jQuery('.chat-messages').scrollTop(chat_messages_top + marker_position);
|
||||
}
|
||||
|
||||
var CLEAN_MESSAGE = '';
|
||||
|
||||
function clearConferenceChat() {
|
||||
$scope.members = [];
|
||||
$scope.messages = [];
|
||||
$scope.message = CLEAN_MESSAGE;
|
||||
}
|
||||
clearConferenceChat();
|
||||
|
||||
$scope.$watch('activePane', function() {
|
||||
if ($scope.activePane == 'chat') {
|
||||
$rootScope.chat_counter = 0;
|
||||
}
|
||||
$rootScope.activePane = $scope.activePane;
|
||||
});
|
||||
|
||||
$rootScope.$on('chat.newMessage', function(event, data) {
|
||||
data.created_at = new Date();
|
||||
console.log('chat.newMessage', data);
|
||||
$scope.$apply(function() {
|
||||
$scope.messages.push(data);
|
||||
if (data.from != verto.data.name && (!$scope.chatStatus ||
|
||||
$scope.activePane != 'chat')) {
|
||||
++$rootScope.chat_counter;
|
||||
}
|
||||
$timeout(function() {
|
||||
scrollToChatBottom();
|
||||
}, 300);
|
||||
});
|
||||
});
|
||||
|
||||
function findMemberByUUID(uuid) {
|
||||
var found = false;
|
||||
for (var idx in $scope.members) {
|
||||
var member = $scope.members[idx];
|
||||
if (member.uuid == uuid) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found) {
|
||||
return idx;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
function translateMember(member) {
|
||||
return {
|
||||
'uuid': member[0],
|
||||
'id': member[1][0],
|
||||
'number': member[1][1],
|
||||
'name': member[1][2],
|
||||
'codec': member[1][3],
|
||||
'status': JSON.parse(member[1][4]),
|
||||
'email': member[1][5].email
|
||||
};
|
||||
}
|
||||
|
||||
function addMember(member) {
|
||||
$scope.members.push(translateMember(member));
|
||||
}
|
||||
|
||||
$rootScope.$on('members.boot', function(event, members) {
|
||||
console.log('members.boot', event, members);
|
||||
$scope.$apply(function() {
|
||||
clearConferenceChat();
|
||||
for (var idx in members) {
|
||||
var member = members[idx];
|
||||
addMember(member);
|
||||
console.log($scope.members);
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
$rootScope.$on('members.add', function(event, member) {
|
||||
$scope.$apply(function() {
|
||||
addMember(member);
|
||||
});
|
||||
});
|
||||
|
||||
$rootScope.$on('members.del', function(event, uuid) {
|
||||
$scope.$apply(function() {
|
||||
var memberIdx = findMemberByUUID(uuid);
|
||||
if (memberIdx != -1) {
|
||||
// Removing the member.
|
||||
$scope.members.splice(memberIdx, 1);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$rootScope.$on('members.update', function(event, member) {
|
||||
member = translateMember(member);
|
||||
var memberIdx = findMemberByUUID(member.uuid);
|
||||
if (memberIdx < 0) {
|
||||
console.log('Didn\'t find the member uuid ' + member.uuid);
|
||||
} else {
|
||||
$scope.$apply(function() {
|
||||
console.log('Updating', memberIdx, ' <', $scope.members[memberIdx],
|
||||
'> with <', member, '>');
|
||||
angular.extend($scope.members[memberIdx], member);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
$rootScope.$on('members.clear', function(event) {
|
||||
$scope.$apply(function() {
|
||||
clearConferenceChat();
|
||||
$scope.closeChat();
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Public methods.
|
||||
*/
|
||||
$scope.send = function() {
|
||||
verto.sendMessage($scope.message, function() {
|
||||
$scope.message = CLEAN_MESSAGE;
|
||||
});
|
||||
};
|
||||
|
||||
// Participants moderation.
|
||||
$scope.confKick = function(memberID) {
|
||||
console.log('$scope.confKick');
|
||||
verto.data.conf.kick(memberID);
|
||||
};
|
||||
|
||||
$scope.confMuteMic = function(memberID) {
|
||||
console.log('$scope.confMuteMic');
|
||||
verto.data.conf.muteMic(memberID);
|
||||
};
|
||||
|
||||
$scope.confMuteVideo = function(memberID) {
|
||||
console.log('$scope.confMuteVideo');
|
||||
verto.data.conf.muteVideo(memberID);
|
||||
};
|
||||
|
||||
$scope.confPresenter = function(memberID) {
|
||||
console.log('$scope.confPresenter');
|
||||
verto.data.conf.presenter(memberID);
|
||||
};
|
||||
|
||||
$scope.confVideoFloor = function(memberID) {
|
||||
console.log('$scope.confVideoFloor');
|
||||
verto.data.conf.videoFloor(memberID);
|
||||
};
|
||||
|
||||
$scope.confBanner = function(memberID) {
|
||||
console.log('$scope.confBanner');
|
||||
var text = 'New Banner';
|
||||
verto.data.conf.banner(memberID, text);
|
||||
};
|
||||
|
||||
$scope.confVolumeDown = function(memberID) {
|
||||
console.log('$scope.confVolumeDown');
|
||||
verto.data.conf.volumeDown(memberID);
|
||||
};
|
||||
|
||||
$scope.confVolumeUp = function(memberID) {
|
||||
console.log('$scope.confVolumeUp');
|
||||
verto.data.conf.volumeUp(memberID);
|
||||
};
|
||||
|
||||
$scope.confTransfer = function(memberID) {
|
||||
console.log('$scope.confTransfer');
|
||||
var exten = '1800';
|
||||
verto.data.conf.transfer(memberID, exten);
|
||||
};
|
||||
}
|
||||
]);
|
||||
|
||||
})();
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
angular
|
||||
.module('vertoControllers')
|
||||
.controller('ContributorsController', ['$scope', '$http',
|
||||
'toastr',
|
||||
function($scope, $http, toastr) {
|
||||
$http.get(window.location.pathname + '/contributors.txt')
|
||||
.success(function(data) {
|
||||
|
||||
var contributors = [];
|
||||
|
||||
angular.forEach(data, function(value, key) {
|
||||
var re = /(.*) <(.*)>/;
|
||||
var name = value.replace(re, "$1");
|
||||
var email = value.replace(re, "$2");
|
||||
|
||||
this.push({
|
||||
'name': name,
|
||||
'email': email
|
||||
});
|
||||
}, contributors);
|
||||
|
||||
$scope.contributors = contributors;
|
||||
})
|
||||
.error(function() {
|
||||
toastr.error('contributors not found.');
|
||||
});
|
||||
}
|
||||
]);
|
||||
})();
|
||||
@@ -0,0 +1,75 @@
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
angular
|
||||
.module('vertoControllers')
|
||||
.controller('DialPadController', ['$rootScope', '$scope',
|
||||
'$http', '$location', 'toastr', 'verto', 'storage',
|
||||
function($rootScope, $scope, $http, $location, toastr, verto, storage) {
|
||||
console.debug('Executing DialPadController.');
|
||||
|
||||
$scope.checkBrowser();
|
||||
storage.data.videoCall = false;
|
||||
storage.data.userStatus = 'connecting';
|
||||
storage.data.calling = false;
|
||||
|
||||
/**
|
||||
* fill dialpad via querystring [?autocall=\d+]
|
||||
*/
|
||||
if ($location.search().autocall) {
|
||||
$rootScope.dialpadNumber = $location.search().autocall;
|
||||
}
|
||||
|
||||
/**
|
||||
* used to bind click on number in call history to fill dialpad
|
||||
* 'cause inside a ng-repeat the angular isnt in ctrl scope
|
||||
*/
|
||||
$scope.fillDialpadNumber = function(number) {
|
||||
$rootScope.dialpadNumber = number;
|
||||
};
|
||||
|
||||
$rootScope.transfer = function() {
|
||||
if (!$rootScope.dialpadNumber) {
|
||||
return false;
|
||||
}
|
||||
verto.data.call.transfer($rootScope.dialpadNumber);
|
||||
};
|
||||
|
||||
/**
|
||||
* Call to the number in the $rootScope.dialpadNumber.
|
||||
*/
|
||||
$rootScope.call = function(extension) {
|
||||
storage.data.onHold = false;
|
||||
storage.data.cur_call = 0;
|
||||
$rootScope.dialpadNumber = extension;
|
||||
if (!$rootScope.dialpadNumber && storage.data.called_number) {
|
||||
$rootScope.dialpadNumber = storage.data.called_number;
|
||||
return false;
|
||||
} else if (!$rootScope.dialpadNumber && !storage.data.called_number) {
|
||||
toastr.warning('Enter an extension, please.');
|
||||
return false;
|
||||
}
|
||||
|
||||
if (verto.data.call) {
|
||||
console.debug('A call is already in progress.');
|
||||
return false;
|
||||
}
|
||||
|
||||
storage.data.mutedVideo = false;
|
||||
storage.data.mutedMic = false;
|
||||
|
||||
storage.data.videoCall = false;
|
||||
verto.call($rootScope.dialpadNumber);
|
||||
|
||||
storage.data.called_number = $rootScope.dialpadNumber;
|
||||
storage.data.call_history.unshift({
|
||||
'number': $rootScope.dialpadNumber,
|
||||
'direction': 'outbound',
|
||||
'call_start': Date()
|
||||
});
|
||||
$location.path('/incall');
|
||||
}
|
||||
}
|
||||
]);
|
||||
|
||||
})();
|
||||
@@ -0,0 +1,81 @@
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
angular
|
||||
.module('vertoControllers')
|
||||
.controller('InCallController', ['$rootScope', '$scope',
|
||||
'$http', '$location', '$modal', '$timeout', 'toastr', 'verto', 'storage', 'prompt', 'Fullscreen',
|
||||
function($rootScope, $scope, $http, $location, $modal, $timeout, toatr,
|
||||
verto, storage, prompt, Fullscreen) {
|
||||
|
||||
console.debug('Executing InCallController.');
|
||||
$scope.layout = null;
|
||||
$scope.checkBrowser();
|
||||
$rootScope.dialpadNumber = '';
|
||||
$scope.callTemplate = 'partials/phone_call.html';
|
||||
$scope.dialpadTemplate = '';
|
||||
$scope.incall = true;
|
||||
|
||||
|
||||
if (storage.data.videoCall) {
|
||||
$scope.callTemplate = 'partials/video_call.html';
|
||||
}
|
||||
|
||||
$rootScope.$on('call.video', function(event, data) {
|
||||
$timeout(function() {
|
||||
$scope.callTemplate = 'partials/video_call.html';
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* toggle dialpad in incall page
|
||||
*/
|
||||
$scope.toggleDialpad = function() {
|
||||
$scope.openModal('partials/dialpad_widget.html',
|
||||
'ModalDialpadController');
|
||||
|
||||
/*
|
||||
if(!$scope.dialpadTemplate) {
|
||||
$scope.dialpadTemplate = 'partials/dialpad_widget.html';
|
||||
} else {
|
||||
$scope.dialpadTemplate = '';
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: useless?
|
||||
*/
|
||||
$scope.videoCall = function() {
|
||||
prompt({
|
||||
title: 'Would you like to activate video for this call?',
|
||||
message: 'Video will be active during the next calls.'
|
||||
}).then(function() {
|
||||
storage.data.videoCall = true;
|
||||
$scope.callTemplate = 'partials/video_call.html';
|
||||
});
|
||||
};
|
||||
|
||||
$scope.cbMuteVideo = function(event, data) {
|
||||
storage.data.mutedVideo = !storage.data.mutedVideo;
|
||||
}
|
||||
|
||||
$scope.cbMuteMic = function(event, data) {
|
||||
storage.data.mutedMic = !storage.data.mutedMic;
|
||||
}
|
||||
|
||||
$scope.confChangeVideoLayout = function(layout) {
|
||||
verto.data.conf.setVideoLayout(layout);
|
||||
};
|
||||
|
||||
$scope.muteMic = verto.muteMic;
|
||||
$scope.muteVideo = verto.muteVideo;
|
||||
|
||||
$timeout(function() {
|
||||
console.log('broadcast time-start incall');
|
||||
$scope.$broadcast('timer-start');
|
||||
}, 1000);
|
||||
|
||||
}
|
||||
]);
|
||||
})();
|
||||
@@ -0,0 +1,25 @@
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
angular
|
||||
.module('vertoControllers')
|
||||
.controller('LoginController', ['$scope', '$http', '$location',
|
||||
'verto',
|
||||
function($scope, $http, $location, verto) {
|
||||
$scope.checkBrowser();
|
||||
|
||||
/**
|
||||
* using stored data (localStorage) for logon
|
||||
*/
|
||||
verto.data.name = $scope.storage.data.name;
|
||||
verto.data.email = $scope.storage.data.email;
|
||||
if ($scope.storage.data.login != '' && $scope.storage.data.password != '') {
|
||||
verto.data.login = $scope.storage.data.login;
|
||||
verto.data.password = $scope.storage.data.password;
|
||||
}
|
||||
|
||||
console.debug('Executing LoginController.');
|
||||
}
|
||||
]);
|
||||
|
||||
})();
|
||||
@@ -0,0 +1,445 @@
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
angular
|
||||
.module('vertoControllers')
|
||||
.controller('MainController',
|
||||
function($scope, $rootScope, $location, $modal, $timeout, verto, storage, toastr, Fullscreen, prompt) {
|
||||
|
||||
console.debug('Executing MainController.');
|
||||
|
||||
var myVideo = document.getElementById("webcam");
|
||||
$scope.verto = verto;
|
||||
$scope.storage = storage;
|
||||
$scope.call_history = angular.element("#call_history").hasClass('active');
|
||||
$scope.chatStatus = angular.element('#wrapper').hasClass('toggled');
|
||||
|
||||
/**
|
||||
* (explanation) scope in another controller extends rootScope (singleton)
|
||||
*/
|
||||
$rootScope.chat_counter = 0;
|
||||
$rootScope.activePane = 'members';
|
||||
/**
|
||||
* The number that will be called.
|
||||
* @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');
|
||||
}
|
||||
|
||||
/**
|
||||
* Login the user to verto server and
|
||||
* redirects him to dialpad page.
|
||||
*/
|
||||
$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.');
|
||||
storage.changeData(verto);
|
||||
toastr.success('Login successful.', 'Welcome');
|
||||
$location.path('/dialpad');
|
||||
} else {
|
||||
toastr.error('There was an error while trying to login. Please try again.', 'Error');
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
verto.connect(connectCallback);
|
||||
};
|
||||
|
||||
/**
|
||||
* Logout the user from verto server and
|
||||
* redirects him to login page.
|
||||
*/
|
||||
$scope.logout = function() {
|
||||
var disconnect = function() {
|
||||
var disconnectCallback = function(v, connected) {
|
||||
console.debug('Redirecting to login page.');
|
||||
storage.reset();
|
||||
$location.path('/login');
|
||||
};
|
||||
|
||||
if (verto.data.call) {
|
||||
verto.hangup();
|
||||
}
|
||||
|
||||
$scope.closeChat();
|
||||
verto.disconnect(disconnectCallback);
|
||||
|
||||
verto.hangup();
|
||||
};
|
||||
|
||||
if (verto.data.call) {
|
||||
prompt({
|
||||
title: 'Oops, Active Call in Course.',
|
||||
message: 'It seems that you are in a call. Do you want to hang up?'
|
||||
}).then(function() {
|
||||
disconnect();
|
||||
});
|
||||
} else {
|
||||
disconnect();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Shows a modal with the settings.
|
||||
*/
|
||||
$scope.openModalSettings = function() {
|
||||
var modalInstance = $modal.open({
|
||||
animation: $scope.animationsEnabled,
|
||||
templateUrl: 'partials/modal_settings.html',
|
||||
controller: 'ModalSettingsController',
|
||||
});
|
||||
|
||||
modalInstance.result.then(
|
||||
function(result) {
|
||||
console.log(result);
|
||||
},
|
||||
function() {
|
||||
console.info('Modal dismissed at: ' + new Date());
|
||||
}
|
||||
);
|
||||
|
||||
modalInstance.rendered.then(
|
||||
function() {
|
||||
jQuery.material.init();
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
$scope.openModal = function(templateUrl, controller) {
|
||||
var modalInstance = $modal.open({
|
||||
animation: $scope.animationsEnabled,
|
||||
templateUrl: templateUrl,
|
||||
controller: controller,
|
||||
});
|
||||
|
||||
modalInstance.result.then(
|
||||
function(result) {
|
||||
console.log(result);
|
||||
},
|
||||
function() {
|
||||
console.info('Modal dismissed at: ' + new Date());
|
||||
}
|
||||
);
|
||||
|
||||
modalInstance.rendered.then(
|
||||
function() {
|
||||
jQuery.material.init();
|
||||
}
|
||||
);
|
||||
|
||||
};
|
||||
|
||||
$scope.showContributors = function() {
|
||||
$scope.openModal('partials/contributors.html', 'ContributorsController');
|
||||
};
|
||||
|
||||
/**
|
||||
* Updates the display adding the new number touched.
|
||||
*
|
||||
* @param {String} number - New touched number.
|
||||
*/
|
||||
$rootScope.dtmf = function(number) {
|
||||
$rootScope.dialpadNumber = $scope.dialpadNumber + number;
|
||||
if (verto.data.call) {
|
||||
verto.dtmf(number);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Removes the last character from the number.
|
||||
*/
|
||||
$rootScope.backspace = function() {
|
||||
var number = $rootScope.dialpadNumber;
|
||||
var len = number.length;
|
||||
$rootScope.dialpadNumber = number.substring(0, len - 1);
|
||||
};
|
||||
|
||||
|
||||
$scope.toggleCallHistory = function() {
|
||||
if (!$scope.call_history) {
|
||||
angular.element("#call_history").addClass('active');
|
||||
angular.element("#call-history-wrapper").addClass('active');
|
||||
} else {
|
||||
angular.element("#call_history").removeClass('active');
|
||||
angular.element("#call-history-wrapper").removeClass('active');
|
||||
}
|
||||
$scope.call_history = angular.element("#call_history").hasClass('active');
|
||||
};
|
||||
|
||||
$scope.clearCallHistory = function() {
|
||||
storage.data.call_history = [];
|
||||
};
|
||||
|
||||
$scope.toggleChat = function() {
|
||||
if ($scope.chatStatus && $rootScope.activePane === 'chat') {
|
||||
$rootScope.chat_counter = 0;
|
||||
}
|
||||
angular.element('#wrapper').toggleClass('toggled');
|
||||
$scope.chatStatus = angular.element('#wrapper').hasClass('toggled');
|
||||
};
|
||||
|
||||
$scope.openChat = function() {
|
||||
$scope.chatStatus = false;
|
||||
angular.element('#wrapper').removeClass('toggled');
|
||||
};
|
||||
|
||||
$scope.closeChat = function() {
|
||||
$scope.chatStatus = true;
|
||||
angular.element('#wrapper').addClass('toggled');
|
||||
};
|
||||
|
||||
$scope.goFullscreen = function() {
|
||||
if (storage.data.userStatus !== 'connected') {
|
||||
return;
|
||||
}
|
||||
$rootScope.fullscreenEnabled = !Fullscreen.isEnabled();
|
||||
if (Fullscreen.isEnabled()) {
|
||||
Fullscreen.cancel();
|
||||
} else {
|
||||
Fullscreen.enable(document.getElementsByTagName('body')[0]);
|
||||
}
|
||||
};
|
||||
|
||||
$rootScope.$on('call.video', function(event) {
|
||||
storage.data.videoCall = true;
|
||||
});
|
||||
|
||||
$rootScope.$on('call.hangup', function(event, data) {
|
||||
if (Fullscreen.isEnabled()) {
|
||||
Fullscreen.cancel();
|
||||
}
|
||||
|
||||
|
||||
console.log($scope.chatStatus);
|
||||
if (!$scope.chatStatus) {
|
||||
angular.element('#wrapper').toggleClass('toggled');
|
||||
$scope.chatStatus = angular.element('#wrapper').hasClass('toggled');
|
||||
}
|
||||
|
||||
$rootScope.dialpadNumber = '';
|
||||
console.debug('Redirecting to dialpad page.');
|
||||
$location.path('/dialpad');
|
||||
|
||||
try {
|
||||
$rootScope.$digest();
|
||||
} catch (e) {
|
||||
console.log('not digest');
|
||||
}
|
||||
});
|
||||
|
||||
$rootScope.$on('page.incall', function(event, data) {
|
||||
if (storage.data.askRecoverCall) {
|
||||
prompt({
|
||||
title: 'Oops, Active Call in Course.',
|
||||
message: 'It seems you were in a call before leaving the last time. Wanna go back to that?'
|
||||
}).then(function() {
|
||||
verto.changeData(storage);
|
||||
console.log('redirect to incall page');
|
||||
$location.path('/incall');
|
||||
}, function() {
|
||||
storage.data.userStatus = 'connecting';
|
||||
verto.hangup();
|
||||
});
|
||||
} else {
|
||||
verto.changeData(storage);
|
||||
console.log('redirect to incall page');
|
||||
$location.path('/incall');
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
$rootScope.callActive = function(data) {
|
||||
verto.data.mutedMic = storage.data.mutedMic;
|
||||
verto.data.mutedVideo = storage.data.mutedVideo;
|
||||
|
||||
if (!storage.data.cur_call) {
|
||||
storage.data.call_start = new Date();
|
||||
}
|
||||
storage.data.userStatus = 'connected';
|
||||
var call_start = new Date(storage.data.call_start);
|
||||
$rootScope.start_time = call_start;
|
||||
|
||||
$timeout(function() {
|
||||
$scope.$broadcast('timer-start');
|
||||
});
|
||||
myVideo.play();
|
||||
storage.data.calling = false;
|
||||
|
||||
storage.data.cur_call = 1;
|
||||
};
|
||||
|
||||
$rootScope.$on('call.active', function(event, data) {
|
||||
$rootScope.callActive(data);
|
||||
});
|
||||
|
||||
$rootScope.$on('call.calling', function(event, data) {
|
||||
storage.data.calling = true;
|
||||
});
|
||||
|
||||
$rootScope.$on('call.incoming', function(event, data) {
|
||||
console.log('Incoming call from: ' + data);
|
||||
|
||||
storage.data.cur_call = 0;
|
||||
$scope.incomingCall = true;
|
||||
storage.data.videoCall = false;
|
||||
storage.data.mutedVideo = false;
|
||||
storage.data.mutedMic = false;
|
||||
|
||||
prompt({
|
||||
title: 'Incoming Call',
|
||||
message: 'from ' + data
|
||||
}).then(function() {
|
||||
var call_start = new Date(storage.data.call_start);
|
||||
$rootScope.start_time = call_start;
|
||||
console.log($rootScope.start_time);
|
||||
|
||||
$scope.answerCall();
|
||||
storage.data.called_number = data;
|
||||
|
||||
storage.data.call_history.unshift({
|
||||
'number': data,
|
||||
'direction': 'inbound',
|
||||
'status': true,
|
||||
'call_start': Date()
|
||||
});
|
||||
$location.path('/incall');
|
||||
}, function() {
|
||||
$scope.declineCall();
|
||||
storage.data.call_history.unshift({
|
||||
'number': data,
|
||||
'direction': 'inbound',
|
||||
'status': false,
|
||||
'call_start': Date()
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
$scope.hold = function() {
|
||||
storage.data.onHold = !storage.data.onHold;
|
||||
verto.data.call.toggleHold();
|
||||
};
|
||||
|
||||
/**
|
||||
* Hangup the current call.
|
||||
*/
|
||||
$scope.hangup = function() {
|
||||
if (!verto.data.call) {
|
||||
toastr.warning('There is no call to hangup.');
|
||||
$location.path('/dialpad');
|
||||
}
|
||||
|
||||
//var hangupCallback = function(v, hangup) {
|
||||
// if (hangup) {
|
||||
// $location.path('/dialpad');
|
||||
// } else {
|
||||
// console.debug('The call could not be hangup.');
|
||||
// }
|
||||
//};
|
||||
//
|
||||
//verto.hangup(hangupCallback);
|
||||
|
||||
verto.hangup();
|
||||
};
|
||||
|
||||
$scope.answerCall = function() {
|
||||
storage.data.onHold = false;
|
||||
|
||||
verto.data.call.answer({
|
||||
useStereo: verto.data.useStereo,
|
||||
useCamera: verto.data.useCamera,
|
||||
useMic: verto.data.useMic,
|
||||
callee_id_name: verto.data.name,
|
||||
callee_id_number: verto.data.login
|
||||
});
|
||||
|
||||
|
||||
$location.path('/incall');
|
||||
};
|
||||
|
||||
$scope.declineCall = function() {
|
||||
$scope.hangup();
|
||||
$scope.incomingCall = false;
|
||||
};
|
||||
|
||||
$scope.screenshare = function() {
|
||||
if (verto.data.shareCall) {
|
||||
verto.screenshareHangup();
|
||||
return false;
|
||||
}
|
||||
verto.screenshare(storage.data.called_number);
|
||||
};
|
||||
|
||||
$scope.play = function() {
|
||||
var file = $scope.promptInput('Please, enter filename', '', 'File',
|
||||
function(file) {
|
||||
verto.data.conf.play(file);
|
||||
console.log('play file :', file);
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
$scope.stop = function() {
|
||||
verto.data.conf.stop();
|
||||
};
|
||||
|
||||
$scope.record = function() {
|
||||
var file = $scope.promptInput('Please, enter filename', '', 'File',
|
||||
function(file) {
|
||||
verto.data.conf.record(file);
|
||||
console.log('recording file :', file);
|
||||
});
|
||||
};
|
||||
|
||||
$scope.stopRecord = function() {
|
||||
verto.data.conf.stopRecord();
|
||||
};
|
||||
|
||||
$scope.snapshot = function() {
|
||||
var file = $scope.promptInput('Please, enter filename', '', 'File',
|
||||
function(file) {
|
||||
verto.data.conf.snapshot(file);
|
||||
console.log('snapshot file :', file);
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
);
|
||||
|
||||
})();
|
||||
@@ -0,0 +1,13 @@
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
angular
|
||||
.module('vertoControllers')
|
||||
.controller('MenuController', ['$scope', '$http', '$location',
|
||||
'verto', 'storage',
|
||||
function($scope, $http, $location, verto, storage) {
|
||||
console.debug('Executing MenuController.');
|
||||
}
|
||||
]);
|
||||
|
||||
})();
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
angular
|
||||
.module('vertoControllers')
|
||||
.controller('ModalDialpadController', ['$scope',
|
||||
'$modalInstance',
|
||||
function($scope, $modalInstance) {
|
||||
|
||||
$scope.ok = function() {
|
||||
$modalInstance.close('Ok.');
|
||||
};
|
||||
|
||||
$scope.cancel = function() {
|
||||
$modalInstance.dismiss('cancel');
|
||||
};
|
||||
|
||||
}
|
||||
]);
|
||||
})();
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
angular
|
||||
.module('vertoControllers')
|
||||
.controller('ModalLoginInformationController', ['$scope',
|
||||
'$http', '$location', '$modalInstance', 'verto', 'storage',
|
||||
function($scope, $http, $location, $modalInstance, verto, storage) {
|
||||
console.debug('Executing ModalLoginInformationController.');
|
||||
|
||||
$scope.verto = verto;
|
||||
$scope.storage = storage;
|
||||
|
||||
$scope.ok = function() {
|
||||
$modalInstance.close('Ok.');
|
||||
};
|
||||
|
||||
$scope.cancel = function() {
|
||||
$modalInstance.dismiss('cancel');
|
||||
};
|
||||
|
||||
}
|
||||
]);
|
||||
|
||||
})();
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
angular
|
||||
.module('vertoControllers')
|
||||
.controller('ModalSettingsController', ['$scope', '$http',
|
||||
'$location', '$modalInstance', 'verto', 'storage',
|
||||
function($scope, $http, $location, $modalInstance, verto, storage) {
|
||||
console.debug('Executing ModalSettingsController.');
|
||||
|
||||
verto.changeData(storage);
|
||||
$scope.verto = verto;
|
||||
$scope.storage = storage;
|
||||
|
||||
$scope.ok = function() {
|
||||
storage.changeData(verto);
|
||||
$modalInstance.close('Ok.');
|
||||
};
|
||||
|
||||
$scope.cancel = function() {
|
||||
$modalInstance.dismiss('cancel');
|
||||
};
|
||||
|
||||
$scope.refreshDeviceList = function() {
|
||||
return verto.refreshDevices();
|
||||
}
|
||||
}
|
||||
]);
|
||||
|
||||
})();
|
||||
@@ -0,0 +1,11 @@
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
var vertoControllers = angular.module('vertoControllers', [
|
||||
'ui.bootstrap',
|
||||
'vertoService',
|
||||
'storageService',
|
||||
'ui.gravatar'
|
||||
]);
|
||||
|
||||
})();
|
||||
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
Sometimes autofocus HTML5 directive just isn't enough with SPAs.
|
||||
This directive will force autofocus to work properly under those circumstances.
|
||||
*/
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
angular
|
||||
.module('vertoDirectives')
|
||||
.directive('autofocus', ['$timeout',
|
||||
function ($timeout) {
|
||||
return {
|
||||
restrict: 'A',
|
||||
link: function ($scope, $element) {
|
||||
$timeout(function () {
|
||||
$element[0].focus();
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
]);
|
||||
})();
|
||||
@@ -0,0 +1,37 @@
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
angular
|
||||
.module('vertoDirectives')
|
||||
.directive('showControls',
|
||||
function(Fullscreen) {
|
||||
var link = function(scope, element, attrs) {
|
||||
var i = null;
|
||||
jQuery('.video-footer').fadeIn('slow');
|
||||
jQuery('.video-hover-buttons').fadeIn('slow');
|
||||
element.parent().bind('mousemove', function() {
|
||||
if (Fullscreen.isEnabled()) {
|
||||
clearTimeout(i);
|
||||
jQuery('.video-footer').fadeIn('slow');
|
||||
jQuery('.video-hover-buttons').fadeIn(500);
|
||||
i = setTimeout(function() {
|
||||
if (Fullscreen.isEnabled()) {
|
||||
jQuery('.video-footer').fadeOut('slow');
|
||||
jQuery('.video-hover-buttons').fadeOut(500);
|
||||
}
|
||||
}, 3000);
|
||||
}
|
||||
});
|
||||
element.parent().bind('mouseleave', function() {
|
||||
jQuery('.video-footer').fadeIn();
|
||||
jQuery('.video-hover-buttons').fadeIn();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
return {
|
||||
link: link
|
||||
};
|
||||
});
|
||||
|
||||
})();
|
||||
@@ -0,0 +1,27 @@
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
angular
|
||||
.module('vertoDirectives').directive('userStatus',
|
||||
function() {
|
||||
var link = function(scope, element, attrs) {
|
||||
scope.$watch('condition', function(condition) {
|
||||
element.removeClass('connected');
|
||||
element.removeClass('disconnected');
|
||||
element.removeClass('connecting');
|
||||
|
||||
element.addClass(condition);
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
scope: {
|
||||
'condition': '='
|
||||
},
|
||||
link: link
|
||||
};
|
||||
|
||||
});
|
||||
|
||||
})();
|
||||
@@ -0,0 +1,35 @@
|
||||
/**
|
||||
* To RTC work properly we need to give a <video> tag as soon as possible
|
||||
* because it needs to attach the video and audio stream to the tag.
|
||||
*
|
||||
* This directive is responsible for moving the video tag from the body to
|
||||
* the right place when a call start and move back to the body when the
|
||||
* call ends. It also hides and display the tag when its convenient.
|
||||
*/
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
angular
|
||||
.module('vertoDirectives')
|
||||
.directive('videoTag',
|
||||
function() {
|
||||
function link(scope, element, attrs) {
|
||||
// Moving the video tag to the new place inside the incall page.
|
||||
console.log('Moving the video to element.');
|
||||
jQuery('video').removeClass('hide').appendTo(element);
|
||||
jQuery('video').css('display', 'block');
|
||||
scope.callActive();
|
||||
|
||||
element.on('$destroy', function() {
|
||||
// Move the video back to the body.
|
||||
console.log('Moving the video back to body.');
|
||||
jQuery('video').addClass('hide').appendTo(jQuery('body'));
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
link: link
|
||||
}
|
||||
});
|
||||
|
||||
})();
|
||||
@@ -0,0 +1,4 @@
|
||||
(function() {
|
||||
'use strict';
|
||||
var vertoDirectives = angular.module('vertoDirectives', []);
|
||||
})();
|
||||
+1
-9
@@ -170,10 +170,6 @@ vertoService.service('verto', ['$rootScope', '$cookieStore', '$location', 'stora
|
||||
$rootScope.$emit('call.incoming', number);
|
||||
}
|
||||
|
||||
function recoveringCall() {
|
||||
$rootScope.$emit('call.recovering');
|
||||
}
|
||||
|
||||
function getVideoParams() {
|
||||
var maxWidth, maxHeight;
|
||||
|
||||
@@ -348,7 +344,7 @@ vertoService.service('verto', ['$rootScope', '$cookieStore', '$location', 'stora
|
||||
|
||||
videoQuality.length = videoQuality.length - removed;
|
||||
this.videoQuality = videoQuality;
|
||||
this.data.vidQual = videoQuality[videoQuality.length - 1].id;
|
||||
this.data.vidQual = (videoQuality.length > 0) ? videoQuality[videoQuality.length - 1].id : null;
|
||||
|
||||
return videoQuality;
|
||||
},
|
||||
@@ -504,10 +500,6 @@ vertoService.service('verto', ['$rootScope', '$cookieStore', '$location', 'stora
|
||||
data.callState = 'active';
|
||||
calling();
|
||||
break;
|
||||
case "recovering":
|
||||
console.debug('We are recovering a call!');
|
||||
recoveringCall();
|
||||
break;
|
||||
case "active":
|
||||
console.debug('Talking to:', d.cidString());
|
||||
data.callState = 'active';
|
||||
@@ -0,0 +1,4 @@
|
||||
(function() {
|
||||
'use strict';
|
||||
var vertoService = angular.module('vertoService', []);
|
||||
})();
|
||||
Reference in new issue
Block a user