recent notes are now keyed by note tree id which simplifies things

This commit is contained in:
azivner 2017-12-03 10:06:53 -05:00
parent 41f089b3f4
commit 15faefe8a3
10 changed files with 36 additions and 54 deletions

View File

@ -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';

View File

@ -8,30 +8,24 @@ const recentNotes = (function() {
const addCurrentAsChildEl = $("#recent-notes-add-current-as-child"); const addCurrentAsChildEl = $("#recent-notes-add-current-as-child");
const addRecentAsChildEl = $("#recent-notes-add-recent-as-child"); const addRecentAsChildEl = $("#recent-notes-add-recent-as-child");
const noteDetailEl = $('#note-detail'); const noteDetailEl = $('#note-detail');
// list of recent note paths
let list = []; let list = [];
server.get('recent-notes').then(result => { 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 () => { setTimeout(async () => {
// we include the note into recent list only if the user stayed on the note at least 5 seconds // we include the note into recent list only if the user stayed on the note at least 5 seconds
if (notePath && notePath === noteTree.getCurrentNotePath()) { 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); list = result.map(r => r.note_path);
} }
}, 1500); }, 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() { function showDialog() {
glob.activeDialog = dialogEl; glob.activeDialog = dialogEl;
@ -146,7 +140,6 @@ const recentNotes = (function() {
return { return {
showDialog, showDialog,
addRecentNote, addRecentNote
removeRecentNote
}; };
})(); })();

View File

@ -319,10 +319,11 @@ const noteTree = (function() {
function setCurrentNotePathToHash(node) { function setCurrentNotePathToHash(node) {
const currentNotePath = treeUtils.getNotePath(node); const currentNotePath = treeUtils.getNotePath(node);
const currentNoteTreeId = node.data.note_tree_id;
document.location.hash = currentNotePath; document.location.hash = currentNotePath;
recentNotes.addRecentNote(currentNotePath); recentNotes.addRecentNote(currentNoteTreeId, currentNotePath);
} }
function initFancyTree(noteTree) { function initFancyTree(noteTree) {
@ -343,13 +344,13 @@ const noteTree = (function() {
const beforeNode = node.getPrevSibling(); const beforeNode = node.getPrevSibling();
if (beforeNode !== null) { if (beforeNode !== null) {
treeChanges.moveBeforeNode(node, beforeNode, false); treeChanges.moveBeforeNode(node, beforeNode);
} }
}, },
"shift+down": node => { "shift+down": node => {
let afterNode = node.getNextSibling(); let afterNode = node.getNextSibling();
if (afterNode !== null) { if (afterNode !== null) {
treeChanges.moveAfterNode(node, afterNode, false); treeChanges.moveAfterNode(node, afterNode);
} }
}, },
"shift+left": node => { "shift+left": node => {
@ -625,6 +626,6 @@ const noteTree = (function() {
createNewTopLevelNote, createNewTopLevelNote,
createNote, createNote,
setPrefix, setPrefix,
getNotePathTitle
}; };
})(); })();

View File

@ -1,29 +1,21 @@
"use strict"; "use strict";
const treeChanges = (function() { 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); await server.put('notes/' + node.data.note_tree_id + '/move-before/' + beforeNode.data.note_tree_id);
node.moveTo(beforeNode, 'before'); 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); await server.put('notes/' + node.data.note_tree_id + '/move-after/' + afterNode.data.note_tree_id);
node.moveTo(afterNode, 'after'); 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! // beware that first arg is noteId and second is noteTreeId!
async function cloneNoteAfter(noteId, afterNoteTreeId) { async function cloneNoteAfter(noteId, afterNoteTreeId) {
@ -47,8 +39,6 @@ const treeChanges = (function() {
toNode.folder = true; toNode.folder = true;
toNode.renderTitle(); toNode.renderTitle();
recentNotes.removeRecentNote(noteTree.getCurrentNotePath());
noteTree.setCurrentNotePathToHash(node); noteTree.setCurrentNotePathToHash(node);
} }
@ -75,8 +65,6 @@ const treeChanges = (function() {
node.getParent().renderTitle(); node.getParent().renderTitle();
} }
recentNotes.removeRecentNote(noteTree.getCurrentNotePath());
let next = node.getNextSibling(); let next = node.getNextSibling();
if (!next) { if (!next) {
next = node.getParent(); next = node.getParent();

View File

@ -12,17 +12,19 @@ router.get('', auth.checkApiAuth, async (req, res, next) => {
res.send(await getRecentNotes()); 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; const notePath = req.params.notePath;
await sql.doInTransaction(async () => { await sql.doInTransaction(async () => {
await sql.replace('recent_notes', { await sql.replace('recent_notes', {
note_tree_id: noteTreeId,
note_path: notePath, note_path: notePath,
date_accessed: utils.nowTimestamp(), date_accessed: utils.nowTimestamp(),
is_deleted: 0 is_deleted: 0
}); });
await sync_table.addRecentNoteSync(notePath); await sync_table.addRecentNoteSync(noteTreeId);
await options.setOption('start_note_tree_id', notePath); 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()); 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() { async function getRecentNotes() {
await deleteOld(); await deleteOld();

View File

@ -66,10 +66,10 @@ router.get('/notes_reordering/:noteTreeParentId', auth.checkApiAuth, async (req,
}); });
}); });
router.get('/recent_notes/:notePath', auth.checkApiAuth, async (req, res, next) => { router.get('/recent_notes/:noteTreeId', auth.checkApiAuth, async (req, res, next) => {
const notePath = req.params.notePath; 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) => { router.put('/notes', auth.checkApiAuth, async (req, res, next) => {

View File

@ -22,7 +22,7 @@ async function getContentHash() {
hash = updateHash(hash, await sql.getResults("SELECT note_history_id, note_id, note_title, note_text, " + 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")); "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")); "ORDER BY note_path"));
const questionMarks = Array(options.SYNCED_OPTIONS.length).fill('?').join(','); const questionMarks = Array(options.SYNCED_OPTIONS.length).fill('?').join(',');

View File

@ -4,7 +4,7 @@ const options = require('./options');
const fs = require('fs-extra'); const fs = require('fs-extra');
const log = require('./log'); const log = require('./log');
const APP_DB_VERSION = 47; const APP_DB_VERSION = 48;
const MIGRATIONS_DIR = "migrations"; const MIGRATIONS_DIR = "migrations";
async function migrate() { async function migrate() {

View File

@ -224,7 +224,7 @@ async function readAndPushEntity(sync, syncContext) {
entity = await sql.getSingleResult('SELECT * FROM options WHERE opt_name = ?', [sync.entity_id]); entity = await sql.getSingleResult('SELECT * FROM options WHERE opt_name = ?', [sync.entity_id]);
} }
else if (sync.entity_name === 'recent_notes') { 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 { else {
throw new Error("Unrecognized entity type " + sync.entity_name); throw new Error("Unrecognized entity type " + sync.entity_name);

View File

@ -92,13 +92,13 @@ async function updateOptions(entity, sourceId) {
} }
async function updateRecentNotes(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) { if (orig === null || orig.date_accessed < entity.date_accessed) {
await sql.doInTransaction(async () => { await sql.doInTransaction(async () => {
await sql.replace('recent_notes', entity); await sql.replace('recent_notes', entity);
await sync_table.addRecentNoteSync(entity.note_path, sourceId); await sync_table.addRecentNoteSync(entity.note_tree_id, sourceId);
}); });
} }
} }