mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-31 02:16:05 +01:00 
			
		
		
		
	fixed recent notes
This commit is contained in:
		
							
								
								
									
										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; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         let noteTitle = note.title; |         return path[path.length - 1]; | ||||||
|  |     } | ||||||
|  |  | ||||||
|         if (noteTitle.endsWith(" (clone)")) { |     function getFullNameForPath(notePath) { | ||||||
|             noteTitle = noteTitle.substr(0, noteTitle.length - 8); |         const path = notePath.split("/"); | ||||||
|         } |         const titlePath = path.map(noteId => noteTree.getNoteTitle(noteId)); | ||||||
|  |  | ||||||
|         return noteTitle; |         return titlePath.join(" > "); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     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() { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user