2014-06-23 16:47:08 +00:00
define [ ] , () ->
2015-10-14 13:15:33 +00:00
ONEHOUR = 1000 * 60 * 60
2014-06-23 16:47:08 +00:00
class ConnectionManager
2015-10-14 13:15:33 +00:00
2015-10-15 10:38:23 +00:00
disconnectAfterMs: ONEHOUR * 24
2015-10-14 13:15:33 +00:00
lastUserAction : new Date ( )
2014-06-23 16:47:08 +00:00
constructor: (@ide, @$scope) ->
2015-03-09 13:57:13 +00:00
if ! io ?
console . error " Socket.io javascript not loaded. Please check that the real-time service is running and accessible. "
@ide.socket =
on : () ->
$scope . $apply () =>
@$scope.state.error = " Could not connect to websocket server :( "
return
2014-06-24 15:33:36 +00:00
2015-10-14 13:15:33 +00:00
setInterval ( () =>
@ disconnectIfInactive ( )
, ONEHOUR )
2015-10-14 15:25:48 +00:00
@userIsLeavingPage = false
window . addEventListener ' beforeunload ' , =>
@userIsLeavingPage = true
2015-11-05 10:18:40 +00:00
return # Don't return true or it will show a pop up
2015-10-14 15:25:48 +00:00
2015-10-14 13:15:33 +00:00
@connected = false
@userIsInactive = false
2014-06-24 15:33:36 +00:00
@$scope.connection =
reconnecting: false
# If we need to force everyone to reload the editor
forced_disconnect: false
2015-10-14 13:15:33 +00:00
inactive_disconnect: false
2014-06-24 15:33:36 +00:00
@$scope.tryReconnectNow = () =>
@ tryReconnect ( )
2015-09-29 09:23:21 +00:00
@ $scope . $on ' cursor:editor:update ' , () =>
2015-10-14 13:15:33 +00:00
@lastUserAction = new Date ( )
2015-09-28 14:45:14 +00:00
if ! @ connected
2015-09-28 15:18:09 +00:00
@ tryReconnect ( )
2015-09-29 09:23:21 +00:00
document . querySelector ( ' body ' ) . addEventListener ' click ' , (e) =>
if ! @ connected and e . target . id != ' try-reconnect-now-button '
2015-09-28 14:45:14 +00:00
@ tryReconnect ( )
2014-07-09 19:32:03 +00:00
2015-03-20 19:08:35 +00:00
@ide.socket = io . connect null ,
2014-06-23 16:47:08 +00:00
reconnect: false
2015-10-04 23:43:37 +00:00
' connect timeout ' : 30 * 1000
2014-06-23 16:47:08 +00:00
" force new connection " : true
@ ide . socket . on " connect " , () =>
2014-06-24 15:33:36 +00:00
@connected = true
@ ide . pushEvent ( " connected " )
2014-06-23 16:47:08 +00:00
@ $scope . $apply () =>
2014-06-24 15:33:36 +00:00
@$scope.connection.reconnecting = false
2015-10-14 13:15:33 +00:00
@$scope.connection.inactive_disconnect = false
2014-06-24 15:33:36 +00:00
if @ $scope . state . loading
2014-07-10 12:41:54 +00:00
@$scope.state.load_progress = 70
2014-06-24 15:33:36 +00:00
setTimeout ( () =>
@ joinProject ( )
, 100 )
2015-07-31 14:42:47 +00:00
@ ide . socket . on " connect_failed " , () =>
@connected = false
$scope . $apply () =>
2015-10-04 23:43:37 +00:00
@$scope.state.error = " Unable to connect, please view the <u><a href= ' http://sharelatex.tenderapp.com/help/kb/latex-editor/editor-connection-problems ' >connection problems guide</a></u> to fix the issue. "
2015-07-31 14:42:47 +00:00
2014-06-24 15:33:36 +00:00
@ ide . socket . on ' disconnect ' , () =>
@connected = false
@ ide . pushEvent ( " disconnected " )
@ $scope . $apply () =>
@$scope.connection.reconnecting = false
2015-10-14 13:15:33 +00:00
if ! $scope . connection . forced_disconnect and ! @ userIsInactive
2014-06-24 15:33:36 +00:00
@ startAutoReconnectCountdown ( )
2014-06-23 16:47:08 +00:00
2014-06-24 15:33:36 +00:00
@ ide . socket . on ' forceDisconnect ' , (message) =>
@ $scope . $apply () =>
2014-07-24 14:59:24 +00:00
@$scope.permissions.write = false
2014-06-24 15:33:36 +00:00
@$scope.connection.forced_disconnect = true
2014-07-24 15:39:32 +00:00
@ ide . socket . disconnect ( )
2014-07-24 14:59:24 +00:00
@ ide . showGenericMessageModal ( " Please Refresh " , """
We ' re performing maintenance on ShareLaTeX and you need to refresh the editor.
Sorry for any inconvenience .
The editor will refresh in automatically in 10 seconds .
""" )
setTimeout () ->
location . reload ( )
, 10 * 1000
2014-06-24 15:33:36 +00:00
joinProject: () ->
@ ide . socket . emit ' joinProject ' , {
project_id: @ ide . project_id
} , (err, project, permissionsLevel, protocolVersion) =>
if @ $scope . protocolVersion ? and @ $scope . protocolVersion != protocolVersion
location . reload ( true )
2014-06-23 16:47:08 +00:00
2014-06-24 15:33:36 +00:00
@ $scope . $apply () =>
@$scope.protocolVersion = protocolVersion
@$scope.project = project
2014-07-03 14:05:35 +00:00
@$scope.permissionsLevel = permissionsLevel
2014-06-24 15:33:36 +00:00
@$scope.state.load_progress = 100
@$scope.state.loading = false
2014-07-08 09:08:38 +00:00
@ $scope . $broadcast " project:joined "
2014-06-24 14:31:44 +00:00
reconnectImmediately: () ->
@ disconnect ( )
2014-06-24 15:33:36 +00:00
@ tryReconnect ( )
2014-06-24 14:31:44 +00:00
disconnect: () ->
2014-06-24 15:33:36 +00:00
@ ide . socket . disconnect ( )
startAutoReconnectCountdown: () ->
2014-06-24 15:56:31 +00:00
twoMinutes = 2 * 60 * 1000
2014-07-09 19:32:03 +00:00
if @ lastUpdated ? and new Date ( ) - @ lastUpdated > twoMinutes
2014-06-24 15:56:31 +00:00
# between 1 minute and 3 minutes
countdown = 60 + Math . floor ( Math . random ( ) * 120 )
else
countdown = 3 + Math . floor ( Math . random ( ) * 7 )
2015-10-14 15:25:48 +00:00
if @ userIsLeavingPage #user will have pressed refresh or back etc
return
2014-06-24 15:33:36 +00:00
@ $scope . $apply () =>
2014-07-02 15:41:29 +00:00
@$scope.connection.reconnecting = false
2014-06-24 15:56:31 +00:00
@$scope.connection.reconnection_countdown = countdown
2014-06-24 15:33:36 +00:00
setTimeout ( =>
if ! @ connected
@timeoutId = setTimeout ( => @ decreaseCountdown ( ) ) , 1000
, 200 )
cancelReconnect: () ->
clearTimeout @ timeoutId if @ timeoutId ?
decreaseCountdown: () ->
2014-06-24 16:44:46 +00:00
return if ! @ $scope . connection . reconnection_countdown ?
2014-06-24 15:33:36 +00:00
@ $scope . $apply () =>
@ $scope . connection . reconnection_countdown - -
if @ $scope . connection . reconnection_countdown <= 0
@ $scope . $apply () =>
@ tryReconnect ( )
else
@timeoutId = setTimeout ( => @ decreaseCountdown ( ) ) , 1000
tryReconnect: () ->
@ cancelReconnect ( )
2014-07-17 12:46:14 +00:00
delete @ $scope . connection . reconnection_countdown
2014-07-17 12:44:50 +00:00
return if @ connected
2014-06-24 15:33:36 +00:00
@$scope.connection.reconnecting = true
@ ide . socket . socket . reconnect ( )
2014-06-24 16:44:46 +00:00
setTimeout ( => @ startAutoReconnectCountdown ( ) if ! @ connected ) , 2000
2014-06-24 15:33:36 +00:00
2015-10-14 13:15:33 +00:00
disconnectIfInactive: ()->
2015-10-15 10:38:23 +00:00
@userIsInactive = ( new Date ( ) - @ lastUserAction ) > @ disconnectAfterMs
2015-10-14 13:15:33 +00:00
if @ userIsInactive and @ connected
@ disconnect ( )
@ $scope . $apply () =>
@$scope.connection.inactive_disconnect = true