mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-31 18:36:30 +01:00 
			
		
		
		
	note cache fixes for created notes
This commit is contained in:
		| @@ -11,6 +11,7 @@ import Component from "../widgets/component.js"; | ||||
| import keyboardActionsService from "./keyboard_actions.js"; | ||||
| import MobileScreenSwitcherExecutor from "../widgets/mobile_widgets/mobile_screen_switcher.js"; | ||||
| import MainTreeExecutors from "./main_tree_executors.js"; | ||||
| import protectedSessionHolder from "./protected_session_holder.js"; | ||||
|  | ||||
| class AppContext extends Component { | ||||
|     constructor(isMainWindow) { | ||||
| @@ -110,6 +111,8 @@ const appContext = new AppContext(window.glob.isMainWindow); | ||||
|  | ||||
| // we should save all outstanding changes before the page/app is closed | ||||
| $(window).on('beforeunload', () => { | ||||
|     protectedSessionHolder.resetSessionCookie(); | ||||
|  | ||||
|     appContext.triggerEvent('beforeUnload'); | ||||
| }); | ||||
|  | ||||
|   | ||||
| @@ -12,15 +12,19 @@ setInterval(() => { | ||||
|  | ||||
|         resetProtectedSession(); | ||||
|     } | ||||
| }, 5000); | ||||
| }, 10000); | ||||
|  | ||||
| function setProtectedSessionId(id) { | ||||
|     // using session cookie so that it disappears after browser/tab is closed | ||||
|     utils.setSessionCookie(PROTECTED_SESSION_ID_KEY, id); | ||||
| } | ||||
|  | ||||
| function resetProtectedSession() { | ||||
| function resetSessionCookie() { | ||||
|     utils.setSessionCookie(PROTECTED_SESSION_ID_KEY, null); | ||||
| } | ||||
|  | ||||
| function resetProtectedSession() { | ||||
|     resetSessionCookie(); | ||||
|  | ||||
|     // most secure solution - guarantees nothing remained in memory | ||||
|     // since this expires because user doesn't use the app, it shouldn't be disruptive | ||||
| @@ -47,6 +51,7 @@ function touchProtectedSessionIfNecessary(note) { | ||||
|  | ||||
| export default { | ||||
|     setProtectedSessionId, | ||||
|     resetSessionCookie, | ||||
|     resetProtectedSession, | ||||
|     isProtectedSessionAvailable, | ||||
|     touchProtectedSession, | ||||
|   | ||||
| @@ -109,11 +109,17 @@ async function addImagesToNote(images, note, content) { | ||||
|  | ||||
|             const {note: imageNote, url} = await imageService.saveImage(note.noteId, buffer, filename, true); | ||||
|  | ||||
|             await new Attribute({ | ||||
|                 noteId: imageNote.noteId, | ||||
|                 type: 'label', | ||||
|                 name: 'hideInAutocomplete' | ||||
|             }).save(); | ||||
|  | ||||
|             await new Attribute({ | ||||
|                 noteId: note.noteId, | ||||
|                 type: 'relation', | ||||
|                 value: imageNote.noteId, | ||||
|                 name: 'imageLink' | ||||
|                 name: 'imageLink', | ||||
|                 value: imageNote.noteId | ||||
|             }).save(); | ||||
|  | ||||
|             console.log(`Replacing ${imageId} with ${url}`); | ||||
|   | ||||
| @@ -1,7 +1,6 @@ | ||||
| const sql = require('./sql'); | ||||
| const sqlInit = require('./sql_init'); | ||||
| const eventService = require('./events'); | ||||
| const repository = require('./repository'); | ||||
| const protectedSessionService = require('./protected_session'); | ||||
| const utils = require('./utils'); | ||||
| const hoistedNoteService = require('./hoisted_note'); | ||||
| @@ -14,9 +13,6 @@ let branches | ||||
| /** @type {Object.<String, Attribute>} */ | ||||
| let attributes; | ||||
|  | ||||
| /** @type {Object.<String, Attribute[]>} */ | ||||
| let noteAttributeCache = {}; | ||||
|  | ||||
| let childParentToBranch = {}; | ||||
|  | ||||
| class Note { | ||||
| @@ -28,7 +24,7 @@ class Note { | ||||
|         /** @param {boolean} */ | ||||
|         this.isProtected = !!row.isProtected; | ||||
|         /** @param {boolean} */ | ||||
|         this.isDecrypted = false; | ||||
|         this.isDecrypted = !row.isProtected || !!row.isContentAvailable; | ||||
|         /** @param {Note[]} */ | ||||
|         this.parents = []; | ||||
|         /** @param {Note[]} */ | ||||
| @@ -45,6 +41,10 @@ class Note { | ||||
|  | ||||
|         /** @param {string|null} */ | ||||
|         this.fulltextCache = null; | ||||
|  | ||||
|         if (protectedSessionService.isProtectedSessionAvailable()) { | ||||
|             decryptProtectedNote(this); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** @return {Attribute[]} */ | ||||
| @@ -114,6 +114,12 @@ class Note { | ||||
|         return this.hasAttribute('label', 'archived'); | ||||
|     } | ||||
|  | ||||
|     get isHideInAutocompleteOrArchived() { | ||||
|         return this.attributes.find(attr => | ||||
|             attr.type === 'label' | ||||
|             && ["archived", "hideInAutocomplete"].includes(attr.name)); | ||||
|     } | ||||
|  | ||||
|     get hasInheritableOwnedArchivedLabel() { | ||||
|         return !!this.ownedAttributes.find(attr => attr.type === 'label' && attr.name === 'archived' && attr.isInheritable); | ||||
|     } | ||||
| @@ -126,6 +132,11 @@ class Note { | ||||
|  | ||||
|     get fulltext() { | ||||
|         if (!this.fulltextCache) { | ||||
|             if (this.isHideInAutocompleteOrArchived) { | ||||
|                 this.fulltextCache = " "; // can't be empty | ||||
|                 return this.fulltextCache; | ||||
|             } | ||||
|  | ||||
|             this.fulltextCache = this.title.toLowerCase(); | ||||
|  | ||||
|             for (const attr of this.attributes) { | ||||
| @@ -193,6 +204,21 @@ class Branch { | ||||
|         /** @param {string} */ | ||||
|         this.prefix = row.prefix; | ||||
|  | ||||
|         if (this.branchId === 'root') { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         const childNote = notes[this.noteId]; | ||||
|         const parentNote = this.parentNote; | ||||
|  | ||||
|         if (!childNote) { | ||||
|             console.log(`Cannot find child note ${this.noteId} of a branch ${this.branchId}`); | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         childNote.parents.push(parentNote); | ||||
|         parentNote.children.push(childNote); | ||||
|  | ||||
|         childParentToBranch[`${this.noteId}-${this.parentNoteId}`] = this; | ||||
|     } | ||||
|  | ||||
| @@ -222,6 +248,8 @@ class Attribute { | ||||
|         this.value = row.value; | ||||
|         /** @param {boolean} */ | ||||
|         this.isInheritable = !!row.isInheritable; | ||||
|  | ||||
|         notes[this.noteId].ownedAttributes.push(this); | ||||
|     } | ||||
|  | ||||
|     get isAffectingSubtree() { | ||||
| @@ -264,42 +292,21 @@ async function load() { | ||||
|     attributes = await getMappedRows(`SELECT attributeId, noteId, type, name, value, isInheritable FROM attributes WHERE isDeleted = 0`, | ||||
|         row => new Attribute(row)); | ||||
|  | ||||
|     for (const attr of Object.values(attributes)) { | ||||
|         notes[attr.noteId].ownedAttributes.push(attr); | ||||
|     } | ||||
|  | ||||
|     for (const branch of Object.values(branches)) { | ||||
|         if (branch.branchId === 'root') { | ||||
|             continue; | ||||
|         } | ||||
|  | ||||
|         const childNote = notes[branch.noteId]; | ||||
|         const parentNote = branch.parentNote; | ||||
|  | ||||
|         if (!childNote) { | ||||
|             console.log(`Cannot find child note ${branch.noteId} of a branch ${branch.branchId}`); | ||||
|             continue; | ||||
|         } | ||||
|  | ||||
|         childNote.parents.push(parentNote); | ||||
|         parentNote.children.push(childNote); | ||||
|     } | ||||
|  | ||||
|     if (protectedSessionService.isProtectedSessionAvailable()) { | ||||
|         await decryptProtectedNotes(); | ||||
|     } | ||||
|  | ||||
|     loaded = true; | ||||
|     loadedPromiseResolve(); | ||||
| } | ||||
|  | ||||
| async function decryptProtectedNotes() { | ||||
|     for (const note of notes) { | ||||
|         if (note.isProtected && !note.isDecrypted) { | ||||
|             note.title = protectedSessionService.decryptString(note.title); | ||||
| function decryptProtectedNote(note) { | ||||
|     if (note.isProtected && !note.isDecrypted && protectedSessionService.isProtectedSessionAvailable()) { | ||||
|         note.title = protectedSessionService.decryptString(note.title); | ||||
|  | ||||
|             note.isDecrypted = true; | ||||
|         } | ||||
|         note.isDecrypted = true; | ||||
|     } | ||||
| } | ||||
|  | ||||
| async function decryptProtectedNotes() { | ||||
|     for (const note of Object.values(notes)) { | ||||
|         decryptProtectedNote(note); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @@ -770,11 +777,17 @@ eventService.subscribe([eventService.ENTITY_CHANGED, eventService.ENTITY_DELETED | ||||
|  | ||||
|             // we can assume we have protected session since we managed to update | ||||
|             note.title = entity.title; | ||||
|             note.isDecrypted = true; | ||||
|             note.isProtected = entity.isProtected; | ||||
|             note.isDecrypted = !entity.isProtected || !!entity.isContentAvailable; | ||||
|             note.fulltextCache = null; | ||||
|  | ||||
|             decryptProtectedNote(note); | ||||
|         } | ||||
|         else { | ||||
|             notes[noteId] = new Note(entity); | ||||
|             const note = new Note(entity); | ||||
|             notes[noteId] = note; | ||||
|  | ||||
|             decryptProtectedNote(note); | ||||
|         } | ||||
|     } | ||||
|     else if (entityName === 'branches') { | ||||
| @@ -848,8 +861,6 @@ eventService.subscribe([eventService.ENTITY_CHANGED, eventService.ENTITY_DELETED | ||||
|             attributes[attributeId] = attr; | ||||
|  | ||||
|             if (note) { | ||||
|                 note.ownedAttributes.push(attr); | ||||
|  | ||||
|                 if (attr.isAffectingSubtree) { | ||||
|                     note.invalidateSubtreeCaches(); | ||||
|                 } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user