diff --git a/src/public/javascripts/services/app_context.js b/src/public/javascripts/services/app_context.js index b3c3c164c..c2015123f 100644 --- a/src/public/javascripts/services/app_context.js +++ b/src/public/javascripts/services/app_context.js @@ -30,6 +30,9 @@ import bundleService from "./bundle.js"; import DialogEventComponent from "./dialog_events.js"; import Entrypoints from "./entrypoints.js"; import CalendarWidget from "../widgets/calendar.js"; +import optionsService from "./options.js"; +import utils from "./utils.js"; +import treeService from "./tree.js"; class AppContext { constructor() { @@ -45,9 +48,84 @@ class AppContext { start() { this.showWidgets(); + this.loadTabs(); + bundleService.executeStartupBundles(); } + async loadTabs() { + const options = await optionsService.waitForOptions(); + + const openTabs = options.getJson('openTabs') || []; + + await treeCache.initializedPromise; + + // if there's notePath in the URL, make sure it's open and active + // (useful, among others, for opening clipped notes from clipper) + if (window.location.hash) { + const notePath = window.location.hash.substr(1); + const noteId = treeService.getNoteIdFromNotePath(notePath); + + if (noteId && await treeCache.noteExists(noteId)) { + for (const tab of openTabs) { + tab.active = false; + } + + const foundTab = openTabs.find(tab => noteId === treeService.getNoteIdFromNotePath(tab.notePath)); + + if (foundTab) { + foundTab.active = true; + } + else { + openTabs.push({ + notePath: notePath, + active: true + }); + } + } + } + + let filteredTabs = []; + + for (const openTab of openTabs) { + const noteId = treeService.getNoteIdFromNotePath(openTab.notePath); + + if (await treeCache.noteExists(noteId)) { + // note doesn't exist so don't try to open tab for it + filteredTabs.push(openTab); + } + } + + if (utils.isMobile()) { + // mobile frontend doesn't have tabs so show only the active tab + filteredTabs = filteredTabs.filter(tab => tab.active); + } + + if (filteredTabs.length === 0) { + filteredTabs.push({ + notePath: 'root', + active: true + }); + } + + if (!filteredTabs.find(tab => tab.active)) { + filteredTabs[0].active = true; + } + + for (const tab of filteredTabs) { + const tabContext = this.openEmptyTab(); + tabContext.setNote(tab.notePath); + + if (tab.active) { + this.activateTab(tabContext.tabId); + } + } + + // previous opening triggered task to save tab changes but these are bogus changes (this is init) + // so we'll cancel it + this.clearOpenTabsTask(); + } + showWidgets() { this.tabRow = new TabRowWidget(this); diff --git a/src/public/javascripts/services/tree.js b/src/public/javascripts/services/tree.js index c58aa50ef..3f2b699a2 100644 --- a/src/public/javascripts/services/tree.js +++ b/src/public/javascripts/services/tree.js @@ -133,82 +133,6 @@ async function getSomeNotePath(note) { return path.reverse().join('/'); } -async function treeInitialized() { - if (appContext.getTabContexts().length > 0) { - // this is just tree reload - tabs are already in place - return; - } - - const options = await optionsService.waitForOptions(); - - const openTabs = options.getJson('openTabs') || []; - - // if there's notePath in the URL, make sure it's open and active - // (useful, among others, for opening clipped notes from clipper) - if (location.hash) { - const notePath = location.hash.substr(1); - const noteId = getNoteIdFromNotePath(notePath); - - if (noteId && await treeCache.noteExists(noteId)) { - for (const tab of openTabs) { - tab.active = false; - } - - const foundTab = openTabs.find(tab => noteId === getNoteIdFromNotePath(tab.notePath)); - - if (foundTab) { - foundTab.active = true; - } - else { - openTabs.push({ - notePath: notePath, - active: true - }); - } - } - } - - let filteredTabs = []; - - for (const openTab of openTabs) { - const noteId = getNoteIdFromNotePath(openTab.notePath); - - if (await treeCache.noteExists(noteId)) { - // note doesn't exist so don't try to open tab for it - filteredTabs.push(openTab); - } - } - - if (utils.isMobile()) { - // mobile frontend doesn't have tabs so show only the active tab - filteredTabs = filteredTabs.filter(tab => tab.active); - } - - if (filteredTabs.length === 0) { - filteredTabs.push({ - notePath: 'root', - active: true - }); - } - - if (!filteredTabs.find(tab => tab.active)) { - filteredTabs[0].active = true; - } - - for (const tab of filteredTabs) { - const tabContext = appContext.openEmptyTab(); - tabContext.setNote(tab.notePath); - - if (tab.active) { - appContext.activateTab(tabContext.tabId); - } - } - - // previous opening triggered task to save tab changes but these are bogus changes (this is init) - // so we'll cancel it - appContext.clearOpenTabsTask(); -} - function isNotePathInAddress() { const [notePath, tabId] = getHashValueFromAddress(); @@ -264,72 +188,9 @@ async function createNote(node, parentNoteId, target, extraOptions = {}) { window.cutToNote.removeSelection(); } - noteDetailService.addDetailLoadedListener(note.noteId, () => appContext.trigger('focusAndSelectTitle')); - - const noteEntity = await treeCache.getNote(note.noteId); - const branchEntity = treeCache.getBranch(branch.branchId); - - let newNodeData = { - title: newNoteName, - noteId: branchEntity.noteId, - parentNoteId: parentNoteId, - refKey: branchEntity.noteId, - branchId: branchEntity.branchId, - isProtected: extraOptions.isProtected, - type: noteEntity.type, - extraClasses: await treeBuilder.getExtraClasses(noteEntity), - icon: await treeBuilder.getIcon(noteEntity), - folder: extraOptions.type === 'search', - lazy: true, - key: utils.randomString(12) // this should prevent some "duplicate key" errors - }; - - /** @var {FancytreeNode} */ - let newNode; - - if (target === 'after') { - newNode = node.appendSibling(newNodeData); - } - else if (target === 'into') { - if (!node.getChildren() && node.isFolder()) { - // folder is not loaded - load will bring up the note since it was already put into cache - await node.load(true); - - await node.setExpanded(); - } - else { - node.addChildren(newNodeData); - } - - newNode = node.getLastChild(); - - const parentNoteEntity = await treeCache.getNote(node.data.noteId); - - node.folder = true; - node.icon = await treeBuilder.getIcon(parentNoteEntity); // icon might change into folder - node.renderTitle(); - } - else { - toastService.throwError("Unrecognized target: " + target); - } - if (extraOptions.activate) { - await newNode.setActive(true); - } - - // need to refresh because original doesn't have methods like .getParent() - newNodeData = appContext.getMainNoteTree().getNodesByNoteId(branchEntity.noteId)[0]; - - // following for cycle will make sure that also clones of a parent are refreshed - for (const newParentNode of appContext.getMainNoteTree().getNodesByNoteId(parentNoteId)) { - if (newParentNode.key === newNodeData.getParent().key) { - // we've added a note into this one so no need to refresh - continue; - } - - await newParentNode.load(true); // force reload to show up new note - - await appContext.getMainNoteTree().updateNode(newParentNode); + const activeTabContext = appContext.getActiveTabContext(); + activeTabContext.setNote(note.noteId); } return {note, branch}; @@ -353,15 +214,10 @@ function parseSelectedHtml(selectedHtml) { async function sortAlphabetically(noteId) { await server.put('notes/' + noteId + '/sort'); - - await reload(); } ws.subscribeToMessages(message => { - if (message.type === 'refresh-tree') { - reload(); - } - else if (message.type === 'open-note') { + if (message.type === 'open-note') { appContext.activateOrOpenNote(message.noteId); if (utils.isElectron()) { @@ -507,7 +363,6 @@ async function getNotePathTitle(notePath) { export default { createNote, sortAlphabetically, - treeInitialized, resolveNotePath, getSomeNotePath, createNewTopLevelNote, diff --git a/src/public/javascripts/widgets/note_tree.js b/src/public/javascripts/widgets/note_tree.js index 60492ac5c..9c594803f 100644 --- a/src/public/javascripts/widgets/note_tree.js +++ b/src/public/javascripts/widgets/note_tree.js @@ -110,7 +110,6 @@ export default class NoteTreeWidget extends TabAwareWidget { }, expand: (event, data) => this.setExpandedToServer(data.node.data.branchId, true), collapse: (event, data) => this.setExpandedToServer(data.node.data.branchId, false), - init: (event, data) => treeService.treeInitialized(), hotkeys: { keydown: await treeKeyBindingService.getKeyboardBindings(this) }, @@ -386,7 +385,7 @@ export default class NoteTreeWidget extends TabAwareWidget { } /** @return {FancytreeNode[]} */ - async getNodesByBranchId(branchId) { + getNodesByBranchId(branchId) { utils.assertArguments(branchId); const branch = treeCache.getBranch(branchId); @@ -464,7 +463,9 @@ export default class NoteTreeWidget extends TabAwareWidget { newActive = node.getParent(); } - await newActive.setActive(true, {noEvents: true}); + const notePath = await treeService.getNotePath(newActive); + + appContext.getActiveTabContext().setNote(notePath); } node.remove(); @@ -489,8 +490,9 @@ export default class NoteTreeWidget extends TabAwareWidget { } } - const activeNode = this.getActiveNode(); - const activateNotePath = activeNode ? await treeService.getNotePath(activeNode) : null; + for (const noteId of loadResults.getNoteIds()) { + noteIdsToUpdate.push(noteId); + } for (const noteId of noteIdsToReload) { for (const node of this.getNodesByNoteId(noteId)) { @@ -500,7 +502,7 @@ export default class NoteTreeWidget extends TabAwareWidget { } } - for (const noteId of noteIdsToReload) { + for (const noteId of noteIdsToUpdate) { for (const node of this.getNodesByNoteId(noteId)) { await this.updateNode(node); } @@ -523,6 +525,8 @@ export default class NoteTreeWidget extends TabAwareWidget { } } + const activateNotePath = appContext.getActiveTabNotePath(); + if (activateNotePath) { const node = await this.getNodeFromPath(activateNotePath); diff --git a/src/services/consistency_checks.js b/src/services/consistency_checks.js index 2a2911b3f..046a6927a 100644 --- a/src/services/consistency_checks.js +++ b/src/services/consistency_checks.js @@ -638,10 +638,6 @@ class ConsistencyChecks { elapsedTimeMs = Date.now() - startTime.getTime(); }); - if (this.fixedIssues) { - ws.refreshTree(); - } - if (this.unrecoveredConsistencyErrors) { log.info(`Consistency checks failed (took ${elapsedTimeMs}ms)`); diff --git a/src/services/ws.js b/src/services/ws.js index 5a5616648..58bf3ffa0 100644 --- a/src/services/ws.js +++ b/src/services/ws.js @@ -125,10 +125,6 @@ function sendPingToAllClients() { } } -function refreshTree() { - sendMessageToAllClients({ type: 'refresh-tree' }); -} - function syncPullInProgress() { sendMessageToAllClients({ type: 'sync-pull-in-progress' }); } @@ -140,7 +136,6 @@ function syncPullFinished() { module.exports = { init, sendMessageToAllClients, - refreshTree, syncPullInProgress, syncPullFinished, sendPingToAllClients