diff --git a/www/addons/mod_chat/controllers/chat.js b/www/addons/mod_chat/controllers/chat.js index f8e45abf132..5df588d9af2 100644 --- a/www/addons/mod_chat/controllers/chat.js +++ b/www/addons/mod_chat/controllers/chat.js @@ -22,14 +22,15 @@ angular.module('mm.addons.mod_chat') * @name mmaModChatChatCtrl */ .controller('mmaModChatChatCtrl', function($scope, $stateParams, $mmApp, $mmaModChat, $log, $ionicModal, $mmUtil, $ionicHistory, - $ionicScrollDelegate, $timeout, $mmSite, $interval, mmaChatPollInterval) { + $ionicScrollDelegate, $timeout, $mmSite, $interval, mmaChatPollInterval, $q) { $log = $log.getInstance('mmaModChatChatCtrl'); var chatId = $stateParams.chatid, courseId = $stateParams.courseid, title = $stateParams.title, - polling; + chatLastTime = 0, + pollingRunning = false; $scope.loaded = false; $scope.title = title; @@ -42,7 +43,6 @@ angular.module('mm.addons.mod_chat') $scope.newMessage = { text: '' }; - chatLastTime = 0; // Chat users modal. $ionicModal.fromTemplateUrl('addons/mod_chat/templates/users.html', { @@ -87,6 +87,23 @@ angular.module('mm.addons.mod_chat') return !$mmApp.isOnline(); }; + // Convenience function to login the user. + function loginUser() { + return $mmaModChat.loginUser(chatId).then(function(chatsid) { + $scope.chatsid = chatsid; + }); + } + + // Convenience function to get chat messages. + function getMessages() { + return $mmaModChat.getLatestMessages($scope.chatsid, chatLastTime).then(function(messagesInfo) { + chatLastTime = messagesInfo.chatnewlasttime; + return $mmaModChat.getMessagesUserData(messagesInfo.messages, courseId).then(function(messages) { + $scope.messages = $scope.messages.concat(messages); + }); + }); + } + // Show error modal. function showError(error, defaultMessage) { if (typeof error === 'string') { @@ -94,6 +111,45 @@ angular.module('mm.addons.mod_chat') } else { $mmUtil.showErrorModal(defaultMessage, true); } + return $q.reject(); + } + + // Start the polling to get chat messages periodically. + function startPolling() { + // We already have the polling in place. + if ($scope.polling) { + return; + } + + // Start polling. + $scope.polling = $interval(getMessagesInterval, mmaChatPollInterval); + } + + // Convenience function to be called every certain time to get chat messages. + function getMessagesInterval() { + $log.debug('Polling for messages'); + if (!$mmApp.isOnline() || pollingRunning) { + // Obviously we cannot check for new messages when the app is offline. + return $q.reject(); + } + + pollingRunning = true; + + return getMessages().catch(function() { + // Try to login, it might have failed because the session expired. + return loginUser().then(function() { + return getMessages(); + }).catch(function(error) { + // Fail again. Stop polling if needed. + if ($scope.polling) { + $interval.cancel($scope.polling); + $scope.polling = undefined; + } + return showError(error, 'mma.mod_chat.errorwhileretrievingmessages'); + }); + }).finally(function() { + pollingRunning = false; + }); } // Check if the date should be displayed between messages (when the day changes at midnight for example). @@ -123,6 +179,7 @@ angular.module('mm.addons.mod_chat') if (beep === '') { $scope.newMessage.text = ''; } + getMessagesInterval(); // Update messages to show the sent message. }, function(error) { // Only close the keyboard if an error happens, we want the user to be able to send multiple // messages withoutthe keyboard being closed. @@ -132,16 +189,24 @@ angular.module('mm.addons.mod_chat') }); }; + $scope.reconnect = function() { + var modal = $mmUtil.showModalLoading(); + + // Call startPolling would take a while for the first execution, so we'll execute it manually to check if it works now. + return getMessagesInterval().then(function() { + // It works, start the polling again. + startPolling(); + }).finally(function() { + modal.dismiss(); + }); + }; + // Login the user. - $mmaModChat.loginUser(chatId).then(function(chatsid) { - return $mmaModChat.getLatestMessages(chatsid, 0).then(function(messagesInfo) { - $scope.chatsid = chatsid; - chatLastTime = messagesInfo.chatnewlasttime; - return $mmaModChat.getMessagesUserData(messagesInfo.messages, courseId).then(function(messages) { - $scope.messages = $scope.messages.concat(messages); - }); - }).catch(function(message) { - showError(message, 'mma.mod_chat.errorwhileretrievingmessages'); + loginUser().then(function() { + return getMessages().then(function() { + startPolling(); + }).catch(function(error) { + return showError(error, 'mma.mod_chat.errorwhileretrievingmessages'); }); }, function(error) { showError(error, 'mma.mod_chat.errorwhileconnecting'); @@ -161,39 +226,11 @@ angular.module('mm.addons.mod_chat') } }; - // Set up the polling on a view enter, this allows for the user to go back and resume the polling. - $scope.$on('$ionicView.enter', function() { - // Strange case, we already have the polling in place. - if (polling) { - return; - } - - // Start polling. - polling = $interval(function() { - $log.debug('Polling for messages'); - if (!$mmApp.isOnline()) { - // Obviously we cannot check for new messages when the app is offline. - return; - } - - $mmaModChat.getLatestMessages($scope.chatsid, chatLastTime).then(function(data) { - chatLastTime = data.chatnewlasttime; - $mmaModChat.getMessagesUserData(data.messages, courseId).then(function(messages) { - $scope.messages = $scope.messages.concat(messages); - }); - }, function(error) { - $interval.cancel(polling); - showError(error, 'mma.mod_chat.errorwhileretrievingmessages'); - }); - - }, mmaChatPollInterval); - }); - // Removing the polling as we leave the page. - $scope.$on('$ionicView.leave', function(e) { - if (polling) { + $scope.$on('$ionicView.leave', function() { + if ($scope.polling) { $log.debug('Cancelling polling for conversation'); - $interval.cancel(polling); + $interval.cancel($scope.polling); } }); diff --git a/www/addons/mod_chat/scss/styles.scss b/www/addons/mod_chat/scss/styles.scss index f7ad8f4105d..a01de76b909 100644 --- a/www/addons/mod_chat/scss/styles.scss +++ b/www/addons/mod_chat/scss/styles.scss @@ -25,3 +25,11 @@ $mma-chat-notice-badge: "stable" !default; margin: 0; width: 100%; } + +.mma-chat-send-form { + width: 100%; +} + +.mma-chat-reconnect-button, .button.mma-chat-reconnect-button { + margin: 0; +} \ No newline at end of file diff --git a/www/addons/mod_chat/services/chat.js b/www/addons/mod_chat/services/chat.js index 330974b295b..092270a427d 100644 --- a/www/addons/mod_chat/services/chat.js +++ b/www/addons/mod_chat/services/chat.js @@ -164,12 +164,13 @@ angular.module('mm.addons.mod_chat') var params = { chatsid: chatsid, chatlasttime: lasttime - }; - var preSets = { - getFromCache: false + }, preSets = { + emergencyCache: false }; - return $mmSite.read('mod_chat_get_chat_latest_messages', params, preSets); + // We use write to not use cache. It doesn't make sense to store the messages in cache + // because we won't be able to retireve them if $mmaModChat#loginUser fails. + return $mmSite.write('mod_chat_get_chat_latest_messages', params, preSets); }; /** diff --git a/www/addons/mod_chat/templates/chat.html b/www/addons/mod_chat/templates/chat.html index 539f573cc64..038b4688260 100644 --- a/www/addons/mod_chat/templates/chat.html +++ b/www/addons/mod_chat/templates/chat.html @@ -50,7 +50,7 @@