mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-31 02:16:05 +01:00 
			
		
		
		
	Compare commits
	
		
			10 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 942132c01d | ||
|  | 1862acd1ff | ||
|  | ce7e18d0b0 | ||
|  | 65280d5ba3 | ||
|  | 7e3d424e23 | ||
|  | bff04c121a | ||
|  | e8903e82a1 | ||
|  | 0cfd95d9b8 | ||
|  | 1aa5349628 | ||
|  | 4e21d12202 | 
							
								
								
									
										2
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										2
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							| @@ -1,6 +1,6 @@ | |||||||
| { | { | ||||||
|   "name": "trilium", |   "name": "trilium", | ||||||
|   "version": "0.46.4-beta", |   "version": "0.46.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.46.5", |   "version": "0.46.6", | ||||||
|   "license": "AGPL-3.0-only", |   "license": "AGPL-3.0-only", | ||||||
|   "main": "electron.js", |   "main": "electron.js", | ||||||
|   "bin": { |   "bin": { | ||||||
| @@ -14,7 +14,7 @@ | |||||||
|   }, |   }, | ||||||
|   "scripts": { |   "scripts": { | ||||||
|     "start-server": "cross-env TRILIUM_ENV=dev node ./src/www", |     "start-server": "cross-env TRILIUM_ENV=dev node ./src/www", | ||||||
|     "start-electron": "cross-env TRILIUM_ENV=dev electron .", |     "start-electron": "cross-env TRILIUM_ENV=dev electron --inspect=5858 .", | ||||||
|     "build-backend-docs": "./node_modules/.bin/jsdoc -c jsdoc-conf.json -d ./docs/backend_api src/entities/*.js src/services/backend_script_api.js", |     "build-backend-docs": "./node_modules/.bin/jsdoc -c jsdoc-conf.json -d ./docs/backend_api src/entities/*.js src/services/backend_script_api.js", | ||||||
|     "build-frontend-docs": "./node_modules/.bin/jsdoc -c jsdoc-conf.json -d ./docs/frontend_api src/public/app/entities/*.js src/public/app/services/frontend_script_api.js src/public/app/widgets/collapsible_widget.js", |     "build-frontend-docs": "./node_modules/.bin/jsdoc -c jsdoc-conf.json -d ./docs/frontend_api src/public/app/entities/*.js src/public/app/services/frontend_script_api.js src/public/app/widgets/collapsible_widget.js", | ||||||
|     "build-docs": "npm run build-backend-docs && npm run build-frontend-docs", |     "build-docs": "npm run build-backend-docs && npm run build-frontend-docs", | ||||||
|   | |||||||
| @@ -156,14 +156,14 @@ class Note extends Entity { | |||||||
|  |  | ||||||
|         sql.upsert("note_contents", "noteId", pojo); |         sql.upsert("note_contents", "noteId", pojo); | ||||||
|  |  | ||||||
|         const hash = utils.hash(this.noteId + "|" + content.toString()); |         const hash = utils.hash(this.noteId + "|" + pojo.content.toString()); | ||||||
|  |  | ||||||
|         entityChangesService.addEntityChange({ |         entityChangesService.addEntityChange({ | ||||||
|             entityName: 'note_contents', |             entityName: 'note_contents', | ||||||
|             entityId: this.noteId, |             entityId: this.noteId, | ||||||
|             hash: hash, |             hash: hash, | ||||||
|             isErased: false, |             isErased: false, | ||||||
|             utcDateChanged: this.getUtcDateChanged() |             utcDateChanged: pojo.utcDateModified | ||||||
|         }, null); |         }, null); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -83,6 +83,9 @@ export default class MobileLayout { | |||||||
|                     .child(new NoteTitleWidget()) |                     .child(new NoteTitleWidget()) | ||||||
|                     .child(new CloseDetailButtonWidget())) |                     .child(new CloseDetailButtonWidget())) | ||||||
|                 .child(new NoteDetailWidget() |                 .child(new NoteDetailWidget() | ||||||
|                     .css('padding', '5px 20px 10px 0'))); |                     .css('padding', '5px 20px 10px 0') | ||||||
|  |                     .css('overflow', 'auto') | ||||||
|  |                     .css('height', '100%') | ||||||
|  |                 )); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -36,7 +36,7 @@ export default class NoteTitleWidget extends TabAwareWidget { | |||||||
|  |  | ||||||
|             protectedSessionHolder.touchProtectedSessionIfNecessary(this.note); |             protectedSessionHolder.touchProtectedSessionIfNecessary(this.note); | ||||||
|  |  | ||||||
|             await server.put(`notes/${this.noteId}/change-title`, {title}); |             await server.put(`notes/${this.noteId}/change-title`, {title}, this.componentId); | ||||||
|         }); |         }); | ||||||
|  |  | ||||||
|         appContext.addBeforeUnloadListener(this); |         appContext.addBeforeUnloadListener(this); | ||||||
|   | |||||||
| @@ -176,6 +176,15 @@ const TPL = ` | |||||||
|                       title="Images which are shown in the parent text note will not be displayed in the tree"></span> |                       title="Images which are shown in the parent text note will not be displayed in the tree"></span> | ||||||
|             </label> |             </label> | ||||||
|         </div> |         </div> | ||||||
|  |         <div class="form-check"> | ||||||
|  |             <label class="form-check-label"> | ||||||
|  |                 <input class="form-check-input auto-collapse-note-tree" type="checkbox" value=""> | ||||||
|  |                  | ||||||
|  |                 Automatically collapse notes | ||||||
|  |                 <span class="bx bx-info-circle"  | ||||||
|  |                       title="Notes will be collapsed after period of inactivity to declutter the tree."></span> | ||||||
|  |             </label> | ||||||
|  |         </div> | ||||||
|      |      | ||||||
|         <br/> |         <br/> | ||||||
|      |      | ||||||
| @@ -235,6 +244,7 @@ export default class NoteTreeWidget extends TabAwareWidget { | |||||||
|         this.$treeSettingsPopup = this.$widget.find('.tree-settings-popup'); |         this.$treeSettingsPopup = this.$widget.find('.tree-settings-popup'); | ||||||
|         this.$hideArchivedNotesCheckbox = this.$treeSettingsPopup.find('.hide-archived-notes'); |         this.$hideArchivedNotesCheckbox = this.$treeSettingsPopup.find('.hide-archived-notes'); | ||||||
|         this.$hideIncludedImages = this.$treeSettingsPopup.find('.hide-included-images'); |         this.$hideIncludedImages = this.$treeSettingsPopup.find('.hide-included-images'); | ||||||
|  |         this.$autoCollapseNoteTree = this.$treeSettingsPopup.find('.auto-collapse-note-tree'); | ||||||
|  |  | ||||||
|         this.$treeSettingsButton = this.$widget.find('.tree-settings-button'); |         this.$treeSettingsButton = this.$widget.find('.tree-settings-button'); | ||||||
|         this.$treeSettingsButton.on("click", e => { |         this.$treeSettingsButton.on("click", e => { | ||||||
| @@ -245,6 +255,7 @@ export default class NoteTreeWidget extends TabAwareWidget { | |||||||
|  |  | ||||||
|             this.$hideArchivedNotesCheckbox.prop("checked", this.hideArchivedNotes); |             this.$hideArchivedNotesCheckbox.prop("checked", this.hideArchivedNotes); | ||||||
|             this.$hideIncludedImages.prop("checked", this.hideIncludedImages); |             this.$hideIncludedImages.prop("checked", this.hideIncludedImages); | ||||||
|  |             this.$autoCollapseNoteTree.prop("checked", this.autoCollapseNoteTree); | ||||||
|  |  | ||||||
|             let top = this.$treeSettingsButton[0].offsetTop; |             let top = this.$treeSettingsButton[0].offsetTop; | ||||||
|             let left = this.$treeSettingsButton[0].offsetLeft; |             let left = this.$treeSettingsButton[0].offsetLeft; | ||||||
| @@ -272,6 +283,7 @@ export default class NoteTreeWidget extends TabAwareWidget { | |||||||
|         this.$saveTreeSettingsButton.on('click', async () => { |         this.$saveTreeSettingsButton.on('click', async () => { | ||||||
|             await this.setHideArchivedNotes(this.$hideArchivedNotesCheckbox.prop("checked")); |             await this.setHideArchivedNotes(this.$hideArchivedNotesCheckbox.prop("checked")); | ||||||
|             await this.setHideIncludedImages(this.$hideIncludedImages.prop("checked")); |             await this.setHideIncludedImages(this.$hideIncludedImages.prop("checked")); | ||||||
|  |             await this.setAutoCollapseNoteTree(this.$autoCollapseNoteTree.prop("checked")); | ||||||
|  |  | ||||||
|             this.$treeSettingsPopup.hide(); |             this.$treeSettingsPopup.hide(); | ||||||
|  |  | ||||||
| @@ -327,6 +339,14 @@ export default class NoteTreeWidget extends TabAwareWidget { | |||||||
|         await options.save("hideIncludedImages_" + this.treeName, val.toString()); |         await options.save("hideIncludedImages_" + this.treeName, val.toString()); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     get autoCollapseNoteTree() { | ||||||
|  |         return options.is("autoCollapseNoteTree"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     async setAutoCollapseNoteTree(val) { | ||||||
|  |         await options.save("autoCollapseNoteTree", val.toString()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     initFancyTree() { |     initFancyTree() { | ||||||
|         const treeData = [this.prepareRootNode()]; |         const treeData = [this.prepareRootNode()]; | ||||||
|  |  | ||||||
| @@ -797,8 +817,10 @@ export default class NoteTreeWidget extends TabAwareWidget { | |||||||
|  |  | ||||||
|             const node = await this.expandToNote(activeContext.notePath); |             const node = await this.expandToNote(activeContext.notePath); | ||||||
|  |  | ||||||
|             await node.makeVisible({scrollIntoView: true}); |             if (node) { | ||||||
|             node.setActive(true, {noEvents: true, noFocus: false}); |                 await node.makeVisible({scrollIntoView: true}); | ||||||
|  |                 node.setActive(true, {noEvents: true, noFocus: false}); | ||||||
|  |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -851,7 +873,11 @@ export default class NoteTreeWidget extends TabAwareWidget { | |||||||
|                             // these are real notes with real notePath, user can display them in a detail |                             // these are real notes with real notePath, user can display them in a detail | ||||||
|                             // but they don't have a node in the tree |                             // but they don't have a node in the tree | ||||||
|  |  | ||||||
|                             ws.logError(`Can't find node for child node of noteId=${childNoteId} for parent of noteId=${parentNode.data.noteId} and hoistedNoteId=${hoistedNoteService.getHoistedNoteId()}, requested path is ${notePath}`); |                             const childNote = await treeCache.getNote(childNoteId); | ||||||
|  |  | ||||||
|  |                             if (!childNote || childNote.type !== 'image') { | ||||||
|  |                                 ws.logError(`Can't find node for child node of noteId=${childNoteId} for parent of noteId=${parentNode.data.noteId} and hoistedNoteId=${hoistedNoteService.getHoistedNoteId()}, requested path is ${notePath}`); | ||||||
|  |                             } | ||||||
|                         } |                         } | ||||||
|  |  | ||||||
|                         return; |                         return; | ||||||
| @@ -955,6 +981,10 @@ export default class NoteTreeWidget extends TabAwareWidget { | |||||||
|         } |         } | ||||||
|  |  | ||||||
|         this.autoCollapseTimeoutId = setTimeout(() => { |         this.autoCollapseTimeoutId = setTimeout(() => { | ||||||
|  |             if (!this.autoCollapseNoteTree) { | ||||||
|  |                 return; | ||||||
|  |             } | ||||||
|  |  | ||||||
|             /* |             /* | ||||||
|              * We're collapsing notes after period of inactivity to "cleanup" the tree - users rarely |              * We're collapsing notes after period of inactivity to "cleanup" the tree - users rarely | ||||||
|              * collapse the notes and the tree becomes unusuably large. |              * collapse the notes and the tree becomes unusuably large. | ||||||
|   | |||||||
| @@ -5,6 +5,7 @@ const TPL = ` | |||||||
|     <style> |     <style> | ||||||
|     .note-detail-read-only-code { |     .note-detail-read-only-code { | ||||||
|         position: relative; |         position: relative; | ||||||
|  |         min-height: 50px; | ||||||
|     } |     } | ||||||
|      |      | ||||||
|     .note-detail-read-only-code-content { |     .note-detail-read-only-code-content { | ||||||
|   | |||||||
| @@ -25,6 +25,7 @@ const TPL = ` | |||||||
|         padding-top: 10px; |         padding-top: 10px; | ||||||
|         font-family: var(--detail-text-font-family); |         font-family: var(--detail-text-font-family); | ||||||
|         position: relative; |         position: relative; | ||||||
|  |         min-height: 50px; | ||||||
|     } |     } | ||||||
|          |          | ||||||
|     .note-detail-readonly-text p:first-child, .note-detail-readonly-text::before { |     .note-detail-readonly-text p:first-child, .note-detail-readonly-text::before { | ||||||
|   | |||||||
| @@ -5,6 +5,7 @@ const noteCacheService = require('../../services/note_cache/note_cache_service') | |||||||
| const protectedSessionService = require('../../services/protected_session'); | const protectedSessionService = require('../../services/protected_session'); | ||||||
| const noteRevisionService = require('../../services/note_revisions'); | const noteRevisionService = require('../../services/note_revisions'); | ||||||
| const utils = require('../../services/utils'); | const utils = require('../../services/utils'); | ||||||
|  | const sql = require('../../services/sql'); | ||||||
| const path = require('path'); | const path = require('path'); | ||||||
|  |  | ||||||
| function getNoteRevisions(req) { | function getNoteRevisions(req) { | ||||||
|   | |||||||
| @@ -41,7 +41,8 @@ const ALLOWED_OPTIONS = new Set([ | |||||||
|     'attributeListExpanded', |     'attributeListExpanded', | ||||||
|     'promotedAttributesExpanded', |     'promotedAttributesExpanded', | ||||||
|     'similarNotesExpanded', |     'similarNotesExpanded', | ||||||
|     'headingStyle' |     'headingStyle', | ||||||
|  |     'autoCollapseNoteTree' | ||||||
| ]); | ]); | ||||||
|  |  | ||||||
| function getOptions() { | function getOptions() { | ||||||
|   | |||||||
| @@ -1 +1 @@ | |||||||
| module.exports = { buildDate:"2021-03-14T22:56:27+01:00", buildRevision: "6c8d20288df302f3a415bd1bdcace98bf29d4bf6" }; | module.exports = { buildDate:"2021-03-23T23:57:48+01:00", buildRevision: "1862acd1ff9261536ebc7118d35bbbd8449ba94d" }; | ||||||
|   | |||||||
| @@ -405,7 +405,7 @@ class Note { | |||||||
|             return 0; |             return 0; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         let minDistance = 999_999; |         let minDistance = 999999; | ||||||
|  |  | ||||||
|         for (const parent of this.parents) { |         for (const parent of this.parents) { | ||||||
|             minDistance = Math.min(minDistance, parent.getDistanceToAncestor(ancestorNoteId) + 1); |             minDistance = Math.min(minDistance, parent.getDistanceToAncestor(ancestorNoteId) + 1); | ||||||
|   | |||||||
| @@ -233,7 +233,7 @@ async function findSimilarNotes(noteId) { | |||||||
|  |  | ||||||
|     const baseNote = noteCache.notes[noteId]; |     const baseNote = noteCache.notes[noteId]; | ||||||
|  |  | ||||||
|     if (!baseNote) { |     if (!baseNote || !baseNote.utcDateCreated) { | ||||||
|         return []; |         return []; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -86,6 +86,7 @@ const defaultOptions = [ | |||||||
|     { name: 'similarNotesExpanded', value: 'true', isSynced: true }, |     { name: 'similarNotesExpanded', value: 'true', isSynced: true }, | ||||||
|     { name: 'debugModeEnabled', value: 'false', isSynced: false }, |     { name: 'debugModeEnabled', value: 'false', isSynced: false }, | ||||||
|     { name: 'headingStyle', value: 'markdown', isSynced: true }, |     { name: 'headingStyle', value: 'markdown', isSynced: true }, | ||||||
|  |     { name: 'autoCollapseNoteTree', value: 'true', isSynced: true }, | ||||||
| ]; | ]; | ||||||
|  |  | ||||||
| function initStartupOptions() { | function initStartupOptions() { | ||||||
|   | |||||||
| @@ -26,9 +26,7 @@ function updateEntity(entityChange, entity, sourceId) { | |||||||
|         ? updateNoteReordering(entityChange, entity, sourceId) |         ? updateNoteReordering(entityChange, entity, sourceId) | ||||||
|         : updateNormalEntity(entityChange, entity, sourceId); |         : updateNormalEntity(entityChange, entity, sourceId); | ||||||
|  |  | ||||||
|     // currently making exception for protected notes and note revisions because here |     if (updated && !entityChange.isErased) { | ||||||
|     // the title and content are not available decrypted as listeners would expect |  | ||||||
|     if (updated && !entity.isProtected && !entityChange.isErased) { |  | ||||||
|         eventService.emit(eventService.ENTITY_SYNCED, { |         eventService.emit(eventService.ENTITY_SYNCED, { | ||||||
|             entityName: entityChange.entityName, |             entityName: entityChange.entityName, | ||||||
|             entity |             entity | ||||||
| @@ -44,7 +42,7 @@ function updateNormalEntity(remoteEntityChange, entity, sourceId) { | |||||||
|  |  | ||||||
|     if (localEntityChange && !localEntityChange.isErased && remoteEntityChange.isErased) { |     if (localEntityChange && !localEntityChange.isErased && remoteEntityChange.isErased) { | ||||||
|         sql.transactional(() => { |         sql.transactional(() => { | ||||||
|             const primaryKey = entityConstructor.getEntityFromEntityName(entityName).primaryKeyName; |             const primaryKey = entityConstructor.getEntityFromEntityName(remoteEntityChange.entityName).primaryKeyName; | ||||||
|  |  | ||||||
|             sql.execute(`DELETE FROM ${remoteEntityChange.entityName} WHERE ${primaryKey} = ?`, remoteEntityChange.entityId); |             sql.execute(`DELETE FROM ${remoteEntityChange.entityName} WHERE ${primaryKey} = ?`, remoteEntityChange.entityId); | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user