From 275851091acb38a15c68634c24887da142558020 Mon Sep 17 00:00:00 2001 From: Kenichi Kobayashi Date: Tue, 15 Nov 2022 02:25:41 +0900 Subject: [PATCH] Desktop: Fixes #6416: Switching a note using Sidebar is slow and grayed out (#6430) --- .../app-desktop/gui/NoteEditor/NoteEditor.tsx | 9 +++++--- .../NoteEditor/utils/useEffectiveNoteId.ts | 21 +++++++++++++++++++ 2 files changed, 27 insertions(+), 3 deletions(-) create mode 100644 packages/app-desktop/gui/NoteEditor/utils/useEffectiveNoteId.ts diff --git a/packages/app-desktop/gui/NoteEditor/NoteEditor.tsx b/packages/app-desktop/gui/NoteEditor/NoteEditor.tsx index 3e318af72..048fcff27 100644 --- a/packages/app-desktop/gui/NoteEditor/NoteEditor.tsx +++ b/packages/app-desktop/gui/NoteEditor/NoteEditor.tsx @@ -12,6 +12,7 @@ import useWindowCommandHandler from './utils/useWindowCommandHandler'; import useDropHandler from './utils/useDropHandler'; import useMarkupToHtml from './utils/useMarkupToHtml'; import useFormNote, { OnLoadEvent } from './utils/useFormNote'; +import useEffectiveNoteId from './utils/useEffectiveNoteId'; import useFolder from './utils/useFolder'; import styles_ from './styles'; import { NoteEditorProps, FormNote, ScrollOptions, ScrollOptionTypes, OnChangeEvent, NoteBodyEditorProps, AllAssetsOptions } from './utils/types'; @@ -66,9 +67,11 @@ function NoteEditor(props: NoteEditorProps) { setTitleHasBeenManuallyChanged(false); }, []); + const effectiveNoteId = useEffectiveNoteId(props); + const { formNote, setFormNote, isNewNote, resourceInfos } = useFormNote({ syncStarted: props.syncStarted, - noteId: props.noteId, + noteId: effectiveNoteId, isProvisional: props.isProvisional, titleInputRef: titleInputRef, editorRef: editorRef, @@ -192,7 +195,7 @@ function NoteEditor(props: NoteEditorProps) { setScrollWhenReady({ type: props.selectedNoteHash ? ScrollOptionTypes.Hash : ScrollOptionTypes.Percent, - value: props.selectedNoteHash ? props.selectedNoteHash : props.lastEditorScrollPercents[props.noteId] || 0, + value: props.selectedNoteHash ? props.selectedNoteHash : props.lastEditorScrollPercents[formNote.id] || 0, }); void ResourceEditWatcher.instance().stopWatchingAll(); @@ -549,7 +552,7 @@ function NoteEditor(props: NoteEditorProps) { } } - if (formNote.encryption_applied || !formNote.id || !props.noteId) { + if (formNote.encryption_applied || !formNote.id || !effectiveNoteId) { return renderNoNotes(styles.root); } diff --git a/packages/app-desktop/gui/NoteEditor/utils/useEffectiveNoteId.ts b/packages/app-desktop/gui/NoteEditor/utils/useEffectiveNoteId.ts new file mode 100644 index 000000000..3852d9d48 --- /dev/null +++ b/packages/app-desktop/gui/NoteEditor/utils/useEffectiveNoteId.ts @@ -0,0 +1,21 @@ +import { useEffect, useRef } from 'react'; +import { NoteEditorProps } from './types'; + +export default function useEffectiveNoteId(props: NoteEditorProps) { + // When a notebook is changed without any selected note, + // no note is selected for a moment, and then a new note gets selected. + // In this short transient period, the last displayed note id should temporarily + // be used to prevent NoteEditor's body from being unmounted. + // See https://github.com/laurent22/joplin/issues/6416 + // and https://github.com/laurent22/joplin/pull/6430 for details. + + const lastDisplayedNoteId = useRef(null); + const whenNoteIdIsTransientlyAbsent = !props.noteId && props.notes.length > 0; + const effectiveNoteId = whenNoteIdIsTransientlyAbsent ? lastDisplayedNoteId.current : props.noteId; + + useEffect(() => { + if (props.noteId) lastDisplayedNoteId.current = props.noteId; + }, [props.noteId]); + + return effectiveNoteId; +}