2014-06-23 12:47:08 -04:00
define [ ] , () ->
2015-10-14 09:15:33 -04:00
ONEHOUR = 1000 * 60 * 60
2014-06-23 12:47:08 -04:00
class ConnectionManager
2015-10-14 09:15:33 -04:00
2015-10-15 06:38:23 -04:00
disconnectAfterMs: ONEHOUR * 24
2015-10-14 09:15:33 -04:00
lastUserAction : new Date ( )
2014-06-23 12:47:08 -04:00
constructor: (@ide, @$scope) ->
2015-03-09 09:57:13 -04: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 11:33:36 -04:00
2015-10-14 09:15:33 -04:00
setInterval ( () =>
@ disconnectIfInactive ( )
, ONEHOUR )
2015-10-14 11:25:48 -04:00
@userIsLeavingPage = false
window . addEventListener ' beforeunload ' , =>
@userIsLeavingPage = true
2015-11-05 05:18:40 -05:00
return # Don't return true or it will show a pop up
2015-10-14 11:25:48 -04:00
2015-10-14 09:15:33 -04:00
@connected = false
@userIsInactive = false
2014-06-24 11:33:36 -04:00
@$scope.connection =
reconnecting: false
# If we need to force everyone to reload the editor
forced_disconnect: false
2015-10-14 09:15:33 -04:00
inactive_disconnect: false
2014-06-24 11:33:36 -04:00
@$scope.tryReconnectNow = () =>
@ tryReconnect ( )
2015-09-29 05:23:21 -04:00
@ $scope . $on ' cursor:editor:update ' , () =>
2015-10-14 09:15:33 -04:00
@lastUserAction = new Date ( )
2015-09-28 10:45:14 -04:00
if ! @ connected
2015-09-28 11:18:09 -04:00
@ tryReconnect ( )
2015-09-29 05:23:21 -04:00
document . querySelector ( ' body ' ) . addEventListener ' click ' , (e) =>
if ! @ connected and e . target . id != ' try-reconnect-now-button '
2015-09-28 10:45:14 -04:00
@ tryReconnect ( )
2014-07-09 15:32:03 -04:00
2015-03-20 15:08:35 -04:00
@ide.socket = io . connect null ,
2014-06-23 12:47:08 -04:00
reconnect: false
2015-10-04 19:43:37 -04:00
' connect timeout ' : 30 * 1000
2014-06-23 12:47:08 -04:00
" force new connection " : true
@ ide . socket . on " connect " , () =>
2014-06-24 11:33:36 -04:00
@connected = true
@ ide . pushEvent ( " connected " )
2014-06-23 12:47:08 -04:00
@ $scope . $apply () =>
2014-06-24 11:33:36 -04:00
@$scope.connection.reconnecting = false
2015-10-14 09:15:33 -04:00
@$scope.connection.inactive_disconnect = false
2014-06-24 11:33:36 -04:00
if @ $scope . state . loading
2014-07-10 08:41:54 -04:00
@$scope.state.load_progress = 70
2014-06-24 11:33:36 -04:00
setTimeout ( () =>
@ joinProject ( )
, 100 )
2015-07-31 10:42:47 -04:00
@ ide . socket . on " connect_failed " , () =>
@connected = false
$scope . $apply () =>
2015-10-04 19:43:37 -04: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 10:42:47 -04:00
2014-06-24 11:33:36 -04:00
@ ide . socket . on ' disconnect ' , () =>
@connected = false
@ ide . pushEvent ( " disconnected " )
@ $scope . $apply () =>
@$scope.connection.reconnecting = false
2015-10-14 09:15:33 -04:00
if ! $scope . connection . forced_disconnect and ! @ userIsInactive
2014-06-24 11:33:36 -04:00
@ startAutoReconnectCountdown ( )
2014-06-23 12:47:08 -04:00
2014-06-24 11:33:36 -04:00
@ ide . socket . on ' forceDisconnect ' , (message) =>
@ $scope . $apply () =>
2014-07-24 10:59:24 -04:00
@$scope.permissions.write = false
2014-06-24 11:33:36 -04:00
@$scope.connection.forced_disconnect = true
2014-07-24 11:39:32 -04:00
@ ide . socket . disconnect ( )
2014-07-24 10:59:24 -04: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 11:33:36 -04: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 12:47:08 -04:00
2014-06-24 11:33:36 -04:00
@ $scope . $apply () =>
@$scope.protocolVersion = protocolVersion
@$scope.project = project
2014-07-03 10:05:35 -04:00
@$scope.permissionsLevel = permissionsLevel
2014-06-24 11:33:36 -04:00
@$scope.state.load_progress = 100
@$scope.state.loading = false
2014-07-08 05:08:38 -04:00
@ $scope . $broadcast " project:joined "
2014-06-24 10:31:44 -04:00
reconnectImmediately: () ->
@ disconnect ( )
2014-06-24 11:33:36 -04:00
@ tryReconnect ( )
2014-06-24 10:31:44 -04:00
disconnect: () ->
2014-06-24 11:33:36 -04:00
@ ide . socket . disconnect ( )
startAutoReconnectCountdown: () ->
2014-06-24 11:56:31 -04:00
twoMinutes = 2 * 60 * 1000
2014-07-09 15:32:03 -04:00
if @ lastUpdated ? and new Date ( ) - @ lastUpdated > twoMinutes
2014-06-24 11:56:31 -04: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 11:25:48 -04:00
if @ userIsLeavingPage #user will have pressed refresh or back etc
return
2014-06-24 11:33:36 -04:00
@ $scope . $apply () =>
2014-07-02 11:41:29 -04:00
@$scope.connection.reconnecting = false
2014-06-24 11:56:31 -04:00
@$scope.connection.reconnection_countdown = countdown
2014-06-24 11:33:36 -04:00
setTimeout ( =>
if ! @ connected
@timeoutId = setTimeout ( => @ decreaseCountdown ( ) ) , 1000
, 200 )
cancelReconnect: () ->
clearTimeout @ timeoutId if @ timeoutId ?
decreaseCountdown: () ->
2014-06-24 12:44:46 -04:00
return if ! @ $scope . connection . reconnection_countdown ?
2014-06-24 11:33:36 -04: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 08:46:14 -04:00
delete @ $scope . connection . reconnection_countdown
2014-07-17 08:44:50 -04:00
return if @ connected
2014-06-24 11:33:36 -04:00
@$scope.connection.reconnecting = true
@ ide . socket . socket . reconnect ( )
2014-06-24 12:44:46 -04:00
setTimeout ( => @ startAutoReconnectCountdown ( ) if ! @ connected ) , 2000
2014-06-24 11:33:36 -04:00
2015-10-14 09:15:33 -04:00
disconnectIfInactive: ()->
2015-10-15 06:38:23 -04:00
@userIsInactive = ( new Date ( ) - @ lastUserAction ) > @ disconnectAfterMs
2015-10-14 09:15:33 -04:00
if @ userIsInactive and @ connected
@ disconnect ( )
@ $scope . $apply () =>
@$scope.connection.inactive_disconnect = true