diff --git a/migrations/0048__add_note_tree_id_to_recent_notes.sql b/migrations/0048__add_note_tree_id_to_recent_notes.sql new file mode 100644 index 000000000..3fbc03066 --- /dev/null +++ b/migrations/0048__add_note_tree_id_to_recent_notes.sql @@ -0,0 +1,10 @@ +DROP TABLE recent_notes; + +CREATE TABLE `recent_notes` ( + 'note_tree_id'TEXT NOT NULL PRIMARY KEY, + `note_path` TEXT NOT NULL, + `date_accessed` INTEGER NOT NULL , + is_deleted INT +); + +DELETE FROM sync WHERE entity_name = 'recent_notes'; \ No newline at end of file diff --git a/public/javascripts/dialogs/recent_notes.js b/public/javascripts/dialogs/recent_notes.js index 1c1e8d29e..372288129 100644 --- a/public/javascripts/dialogs/recent_notes.js +++ b/public/javascripts/dialogs/recent_notes.js @@ -8,30 +8,24 @@ const recentNotes = (function() { const addCurrentAsChildEl = $("#recent-notes-add-current-as-child"); const addRecentAsChildEl = $("#recent-notes-add-recent-as-child"); const noteDetailEl = $('#note-detail'); + // list of recent note paths let list = []; server.get('recent-notes').then(result => { - list = result.map(r => r.note_tree_id); + list = result.map(r => r.note_path); }); - function addRecentNote(notePath) { + function addRecentNote(noteTreeId, notePath) { setTimeout(async () => { // we include the note into recent list only if the user stayed on the note at least 5 seconds if (notePath && notePath === noteTree.getCurrentNotePath()) { - const result = await server.put('recent-notes/' + encodeURIComponent(notePath)); + const result = await server.put('recent-notes/' + noteTreeId + '/' + encodeURIComponent(notePath)); list = result.map(r => r.note_path); } }, 1500); } - // FIXME: this should be probably just refresh upon deletion, not explicit delete - async function removeRecentNote(notePathIdToRemove) { - const result = await server.remove('recent-notes/' + encodeURIComponent(notePathIdToRemove)); - - list = result.map(r => r.note_path); - } - function showDialog() { glob.activeDialog = dialogEl; @@ -146,7 +140,6 @@ const recentNotes = (function() { return { showDialog, - addRecentNote, - removeRecentNote + addRecentNote }; })(); \ No newline at end of file diff --git a/public/javascripts/note_tree.js b/public/javascripts/note_tree.js index 4ef6e0756..edd23cf10 100644 --- a/public/javascripts/note_tree.js +++ b/public/javascripts/note_tree.js @@ -319,10 +319,11 @@ const noteTree = (function() { function setCurrentNotePathToHash(node) { const currentNotePath = treeUtils.getNotePath(node); + const currentNoteTreeId = node.data.note_tree_id; document.location.hash = currentNotePath; - recentNotes.addRecentNote(currentNotePath); + recentNotes.addRecentNote(currentNoteTreeId, currentNotePath); } function initFancyTree(noteTree) { @@ -343,13 +344,13 @@ const noteTree = (function() { const beforeNode = node.getPrevSibling(); if (beforeNode !== null) { - treeChanges.moveBeforeNode(node, beforeNode, false); + treeChanges.moveBeforeNode(node, beforeNode); } }, "shift+down": node => { let afterNode = node.getNextSibling(); if (afterNode !== null) { - treeChanges.moveAfterNode(node, afterNode, false); + treeChanges.moveAfterNode(node, afterNode); } }, "shift+left": node => { @@ -625,6 +626,6 @@ const noteTree = (function() { createNewTopLevelNote, createNote, setPrefix, - + getNotePathTitle }; })(); \ No newline at end of file diff --git a/public/javascripts/tree_changes.js b/public/javascripts/tree_changes.js index 94e8dc0cb..c18e35d97 100644 --- a/public/javascripts/tree_changes.js +++ b/public/javascripts/tree_changes.js @@ -1,28 +1,20 @@ "use strict"; const treeChanges = (function() { - async function moveBeforeNode(node, beforeNode, changeInPath = true) { + async function moveBeforeNode(node, beforeNode) { await server.put('notes/' + node.data.note_tree_id + '/move-before/' + beforeNode.data.note_tree_id); node.moveTo(beforeNode, 'before'); - if (changeInPath) { - recentNotes.removeRecentNote(noteTree.getCurrentNotePath()); - - noteTree.setCurrentNotePathToHash(node); - } + noteTree.setCurrentNotePathToHash(node); } - async function moveAfterNode(node, afterNode, changeInPath = true) { + async function moveAfterNode(node, afterNode) { await server.put('notes/' + node.data.note_tree_id + '/move-after/' + afterNode.data.note_tree_id); node.moveTo(afterNode, 'after'); - if (changeInPath) { - recentNotes.removeRecentNote(noteTree.getCurrentNotePath()); - - noteTree.setCurrentNotePathToHash(node); - } + noteTree.setCurrentNotePathToHash(node); } // beware that first arg is noteId and second is noteTreeId! @@ -47,8 +39,6 @@ const treeChanges = (function() { toNode.folder = true; toNode.renderTitle(); - recentNotes.removeRecentNote(noteTree.getCurrentNotePath()); - noteTree.setCurrentNotePathToHash(node); } @@ -75,8 +65,6 @@ const treeChanges = (function() { node.getParent().renderTitle(); } - recentNotes.removeRecentNote(noteTree.getCurrentNotePath()); - let next = node.getNextSibling(); if (!next) { next = node.getParent(); diff --git a/routes/api/recent_notes.js b/routes/api/recent_notes.js index a3c6a807a..1b78c8151 100644 --- a/routes/api/recent_notes.js +++ b/routes/api/recent_notes.js @@ -12,17 +12,19 @@ router.get('', auth.checkApiAuth, async (req, res, next) => { res.send(await getRecentNotes()); }); -router.put('/:notePath', auth.checkApiAuth, async (req, res, next) => { +router.put('/:noteTreeId/:notePath', auth.checkApiAuth, async (req, res, next) => { + const noteTreeId = req.params.noteTreeId; const notePath = req.params.notePath; await sql.doInTransaction(async () => { await sql.replace('recent_notes', { + note_tree_id: noteTreeId, note_path: notePath, date_accessed: utils.nowTimestamp(), is_deleted: 0 }); - await sync_table.addRecentNoteSync(notePath); + await sync_table.addRecentNoteSync(noteTreeId); await options.setOption('start_note_tree_id', notePath); }); @@ -30,18 +32,6 @@ router.put('/:notePath', auth.checkApiAuth, async (req, res, next) => { res.send(await getRecentNotes()); }); -router.delete('/:notePath', auth.checkApiAuth, async (req, res, next) => { - const notePath = req.params.notePath; - - await sql.doInTransaction(async () => { - await sql.execute('UPDATE recent_notes SET is_deleted = 1 WHERE note_path = ?', [notePath]); - - await sync_table.addRecentNoteSync(notePath); - }); - - res.send(await getRecentNotes()); -}); - async function getRecentNotes() { await deleteOld(); diff --git a/routes/api/sync.js b/routes/api/sync.js index 18fc9c640..ed9a2e361 100644 --- a/routes/api/sync.js +++ b/routes/api/sync.js @@ -66,10 +66,10 @@ router.get('/notes_reordering/:noteTreeParentId', auth.checkApiAuth, async (req, }); }); -router.get('/recent_notes/:notePath', auth.checkApiAuth, async (req, res, next) => { - const notePath = req.params.notePath; +router.get('/recent_notes/:noteTreeId', auth.checkApiAuth, async (req, res, next) => { + const noteTreeId = req.params.noteTreeId; - res.send(await sql.getSingleResult("SELECT * FROM recent_notes WHERE note_path = ?", [notePath])); + res.send(await sql.getSingleResult("SELECT * FROM recent_notes WHERE note_tree_id = ?", [noteTreeId])); }); router.put('/notes', auth.checkApiAuth, async (req, res, next) => { diff --git a/services/content_hash.js b/services/content_hash.js index 0bf118761..e0494d34b 100644 --- a/services/content_hash.js +++ b/services/content_hash.js @@ -22,7 +22,7 @@ async function getContentHash() { hash = updateHash(hash, await sql.getResults("SELECT note_history_id, note_id, note_title, note_text, " + "date_modified_from, date_modified_to FROM notes_history ORDER BY note_history_id")); - hash = updateHash(hash, await sql.getResults("SELECT note_path, date_accessed, is_deleted FROM recent_notes " + + hash = updateHash(hash, await sql.getResults("SELECT note_tree_id, note_path, date_accessed, is_deleted FROM recent_notes " + "ORDER BY note_path")); const questionMarks = Array(options.SYNCED_OPTIONS.length).fill('?').join(','); diff --git a/services/migration.js b/services/migration.js index 1ab2ed09b..39771eac4 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 = 47; +const APP_DB_VERSION = 48; const MIGRATIONS_DIR = "migrations"; async function migrate() { diff --git a/services/sync.js b/services/sync.js index cd1fb0a7c..d59a74986 100644 --- a/services/sync.js +++ b/services/sync.js @@ -224,7 +224,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_path = ?', [sync.entity_id]); + entity = await sql.getSingleResult('SELECT * FROM recent_notes WHERE note_tree_id = ?', [sync.entity_id]); } else { throw new Error("Unrecognized entity type " + sync.entity_name); diff --git a/services/sync_update.js b/services/sync_update.js index 034fe03f1..5b486cd28 100644 --- a/services/sync_update.js +++ b/services/sync_update.js @@ -92,13 +92,13 @@ async function updateOptions(entity, sourceId) { } async function updateRecentNotes(entity, sourceId) { - const orig = await sql.getSingleResultOrNull("SELECT * FROM recent_notes WHERE note_path = ?", [entity.note_path]); + const orig = await sql.getSingleResultOrNull("SELECT * FROM recent_notes WHERE note_tree_id = ?", [entity.note_tree_id]); if (orig === null || orig.date_accessed < entity.date_accessed) { await sql.doInTransaction(async () => { await sql.replace('recent_notes', entity); - await sync_table.addRecentNoteSync(entity.note_path, sourceId); + await sync_table.addRecentNoteSync(entity.note_tree_id, sourceId); }); } }