Don't flash "socket connection lost" on every unload in Firefox.

This commit is contained in:
Simo Kinnunen
2014-12-03 13:34:35 +09:00
parent c4bb2e33b7
commit 470d676c31

View File

@@ -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('<h4>WebSocket</h4>' + $filter('translate')(
gettext('Connected successfully.')) +
'<refresh-page></refresh-page>', {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('<h4>WebSocket</h4>' + $filter('translate')(
gettext('Reconnected successfully.')), {ttl: -1})
break;
}
function setState(state) {
switch (state) {
case 'connect':
if (hasFailedOnce) {
growl.success('<h4>WebSocket</h4>' + $filter('translate')(
gettext('Connected successfully.')) +
'<refresh-page></refresh-page>', {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('<h4>WebSocket</h4>' + $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)
})
}
}