diff --git a/res/app/components/stf/socket/socket-state/socket-state-directive.js b/res/app/components/stf/socket/socket-state/socket-state-directive.js index f5923b09..7715bad6 100644 --- a/res/app/components/stf/socket/socket-state/socket-state-directive.js +++ b/res/app/components/stf/socket/socket-state/socket-state-directive.js @@ -1,91 +1,98 @@ -module.exports = function SocketStateDirectiveFactory(socket, growl, gettext, - $filter, SocketDisconnectedService) { - +module.exports = function SocketStateDirectiveFactory( + socket +, growl +, gettext +, $filter +, SocketDisconnectedService +, $window +) { return { restrict: 'EA', template: require('./socket-state.jade'), link: function (scope) { var hasFailedOnce = false - socket.on('connect', function () { - scope.$apply(function () { - scope.socketState = 'connect' - }) - }) - - // TODO: disable this if we are on a onbeforeunload event - socket.on('disconnect', function () { - scope.$apply(function () { - scope.socketState = 'disconnect' - }) - hasFailedOnce = true - }) - - socket.on('error', function () { - scope.$apply(function () { - scope.socketState = 'error' - }) - hasFailedOnce = true - }) - - socket.on('connect_error', function () { - scope.$apply(function () { - scope.socketState = 'connect_error' - }) - hasFailedOnce = true - }) - - socket.on('reconnect_error', function () { - scope.$apply(function () { - scope.socketState = 'reconnect_error' - }) - hasFailedOnce = true - }) - - socket.on('reconnect_failed', function () { - scope.$apply(function () { - scope.socketState = 'reconnect_failed' - }) - hasFailedOnce = true - }) - - socket.on('reconnect', function () { - scope.$apply(function () { - scope.socketState = 'reconnect' - }) - hasFailedOnce = true - }) - - scope.$watch('socketState', function (newValue) { - if (newValue) { - if (newValue === 'connect') { - if (hasFailedOnce) { - growl.success('

WebSocket

' + $filter('translate')( - gettext('Connected successfully.')) + - '', {ttl: 2000}) - } - } else { - switch (newValue) { - case 'disconnect': - SocketDisconnectedService.open( - gettext('Socket connection was lost')) - break; - case 'connect_error': - case 'error': - SocketDisconnectedService.open( - gettext('Error')) - break; - case 'reconnect_failed': - SocketDisconnectedService.open( - gettext('Error while reconnecting')) - break; - case 'reconnect': - growl.success('

WebSocket

' + $filter('translate')( - gettext('Reconnected successfully.')), {ttl: -1}) - break; - } + function setState(state) { + switch (state) { + case 'connect': + if (hasFailedOnce) { + growl.success('

WebSocket

' + $filter('translate')( + gettext('Connected successfully.')) + + '', {ttl: 2000}) } + break + case 'disconnect': + SocketDisconnectedService.open( + gettext('Socket connection was lost')) + break + case 'connect_error': + case 'error': + SocketDisconnectedService.open( + gettext('Error')) + break + case 'reconnect_failed': + SocketDisconnectedService.open( + gettext('Error while reconnecting')) + break + case 'reconnect': + growl.success('

WebSocket

' + $filter('translate')( + gettext('Reconnected successfully.')), {ttl: -1}) + break } + + scope.$apply(function () { + scope.socketState = state + }) + } + + var socketListeners = { + 'connect': function () { + setState('connect') + } + , 'disconnect': function () { + setState('disconnect') + hasFailedOnce = true + } + , 'error': function () { + setState('error') + hasFailedOnce = true + } + , 'connect_error': function () { + setState('connect_error') + hasFailedOnce = true + } + , 'reconnect_error': function () { + setState('reconnect_error') + hasFailedOnce = true + } + , 'reconnect_failed': function () { + setState('reconnect_failed') + hasFailedOnce = true + } + , 'reconnect': function () { + setState('reconnect') + hasFailedOnce = true + } + } + + Object.keys(socketListeners).forEach(function(event) { + socket.on(event, socketListeners[event]) + }) + + function unloadListener() { + // On at least Firefox, the socket connection will close + // before the page unloads, causing the "socket disconnected" + // message to display on every unload. To prevent that from + // happening, let's unbind all the listeners when it's time. + Object.keys(socketListeners).forEach(function(event) { + socket.removeListener(event, socketListeners[event]) + }) + } + + $window.addEventListener('beforeunload', unloadListener, false) + + scope.$on('$destroy', function() { + $window.removeEventListener('beforeunload', unloadListener, false) }) } }