mirror of
				https://github.com/TriliumNext/Notes.git
				synced 2025-10-31 13:01:31 +08:00 
			
		
		
		
	treecache now manages reloading when starting protected session
This commit is contained in:
		
							parent
							
								
									513ce1a183
								
							
						
					
					
						commit
						0054a32dc7
					
				| @ -1,11 +1,9 @@ | ||||
| import treeService from "./services/tree.js"; | ||||
| import noteDetailService from "./services/note_detail.js"; | ||||
| import treeCache from "./services/tree_cache.js"; | ||||
| import treeBuilder from "./services/tree_builder.js"; | ||||
| import contextMenuWidget from "./services/context_menu.js"; | ||||
| import treeChangesService from "./services/branches.js"; | ||||
| import utils from "./services/utils.js"; | ||||
| import treeService from "./services/tree.js"; | ||||
| import appContext from "./services/app_context.js"; | ||||
| 
 | ||||
| window.glob.isDesktop = utils.isDesktop; | ||||
| @ -37,7 +35,7 @@ $detail.on("click", ".close-detail-button",() => { | ||||
| }); | ||||
| 
 | ||||
| async function showTree() { | ||||
|     const treeData = await treeService.loadTreeData(); | ||||
|     const treeData = await treeBuilder.prepareTree(); | ||||
| 
 | ||||
|     $tree.fancytree({ | ||||
|         autoScroll: true, | ||||
|  | ||||
| @ -20,7 +20,6 @@ import GlobalMenuWidget from "../widgets/global_menu.js"; | ||||
| import RowFlexContainer from "../widgets/row_flex_container.js"; | ||||
| import StandardTopWidget from "../widgets/standard_top_widget.js"; | ||||
| import treeCache from "./tree_cache.js"; | ||||
| import treeService from "./tree.js"; | ||||
| import NotePathsWidget from "../widgets/note_paths.js"; | ||||
| import RunScriptButtonsWidget from "../widgets/run_script_buttons.js"; | ||||
| import ProtectedNoteSwitchWidget from "../widgets/protected_note_switch.js"; | ||||
| @ -392,6 +391,12 @@ class AppContext { | ||||
|     removeAllTabsExceptForThis() { | ||||
|         // TODO
 | ||||
|     } | ||||
| 
 | ||||
|     async protectedSessionStartedListener() { | ||||
|         await treeCache.loadInitialTree(); | ||||
| 
 | ||||
|         this.trigger('treeCacheReloaded'); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| const appContext = new AppContext(); | ||||
|  | ||||
| @ -7,7 +7,7 @@ export default class SpacedUpdate { | ||||
|     } | ||||
| 
 | ||||
|     scheduleUpdate() { | ||||
|         if (!this.changeForbidden) { | ||||
|         if (!this.changeForbidden) {console.trace(); | ||||
|             this.changed = true; | ||||
|             setTimeout(() => this.triggerUpdate()); | ||||
|         } | ||||
|  | ||||
| @ -46,10 +46,7 @@ class TabContext extends Component { | ||||
|         await this.trigger('beforeNoteSwitch', {tabId: this.tabId}, true); | ||||
| 
 | ||||
|         this.notePath = notePath; | ||||
|         const noteId = treeService.getNoteIdFromNotePath(notePath); | ||||
| 
 | ||||
|         /** @property {NoteShort} */ | ||||
|         this.note = await treeCache.getNote(noteId); | ||||
|         this.noteId = treeService.getNoteIdFromNotePath(notePath); | ||||
| 
 | ||||
|         //this.cleanup(); // esp. on windows autocomplete is not getting closed automatically
 | ||||
| 
 | ||||
| @ -75,8 +72,9 @@ class TabContext extends Component { | ||||
|         this.trigger('openTabsChanged'); | ||||
|     } | ||||
| 
 | ||||
|     get noteId() { | ||||
|         return this.note && this.note.noteId; | ||||
|     /** @property {NoteShort} */ | ||||
|     get note() { | ||||
|         return treeCache.notes[this.noteId]; | ||||
|     } | ||||
| 
 | ||||
|     /** @return {NoteComplement} */ | ||||
|  | ||||
| @ -37,6 +37,7 @@ async function setNodeTitleWithPrefix(node) { | ||||
|     node.setTitle(utils.escapeHtml(title)); | ||||
| } | ||||
| 
 | ||||
| // FIXME: unused?
 | ||||
| /** @return {FancytreeNode} */ | ||||
| async function activateNote(notePath, noteLoadedListener) { | ||||
|     utils.assertArguments(notePath); | ||||
| @ -291,14 +292,6 @@ function getHashValueFromAddress() { | ||||
|     return str.split("-"); | ||||
| } | ||||
| 
 | ||||
| async function loadTreeData() { | ||||
|     const resp = await server.get('tree'); | ||||
| 
 | ||||
|     treeCache.load(resp.notes, resp.branches, resp.attributes); | ||||
| 
 | ||||
|     return await treeBuilder.prepareTree(); | ||||
| } | ||||
| 
 | ||||
| function setProtected(noteId, isProtected) { | ||||
|     appContext.getMainNoteTree().getNodesByNoteId(noteId).map(node => { | ||||
|         node.data.isProtected = isProtected; | ||||
| @ -595,7 +588,6 @@ export default { | ||||
|     setPrefix, | ||||
|     createNote, | ||||
|     sortAlphabetically, | ||||
|     loadTreeData, | ||||
|     treeInitialized, | ||||
|     resolveNotePath, | ||||
|     getSomeNotePath, | ||||
|  | ||||
| @ -4,6 +4,8 @@ import ws from "./ws.js"; | ||||
| import hoistedNoteService from "./hoisted_note.js"; | ||||
| 
 | ||||
| async function prepareTree() { | ||||
|     await treeCache.initializedPromise; | ||||
| 
 | ||||
|     const hoistedNoteId = await hoistedNoteService.getHoistedNoteId(); | ||||
| 
 | ||||
|     let hoistedBranch; | ||||
|  | ||||
| @ -4,6 +4,7 @@ import Attribute from "../entities/attribute.js"; | ||||
| import server from "./server.js"; | ||||
| import {LoadResults} from "./load_results.js"; | ||||
| import NoteComplement from "../entities/note_complement.js"; | ||||
| import appContext from "./app_context.js"; | ||||
| 
 | ||||
| /** | ||||
|  * TreeCache keeps a read only cache of note tree structure in frontend's memory. | ||||
| @ -15,10 +16,14 @@ import NoteComplement from "../entities/note_complement.js"; | ||||
|  */ | ||||
| class TreeCache { | ||||
|     constructor() { | ||||
|         this.init(); | ||||
|         this.initializedPromise = this.loadInitialTree(); | ||||
|     } | ||||
| 
 | ||||
|     init() { | ||||
|     async loadInitialTree() { | ||||
|         const {notes, branches, attributes} = await server.get('tree'); | ||||
| 
 | ||||
|         // clear the cache only directly before adding new content which is important for e.g. switching to protected session
 | ||||
| 
 | ||||
|         /** @type {Object.<string, NoteShort>} */ | ||||
|         this.notes = {}; | ||||
| 
 | ||||
| @ -30,12 +35,8 @@ class TreeCache { | ||||
| 
 | ||||
|         /** @type {Object.<string, Promise<NoteComplement>>} */ | ||||
|         this.noteComplementPromises = {}; | ||||
|     } | ||||
| 
 | ||||
|     load(noteRows, branchRows, attributeRows) { | ||||
|         this.init(); | ||||
| 
 | ||||
|         this.addResp(noteRows, branchRows, attributeRows); | ||||
|         this.addResp(notes, branches, attributes); | ||||
|     } | ||||
| 
 | ||||
|     addResp(noteRows, branchRows, attributeRows) { | ||||
| @ -350,7 +351,6 @@ class TreeCache { | ||||
|             loadResults.addNoteRevision(sync.entityId, sync.noteId, sync.sourceId); | ||||
|         }); | ||||
| 
 | ||||
|         const appContext = (await import('./app_context.js')).default; | ||||
|         appContext.trigger('entitiesReloaded', {loadResults}); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -214,10 +214,6 @@ export default class NoteDetailWidget extends TabAwareWidget { | ||||
|         this.refresh(); | ||||
|     } | ||||
| 
 | ||||
|     protectedSessionStartedListener() { | ||||
|         this.refresh(); | ||||
|     } | ||||
| 
 | ||||
|     async entitiesReloadedListener({loadResults}) { | ||||
|         // we should test what happens when the loaded note is deleted
 | ||||
| 
 | ||||
|  | ||||
| @ -4,7 +4,6 @@ import protectedSessionHolder from "../services/protected_session_holder.js"; | ||||
| import treeCache from "../services/tree_cache.js"; | ||||
| import server from "../services/server.js"; | ||||
| import SpacedUpdate from "../services/spaced_update.js"; | ||||
| import appContext from "../services/app_context.js"; | ||||
| 
 | ||||
| const TPL = ` | ||||
| <div class="note-title-container"> | ||||
| @ -75,9 +74,7 @@ export default class NoteTitleWidget extends TabAwareWidget { | ||||
|     async refreshWithNote(note) { | ||||
|         this.$noteTitle.val(note.title); | ||||
| 
 | ||||
|         if (note.isProtected && !protectedSessionHolder.isProtectedSessionAvailable()) { | ||||
|             this.$noteTitle.prop("readonly", true); | ||||
|         } | ||||
|         this.$noteTitle.prop("readonly", note.isProtected && !protectedSessionHolder.isProtectedSessionAvailable()); | ||||
|     } | ||||
| 
 | ||||
|     async beforeNoteSwitchListener({tabId}) { | ||||
|  | ||||
| @ -61,7 +61,7 @@ export default class NoteTreeWidget extends TabAwareWidget { | ||||
|             } | ||||
|         }); | ||||
| 
 | ||||
|         treeService.loadTreeData().then(treeData => this.initFancyTree($tree, treeData)); | ||||
|         treeBuilder.prepareTree().then(treeData => this.initFancyTree($tree, treeData)); | ||||
| 
 | ||||
|         return $widget; | ||||
|     } | ||||
| @ -577,8 +577,8 @@ export default class NoteTreeWidget extends TabAwareWidget { | ||||
|         await server.put('branches/' + branchId + '/expanded/' + expandedNum); | ||||
|     } | ||||
| 
 | ||||
|     async reloadTreeListener() { | ||||
|         const notes = await treeService.loadTreeData(); | ||||
|     async reloadTreeFromCache() { | ||||
|         const notes = await treeBuilder.prepareTree(); | ||||
| 
 | ||||
|         const activeNode = this.getActiveNode(); | ||||
| 
 | ||||
| @ -594,10 +594,10 @@ export default class NoteTreeWidget extends TabAwareWidget { | ||||
|     } | ||||
| 
 | ||||
|     hoistedNoteChangedListener() { | ||||
|         this.reloadTreeListener(); | ||||
|         this.reloadTreeFromCache(); | ||||
|     } | ||||
| 
 | ||||
|     protectedSessionStartedListener() { | ||||
|         this.reloadTreeListener(); | ||||
|     treeCacheReloadedListener() { | ||||
|         this.reloadTreeFromCache(); | ||||
|     } | ||||
| } | ||||
| @ -59,4 +59,8 @@ export default class TabAwareWidget extends BasicWidget { | ||||
| 
 | ||||
|         this.activeTabChanged(); | ||||
|     } | ||||
| 
 | ||||
|     treeCacheReloadedListener() { | ||||
|         this.refresh(); | ||||
|     } | ||||
| } | ||||
| @ -582,8 +582,8 @@ export default class TabRowWidget extends BasicWidget { | ||||
|                 if (currentIndex !== destinationIndex) { | ||||
|                     this.animateTabMove(tabEl, currentIndex, destinationIndex); | ||||
|                 } | ||||
|             }) | ||||
|         }) | ||||
|             }); | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     animateTabMove(tabEl, originIndex, destinationIndex) { | ||||
| @ -619,7 +619,7 @@ export default class TabRowWidget extends BasicWidget { | ||||
|         array.forEach((v, i) => { | ||||
|             if (Math.abs(value - v) < closest) { | ||||
|                 closest = Math.abs(value - v); | ||||
|                 closestIndex = i | ||||
|                 closestIndex = i; | ||||
|             } | ||||
|         }); | ||||
| 
 | ||||
| @ -662,7 +662,11 @@ export default class TabRowWidget extends BasicWidget { | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     protectedSessionStartedListener() { | ||||
|         // FIXME
 | ||||
|     treeCacheReloadedListener() { | ||||
|         for (const tabContext of this.appContext.getTabContexts()) { | ||||
|             const $tab = this.getTabById(tabContext.tabId); | ||||
| 
 | ||||
|             this.updateTab($tab, tabContext.note); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -129,7 +129,9 @@ export default class CodeTypeWidget extends TypeWidget { | ||||
| 
 | ||||
|     cleanup() { | ||||
|         if (this.codeEditor) { | ||||
|             this.spacedUpdate.allowUpdateWithoutChange(() => { | ||||
|                 this.codeEditor.setValue(''); | ||||
|             }); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  | ||||
| @ -576,10 +576,6 @@ export default class RelationMapTypeWidget extends TypeWidget { | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     async refresh() { | ||||
|         await this.loadNotesAndRelations(); | ||||
|     } | ||||
| 
 | ||||
|     getZoom() { | ||||
|         const matrixRegex = /matrix\((-?\d*\.?\d+),\s*0,\s*0,\s*-?\d*\.?\d+,\s*-?\d*\.?\d+,\s*-?\d*\.?\d+\)/; | ||||
| 
 | ||||
|  | ||||
| @ -174,7 +174,9 @@ export default class TextTypeWidget extends TypeWidget { | ||||
| 
 | ||||
|     cleanup() { | ||||
|         if (this.textEditor) { | ||||
|             this.spacedUpdate.allowUpdateWithoutChange(() => { | ||||
|                 this.textEditor.setData(''); | ||||
|             }); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  | ||||
| @ -16,13 +16,13 @@ const TaskContext = require('../../services/task_context'); | ||||
| async function moveBranchToParent(req) { | ||||
|     const {branchId, parentNoteId} = req.params; | ||||
| 
 | ||||
|     const noteToMove = await tree.getBranch(branchId); | ||||
|     const branchToMove = await tree.getBranch(branchId); | ||||
| 
 | ||||
|     if (noteToMove.parentNoteId === parentNoteId) { | ||||
|     if (branchToMove.parentNoteId === parentNoteId) { | ||||
|         return { success: true }; // no-op
 | ||||
|     } | ||||
| 
 | ||||
|     const validationResult = await tree.validateParentChild(parentNoteId, noteToMove.noteId, branchId); | ||||
|     const validationResult = await tree.validateParentChild(parentNoteId, branchToMove.noteId, branchId); | ||||
| 
 | ||||
|     if (!validationResult.success) { | ||||
|         return [200, validationResult]; | ||||
| @ -31,11 +31,11 @@ async function moveBranchToParent(req) { | ||||
|     const maxNotePos = await sql.getValue('SELECT MAX(notePosition) FROM branches WHERE parentNoteId = ? AND isDeleted = 0', [parentNoteId]); | ||||
|     const newNotePos = maxNotePos === null ? 0 : maxNotePos + 10; | ||||
| 
 | ||||
|     const newBranch = noteToMove.getClone(parentNoteId, newNotePos); | ||||
|     const newBranch = branchToMove.createClone(parentNoteId, newNotePos); | ||||
|     await newBranch.save(); | ||||
| 
 | ||||
|     noteToMove.isDeleted = true; | ||||
|     await noteToMove.save(); | ||||
|     branchToMove.isDeleted = true; | ||||
|     await branchToMove.save(); | ||||
| 
 | ||||
|     return { success: true }; | ||||
| } | ||||
| @ -43,10 +43,10 @@ async function moveBranchToParent(req) { | ||||
| async function moveBranchBeforeNote(req) { | ||||
|     const {branchId, beforeBranchId} = req.params; | ||||
| 
 | ||||
|     const noteToMove = await tree.getBranch(branchId); | ||||
|     const branchToMove = await tree.getBranch(branchId); | ||||
|     const beforeNote = await tree.getBranch(beforeBranchId); | ||||
| 
 | ||||
|     const validationResult = await tree.validateParentChild(beforeNote.parentNoteId, noteToMove.noteId, branchId); | ||||
|     const validationResult = await tree.validateParentChild(beforeNote.parentNoteId, branchToMove.noteId, branchId); | ||||
| 
 | ||||
|     if (!validationResult.success) { | ||||
|         return [200, validationResult]; | ||||
| @ -59,16 +59,16 @@ async function moveBranchBeforeNote(req) { | ||||
| 
 | ||||
|     await syncTableService.addNoteReorderingSync(beforeNote.parentNoteId); | ||||
| 
 | ||||
|     if (noteToMove.parentNoteId === beforeNote.parentNoteId) { | ||||
|         noteToMove.notePosition = beforeNote.notePosition; | ||||
|         await noteToMove.save(); | ||||
|     if (branchToMove.parentNoteId === beforeNote.parentNoteId) { | ||||
|         branchToMove.notePosition = beforeNote.notePosition; | ||||
|         await branchToMove.save(); | ||||
|     } | ||||
|     else { | ||||
|         const newBranch = noteToMove.getClone(beforeNote.parentNoteId, beforeNote.notePosition); | ||||
|         const newBranch = branchToMove.createClone(beforeNote.parentNoteId, beforeNote.notePosition); | ||||
|         await newBranch.save(); | ||||
| 
 | ||||
|         noteToMove.isDeleted = true; | ||||
|         await noteToMove.save(); | ||||
|         branchToMove.isDeleted = true; | ||||
|         await branchToMove.save(); | ||||
|     } | ||||
| 
 | ||||
|     return { success: true }; | ||||
| @ -77,10 +77,10 @@ async function moveBranchBeforeNote(req) { | ||||
| async function moveBranchAfterNote(req) { | ||||
|     const {branchId, afterBranchId} = req.params; | ||||
| 
 | ||||
|     const noteToMove = await tree.getBranch(branchId); | ||||
|     const branchToMove = await tree.getBranch(branchId); | ||||
|     const afterNote = await tree.getBranch(afterBranchId); | ||||
| 
 | ||||
|     const validationResult = await tree.validateParentChild(afterNote.parentNoteId, noteToMove.noteId, branchId); | ||||
|     const validationResult = await tree.validateParentChild(afterNote.parentNoteId, branchToMove.noteId, branchId); | ||||
| 
 | ||||
|     if (!validationResult.success) { | ||||
|         return [200, validationResult]; | ||||
| @ -95,16 +95,16 @@ async function moveBranchAfterNote(req) { | ||||
| 
 | ||||
|     const movedNotePosition = afterNote.notePosition + 10; | ||||
| 
 | ||||
|     if (noteToMove.parentNoteId === afterNote.parentNoteId) { | ||||
|         noteToMove.notePosition = movedNotePosition; | ||||
|         await noteToMove.save(); | ||||
|     if (branchToMove.parentNoteId === afterNote.parentNoteId) { | ||||
|         branchToMove.notePosition = movedNotePosition; | ||||
|         await branchToMove.save(); | ||||
|     } | ||||
|     else { | ||||
|         const newBranch = noteToMove.getClone(afterNote.parentNoteId, movedNotePosition); | ||||
|         const newBranch = branchToMove.createClone(afterNote.parentNoteId, movedNotePosition); | ||||
|         await newBranch.save(); | ||||
| 
 | ||||
|         noteToMove.isDeleted = true; | ||||
|         await noteToMove.save(); | ||||
|         branchToMove.isDeleted = true; | ||||
|         await branchToMove.save(); | ||||
|     } | ||||
| 
 | ||||
|     return { success: true }; | ||||
|  | ||||
| @ -4,6 +4,7 @@ const log = require('./log'); | ||||
| const sql = require('./sql'); | ||||
| const cls = require('./cls'); | ||||
| const syncMutexService = require('./sync_mutex'); | ||||
| const protectedSessionService = require('./protected_session'); | ||||
| 
 | ||||
| let webSocketServer; | ||||
| let lastAcceptedSyncIds = {}; | ||||
| @ -80,6 +81,10 @@ async function fillInAdditionalProperties(sync) { | ||||
|         sync.entity = await sql.getRow(`SELECT * FROM branches WHERE branchId = ?`, [sync.entityId]); | ||||
|     } else if (sync.entityName === 'notes') { | ||||
|         sync.entity = await sql.getRow(`SELECT * FROM notes WHERE noteId = ?`, [sync.entityId]); | ||||
| 
 | ||||
|         if (sync.entity.isProtected) { | ||||
|             sync.entity.title = protectedSessionService.decryptString(sync.entity.title); | ||||
|         } | ||||
|     } else if (sync.entityName === 'note_revisions') { | ||||
|         sync.noteId = await sql.getValue(`SELECT noteId
 | ||||
|                                           FROM note_revisions | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 zadam
						zadam