define [], () -> class ConnectionManager constructor: (@ide, @$scope) -> 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 @connected = false @$scope.connection = reconnecting: false # If we need to force everyone to reload the editor forced_disconnect: false @$scope.tryReconnectNow = () => @tryReconnect() @$scope.$on "editor:change", () => @lastUpdated = new Date() @ide.socket = io.connect null, reconnect: false "force new connection": true @ide.socket.on "connect", () => @connected = true @ide.pushEvent("connected") @$scope.$apply () => @$scope.connection.reconnecting = false if @$scope.state.loading @$scope.state.load_progress = 70 setTimeout(() => @joinProject() , 100) @ide.socket.on 'disconnect', () => @connected = false @ide.pushEvent("disconnected") @$scope.$apply () => @$scope.connection.reconnecting = false setTimeout(=> ga('send', 'event', 'editor-interaction', 'disconnect') , 2000) if !$scope.connection.forced_disconnect @startAutoReconnectCountdown() @ide.socket.on 'forceDisconnect', (message) => @$scope.$apply () => @$scope.permissions.write = false @$scope.connection.forced_disconnect = true @ide.socket.disconnect() @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 joinProject: () -> @ide.socket.emit 'joinProject', { project_id: @ide.project_id }, (err, project, permissionsLevel, protocolVersion) => if @$scope.protocolVersion? and @$scope.protocolVersion != protocolVersion location.reload(true) @$scope.$apply () => @$scope.protocolVersion = protocolVersion @$scope.project = project @$scope.permissionsLevel = permissionsLevel @$scope.state.load_progress = 100 @$scope.state.loading = false @$scope.$broadcast "project:joined" reconnectImmediately: () -> @disconnect() @tryReconnect() disconnect: () -> @ide.socket.disconnect() startAutoReconnectCountdown: () -> twoMinutes = 2 * 60 * 1000 if @lastUpdated? and new Date() - @lastUpdated > twoMinutes # between 1 minute and 3 minutes countdown = 60 + Math.floor(Math.random() * 120) else countdown = 3 + Math.floor(Math.random() * 7) @$scope.$apply () => @$scope.connection.reconnecting = false @$scope.connection.reconnection_countdown = countdown setTimeout(=> if !@connected @timeoutId = setTimeout (=> @decreaseCountdown()), 1000 , 200) cancelReconnect: () -> clearTimeout @timeoutId if @timeoutId? decreaseCountdown: () -> return if !@$scope.connection.reconnection_countdown? @$scope.$apply () => @$scope.connection.reconnection_countdown-- if @$scope.connection.reconnection_countdown <= 0 @$scope.$apply () => @tryReconnect() else @timeoutId = setTimeout (=> @decreaseCountdown()), 1000 tryReconnect: () -> @cancelReconnect() delete @$scope.connection.reconnection_countdown return if @connected @$scope.connection.reconnecting = true @ide.socket.socket.reconnect() setTimeout (=> @startAutoReconnectCountdown() if !@connected), 2000