mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-31 18:36:30 +01:00 
			
		
		
		
	Compare commits
	
		
			8 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 5b30291601 | ||
|  | 5193f073e9 | ||
|  | 6c7d8a9667 | ||
|  | 5e9bedd903 | ||
|  | e712990c03 | ||
|  | 91487b338a | ||
|  | 3ff24d53e5 | ||
|  | 94c904fb40 | 
| @@ -1,6 +1,6 @@ | |||||||
| <?xml version="1.0" encoding="UTF-8"?> | <?xml version="1.0" encoding="UTF-8"?> | ||||||
| <dataSource name="document.db"> | <dataSource name="document.db"> | ||||||
|   <database-model serializer="dbm" dbms="SQLITE" family-id="SQLITE" format-version="4.16"> |   <database-model serializer="dbm" dbms="SQLITE" family-id="SQLITE" format-version="4.17"> | ||||||
|     <root id="1"> |     <root id="1"> | ||||||
|       <ServerVersion>3.25.1</ServerVersion> |       <ServerVersion>3.25.1</ServerVersion> | ||||||
|     </root> |     </root> | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										2
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							| @@ -1,6 +1,6 @@ | |||||||
| { | { | ||||||
|   "name": "trilium", |   "name": "trilium", | ||||||
|   "version": "0.37.4", |   "version": "0.37.5", | ||||||
|   "lockfileVersion": 1, |   "lockfileVersion": 1, | ||||||
|   "requires": true, |   "requires": true, | ||||||
|   "dependencies": { |   "dependencies": { | ||||||
|   | |||||||
| @@ -2,7 +2,7 @@ | |||||||
|   "name": "trilium", |   "name": "trilium", | ||||||
|   "productName": "Trilium Notes", |   "productName": "Trilium Notes", | ||||||
|   "description": "Trilium Notes", |   "description": "Trilium Notes", | ||||||
|   "version": "0.37.5", |   "version": "0.37.6", | ||||||
|   "license": "AGPL-3.0-only", |   "license": "AGPL-3.0-only", | ||||||
|   "main": "electron.js", |   "main": "electron.js", | ||||||
|   "bin": { |   "bin": { | ||||||
|   | |||||||
| @@ -788,6 +788,7 @@ class Note extends Entity { | |||||||
|         delete pojo.isContentAvailable; |         delete pojo.isContentAvailable; | ||||||
|         delete pojo.__attributeCache; |         delete pojo.__attributeCache; | ||||||
|         delete pojo.content; |         delete pojo.content; | ||||||
|  |         /** zero references to contentHash, probably can be removed */ | ||||||
|         delete pojo.contentHash; |         delete pojo.contentHash; | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -93,7 +93,7 @@ export default class SidebarOptions { | |||||||
|         this.$sidebarMinWidth.val(options.sidebarMinWidth); |         this.$sidebarMinWidth.val(options.sidebarMinWidth); | ||||||
|         this.$sidebarWidthPercent.val(options.sidebarWidthPercent); |         this.$sidebarWidthPercent.val(options.sidebarWidthPercent); | ||||||
|  |  | ||||||
|         if (parseInt(options.showSidebarInNewTab)) { |         if (options.showSidebarInNewTab === 'true') { | ||||||
|             this.$showSidebarInNewTab.attr("checked", "checked"); |             this.$showSidebarInNewTab.attr("checked", "checked"); | ||||||
|         } |         } | ||||||
|         else { |         else { | ||||||
|   | |||||||
| @@ -273,7 +273,9 @@ async function filterTabs(noteId) { | |||||||
|  |  | ||||||
| async function noteDeleted(noteId) { | async function noteDeleted(noteId) { | ||||||
|     for (const tc of tabContexts) { |     for (const tc of tabContexts) { | ||||||
|         if (tc.notePath && tc.notePath.split("/").includes(noteId)) { |         // not removing active even if it contains deleted note since that one will move to another note (handled by deletion logic) | ||||||
|  |         // and we would lose tab context state (e.g. sidebar visibility) | ||||||
|  |         if (!tc.isActive() && tc.notePath && tc.notePath.split("/").includes(noteId)) { | ||||||
|             await tabRow.removeTab(tc.$tab[0]); |             await tabRow.removeTab(tc.$tab[0]); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -246,11 +246,15 @@ class TabContext { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     setCurrentNotePathToHash() { |     setCurrentNotePathToHash() { | ||||||
|         if (this.$tab[0] === this.tabRow.activeTabEl) { |         if (this.isActive()) { | ||||||
|             document.location.hash = (this.notePath || "") + "-" + this.tabId; |             document.location.hash = (this.notePath || "") + "-" + this.tabId; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     isActive() { | ||||||
|  |         return this.$tab[0] === this.tabRow.activeTabEl; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     setupClasses() { |     setupClasses() { | ||||||
|         for (const clazz of Array.from(this.$tab[0].classList)) { // create copy to safely iterate over while removing classes |         for (const clazz of Array.from(this.$tab[0].classList)) { // create copy to safely iterate over while removing classes | ||||||
|             if (clazz !== 'note-tab') { |             if (clazz !== 'note-tab') { | ||||||
|   | |||||||
| @@ -42,7 +42,7 @@ class TreeContextMenu { | |||||||
|                 || (selNodes.length === 1 && selNodes[0] === this.node); |                 || (selNodes.length === 1 && selNodes[0] === this.node); | ||||||
|  |  | ||||||
|         const notSearch = note.type !== 'search'; |         const notSearch = note.type !== 'search'; | ||||||
|         const parentNotSearch = parentNote.type !== 'search'; |         const parentNotSearch = !parentNote || parentNote.type !== 'search'; | ||||||
|         const insertNoteAfterEnabled = isNotRoot && !isHoisted && parentNotSearch; |         const insertNoteAfterEnabled = isNotRoot && !isHoisted && parentNotSearch; | ||||||
|  |  | ||||||
|         return [ |         return [ | ||||||
| @@ -79,7 +79,7 @@ class TreeContextMenu { | |||||||
|             { title: "Paste after", cmd: "pasteAfter", uiIcon: "paste", |             { title: "Paste after", cmd: "pasteAfter", uiIcon: "paste", | ||||||
|                 enabled: !clipboard.isClipboardEmpty() && isNotRoot && !isHoisted && parentNotSearch && noSelectedNotes }, |                 enabled: !clipboard.isClipboardEmpty() && isNotRoot && !isHoisted && parentNotSearch && noSelectedNotes }, | ||||||
|             { title: "Duplicate note here", cmd: "duplicateNote", uiIcon: "empty", |             { title: "Duplicate note here", cmd: "duplicateNote", uiIcon: "empty", | ||||||
|                 enabled: noSelectedNotes && parentNotSearch && (!note.isProtected || protectedSessionHolder.isProtectedSessionAvailable()) }, |                 enabled: noSelectedNotes && parentNotSearch && isNotRoot && !isHoisted && (!note.isProtected || protectedSessionHolder.isProtectedSessionAvailable()) }, | ||||||
|             { title: "----" }, |             { title: "----" }, | ||||||
|             { title: "Export", cmd: "export", uiIcon: "empty", |             { title: "Export", cmd: "export", uiIcon: "empty", | ||||||
|                 enabled: notSearch && noSelectedNotes }, |                 enabled: notSearch && noSelectedNotes }, | ||||||
|   | |||||||
| @@ -89,6 +89,11 @@ body { | |||||||
|     font-size: inherit; |     font-size: inherit; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | #context-menu-container { | ||||||
|  |     max-height: 100vh; | ||||||
|  |     overflow: auto; /* make it scrollable when exceeding total height of the window */ | ||||||
|  | } | ||||||
|  |  | ||||||
| #context-menu-container, #context-menu-container .dropdown-menu { | #context-menu-container, #context-menu-container .dropdown-menu { | ||||||
|     padding: 3px 0 0; |     padding: 3px 0 0; | ||||||
|     z-index: 1111; |     z-index: 1111; | ||||||
|   | |||||||
| @@ -1 +1 @@ | |||||||
| module.exports = { buildDate:"2019-11-25T22:46:15+01:00", buildRevision: "bf9ad976b9bf340db3d47db72ddf0857a04de178" }; | module.exports = { buildDate:"2019-11-26T22:50:08+01:00", buildRevision: "5193f073e9e55f5440fe2e71fbd2cdfcdb2d2c6b" }; | ||||||
|   | |||||||
| @@ -3,6 +3,7 @@ const fileType = require('file-type'); | |||||||
| const stream = require('stream'); | const stream = require('stream'); | ||||||
| const log = require("../log"); | const log = require("../log"); | ||||||
| const utils = require("../utils"); | const utils = require("../utils"); | ||||||
|  | const sql = require("../sql"); | ||||||
| const noteService = require("../notes"); | const noteService = require("../notes"); | ||||||
| const imageService = require("../image"); | const imageService = require("../image"); | ||||||
| const protectedSessionService = require('../protected_session'); | const protectedSessionService = require('../protected_session'); | ||||||
| @@ -11,7 +12,7 @@ const protectedSessionService = require('../protected_session'); | |||||||
| function parseDate(text) { | function parseDate(text) { | ||||||
|     // insert - and : to make it ISO format |     // insert - and : to make it ISO format | ||||||
|     text = text.substr(0, 4) + "-" + text.substr(4, 2) + "-" + text.substr(6, 2) |     text = text.substr(0, 4) + "-" + text.substr(4, 2) + "-" + text.substr(6, 2) | ||||||
|         + "T" + text.substr(9, 2) + ":" + text.substr(11, 2) + ":" + text.substr(13, 2) + "Z"; |         + " " + text.substr(9, 2) + ":" + text.substr(11, 2) + ":" + text.substr(13, 2) + ".000Z"; | ||||||
|  |  | ||||||
|     return text; |     return text; | ||||||
| } | } | ||||||
| @@ -150,7 +151,7 @@ async function importEnex(taskContext, file, parentNote) { | |||||||
|             } else if (currentTag === 'created') { |             } else if (currentTag === 'created') { | ||||||
|                 note.utcDateCreated = parseDate(text); |                 note.utcDateCreated = parseDate(text); | ||||||
|             } else if (currentTag === 'updated') { |             } else if (currentTag === 'updated') { | ||||||
|                 // updated is currently ignored since utcDateModified is updated automatically with each save |                 note.utcDateModified = parseDate(text); | ||||||
|             } else if (currentTag === 'tag') { |             } else if (currentTag === 'tag') { | ||||||
|                 note.attributes.push({ |                 note.attributes.push({ | ||||||
|                     type: 'label', |                     type: 'label', | ||||||
| @@ -187,9 +188,27 @@ async function importEnex(taskContext, file, parentNote) { | |||||||
|         } |         } | ||||||
|     }); |     }); | ||||||
|  |  | ||||||
|  |     async function updateDates(noteId, utcDateCreated, utcDateModified) { | ||||||
|  |         // it's difficult to force custom dateCreated and dateModified to Note entity so we do it post-creation with SQL | ||||||
|  |         await sql.execute(` | ||||||
|  |                 UPDATE notes  | ||||||
|  |                 SET dateCreated = ?,  | ||||||
|  |                     utcDateCreated = ?, | ||||||
|  |                     dateModified = ?, | ||||||
|  |                     utcDateModified = ? | ||||||
|  |                 WHERE noteId = ?`, | ||||||
|  |             [utcDateCreated, utcDateCreated, utcDateModified, utcDateModified, noteId]); | ||||||
|  |  | ||||||
|  |         await sql.execute(` | ||||||
|  |                 UPDATE note_contents | ||||||
|  |                 SET utcDateModified = ? | ||||||
|  |                 WHERE noteId = ?`, | ||||||
|  |             [utcDateModified, noteId]); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     async function saveNote() { |     async function saveNote() { | ||||||
|         // make a copy because stream continues with the next async call and note gets overwritten |         // make a copy because stream continues with the next async call and note gets overwritten | ||||||
|         let {title, content, attributes, resources, utcDateCreated} = note; |         let {title, content, attributes, resources, utcDateCreated, utcDateModified} = note; | ||||||
|  |  | ||||||
|         content = extractContent(content); |         content = extractContent(content); | ||||||
|  |  | ||||||
| @@ -201,6 +220,10 @@ async function importEnex(taskContext, file, parentNote) { | |||||||
|             isProtected: parentNote.isProtected && protectedSessionService.isProtectedSessionAvailable(), |             isProtected: parentNote.isProtected && protectedSessionService.isProtectedSessionAvailable(), | ||||||
|         })).note; |         })).note; | ||||||
|  |  | ||||||
|  |         utcDateCreated = utcDateCreated || noteEntity.utcDateCreated; | ||||||
|  |         // sometime date modified is not present in ENEX, then use date created | ||||||
|  |         utcDateModified = utcDateModified || utcDateCreated; | ||||||
|  |  | ||||||
|         taskContext.increaseProgressCount(); |         taskContext.increaseProgressCount(); | ||||||
|  |  | ||||||
|         let noteContent = await noteEntity.getContent(); |         let noteContent = await noteEntity.getContent(); | ||||||
| @@ -224,6 +247,8 @@ async function importEnex(taskContext, file, parentNote) { | |||||||
|                     isProtected: parentNote.isProtected && protectedSessionService.isProtectedSessionAvailable(), |                     isProtected: parentNote.isProtected && protectedSessionService.isProtectedSessionAvailable(), | ||||||
|                 })).note; |                 })).note; | ||||||
|  |  | ||||||
|  |                 await updateDates(resourceNote.noteId, utcDateCreated, utcDateModified); | ||||||
|  |  | ||||||
|                 taskContext.increaseProgressCount(); |                 taskContext.increaseProgressCount(); | ||||||
|  |  | ||||||
|                 const resourceLink = `<a href="#root/${resourceNote.noteId}">${utils.escapeHtml(resource.title)}</a>`; |                 const resourceLink = `<a href="#root/${resourceNote.noteId}">${utils.escapeHtml(resource.title)}</a>`; | ||||||
| @@ -235,7 +260,9 @@ async function importEnex(taskContext, file, parentNote) { | |||||||
|                 try { |                 try { | ||||||
|                     const originalName = "image." + resource.mime.substr(6); |                     const originalName = "image." + resource.mime.substr(6); | ||||||
|  |  | ||||||
|                     const {url} = await imageService.saveImage(noteEntity.noteId, resource.content, originalName, taskContext.data.shrinkImages); |                     const {url, note: imageNote} = await imageService.saveImage(noteEntity.noteId, resource.content, originalName, taskContext.data.shrinkImages); | ||||||
|  |  | ||||||
|  |                     await updateDates(imageNote.noteId, utcDateCreated, utcDateModified); | ||||||
|  |  | ||||||
|                     const imageLink = `<img src="${url}">`; |                     const imageLink = `<img src="${url}">`; | ||||||
|  |  | ||||||
| @@ -257,6 +284,10 @@ async function importEnex(taskContext, file, parentNote) { | |||||||
|  |  | ||||||
|         // save updated content with links to files/images |         // save updated content with links to files/images | ||||||
|         await noteEntity.setContent(noteContent); |         await noteEntity.setContent(noteContent); | ||||||
|  |  | ||||||
|  |         await noteService.scanForLinks(noteEntity.noteId); | ||||||
|  |  | ||||||
|  |         await updateDates(noteEntity.noteId, utcDateCreated, utcDateModified); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     saxStream.on("closetag", async tag => { |     saxStream.on("closetag", async tag => { | ||||||
|   | |||||||
| @@ -37,7 +37,7 @@ function isProtectedSessionAvailable() { | |||||||
| function decryptNotes(notes) { | function decryptNotes(notes) { | ||||||
|     for (const note of notes) { |     for (const note of notes) { | ||||||
|         if (note.isProtected) { |         if (note.isProtected) { | ||||||
|             note.title = decrypt(note.title); |             note.title = decryptString(note.title); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user