diff --git a/packages/app-desktop/gui/NoteEditor/NoteEditor.tsx b/packages/app-desktop/gui/NoteEditor/NoteEditor.tsx index c991774c8ba..f94c3daeab9 100644 --- a/packages/app-desktop/gui/NoteEditor/NoteEditor.tsx +++ b/packages/app-desktop/gui/NoteEditor/NoteEditor.tsx @@ -76,18 +76,11 @@ function NoteEditor(props: NoteEditorProps) { }, []); const effectiveNoteId = useEffectiveNoteId(props); - const effectiveNote = props.notes.find(n => n.id === effectiveNoteId); const { formNote, setFormNote, isNewNote, resourceInfos } = useFormNote({ syncStarted: props.syncStarted, decryptionStarted: props.decryptionStarted, noteId: effectiveNoteId, - - // The effective updated_time property of the note. It may be different - // from the last time the note was saved, if it was modified outside the - // editor (eg. via API). - dbNote: effectiveNote ? { id: effectiveNote.id, updated_time: effectiveNote.updated_time } : { id: '', updated_time: 0 }, - isProvisional: props.isProvisional, titleInputRef: titleInputRef, editorRef: editorRef, @@ -127,32 +120,12 @@ function NoteEditor(props: NoteEditorProps) { return async function() { const note = await formNoteToNote(formNote); reg.logger().debug('Saving note...', note); - const noteUpdatedTime = Date.now(); - - // First we set the formNote object, then we save the note. We - // do it in that order, otherwise `useFormNote` will be rendered - // with the newly saved note and the timestamp of that note will - // be more recent that the one in the editor, which will trigger - // an update. We do not want this since we already have the - // latest changes. - // - // It also means that we manually set the timestamp, so that we - // have it before the note is saved. + const savedNote: any = await Note.save(note); setFormNote((prev: FormNote) => { - return { - ...prev, - user_updated_time: noteUpdatedTime, - updated_time: noteUpdatedTime, - hasChanged: false, - }; + return { ...prev, user_updated_time: savedNote.user_updated_time, hasChanged: false }; }); - const savedNote = await Note.save({ - ...note, - updated_time: noteUpdatedTime, - }, { autoTimestamp: false }); - void ExternalEditWatcher.instance().updateNoteFile(savedNote); props.dispatch({ diff --git a/packages/app-desktop/gui/NoteEditor/utils/types.ts b/packages/app-desktop/gui/NoteEditor/utils/types.ts index 5f3ed39d5eb..0c0c6a60c55 100644 --- a/packages/app-desktop/gui/NoteEditor/utils/types.ts +++ b/packages/app-desktop/gui/NoteEditor/utils/types.ts @@ -5,7 +5,6 @@ import { MarkupLanguage } from '@joplin/renderer'; import { RenderResult, RenderResultPluginAsset } from '@joplin/renderer/MarkupToHtml'; import { MarkupToHtmlOptions } from './useMarkupToHtml'; import { Dispatch } from 'redux'; -import { NoteEntity } from '@joplin/lib/services/database/types'; export interface AllAssetsOptions { contentMaxWidthTarget?: string; @@ -21,7 +20,7 @@ export interface NoteEditorProps { dispatch: Dispatch; selectedNoteIds: string[]; selectedFolderId: string; - notes: NoteEntity[]; + notes: any[]; watchedNoteFiles: string[]; isProvisional: boolean; editorNoteStatuses: any; @@ -105,7 +104,6 @@ export interface FormNote { markup_language: number; user_updated_time: number; encryption_applied: number; - updated_time: number; hasChanged: boolean; @@ -156,7 +154,6 @@ export function defaultFormNote(): FormNote { hasChanged: false, user_updated_time: 0, encryption_applied: 0, - updated_time: 0, }; } diff --git a/packages/app-desktop/gui/NoteEditor/utils/useFormNote.test.ts b/packages/app-desktop/gui/NoteEditor/utils/useFormNote.test.ts index 05a7fff36fe..345c1015258 100644 --- a/packages/app-desktop/gui/NoteEditor/utils/useFormNote.test.ts +++ b/packages/app-desktop/gui/NoteEditor/utils/useFormNote.test.ts @@ -12,7 +12,6 @@ const defaultFormNoteProps: HookDependencies = { editorRef: null, onBeforeLoad: ()=>{}, onAfterLoad: ()=>{}, - dbNote: { id: '', updated_time: 0 }, }; describe('useFormNote', () => { diff --git a/packages/app-desktop/gui/NoteEditor/utils/useFormNote.ts b/packages/app-desktop/gui/NoteEditor/utils/useFormNote.ts index a8c335aa564..96a330dc84c 100644 --- a/packages/app-desktop/gui/NoteEditor/utils/useFormNote.ts +++ b/packages/app-desktop/gui/NoteEditor/utils/useFormNote.ts @@ -7,30 +7,21 @@ import { splitHtml } from '@joplin/renderer/HtmlToHtml'; import Setting from '@joplin/lib/models/Setting'; import usePrevious from '../../hooks/usePrevious'; import ResourceEditWatcher from '@joplin/lib/services/ResourceEditWatcher/index'; -import { MarkupToHtml } from '@joplin/renderer'; + +const { MarkupToHtml } = require('@joplin/renderer'); import Note from '@joplin/lib/models/Note'; +import { reg } from '@joplin/lib/registry'; import ResourceFetcher from '@joplin/lib/services/ResourceFetcher'; import DecryptionWorker from '@joplin/lib/services/DecryptionWorker'; -import { NoteEntity } from '@joplin/lib/services/database/types'; -import Logger from '@joplin/utils/Logger'; - -const logger = Logger.create('useFormNote'); export interface OnLoadEvent { formNote: FormNote; - updated_time: number; -} - -export interface DbNote { - id: string; - updated_time: number; } export interface HookDependencies { syncStarted: boolean; decryptionStarted: boolean; noteId: string; - dbNote: DbNote; isProvisional: boolean; titleInputRef: any; editorRef: any; @@ -72,7 +63,7 @@ function resourceInfosChanged(a: ResourceInfos, b: ResourceInfos): boolean { export default function useFormNote(dependencies: HookDependencies) { const { - syncStarted, decryptionStarted, noteId, isProvisional, titleInputRef, editorRef, onBeforeLoad, onAfterLoad, dbNote, + syncStarted, decryptionStarted, noteId, isProvisional, titleInputRef, editorRef, onBeforeLoad, onAfterLoad, } = dependencies; const [formNote, setFormNote] = useState(defaultFormNote()); @@ -86,7 +77,7 @@ export default function useFormNote(dependencies: HookDependencies) { // a new refresh. const [formNoteRefeshScheduled, setFormNoteRefreshScheduled] = useState(0); - async function initNoteState(n: NoteEntity) { + async function initNoteState(n: any) { let originalCss = ''; if (n.markup_language === MarkupToHtml.MARKUP_LANGUAGE_HTML) { @@ -94,7 +85,7 @@ export default function useFormNote(dependencies: HookDependencies) { originalCss = splitted.css; } - const newFormNote: FormNote = { + const newFormNote = { id: n.id, title: n.title, body: n.body, @@ -108,7 +99,6 @@ export default function useFormNote(dependencies: HookDependencies) { hasChanged: false, user_updated_time: n.user_updated_time, encryption_applied: n.encryption_applied, - updated_time: n.updated_time, }; // Note that for performance reason,the call to setResourceInfos should @@ -126,7 +116,7 @@ export default function useFormNote(dependencies: HookDependencies) { useEffect(() => { if (formNoteRefeshScheduled <= 0) return () => {}; - logger.info('Sync has finished and note has never been changed - reloading it'); + reg.logger().info('Sync has finished and note has never been changed - reloading it'); let cancelled = false; @@ -138,7 +128,7 @@ export default function useFormNote(dependencies: HookDependencies) { // it would not have been loaded in the editor (due to note selection changing // on delete) if (!n) { - logger.warn('Trying to reload note that has been deleted:', noteId); + reg.logger().warn('Trying to reload note that has been deleted:', noteId); return; } @@ -160,19 +150,19 @@ export default function useFormNote(dependencies: HookDependencies) { }, [formNoteRefeshScheduled]); useEffect(() => { - // Check that synchronisation has just finished - and if the note has - // never been changed, we reload it. If the note has already been - // changed, it's a conflict that's already been handled by the - // synchronizer. + // Check that synchronisation has just finished - and + // if the note has never been changed, we reload it. + // If the note has already been changed, it's a conflict + // that's already been handled by the synchronizer. const decryptionJustEnded = prevDecryptionStarted && !decryptionStarted; const syncJustEnded = prevSyncStarted && !syncStarted; if (!decryptionJustEnded && !syncJustEnded) return; if (formNote.hasChanged) return; - // Refresh the form note. This is kept separate from the above logic so - // that when prevSyncStarted is changed from true to false, it doesn't - // cancel the note from loading. + // Refresh the form note. + // This is kept separate from the above logic so that when prevSyncStarted is changed + // from true to false, it doesn't cancel the note from loading. refreshFormNote(); }, [ prevSyncStarted, syncStarted, @@ -180,18 +170,6 @@ export default function useFormNote(dependencies: HookDependencies) { formNote.hasChanged, refreshFormNote, ]); - useEffect(() => { - // Something's not fully initialised - we skip the check - if (!dbNote.id || !dbNote.updated_time || !formNote.updated_time) return; - - // If the note in the database is more recent that the note in editor, - // it was modified outside the editor, so we refresh it. - if (dbNote.id === formNote.id && dbNote.updated_time > formNote.updated_time) { - logger.info('Note has been changed outside the editor - reloading it'); - refreshFormNote(); - } - }, [dbNote.id, dbNote.updated_time, formNote.updated_time, formNote.id, refreshFormNote]); - useEffect(() => { if (!noteId) { if (formNote.id) setFormNote(defaultFormNote()); @@ -202,7 +180,7 @@ export default function useFormNote(dependencies: HookDependencies) { let cancelled = false; - logger.debug('Loading existing note', noteId); + reg.logger().debug('Loading existing note', noteId); function handleAutoFocus(noteIsTodo: boolean) { if (!isProvisional) return; @@ -222,15 +200,15 @@ export default function useFormNote(dependencies: HookDependencies) { const n = await Note.load(noteId); if (cancelled) return; if (!n) throw new Error(`Cannot find note with ID: ${noteId}`); - logger.debug('Loaded note:', n); + reg.logger().debug('Loaded note:', n); - await onBeforeLoad({ formNote, updated_time: 0 }); + await onBeforeLoad({ formNote }); const newFormNote = await initNoteState(n); setIsNewNote(isProvisional); - await onAfterLoad({ formNote: newFormNote, updated_time: n.updated_time }); + await onAfterLoad({ formNote: newFormNote }); handleAutoFocus(!!n.is_todo); }