From 12d9d45843f5e8d11bedbd0283482cb96f46dc95 Mon Sep 17 00:00:00 2001 From: Erik Demaine Date: Tue, 5 Dec 2023 11:47:42 -0500 Subject: [PATCH] Remove 100ms race when Stop Editing --- CHANGELOG.md | 4 ++++ client/message.coffee | 29 +++++++++++++++++++++++------ 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 97d4d98..999e35e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ To see every change with descriptions aimed at developers, see As a continuously updated web app, Coauthor uses dates instead of version numbers. +## 2023-12-05 + +* Remove small (100ms) race where Stop Editing could lose your changes + ## 2023-11-21 * Only cluster by leading tags in the sort order, so if you click to sort by diff --git a/client/message.coffee b/client/message.coffee index 924eead..1108a28 100644 --- a/client/message.coffee +++ b/client/message.coffee @@ -658,7 +658,7 @@ export MessageParent = React.memo ({message}) -> MessageParent.displayName = 'MessageParent' -export MessageEditor = React.memo ({message, setEditBody, tabindex}) -> +export MessageEditor = React.memo ({message, setEditBody, setEditDirty, tabindex}) -> messageID = message._id [editor, setEditor] = useState() useEffect -> @@ -883,9 +883,21 @@ export MessageEditor = React.memo ({message, setEditBody, tabindex}) -> # # when 'latex' # # e.dataTransfer.setData('text/plain', "\\href{#{id}}{}") # e.dataTransfer.setData('text/plain', "") - editor.on 'change', - _.debounce => setEditBody editor.getDoc().getValue() - , 100 + init = true + updateBody = _.debounce => + ## When we update body, mark as no longer dirty + setEditBody editor.getDoc().getValue() + setEditDirty false + , 100 + editor.on 'change', => + if init + ## On first change (initial load), immediately update body + setEditBody editor.getDoc().getValue() + else + ## Future changes: Immediate mark editor as dirty, + ## but debounce actual body update + setEditDirty true + updateBody() , [editor] useTracker -> return unless editor? @@ -2184,9 +2196,11 @@ export WrappedSubmessage = React.memo ({message, read}) -> [editBody, setEditBody] = useState null # special value null indicates meaning not editing so safe -- # though we actually allow stopping on '' too in case editor crash-starts + [editDirty, setEditDirty] = useState false [editStopping, setEditStopping] = useState() safeToStopEditing = not editBody or - (message.title == editTitle and message.body == editBody) + (not editDirty and + message.title == editTitle and message.body == editBody) useEffect -> setMigrateSafe message._id, safeToStopEditing if editStopping and safeToStopEditing @@ -2202,6 +2216,7 @@ export WrappedSubmessage = React.memo ({message, read}) -> useEffect -> -> setEditBody null + setEditDirty false setMigrateSafe message._id, true , [message._id] @@ -2239,6 +2254,7 @@ export WrappedSubmessage = React.memo ({message, read}) -> unless lastTitle.current? setEditTitle lastTitle.current = message.title setEditBody message.body + setEditDirty false ## Update input's value when title changes on server else if message.title != lastTitle.current lastTitle.current = message.title @@ -2259,6 +2275,7 @@ export WrappedSubmessage = React.memo ({message, read}) -> lastTitle.current = null savedTitles.current = [] setEditBody null + setEditDirty false undefined , [editing, editTitle, message.title] @@ -2802,7 +2819,7 @@ export WrappedSubmessage = React.memo ({message, read}) ->
{if editing <> - + {unless previewSideBySide }