mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-31 19:49:01 +01:00 
			
		
		
		
	clean up tree service WIP
This commit is contained in:
		
							parent
							
								
									d5ae3802d1
								
							
						
					
					
						commit
						b63ecba695
					
				| @ -135,7 +135,7 @@ macInit.init(); | ||||
| 
 | ||||
| searchNotesService.init(); // should be in front of treeService since that one manipulates address bar hash
 | ||||
| 
 | ||||
| appContext.showWidgets(); | ||||
| appContext.start(); | ||||
| 
 | ||||
| noteTooltipService.setupGlobalTooltip(); | ||||
| 
 | ||||
|  | ||||
| @ -1,7 +1,7 @@ | ||||
| import treeService from '../services/tree.js'; | ||||
| import searchNotesService from '../services/search_notes.js'; | ||||
| import noteAutocompleteService from '../services/note_autocomplete.js'; | ||||
| import utils from "../services/utils.js"; | ||||
| import appContext from "../services/app_context.js"; | ||||
| 
 | ||||
| const $dialog = $("#jump-to-note-dialog"); | ||||
| const $autoComplete = $("#jump-to-note-autocomplete"); | ||||
| @ -22,7 +22,7 @@ export async function showDialog() { | ||||
|                 return false; | ||||
|             } | ||||
| 
 | ||||
|             treeService.activateNote(suggestion.path); | ||||
|             appContext.getActiveTabContext().setNote(suggestion.path); | ||||
|         }); | ||||
| 
 | ||||
|     noteAutocompleteService.showRecentNotes($autoComplete); | ||||
|  | ||||
| @ -3,6 +3,7 @@ import utils from '../services/utils.js'; | ||||
| import server from '../services/server.js'; | ||||
| import treeService from "../services/tree.js"; | ||||
| import treeCache from "../services/tree_cache.js"; | ||||
| import appContext from "../services/app_context.js"; | ||||
| 
 | ||||
| const $dialog = $("#recent-changes-dialog"); | ||||
| const $content = $("#recent-changes-content"); | ||||
| @ -54,7 +55,7 @@ export async function showDialog() { | ||||
| 
 | ||||
|                                 await treeCache.reloadNotes([change.noteId]); | ||||
| 
 | ||||
|                                 treeService.activateNote(change.noteId); | ||||
|                                 appContext.getActiveTabContext().setNote(change.noteId); | ||||
|                             } | ||||
|                         }); | ||||
| 
 | ||||
|  | ||||
| @ -42,8 +42,13 @@ class AppContext { | ||||
|         this.activeTabId = null; | ||||
|     } | ||||
| 
 | ||||
