Desktop: Fixed save issue in Rich Text editor when making a change to a note and quickly switching to a different notebook

pull/3559/head
Laurent Cozic 2020-07-23 23:55:01 +00:00
parent d6daa34e0a
commit 4be02bc33c
3 changed files with 48 additions and 28 deletions

View File

@ -857,32 +857,60 @@ const TinyMCE = (props:NoteBodyEditorProps, ref:any) => {
const prop_htmlToMarkdownRef = useRef<Function>();
prop_htmlToMarkdownRef.current = props.htmlToMarkdown;
const nextOnChangeEventInfo = useRef<any>(null);
async function execOnChangeEvent() {
const info = nextOnChangeEventInfo.current;
if (!info) return;
nextOnChangeEventInfo.current = null;
const contentMd = await prop_htmlToMarkdownRef.current(info.contentMarkupLanguage, info.editor.getContent(), info.contentOriginalCss);
lastOnChangeEventInfo.current.content = contentMd;
props_onChangeRef.current({
changeId: info.changeId,
content: contentMd,
});
dispatchDidUpdate(info.editor);
}
// When the component unmount, we dispatch the change event
// that was scheduled so that the parent component can save
// the note.
useEffect(() => {
return () => {
execOnChangeEvent();
};
}, []);
const onChangeHandlerTimeoutRef = useRef<any>(null);
useEffect(() => {
if (!editor) return () => {};
let onChangeHandlerIID:any = null;
function onChangeHandler() {
// First this component notifies the parent that a change is going to happen.
// Then the actual onChange event is fired after a timeout or when this
// component gets unmounted.
const changeId = changeId_++;
props.onWillChange({ changeId: changeId });
if (onChangeHandlerIID) clearTimeout(onChangeHandlerIID);
if (onChangeHandlerTimeoutRef.current) clearTimeout(onChangeHandlerTimeoutRef.current);
onChangeHandlerIID = setTimeout(async () => {
onChangeHandlerIID = null;
nextOnChangeEventInfo.current = {
changeId: changeId,
editor: editor,
contentMarkupLanguage: props.contentMarkupLanguage,
contentOriginalCss: props.contentOriginalCss,
};
const contentMd = await prop_htmlToMarkdownRef.current(props.contentMarkupLanguage, editor.getContent(), props.contentOriginalCss);
if (!editor) return;
lastOnChangeEventInfo.current.content = contentMd;
props_onChangeRef.current({
changeId: changeId,
content: contentMd,
});
dispatchDidUpdate(editor);
onChangeHandlerTimeoutRef.current = setTimeout(async () => {
onChangeHandlerTimeoutRef.current = null;
execOnChangeEvent();
}, 1000);
}

View File

@ -155,17 +155,6 @@ function NoteEditor(props: NoteEditorProps) {
}
}, [props.isProvisional, formNote.id]);
useEffect(() => {
// This is not exactly a hack but a bit ugly. If the note was changed (willChangeId > 0) but not
// yet saved, we need to save it now before the component is unmounted. However, we can't put
// formNote in the dependency array or that effect will run every time the note changes. We only
// want to run it once on unmount. So because of that we need to use that formNoteRef.
return () => {
isMountedRef.current = false;
saveNoteIfWillChange(formNoteRef.current);
};
}, []);
const previousNoteId = usePrevious(formNote.id);
useEffect(() => {

View File

@ -22,6 +22,9 @@ export async function htmlToMarkdown(markupLanguage: number, html: string, origi
export async function formNoteToNote(formNote: FormNote): Promise<any> {
return {
id: formNote.id,
// Should also include parent_id so that the reducer can know in which folder the note should go when saving
// https://discourse.joplinapp.org/t/experimental-wysiwyg-editor-in-joplin/6915/57?u=laurent
parent_id: formNote.parent_id,
title: formNote.title,
body: formNote.body,
};