mirror of
				https://github.com/TriliumNext/Notes.git
				synced 2025-10-31 21:11:30 +08:00 
			
		
		
		
	initializing note tree synchronously
This commit is contained in:
		
							parent
							
								
									87161cfe0d
								
							
						
					
					
						commit
						6aa61ca306
					
				| @ -28,6 +28,11 @@ class Branch { | ||||
|         return this.treeCache.getNote(this.noteId); | ||||
|     } | ||||
| 
 | ||||
|     /** @returns {NoteShort} */ | ||||
|     getNoteFromCache() { | ||||
|         return this.treeCache.getNoteFromCache(this.noteId); | ||||
|     } | ||||
| 
 | ||||
|     /** @returns {NoteShort} */ | ||||
|     async getParentNote() { | ||||
|         return this.treeCache.getNote(this.parentNoteId); | ||||
|  | ||||
| @ -70,7 +70,7 @@ async function resolveNotePathToSegments(notePath, logErrors = true) { | ||||
| 
 | ||||
|             if (!parents.some(p => p.noteId === parentNoteId)) { | ||||
|                 if (logErrors) { | ||||
|                     console.log(utils.now(), `Did not find parent ${parentNoteId} for child ${childNoteId}, available parents: ${parents}`); | ||||
|                     console.log(utils.now(), `Did not find parent ${parentNoteId} for child ${childNoteId}, available parents: ${parents.map(p => p.noteId)}`); | ||||
|                 } | ||||
| 
 | ||||
|                 const someNotePath = getSomeNotePath(parents[0]); | ||||
|  | ||||
| @ -20,8 +20,6 @@ class TreeCache { | ||||
|     async loadInitialTree() { | ||||
|         const resp = await server.get('tree'); | ||||
| 
 | ||||
|         await this.loadParents(resp, false); | ||||
| 
 | ||||
|         // clear the cache only directly before adding new content which is important for e.g. switching to protected session
 | ||||
| 
 | ||||
|         /** @type {Object.<string, NoteShort>} */ | ||||
| @ -39,6 +37,14 @@ class TreeCache { | ||||
|         this.addResp(resp); | ||||
|     } | ||||
| 
 | ||||
|     async loadSubTree(subTreeNoteId) { | ||||
|         const resp = await server.get('tree?subTreeNoteId=' + subTreeNoteId); | ||||
| 
 | ||||
|         this.addResp(resp); | ||||
| 
 | ||||
|         return this.notes[subTreeNoteId]; | ||||
|     } | ||||
| 
 | ||||
|     async loadParents(resp, additiveLoad) { | ||||
|         const noteIds = new Set(resp.notes.map(note => note.noteId)); | ||||
|         const missingNoteIds = []; | ||||
|  | ||||
| @ -50,7 +50,7 @@ const TPL = ` | ||||
| export default class NotePathsWidget extends TabAwareWidget { | ||||
|     doRender() { | ||||
|         this.$widget = $(TPL); | ||||
|         this.contentSized(); | ||||
|         this.overflowing(); | ||||
| 
 | ||||
|         this.$currentPath = this.$widget.find('.current-path'); | ||||
|         this.$dropdown = this.$widget.find(".dropdown"); | ||||
|  | ||||
| @ -297,8 +297,8 @@ export default class NoteTreeWidget extends TabAwareWidget { | ||||
|         await options.save("hideIncludedImages_" + this.treeName, val.toString()); | ||||
|     } | ||||
| 
 | ||||
|     async initFancyTree() { | ||||
|         const treeData = [await this.prepareRootNode()]; | ||||
|     initFancyTree() { | ||||
|         const treeData = [this.prepareRootNode()]; | ||||
| 
 | ||||
|         this.$tree.fancytree({ | ||||
|             titlesTabbable: true, | ||||
| @ -354,7 +354,7 @@ export default class NoteTreeWidget extends TabAwareWidget { | ||||
|             }, | ||||
|             expand: (event, data) => this.setExpanded(data.node.data.branchId, true), | ||||
|             collapse: (event, data) => this.setExpanded(data.node.data.branchId, false), | ||||
|             hotkeys: utils.isMobile() ? undefined : { keydown: await this.getHotKeys() }, | ||||
|             //hotkeys: utils.isMobile() ? undefined : { keydown: await this.getHotKeys() },
 | ||||
|             dnd5: { | ||||
|                 autoExpandMS: 600, | ||||
|                 dragStart: (node, data) => { | ||||
| @ -443,34 +443,41 @@ export default class NoteTreeWidget extends TabAwareWidget { | ||||
|                         data.result = []; | ||||
|                         return; | ||||
|                     } | ||||
|                 } | ||||
| 
 | ||||
|                 data.result = treeCache.getNote(noteId).then(note => this.prepareChildren(note)); | ||||
|                     data.result = treeCache.reloadNotes([noteId]).then(() => { | ||||
|                        const note = treeCache.getNoteFromCache(noteId); | ||||
| 
 | ||||
|                        return this.prepareChildren(note); | ||||
|                     }); | ||||
|                 } | ||||
|                 else { | ||||
|                     data.result = treeCache.loadSubTree(noteId).then(note => this.prepareChildren(note)); | ||||
|                 } | ||||
|             }, | ||||
|             clones: { | ||||
|                 highlightActiveClones: true | ||||
|             }, | ||||
|             enhanceTitle: async function (event, data) { | ||||
|                 const node = data.node; | ||||
|                 const $span = $(node.span); | ||||
| 
 | ||||
|                 if (node.data.noteId !== 'root' | ||||
|                     && node.data.noteId === hoistedNoteService.getHoistedNoteId() | ||||
|                     && $span.find('.unhoist-button').length === 0) { | ||||
| 
 | ||||
|                     const unhoistButton = $('<span>  (<a class="unhoist-button">unhoist</a>)</span>'); | ||||
| 
 | ||||
|                     $span.append(unhoistButton); | ||||
|                 } | ||||
| 
 | ||||
|                 const note = await treeCache.getNote(node.data.noteId); | ||||
| 
 | ||||
|                 if (note.type === 'search' && $span.find('.refresh-search-button').length === 0) { | ||||
|                     const refreshSearchButton = $('<span>  <span class="refresh-search-button bx bx-refresh" title="Refresh saved search results"></span></span>'); | ||||
| 
 | ||||
|                     $span.append(refreshSearchButton); | ||||
|                 } | ||||
|             }, | ||||
|             // enhanceTitle: async function (event, data) {
 | ||||
|             //     const node = data.node;
 | ||||
|             //     const $span = $(node.span);
 | ||||
|             //
 | ||||
|             //     if (node.data.noteId !== 'root'
 | ||||
|             //         && node.data.noteId === hoistedNoteService.getHoistedNoteId()
 | ||||
|             //         && $span.find('.unhoist-button').length === 0) {
 | ||||
|             //
 | ||||
|             //         const unhoistButton = $('<span>  (<a class="unhoist-button">unhoist</a>)</span>');
 | ||||
|             //
 | ||||
|             //         $span.append(unhoistButton);
 | ||||
|             //     }
 | ||||
|             //
 | ||||
|             //     const note = await treeCache.getNote(node.data.noteId);
 | ||||
|             //
 | ||||
|             //     if (note.type === 'search' && $span.find('.refresh-search-button').length === 0) {
 | ||||
|             //         const refreshSearchButton = $('<span>  <span class="refresh-search-button bx bx-refresh" title="Refresh saved search results"></span></span>');
 | ||||
|             //
 | ||||
|             //         $span.append(refreshSearchButton);
 | ||||
|             //     }
 | ||||
|             // },
 | ||||
|             // this is done to automatically lazy load all expanded notes after tree load
 | ||||
|             loadChildren: (event, data) => { | ||||
|                 data.node.visit((subNode) => { | ||||
| @ -497,9 +504,7 @@ export default class NoteTreeWidget extends TabAwareWidget { | ||||
|         this.tree = $.ui.fancytree.getTree(this.$tree); | ||||
|     } | ||||
| 
 | ||||
|     async prepareRootNode() { | ||||
|         await treeCache.initializedPromise; | ||||
| 
 | ||||
|     prepareRootNode() { | ||||
|         const hoistedNoteId = hoistedNoteService.getHoistedNoteId(); | ||||
| 
 | ||||
|         let hoistedBranch; | ||||
| @ -508,31 +513,17 @@ export default class NoteTreeWidget extends TabAwareWidget { | ||||
|             hoistedBranch = treeCache.getBranch('root'); | ||||
|         } | ||||
|         else { | ||||
|             const hoistedNote = await treeCache.getNote(hoistedNoteId); | ||||
|             hoistedBranch = (await hoistedNote.getBranches())[0]; | ||||
|             const hoistedNote = treeCache.getNoteFromCache(hoistedNoteId); | ||||
|             hoistedBranch = hoistedNote.getBranches()[0]; | ||||
|         } | ||||
| 
 | ||||
|         return await this.prepareNode(hoistedBranch); | ||||
|         return this.prepareNode(hoistedBranch); | ||||
|     } | ||||
| 
 | ||||
|     async prepareChildren(note) { | ||||
|         if (note.type === 'search') { | ||||
|             return await this.prepareSearchNoteChildren(note); | ||||
|         } | ||||
|         else { | ||||
|             return await this.prepareNormalNoteChildren(note); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     async prepareSearchNoteChildren(note) { | ||||
|         await treeCache.reloadNotes([note.noteId]); | ||||
| 
 | ||||
|         const newNote = await treeCache.getNote(note.noteId); | ||||
| 
 | ||||
|         return await this.prepareNormalNoteChildren(newNote); | ||||
|     } | ||||
| 
 | ||||
|     async prepareNormalNoteChildren(parentNote) { | ||||
|     /** | ||||
|      * @param {NoteShort} parentNote | ||||
|      */ | ||||
|     prepareChildren(parentNote) { | ||||
|         utils.assertArguments(parentNote); | ||||
| 
 | ||||
|         const noteList = []; | ||||
| @ -541,14 +532,14 @@ export default class NoteTreeWidget extends TabAwareWidget { | ||||
| 
 | ||||
|         for (const branch of this.getChildBranches(parentNote)) { | ||||
|             if (hideArchivedNotes) { | ||||
|                 const note = await branch.getNote(); | ||||
|                 const note = branch.getNoteFromCache(); | ||||
| 
 | ||||
|                 if (note.hasLabel('archived')) { | ||||
|                     continue; | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             const node = await this.prepareNode(branch); | ||||
|             const node = this.prepareNode(branch); | ||||
| 
 | ||||
|             noteList.push(node); | ||||
|         } | ||||
| @ -613,10 +604,15 @@ export default class NoteTreeWidget extends TabAwareWidget { | ||||
|         node.renderTitle(); | ||||
|     } | ||||
| 
 | ||||
|     async prepareNode(branch) { | ||||
|         const note = await branch.getNote(); | ||||
|     /** | ||||
|      * @param {Branch} branch | ||||
|      */ | ||||
|     prepareNode(branch) { | ||||
|         const note = branch.getNoteFromCache(); | ||||
| 
 | ||||
|         if (!note) { | ||||
|             console.log("branch", branch); | ||||
| 
 | ||||
|             throw new Error(`Branch has no note "${branch.noteId}": ${JSON.stringify(note)}`); | ||||
|         } | ||||
| 
 | ||||
| @ -642,7 +638,7 @@ export default class NoteTreeWidget extends TabAwareWidget { | ||||
|         }; | ||||
| 
 | ||||
|         if (node.folder && node.expanded) { | ||||
|             node.children = await this.prepareChildren(note); | ||||
|             node.children = this.prepareChildren(note); | ||||
|         } | ||||
| 
 | ||||
|         return node; | ||||
| @ -1141,9 +1137,6 @@ export default class NoteTreeWidget extends TabAwareWidget { | ||||
|     } | ||||
| 
 | ||||
|     async setExpanded(branchId, isExpanded) { | ||||
|         console.log("expand", isExpanded); | ||||
| 
 | ||||
| 
 | ||||
|         utils.assertArguments(branchId); | ||||
| 
 | ||||
|         const branch = treeCache.getBranch(branchId); | ||||
| @ -1157,7 +1150,7 @@ export default class NoteTreeWidget extends TabAwareWidget { | ||||
| 
 | ||||
|         const activeNotePath = activeNode !== null ? treeService.getNotePath(activeNode) : null; | ||||
| 
 | ||||
|         const rootNode = await this.prepareRootNode(); | ||||
|         const rootNode = this.prepareRootNode(); | ||||
| 
 | ||||
|         await this.batchUpdate(async () => { | ||||
|             await this.tree.reload([rootNode]); | ||||
|  | ||||
| @ -50,23 +50,30 @@ function getNotesAndBranchesAndAttributes(noteIds) { | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| function getTree() { | ||||
|     const hoistedNoteId = optionService.getOption('hoistedNoteId'); | ||||
| function getTree(req) { | ||||
|     const subTreeNoteId = req.query.subTreeNoteId || optionService.getOption('hoistedNoteId'); | ||||
| 
 | ||||
|     // we fetch all branches of notes, even if that particular branch isn't visible
 | ||||
|     // this allows us to e.g. detect and properly display clones
 | ||||
|     const noteIds = sql.getColumn(` | ||||
|         WITH RECURSIVE | ||||
|             tree(branchId, noteId, isExpanded) AS ( | ||||
|             SELECT branchId, noteId, isExpanded FROM branches WHERE noteId = ?  | ||||
|             UNION ALL | ||||
|             SELECT branches.branchId, branches.noteId, branches.isExpanded FROM branches | ||||
|               JOIN tree ON branches.parentNoteId = tree.noteId | ||||
|               WHERE tree.isExpanded = 1 AND branches.isDeleted = 0 | ||||
|             treeWithDescendants(noteId, isExpanded) AS ( | ||||
|                 SELECT noteId, 1 FROM branches WHERE parentNoteId = ? AND isDeleted = 0 | ||||
|                 UNION | ||||
|                 SELECT branches.noteId, branches.isExpanded FROM branches | ||||
|                   JOIN treeWithDescendants ON branches.parentNoteId = treeWithDescendants.noteId | ||||
|                 WHERE treeWithDescendants.isExpanded = 1  | ||||
|                   AND branches.isDeleted = 0 | ||||
|             ), | ||||
|             treeWithDescendantsAndAscendants AS ( | ||||
|                 SELECT noteId FROM treeWithDescendants | ||||
|                 UNION | ||||
|                 SELECT branches.parentNoteId FROM branches | ||||
|                   JOIN treeWithDescendantsAndAscendants ON branches.noteId = treeWithDescendantsAndAscendants.noteId | ||||
|                 WHERE branches.isDeleted = 0 | ||||
|                   AND branches.parentNoteId != ? | ||||
|             ) | ||||
|         SELECT noteId FROM tree`, [hoistedNoteId]);
 | ||||
|         SELECT noteId FROM treeWithDescendantsAndAscendants`, [subTreeNoteId, subTreeNoteId]);
 | ||||
| 
 | ||||
|     noteIds.push('root'); | ||||
|     noteIds.push(subTreeNoteId); | ||||
| 
 | ||||
|     return getNotesAndBranchesAndAttributes(noteIds); | ||||
| } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 zadam
						zadam