|     showWidgets() { | ||||
|     start() { | ||||
|         this.showWidgets(); | ||||
| 
 | ||||
|         bundleService.executeStartupBundles(); | ||||
|     } | ||||
| 
 | ||||
|     showWidgets() { | ||||
|         this.tabRow = new TabRowWidget(this); | ||||
| 
 | ||||
|         const topPaneWidgets = [ | ||||
| @ -247,18 +252,22 @@ class AppContext { | ||||
|         await tabContext.setNote(noteId); | ||||
|     } | ||||
| 
 | ||||
|     async filterTabs(noteId) { | ||||
|     hoistedNoteChangedListener({hoistedNoteId}) { | ||||
|         if (hoistedNoteId === 'root') { | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         for (const tc of this.tabContexts) { | ||||
|             if (tc.notePath && !tc.notePath.split("/").includes(noteId)) { | ||||
|             if (tc.notePath && !tc.notePath.split("/").includes(hoistedNoteId)) { | ||||
|                 this.tabRow.removeTab(tc.tabId); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         if (this.tabContexts.length === 0) { | ||||
|             this.openAndActivateEmptyTab() | ||||
|             this.openAndActivateEmptyTab(); | ||||
|         } | ||||
| 
 | ||||
|         await this.saveOpenTabs(); | ||||
|         this.saveOpenTabs(); | ||||
|     } | ||||
| 
 | ||||
|     async saveOpenTabs() { | ||||
|  | ||||
| @ -38,7 +38,7 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, tabConte | ||||
|     this.tabContext = tabContext; | ||||
| 
 | ||||
|     /** @property {CollapsibleWidget} */ | ||||
|     this.StandardWidget = CollapsibleWidget; | ||||
|     this.CollapsibleWidget = CollapsibleWidget; | ||||
| 
 | ||||
|     /** | ||||
|      * Activates note in the tree and in the note detail. | ||||
| @ -47,14 +47,8 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, tabConte | ||||
|      * @param {string} notePath (or noteId) | ||||
|      * @returns {Promise<void>} | ||||
|      */ | ||||
|     this.activateNote = async (notePath, noteLoadedListener) => { | ||||
|         await treeService.activateNote(notePath, async () => { | ||||
|             await appContext.getMainNoteTree().scrollToActiveNoteListener(); | ||||
| 
 | ||||
|             if (noteLoadedListener) { | ||||
|                 noteLoadedListener(); | ||||
|             } | ||||
|         }); | ||||
|     this.activateNote = async notePath => { | ||||
|         await appContext.getActiveTabContext().setNote(notePath); | ||||
|     }; | ||||
| 
 | ||||
|     /** | ||||
| @ -66,7 +60,8 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, tabConte | ||||
|     this.activateNewNote = async notePath => { | ||||
|         await ws.waitForMaxKnownSyncId(); | ||||
| 
 | ||||
|         await treeService.activateNote(notePath, () => appContext.trigger('focusAndSelectTitle')); | ||||
|         await appContext.getActiveTabContext().setNote(notePath); | ||||
|         appContext.trigger('focusAndSelectTitle'); | ||||
|     }; | ||||
| 
 | ||||
|     /** | ||||
|  | ||||
| @ -1,6 +1,7 @@ | ||||
| import optionsService from './options.js'; | ||||
| import server from "./server.js"; | ||||
| import appContext from "./app_context.js"; | ||||
| import treeService from "./tree.js"; | ||||
| 
 | ||||
| let hoistedNoteId = 'root'; | ||||
| 
 | ||||
| @ -19,15 +20,11 @@ async function getHoistedNoteId() { | ||||
| } | ||||
| 
 | ||||
| async function setHoistedNoteId(noteId) { | ||||
|     if (noteId !== 'root') { | ||||
|         await appContext.filterTabs(noteId); | ||||
|     } | ||||
| 
 | ||||
|     hoistedNoteId = noteId; | ||||
| 
 | ||||
|     await server.put('options/hoistedNoteId/' + noteId); | ||||
| 
 | ||||
|     appContext.trigger('hoistedNoteChanged'); | ||||
|     appContext.trigger('hoistedNoteChanged', {hoistedNoteId}); | ||||
| } | ||||
| 
 | ||||
| async function unhoist() { | ||||
| @ -44,11 +41,38 @@ async function isRootNode(node) { | ||||
|         || node.data.noteId === await getHoistedNoteId(); | ||||
| } | ||||
| 
 | ||||
| async function checkNoteAccess(notePath) { | ||||
|     // notePath argument can contain only noteId which is not good when hoisted since
 | ||||
|     // then we need to check the whole note path
 | ||||
|     const runNotePath = await treeService.getRunPath(notePath); | ||||
| 
 | ||||
|     if (!runNotePath) { | ||||
|         console.log("Cannot activate " + notePath); | ||||
|         return false; | ||||
|     } | ||||
| 
 | ||||
|     const hoistedNoteId = await getHoistedNoteId(); | ||||
| 
 | ||||
|     if (hoistedNoteId !== 'root' && !runNotePath.includes(hoistedNoteId)) { | ||||
|         const confirmDialog = await import('../dialogs/confirm.js'); | ||||
| 
 | ||||
|         if (!await confirmDialog.confirm("Requested note is outside of hoisted note subtree and you must unhoist to access the note. Do you want to proceed with unhoisting?")) { | ||||
|             return false; | ||||
|         } | ||||
| 
 | ||||
|         // unhoist so we can activate the note
 | ||||
|         await unhoist(); | ||||
|     } | ||||
| 
 | ||||
|     return true; | ||||
| } | ||||
| 
 | ||||
| export default { | ||||
|     getHoistedNoteId, | ||||
|     getHoistedNoteNoPromise, | ||||
|     setHoistedNoteId, | ||||
|     unhoist, | ||||
|     isTopLevelNode, | ||||
|     isRootNode | ||||
|     isRootNode, | ||||
|     checkNoteAccess | ||||
| } | ||||
| @ -67,9 +67,7 @@ ws.subscribeToMessages(async message => { | ||||
|         appContext.trigger('reloadNotes', {noteIds: [message.result.parentNoteId]}); | ||||
| 
 | ||||
|         if (message.result.importedNoteId) { | ||||
|             const node = await treeService.activateNote(message.result.importedNoteId); | ||||
| 
 | ||||
|             node.setExpanded(true); | ||||
|             await appContext.getActiveTabContext.setNote(message.result.importedNoteId); | ||||
|         } | ||||
|     } | ||||
| }); | ||||
|  | ||||
| @ -26,7 +26,7 @@ server.get('keyboard-shortcuts-for-notes').then(shortcutForNotes => { | ||||
| 		utils.bindGlobalShortcut(shortcut, async () => { | ||||
| 			const treeService = (await import("./tree.js")).default; | ||||
| 
 | ||||
| 			treeService.activateNote(shortcutForNotes[shortcut]); | ||||
| 			appContext.getActiveTabContext().setNote(shortcutForNotes[shortcut]); | ||||
| 		}); | ||||
| 	} | ||||
| }); | ||||
|  | ||||
| @ -79,8 +79,6 @@ async function protectNoteAndSendToServer() { | ||||
|     note.isProtected = true; | ||||
| 
 | ||||
|     await appContext.getActiveTabContext().saveNote(); | ||||
| 
 | ||||
|     treeService.setProtected(note.noteId, note.isProtected); | ||||
| } | ||||
| 
 | ||||
| async function unprotectNoteAndSendToServer() { | ||||
| @ -104,8 +102,6 @@ async function unprotectNoteAndSendToServer() { | ||||
|     activeNote.isProtected = false; | ||||
| 
 | ||||
|     await appContext.getActiveTabContext().saveNote(); | ||||
| 
 | ||||
|     treeService.setProtected(activeNote.noteId, activeNote.isProtected); | ||||
| } | ||||
| 
 | ||||
| async function protectSubtree(noteId, protect) { | ||||
|  | ||||
| @ -7,6 +7,7 @@ import appContext from "./app_context.js"; | ||||
| import treeService from "./tree.js"; | ||||
| import Component from "../widgets/component.js"; | ||||
| import treeCache from "./tree_cache.js"; | ||||
| import hoistedNoteService from "./hoisted_note.js"; | ||||
| 
 | ||||
| let showSidebarInNewTab = true; | ||||
| 
 | ||||
| @ -42,6 +43,10 @@ class TabContext extends Component { | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         if (await hoistedNoteService.checkNoteAccess(notePath) === false) { | ||||
|             return; // note is outside of hoisted subtree and user chose not to unhoist
 | ||||
|         } | ||||
| 
 | ||||
|         await this.trigger('beforeNoteSwitch', {tabId: this.tabId}, true); | ||||
| 
 | ||||
|         this.notePath = notePath; | ||||
| @ -73,6 +78,7 @@ class TabContext extends Component { | ||||
|             tabId: this.tabId, | ||||
|             notePath: this.notePath | ||||
|         }); | ||||
| 
 | ||||
|         this.trigger('openTabsChanged'); | ||||
|     } | ||||
| 
 | ||||
|  | ||||
| @ -10,73 +10,6 @@ import optionsService from "../services/options.js"; | ||||
| import bundle from "./bundle.js"; | ||||
| import appContext from "./app_context.js"; | ||||
| 
 | ||||
| let setFrontendAsLoaded; | ||||
| const frontendLoaded = new Promise(resolve => { setFrontendAsLoaded = resolve; }); | ||||
| 
 | ||||
| async function setPrefix(branchId, prefix) { | ||||
|     utils.assertArguments(branchId); | ||||
| 
 | ||||
|     const branch = treeCache.getBranch(branchId); | ||||
| 
 | ||||
|     branch.prefix = prefix; | ||||
| 
 | ||||
|     for (const node of await appContext.getMainNoteTree().getNodesByBranchId(branchId)) { | ||||
|         await setNodeTitleWithPrefix(node); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| async function setNodeTitleWithPrefix(node) { | ||||
|     const noteTitle = await getNoteTitle(node.data.noteId); | ||||
|     const branch = treeCache.getBranch(node.data.branchId); | ||||
| 
 | ||||
|     const prefix = branch.prefix; | ||||
| 
 | ||||
|     const title = (prefix ? (prefix + " - ") : "") + noteTitle; | ||||
| 
 | ||||
|     node.setTitle(utils.escapeHtml(title)); | ||||
| } | ||||
| 
 | ||||
| // FIXME: unused?
 | ||||
| /** @return {FancytreeNode} */ | ||||
| async function activateNote(notePath, noteLoadedListener) { | ||||
|     utils.assertArguments(notePath); | ||||
| 
 | ||||
|     // notePath argument can contain only noteId which is not good when hoisted since
 | ||||
|     // then we need to check the whole note path
 | ||||
|     const runNotePath = await getRunPath(notePath); | ||||
| 
 | ||||
|     if (!runNotePath) { | ||||
|         console.log("Cannot activate " + notePath); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     const hoistedNoteId = await hoistedNoteService.getHoistedNoteId(); | ||||
| 
 | ||||
|     if (hoistedNoteId !== 'root' && !runNotePath.includes(hoistedNoteId)) { | ||||
|         const confirmDialog = await import('../dialogs/confirm.js'); | ||||
| 
 | ||||
|         if (!await confirmDialog.confirm("Requested note is outside of hoisted note subtree. Do you want to unhoist?")) { | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         // unhoist so we can activate the note
 | ||||
|         await hoistedNoteService.unhoist(); | ||||
|     } | ||||
| 
 | ||||
|     utils.closeActiveDialog(); | ||||
| 
 | ||||
|     const node = await appContext.getMainNoteTree().expandToNote(notePath); | ||||
| 
 | ||||
|     if (noteLoadedListener) { | ||||
|         // FIXME
 | ||||
|         noteDetailService.addDetailLoadedListener(node.data.noteId, noteLoadedListener); | ||||
|     } | ||||
| 
 | ||||
|     await node.setActive(true); | ||||
| 
 | ||||
|     return node; | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * Accepts notePath which might or might not be valid and returns an existing path as close to the original | ||||
|  * notePath as possible. | ||||
| @ -274,8 +207,6 @@ async function treeInitialized() { | ||||
|     // previous opening triggered task to save tab changes but these are bogus changes (this is init)
 | ||||
|     // so we'll cancel it
 | ||||
|     appContext.clearOpenTabsTask(); | ||||
| 
 | ||||
|     setFrontendAsLoaded(); | ||||
| } | ||||
| 
 | ||||
| function isNotePathInAddress() { | ||||
| @ -292,13 +223,6 @@ function getHashValueFromAddress() { | ||||
|     return str.split("-"); | ||||
| } | ||||
| 
 | ||||
| function setProtected(noteId, isProtected) { | ||||
|     appContext.getMainNoteTree().getNodesByNoteId(noteId).map(node => { | ||||
|         node.data.isProtected = isProtected; | ||||
|         node.toggleClass("protected", isProtected); | ||||
|     }); | ||||
| } | ||||
| 
 | ||||
| async function createNewTopLevelNote() { | ||||
|     const hoistedNoteId = await hoistedNoteService.getHoistedNoteId(); | ||||
| 
 | ||||
| @ -580,12 +504,7 @@ async function getNotePathTitle(notePath) { | ||||
|     return titlePath.join(' / '); | ||||
| } | ||||
| 
 | ||||
| frontendLoaded.then(bundle.executeStartupBundles); | ||||
| 
 | ||||
| export default { | ||||
|     setProtected, | ||||
|     activateNote, | ||||
|     setPrefix, | ||||
|     createNote, | ||||
|     sortAlphabetically, | ||||
|     treeInitialized, | ||||
| @ -594,7 +513,6 @@ export default { | ||||
|     createNewTopLevelNote, | ||||
|     duplicateNote, | ||||
|     getRunPath, | ||||
|     setNodeTitleWithPrefix, | ||||
|     getParentProtectedStatus, | ||||
|     getNotePath, | ||||
|     getNoteIdFromNotePath, | ||||
|  | ||||
| @ -4,6 +4,7 @@ import utils from "../services/utils.js"; | ||||
| import dateNoteService from "../services/date_notes.js"; | ||||
| import treeService from "../services/tree.js"; | ||||
| import server from "../services/server.js"; | ||||
| import appContext from "../services/app_context.js"; | ||||
| 
 | ||||
| const TPL = ` | ||||
| <div class="calendar-widget"> | ||||
| @ -58,7 +59,7 @@ export default class CalendarWidget extends CollapsibleWidget { | ||||
|             const note = await dateNoteService.getDateNote(date); | ||||
| 
 | ||||
|             if (note) { | ||||
|                 treeService.activateNote(note.noteId); | ||||
|                 appContext.getActiveTabContext().setNote(note.noteId); | ||||
|             } | ||||
|             else { | ||||
|                 alert("Cannot find day note"); | ||||
|  | ||||
| @ -1,6 +1,7 @@ | ||||
| import noteAutocompleteService from '../../services/note_autocomplete.js'; | ||||
| import treeService from "../../services/tree.js"; | ||||
| import TypeWidget from "./type_widget.js"; | ||||
| import appContext from "../../services/app_context.js"; | ||||
| 
 | ||||
| const TPL = ` | ||||
| <div class="note-detail-empty note-detail-printable"> | ||||
| @ -27,7 +28,7 @@ export default class EmptyTypeWidget extends TypeWidget { | ||||
|                     return false; | ||||
|                 } | ||||
| 
 | ||||
|                 treeService.activateNote(suggestion.path); | ||||
|                 appContext.getActiveTabContext().setNote(suggestion.path); | ||||
|             }); | ||||
| 
 | ||||
|         noteAutocompleteService.showRecentNotes(this.$autoComplete); | ||||
|  | ||||
| @ -4,6 +4,7 @@ import noteAutocompleteService from '../../services/note_autocomplete.js'; | ||||
| import mimeTypesService from '../../services/mime_types.js'; | ||||
| import TypeWidget from "./type_widget.js"; | ||||
| import utils from "../../services/utils.js"; | ||||
| import appContext from "../../services/app_context.js"; | ||||
| 
 | ||||
| const ENABLE_INSPECTOR = false; | ||||
| 
 | ||||
| @ -90,7 +91,7 @@ export default class TextTypeWidget extends TypeWidget { | ||||
|             if (match) { | ||||
|                 const noteId = match[1]; | ||||
| 
 | ||||
|                 treeService.activateNote(noteId); | ||||
|                 appContext.getActiveTabContext().setNote(noteId); | ||||
|             } | ||||
|             else { | ||||
|                 window.open(src, '_blank'); | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 zadam
						zadam