From b22eb2db1e2b16e0375afeff4403178527033292 Mon Sep 17 00:00:00 2001 From: azivner Date: Sun, 19 Nov 2017 08:47:22 -0500 Subject: [PATCH] support for note path --- public/javascripts/dialogs/jump_to_note.js | 2 +- public/javascripts/dialogs/recent_notes.js | 5 +- public/javascripts/link.js | 6 +- public/javascripts/note_tree.js | 71 ++++++++++++++++------ public/javascripts/tree_utils.js | 43 +++++-------- services/notes.js | 4 +- services/utils.js | 10 +++ 7 files changed, 86 insertions(+), 55 deletions(-) diff --git a/public/javascripts/dialogs/jump_to_note.js b/public/javascripts/dialogs/jump_to_note.js index 8b6f494c8..dac1f3803 100644 --- a/public/javascripts/dialogs/jump_to_note.js +++ b/public/javascripts/dialogs/jump_to_note.js @@ -28,7 +28,7 @@ const jumpToNote = (function() { const noteId = link.getNodeIdFromLabel(val); if (noteId) { - treeUtils.activateNode(noteId); + noteTree.activateNode(noteId); dialogEl.dialog('close'); } diff --git a/public/javascripts/dialogs/recent_notes.js b/public/javascripts/dialogs/recent_notes.js index 4278aece2..b30f54e91 100644 --- a/public/javascripts/dialogs/recent_notes.js +++ b/public/javascripts/dialogs/recent_notes.js @@ -18,9 +18,6 @@ const recentNotes = (function() { function addRecentNote(noteTreeId) { setTimeout(() => { - console.log("note tree: " + noteTreeId); - console.log("current note tree: " + noteTree.getCurrentNoteTreeId()); - // we include the note into recent list only if the user stayed on the note at least 5 seconds if (noteTreeId === noteTree.getCurrentNoteTreeId()) { $.ajax({ @@ -86,7 +83,7 @@ const recentNotes = (function() { function setActiveNoteBasedOnRecentNotes() { const noteId = getSelectedNoteIdFromRecentNotes(); - treeUtils.activateNode(noteId); + noteTree.activateNode(noteId); dialogEl.dialog('close'); } diff --git a/public/javascripts/link.js b/public/javascripts/link.js index ee9e2a8de..541f401d6 100644 --- a/public/javascripts/link.js +++ b/public/javascripts/link.js @@ -2,7 +2,7 @@ const link = (function() { function getNoteIdFromLink(url) { - const noteIdMatch = /app#([A-Za-z0-9]{12})/.exec(url); + const noteIdMatch = /app#([A-Za-z0-9]+)$/.exec(url); if (noteIdMatch === null) { return null; @@ -13,7 +13,7 @@ const link = (function() { } function getNodeIdFromLabel(label) { - const noteIdMatch = / \(([A-Za-z0-9]{12})\)/.exec(label); + const noteIdMatch = / \(([A-Za-z0-9]+)\)/.exec(label); if (noteIdMatch !== null) { return noteIdMatch[1]; @@ -41,7 +41,7 @@ const link = (function() { } if (noteId) { - treeUtils.activateNode(noteId); + noteTree.activateNode(noteId); // this is quite ugly hack, but it seems like we can't close the tooltip otherwise $("[role='tooltip']").remove(); diff --git a/public/javascripts/note_tree.js b/public/javascripts/note_tree.js index 7da0503a7..e7d6c55ce 100644 --- a/public/javascripts/note_tree.js +++ b/public/javascripts/note_tree.js @@ -7,7 +7,8 @@ const noteTree = (function() { let treeLoadTime = null; let clipboardNoteTreeId = null; let notesMap = {}; - let parentToNotes = {}; + let parentToChildren = {}; + let childToParents = {}; let counter = 1; let noteTreeIdToKey = {}; @@ -34,7 +35,8 @@ const noteTree = (function() { } function prepareNoteTree(notes, notesParent) { - parentToNotes = {}; + parentToChildren = {}; + childToParents = {}; notesMap = {}; for (const note of notes) { @@ -42,16 +44,22 @@ const noteTree = (function() { } for (const np of notesParent) { - if (!parentToNotes[np.parent_id]) { - parentToNotes[np.parent_id] = []; + if (!parentToChildren[np.parent_id]) { + parentToChildren[np.parent_id] = []; } - parentToNotes[np.parent_id].push(np.child_id); + parentToChildren[np.parent_id].push(np.child_id); + + if (!childToParents[np.child_id]) { + childToParents[np.child_id] = []; + } + + childToParents[np.child_id].push(np.parent_id); } glob.allNoteIds = Object.keys(notesMap); - return prepareNoteTreeInner(parentToNotes['root']); + return prepareNoteTreeInner(parentToChildren['root']); } function prepareNoteTreeInner(noteTreeIds) { @@ -71,11 +79,11 @@ const noteTree = (function() { noteTreeIdToKey[noteTreeId] = note.key; - if (parentToNotes[noteTreeId] && parentToNotes[noteTreeId].length > 0) { + if (parentToChildren[noteTreeId] && parentToChildren[noteTreeId].length > 0) { note.folder = true; if (note.expanded) { - note.children = prepareNoteTreeInner(parentToNotes[noteTreeId], notesMap, parentToNotes); + note.children = prepareNoteTreeInner(parentToChildren[noteTreeId], notesMap, parentToChildren); } else { note.lazy = true; @@ -88,6 +96,36 @@ const noteTree = (function() { return noteList; } + async function activateNode(notePath) { + const path = notePath.split("/").reverse(); + + if (!notesMap[path[0]]) { + console.log("Requested note doesn't exist."); + return; + } + + const effectivePath = []; + + for (const noteTreeId of path) { + effectivePath.push(noteTreeId); + } + + const runPath = effectivePath.reverse(); + + for (let i = 0; i < runPath.length; i++) { + const noteTreeId = runPath[i]; + + const node = treeUtils.getNodeByNoteTreeId(noteTreeId); + + if (i < runPath.length - 1) { + await node.setExpanded(); + } + else { + await node.setActive(); + } + } + } + function setExpandedToServer(noteTreeId, isExpanded) { const expandedNum = isExpanded ? 1 : 0; @@ -150,7 +188,7 @@ const noteTree = (function() { activate: (event, data) => { const node = data.node.data; - document.location.hash = node.note_tree_id; + document.location.hash = treeUtils.getNotePath(data.node); recentNotes.addRecentNote(node.note_tree_id); @@ -163,13 +201,9 @@ const noteTree = (function() { setExpandedToServer(getNoteTreeIdFromKey(data.node.key), false); }, init: (event, data) => { - // if (startNoteTreeId) { - // treeUtils.activateNode(startNoteTreeId); - // } - - - - showAppIfHidden(); + if (startNoteTreeId) { + activateNode(startNoteTreeId); + } }, hotkeys: { keydown: keybindings @@ -237,8 +271,8 @@ const noteTree = (function() { const node = data.node.data; const noteTreeId = node.note_tree_id; - if (parentToNotes[noteTreeId]) { - data.result = prepareNoteTreeInner(parentToNotes[noteTreeId]); + if (parentToChildren[noteTreeId]) { + data.result = prepareNoteTreeInner(parentToChildren[noteTreeId]); } else { console.log("No children for " + noteTreeId + ". This shouldn't happen."); @@ -372,5 +406,6 @@ const noteTree = (function() { setCurrentNoteTreeBasedOnProtectedStatus, getCurrentNode, getCurrentNoteTreeId, + activateNode }; })(); \ No newline at end of file diff --git a/public/javascripts/tree_utils.js b/public/javascripts/tree_utils.js index 0826bef9d..1d0646add 100644 --- a/public/javascripts/tree_utils.js +++ b/public/javascripts/tree_utils.js @@ -21,31 +21,6 @@ const treeUtils = (function() { return getNodeByKey(key); } - async function activateNode(noteTreeIdToActivate) { - const noteTreeIdPath = [ noteTreeIdToActivate ]; - - let note = noteTree.getByNoteId(noteTreeIdToActivate); - - while (note) { - if (note.note_pid !== 'root') { - noteTreeIdPath.push(note.note_pid); - } - - note = noteTree.getByNoteId(note.note_pid); - } - - for (const noteTreeId of noteTreeIdPath.reverse()) { - const node = treeUtils.getNodeByNoteTreeId(noteTreeId); - - if (noteTreeId !== noteTreeIdToActivate) { - await node.setExpanded(); - } - else { - await node.setActive(); - } - } - } - function getNoteTitle(noteId) { const note = treeUtils.getNodeByKey(noteId); if (!note) { @@ -79,13 +54,27 @@ const treeUtils = (function() { return path.reverse().join(" > "); } + function getNotePath(node) { + const path = []; + + while (node) { + if (node.data.note_tree_id) { + path.push(node.data.note_tree_id); + } + + node = node.getParent(); + } + + return path.reverse().join("/"); + } + return { getParentNoteTreeId, getParentProtectedStatus, getNodeByKey, getNodeByNoteTreeId, - activateNode, getNoteTitle, - getFullName + getFullName, + getNotePath }; })(); \ No newline at end of file diff --git a/services/notes.js b/services/notes.js index 2cdc57ba7..eea4a5ca6 100644 --- a/services/notes.js +++ b/services/notes.js @@ -8,7 +8,7 @@ const sync_table = require('./sync_table'); async function createNewNote(parentNoteId, note, browserId) { const noteId = utils.newNoteId(); - const noteTreeId = utils.newNoteId(); + const noteTreeId = utils.newNoteTreeId(); let newNotePos = 0; @@ -156,7 +156,7 @@ async function updateNote(noteId, newNote, ctx) { await sql.doInTransaction(async () => { if (!existingNoteHistoryId) { - const newNoteHistoryId = utils.randomString(16); + const newNoteHistoryId = utils.newNoteHistoryId(); await sql.execute("insert into notes_history (note_history_id, note_id, note_title, note_text, is_protected, date_modified_from, date_modified_to) " + "values (?, ?, ?, ?, ?, ?, ?)", [ diff --git a/services/utils.js b/services/utils.js index 928a9edb3..2acda8488 100644 --- a/services/utils.js +++ b/services/utils.js @@ -6,6 +6,14 @@ function newNoteId() { return randomString(12); } +function newNoteTreeId() { + return randomString(8); +} + +function newNoteHistoryId() { + return randomString(12); +} + const ALPHA_NUMERIC = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; function randomString(length) { @@ -63,6 +71,8 @@ module.exports = { randomString, nowTimestamp, newNoteId, + newNoteTreeId, + newNoteHistoryId, toBase64, fromBase64, hmac,