From 3ab657fe4663914c2c0ac1b285ba615e9d2953ee Mon Sep 17 00:00:00 2001 From: azivner Date: Tue, 1 Jan 2019 19:32:34 +0100 Subject: [PATCH] created concept of "detail loaded listeners" which allow scripts to execute some action after the note detail has been loaded --- .../services/frontend_script_api.js | 2 +- .../javascripts/services/note_detail.js | 52 ++++++++++++------- src/public/javascripts/services/tree.js | 8 +-- 3 files changed, 39 insertions(+), 23 deletions(-) diff --git a/src/public/javascripts/services/frontend_script_api.js b/src/public/javascripts/services/frontend_script_api.js index 47159d6d9..95e3e1a6f 100644 --- a/src/public/javascripts/services/frontend_script_api.js +++ b/src/public/javascripts/services/frontend_script_api.js @@ -43,7 +43,7 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null) { this.activateNewNote = async notePath => { await treeService.reload(); - await treeService.activateNote(notePath, true); + await treeService.activateNote(notePath, noteDetailService.focusOnTitle); }; /** diff --git a/src/public/javascripts/services/note_detail.js b/src/public/javascripts/services/note_detail.js index ec275e0f3..1556dec7c 100644 --- a/src/public/javascripts/services/note_detail.js +++ b/src/public/javascripts/services/note_detail.js @@ -37,6 +37,8 @@ let noteChangeDisabled = false; let isNoteChanged = false; +let detailLoadedListeners = []; + const components = { 'code': noteDetailCode, 'text': noteDetailText, @@ -147,12 +149,6 @@ function setNoteBackgroundIfProtected(note) { $unprotectButton.prop("disabled", !protectedSessionHolder.isProtectedSessionAvailable()); } -let isNewNoteCreated = false; - -function newNoteCreated() { - isNewNoteCreated = true; -} - async function handleProtectedSession() { const newSessionCreated = await protectedSessionService.ensureProtectedSession(currentNote.isProtected, false); @@ -191,12 +187,6 @@ async function loadNoteDetail(noteId) { attributeService.invalidateAttributes(); } - if (isNewNoteCreated) { - isNewNoteCreated = false; - - $noteTitle.focus().select(); - } - $noteIdDisplay.html(noteId); setNoteBackgroundIfProtected(currentNote); @@ -240,11 +230,13 @@ async function loadNoteDetail(noteId) { // after loading new note make sure editor is scrolled to the top getComponent(currentNote.type).scrollToTop(); + fireDetailLoaded(); + + $scriptArea.empty(); + + await bundleService.executeRelationBundles(getCurrentNote(), 'runOnNoteView'); + if (utils.isDesktop()) { - $scriptArea.empty(); - - await bundleService.executeRelationBundles(getCurrentNote(), 'runOnNoteView'); - await attributeService.showAttributes(); await showChildrenOverview(); @@ -291,6 +283,30 @@ function focusOnTitle() { $noteTitle.focus(); } +/** + * Since detail loading may take some time and user might just browse through the notes using UP-DOWN keys, + * we intentionally decouple activation of the note in the tree and full load of the note so just avaiting on + * fancytree's activate() won't wait for the full load. + * + * This causes an issue where in some cases you want to do some action after detail is loaded. For this reason + * we provide the listeners here which will be triggered after the detail is loaded and if the loaded note + * is the one registered in the listener. + */ +function addDetailLoadedListener(noteId, callback) { + detailLoadedListeners.push({ noteId, callback }); +} + +function fireDetailLoaded() { + for (const {noteId, callback} of detailLoadedListeners) { + if (noteId === currentNote.noteId) { + callback(); + } + } + + // all the listeners are one time only + detailLoadedListeners = []; +} + messagingService.subscribeToSyncMessages(syncData => { if (syncData.some(sync => sync.entityName === 'notes' && sync.entityId === getCurrentNoteId())) { infoService.showMessage('Reloading note because of background changes'); @@ -325,11 +341,11 @@ export default { getCurrentNote, getCurrentNoteType, getCurrentNoteId, - newNoteCreated, focusOnTitle, saveNote, saveNoteIfChanged, noteChanged, getCurrentNoteContent, - onNoteChange + onNoteChange, + addDetailLoadedListener }; \ No newline at end of file diff --git a/src/public/javascripts/services/tree.js b/src/public/javascripts/services/tree.js index fe83021d2..e52dd822a 100644 --- a/src/public/javascripts/services/tree.js +++ b/src/public/javascripts/services/tree.js @@ -126,7 +126,7 @@ async function expandToNote(notePath, expandOpts) { } } -async function activateNote(notePath, newNote) { +async function activateNote(notePath, noteLoadedListener) { utils.assertArguments(notePath); const hoistedNoteId = await hoistedNoteService.getHoistedNoteId(); @@ -146,8 +146,8 @@ async function activateNote(notePath, newNote) { const node = await expandToNote(notePath); - if (newNote) { - noteDetailService.newNoteCreated(); + if (noteLoadedListener) { + noteDetailService.addDetailLoadedListener(node.data.noteId, noteLoadedListener); } // we use noFocus because when we reload the tree because of background changes @@ -562,7 +562,7 @@ async function createNote(node, parentNoteId, target, isProtected, saveSelection await noteDetailService.saveNoteIfChanged(); - noteDetailService.newNoteCreated(); + noteDetailService.addDetailLoadedListener(note.noteId, noteDetailService.focusOnTitle); const noteEntity = new NoteShort(treeCache, note); const branchEntity = new Branch(treeCache, branch);