mirror of
https://github.com/zadam/trilium.git
synced 2025-06-06 18:08:33 +02:00
fixed recent notes
This commit is contained in:
parent
f18d25911b
commit
00151beded
7
migrations/0041__recent_notes_with_note_path.sql
Normal file
7
migrations/0041__recent_notes_with_note_path.sql
Normal file
@ -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
|
||||||
|
);
|
@ -16,28 +16,28 @@ const recentNotes = (function() {
|
|||||||
list = result.map(r => r.note_tree_id);
|
list = result.map(r => r.note_tree_id);
|
||||||
});
|
});
|
||||||
|
|
||||||
function addRecentNote(noteTreeId) {
|
function addRecentNote(notePath) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
// 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 (noteTreeId === noteTree.getCurrentNoteTreeId()) {
|
if (notePath === noteTree.getCurrentNotePath()) {
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: baseApiUrl + 'recent-notes/' + noteTreeId,
|
url: baseApiUrl + 'recent-notes/' + encodeURIComponent(notePath),
|
||||||
type: 'PUT',
|
type: 'PUT',
|
||||||
error: () => showError("Error setting recent notes.")
|
error: () => showError("Error setting recent notes.")
|
||||||
}).then(result => {
|
}).then(result => {
|
||||||
list = result.map(r => r.note_tree_id);
|
list = result.map(r => r.note_path);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, 1500);
|
}, 1500);
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeRecentNote(noteTreeIdToRemove) {
|
function removeRecentNote(notePathIdToRemove) {
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: baseApiUrl + 'recent-notes/' + noteTreeIdToRemove,
|
url: baseApiUrl + 'recent-notes/' + notePathIdToRemove,
|
||||||
type: 'DELETE',
|
type: 'DELETE',
|
||||||
error: () => showError("Error removing note from recent notes.")
|
error: () => showError("Error removing note from recent notes.")
|
||||||
}).then(result => {
|
}).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();
|
selectBoxEl.find('option').remove();
|
||||||
|
|
||||||
// remove the current note
|
// remove the current note
|
||||||
const recNotes = list.filter(note => note !== noteEditor.getCurrentNoteId());
|
const recNotes = list.filter(note => note !== noteTree.getCurrentNotePath());
|
||||||
|
|
||||||
$.each(recNotes, (key, valueNoteTreeId) => {
|
$.each(recNotes, (key, valueNotePath) => {
|
||||||
const noteTitle = treeUtils.getFullName(valueNoteTreeId);
|
const noteTitle = treeUtils.getFullNameForPath(valueNotePath);
|
||||||
|
|
||||||
if (!noteTitle) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const option = $("<option></option>")
|
const option = $("<option></option>")
|
||||||
.attr("value", valueNoteTreeId)
|
.attr("value", valueNotePath)
|
||||||
.text(noteTitle);
|
.text(noteTitle);
|
||||||
|
|
||||||
// select the first one (most recent one) by default
|
// 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();
|
return selectBoxEl.find("option:selected").val();
|
||||||
}
|
}
|
||||||
|
|
||||||
function setActiveNoteBasedOnRecentNotes() {
|
function setActiveNoteBasedOnRecentNotes() {
|
||||||
const noteId = getSelectedNoteIdFromRecentNotes();
|
const notePath = getSelectedNotePathFromRecentNotes();
|
||||||
|
|
||||||
noteTree.activateNode(noteId);
|
noteTree.activateNode(notePath);
|
||||||
|
|
||||||
dialogEl.dialog('close');
|
dialogEl.dialog('close');
|
||||||
}
|
}
|
||||||
|
|
||||||
function addLinkBasedOnRecentNotes() {
|
function addLinkBasedOnRecentNotes() {
|
||||||
const noteId = getSelectedNoteIdFromRecentNotes();
|
const notePath = getSelectedNotePathFromRecentNotes();
|
||||||
|
|
||||||
const linkTitle = treeUtils.getNoteTitle(noteId);
|
const linkTitle = treeUtils.getNoteTitle(notePath);
|
||||||
|
|
||||||
dialogEl.dialog("close");
|
dialogEl.dialog("close");
|
||||||
|
|
||||||
@ -99,7 +95,7 @@ const recentNotes = (function() {
|
|||||||
|
|
||||||
noteDetailEl.summernote('createLink', {
|
noteDetailEl.summernote('createLink', {
|
||||||
text: linkTitle,
|
text: linkTitle,
|
||||||
url: 'app#' + noteId,
|
url: 'app#' + notePath,
|
||||||
isNewWindow: true
|
isNewWindow: true
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ const noteTree = (function() {
|
|||||||
let counter = 1;
|
let counter = 1;
|
||||||
let noteTreeIdToKey = {};
|
let noteTreeIdToKey = {};
|
||||||
let parentChildToNoteTreeId = {};
|
let parentChildToNoteTreeId = {};
|
||||||
|
let noteIdToTitle = {};
|
||||||
|
|
||||||
function getNoteTreeIdFromKey(key) {
|
function getNoteTreeIdFromKey(key) {
|
||||||
const node = treeUtils.getNodeByKey(key);
|
const node = treeUtils.getNodeByKey(key);
|
||||||
@ -41,12 +42,25 @@ const noteTree = (function() {
|
|||||||
const noteTreeId = parentChildToNoteTreeId[key];
|
const noteTreeId = parentChildToNoteTreeId[key];
|
||||||
|
|
||||||
if (!noteTreeId) {
|
if (!noteTreeId) {
|
||||||
|
console.trace();
|
||||||
|
|
||||||
throw new Error("Can't find note tree id for parent=" + parentNoteId + ", child=" + childNoteId);
|
throw new Error("Can't find note tree id for parent=" + parentNoteId + ", child=" + childNoteId);
|
||||||
}
|
}
|
||||||
|
|
||||||
return noteTreeId;
|
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) {
|
function prepareNoteTree(notes) {
|
||||||
parentToChildren = {};
|
parentToChildren = {};
|
||||||
childToParents = {};
|
childToParents = {};
|
||||||
@ -55,6 +69,8 @@ const noteTree = (function() {
|
|||||||
for (const note of notes) {
|
for (const note of notes) {
|
||||||
notesMap[note.note_tree_id] = note;
|
notesMap[note.note_tree_id] = note;
|
||||||
|
|
||||||
|
noteIdToTitle[note.note_id] = note.note_title;
|
||||||
|
|
||||||
const key = note.note_pid + "-" + note.note_id;
|
const key = note.note_pid + "-" + note.note_id;
|
||||||
|
|
||||||
parentChildToNoteTreeId[key] = note.note_tree_id;
|
parentChildToNoteTreeId[key] = note.note_tree_id;
|
||||||
@ -225,10 +241,11 @@ const noteTree = (function() {
|
|||||||
scrollParent: $("#tree"),
|
scrollParent: $("#tree"),
|
||||||
activate: (event, data) => {
|
activate: (event, data) => {
|
||||||
const node = data.node.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);
|
noteEditor.switchToNote(node.note_id);
|
||||||
},
|
},
|
||||||
@ -400,6 +417,12 @@ const noteTree = (function() {
|
|||||||
return node.data.note_tree_id;
|
return node.data.note_tree_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getCurrentNotePath() {
|
||||||
|
const node = getCurrentNode();
|
||||||
|
|
||||||
|
return treeUtils.getNotePath(node);
|
||||||
|
}
|
||||||
|
|
||||||
function setCurrentNoteTreeBasedOnProtectedStatus() {
|
function setCurrentNoteTreeBasedOnProtectedStatus() {
|
||||||
const node = getCurrentNode();
|
const node = getCurrentNode();
|
||||||
|
|
||||||
@ -445,6 +468,8 @@ const noteTree = (function() {
|
|||||||
setCurrentNoteTreeBasedOnProtectedStatus,
|
setCurrentNoteTreeBasedOnProtectedStatus,
|
||||||
getCurrentNode,
|
getCurrentNode,
|
||||||
getCurrentNoteTreeId,
|
getCurrentNoteTreeId,
|
||||||
activateNode
|
activateNode,
|
||||||
|
getCurrentNotePath,
|
||||||
|
getNoteTitle
|
||||||
};
|
};
|
||||||
})();
|
})();
|
@ -21,19 +21,17 @@ const treeUtils = (function() {
|
|||||||
return getNodeByKey(key);
|
return getNodeByKey(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getNoteTitle(noteId) {
|
function getNoteIdFromNotePath(notePath) {
|
||||||
const note = treeUtils.getNodeByKey(noteId);
|
const path = notePath.split("/");
|
||||||
if (!note) {
|
|
||||||
return;
|
return path[path.length - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
let noteTitle = note.title;
|
function getFullNameForPath(notePath) {
|
||||||
|
const path = notePath.split("/");
|
||||||
|
const titlePath = path.map(noteId => noteTree.getNoteTitle(noteId));
|
||||||
|
|
||||||
if (noteTitle.endsWith(" (clone)")) {
|
return titlePath.join(" > ");
|
||||||
noteTitle = noteTitle.substr(0, noteTitle.length - 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
return noteTitle;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getFullName(noteTreeId) {
|
function getFullName(noteTreeId) {
|
||||||
@ -73,8 +71,9 @@ const treeUtils = (function() {
|
|||||||
getParentProtectedStatus,
|
getParentProtectedStatus,
|
||||||
getNodeByKey,
|
getNodeByKey,
|
||||||
getNodeByNoteTreeId,
|
getNodeByNoteTreeId,
|
||||||
getNoteTitle,
|
|
||||||
getFullName,
|
getFullName,
|
||||||
getNotePath
|
getFullNameForPath,
|
||||||
|
getNotePath,
|
||||||
|
getNoteIdFromNotePath
|
||||||
};
|
};
|
||||||
})();
|
})();
|
@ -12,26 +12,26 @@ router.get('', auth.checkApiAuth, async (req, res, next) => {
|
|||||||
res.send(await getRecentNotes());
|
res.send(await getRecentNotes());
|
||||||
});
|
});
|
||||||
|
|
||||||
router.put('/:noteTreeId', auth.checkApiAuth, async (req, res, next) => {
|
router.put('/:notePath', auth.checkApiAuth, async (req, res, next) => {
|
||||||
const noteTreeId = req.params.noteTreeId;
|
const notePath = req.params.notePath;
|
||||||
|
|
||||||
await sql.replace('recent_notes', {
|
await sql.replace('recent_notes', {
|
||||||
note_tree_id: noteTreeId,
|
note_path: notePath,
|
||||||
date_accessed: utils.nowTimestamp(),
|
date_accessed: utils.nowTimestamp(),
|
||||||
is_deleted: 0
|
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());
|
res.send(await getRecentNotes());
|
||||||
});
|
});
|
||||||
|
|
||||||
router.delete('/:noteTreeId', auth.checkApiAuth, async (req, res, next) => {
|
router.delete('/:notePath', auth.checkApiAuth, async (req, res, next) => {
|
||||||
await sql.execute('UPDATE recent_notes SET is_deleted = 1 WHERE note_tree_id = ?', [req.params.noteTreeId]);
|
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());
|
res.send(await getRecentNotes());
|
||||||
});
|
});
|
||||||
|
@ -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 = 40;
|
const APP_DB_VERSION = 41;
|
||||||
const MIGRATIONS_DIR = "migrations";
|
const MIGRATIONS_DIR = "migrations";
|
||||||
|
|
||||||
async function migrate() {
|
async function migrate() {
|
||||||
|
@ -194,7 +194,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_tree_id = ?', [sync.entity_id]);
|
entity = await sql.getSingleResult('SELECT * FROM recent_notes WHERE note_path = ?', [sync.entity_id]);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throw new Error("Unrecognized entity type " + sync.entity_name);
|
throw new Error("Unrecognized entity type " + sync.entity_name);
|
||||||
|
@ -22,8 +22,8 @@ async function addOptionsSync(optName, sourceId) {
|
|||||||
await addEntitySync("options", optName, sourceId);
|
await addEntitySync("options", optName, sourceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function addRecentNoteSync(noteTreeId, sourceId) {
|
async function addRecentNoteSync(notePath, sourceId) {
|
||||||
await addEntitySync("recent_notes", noteTreeId, sourceId);
|
await addEntitySync("recent_notes", notePath, sourceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function addEntitySync(entityName, entityId, sourceId) {
|
async function addEntitySync(entityName, entityId, sourceId) {
|
||||||
|
@ -106,7 +106,7 @@ 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_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) {
|
if (orig === null || orig.date_accessed < entity.date_accessed) {
|
||||||
await sql.doInTransaction(async () => {
|
await sql.doInTransaction(async () => {
|
||||||
|
@ -3,11 +3,11 @@
|
|||||||
const crypto = require('crypto');
|
const crypto = require('crypto');
|
||||||
|
|
||||||
function newNoteId() {
|
function newNoteId() {
|
||||||
return randomString(12);
|
return randomString(8);
|
||||||
}
|
}
|
||||||
|
|
||||||
function newNoteTreeId() {
|
function newNoteTreeId() {
|
||||||
return randomString(8);
|
return randomString(12);
|
||||||
}
|
}
|
||||||
|
|
||||||
function newNoteHistoryId() {
|
function newNoteHistoryId() {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user