treecache now manages reloading when starting protected session

This commit is contained in:
zadam 2020-02-01 22:29:32 +01:00
parent 513ce1a183
commit 0054a32dc7
17 changed files with 76 additions and 75 deletions

View File

@ -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,

View File

@ -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();

View File

@ -7,7 +7,7 @@ export default class SpacedUpdate {
}
scheduleUpdate() {
if (!this.changeForbidden) {
if (!this.changeForbidden) {console.trace();
this.changed = true;
setTimeout(() => this.triggerUpdate());
}

View File

@ -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} */

View File

@ -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,

View File

@ -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;

View File

@ -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});
}
}

View File

@ -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

View File

@ -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}) {

View File

@ -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();
}
}

View File

@ -59,4 +59,8 @@ export default class TabAwareWidget extends BasicWidget {
this.activeTabChanged();
}
treeCacheReloadedListener() {
this.refresh();
}
}

View File

@ -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);
}
}
}

View File

@ -129,7 +129,9 @@ export default class CodeTypeWidget extends TypeWidget {
cleanup() {
if (this.codeEditor) {
this.spacedUpdate.allowUpdateWithoutChange(() => {
this.codeEditor.setValue('');
});
}
}

View File

@ -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+\)/;

View File

@ -174,7 +174,9 @@ export default class TextTypeWidget extends TypeWidget {
cleanup() {
if (this.textEditor) {
this.spacedUpdate.allowUpdateWithoutChange(() => {
this.textEditor.setData('');
});
}
}

View File

@ -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 };

View File

@ -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