Merge branch 'stable'

This commit is contained in:
zadam 2020-01-05 20:02:19 +01:00
commit 1cd2711097
23 changed files with 132 additions and 312 deletions

Binary file not shown.

View File

@ -553,7 +553,7 @@ class Note extends Entity {
const attributes = await this.loadOwnedAttributesToCache(); const attributes = await this.loadOwnedAttributesToCache();
for (const attribute of attributes) { for (const attribute of attributes) {
if (attribute.type === type && (value === undefined || value === attribute.value)) { if (attribute.type === type && attribute.name === name && (value === undefined || value === attribute.value)) {
attribute.isDeleted = true; attribute.isDeleted = true;
await attribute.save(); await attribute.save();

View File

@ -232,7 +232,7 @@ function BackendScriptApi(currentNote, apiParams) {
this.createDataNote = async (parentNoteId, title, content = {}) => await noteService.createNewNote({ this.createDataNote = async (parentNoteId, title, content = {}) => await noteService.createNewNote({
parentNoteId, parentNoteId,
title, title,
content: JSON.stringify(content), content: JSON.stringify(content, null, '\t'),
type: 'code', type: 'code',
mime: 'application/json' mime: 'application/json'
}); });

View File

@ -807,7 +807,7 @@
<div class="description"> <div class="description">
Activates newly created note. Compared to this.activateNote() also refreshes tree. Activates newly created note. Compared to this.activateNote() also makes sure that frontend has been fully synced.
</div> </div>

View File

@ -86,13 +86,13 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, tabConte
}; };
/** /**
* Activates newly created note. Compared to this.activateNote() also refreshes tree. * Activates newly created note. Compared to this.activateNote() also makes sure that frontend has been fully synced.
* *
* @param {string} notePath (or noteId) * @param {string} notePath (or noteId)
* @return {Promise&lt;void>} * @return {Promise&lt;void>}
*/ */
this.activateNewNote = async notePath => { this.activateNewNote = async notePath => {
await treeService.reload(); await ws.waitForMaxKnownSyncId();
await treeService.activateNote(notePath, noteDetailService.focusAndSelectTitle); await treeService.activateNote(notePath, noteDetailService.focusAndSelectTitle);
}; };

308
package-lock.json generated
View File

@ -722,29 +722,29 @@
"integrity": "sha512-uMgjozySS8adZZYePpaWs8cxB9/kdzmpX6SgJZ+wbz1K5eYk5QMYDVJaZKhxyIHUdnnJkfR7SVgStgH7LkGUyg==" "integrity": "sha512-uMgjozySS8adZZYePpaWs8cxB9/kdzmpX6SgJZ+wbz1K5eYk5QMYDVJaZKhxyIHUdnnJkfR7SVgStgH7LkGUyg=="
}, },
"app-builder-bin": { "app-builder-bin": {
"version": "3.4.4", "version": "3.4.3",
"resolved": "https://registry.npmjs.org/app-builder-bin/-/app-builder-bin-3.4.4.tgz", "resolved": "https://registry.npmjs.org/app-builder-bin/-/app-builder-bin-3.4.3.tgz",
"integrity": "sha512-Xib+wgdK+8zZhbZr5pma3pNB23Y4JRY5Yt6h8peou6MTFSQzXdIkqalh/ezy9SMLuS43S4b0s7jTVAmUs8WVmA==", "integrity": "sha512-qMhayIwi3juerQEVJMQ76trObEbfQT0nhUdxZz9a26/3NLT3pE6awmQ8S1cEnrGugaaM5gYqR8OElcDezfmEsg==",
"dev": true "dev": true
}, },
"app-builder-lib": { "app-builder-lib": {
"version": "22.1.0", "version": "21.2.0",
"resolved": "https://registry.npmjs.org/app-builder-lib/-/app-builder-lib-22.1.0.tgz", "resolved": "https://registry.npmjs.org/app-builder-lib/-/app-builder-lib-21.2.0.tgz",
"integrity": "sha512-jDTfWsVS/MePO4FexqiSQcsWM9Yfr81ETIYbmVbKmW05o0dn9k1DvMOMoLb0kTLQpW+pWBVvGMAOPfk68HnBrg==", "integrity": "sha512-aOX/nv77/Bti6NymJDg7p9T067xD8m1ipIEJR7B4Mm1GsJWpMm9PZdXtCRiMNRjHtQS5KIljT0g17781y6qn5A==",
"dev": true, "dev": true,
"requires": { "requires": {
"7zip-bin": "~5.0.3", "7zip-bin": "~5.0.3",
"@develar/schema-utils": "~2.1.0", "@develar/schema-utils": "~2.1.0",
"async-exit-hook": "^2.0.1", "async-exit-hook": "^2.0.1",
"bluebird-lst": "^1.0.9", "bluebird-lst": "^1.0.9",
"builder-util": "22.1.0", "builder-util": "21.2.0",
"builder-util-runtime": "8.4.0", "builder-util-runtime": "8.3.0",
"chromium-pickle-js": "^0.2.0", "chromium-pickle-js": "^0.2.0",
"debug": "^4.1.1", "debug": "^4.1.1",
"ejs": "^2.7.1", "ejs": "^2.6.2",
"electron-publish": "22.1.0", "electron-publish": "21.2.0",
"fs-extra": "^8.1.0", "fs-extra": "^8.1.0",
"hosted-git-info": "^3.0.0", "hosted-git-info": "^2.7.1",
"is-ci": "^2.0.0", "is-ci": "^2.0.0",
"isbinaryfile": "^4.0.2", "isbinaryfile": "^4.0.2",
"js-yaml": "^3.13.1", "js-yaml": "^3.13.1",
@ -752,26 +752,11 @@
"minimatch": "^3.0.4", "minimatch": "^3.0.4",
"normalize-package-data": "^2.5.0", "normalize-package-data": "^2.5.0",
"read-config-file": "5.0.0", "read-config-file": "5.0.0",
"sanitize-filename": "^1.6.3", "sanitize-filename": "^1.6.2",
"semver": "^6.3.0", "semver": "^6.3.0",
"temp-file": "^3.3.4" "temp-file": "^3.3.4"
}, },
"dependencies": { "dependencies": {
"ejs": {
"version": "2.7.4",
"resolved": "https://registry.npmjs.org/ejs/-/ejs-2.7.4.tgz",
"integrity": "sha512-7vmuyh5+kuUyJKePhQfRQBhXV5Ce+RnaeeQArKu1EAMpL3WbgMt5WG6uQZpEVvYSSsxMXRKOewtDk9RaTKXRlA==",
"dev": true
},
"hosted-git-info": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-3.0.2.tgz",
"integrity": "sha512-ezZMWtHXm7Eb7Rq4Mwnx2vs79WUx2QmRg3+ZqeGroKzfDO+EprOcgRPYghsOP9JuYBfK18VojmRTGCg8Ma+ktw==",
"dev": true,
"requires": {
"lru-cache": "^5.1.1"
}
},
"semver": { "semver": {
"version": "6.3.0", "version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
@ -1381,16 +1366,16 @@
} }
}, },
"builder-util": { "builder-util": {
"version": "22.1.0", "version": "21.2.0",
"resolved": "https://registry.npmjs.org/builder-util/-/builder-util-22.1.0.tgz", "resolved": "https://registry.npmjs.org/builder-util/-/builder-util-21.2.0.tgz",
"integrity": "sha512-BPvpWvxQ5XOzm2WepIgmOAyo2IyaM/Bd1LJmeTYy5CtknNAtxgmAPQJfCHCikMKKQA4Obz/KYecXQiGpGJ2ThA==", "integrity": "sha512-Nd6CUb6YgDY8EXAXEIegx+1kzKqyFQ5ZM5BoYkeunAlwz/zDJoH1UCyULjoS5wQe5czNClFQy07zz2bzYD0Z4A==",
"dev": true, "dev": true,
"requires": { "requires": {
"7zip-bin": "~5.0.3", "7zip-bin": "~5.0.3",
"@types/debug": "^4.1.5", "@types/debug": "^4.1.4",
"app-builder-bin": "3.4.4", "app-builder-bin": "3.4.3",
"bluebird-lst": "^1.0.9", "bluebird-lst": "^1.0.9",
"builder-util-runtime": "8.4.0", "builder-util-runtime": "8.3.0",
"chalk": "^2.4.2", "chalk": "^2.4.2",
"debug": "^4.1.1", "debug": "^4.1.1",
"fs-extra": "^8.1.0", "fs-extra": "^8.1.0",
@ -1439,9 +1424,9 @@
} }
}, },
"builder-util-runtime": { "builder-util-runtime": {
"version": "8.4.0", "version": "8.3.0",
"resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-8.4.0.tgz", "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-8.3.0.tgz",
"integrity": "sha512-CJB/eKfPf2vHrkmirF5eicVnbDCkMBbwd5tRYlTlgud16zFeqD7QmrVUAOEXdnsrcNkiLg9dbuUsQKtl/AwsYQ==", "integrity": "sha512-CSOdsYqf4RXIHh1HANPbrZHlZ9JQJXSuDDloblZPcWQVN62inyYoTQuSmY3KrgefME2Sv3Kn2MxHvbGQHRf8Iw==",
"dev": true, "dev": true,
"requires": { "requires": {
"debug": "^4.1.1", "debug": "^4.1.1",
@ -2424,122 +2409,6 @@
"sanitize-filename": "^1.6.2" "sanitize-filename": "^1.6.2"
}, },
"dependencies": { "dependencies": {
"ansi-styles": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
"dev": true,
"requires": {
"color-convert": "^1.9.0"
}
},
"app-builder-bin": {
"version": "3.4.3",
"resolved": "https://registry.npmjs.org/app-builder-bin/-/app-builder-bin-3.4.3.tgz",
"integrity": "sha512-qMhayIwi3juerQEVJMQ76trObEbfQT0nhUdxZz9a26/3NLT3pE6awmQ8S1cEnrGugaaM5gYqR8OElcDezfmEsg==",
"dev": true
},
"app-builder-lib": {
"version": "21.2.0",
"resolved": "https://registry.npmjs.org/app-builder-lib/-/app-builder-lib-21.2.0.tgz",
"integrity": "sha512-aOX/nv77/Bti6NymJDg7p9T067xD8m1ipIEJR7B4Mm1GsJWpMm9PZdXtCRiMNRjHtQS5KIljT0g17781y6qn5A==",
"dev": true,
"requires": {
"7zip-bin": "~5.0.3",
"@develar/schema-utils": "~2.1.0",
"async-exit-hook": "^2.0.1",
"bluebird-lst": "^1.0.9",
"builder-util": "21.2.0",
"builder-util-runtime": "8.3.0",
"chromium-pickle-js": "^0.2.0",
"debug": "^4.1.1",
"ejs": "^2.6.2",
"electron-publish": "21.2.0",
"fs-extra": "^8.1.0",
"hosted-git-info": "^2.7.1",
"is-ci": "^2.0.0",
"isbinaryfile": "^4.0.2",
"js-yaml": "^3.13.1",
"lazy-val": "^1.0.4",
"minimatch": "^3.0.4",
"normalize-package-data": "^2.5.0",
"read-config-file": "5.0.0",
"sanitize-filename": "^1.6.2",
"semver": "^6.3.0",
"temp-file": "^3.3.4"
},
"dependencies": {
"ejs": {
"version": "2.7.4",
"resolved": "https://registry.npmjs.org/ejs/-/ejs-2.7.4.tgz",
"integrity": "sha512-7vmuyh5+kuUyJKePhQfRQBhXV5Ce+RnaeeQArKu1EAMpL3WbgMt5WG6uQZpEVvYSSsxMXRKOewtDk9RaTKXRlA==",
"dev": true
},
"semver": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
"dev": true
}
}
},
"builder-util": {
"version": "21.2.0",
"resolved": "https://registry.npmjs.org/builder-util/-/builder-util-21.2.0.tgz",
"integrity": "sha512-Nd6CUb6YgDY8EXAXEIegx+1kzKqyFQ5ZM5BoYkeunAlwz/zDJoH1UCyULjoS5wQe5czNClFQy07zz2bzYD0Z4A==",
"dev": true,
"requires": {
"7zip-bin": "~5.0.3",
"@types/debug": "^4.1.4",
"app-builder-bin": "3.4.3",
"bluebird-lst": "^1.0.9",
"builder-util-runtime": "8.3.0",
"chalk": "^2.4.2",
"debug": "^4.1.1",
"fs-extra": "^8.1.0",
"is-ci": "^2.0.0",
"js-yaml": "^3.13.1",
"source-map-support": "^0.5.13",
"stat-mode": "^0.3.0",
"temp-file": "^3.3.4"
}
},
"builder-util-runtime": {
"version": "8.3.0",
"resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-8.3.0.tgz",
"integrity": "sha512-CSOdsYqf4RXIHh1HANPbrZHlZ9JQJXSuDDloblZPcWQVN62inyYoTQuSmY3KrgefME2Sv3Kn2MxHvbGQHRf8Iw==",
"dev": true,
"requires": {
"debug": "^4.1.1",
"sax": "^1.2.4"
}
},
"chalk": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
"dev": true,
"requires": {
"ansi-styles": "^3.2.1",
"escape-string-regexp": "^1.0.5",
"supports-color": "^5.3.0"
}
},
"electron-publish": {
"version": "21.2.0",
"resolved": "https://registry.npmjs.org/electron-publish/-/electron-publish-21.2.0.tgz",
"integrity": "sha512-mWavuoWJe87iaeKd0I24dNWIaR+0yRzshjNVqGyK019H766fsPWl3caQJnVKFaEyrZRP397v4JZVG0e7s16AxA==",
"dev": true,
"requires": {
"bluebird-lst": "^1.0.9",
"builder-util": "~21.2.0",
"builder-util-runtime": "8.3.0",
"chalk": "^2.4.2",
"fs-extra": "^8.1.0",
"lazy-val": "^1.0.4",
"mime": "^2.4.4"
}
},
"iconv-lite": { "iconv-lite": {
"version": "0.5.0", "version": "0.5.0",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.5.0.tgz", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.5.0.tgz",
@ -2548,27 +2417,6 @@
"requires": { "requires": {
"safer-buffer": ">= 2.1.2 < 3" "safer-buffer": ">= 2.1.2 < 3"
} }
},
"mime": {
"version": "2.4.4",
"resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz",
"integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA==",
"dev": true
},
"stat-mode": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/stat-mode/-/stat-mode-0.3.0.tgz",
"integrity": "sha512-QjMLR0A3WwFY2aZdV0okfFEJB5TRjkggXZjxP3A1RsWsNHNu3YPv8btmtc6iCFZ0Rul3FE93OYogvhOUClU+ng==",
"dev": true
},
"supports-color": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
"dev": true,
"requires": {
"has-flag": "^3.0.0"
}
} }
} }
}, },
@ -2748,32 +2596,26 @@
} }
}, },
"electron-builder": { "electron-builder": {
"version": "22.1.0", "version": "21.2.0",
"resolved": "https://registry.npmjs.org/electron-builder/-/electron-builder-22.1.0.tgz", "resolved": "https://registry.npmjs.org/electron-builder/-/electron-builder-21.2.0.tgz",
"integrity": "sha512-uu2W9BLG38D0i2PG6dHupmOYc+q/TRL+Ztf8xitqK+2Quq33PFbeN0ipfySuVEDg4I6whDRBOgxBEWwnUYqZZQ==", "integrity": "sha512-x8EXrqFbAb2L3N22YlGar3dGh8vwptbB3ovo3OF6K7NTpcsmM2zEoJv7GhFyX73rNzSG2HaWpXwGAtOp2JWiEw==",
"dev": true, "dev": true,
"requires": { "requires": {
"app-builder-lib": "22.1.0", "app-builder-lib": "21.2.0",
"bluebird-lst": "^1.0.9", "bluebird-lst": "^1.0.9",
"builder-util": "22.1.0", "builder-util": "21.2.0",
"builder-util-runtime": "8.4.0", "builder-util-runtime": "8.3.0",
"chalk": "^2.4.2", "chalk": "^2.4.2",
"dmg-builder": "21.2.0", "dmg-builder": "21.2.0",
"fs-extra": "^8.1.0", "fs-extra": "^8.1.0",
"is-ci": "^2.0.0", "is-ci": "^2.0.0",
"lazy-val": "^1.0.4", "lazy-val": "^1.0.4",
"read-config-file": "5.0.0", "read-config-file": "5.0.0",
"sanitize-filename": "^1.6.3", "sanitize-filename": "^1.6.2",
"update-notifier": "^3.0.1", "update-notifier": "^3.0.1",
"yargs": "^14.0.0" "yargs": "^13.3.0"
}, },
"dependencies": { "dependencies": {
"ansi-regex": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
"integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
"dev": true
},
"ansi-styles": { "ansi-styles": {
"version": "3.2.1", "version": "3.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
@ -2783,12 +2625,6 @@
"color-convert": "^1.9.0" "color-convert": "^1.9.0"
} }
}, },
"camelcase": {
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
"integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
"dev": true
},
"chalk": { "chalk": {
"version": "2.4.2", "version": "2.4.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
@ -2800,41 +2636,6 @@
"supports-color": "^5.3.0" "supports-color": "^5.3.0"
} }
}, },
"find-up": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
"integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
"dev": true,
"requires": {
"locate-path": "^3.0.0"
}
},
"is-fullwidth-code-point": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
"integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
"dev": true
},
"string-width": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
"integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
"dev": true,
"requires": {
"emoji-regex": "^7.0.1",
"is-fullwidth-code-point": "^2.0.0",
"strip-ansi": "^5.1.0"
}
},
"strip-ansi": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
"integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
"dev": true,
"requires": {
"ansi-regex": "^4.1.0"
}
},
"supports-color": { "supports-color": {
"version": "5.5.0", "version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
@ -2843,35 +2644,6 @@
"requires": { "requires": {
"has-flag": "^3.0.0" "has-flag": "^3.0.0"
} }
},
"yargs": {
"version": "14.2.0",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-14.2.0.tgz",
"integrity": "sha512-/is78VKbKs70bVZH7w4YaZea6xcJWOAwkhbR0CFuZBmYtfTYF0xjGJF43AYd8g2Uii1yJwmS5GR2vBmrc32sbg==",
"dev": true,
"requires": {
"cliui": "^5.0.0",
"decamelize": "^1.2.0",
"find-up": "^3.0.0",
"get-caller-file": "^2.0.1",
"require-directory": "^2.1.1",
"require-main-filename": "^2.0.0",
"set-blocking": "^2.0.0",
"string-width": "^3.0.0",
"which-module": "^2.0.0",
"y18n": "^4.0.0",
"yargs-parser": "^15.0.0"
}
},
"yargs-parser": {
"version": "15.0.0",
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-15.0.0.tgz",
"integrity": "sha512-xLTUnCMc4JhxrPEPUYD5IBR1mWCK/aT6+RJ/K29JY2y1vD+FhtgKK0AXRWvI262q3QSffAQuTouFIKUuHX89wQ==",
"dev": true,
"requires": {
"camelcase": "^5.0.0",
"decamelize": "^1.2.0"
}
} }
} }
}, },
@ -3191,14 +2963,14 @@
} }
}, },
"electron-publish": { "electron-publish": {
"version": "22.1.0", "version": "21.2.0",
"resolved": "https://registry.npmjs.org/electron-publish/-/electron-publish-22.1.0.tgz", "resolved": "https://registry.npmjs.org/electron-publish/-/electron-publish-21.2.0.tgz",
"integrity": "sha512-jHjMCaL2dFU+iOq8wW568F59+DW1jFJGT3vc2xqm9iXyZ8gWlQ+NVve4bq9HZG7m4iNqWbGw9StmZcOzmIBxMQ==", "integrity": "sha512-mWavuoWJe87iaeKd0I24dNWIaR+0yRzshjNVqGyK019H766fsPWl3caQJnVKFaEyrZRP397v4JZVG0e7s16AxA==",
"dev": true, "dev": true,
"requires": { "requires": {
"bluebird-lst": "^1.0.9", "bluebird-lst": "^1.0.9",
"builder-util": "~22.1.0", "builder-util": "~21.2.0",
"builder-util-runtime": "8.4.0", "builder-util-runtime": "8.3.0",
"chalk": "^2.4.2", "chalk": "^2.4.2",
"fs-extra": "^8.1.0", "fs-extra": "^8.1.0",
"lazy-val": "^1.0.4", "lazy-val": "^1.0.4",
@ -5449,9 +5221,9 @@
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
}, },
"isbinaryfile": { "isbinaryfile": {
"version": "4.0.2", "version": "4.0.3",
"resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.2.tgz", "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.3.tgz",
"integrity": "sha512-C3FSxJdNrEr2F4z6uFtNzECDM5hXk+46fxaa+cwBe5/XrWSmzdG8DDgyjfX6/NRdBB21q2JXuRAzPCUs+fclnQ==", "integrity": "sha512-GQ9Gjhp3AsEbo8/L/pA+MYl/c4hRm5O/+uCkF4LMx1a556Wh4/d75H13qu9LldmhU4yKnlfNKBmEcCaze3b2Gw==",
"dev": true "dev": true
}, },
"isexe": { "isexe": {
@ -9600,9 +9372,9 @@
"integrity": "sha1-CnwOom06Oa+n4OvqnB/AvE2qAR0=" "integrity": "sha1-CnwOom06Oa+n4OvqnB/AvE2qAR0="
}, },
"temp-file": { "temp-file": {
"version": "3.3.4", "version": "3.3.6",
"resolved": "https://registry.npmjs.org/temp-file/-/temp-file-3.3.4.tgz", "resolved": "https://registry.npmjs.org/temp-file/-/temp-file-3.3.6.tgz",
"integrity": "sha512-qSZ5W5q54iyGnP8cNl49RE0jTJc5CrzNocux5APD5yIxcgonoMuMSbsZfaZy8rTGCYo0Xz6ySVv3adagZ8gffg==", "integrity": "sha512-7TPldi8QJqRlPIF/Y33mVvo8+xDfi6+aVTCK4CrCaLqCoaOnVtf3SA4hCU0T5nhYDdOC7erw7o2uWfvijlk4Ug==",
"dev": true, "dev": true,
"requires": { "requires": {
"async-exit-hook": "^2.0.1", "async-exit-hook": "^2.0.1",

View File

@ -2,7 +2,7 @@
"name": "trilium", "name": "trilium",
"productName": "Trilium Notes", "productName": "Trilium Notes",
"description": "Trilium Notes", "description": "Trilium Notes",
"version": "0.39.3", "version": "0.39.4",
"license": "AGPL-3.0-only", "license": "AGPL-3.0-only",
"main": "electron.js", "main": "electron.js",
"bin": { "bin": {
@ -78,7 +78,7 @@
}, },
"devDependencies": { "devDependencies": {
"electron": "6.0.12", "electron": "6.0.12",
"electron-builder": "22.1.0", "electron-builder": "21.2.0",
"electron-packager": "14.1.1", "electron-packager": "14.1.1",
"electron-rebuild": "1.8.8", "electron-rebuild": "1.8.8",
"jsdoc": "3.6.3", "jsdoc": "3.6.3",

View File

@ -12,7 +12,7 @@ const TPL = `
<div class="form-group"> <div class="form-group">
<label for="sync-server-timeout">Sync timeout (milliseconds)</label> <label for="sync-server-timeout">Sync timeout (milliseconds)</label>
<input class="form-control" id="sync-server-timeout" min="1" max="10000000" type="number"> <input class="form-control" id="sync-server-timeout" min="1" max="10000000" type="number" style="text-align: left;">
</div> </div>
<div class="form-group"> <div class="form-group">

View File

@ -58,13 +58,13 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, tabConte
}; };
/** /**
* Activates newly created note. Compared to this.activateNote() also refreshes tree. * Activates newly created note. Compared to this.activateNote() also makes sure that frontend has been fully synced.
* *
* @param {string} notePath (or noteId) * @param {string} notePath (or noteId)
* @return {Promise<void>} * @return {Promise<void>}
*/ */
this.activateNewNote = async notePath => { this.activateNewNote = async notePath => {
await treeService.reload(); await ws.waitForMaxKnownSyncId();
await treeService.activateNote(notePath, noteDetailService.focusAndSelectTitle); await treeService.activateNote(notePath, noteDetailService.focusAndSelectTitle);
}; };

View File

@ -43,6 +43,7 @@ class NoteDetailBook {
this.$zoomInButton = this.$component.find('.book-zoom-in-button'); this.$zoomInButton = this.$component.find('.book-zoom-in-button');
this.$zoomOutButton = this.$component.find('.book-zoom-out-button'); this.$zoomOutButton = this.$component.find('.book-zoom-out-button');
this.$expandChildrenButton = this.$component.find('.expand-children-button'); this.$expandChildrenButton = this.$component.find('.expand-children-button');
this.$help = this.$component.find('.note-detail-book-help');
this.$zoomInButton.on('click', () => this.setZoom(this.zoomLevel - 1)); this.$zoomInButton.on('click', () => this.setZoom(this.zoomLevel - 1));
this.$zoomOutButton.on('click', () => this.setZoom(this.zoomLevel + 1)); this.$zoomOutButton.on('click', () => this.setZoom(this.zoomLevel + 1));
@ -105,6 +106,7 @@ class NoteDetailBook {
async render() { async render() {
this.$content.empty(); this.$content.empty();
this.$help.hide();
if (this.isAutoBook()) { if (this.isAutoBook()) {
const $addTextLink = $('<a href="javascript:">here</a>').on('click', () => { const $addTextLink = $('<a href="javascript:">here</a>').on('click', () => {
@ -124,7 +126,9 @@ class NoteDetailBook {
} }
async renderIntoElement(note, $container) { async renderIntoElement(note, $container) {
for (const childNote of await note.getChildNotes()) { const childNotes = await note.getChildNotes();
for (const childNote of childNotes) {
const childNotePath = this.ctx.notePath + '/' + childNote.noteId; const childNotePath = this.ctx.notePath + '/' + childNote.noteId;
const {type, renderedContent} = await noteContentRenderer.getRenderedContent(childNote); const {type, renderedContent} = await noteContentRenderer.getRenderedContent(childNote);
@ -152,6 +156,10 @@ class NoteDetailBook {
$container.append($card); $container.append($card);
} }
if (childNotes.length === 0) {
this.$help.show();
}
} }
/** @return {boolean} true if this is "auto book" activated (empty text note) and not explicit book note */ /** @return {boolean} true if this is "auto book" activated (empty text note) and not explicit book note */

View File

@ -116,15 +116,19 @@ class NoteDetailText {
} }
getContent() { getContent() {
let content = this.textEditor.getData(); const content = this.textEditor.getData();
// if content is only tags/whitespace (typically <p>&nbsp;</p>), then just make it empty // if content is only tags/whitespace (typically <p>&nbsp;</p>), then just make it empty
// this is important when setting new note to code // this is important when setting new note to code
if (jQuery(content).text().trim() === '' && !content.includes("<img")) { return this.isContentEmpty(content) ? '' : content;
content = ''; }
}
return content; isContentEmpty(content) {
content = content.toLowerCase();
return jQuery(content).text().trim() === ''
&& !content.includes("<img")
&& !content.includes("<section")
} }
async isReadOnly() { async isReadOnly() {

View File

@ -213,7 +213,11 @@ function closeActiveDialog() {
} }
function isHtmlEmpty(html) { function isHtmlEmpty(html) {
return $("<div>").html(html).text().trim().length === 0 && !html.toLowerCase().includes('<img'); html = html.toLowerCase();
return $("<div>").html(html).text().trim().length === 0
&& !html.includes('<img')
&& !html.includes('<section');
} }
async function clearBrowserCache() { async function clearBrowserCache() {

View File

@ -1,18 +1,18 @@
import StandardWidget from "./standard_widget.js"; import StandardWidget from "./standard_widget.js";
const TPL = ` const TPL = `
<table class="note-info-table"> <table class="note-info-table" style="table-layout: fixed; width: 100%;">
<tr> <tr>
<th>Note ID:</th> <th nowrap>Note ID:</th>
<td colspan="3" class="note-info-note-id"></td> <td nowrap colspan="3" class="note-info-note-id"></td>
</tr> </tr>
<tr> <tr>
<th>Created:</th> <th nowrap>Created:</th>
<td colspan="3" class="note-info-date-created"></td> <td nowrap colspan="3" style="overflow: hidden; text-overflow: ellipsis;" class="note-info-date-created"></td>
</tr> </tr>
<tr> <tr>
<th>Modified:</th> <th nowrap>Modified:</th>
<td colspan="3" class="note-info-date-modified"></td> <td nowrap colspan="3" style="overflow: hidden; text-overflow: ellipsis;" class="note-info-date-modified"></td>
</tr> </tr>
<tr> <tr>
<th>Type:</th> <th>Type:</th>
@ -39,10 +39,19 @@ class NoteInfoWidget extends StandardWidget {
const note = this.ctx.note; const note = this.ctx.note;
$noteId.text(note.noteId); $noteId.text(note.noteId);
$dateCreated.text(note.dateCreated); $dateCreated
$dateModified.text(note.dateModified); .text(note.dateCreated)
.attr("title", note.dateCreated);
$dateModified
.text(note.dateModified)
.attr("title", note.dateCreated);
$type.text(note.type); $type.text(note.type);
$mime.text(note.mime).attr("title", note.mime);
$mime
.text(note.mime)
.attr("title", note.mime);
} }
eventReceived(name, data) { eventReceived(name, data) {

View File

@ -407,7 +407,7 @@ body {
position: fixed; position: fixed;
bottom: 10px; bottom: 10px;
right: 10px; right: 10px;
z-index: 100000; z-index: 1000;
} }
#right-pane { #right-pane {

View File

@ -594,7 +594,7 @@ table.promoted-attributes-in-tooltip td, table.promoted-attributes-in-tooltip th
padding: 10px; padding: 10px;
} }
.note-detail-render-help { .note-detail-render-help, .note-detail-book-help {
margin: 50px; margin: 50px;
padding: 20px; padding: 20px;
} }
@ -967,4 +967,14 @@ a.external:not(.no-arrow):after, a[href^="http://"]:not(.no-arrow):after, a[href
padding: 20px; padding: 20px;
border-radius: 10px; border-radius: 10px;
background-color: var(--accented-background-color); background-color: var(--accented-background-color);
}
.include-note.ck-placeholder::before { /* remove placeholder in otherwise empty note */
content: '' !important;
}
.alert-warning {
color: var(--main-text-color) !important;
background-color: var(--accented-background-color) !important;
border-color: var(--main-border-color) !important;
} }

View File

@ -204,7 +204,7 @@ function BackendScriptApi(currentNote, apiParams) {
this.createDataNote = async (parentNoteId, title, content = {}) => await noteService.createNewNote({ this.createDataNote = async (parentNoteId, title, content = {}) => await noteService.createNewNote({
parentNoteId, parentNoteId,
title, title,
content: JSON.stringify(content), content: JSON.stringify(content, null, '\t'),
type: 'code', type: 'code',
mime: 'application/json' mime: 'application/json'
}); });

View File

@ -1 +1 @@
module.exports = { buildDate:"2020-01-02T10:43:41+01:00", buildRevision: "cb79f2c7eb51904537307f4ffc1135a7383da29f" }; module.exports = { buildDate:"2020-01-04T22:01:20+01:00", buildRevision: "3b8b4da149fbc1b17d09253693823f5135a55f2e" };

View File

@ -31,7 +31,8 @@ module.exports = function(filters, selectedColumns = 'notes.*') {
// can match notes because @tag can be both "shopping" and "christmas" // can match notes because @tag can be both "shopping" and "christmas"
const alias = "attr_" + property + "_" + attrFilterId++; const alias = "attr_" + property + "_" + attrFilterId++;
joins[alias] = `LEFT JOIN attributes AS ${alias} ` // forcing to use particular index since SQLite query planner would often choose something pretty bad
joins[alias] = `LEFT JOIN attributes AS ${alias} INDEXED BY IDX_attributes_noteId_index `
+ `ON ${alias}.noteId = notes.noteId ` + `ON ${alias}.noteId = notes.noteId `
+ `AND ${alias}.name = '${property}' AND ${alias}.isDeleted = 0`; + `AND ${alias}.name = '${property}' AND ${alias}.isDeleted = 0`;

View File

@ -75,14 +75,17 @@ async function saveImage(parentNoteId, uploadBuffer, originalName, shrinkImageSw
} }
async function shrinkImage(buffer, originalName) { async function shrinkImage(buffer, originalName) {
const resizedImage = await resize(buffer); // we do resizing with max (100) quality which will be trimmed during optimization step next
const resizedImage = await resize(buffer, 100);
let finalImageBuffer; let finalImageBuffer;
const jpegQuality = await optionService.getOptionInt('imageJpegQuality');
try { try {
finalImageBuffer = await optimize(resizedImage); finalImageBuffer = await optimize(resizedImage, jpegQuality);
} catch (e) { } catch (e) {
log.error("Failed to optimize image '" + originalName + "'\nStack: " + e.stack); log.error("Failed to optimize image '" + originalName + "'\nStack: " + e.stack);
finalImageBuffer = resizedImage; finalImageBuffer = await resize(buffer, jpegQuality);
} }
// if resizing & shrinking did not help with size then save the original // if resizing & shrinking did not help with size then save the original
@ -94,7 +97,7 @@ async function shrinkImage(buffer, originalName) {
return finalImageBuffer; return finalImageBuffer;
} }
async function resize(buffer) { async function resize(buffer, quality) {
const imageMaxWidthHeight = await optionService.getOptionInt('imageMaxWidthHeight'); const imageMaxWidthHeight = await optionService.getOptionInt('imageMaxWidthHeight');
const image = await jimp.read(buffer); const image = await jimp.read(buffer);
@ -106,8 +109,7 @@ async function resize(buffer) {
image.resize(jimp.AUTO, imageMaxWidthHeight); image.resize(jimp.AUTO, imageMaxWidthHeight);
} }
// we do resizing with max quality which will be trimmed during optimization step next image.quality(quality);
image.quality(100);
// when converting PNG to JPG we lose alpha channel, this is replaced by white to match Trilium white background // when converting PNG to JPG we lose alpha channel, this is replaced by white to match Trilium white background
image.background(0xFFFFFFFF); image.background(0xFFFFFFFF);
@ -115,11 +117,11 @@ async function resize(buffer) {
return image.getBufferAsync(jimp.MIME_JPEG); return image.getBufferAsync(jimp.MIME_JPEG);
} }
async function optimize(buffer) { async function optimize(buffer, jpegQuality) {
return await imagemin.buffer(buffer, { return await imagemin.buffer(buffer, {
plugins: [ plugins: [
imageminMozJpeg({ imageminMozJpeg({
quality: await optionService.getOptionInt('imageJpegQuality') quality: jpegQuality
}), }),
imageminPngQuant({ imageminPngQuant({
quality: [0, 0.7] quality: [0, 0.7]

View File

@ -48,7 +48,7 @@ function deriveMime(type, mime) {
mime = 'text/plain'; mime = 'text/plain';
} else if (['relation-map', 'search'].includes(type)) { } else if (['relation-map', 'search'].includes(type)) {
mime = 'application/json'; mime = 'application/json';
} else if (type === 'render') { } else if (['render', 'book'].includes(type)) {
mime = ''; mime = '';
} }

View File

@ -12,8 +12,14 @@ class TaskContext {
this.data = data; this.data = data;
// progressCount is meant to represent just some progress - to indicate the task is not stuck // progressCount is meant to represent just some progress - to indicate the task is not stuck
this.progressCount = 0; this.progressCount = -1; // we're incrementing immediatelly
this.lastSentCountTs = Date.now(); this.lastSentCountTs = 0; // 0 will guarantee first message will be sent
// just the fact this has been initialized is a progress which should be sent to clients
// this is esp. important when importing big files/images which take long time to upload/process
// which means that first "real" increaseProgressCount() will be called quite late and user is without
// feedback until then
this.increaseProgressCount();
} }
/** @return {TaskContext} */ /** @return {TaskContext} */

View File

@ -13,5 +13,9 @@
title="Zoom Out"></button> title="Zoom Out"></button>
</div> </div>
<div class="note-detail-book-help alert alert-warning">
This note of type Book doesn't have any child notes so there's nothing to display. See <a href="https://github.com/zadam/trilium/wiki/Book-note">wiki</a> for details.
</div>
<div class="note-detail-book-content"></div> <div class="note-detail-book-content"></div>
</div> </div>

View File

@ -1,5 +1,5 @@
<button id="hide-sidebar-button" class="btn btn-sm icon-button bx bx-chevrons-right hide-in-zen-mode" title="Hide sidebar"></button> <button id="hide-sidebar-button" class="btn btn-sm icon-button bx bx-chevrons-right hide-in-zen-mode" title="Hide sidebar"></button>
<button id="show-sidebar-button" class="btn btn-sm icon-button bx bx-chevrons-lefthide-in-zen-mode" title="Show sidebar"></button> <button id="show-sidebar-button" class="btn btn-sm icon-button bx bx-chevrons-left hide-in-zen-mode" title="Show sidebar"></button>
<div id="right-pane" class="hide-in-zen-mode"> <div id="right-pane" class="hide-in-zen-mode">
<div id="sidebar-container"></div> <div id="sidebar-container"></div>