From 00151bededc03d1603e1cb1532cd7353a7335b9c Mon Sep 17 00:00:00 2001 From: azivner Date: Sun, 19 Nov 2017 12:06:48 -0500 Subject: [PATCH] fixed recent notes --- .../0041__recent_notes_with_note_path.sql | 7 ++++ public/javascripts/dialogs/recent_notes.js | 38 +++++++++---------- public/javascripts/note_tree.js | 31 +++++++++++++-- public/javascripts/tree_utils.js | 23 ++++++----- routes/api/recent_notes.js | 16 ++++---- services/migration.js | 2 +- services/sync.js | 2 +- services/sync_table.js | 4 +- services/sync_update.js | 2 +- services/utils.js | 4 +- 10 files changed, 78 insertions(+), 51 deletions(-) create mode 100644 migrations/0041__recent_notes_with_note_path.sql diff --git a/migrations/0041__recent_notes_with_note_path.sql b/migrations/0041__recent_notes_with_note_path.sql new file mode 100644 index 000000000..c83caa699 --- /dev/null +++ b/migrations/0041__recent_notes_with_note_path.sql @@ -0,0 +1,7 @@ +DROP TABLE recent_notes; + +CREATE TABLE `recent_notes` ( + `note_path` TEXT NOT NULL PRIMARY KEY, + `date_accessed` INTEGER NOT NULL , + is_deleted INT +); \ No newline at end of file diff --git a/public/javascripts/dialogs/recent_notes.js b/public/javascripts/dialogs/recent_notes.js index b30f54e91..278a8af90 100644 --- a/public/javascripts/dialogs/recent_notes.js +++ b/public/javascripts/dialogs/recent_notes.js @@ -16,28 +16,28 @@ const recentNotes = (function() { list = result.map(r => r.note_tree_id); }); - function addRecentNote(noteTreeId) { + function addRecentNote(notePath) { setTimeout(() => { // we include the note into recent list only if the user stayed on the note at least 5 seconds - if (noteTreeId === noteTree.getCurrentNoteTreeId()) { + if (notePath === noteTree.getCurrentNotePath()) { $.ajax({ - url: baseApiUrl + 'recent-notes/' + noteTreeId, + url: baseApiUrl + 'recent-notes/' + encodeURIComponent(notePath), type: 'PUT', error: () => showError("Error setting recent notes.") }).then(result => { - list = result.map(r => r.note_tree_id); + list = result.map(r => r.note_path); }); } }, 1500); } - function removeRecentNote(noteTreeIdToRemove) { + function removeRecentNote(notePathIdToRemove) { $.ajax({ - url: baseApiUrl + 'recent-notes/' + noteTreeIdToRemove, + url: baseApiUrl + 'recent-notes/' + notePathIdToRemove, type: 'DELETE', error: () => showError("Error removing note from recent notes.") }).then(result => { - list = result.map(r => r.note_tree_id); + list = result.map(r => r.note_path); }); } @@ -54,17 +54,13 @@ const recentNotes = (function() { selectBoxEl.find('option').remove(); // remove the current note - const recNotes = list.filter(note => note !== noteEditor.getCurrentNoteId()); + const recNotes = list.filter(note => note !== noteTree.getCurrentNotePath()); - $.each(recNotes, (key, valueNoteTreeId) => { - const noteTitle = treeUtils.getFullName(valueNoteTreeId); - - if (!noteTitle) { - return; - } + $.each(recNotes, (key, valueNotePath) => { + const noteTitle = treeUtils.getFullNameForPath(valueNotePath); const option = $("") - .attr("value", valueNoteTreeId) + .attr("value", valueNotePath) .text(noteTitle); // select the first one (most recent one) by default @@ -76,22 +72,22 @@ const recentNotes = (function() { }); } - function getSelectedNoteIdFromRecentNotes() { + function getSelectedNotePathFromRecentNotes() { return selectBoxEl.find("option:selected").val(); } function setActiveNoteBasedOnRecentNotes() { - const noteId = getSelectedNoteIdFromRecentNotes(); + const notePath = getSelectedNotePathFromRecentNotes(); - noteTree.activateNode(noteId); + noteTree.activateNode(notePath); dialogEl.dialog('close'); } function addLinkBasedOnRecentNotes() { - const noteId = getSelectedNoteIdFromRecentNotes(); + const notePath = getSelectedNotePathFromRecentNotes(); - const linkTitle = treeUtils.getNoteTitle(noteId); + const linkTitle = treeUtils.getNoteTitle(notePath); dialogEl.dialog("close"); @@ -99,7 +95,7 @@ const recentNotes = (function() { noteDetailEl.summernote('createLink', { text: linkTitle, - url: 'app#' + noteId, + url: 'app#' + notePath, isNewWindow: true }); } diff --git a/public/javascripts/note_tree.js b/public/javascripts/note_tree.js index 474c389db..d5047fa7c 100644 --- a/public/javascripts/note_tree.js +++ b/public/javascripts/note_tree.js @@ -12,6 +12,7 @@ const noteTree = (function() { let counter = 1; let noteTreeIdToKey = {}; let parentChildToNoteTreeId = {}; + let noteIdToTitle = {}; function getNoteTreeIdFromKey(key) { const node = treeUtils.getNodeByKey(key); @@ -41,12 +42,25 @@ const noteTree = (function() { const noteTreeId = parentChildToNoteTreeId[key]; if (!noteTreeId) { + console.trace(); + throw new Error("Can't find note tree id for parent=" + parentNoteId + ", child=" + childNoteId); } return noteTreeId; } + function getNoteTitle(notePath) { + const noteId = treeUtils.getNoteIdFromNotePath(notePath); + const title = noteIdToTitle[noteId]; + + if (!title) { + throw new Error("Can't find title for noteId=" + noteId); + } + + return title; + } + function prepareNoteTree(notes) { parentToChildren = {}; childToParents = {}; @@ -55,6 +69,8 @@ const noteTree = (function() { for (const note of notes) { notesMap[note.note_tree_id] = note; + noteIdToTitle[note.note_id] = note.note_title; + const key = note.note_pid + "-" + note.note_id; parentChildToNoteTreeId[key] = note.note_tree_id; @@ -225,10 +241,11 @@ const noteTree = (function() { scrollParent: $("#tree"), activate: (event, data) => { const node = data.node.data; + const currentNotePath = treeUtils.getNotePath(data.node); - document.location.hash = treeUtils.getNotePath(data.node); + document.location.hash = currentNotePath; - recentNotes.addRecentNote(node.note_tree_id); + recentNotes.addRecentNote(currentNotePath); noteEditor.switchToNote(node.note_id); }, @@ -400,6 +417,12 @@ const noteTree = (function() { return node.data.note_tree_id; } + function getCurrentNotePath() { + const node = getCurrentNode(); + + return treeUtils.getNotePath(node); + } + function setCurrentNoteTreeBasedOnProtectedStatus() { const node = getCurrentNode(); @@ -445,6 +468,8 @@ const noteTree = (function() { setCurrentNoteTreeBasedOnProtectedStatus, getCurrentNode, getCurrentNoteTreeId, - activateNode + activateNode, + getCurrentNotePath, + getNoteTitle }; })(); \ No newline at end of file diff --git a/public/javascripts/tree_utils.js b/public/javascripts/tree_utils.js index 3edb1d54d..2b0a0c4ad 100644 --- a/public/javascripts/tree_utils.js +++ b/public/javascripts/tree_utils.js @@ -21,19 +21,17 @@ const treeUtils = (function() { return getNodeByKey(key); } - function getNoteTitle(noteId) { - const note = treeUtils.getNodeByKey(noteId); - if (!note) { - return; - } + function getNoteIdFromNotePath(notePath) { + const path = notePath.split("/"); - let noteTitle = note.title; + return path[path.length - 1]; + } - if (noteTitle.endsWith(" (clone)")) { - noteTitle = noteTitle.substr(0, noteTitle.length - 8); - } + function getFullNameForPath(notePath) { + const path = notePath.split("/"); + const titlePath = path.map(noteId => noteTree.getNoteTitle(noteId)); - return noteTitle; + return titlePath.join(" > "); } function getFullName(noteTreeId) { @@ -73,8 +71,9 @@ const treeUtils = (function() { getParentProtectedStatus, getNodeByKey, getNodeByNoteTreeId, - getNoteTitle, getFullName, - getNotePath + getFullNameForPath, + getNotePath, + getNoteIdFromNotePath }; })(); \ No newline at end of file diff --git a/routes/api/recent_notes.js b/routes/api/recent_notes.js index 14baf4d20..9b106119b 100644 --- a/routes/api/recent_notes.js +++ b/routes/api/recent_notes.js @@ -12,26 +12,26 @@ router.get('', auth.checkApiAuth, async (req, res, next) => { res.send(await getRecentNotes()); }); -router.put('/:noteTreeId', auth.checkApiAuth, async (req, res, next) => { - const noteTreeId = req.params.noteTreeId; +router.put('/:notePath', auth.checkApiAuth, async (req, res, next) => { + const notePath = req.params.notePath; await sql.replace('recent_notes', { - note_tree_id: noteTreeId, + note_path: notePath, date_accessed: utils.nowTimestamp(), is_deleted: 0 }); - await sync_table.addRecentNoteSync(noteTreeId); + await sync_table.addRecentNoteSync(notePath); - await options.setOption('start_note_tree_id', noteTreeId); + await options.setOption('start_note_tree_id', notePath); res.send(await getRecentNotes()); }); -router.delete('/:noteTreeId', auth.checkApiAuth, async (req, res, next) => { - await sql.execute('UPDATE recent_notes SET is_deleted = 1 WHERE note_tree_id = ?', [req.params.noteTreeId]); +router.delete('/:notePath', auth.checkApiAuth, async (req, res, next) => { + await sql.execute('UPDATE recent_notes SET is_deleted = 1 WHERE note_path = ?', [req.params.notePath]); - await sync_table.addRecentNoteSync(req.params.noteTreeId); + await sync_table.addRecentNoteSync(req.params.notePath); res.send(await getRecentNotes()); }); diff --git a/services/migration.js b/services/migration.js index 25f2dd352..dc949053f 100644 --- a/services/migration.js +++ b/services/migration.js @@ -4,7 +4,7 @@ const options = require('./options'); const fs = require('fs-extra'); const log = require('./log'); -const APP_DB_VERSION = 40; +const APP_DB_VERSION = 41; const MIGRATIONS_DIR = "migrations"; async function migrate() { diff --git a/services/sync.js b/services/sync.js index 4a13080a8..5a8e0ca65 100644 --- a/services/sync.js +++ b/services/sync.js @@ -194,7 +194,7 @@ async function readAndPushEntity(sync, syncContext) { entity = await sql.getSingleResult('SELECT * FROM options WHERE opt_name = ?', [sync.entity_id]); } else if (sync.entity_name === 'recent_notes') { - entity = await sql.getSingleResult('SELECT * FROM recent_notes WHERE note_tree_id = ?', [sync.entity_id]); + entity = await sql.getSingleResult('SELECT * FROM recent_notes WHERE note_path = ?', [sync.entity_id]); } else { throw new Error("Unrecognized entity type " + sync.entity_name); diff --git a/services/sync_table.js b/services/sync_table.js index 6cebc62af..e34b2d63c 100644 --- a/services/sync_table.js +++ b/services/sync_table.js @@ -22,8 +22,8 @@ async function addOptionsSync(optName, sourceId) { await addEntitySync("options", optName, sourceId); } -async function addRecentNoteSync(noteTreeId, sourceId) { - await addEntitySync("recent_notes", noteTreeId, sourceId); +async function addRecentNoteSync(notePath, sourceId) { + await addEntitySync("recent_notes", notePath, sourceId); } async function addEntitySync(entityName, entityId, sourceId) { diff --git a/services/sync_update.js b/services/sync_update.js index b590f606f..6ae069d8b 100644 --- a/services/sync_update.js +++ b/services/sync_update.js @@ -106,7 +106,7 @@ async function updateOptions(entity, sourceId) { } async function updateRecentNotes(entity, sourceId) { - const orig = await sql.getSingleResultOrNull("select * from recent_notes where note_tree_id = ?", [entity.note_tree_id]); + const orig = await sql.getSingleResultOrNull("select * from recent_notes where note_path = ?", [entity.note_path]); if (orig === null || orig.date_accessed < entity.date_accessed) { await sql.doInTransaction(async () => { diff --git a/services/utils.js b/services/utils.js index 2acda8488..ba4b9516e 100644 --- a/services/utils.js +++ b/services/utils.js @@ -3,11 +3,11 @@ const crypto = require('crypto'); function newNoteId() { - return randomString(12); + return randomString(8); } function newNoteTreeId() { - return randomString(8); + return randomString(12); } function newNoteHistoryId() {