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