From ad7a55d30564bc41d5b89879ada049c85d185c41 Mon Sep 17 00:00:00 2001 From: zadam Date: Wed, 19 Feb 2020 19:51:36 +0100 Subject: [PATCH 1/9] always autofix note_contents.content = NULL sync issue after note erasion --- .idea/dataSources.xml | 3 -- package-lock.json | 2 +- src/services/consistency_checks.js | 57 ++++++++++++++++++------------ src/services/notes.js | 1 + 4 files changed, 36 insertions(+), 27 deletions(-) diff --git a/.idea/dataSources.xml b/.idea/dataSources.xml index 69c5fd8e8..caa742fa5 100644 --- a/.idea/dataSources.xml +++ b/.idea/dataSources.xml @@ -6,9 +6,6 @@ true org.sqlite.JDBC jdbc:sqlite:$PROJECT_DIR$/../trilium-data/document.db - - - \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index c34def86c..6eec5f662 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "trilium", - "version": "0.40.2", + "version": "0.40.3", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/src/services/consistency_checks.js b/src/services/consistency_checks.js index 2a2911b3f..871706a11 100644 --- a/src/services/consistency_checks.js +++ b/src/services/consistency_checks.js @@ -323,14 +323,25 @@ class ConsistencyChecks { WHERE isErased = 1 AND content IS NOT NULL`, 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`); - } + // we always fix this issue because there does not seem to be a good way to prevent it. + // Scenario in which this can happen: + // 1. user on instance A deletes the note (sync for notes is created, but not for note_contents) and is later erased + // 2. instance B gets synced from instance A, note is updated because of sync row for notes, + // but note_contents is not because erasion does not create sync rows + // 3. therefore note.isErased = true, but note_contents.content remains not updated and not erased. + // + // Considered solutions: + // - don't sync erased notes - this might prevent syncing also of the isDeleted flag and note would continue + // to exist on the other instance + // - create sync rows for erased event - this would be a problem for undeletion since erasion might happen + // on one instance after undelete and thus would win even though there's no user action behind it + // + // So instead we just fix such cases afterwards here. + + 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`); }); await this.findAndFixIssues(` @@ -547,23 +558,23 @@ class ConsistencyChecks { }); await this.findAndFixIssues(` - SELECT - id, entityId - FROM - sync - LEFT JOIN ${entityName} ON entityId = ${key} - WHERE - sync.entityName = '${entityName}' - AND ${key} IS NULL`, - async ({id, entityId}) => { - if (this.autoFix) { - await sql.execute("DELETE FROM sync WHERE entityName = ? AND entityId = ?", [entityName, entityId]); + SELECT + id, entityId + FROM + sync + LEFT JOIN ${entityName} ON entityId = ${key} + WHERE + sync.entityName = '${entityName}' + AND ${key} IS NULL`, + async ({id, entityId}) => { + if (this.autoFix) { + await sql.execute("DELETE FROM sync WHERE entityName = ? AND entityId = ?", [entityName, entityId]); - logFix(`Deleted extra sync record id=${id}, entityName=${entityName}, entityId=${entityId}`); - } else { - logError(`Unrecognized sync record id=${id}, entityName=${entityName}, entityId=${entityId}`); - } - }); + logFix(`Deleted extra sync record id=${id}, entityName=${entityName}, entityId=${entityId}`); + } else { + logError(`Unrecognized sync record id=${id}, entityName=${entityName}, entityId=${entityId}`); + } + }); } async findSyncRowsIssues() { diff --git a/src/services/notes.js b/src/services/notes.js index ffafb4bb6..068ad0536 100644 --- a/src/services/notes.js +++ b/src/services/notes.js @@ -599,6 +599,7 @@ async function eraseDeletedNotes() { UPDATE notes SET title = '[deleted]', contentLength = 0, + isProtected = 0, isErased = 1 WHERE noteId IN (???)`, noteIdsToErase); From fe31f08c0dcb290b796b50c12146258dced06c1a Mon Sep 17 00:00:00 2001 From: zadam Date: Wed, 19 Feb 2020 22:09:49 +0100 Subject: [PATCH 2/9] show setup window if DB is not initialized --- electron.js | 6 +++--- src/services/sync.js | 5 +++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/electron.js b/electron.js index 8296d0435..d7f094a17 100644 --- a/electron.js +++ b/electron.js @@ -26,9 +26,9 @@ app.on('ready', async () => { await sqlInit.dbConnection; - // if schema doesn't exist -> setup process - // if schema exists, then we need to wait until the migration process is finished - if (await sqlInit.schemaExists()) { + // if db is not initialized -> setup process + // if db is initialized, then we need to wait until the migration process is finished + if (await sqlInit.isDbInitialized()) { await sqlInit.dbReady; await windowService.createMainWindow(); diff --git a/src/services/sync.js b/src/services/sync.js index 8cb12339c..0d965d88f 100644 --- a/src/services/sync.js +++ b/src/services/sync.js @@ -228,9 +228,10 @@ async function syncFinished(syncContext) { async function checkContentHash(syncContext) { const resp = await syncRequest(syncContext, 'GET', '/api/sync/check'); + const lastSyncedPullId = await getLastSyncedPull(); - if (await getLastSyncedPull() < resp.maxSyncId) { - log.info("There are some outstanding pulls, skipping content check."); + if (lastSyncedPullId < resp.maxSyncId) { + log.info(`There are some outstanding pulls (${lastSyncedPullId} vs. ${resp.maxSyncId}), skipping content check.`); return true; } From 2d58019d6e4c8209bcd47e6b47fef757df2927cb Mon Sep 17 00:00:00 2001 From: zadam Date: Wed, 19 Feb 2020 22:10:40 +0100 Subject: [PATCH 3/9] allow to setup web version as a sync client --- src/views/setup.ejs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/views/setup.ejs b/src/views/setup.ejs index 0a2454290..896a4ec7f 100644 --- a/src/views/setup.ejs +++ b/src/views/setup.ejs @@ -19,13 +19,13 @@ -
+
-
+
+ I have server instance already and I want to setup sync with it
From 2b1b7774f8c16ce3efb747e17f06640690c9c138 Mon Sep 17 00:00:00 2001 From: zadam Date: Wed, 19 Feb 2020 22:24:31 +0100 Subject: [PATCH 4/9] make images in text notes rendered responsively in a book, fixes #871 --- src/public/stylesheets/style.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/public/stylesheets/style.css b/src/public/stylesheets/style.css index 3deaeebf6..10acf89d6 100644 --- a/src/public/stylesheets/style.css +++ b/src/public/stylesheets/style.css @@ -897,7 +897,7 @@ a.external:not(.no-arrow):after, a[href^="http://"]:not(.no-arrow):after, a[href text-align: center; } -.note-book-card.type-image .note-book-content img { +.note-book-card.type-image .note-book-content img, .note-book-card.type-text .note-book-content img { max-width: 100%; max-height: 100%; } From fe7705524af0732ac98474447432d0c923f52ff6 Mon Sep 17 00:00:00 2001 From: zadam Date: Mon, 24 Feb 2020 22:37:45 +0100 Subject: [PATCH 5/9] fix include note in mobile frontend, closes #878 --- src/public/javascripts/mobile.js | 17 +++++++++++++++++ src/views/mobile.ejs | 2 ++ 2 files changed, 19 insertions(+) diff --git a/src/public/javascripts/mobile.js b/src/public/javascripts/mobile.js index 659f3dc51..ce6262f7d 100644 --- a/src/public/javascripts/mobile.js +++ b/src/public/javascripts/mobile.js @@ -7,9 +7,26 @@ import contextMenuWidget from "./services/context_menu.js"; import treeChangesService from "./services/branches.js"; import utils from "./services/utils.js"; import treeUtils from "./services/tree_utils.js"; +import linkService from "./services/link.js"; +import noteContentRenderer from "./services/note_content_renderer.js"; window.glob.isDesktop = utils.isDesktop; window.glob.isMobile = utils.isMobile; +window.glob.showAddLinkDialog = () => import('./dialogs/add_link.js').then(d => d.showDialog()); +window.glob.showIncludeNoteDialog = cb => import('./dialogs/include_note.js').then(d => d.showDialog(cb)); +window.glob.loadIncludedNote = async (noteId, el) => { + const note = await treeCache.getNote(noteId); + + if (note) { + $(el).empty().append($("

