mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-31 10:26:08 +01:00 
			
		
		
		
	refactorings of note creation code
This commit is contained in:
		| @@ -30,6 +30,9 @@ import bundleService from "./bundle.js"; | |||||||
| import DialogEventComponent from "./dialog_events.js"; | import DialogEventComponent from "./dialog_events.js"; | ||||||
| import Entrypoints from "./entrypoints.js"; | import Entrypoints from "./entrypoints.js"; | ||||||
| import CalendarWidget from "../widgets/calendar.js"; | import CalendarWidget from "../widgets/calendar.js"; | ||||||
|  | import optionsService from "./options.js"; | ||||||
|  | import utils from "./utils.js"; | ||||||
|  | import treeService from "./tree.js"; | ||||||
|  |  | ||||||
| class AppContext { | class AppContext { | ||||||
|     constructor() { |     constructor() { | ||||||
| @@ -45,9 +48,84 @@ class AppContext { | |||||||
|     start() { |     start() { | ||||||
|         this.showWidgets(); |         this.showWidgets(); | ||||||
|  |  | ||||||
|  |         this.loadTabs(); | ||||||
|  |  | ||||||
|         bundleService.executeStartupBundles(); |         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() { |     showWidgets() { | ||||||
|         this.tabRow = new TabRowWidget(this); |         this.tabRow = new TabRowWidget(this); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -133,82 +133,6 @@ async function getSomeNotePath(note) { | |||||||
|     return path.reverse().join('/'); |     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() { | function isNotePathInAddress() { | ||||||
|     const [notePath, tabId] = getHashValueFromAddress(); |     const [notePath, tabId] = getHashValueFromAddress(); | ||||||
|  |  | ||||||
| @@ -264,72 +188,9 @@ async function createNote(node, parentNoteId, target, extraOptions = {}) { | |||||||
|         window.cutToNote.removeSelection(); |         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) { |     if (extraOptions.activate) { | ||||||
|         await newNode.setActive(true); |         const activeTabContext = appContext.getActiveTabContext(); | ||||||
|     } |         activeTabContext.setNote(note.noteId); | ||||||
|  |  | ||||||
|     // 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); |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     return {note, branch}; |     return {note, branch}; | ||||||
| @@ -353,15 +214,10 @@ function parseSelectedHtml(selectedHtml) { | |||||||
|  |  | ||||||
| async function sortAlphabetically(noteId) { | async function sortAlphabetically(noteId) { | ||||||
|     await server.put('notes/' + noteId + '/sort'); |     await server.put('notes/' + noteId + '/sort'); | ||||||
|  |  | ||||||
|     await reload(); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| ws.subscribeToMessages(message => { | ws.subscribeToMessages(message => { | ||||||
|    if (message.type === 'refresh-tree') { |    if (message.type === 'open-note') { | ||||||
|        reload(); |  | ||||||
|    } |  | ||||||
|    else if (message.type === 'open-note') { |  | ||||||
|        appContext.activateOrOpenNote(message.noteId); |        appContext.activateOrOpenNote(message.noteId); | ||||||
|  |  | ||||||
|        if (utils.isElectron()) { |        if (utils.isElectron()) { | ||||||
| @@ -507,7 +363,6 @@ async function getNotePathTitle(notePath) { | |||||||
| export default { | export default { | ||||||
|     createNote, |     createNote, | ||||||
|     sortAlphabetically, |     sortAlphabetically, | ||||||
|     treeInitialized, |  | ||||||
|     resolveNotePath, |     resolveNotePath, | ||||||
|     getSomeNotePath, |     getSomeNotePath, | ||||||
|     createNewTopLevelNote, |     createNewTopLevelNote, | ||||||
|   | |||||||
| @@ -110,7 +110,6 @@ export default class NoteTreeWidget extends TabAwareWidget { | |||||||
|             }, |             }, | ||||||
|             expand: (event, data) => this.setExpandedToServer(data.node.data.branchId, true), |             expand: (event, data) => this.setExpandedToServer(data.node.data.branchId, true), | ||||||
|             collapse: (event, data) => this.setExpandedToServer(data.node.data.branchId, false), |             collapse: (event, data) => this.setExpandedToServer(data.node.data.branchId, false), | ||||||
|             init: (event, data) => treeService.treeInitialized(), |  | ||||||
|             hotkeys: { |             hotkeys: { | ||||||
|                 keydown: await treeKeyBindingService.getKeyboardBindings(this) |                 keydown: await treeKeyBindingService.getKeyboardBindings(this) | ||||||
|             }, |             }, | ||||||
| @@ -386,7 +385,7 @@ export default class NoteTreeWidget extends TabAwareWidget { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** @return {FancytreeNode[]} */ |     /** @return {FancytreeNode[]} */ | ||||||
|     async getNodesByBranchId(branchId) { |     getNodesByBranchId(branchId) { | ||||||
|         utils.assertArguments(branchId); |         utils.assertArguments(branchId); | ||||||
|  |  | ||||||
|         const branch = treeCache.getBranch(branchId); |         const branch = treeCache.getBranch(branchId); | ||||||
| @@ -464,7 +463,9 @@ export default class NoteTreeWidget extends TabAwareWidget { | |||||||
|                             newActive = node.getParent(); |                             newActive = node.getParent(); | ||||||
|                         } |                         } | ||||||
|  |  | ||||||
|                         await newActive.setActive(true, {noEvents: true}); |                         const notePath = await treeService.getNotePath(newActive); | ||||||
|  |  | ||||||
|  |                         appContext.getActiveTabContext().setNote(notePath); | ||||||
|                     } |                     } | ||||||
|  |  | ||||||
|                     node.remove(); |                     node.remove(); | ||||||
| @@ -489,8 +490,9 @@ export default class NoteTreeWidget extends TabAwareWidget { | |||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         const activeNode = this.getActiveNode(); |         for (const noteId of loadResults.getNoteIds()) { | ||||||
|         const activateNotePath = activeNode ? await treeService.getNotePath(activeNode) : null; |             noteIdsToUpdate.push(noteId); | ||||||
|  |         } | ||||||
|  |  | ||||||
|         for (const noteId of noteIdsToReload) { |         for (const noteId of noteIdsToReload) { | ||||||
|             for (const node of this.getNodesByNoteId(noteId)) { |             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)) { |             for (const node of this.getNodesByNoteId(noteId)) { | ||||||
|                 await this.updateNode(node); |                 await this.updateNode(node); | ||||||
|             } |             } | ||||||
| @@ -523,6 +525,8 @@ export default class NoteTreeWidget extends TabAwareWidget { | |||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         const activateNotePath = appContext.getActiveTabNotePath(); | ||||||
|  |  | ||||||
|         if (activateNotePath) { |         if (activateNotePath) { | ||||||
|             const node = await this.getNodeFromPath(activateNotePath); |             const node = await this.getNodeFromPath(activateNotePath); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -638,10 +638,6 @@ class ConsistencyChecks { | |||||||
|             elapsedTimeMs = Date.now() - startTime.getTime(); |             elapsedTimeMs = Date.now() - startTime.getTime(); | ||||||
|         }); |         }); | ||||||
|  |  | ||||||
|         if (this.fixedIssues) { |  | ||||||
|             ws.refreshTree(); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         if (this.unrecoveredConsistencyErrors) { |         if (this.unrecoveredConsistencyErrors) { | ||||||
|             log.info(`Consistency checks failed (took ${elapsedTimeMs}ms)`); |             log.info(`Consistency checks failed (took ${elapsedTimeMs}ms)`); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -125,10 +125,6 @@ function sendPingToAllClients() { | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| function refreshTree() { |  | ||||||
|     sendMessageToAllClients({ type: 'refresh-tree' }); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function syncPullInProgress() { | function syncPullInProgress() { | ||||||
|     sendMessageToAllClients({ type: 'sync-pull-in-progress' }); |     sendMessageToAllClients({ type: 'sync-pull-in-progress' }); | ||||||
| } | } | ||||||
| @@ -140,7 +136,6 @@ function syncPullFinished() { | |||||||
| module.exports = { | module.exports = { | ||||||
|     init, |     init, | ||||||
|     sendMessageToAllClients, |     sendMessageToAllClients, | ||||||
|     refreshTree, |  | ||||||
|     syncPullInProgress, |     syncPullInProgress, | ||||||
|     syncPullFinished, |     syncPullFinished, | ||||||
|     sendPingToAllClients |     sendPingToAllClients | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user