mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
Show saving dialog based on whether there are inflight ops, and show a warning when leaving the page if there are
This commit is contained in:
parent
6ad8566e24
commit
a12716ab6b
5 changed files with 74 additions and 25 deletions
|
@ -10,6 +10,11 @@ define [
|
|||
@openDocs[doc_id] = new Document(ide, doc_id)
|
||||
return @openDocs[doc_id]
|
||||
|
||||
@hasUnsavedChanges: () ->
|
||||
for doc_id, doc of (@openDocs or {})
|
||||
return true if doc.hasBufferedOps()
|
||||
return false
|
||||
|
||||
constructor: (@ide, @doc_id) ->
|
||||
@connected = @ide.socket.socket.connected
|
||||
@joined = false
|
||||
|
@ -25,8 +30,8 @@ define [
|
|||
|
||||
detachFromAce: () ->
|
||||
@doc?.detachFromAce()
|
||||
editorDoc = @ace.getSession().getDocument()
|
||||
editorDoc.off "change", @_checkConsistency
|
||||
editorDoc = @ace?.getSession().getDocument()
|
||||
editorDoc?.off "change", @_checkConsistency
|
||||
|
||||
_checkConsistency: () ->
|
||||
editorValue = @ace?.getValue()
|
||||
|
@ -40,6 +45,15 @@ define [
|
|||
getType: () ->
|
||||
@doc?.getType()
|
||||
|
||||
getInflightOp: () ->
|
||||
@doc?.getInflightOp()
|
||||
|
||||
getPendingOp: () ->
|
||||
@doc?.getPendingOp()
|
||||
|
||||
hasBufferedOps: () ->
|
||||
@doc?.hasBufferedOps()
|
||||
|
||||
_bindToSocketEvents: () ->
|
||||
@_onUpdateAppliedHandler = (update) => @_onUpdateApplied(update)
|
||||
@ide.socket.on "otUpdateApplied", @_onUpdateAppliedHandler
|
||||
|
@ -84,6 +98,25 @@ define [
|
|||
else
|
||||
@_leaveDoc(callback)
|
||||
|
||||
pollSavedStatus: () ->
|
||||
# returns false if doc has ops waiting to be acknowledged or
|
||||
# sent that haven't changed since the last time we checked.
|
||||
# Otherwise returns true.
|
||||
inflightOp = @getInflightOp()
|
||||
pendingOp = @getPendingOp()
|
||||
if !inflightOp? and !pendingOp?
|
||||
# there's nothing going on
|
||||
saved = true
|
||||
else if inflightOp == @oldInflightOp
|
||||
saved = false
|
||||
else if pendingOp?
|
||||
saved = false
|
||||
else
|
||||
saved = true
|
||||
|
||||
@oldInflightOp = inflightOp
|
||||
return saved
|
||||
|
||||
_cancelLeave: () ->
|
||||
if @_leaveCallbacks?
|
||||
delete @_leaveCallbacks
|
||||
|
|
|
@ -210,11 +210,6 @@ define [
|
|||
callback null, @document
|
||||
|
||||
_bindToDocumentEvents: (document) ->
|
||||
document.on "op:sent", () =>
|
||||
@ide.savingAreaManager.saving()
|
||||
document.on "op:acknowledged", () =>
|
||||
@ide.savingAreaManager.saved()
|
||||
|
||||
document.on "remoteop", () =>
|
||||
@undoManager.nextUpdateIsRemote = true
|
||||
|
||||
|
@ -364,3 +359,6 @@ define [
|
|||
|
||||
disable: () ->
|
||||
@enabled = false
|
||||
|
||||
hasUnsavedChanges: () ->
|
||||
Document.hasUnsavedChanges()
|
||||
|
|
|
@ -89,6 +89,9 @@ define [
|
|||
hasBufferedOps: () ->
|
||||
@_doc.inflightOp? or @_doc.pendingOp?
|
||||
|
||||
getInflightOp: () -> @_doc.inflightOp
|
||||
getPendingOp: () -> @_doc.pendingOp
|
||||
|
||||
attachToAce: (ace) -> @_doc.attach_ace(ace)
|
||||
detachFromAce: () -> @_doc.detach_ace?()
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ define [
|
|||
"ide/TabManager"
|
||||
"ide/LayoutManager"
|
||||
"ide/FileUploadManager"
|
||||
"ide/SavingAreaManager"
|
||||
"spelling/SpellingManager"
|
||||
"search/SearchManager"
|
||||
"models/Project"
|
||||
|
@ -45,6 +46,7 @@ define [
|
|||
TabManager,
|
||||
LayoutManager,
|
||||
FileUploadManager,
|
||||
SavingAreaManager,
|
||||
SpellingManager,
|
||||
SearchManager,
|
||||
Project,
|
||||
|
@ -205,22 +207,5 @@ define [
|
|||
ide.tourManager = new IdeTour ide
|
||||
ide.debugManager = new DebugManager(ide)
|
||||
|
||||
ide.savingAreaManager =
|
||||
$savingArea : $('#saving-area')
|
||||
timeOut: undefined
|
||||
saved:->
|
||||
@clearTimeout()
|
||||
$("#savingProblems").hide()
|
||||
saving:->
|
||||
return if @timeOut?
|
||||
@clearTimeout()
|
||||
@timeOut = setTimeout((=>
|
||||
ga?('send', 'event', 'editor-interaction', 'notification-shown', "saving")
|
||||
$("#savingProblems").show()
|
||||
), 3000)
|
||||
|
||||
clearTimeout:->
|
||||
if @timeOut?
|
||||
clearTimeout @timeOut
|
||||
delete @timeOut
|
||||
ide.savingAreaManager = new SavingAreaManager(ide)
|
||||
|
||||
|
|
30
services/web/public/coffee/ide/SavingAreaManager.coffee
Normal file
30
services/web/public/coffee/ide/SavingAreaManager.coffee
Normal file
|
@ -0,0 +1,30 @@
|
|||
define [
|
||||
], () ->
|
||||
class SavingAreaManager
|
||||
$el: $('#saving-area')
|
||||
|
||||
constructor: (@ide) ->
|
||||
@unsavedSeconds = 0
|
||||
setInterval () =>
|
||||
@pollSavedStatus()
|
||||
, 1000
|
||||
|
||||
$(window).bind 'beforeunload', () =>
|
||||
@warnAboutUnsavedChanges()
|
||||
|
||||
pollSavedStatus: () ->
|
||||
saved = @ide.editor.document.pollSavedStatus()
|
||||
if saved
|
||||
@unsavedSeconds = 0
|
||||
else
|
||||
@unsavedSeconds += 1
|
||||
|
||||
if @unsavedSeconds >= 4
|
||||
$("#savingProblems").text("Saving... (#{@unsavedSeconds} seconds of unsaved changes)")
|
||||
$("#savingProblems").show()
|
||||
else
|
||||
$("#savingProblems").hide()
|
||||
|
||||
warnAboutUnsavedChanges: () ->
|
||||
if @ide.editor.hasUnsavedChanges()
|
||||
return "You have unsaved changes. If you leave now they will not be saved."
|
Loading…
Reference in a new issue