").append(await linkService.createNoteLink(note.noteId, { + showTooltip: false + }))); + + const {renderedContent} = await noteContentRenderer.getRenderedContent(note); + + $(el).append(renderedContent); + } +}; const $leftPane = $("#left-pane"); const $tree = $("#tree"); diff --git a/src/views/mobile.ejs b/src/views/mobile.ejs index 2591c7f45..fa43557da 100644 --- a/src/views/mobile.ejs +++ b/src/views/mobile.ejs @@ -73,6 +73,8 @@ <% include details/relation_map.ejs %> <% include details/protected_session_password.ejs %> + + <% include details/book.ejs %>

From 8dfdd090f5addf5f836c8a38ddfc76f48af09f0e Mon Sep 17 00:00:00 2001 From: zadam Date: Mon, 24 Feb 2020 22:46:27 +0100 Subject: [PATCH 6/9] use note's css class also in book and included note, closes #879 --- .../services/note_content_renderer.js | 26 +++++++++++-------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/src/public/javascripts/services/note_content_renderer.js b/src/public/javascripts/services/note_content_renderer.js index dafa39579..0d23e9acc 100644 --- a/src/public/javascripts/services/note_content_renderer.js +++ b/src/public/javascripts/services/note_content_renderer.js @@ -7,7 +7,7 @@ import protectedSessionHolder from "./protected_session_holder.js"; async function getRenderedContent(note) { const type = getRenderingType(note); - let rendered; + let $rendered; if (type === 'text') { const fullNote = await server.get('notes/' + note.noteId); @@ -15,23 +15,23 @@ async function getRenderedContent(note) { const $content = $("
").html(fullNote.content); if (utils.isHtmlEmpty(fullNote.content)) { - rendered = ""; + $rendered = ""; } else { - rendered = $content; + $rendered = $content; } } else if (type === 'code') { const fullNote = await server.get('notes/' + note.noteId); if (fullNote.content.trim() === "") { - rendered = ""; + $rendered = ""; } - rendered = $("
").text(fullNote.content);
+        $rendered = $("
").text(fullNote.content);
     }
     else if (type === 'image') {
-        rendered = $("").attr("src", `api/images/${note.noteId}/${note.title}`);
+        $rendered = $("").attr("src", `api/images/${note.noteId}/${note.title}`);
     }
     else if (type === 'file') {
         function getFileUrl() {
@@ -56,7 +56,7 @@ async function getRenderedContent(note) {
         // open doesn't work for protected notes since it works through browser which isn't in protected session
         $openButton.toggle(!note.isProtected);
 
-        rendered = $('
') + $rendered = $('
') .append($downloadButton) .append('   ') .append($openButton); @@ -66,23 +66,27 @@ async function getRenderedContent(note) { await renderService.render(note, $el, this.ctx); - rendered = $el; + $rendered = $el; } else if (type === 'protected-session') { const $button = $(``) .on('click', protectedSessionService.enterProtectedSession); - rendered = $("
") + $rendered = $("
") .append("
This note is protected and to access it you need to enter password.
") .append("
") .append($button); } else { - rendered = "Content of this note cannot be displayed in the book format"; + $rendered = $("Content of this note cannot be displayed in the book format"); + } + + if (note.cssClass) { + $rendered.addClass(note.cssClass); } return { - renderedContent: rendered, + renderedContent: $rendered, type }; } From b9b2cc83649661379f44d62a08bd5d7ef1f3c000 Mon Sep 17 00:00:00 2001 From: zadam Date: Mon, 24 Feb 2020 22:55:12 +0100 Subject: [PATCH 7/9] make sure $rendered is always jquery object --- .../services/note_content_renderer.js | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/src/public/javascripts/services/note_content_renderer.js b/src/public/javascripts/services/note_content_renderer.js index 0d23e9acc..5c70e60b8 100644 --- a/src/public/javascripts/services/note_content_renderer.js +++ b/src/public/javascripts/services/note_content_renderer.js @@ -12,22 +12,11 @@ async function getRenderedContent(note) { if (type === 'text') { const fullNote = await server.get('notes/' + note.noteId); - const $content = $("
").html(fullNote.content); - - if (utils.isHtmlEmpty(fullNote.content)) { - $rendered = ""; - } - else { - $rendered = $content; - } + $rendered = $("
").html(fullNote.content); } else if (type === 'code') { const fullNote = await server.get('notes/' + note.noteId); - if (fullNote.content.trim() === "") { - $rendered = ""; - } - $rendered = $("
").text(fullNote.content);
     }
     else if (type === 'image') {
@@ -62,11 +51,9 @@ async function getRenderedContent(note) {
             .append($openButton);
     }
     else if (type === 'render') {
-        const $el = $('
'); + $rendered = $('
'); - await renderService.render(note, $el, this.ctx); - - $rendered = $el; + await renderService.render(note, $rendered, this.ctx); } else if (type === 'protected-session') { const $button = $(``) From fb55cdaea6b1367129e11118b8b6fd2eadebad5f Mon Sep 17 00:00:00 2001 From: zadam Date: Mon, 24 Feb 2020 22:58:18 +0100 Subject: [PATCH 8/9] release 0.40.4 --- package.json | 2 +- src/services/build.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 1fb61dcc8..6b3029e87 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "trilium", "productName": "Trilium Notes", "description": "Trilium Notes", - "version": "0.40.3", + "version": "0.40.4", "license": "AGPL-3.0-only", "main": "electron.js", "bin": { diff --git a/src/services/build.js b/src/services/build.js index 887b8aecd..ea561531c 100644 --- a/src/services/build.js +++ b/src/services/build.js @@ -1 +1 @@ -module.exports = { buildDate:"2020-02-09T10:48:23+01:00", buildRevision: "88bd65c6798609a39206722305fab4f8d91d618b" }; +module.exports = { buildDate:"2020-02-24T22:58:18+01:00", buildRevision: "b9b2cc83649661379f44d62a08bd5d7ef1f3c000" }; From e8a9e49e9e3f636b2331e999febbca6e5216d88a Mon Sep 17 00:00:00 2001 From: zadam Date: Mon, 24 Feb 2020 22:59:22 +0100 Subject: [PATCH 9/9] release 0.40.4 --- src/services/build.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/services/build.js b/src/services/build.js index ea561531c..96eeb5fd3 100644 --- a/src/services/build.js +++ b/src/services/build.js @@ -1 +1 @@ -module.exports = { buildDate:"2020-02-24T22:58:18+01:00", buildRevision: "b9b2cc83649661379f44d62a08bd5d7ef1f3c000" }; +module.exports = { buildDate:"2020-02-24T22:59:22+01:00", buildRevision: "fb55cdaea6b1367129e11118b8b6fd2eadebad5f" };