created concept of "detail loaded listeners" which allow scripts to execute some action after the note detail has been loaded

This commit is contained in:
azivner 2019-01-01 19:32:34 +01:00
parent 8785dae753
commit 3ab657fe46
3 changed files with 39 additions and 23 deletions

View File

@ -43,7 +43,7 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null) {
this.activateNewNote = async notePath => { this.activateNewNote = async notePath => {
await treeService.reload(); await treeService.reload();
await treeService.activateNote(notePath, true); await treeService.activateNote(notePath, noteDetailService.focusOnTitle);
}; };
/** /**

View File

@ -37,6 +37,8 @@ let noteChangeDisabled = false;
let isNoteChanged = false; let isNoteChanged = false;
let detailLoadedListeners = [];
const components = { const components = {
'code': noteDetailCode, 'code': noteDetailCode,
'text': noteDetailText, 'text': noteDetailText,
@ -147,12 +149,6 @@ function setNoteBackgroundIfProtected(note) {
$unprotectButton.prop("disabled", !protectedSessionHolder.isProtectedSessionAvailable()); $unprotectButton.prop("disabled", !protectedSessionHolder.isProtectedSessionAvailable());
} }
let isNewNoteCreated = false;
function newNoteCreated() {
isNewNoteCreated = true;
}
async function handleProtectedSession() { async function handleProtectedSession() {
const newSessionCreated = await protectedSessionService.ensureProtectedSession(currentNote.isProtected, false); const newSessionCreated = await protectedSessionService.ensureProtectedSession(currentNote.isProtected, false);
@ -191,12 +187,6 @@ async function loadNoteDetail(noteId) {
attributeService.invalidateAttributes(); attributeService.invalidateAttributes();
} }
if (isNewNoteCreated) {
isNewNoteCreated = false;
$noteTitle.focus().select();
}
$noteIdDisplay.html(noteId); $noteIdDisplay.html(noteId);
setNoteBackgroundIfProtected(currentNote); setNoteBackgroundIfProtected(currentNote);
@ -240,11 +230,13 @@ async function loadNoteDetail(noteId) {
// after loading new note make sure editor is scrolled to the top // after loading new note make sure editor is scrolled to the top
getComponent(currentNote.type).scrollToTop(); getComponent(currentNote.type).scrollToTop();
fireDetailLoaded();
$scriptArea.empty();
await bundleService.executeRelationBundles(getCurrentNote(), 'runOnNoteView');
if (utils.isDesktop()) { if (utils.isDesktop()) {
$scriptArea.empty();
await bundleService.executeRelationBundles(getCurrentNote(), 'runOnNoteView');
await attributeService.showAttributes(); await attributeService.showAttributes();
await showChildrenOverview(); await showChildrenOverview();
@ -291,6 +283,30 @@ function focusOnTitle() {
$noteTitle.focus(); $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 => { messagingService.subscribeToSyncMessages(syncData => {
if (syncData.some(sync => sync.entityName === 'notes' && sync.entityId === getCurrentNoteId())) { if (syncData.some(sync => sync.entityName === 'notes' && sync.entityId === getCurrentNoteId())) {
infoService.showMessage('Reloading note because of background changes'); infoService.showMessage('Reloading note because of background changes');
@ -325,11 +341,11 @@ export default {
getCurrentNote, getCurrentNote,
getCurrentNoteType, getCurrentNoteType,
getCurrentNoteId, getCurrentNoteId,
newNoteCreated,
focusOnTitle, focusOnTitle,
saveNote, saveNote,
saveNoteIfChanged, saveNoteIfChanged,
noteChanged, noteChanged,
getCurrentNoteContent, getCurrentNoteContent,
onNoteChange onNoteChange,
addDetailLoadedListener
}; };

View File

@ -126,7 +126,7 @@ async function expandToNote(notePath, expandOpts) {
} }
} }
async function activateNote(notePath, newNote) { async function activateNote(notePath, noteLoadedListener) {
utils.assertArguments(notePath); utils.assertArguments(notePath);
const hoistedNoteId = await hoistedNoteService.getHoistedNoteId(); const hoistedNoteId = await hoistedNoteService.getHoistedNoteId();
@ -146,8 +146,8 @@ async function activateNote(notePath, newNote) {
const node = await expandToNote(notePath); const node = await expandToNote(notePath);
if (newNote) { if (noteLoadedListener) {
noteDetailService.newNoteCreated(); noteDetailService.addDetailLoadedListener(node.data.noteId, noteLoadedListener);
} }
// we use noFocus because when we reload the tree because of background changes // 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(); await noteDetailService.saveNoteIfChanged();
noteDetailService.newNoteCreated(); noteDetailService.addDetailLoadedListener(note.noteId, noteDetailService.focusOnTitle);
const noteEntity = new NoteShort(treeCache, note); const noteEntity = new NoteShort(treeCache, note);
const branchEntity = new Branch(treeCache, branch); const branchEntity = new Branch(treeCache, branch);