611 lines
18 KiB
JavaScript
611 lines
18 KiB
JavaScript
(function() {
|
|
'use strict';
|
|
|
|
angular
|
|
.module('vertoControllers')
|
|
.controller('MainController',
|
|
function($scope, $rootScope, $location, $modal, $timeout, $q, verto, storage, CallHistory, toastr, Fullscreen, prompt, eventQueue, $translate, $window) {
|
|
|
|
console.debug('Executing MainController.');
|
|
$rootScope.dtmfHistory = { value: '' };
|
|
$rootScope.onKeydownDtmfEnabled = true;
|
|
|
|
$.verto.haltClosure = function() {
|
|
if (verto.data.callState == 'active') {
|
|
return true;
|
|
}
|
|
};
|
|
|
|
if (storage.data.language && storage.data.language !== 'browser') {
|
|
$translate.use(storage.data.language);
|
|
} else {
|
|
storage.data.language = 'browser';
|
|
}
|
|
|
|
$rootScope.master = $location.search().master;
|
|
if ($location.search().watcher === 'true') {
|
|
$rootScope.watcher = true;
|
|
angular.element(document.body).addClass('watcher');
|
|
var dialpad;
|
|
var extension = dialpad = $location.search().extension;
|
|
var canvasID = $location.search().canvas_id;
|
|
|
|
if (dialpad) {
|
|
if (canvasID) {
|
|
dialpad += '-canvas-' + canvasID;
|
|
}
|
|
$rootScope.extension = extension;
|
|
$rootScope.canvasID = canvasID;
|
|
$location.search().autocall = dialpad;
|
|
}
|
|
}
|
|
|
|
var myVideo = document.getElementById("webcam");
|
|
$scope.verto = verto;
|
|
$scope.storage = storage;
|
|
$scope.call_history = angular.element("#call_history").hasClass('active');
|
|
$rootScope.chatStatus = angular.element('#wrapper').hasClass('toggled');
|
|
$scope.showReconnectModal = true;
|
|
/**
|
|
* (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 verto is not connected, redirects to login page.
|
|
if (!verto.data.connected) {
|
|
console.debug('MainController: WebSocket not connected. Redirecting to login.');
|
|
$location.path('/');
|
|
}
|
|
|
|
$rootScope.$on('config.http.success', function(ev) {
|
|
$scope.login(false);
|
|
});
|
|
|
|
$rootScope.$on('changedSpeaker', function(event, speakerId) {
|
|
if (verto.data.call) {
|
|
verto.data.call.setAudioPlaybackDevice(speakerId, sinkIdCallback);
|
|
}
|
|
});
|
|
|
|
/**
|
|
* Login the user to verto server and
|
|
* redirects him to dialpad page.
|
|
*/
|
|
$rootScope.login = function(redirect, skipPreview) {
|
|
if(redirect == undefined) {
|
|
redirect = true;
|
|
}
|
|
|
|
if(skipPreview == undefined) {
|
|
skipPreview = false;
|
|
}
|
|
|
|
var connectCallback = function(v, connected) {
|
|
$scope.$apply(function() {
|
|
verto.data.connecting = false;
|
|
if (connected) {
|
|
storage.data.hostname = verto.data.hostname;
|
|
storage.data.wsURL = verto.data.wsURL;
|
|
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;
|
|
if (storage.data.autoBand) {
|
|
verto.testSpeed();
|
|
}
|
|
|
|
if (redirect && storage.data.preview && !skipPreview) {
|
|
$location.path('/loading');
|
|
} else if (redirect) {
|
|
$location.path('/dialpad');
|
|
}
|
|
}
|
|
});
|
|
};
|
|
|
|
verto.data.connecting = true;
|
|
verto.connect(connectCallback);
|
|
};
|
|
|
|
/**
|
|
* Logout the user from verto server and
|
|
* redirects him to login page.
|
|
*/
|
|
$rootScope.logout = function() {
|
|
var disconnect = function() {
|
|
var disconnectCallback = function(v, connected) {
|
|
console.debug('Redirecting to login page.');
|
|
storage.reset();
|
|
if (typeof gapi !== 'undefined'){
|
|
console.debug(gapi);
|
|
gapi.auth.signOut();
|
|
}
|
|
$location.path('/login');
|
|
};
|
|
|
|
if (verto.data.call) {
|
|
verto.hangup();
|
|
}
|
|
|
|
$scope.closeChat();
|
|
$scope.showReconnectModal = false;
|
|
verto.disconnect(disconnectCallback);
|
|
|
|
verto.hangup();
|
|
};
|
|
|
|
if (verto.data.call) {
|
|
prompt({
|
|
title: $translate.instant('TITLE_ACTIVE_CALL'),
|
|
message: $translate.instant('MESSAGE_ACTIVE_CALL_HANGUP')
|
|
}).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();
|
|
}
|
|
);
|
|
};
|
|
|
|
$rootScope.openModal = function(templateUrl, controller, _options) {
|
|
var options = {
|
|
animation: $scope.animationsEnabled,
|
|
templateUrl: templateUrl,
|
|
controller: controller,
|
|
};
|
|
|
|
angular.extend(options, _options);
|
|
|
|
var modalInstance = $modal.open(options);
|
|
|
|
modalInstance.result.then(
|
|
function(result) {
|
|
console.log(result);
|
|
},
|
|
function() {
|
|
console.info('Modal dismissed at: ' + new Date());
|
|
}
|
|
);
|
|
|
|
modalInstance.rendered.then(
|
|
function() {
|
|
jQuery.material.init();
|
|
}
|
|
);
|
|
|
|
return modalInstance;
|
|
};
|
|
|
|
$rootScope.$on('ws.close', onWSClose);
|
|
$rootScope.$on('ws.login', onWSLogin);
|
|
|
|
$rootScope.ws_modalInstance;
|
|
|
|
function onWSClose(ev, data) {
|
|
if($rootScope.ws_modalInstance) {
|
|
return;
|
|
};
|
|
var options = {
|
|
backdrop: 'static',
|
|
keyboard: false
|
|
};
|
|
if ($scope.showReconnectModal) {
|
|
$rootScope.ws_modalInstance = $scope.openModal('partials/ws_reconnect.html', 'ModalWsReconnectController', options);
|
|
};
|
|
};
|
|
|
|
function onWSLogin(ev, data) {
|
|
if(storage.data.autoBand) {
|
|
verto.testSpeed();
|
|
}
|
|
if(!$rootScope.ws_modalInstance) {
|
|
return;
|
|
};
|
|
|
|
$rootScope.ws_modalInstance.close();
|
|
$rootScope.ws_modalInstance = null;
|
|
};
|
|
|
|
$scope.showAbout = function() {
|
|
$scope.openModal('partials/about.html', 'AboutController');
|
|
};
|
|
|
|
$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) {
|
|
console.log('dtmf', number);
|
|
$rootScope.dialpadNumber = $rootScope.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.toggleChat = function() {
|
|
if ($rootScope.chatStatus && $rootScope.activePane === 'chat') {
|
|
$rootScope.chat_counter = 0;
|
|
}
|
|
angular.element('#wrapper').toggleClass('toggled');
|
|
$rootScope.chatStatus = angular.element('#wrapper').hasClass('toggled');
|
|
updateVideoSize();
|
|
};
|
|
|
|
$rootScope.openChat = function() {
|
|
$rootScope.chatStatus = false;
|
|
angular.element('#wrapper').removeClass('toggled');
|
|
};
|
|
|
|
$scope.closeChat = function() {
|
|
$rootScope.chatStatus = true;
|
|
angular.element('#wrapper').addClass('toggled');
|
|
};
|
|
|
|
$scope.toggleSettings = function() {
|
|
var settingsEl = angular.element(document.querySelector('#settings'));
|
|
settingsEl.toggleClass('toggled');
|
|
$rootScope.$emit('toggledSettings', settingsEl.hasClass('toggled'));
|
|
};
|
|
|
|
$scope.closeSettings = function() {
|
|
var settingsEl = angular.element(document.querySelector('#settings'));
|
|
if (settingsEl.hasClass('toggled')) {
|
|
settingsEl.removeClass('toggled');
|
|
$rootScope.$emit('toggledSettings', settingsEl.hasClass('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();
|
|
}
|
|
|
|
if (!$rootScope.chatStatus) {
|
|
angular.element('#wrapper').toggleClass('toggled');
|
|
$rootScope.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) {
|
|
var page_incall = function() {
|
|
return $q(function(resolve, reject) {
|
|
if (storage.data.askRecoverCall) {
|
|
prompt({
|
|
title: $translate.instant('TITLE_ACTIVE_CALL'),
|
|
message: $translate.instant('MESSAGE_ACTIVE_CALL_BACK')
|
|
}).then(function() {
|
|
console.log('redirect to incall page');
|
|
$location.path('/incall');
|
|
}, function() {
|
|
storage.data.userStatus = 'connecting';
|
|
verto.hangup();
|
|
});
|
|
} else {
|
|
console.log('redirect to incall page');
|
|
$location.path('/incall');
|
|
}
|
|
resolve();
|
|
});
|
|
};
|
|
eventQueue.events.push(page_incall);
|
|
});
|
|
|
|
$scope.$on('event:google-plus-signin-success', function (event,authResult) {
|
|
// Send login to server or save into cookie
|
|
console.log('Google+ Login Success');
|
|
console.log(authResult);
|
|
gapi.client.load('plus', 'v1', gapiClientLoaded);
|
|
});
|
|
|
|
function gapiClientLoaded() {
|
|
gapi.client.plus.people.get({userId: 'me'}).execute(handleEmailResponse);
|
|
}
|
|
|
|
function handleEmailResponse(resp){
|
|
var primaryEmail;
|
|
for (var i=0; i < resp.emails.length; i++) {
|
|
if (resp.emails[i].type === 'account') primaryEmail = resp.emails[i].value;
|
|
}
|
|
console.debug("Primary Email: " + primaryEmail );
|
|
console.debug("display name: " + resp.displayName);
|
|
console.debug("imageurl: " + resp.image.url);
|
|
console.debug(resp);
|
|
console.debug(verto.data);
|
|
verto.data.email = primaryEmail;
|
|
verto.data.name = resp.displayName;
|
|
storage.data.name = verto.data.name;
|
|
storage.data.email = verto.data.email;
|
|
|
|
$scope.login();
|
|
}
|
|
|
|
$scope.$on('event:google-plus-signin-failure', function (event,authResult) {
|
|
// Auth failure or signout detected
|
|
console.log('Google+ Login Failure');
|
|
});
|
|
|
|
$rootScope.callActive = function(data, params) {
|
|
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;
|
|
|
|
$location.path('/incall');
|
|
|
|
if(params.useVideo) {
|
|
$rootScope.$emit('call.video', 'video');
|
|
}
|
|
};
|
|
|
|
$rootScope.$on('call.active', function(event, data, params) {
|
|
$rootScope.callActive(data, params);
|
|
});
|
|
|
|
$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: $translate.instant('TITLE_INCOMING_CALL'),
|
|
message: $translate.instant('MESSAGE_INCOMING_CALL') + 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;
|
|
CallHistory.add(data, 'inbound', true);
|
|
$location.path('/incall');
|
|
}, function() {
|
|
$scope.declineCall();
|
|
CallHistory.add(data, 'inbound', false);
|
|
});
|
|
});
|
|
|
|
$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($translate.instant('MESSAGE_NO_HANGUP_CALL'));
|
|
$location.path('/dialpad');
|
|
return;
|
|
}
|
|
|
|
if ($rootScope.watcher) {
|
|
window.close();
|
|
return;
|
|
}
|
|
|
|
//var hangupCallback = function(v, hangup) {
|
|
// if (hangup) {
|
|
// $location.path('/dialpad');
|
|
// } else {
|
|
// console.debug('The call could not be hangup.');
|
|
// }
|
|
//};
|
|
//
|
|
//verto.hangup(hangupCallback);
|
|
if (verto.data.shareCall) {
|
|
verto.screenshareHangup();
|
|
}
|
|
|
|
verto.hangup();
|
|
|
|
$rootScope.$emit('hangupCall');
|
|
$location.path('/dialpad');
|
|
};
|
|
|
|
$scope.answerCall = function() {
|
|
storage.data.onHold = false;
|
|
|
|
verto.data.call.answer({
|
|
useStereo: storage.data.useStereo,
|
|
useCamera: storage.data.selectedVideo,
|
|
useVideo: storage.data.useVideo,
|
|
useMic: storage.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.play = function() {
|
|
var file = $scope.promptInput($translate.instant('MESSAGE_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($translate.instant('MESSAGE_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($translate.instant('MESSAGE_ENTER_FILENAME'), '', 'File',
|
|
function(file) {
|
|
verto.data.conf.snapshot(file);
|
|
console.log('snapshot file :', file);
|
|
});
|
|
};
|
|
|
|
function sinkIdCallback(success, deviceName) {
|
|
if (success) {
|
|
toastr.info('Speaker is now <span class="install">' + deviceName + '</a>', 'Success', { allowHtml: true });
|
|
} else {
|
|
toastr.error('Your browser doesn\'t seem to support this feature', 'Error');
|
|
}
|
|
}
|
|
|
|
$rootScope.dtmfWidget = function(number) {
|
|
$rootScope.dtmfHistory.value = $rootScope.dtmfHistory.value + number;
|
|
if (verto.data.call) {
|
|
verto.dtmf(number);
|
|
}
|
|
}
|
|
|
|
$rootScope.disableOnKeydownDtmf = function() {
|
|
$rootScope.onKeydownDtmfEnabled = false;
|
|
};
|
|
|
|
$rootScope.enableOnKeydownDtmf = function() {
|
|
$rootScope.onKeydownDtmfEnabled = true;
|
|
};
|
|
|
|
$rootScope.$on("$routeChangeStart", function(event, next, current) {
|
|
if (next.$$route.originalPath === '/incall') {
|
|
$rootScope.dtmfHistory.value = '';
|
|
angular.element($window).bind('keydown', onKeydownDtmfHistory);
|
|
} else {
|
|
angular.element($window).unbind('keydown', onKeydownDtmfHistory);
|
|
}
|
|
});
|
|
|
|
function onKeydownDtmfHistory(event) {
|
|
var caracter = event.key;
|
|
if ($rootScope.onKeydownDtmfEnabled && caracter.match(/^(\*|\#|[0-9a-dA-D])$/g)) {
|
|
$rootScope.dtmfWidget(caracter);
|
|
$scope.$applyAsync();
|
|
}
|
|
}
|
|
|
|
}
|
|
);
|
|
|
|
})();
|