mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-31 18:36:30 +01:00 
			
		
		
		
	Compare commits
	
		
			6 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 3cf3fc13b9 | ||
|  | 2b69abf8ab | ||
|  | 3e49a7dbfa | ||
|  | f782d2bef9 | ||
|  | ccaa9eae3a | ||
|  | 24c5388e0c | 
| @@ -2,7 +2,7 @@ | ||||
|   "name": "trilium", | ||||
|   "productName": "Trilium Notes", | ||||
|   "description": "Trilium Notes", | ||||
|   "version": "0.39.4", | ||||
|   "version": "0.39.5", | ||||
|   "license": "AGPL-3.0-only", | ||||
|   "main": "electron.js", | ||||
|   "bin": { | ||||
|   | ||||
| @@ -76,8 +76,7 @@ async function initContextMenu(event, contextMenu) { | ||||
|     // in such case we'll position it above click coordinates so it will fit into client | ||||
|     const clickPosition = event.pageY; | ||||
|     const clientHeight = document.documentElement.clientHeight; | ||||
|     const contextMenuHeight = $contextMenuContainer.height(); | ||||
|  | ||||
|     const contextMenuHeight = $contextMenuContainer.outerHeight() + 30; | ||||
|     let top; | ||||
|  | ||||
|     if (clickPosition + contextMenuHeight > clientHeight) { | ||||
|   | ||||
| @@ -201,17 +201,13 @@ async function loadNoteDetail(origNotePath, options = {}) { | ||||
|     const newTab = !!options.newTab; | ||||
|     const activate = !!options.activate; | ||||
|  | ||||
|     const notePath = await treeService.resolveNotePath(origNotePath); | ||||
|     let notePath = await treeService.resolveNotePath(origNotePath); | ||||
|  | ||||
|     if (!notePath) { | ||||
|         console.error(`Cannot resolve note path ${origNotePath}`); | ||||
|  | ||||
|         // fallback to display something | ||||
|         if (tabContexts.length === 0) { | ||||
|             await openEmptyTab(); | ||||
|         } | ||||
|  | ||||
|         return; | ||||
|         notePath = 'root'; | ||||
|     } | ||||
|  | ||||
|     const noteId = treeUtils.getNoteIdFromNotePath(notePath); | ||||
|   | ||||
| @@ -47,6 +47,7 @@ class NoteDetailText { | ||||
|         this.ctx = ctx; | ||||
|         this.$component = ctx.$tabContent.find('.note-detail-text'); | ||||
|         this.$editorEl = this.$component.find('.note-detail-text-editor'); | ||||
|         this.textEditorPromise = null; | ||||
|         this.textEditor = null; | ||||
|  | ||||
|         this.$component.on("dblclick", "img", e => { | ||||
| @@ -67,7 +68,23 @@ class NoteDetailText { | ||||
|     } | ||||
|  | ||||
|     async render() { | ||||
|         if (!this.textEditor) { | ||||
|         if (!this.textEditorPromise) { | ||||
|             this.textEditorPromise = this.initEditor(); | ||||
|         } | ||||
|  | ||||
|         await this.textEditorPromise; | ||||
|  | ||||
|         // lazy loading above can take time and tab might have been already switched to another note | ||||
|         if (this.ctx.note && this.ctx.note.type === 'text') { | ||||
|             this.textEditor.isReadOnly = await this.isReadOnly(); | ||||
|  | ||||
|             this.$component.show(); | ||||
|  | ||||
|             this.textEditor.setData(this.ctx.note.content); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     async initEditor() { | ||||
|         await libraryLoader.requireLibrary(libraryLoader.CKEDITOR); | ||||
|  | ||||
|         const codeBlockLanguages = | ||||
| @@ -85,10 +102,7 @@ class NoteDetailText { | ||||
|         // display of $component in both branches. | ||||
|         this.$component.show(); | ||||
|  | ||||
|             // textEditor might have been initialized during previous await so checking again | ||||
|             // looks like double initialization can freeze CKEditor pretty badly | ||||
|             if (!this.textEditor) { | ||||
|                 this.textEditor = await BalloonEditor.create(this.$editorEl[0], { | ||||
|         const textEditorInstance = await BalloonEditor.create(this.$editorEl[0], { | ||||
|             placeholder: "Type the content of your note here ...", | ||||
|             mention: mentionSetup, | ||||
|             codeBlock: { | ||||
| @@ -98,22 +112,13 @@ class NoteDetailText { | ||||
|  | ||||
|         if (glob.isDev && ENABLE_INSPECTOR) { | ||||
|             await import('../../libraries/ckeditor/inspector.js'); | ||||
|                     CKEditorInspector.attach(this.textEditor); | ||||
|             CKEditorInspector.attach(textEditorInstance); | ||||
|         } | ||||
|  | ||||
|         this.textEditor = textEditorInstance; | ||||
|  | ||||
|         this.onNoteChange(() => this.ctx.noteChanged()); | ||||
|     } | ||||
|         } | ||||
|  | ||||
|         // lazy loading above can take time and tab might have been already switched to another note | ||||
|         if (this.ctx.note && this.ctx.note.type === 'text') { | ||||
|             this.textEditor.isReadOnly = await this.isReadOnly(); | ||||
|  | ||||
|             this.$component.show(); | ||||
|  | ||||
|             this.textEditor.setData(this.ctx.note.content); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     getContent() { | ||||
|         const content = this.textEditor.getData(); | ||||
|   | ||||
| @@ -42,6 +42,8 @@ async function setupProtectedSession(password) { | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     $("#container").addClass('protected-session-active'); | ||||
|  | ||||
|     protectedSessionHolder.setProtectedSessionId(response.protectedSessionId); | ||||
|     protectedSessionHolder.touchProtectedSession(); | ||||
|  | ||||
|   | ||||
| @@ -350,8 +350,6 @@ class TabContext { | ||||
|  | ||||
|         this.$savedIndicator.fadeIn(); | ||||
|  | ||||
|         this.$scriptArea.empty(); | ||||
|  | ||||
|         // run async | ||||
|         bundleService.executeRelationBundles(this.note, 'runOnNoteChange', this); | ||||
|  | ||||
|   | ||||
| @@ -110,7 +110,7 @@ body { | ||||
|  | ||||
| #context-menu-container { | ||||
|     max-height: 100vh; | ||||
|     overflow: auto; /* make it scrollable when exceeding total height of the window */ | ||||
|     /* !!! Cannot set overflow: auto, submenus will break !!! */ | ||||
| } | ||||
|  | ||||
| #context-menu-container, #context-menu-container .dropdown-menu { | ||||
|   | ||||
| @@ -1 +1 @@ | ||||
| module.exports = { buildDate:"2020-01-04T22:01:20+01:00", buildRevision: "3b8b4da149fbc1b17d09253693823f5135a55f2e" }; | ||||
| module.exports = { buildDate:"2020-01-08T21:01:24+01:00", buildRevision: "2b69abf8ab2241f01cd38b31308e54b9faaa74d5" }; | ||||
|   | ||||
| @@ -18,18 +18,6 @@ class ConsistencyChecks { | ||||
|         this.fixedIssues = false; | ||||
|     } | ||||
|  | ||||
|     async findIssues(query, errorCb) { | ||||
|         const results = await sql.getRows(query); | ||||
|  | ||||
|         for (const res of results) { | ||||
|             logError(errorCb(res)); | ||||
|  | ||||
|             this.unrecoveredConsistencyErrors = true; | ||||
|         } | ||||
|  | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
|     async findAndFixIssues(query, fixerCb) { | ||||
|         const results = await sql.getRows(query); | ||||
|  | ||||
| @@ -175,13 +163,6 @@ class ConsistencyChecks { | ||||
|                     logError(`Relation ${attributeId} references missing note ${noteId}`) | ||||
|                 } | ||||
|             }); | ||||
|  | ||||
|         await this.findIssues(` | ||||
|                     SELECT noteRevisionId, note_revisions.noteId | ||||
|                     FROM note_revisions | ||||
|                              LEFT JOIN notes USING (noteId) | ||||
|                     WHERE notes.noteId IS NULL`, | ||||
|             ({noteRevisionId, noteId}) => `Note revision ${noteRevisionId} references missing note ${noteId}`); | ||||
|     } | ||||
|  | ||||
|     async findExistencyIssues() { | ||||
| @@ -335,13 +316,22 @@ class ConsistencyChecks { | ||||
|                 } | ||||
|             }); | ||||
|  | ||||
|         await this.findIssues(` | ||||
|         await this.findAndFixIssues(` | ||||
|                     SELECT noteId | ||||
|                     FROM notes | ||||
|                              JOIN note_contents USING (noteId) | ||||
|                     WHERE isErased = 1 | ||||
|                       AND content IS NOT NULL`, | ||||
|             ({noteId}) => `Note ${noteId} content is not null even though the note is erased`); | ||||
|             async ({noteId}) => { | ||||
|             if (this.autoFix) { | ||||
|                 await sql.execute(`UPDATE note_contents SET content = NULL WHERE noteId = ?`, [noteId]); | ||||
|  | ||||
|                 logFix(`Note ${noteId} content has been set to null since the note is erased`); | ||||
|             } | ||||
|             else { | ||||
|                 logError(`Note ${noteId} content is not null even though the note is erased`); | ||||
|             } | ||||
|         }); | ||||
|  | ||||
|         await this.findAndFixIssues(` | ||||
|                     SELECT noteId, noteRevisionId | ||||
| @@ -398,20 +388,40 @@ class ConsistencyChecks { | ||||
|                 } | ||||
|             }); | ||||
|  | ||||
|         await this.findIssues(` | ||||
|         await this.findAndFixIssues(` | ||||
|                     SELECT noteRevisionId | ||||
|                     FROM note_revisions | ||||
|                              JOIN note_revision_contents USING (noteRevisionId) | ||||
|                     WHERE isErased = 1 | ||||
|                       AND content IS NOT NULL`, | ||||
|             ({noteRevisionId}) => `Note revision ${noteRevisionId} content is not null even though the note revision is erased`); | ||||
|             async ({noteRevisionId}) => { | ||||
|                 if (this.autoFix) { | ||||
|                     await sql.execute(`UPDATE note_revision_contents SET content = NULL WHERE noteRevisionId = ?`, [noteRevisionId]); | ||||
|  | ||||
|         await this.findIssues(` | ||||
|                     logFix(`Note revision ${noteRevisionId} content was set to null since the note revision is erased`); | ||||
|                 } | ||||
|                 else { | ||||
|                     logError(`Note revision ${noteRevisionId} content is not null even though the note revision is erased`); | ||||
|                 } | ||||
|             }); | ||||
|  | ||||
|         await this.findAndFixIssues(` | ||||
|                     SELECT noteId | ||||
|                     FROM notes | ||||
|                     WHERE isErased = 1 | ||||
|                       AND isDeleted = 0`, | ||||
|             ({noteId}) => `Note ${noteId} is not deleted even though it is erased`); | ||||
|             async ({noteId}) => { | ||||
|                 if (this.autoFix) { | ||||
|                     const note = await repository.getNote(noteId); | ||||
|                     note.isDeleted = true; | ||||
|                     await note.save(); | ||||
|  | ||||
|                     logFix(`Note ${noteId} was set to deleted since it is erased`); | ||||
|                 } | ||||
|                 else { | ||||
|                     logError(`Note ${noteId} is not deleted even though it is erased`); | ||||
|                 } | ||||
|             }); | ||||
|  | ||||
|         await this.findAndFixIssues(` | ||||
|                     SELECT parentNoteId | ||||
|   | ||||
| @@ -490,6 +490,8 @@ async function eraseDeletedNotes() { | ||||
|         SET isErased = 1, | ||||
|             title = NULL | ||||
|         WHERE isErased = 0 AND noteId IN (???)`, noteIdsToErase); | ||||
|  | ||||
|     log.info(`Erased notes: ${JSON.stringify(noteIdsToErase)}`); | ||||
| } | ||||
|  | ||||
| async function duplicateNote(noteId, parentNoteId) { | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| const dayjs = require("dayjs"); | ||||
|  | ||||
| const filterRegex = /(\b(AND|OR)\s+)?@(!?)([\p{L}\p{Number}_]+|"[^"]+")\s*((=|!=|<|<=|>|>=|!?\*=|!?=\*|!?\*=\*)\s*(\S+|"[^"]+"))?/igu; | ||||
| const filterRegex = /(\b(AND|OR)\s+)?@(!?)([\p{L}\p{Number}_]+|"[^"]+")\s*((=|!=|<|<=|>|>=|!?\*=|!?=\*|!?\*=\*)\s*([^\s=*]+|"[^"]+"))?/igu; | ||||
| const smartValueRegex = /^(NOW|TODAY|WEEK|MONTH|YEAR) *([+\-] *\d+)?$/i; | ||||
|  | ||||
| function calculateSmartValue(v) { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user