mirror of
https://github.com/laurent22/joplin.git
synced 2024-12-24 10:27:10 +02:00
This commit is contained in:
parent
55c222c577
commit
99b840da34
@ -51,6 +51,7 @@ import getPluginSettingValue from '@joplin/lib/services/plugins/utils/getPluginS
|
||||
import { MarkupLanguage } from '@joplin/renderer';
|
||||
import useScrollWhenReadyOptions from './utils/useScrollWhenReadyOptions';
|
||||
import useScheduleSaveCallbacks from './utils/useScheduleSaveCallbacks';
|
||||
const debounce = require('debounce');
|
||||
|
||||
const commands = [
|
||||
require('./commands/showRevisions'),
|
||||
@ -94,7 +95,6 @@ function NoteEditor(props: NoteEditorProps) {
|
||||
onAfterLoad: formNote_afterLoad,
|
||||
});
|
||||
setFormNoteRef.current = setFormNote;
|
||||
|
||||
const formNoteRef = useRef<FormNote>();
|
||||
formNoteRef.current = { ...formNote };
|
||||
|
||||
@ -158,9 +158,16 @@ function NoteEditor(props: NoteEditorProps) {
|
||||
}
|
||||
}, [props.isProvisional, formNote.id, props.dispatch]);
|
||||
|
||||
const scheduleNoteListResort = useMemo(() => {
|
||||
return debounce(() => {
|
||||
// Although the note list will update automatically, it may take some time. This
|
||||
// forces an immediate update.
|
||||
props.dispatch({ type: 'NOTE_SORT' });
|
||||
}, 100);
|
||||
}, [props.dispatch]);
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
|
||||
const onFieldChange = useCallback((field: string, value: any, changeId = 0) => {
|
||||
const onFieldChange = useCallback(async (field: string, value: any, changeId = 0) => {
|
||||
if (!isMountedRef.current) {
|
||||
// When the component is unmounted, various actions can happen which can
|
||||
// trigger onChange events, for example the textarea might be cleared.
|
||||
@ -200,9 +207,16 @@ function NoteEditor(props: NoteEditorProps) {
|
||||
// The previously loaded note, that was modified, will be saved via saveNoteIfWillChange()
|
||||
} else {
|
||||
setFormNote(newNote);
|
||||
void scheduleSaveNote(newNote);
|
||||
await scheduleSaveNote(newNote);
|
||||
}
|
||||
}, [handleProvisionalFlag, formNote, setFormNote, isNewNote, titleHasBeenManuallyChanged, scheduleSaveNote]);
|
||||
|
||||
if (field === 'title') {
|
||||
// Scheduling a resort needs to be:
|
||||
// - called after scheduleSaveNote so that the new note title is used for sorting
|
||||
// - debounced because many calls to scheduleSaveNote can resolve at once
|
||||
scheduleNoteListResort();
|
||||
}
|
||||
}, [handleProvisionalFlag, formNote, setFormNote, isNewNote, titleHasBeenManuallyChanged, scheduleNoteListResort, scheduleSaveNote]);
|
||||
|
||||
useWindowCommandHandler({
|
||||
dispatch: props.dispatch,
|
||||
|
@ -17,7 +17,7 @@ interface Props {
|
||||
}
|
||||
|
||||
const useScheduleSaveCallbacks = (props: Props) => {
|
||||
const scheduleSaveNote = useCallback(async (formNote: FormNote) => {
|
||||
const scheduleSaveNote = useCallback((formNote: FormNote) => {
|
||||
if (!formNote.saveActionQueue) throw new Error('saveActionQueue is not set!!'); // Sanity check
|
||||
|
||||
// reg.logger().debug('Scheduling...', formNote);
|
||||
@ -44,6 +44,7 @@ const useScheduleSaveCallbacks = (props: Props) => {
|
||||
};
|
||||
|
||||
formNote.saveActionQueue.push(makeAction(formNote));
|
||||
return formNote.saveActionQueue.waitForAllDone();
|
||||
}, [props.dispatch, props.setFormNote]);
|
||||
|
||||
const saveNoteIfWillChange = useCallback(async (formNote: FormNote) => {
|
||||
|
@ -28,9 +28,19 @@ export default class AsyncActionQueue {
|
||||
private scheduleProcessingIID_: any = null;
|
||||
private processing_ = false;
|
||||
|
||||
private processingFinishedPromise_: Promise<void>;
|
||||
private onProcessingFinished_: ()=> void;
|
||||
|
||||
public constructor(interval = 100, intervalType: IntervalType = IntervalType.Debounce) {
|
||||
this.interval_ = interval;
|
||||
this.intervalType_ = intervalType;
|
||||
this.resetFinishProcessingPromise_();
|
||||
}
|
||||
|
||||
private resetFinishProcessingPromise_() {
|
||||
this.processingFinishedPromise_ = new Promise<void>(resolve => {
|
||||
this.onProcessingFinished_ = resolve;
|
||||
});
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
|
||||
@ -77,6 +87,11 @@ export default class AsyncActionQueue {
|
||||
}
|
||||
|
||||
this.processing_ = false;
|
||||
|
||||
if (this.queue_.length === 0) {
|
||||
this.onProcessingFinished_();
|
||||
this.resetFinishProcessingPromise_();
|
||||
}
|
||||
}
|
||||
|
||||
public async reset() {
|
||||
@ -86,30 +101,17 @@ export default class AsyncActionQueue {
|
||||
}
|
||||
|
||||
this.queue_ = [];
|
||||
return this.waitForAllDone();
|
||||
return this.processAllNow();
|
||||
}
|
||||
|
||||
// Currently waitForAllDone() already finishes all the actions
|
||||
// as quickly as possible so we can make it an alias.
|
||||
public async processAllNow() {
|
||||
this.scheduleProcessing(1);
|
||||
return this.waitForAllDone();
|
||||
}
|
||||
|
||||
public async waitForAllDone() {
|
||||
if (!this.queue_.length) return Promise.resolve();
|
||||
|
||||
this.scheduleProcessing(1);
|
||||
|
||||
return new Promise((resolve) => {
|
||||
const iid = shim.setInterval(() => {
|
||||
if (this.processing_) return;
|
||||
|
||||
if (!this.queue_.length) {
|
||||
shim.clearInterval(iid);
|
||||
resolve(null);
|
||||
}
|
||||
}, 100);
|
||||
});
|
||||
return this.processingFinishedPromise_;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -299,7 +299,7 @@ export default class ResourceEditWatcher {
|
||||
return;
|
||||
}
|
||||
|
||||
await item.asyncSaveQueue.waitForAllDone();
|
||||
await item.asyncSaveQueue.processAllNow();
|
||||
|
||||
try {
|
||||
if (this.watcher_) this.watcher_.unwatch(item.path);
|
||||
|
Loading…
Reference in New Issue
Block a user