Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Desktop: Fixes #8960: Fix cursor jumps to the top of the note editor on sync #10456

Merged

Conversation

personalizedrefrigerator
Copy link
Collaborator

@personalizedrefrigerator personalizedrefrigerator commented May 21, 2024

Summary

Note

Update: This does not seem to have resolved the issue.

This pull request fixes a race condition in useFormNote.ts that sometimes caused the editor cursor to jump to the top of a note after a sync finishes.

May fix #8960.

Details

More specifically, the issue was caused by formNote.hasChanged being out-of-date.

In NoteEditor.tsx, .hasChanged is set to true by changing the value of a state variable (setFormNote). This is done in a callback fired when the current note updates:

Previously, .hasChanged was checked just before scheduling a refresh:

if (formNote.hasChanged) return;

After a refresh completed, .hasChanged was set to false:

The issue can occur if .hasChanged becomes true just after a refresh is scheduled. In this case, the refresh would still happen. The refresh would load the current copy of the note from the database (n).

Because the editor's recent changes haven't had time to be written to the database, n.body would not match the content of the editor. The CodeMirror 5 (and also the rich text?) editors handle this by changing the editor's content, clearing the editor's undo history, and resetting the cursor position. (The CodeMirror 6 editor handles cursor positioning differently).

Adding an additional .hasChanged-based check doesn't seem to be enough to fix the issue (see comment). It seems to be necessary to set .hasChanged immediately, without waiting for a re-render to update its value. This pull request does this by:

  1. Exposing a custom onSetFormNote callback that wraps setFormNote.
  2. Updating a formNoteRef within onSetFormNote.
  3. Checking formNoteRef.current.hasChanged just before setting the new form note.

Testing plan

The original issue is difficult to reproduce. As such, the following testing plan focuses on avoiding regressions:

  1. Create a new note and trigger a manual sync with ctrl-s while typing.
    • Verify that the cursor doesn't jump to the beginning of the note. Note: This does not verify that the issue has been fixed.
  2. Switch to a different note.
  3. Switch back to the original note.
  4. Verify that the content of the original note was saved.
  5. Repeat steps 1-4 for the rich text editor and the CodeMirror 6-based beta editor.

This has been tested successfully on Ubuntu 24.04.

Note: Additional manual testing was done with an equivalent fix on this branch with additional debug logging and more frequent auto-sync enabled.

…e on sync

This commit fixes a race condition caused by the editor's form note's hasChanged
property not being up-to-date (or checked) while refreshing the note.

The `.hasChanged` property was previously checked only before running
async logic that updated the note. If the note changed during this async
logic, this could change the value passed down to the editor as its
content. If the editor had recently updated its content, the content
prop would then **not match** the current content of the editor.

The CodeMirror 5 (and also the rich text?) editors handle this by 1)
changing the editor's content 2) clearing the editor's undo history and
3) resetting the cursor position. The CodeMirror 6 editor only does 1
and 2, so the issue was most significant in the CodeMirror 5-based
editor.

This commit fixes the issue by 1) storing a refrence to the latest
formNote in a ref and 2) checking ref.current.hasChanged just before
saving changes to the note.
@personalizedrefrigerator personalizedrefrigerator changed the title Desktop: Fixes #8960: Fix cursor jumps to the top of the note on sync Desktop: Fixes #8960: Fix cursor jumps to the top of the note editor on sync May 21, 2024
@laurent22
Copy link
Owner

That's great, thanks for looking into this! Let's merge and see what feedback we get, hopefully that fixes it for good!

@laurent22 laurent22 merged commit efb753e into laurent22:dev May 22, 2024
10 checks passed
@joochlee
Copy link

Good job!
I have been suffered by this issue for a long time...

Thanks a lot!

@nonobio
Copy link

nonobio commented Jun 11, 2024

The issue is still present: #8960 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Cursor jumps to top of editor when typing
4 participants