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) { async function moveNotesTo(notePath) {
const targetNode = await appContext.getMainNoteTree().getNodeFromPath(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}`); 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 ws from "./ws.js";
import appContext from "./app_context.js"; import appContext from "./app_context.js";
async function moveBeforeNode(branchIdsToMove, beforeBranchId) { async function moveBeforeBranch(branchIdsToMove, beforeBranchId) {
branchIdsToMove = await filterRootNote(branchIdsToMove); branchIdsToMove = await filterRootNote(branchIdsToMove);
if (beforeBranchId === 'root') { 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); branchIdsToMove = await filterRootNote(branchIdsToMove);
const afterNote = await treeCache.getBranch(afterBranchId).getNote(); 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); branchIdsToMove = await filterRootNote(branchIdsToMove);
for (const branchIdToMove of branchIdsToMove) { for (const branchIdToMove of branchIdsToMove) {
@ -229,9 +229,9 @@ ws.subscribeToMessages(async message => {
}); });
export default { export default {
moveBeforeNode, moveBeforeBranch,
moveAfterNode, moveAfterBranch,
moveToNode, moveToParentNote,
deleteNodes, deleteNodes,
moveNodeUpInHierarchy moveNodeUpInHierarchy
}; };

View File

@ -13,7 +13,7 @@ async function pasteAfter(afterBranchId) {
} }
if (clipboardMode === 'cut') { if (clipboardMode === 'cut') {
await treeChangesService.moveAfterNode(clipboardBranchIds, afterBranchId); await treeChangesService.moveAfterBranch(clipboardBranchIds, afterBranchId);
clipboardBranchIds = []; clipboardBranchIds = [];
clipboardMode = null; clipboardMode = null;
@ -40,7 +40,7 @@ async function pasteInto(parentNoteId) {
} }
if (clipboardMode === 'cut') { if (clipboardMode === 'cut') {
await treeChangesService.moveToNode(clipboardBranchIds, parentNoteId); await treeChangesService.moveToParentNote(clipboardBranchIds, parentNoteId);
clipboardBranchIds = []; clipboardBranchIds = [];
clipboardMode = null; 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 }); const resp = await server.post('tree/load', { noteIds });
this.addResp(resp.notes, resp.branches, resp.attributes); 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 // 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); 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, branchId: "virt" + result.noteId + '-' + note.noteId,
noteId: result.noteId, noteId: result.noteId,
parentNoteId: note.noteId, parentNoteId: note.noteId,
prefix: treeCache.getBranch(result.branchId).prefix, prefix: this.getBranch(result.branchId).prefix,
notePosition: (index + 1) * 10 notePosition: (index + 1) * 10
})); }));
// update this note with standard (parent) branches + virtual (children) branches // 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[]>} */ /** @return {Promise<NoteShort[]>} */
async getNotes(noteIds, silentNotFoundError = false) { async getNotes(noteIds, silentNotFoundError = false) {
const missingNoteIds = noteIds.filter(noteId => !this.notes[noteId]); const missingNoteIds = noteIds.filter(noteId => !this.notes[noteId]);
if (missingNoteIds.length > 0) { await this.reloadNotes(missingNoteIds);
await this.reloadNotes(missingNoteIds);
}
return noteIds.map(noteId => { return noteIds.map(noteId => {
if (!this.notes[noteId] && !silentNotFoundError) { if (!this.notes[noteId] && !silentNotFoundError) {
@ -225,10 +230,10 @@ class TreeCache {
return child.parentToBranch[parentNoteId]; return child.parentToBranch[parentNoteId];
} }
syncDataListener({data}) {return; async processSyncRows(syncRows) {
const noteIdsToRefresh = new Set(); 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]; const branch = this.branches[sync.entityId];
// we assume that the cache contains the old branch state and we add also the old parentNoteId // 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 // so that the old parent can also be updated
@ -238,21 +243,14 @@ class TreeCache {
noteIdsToRefresh.add(sync.parentNoteId); 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 => { // missing reloading the relation target note
const note = treeCache.notes[sync.noteId]; syncRows.filter(sync => sync.entityName === 'attributes').forEach(sync => noteIdsToRefresh.add(sync.noteId));
if (note && note.__attributeCache) { await this.reloadNotes(Array.from(noteIdsToRefresh));
noteIdsToRefresh.add(sync.entityId);
}
});
if (noteIdsToRefresh.size > 0) {
this.reloadNotes({noteIds: Array.from(noteIdsToRefresh)});
}
} }
} }

View File

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

View File

@ -133,10 +133,12 @@ async function consumeSyncData() {
try { try {
const appContext = (await import("./app_context.js")).default; 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 // the update process should be synchronous as a whole but individual handlers can run in parallel
await Promise.all([ await Promise.all([
() => appContext.trigger('syncData', {data: allSyncData}), () => appContext.trigger('syncData', {data: allSyncData}),
() => treeCache.processSyncRows(allSyncData),
...outsideSyncMessageHandlers.map(syncHandler => runSafely(syncHandler, outsideSyncData)) ...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); const selectedBranchIds = this.getSelectedNodes().map(node => node.data.branchId);
if (data.hitMode === "before") { if (data.hitMode === "before") {
treeChangesService.moveBeforeNode(selectedBranchIds, node.data.branchId); treeChangesService.moveBeforeBranch(selectedBranchIds, node.data.branchId);
} else if (data.hitMode === "after") { } else if (data.hitMode === "after") {
treeChangesService.moveAfterNode(selectedBranchIds, node.data.branchId); treeChangesService.moveAfterBranch(selectedBranchIds, node.data.branchId);
} else if (data.hitMode === "over") { } else if (data.hitMode === "over") {
treeChangesService.moveToNode(selectedBranchIds, node.data.noteId); treeChangesService.moveToParentNote(selectedBranchIds, node.data.noteId);
} else { } else {
throw new Error("Unknown hitMode=" + data.hitMode); throw new Error("Unknown hitMode=" + data.hitMode);
} }
@ -428,6 +428,14 @@ export default class NoteTreeWidget extends TabAwareWidget {
} }
async notesReloadedListener({ noteIds, activateNotePath }) { async notesReloadedListener({ noteIds, activateNotePath }) {
if (!activateNotePath) {
const activeNode = this.getActiveNode();
if (activeNode) {
activateNotePath = await treeService.getNotePath(activeNode);
}
}
for (const noteId of noteIds) { for (const noteId of noteIds) {
for (const node of this.getNodesByNoteId(noteId)) { for (const node of this.getNodesByNoteId(noteId)) {
const branch = treeCache.getBranch(node.data.branchId, true); 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); await server.put('branches/' + branchId + '/expanded/' + expandedNum);
} }
async reloadNotesListener({noteIds, activateNotePath = null}) { // async reloadNotesListener({noteIds, activateNotePath = null}) {
if (noteIds.length === 0) { // if (noteIds.length === 0) {
return; // return;
} // }
//
await treeCache.reloadNotes(noteIds); // await treeCache.reloadNotes(noteIds);
//
if (!activateNotePath) { // if (!activateNotePath) {
activateNotePath = appContext.getActiveTabNotePath(); // activateNotePath = appContext.getActiveTabNotePath();
} // }
//
appContext.trigger('notesReloaded', { noteIds, activateNotePath }); // appContext.trigger('notesReloaded', { noteIds, activateNotePath });
} // }
async reloadTreeListener() { async reloadTreeListener() {
const notes = await treeService.loadTreeData(); 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() { hoistedNoteChangedListener() {
this.reloadTreeListener(); this.reloadTreeListener();
} }