sync changes wip

This commit is contained in:
zadam 2020-01-26 11:41:40 +01:00
parent 97a35d6fba
commit c243d2e85c
7 changed files with 57 additions and 80 deletions

View File

@ -38,7 +38,7 @@ export async function showDialog(nodes) {
async function moveNotesTo(notePath) {
const targetNode = await appContext.getMainNoteTree().getNodeFromPath(notePath);
await treeChangesService.moveToNode(movedNodes, targetNode);
await treeChangesService.moveToParentNote(movedNodes, targetNode);
toastService.showMessage(`Selected notes have been moved into ${targetNode.title}`);
}

View File

@ -8,7 +8,7 @@ import noteDetailService from "./note_detail.js";
import ws from "./ws.js";
import appContext from "./app_context.js";
async function moveBeforeNode(branchIdsToMove, beforeBranchId) {
async function moveBeforeBranch(branchIdsToMove, beforeBranchId) {
branchIdsToMove = await filterRootNote(branchIdsToMove);
if (beforeBranchId === 'root') {
@ -26,7 +26,7 @@ async function moveBeforeNode(branchIdsToMove, beforeBranchId) {
}
}
async function moveAfterNode(branchIdsToMove, afterBranchId) {
async function moveAfterBranch(branchIdsToMove, afterBranchId) {
branchIdsToMove = await filterRootNote(branchIdsToMove);
const afterNote = await treeCache.getBranch(afterBranchId).getNote();
@ -48,7 +48,7 @@ async function moveAfterNode(branchIdsToMove, afterBranchId) {
}
}
async function moveToNode(branchIdsToMove, newParentNoteId) {
async function moveToParentNote(branchIdsToMove, newParentNoteId) {
branchIdsToMove = await filterRootNote(branchIdsToMove);
for (const branchIdToMove of branchIdsToMove) {
@ -229,9 +229,9 @@ ws.subscribeToMessages(async message => {
});
export default {
moveBeforeNode,
moveAfterNode,
moveToNode,
moveBeforeBranch,
moveAfterBranch,
moveToParentNote,
deleteNodes,
moveNodeUpInHierarchy
};

View File

@ -13,7 +13,7 @@ async function pasteAfter(afterBranchId) {
}
if (clipboardMode === 'cut') {
await treeChangesService.moveAfterNode(clipboardBranchIds, afterBranchId);
await treeChangesService.moveAfterBranch(clipboardBranchIds, afterBranchId);
clipboardBranchIds = [];
clipboardMode = null;
@ -40,7 +40,7 @@ async function pasteInto(parentNoteId) {
}
if (clipboardMode === 'cut') {
await treeChangesService.moveToNode(clipboardBranchIds, parentNoteId);
await treeChangesService.moveToParentNote(clipboardBranchIds, parentNoteId);
clipboardBranchIds = [];
clipboardMode = null;

View File

@ -123,7 +123,11 @@ class TreeCache {
}
}
async reloadData(noteIds) {
async reloadNotes(noteIds) {
if (noteIds.length === 0) {
return;
}
const resp = await server.post('tree/load', { noteIds });
this.addResp(resp.notes, resp.branches, resp.attributes);
@ -137,7 +141,7 @@ class TreeCache {
}
// force to load all the notes at once instead of one by one
await treeCache.getNotes(searchResults.map(res => res.noteId));
await this.getNotes(searchResults.map(res => res.noteId));
const branches = resp.branches.filter(b => b.noteId === note.noteId || b.parentNoteId === note.noteId);
@ -146,23 +150,24 @@ class TreeCache {
branchId: "virt" + result.noteId + '-' + note.noteId,
noteId: result.noteId,
parentNoteId: note.noteId,
prefix: treeCache.getBranch(result.branchId).prefix,
prefix: this.getBranch(result.branchId).prefix,
notePosition: (index + 1) * 10
}));
// update this note with standard (parent) branches + virtual (children) branches
treeCache.addResp([note], branches, []);
this.addResp([note], branches, []);
}
}
const appContext = (await import('./app_context.js')).default;
appContext.trigger('notesReloaded', {noteIds})
}
/** @return {Promise<NoteShort[]>} */
async getNotes(noteIds, silentNotFoundError = false) {
const missingNoteIds = noteIds.filter(noteId => !this.notes[noteId]);
if (missingNoteIds.length > 0) {
await this.reloadNotes(missingNoteIds);
}
await this.reloadNotes(missingNoteIds);
return noteIds.map(noteId => {
if (!this.notes[noteId] && !silentNotFoundError) {
@ -225,10 +230,10 @@ class TreeCache {
return child.parentToBranch[parentNoteId];
}
syncDataListener({data}) {return;
async processSyncRows(syncRows) {
const noteIdsToRefresh = new Set();
data.filter(sync => sync.entityName === 'branches').forEach(sync => {
syncRows.filter(sync => sync.entityName === 'branches').forEach(sync => {
const branch = this.branches[sync.entityId];
// we assume that the cache contains the old branch state and we add also the old parentNoteId
// so that the old parent can also be updated
@ -238,21 +243,14 @@ class TreeCache {
noteIdsToRefresh.add(sync.parentNoteId);
});
data.filter(sync => sync.entityName === 'notes').forEach(sync => noteIdsToRefresh.add(sync.entityId));
syncRows.filter(sync => sync.entityName === 'notes').forEach(sync => noteIdsToRefresh.add(sync.entityId));
data.filter(sync => sync.entityName === 'note_reordering').forEach(sync => noteIdsToRefresh.add(sync.entityId));
syncRows.filter(sync => sync.entityName === 'note_reordering').forEach(sync => noteIdsToRefresh.add(sync.entityId));
data.filter(sync => sync.entityName === 'attributes').forEach(sync => {
const note = treeCache.notes[sync.noteId];
// missing reloading the relation target note
syncRows.filter(sync => sync.entityName === 'attributes').forEach(sync => noteIdsToRefresh.add(sync.noteId));
if (note && note.__attributeCache) {
noteIdsToRefresh.add(sync.entityId);
}
});
if (noteIdsToRefresh.size > 0) {
this.reloadNotes({noteIds: Array.from(noteIdsToRefresh)});
}
await this.reloadNotes(Array.from(noteIdsToRefresh));
}
}

View File

@ -59,7 +59,7 @@ function getTemplates(treeWidget) {
const beforeNode = node.getPrevSibling();
if (beforeNode !== null) {
treeChangesService.moveBeforeNode([node], beforeNode);
treeChangesService.moveBeforeBranch([node.data.branchId], beforeNode.data.branchId);
}
return false;
@ -67,7 +67,7 @@ function getTemplates(treeWidget) {
"MoveNoteDown": node => {
const afterNode = node.getNextSibling();
if (afterNode !== null) {
treeChangesService.moveAfterNode([node], afterNode);
treeChangesService.moveAfterBranch([node.data.branchId], afterNode.data.branchId);
}
return false;
@ -81,7 +81,7 @@ function getTemplates(treeWidget) {
const toNode = node.getPrevSibling();
if (toNode !== null) {
treeChangesService.moveToNode([node], toNode);
treeChangesService.moveToParentNote([node.data.branchId], toNode.data.noteId);
}
return false;

View File

@ -133,10 +133,12 @@ async function consumeSyncData() {
try {
const appContext = (await import("./app_context.js")).default;
const treeCache = (await import("./tree_cache.js")).default;
// the update process should be synchronous as a whole but individual handlers can run in parallel
await Promise.all([
() => appContext.trigger('syncData', {data: allSyncData}),
() => treeCache.processSyncRows(allSyncData),
...outsideSyncMessageHandlers.map(syncHandler => runSafely(syncHandler, outsideSyncData))
]);
}

View File

@ -172,11 +172,11 @@ export default class NoteTreeWidget extends TabAwareWidget {
const selectedBranchIds = this.getSelectedNodes().map(node => node.data.branchId);
if (data.hitMode === "before") {
treeChangesService.moveBeforeNode(selectedBranchIds, node.data.branchId);
treeChangesService.moveBeforeBranch(selectedBranchIds, node.data.branchId);
} else if (data.hitMode === "after") {
treeChangesService.moveAfterNode(selectedBranchIds, node.data.branchId);
treeChangesService.moveAfterBranch(selectedBranchIds, node.data.branchId);
} else if (data.hitMode === "over") {
treeChangesService.moveToNode(selectedBranchIds, node.data.noteId);
treeChangesService.moveToParentNote(selectedBranchIds, node.data.noteId);
} else {
throw new Error("Unknown hitMode=" + data.hitMode);
}
@ -428,6 +428,14 @@ export default class NoteTreeWidget extends TabAwareWidget {
}
async notesReloadedListener({ noteIds, activateNotePath }) {
if (!activateNotePath) {
const activeNode = this.getActiveNode();
if (activeNode) {
activateNotePath = await treeService.getNotePath(activeNode);
}
}
for (const noteId of noteIds) {
for (const node of this.getNodesByNoteId(noteId)) {
const branch = treeCache.getBranch(node.data.branchId, true);
@ -503,19 +511,19 @@ export default class NoteTreeWidget extends TabAwareWidget {
await server.put('branches/' + branchId + '/expanded/' + expandedNum);
}
async reloadNotesListener({noteIds, activateNotePath = null}) {
if (noteIds.length === 0) {
return;
}
await treeCache.reloadNotes(noteIds);
if (!activateNotePath) {
activateNotePath = appContext.getActiveTabNotePath();
}
appContext.trigger('notesReloaded', { noteIds, activateNotePath });
}
// async reloadNotesListener({noteIds, activateNotePath = null}) {
// if (noteIds.length === 0) {
// return;
// }
//
// await treeCache.reloadNotes(noteIds);
//
// if (!activateNotePath) {
// activateNotePath = appContext.getActiveTabNotePath();
// }
//
// appContext.trigger('notesReloaded', { noteIds, activateNotePath });
// }
async reloadTreeListener() {
const notes = await treeService.loadTreeData();
@ -533,37 +541,6 @@ export default class NoteTreeWidget extends TabAwareWidget {
}
}
syncDataListener({data}) {return;
const noteIdsToRefresh = new Set();
// this has the problem that the former parentNoteId might not be invalidated
// and the former location of the branch/note won't be removed.
data.filter(sync => sync.entityName === 'branches').forEach(sync => {
const branch = treeCache.getBranch(sync.entityId);
// we assume that the cache contains the old branch state and we add also the old parentNoteId
// so that the old parent can also be updated
noteIdsToRefresh.add(branch.parentNoteId);
noteIdsToRefresh.add(sync.parentNoteId);
});
data.filter(sync => sync.entityName === 'notes').forEach(sync => noteIdsToRefresh.add(sync.entityId));
data.filter(sync => sync.entityName === 'note_reordering').forEach(sync => noteIdsToRefresh.add(sync.entityId));
data.filter(sync => sync.entityName === 'attributes').forEach(sync => {
const note = treeCache.notes[sync.noteId];
if (note && note.__attributeCache) {
noteIdsToRefresh.add(sync.entityId);
}
});
if (noteIdsToRefresh.size > 0) {
this.appContext.trigger('reloadNotes', {noteIds: Array.from(noteIdsToRefresh)});
}
}
hoistedNoteChangedListener() {
this.reloadTreeListener();
}