mirror of
https://github.com/zadam/trilium.git
synced 2025-06-06 18:08:33 +02:00
Merge remote-tracking branch 'origin/master'
# Conflicts: # package-lock.json # package.json
This commit is contained in:
commit
b2b3c80192
838
package-lock.json
generated
838
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
10
package.json
10
package.json
@ -32,7 +32,7 @@
|
|||||||
"commonmark": "0.29.2",
|
"commonmark": "0.29.2",
|
||||||
"cookie-parser": "1.4.5",
|
"cookie-parser": "1.4.5",
|
||||||
"csurf": "1.11.0",
|
"csurf": "1.11.0",
|
||||||
"dayjs": "1.8.36",
|
"dayjs": "1.9.1",
|
||||||
"ejs": "3.1.5",
|
"ejs": "3.1.5",
|
||||||
"electron-debug": "3.1.0",
|
"electron-debug": "3.1.0",
|
||||||
"electron-dl": "3.0.2",
|
"electron-dl": "3.0.2",
|
||||||
@ -55,17 +55,17 @@
|
|||||||
"mime-types": "2.1.27",
|
"mime-types": "2.1.27",
|
||||||
"multer": "1.4.2",
|
"multer": "1.4.2",
|
||||||
"node-abi": "2.19.1",
|
"node-abi": "2.19.1",
|
||||||
"open": "7.2.1",
|
"open": "7.3.0",
|
||||||
"portscanner": "2.2.0",
|
"portscanner": "2.2.0",
|
||||||
"rand-token": "1.0.1",
|
"rand-token": "1.0.1",
|
||||||
"request": "^2.88.2",
|
"request": "^2.88.2",
|
||||||
"rimraf": "3.0.2",
|
"rimraf": "3.0.2",
|
||||||
"sanitize-filename": "1.6.3",
|
"sanitize-filename": "1.6.3",
|
||||||
"sanitize-html": "1.27.4",
|
"sanitize-html": "2.1.0",
|
||||||
"sax": "1.2.4",
|
"sax": "1.2.4",
|
||||||
"semver": "7.3.2",
|
"semver": "7.3.2",
|
||||||
"serve-favicon": "2.5.0",
|
"serve-favicon": "2.5.0",
|
||||||
"session-file-store": "1.4.0",
|
"session-file-store": "1.5.0",
|
||||||
"striptags": "3.1.1",
|
"striptags": "3.1.1",
|
||||||
"tmp": "^0.2.1",
|
"tmp": "^0.2.1",
|
||||||
"turndown": "6.0.0",
|
"turndown": "6.0.0",
|
||||||
@ -80,7 +80,7 @@
|
|||||||
"electron": "9.3.2",
|
"electron": "9.3.2",
|
||||||
"electron-builder": "22.8.1",
|
"electron-builder": "22.8.1",
|
||||||
"electron-packager": "15.1.0",
|
"electron-packager": "15.1.0",
|
||||||
"electron-rebuild": "2.0.3",
|
"electron-rebuild": "2.2.0",
|
||||||
"esm": "3.2.25",
|
"esm": "3.2.25",
|
||||||
"jasmine": "3.6.1",
|
"jasmine": "3.6.1",
|
||||||
"jsdoc": "3.6.6",
|
"jsdoc": "3.6.6",
|
||||||
|
@ -806,7 +806,7 @@ class Note extends Entity {
|
|||||||
* @returns {boolean} - true if note has children
|
* @returns {boolean} - true if note has children
|
||||||
*/
|
*/
|
||||||
hasChildren() {
|
hasChildren() {
|
||||||
return (this.getChildNotes()).length > 0;
|
return this.getChildNotes().length > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -13,6 +13,8 @@ export async function showDialog() {
|
|||||||
utils.openDialog($dialog);
|
utils.openDialog($dialog);
|
||||||
|
|
||||||
noteAutocompleteService.initNoteAutocomplete($autoComplete, { hideGoToSelectedNoteButton: true })
|
noteAutocompleteService.initNoteAutocomplete($autoComplete, { hideGoToSelectedNoteButton: true })
|
||||||
|
// clear any event listener added in previous invocation of this function
|
||||||
|
.off('autocomplete:noteselected')
|
||||||
.on('autocomplete:noteselected', function(event, suggestion, dataset) {
|
.on('autocomplete:noteselected', function(event, suggestion, dataset) {
|
||||||
if (!suggestion.notePath) {
|
if (!suggestion.notePath) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -26,7 +26,7 @@ async function getRenderedContent(note) {
|
|||||||
}
|
}
|
||||||
else if (type === 'file' || type === 'pdf') {
|
else if (type === 'file' || type === 'pdf') {
|
||||||
function getFileUrl() {
|
function getFileUrl() {
|
||||||
return utils.getUrlForDownload("api/notes/" + note.noteId + "/download");
|
return utils.getUrlForDownload(`api/notes/${note.noteId}/download`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const $downloadButton = $('<button class="file-download btn btn-primary" type="button">Download</button>');
|
const $downloadButton = $('<button class="file-download btn btn-primary" type="button">Download</button>');
|
||||||
@ -51,7 +51,7 @@ async function getRenderedContent(note) {
|
|||||||
|
|
||||||
if (type === 'pdf') {
|
if (type === 'pdf') {
|
||||||
const $pdfPreview = $('<iframe class="pdf-preview" style="width: 100%; flex-grow: 100;"></iframe>');
|
const $pdfPreview = $('<iframe class="pdf-preview" style="width: 100%; flex-grow: 100;"></iframe>');
|
||||||
$pdfPreview.attr("src", utils.getUrlForDownload("api/notes/" + note.noteId + "/open"));
|
$pdfPreview.attr("src", utils.getUrlForDownload(`api/notes/${note.noteId}/open`));
|
||||||
|
|
||||||
$rendered.append($pdfPreview);
|
$rendered.append($pdfPreview);
|
||||||
}
|
}
|
||||||
|
240
src/public/app/services/note_list_renderer.js
Normal file
240
src/public/app/services/note_list_renderer.js
Normal file
@ -0,0 +1,240 @@
|
|||||||
|
import linkService from "./link.js";
|
||||||
|
import noteContentRenderer from "./note_content_renderer.js";
|
||||||
|
import treeCache from "./tree_cache.js";
|
||||||
|
|
||||||
|
const ZOOMS = {
|
||||||
|
1: {
|
||||||
|
width: "100%",
|
||||||
|
height: "100%"
|
||||||
|
},
|
||||||
|
2: {
|
||||||
|
width: "49%",
|
||||||
|
height: "350px"
|
||||||
|
},
|
||||||
|
3: {
|
||||||
|
width: "32%",
|
||||||
|
height: "250px"
|
||||||
|
},
|
||||||
|
4: {
|
||||||
|
width: "24%",
|
||||||
|
height: "200px"
|
||||||
|
},
|
||||||
|
5: {
|
||||||
|
width: "19%",
|
||||||
|
height: "175px"
|
||||||
|
},
|
||||||
|
6: {
|
||||||
|
width: "16%",
|
||||||
|
height: "150px"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const zoomLevel = 2;
|
||||||
|
|
||||||
|
const TPL = `
|
||||||
|
<div class="note-list">
|
||||||
|
<style>
|
||||||
|
.note-list {
|
||||||
|
overflow: hidden;
|
||||||
|
position: relative;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.note-book-card {
|
||||||
|
border-radius: 10px;
|
||||||
|
background-color: var(--accented-background-color);
|
||||||
|
padding: 15px;
|
||||||
|
padding-bottom: 5px;
|
||||||
|
margin: 5px;
|
||||||
|
margin-left: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.note-book-card .note-book-card {
|
||||||
|
border: 1px solid var(--main-border-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.note-book-card.type-image .note-book-content, .note-book-card.type-file .note-book-content, .note-book-card.type-protected-session .note-book-content {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.note-book-card.type-image .note-book-content img, .note-book-card.type-text .note-book-content img {
|
||||||
|
max-width: 100%;
|
||||||
|
max-height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.note-book-title {
|
||||||
|
flex-grow: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.note-list-container {
|
||||||
|
height: 100%;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.note-expander {
|
||||||
|
font-size: x-large;
|
||||||
|
position: relative;
|
||||||
|
top: 2px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div class="btn-group floating-button" style="right: 20px; top: 10px;">
|
||||||
|
<button type="button"
|
||||||
|
class="expand-children-button btn icon-button bx bx-move-vertical"
|
||||||
|
title="Expand all children"></button>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<button type="button"
|
||||||
|
class="list-view-button btn icon-button bx bx-menu"
|
||||||
|
title="List view"></button>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<button type="button"
|
||||||
|
class="grid-view-button btn icon-button bx bx-grid-alt"
|
||||||
|
title="Grid view"></button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="note-list-container"></div>
|
||||||
|
</div>`;
|
||||||
|
|
||||||
|
async function renderList(notes, parentNote = null) {
|
||||||
|
const $noteList = $(TPL);
|
||||||
|
|
||||||
|
// $zoomInButton.on('click', () => this.setZoom(this.zoomLevel - 1));
|
||||||
|
// $zoomOutButton.on('click', () => this.setZoom(this.zoomLevel + 1));
|
||||||
|
//
|
||||||
|
// $expandChildrenButton.on('click', async () => {
|
||||||
|
// for (let i = 1; i < 30; i++) { // protection against infinite cycle
|
||||||
|
// const $unexpandedLinks = this.$content.find('.note-book-open-children-button:visible');
|
||||||
|
//
|
||||||
|
// if ($unexpandedLinks.length === 0) {
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// for (const link of $unexpandedLinks) {
|
||||||
|
// const $card = $(link).closest(".note-book-card");
|
||||||
|
//
|
||||||
|
// await this.expandCard($card);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
|
||||||
|
$noteList.on('click', '.note-book-open-children-button', async ev => {
|
||||||
|
const $card = $(ev.target).closest('.note-book-card');
|
||||||
|
|
||||||
|
await expandCard($card);
|
||||||
|
});
|
||||||
|
|
||||||
|
$noteList.on('click', '.note-book-hide-children-button', async ev => {
|
||||||
|
const $card = $(ev.target).closest('.note-book-card');
|
||||||
|
|
||||||
|
$card.find('.note-book-open-children-button').show();
|
||||||
|
$card.find('.note-book-hide-children-button').hide();
|
||||||
|
|
||||||
|
$card.find('.note-book-children-content').empty();
|
||||||
|
});
|
||||||
|
|
||||||
|
const $container = $noteList.find('.note-list-container');
|
||||||
|
|
||||||
|
const imageLinks = parentNote ? parentNote.getRelations('imageLink') : [];
|
||||||
|
|
||||||
|
for (const note of notes) {
|
||||||
|
// image is already visible in the parent note so no need to display it separately in the book
|
||||||
|
if (imageLinks.find(rel => rel.value === note.noteId)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const $card = await renderNote(note);
|
||||||
|
|
||||||
|
$container.append($card);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $noteList;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: we should also render (promoted) attributes
|
||||||
|
async function renderNote(note, renderContent) {
|
||||||
|
const notePath = /*this.notePath + '/' + */ note.noteId;
|
||||||
|
|
||||||
|
const $content = $('<div class="note-book-content">')
|
||||||
|
.css("max-height", ZOOMS[zoomLevel].height);
|
||||||
|
|
||||||
|
const $card = $('<div class="note-book-card">')
|
||||||
|
.attr('data-note-id', note.noteId)
|
||||||
|
.css("flex-basis", ZOOMS[zoomLevel].width)
|
||||||
|
.append(
|
||||||
|
$('<h5 class="note-book-title">')
|
||||||
|
.append('<span class="note-expander bx bx-chevron-right"></span>')
|
||||||
|
.append(await linkService.createNoteLink(notePath, {showTooltip: false}))
|
||||||
|
)
|
||||||
|
.append($content);
|
||||||
|
|
||||||
|
if (renderContent) {
|
||||||
|
try {
|
||||||
|
const {type, renderedContent} = await noteContentRenderer.getRenderedContent(note);
|
||||||
|
|
||||||
|
$card.addClass("type-" + type);
|
||||||
|
$content.append(renderedContent);
|
||||||
|
} catch (e) {
|
||||||
|
console.log(`Caught error while rendering note ${note.noteId} of type ${note.type}: ${e.message}, stack: ${e.stack}`);
|
||||||
|
|
||||||
|
$content.append("rendering error");
|
||||||
|
}
|
||||||
|
|
||||||
|
const imageLinks = note.getRelations('imageLink');
|
||||||
|
|
||||||
|
const childCount = note.getChildNoteIds()
|
||||||
|
.filter(childNoteId => !imageLinks.find(rel => rel.value === childNoteId))
|
||||||
|
.length;
|
||||||
|
|
||||||
|
if (childCount > 0) {
|
||||||
|
const label = `${childCount} child${childCount > 1 ? 'ren' : ''}`;
|
||||||
|
|
||||||
|
$card.append($('<div class="note-book-children">')
|
||||||
|
.append($(`<a class="note-book-open-children-button no-print" href="javascript:">+ Show ${label}</a>`))
|
||||||
|
.append($(`<a class="note-book-hide-children-button no-print" href="javascript:">- Hide ${label}</a>`).hide())
|
||||||
|
.append($('<div class="note-book-children-content">'))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $card;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function expandCard($card) {
|
||||||
|
const noteId = $card.attr('data-note-id');
|
||||||
|
const note = await treeCache.getNote(noteId);
|
||||||
|
|
||||||
|
$card.find('.note-book-open-children-button').hide();
|
||||||
|
$card.find('.note-book-hide-children-button').show();
|
||||||
|
|
||||||
|
$card.find('.note-book-children-content').append(await renderList(await note.getChildNotes(), note));
|
||||||
|
}
|
||||||
|
|
||||||
|
function setZoom(zoomLevel) {
|
||||||
|
if (!(zoomLevel in ZOOMS)) {
|
||||||
|
zoomLevel = this.getDefaultZoomLevel();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.zoomLevel = zoomLevel;
|
||||||
|
|
||||||
|
this.$zoomInButton.prop("disabled", zoomLevel === MIN_ZOOM_LEVEL);
|
||||||
|
this.$zoomOutButton.prop("disabled", zoomLevel === MAX_ZOOM_LEVEL);
|
||||||
|
|
||||||
|
this.$content.find('.note-book-card').css("flex-basis", ZOOMS[zoomLevel].width);
|
||||||
|
this.$content.find('.note-book-content').css("max-height", ZOOMS[zoomLevel].height);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
renderList
|
||||||
|
};
|
@ -30,7 +30,7 @@ const TPL = `
|
|||||||
border-color: red !important;
|
border-color: red !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.attr-expander {
|
.area-expander {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
color: var(--muted-text-color);
|
color: var(--muted-text-color);
|
||||||
@ -47,29 +47,29 @@ const TPL = `
|
|||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.attr-expander-text {
|
.area-expander-text {
|
||||||
padding-left: 20px;
|
padding-left: 20px;
|
||||||
padding-right: 20px;
|
padding-right: 20px;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.attr-expander:hover {
|
.area-expander:hover {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.attr-expander:hover hr {
|
.area-expander:hover hr {
|
||||||
border-color: var(--main-text-color);
|
border-color: var(--main-text-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.attr-expander:hover .attr-expander-text {
|
.area-expander:hover .area-expander-text {
|
||||||
color: var(--main-text-color);
|
color: var(--main-text-color);
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<div class="attr-expander attr-promoted-expander">
|
<div class="area-expander attr-promoted-expander">
|
||||||
<hr class="w-100">
|
<hr class="w-100">
|
||||||
|
|
||||||
<div class="attr-expander-text">Promoted attributes</div>
|
<div class="area-expander-text">Promoted attributes</div>
|
||||||
|
|
||||||
<hr class="w-100">
|
<hr class="w-100">
|
||||||
</div>
|
</div>
|
||||||
@ -77,10 +77,10 @@ const TPL = `
|
|||||||
<div class="all-attr-wrapper">
|
<div class="all-attr-wrapper">
|
||||||
<div class="promoted-attributes-placeholder"></div>
|
<div class="promoted-attributes-placeholder"></div>
|
||||||
|
|
||||||
<div class="attr-expander attr-owned-and-inherited-expander">
|
<div class="area-expander attr-owned-and-inherited-expander">
|
||||||
<hr class="w-100">
|
<hr class="w-100">
|
||||||
|
|
||||||
<div class="attr-expander-text"></div>
|
<div class="area-expander-text"></div>
|
||||||
|
|
||||||
<hr class="w-100">
|
<hr class="w-100">
|
||||||
</div>
|
</div>
|
||||||
@ -90,10 +90,10 @@ const TPL = `
|
|||||||
|
|
||||||
<hr class="w-100 attr-inherited-empty-expander" style="margin-bottom: 10px;">
|
<hr class="w-100 attr-inherited-empty-expander" style="margin-bottom: 10px;">
|
||||||
|
|
||||||
<div class="attr-expander attr-inherited-expander">
|
<div class="area-expander attr-inherited-expander">
|
||||||
<hr class="w-100">
|
<hr class="w-100">
|
||||||
|
|
||||||
<div class="attr-expander-text"></div>
|
<div class="area-expander-text"></div>
|
||||||
|
|
||||||
<hr class="w-100">
|
<hr class="w-100">
|
||||||
</div>
|
</div>
|
||||||
@ -141,7 +141,7 @@ export default class AttributeListWidget extends TabAwareWidget {
|
|||||||
this.triggerEvent(`attributeListCollapsedStateChanged`, {collapse});
|
this.triggerEvent(`attributeListCollapsedStateChanged`, {collapse});
|
||||||
});
|
});
|
||||||
|
|
||||||
this.$ownedExpanderText = this.$ownedExpander.find('.attr-expander-text');
|
this.$ownedExpanderText = this.$ownedExpander.find('.area-expander-text');
|
||||||
|
|
||||||
this.$inheritedAttributesWrapper = this.$widget.find('.inherited-attributes-wrapper');
|
this.$inheritedAttributesWrapper = this.$widget.find('.inherited-attributes-wrapper');
|
||||||
|
|
||||||
@ -155,7 +155,7 @@ export default class AttributeListWidget extends TabAwareWidget {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.$inheritedExpanderText = this.$inheritedExpander.find('.attr-expander-text');
|
this.$inheritedExpanderText = this.$inheritedExpander.find('.area-expander-text');
|
||||||
|
|
||||||
this.$inheritedEmptyExpander = this.$widget.find('.attr-inherited-empty-expander');
|
this.$inheritedEmptyExpander = this.$widget.find('.attr-inherited-empty-expander');
|
||||||
|
|
||||||
|
@ -24,46 +24,12 @@ const TPL = `
|
|||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.similar-notes-expander {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
color: var(--muted-text-color);
|
|
||||||
font-size: 90%;
|
|
||||||
m
|
|
||||||
}
|
|
||||||
|
|
||||||
.similar-notes-expander hr {
|
|
||||||
height: 1px;
|
|
||||||
border-color: var(--main-border-color);
|
|
||||||
position: relative;
|
|
||||||
top: 4px;
|
|
||||||
margin-top: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.similar-notes-expander-text {
|
|
||||||
padding-left: 20px;
|
|
||||||
padding-right: 20px;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.similar-notes-expander:hover {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.similar-notes-expander:hover hr {
|
|
||||||
border-color: var(--main-text-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
.similar-notes-expander:hover .similar-notes-expander-text {
|
|
||||||
color: var(--main-text-color);
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<div class="similar-notes-expander">
|
<div class="area-expander">
|
||||||
<hr class="w-100">
|
<hr class="w-100">
|
||||||
|
|
||||||
<div class="similar-notes-expander-text"
|
<div class="area-expander-text"
|
||||||
title="This list contains notes which might be similar to the current note based on textual similarity of note title, its labels and relations."></div>
|
title="This list contains notes which might be similar to the current note based on textual similarity of note title, its labels and relations."></div>
|
||||||
|
|
||||||
<hr class="w-100">
|
<hr class="w-100">
|
||||||
@ -83,9 +49,9 @@ export default class SimilarNotesWidget extends TabAwareWidget {
|
|||||||
this.overflowing();
|
this.overflowing();
|
||||||
|
|
||||||
this.$similarNotesWrapper = this.$widget.find(".similar-notes-wrapper");
|
this.$similarNotesWrapper = this.$widget.find(".similar-notes-wrapper");
|
||||||
this.$similarNotesExpanderText = this.$widget.find(".similar-notes-expander-text");
|
this.$expanderText = this.$widget.find(".area-expander-text");
|
||||||
|
|
||||||
this.$expander = this.$widget.find('.similar-notes-expander');
|
this.$expander = this.$widget.find('.area-expander');
|
||||||
this.$expander.on('click', async () => {
|
this.$expander.on('click', async () => {
|
||||||
const collapse = this.$similarNotesWrapper.is(":visible");
|
const collapse = this.$similarNotesWrapper.is(":visible");
|
||||||
|
|
||||||
@ -132,7 +98,7 @@ export default class SimilarNotesWidget extends TabAwareWidget {
|
|||||||
this.$similarNotesWrapper.show();
|
this.$similarNotesWrapper.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
this.$similarNotesExpanderText.text(`${similarNotes.length} similar note${similarNotes.length === 1 ? '': "s"}`);
|
this.$expanderText.text(`${similarNotes.length} similar note${similarNotes.length === 1 ? '': "s"}`);
|
||||||
|
|
||||||
const noteIds = similarNotes.flatMap(note => note.notePath);
|
const noteIds = similarNotes.flatMap(note => note.notePath);
|
||||||
|
|
||||||
|
@ -1,98 +1,15 @@
|
|||||||
import linkService from "../../services/link.js";
|
import noteListRenderer from "../../services/note_list_renderer.js";
|
||||||
import treeCache from "../../services/tree_cache.js";
|
|
||||||
import noteContentRenderer from "../../services/note_content_renderer.js";
|
|
||||||
import TypeWidget from "./type_widget.js";
|
import TypeWidget from "./type_widget.js";
|
||||||
|
|
||||||
const MIN_ZOOM_LEVEL = 1;
|
|
||||||
const MAX_ZOOM_LEVEL = 6;
|
|
||||||
|
|
||||||
const ZOOMS = {
|
|
||||||
1: {
|
|
||||||
width: "100%",
|
|
||||||
height: "100%"
|
|
||||||
},
|
|
||||||
2: {
|
|
||||||
width: "49%",
|
|
||||||
height: "350px"
|
|
||||||
},
|
|
||||||
3: {
|
|
||||||
width: "32%",
|
|
||||||
height: "250px"
|
|
||||||
},
|
|
||||||
4: {
|
|
||||||
width: "24%",
|
|
||||||
height: "200px"
|
|
||||||
},
|
|
||||||
5: {
|
|
||||||
width: "19%",
|
|
||||||
height: "175px"
|
|
||||||
},
|
|
||||||
6: {
|
|
||||||
width: "16%",
|
|
||||||
height: "150px"
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const TPL = `
|
const TPL = `
|
||||||
<div class="note-detail-book note-detail-printable">
|
<div class="note-detail-book note-detail-printable">
|
||||||
<style>
|
<style>
|
||||||
/*
|
|
||||||
* We have specific CSS file here instead of being part of the respective widgets to also include this in the printing process
|
|
||||||
*/
|
|
||||||
|
|
||||||
.note-detail-book {
|
.note-detail-book {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
padding: 0 10px 10px 10px;
|
padding: 0 10px 10px 10px;
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
|
||||||
|
|
||||||
.note-detail-book-content {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
overflow: auto;
|
|
||||||
height: 100%;
|
|
||||||
align-content: start;
|
|
||||||
}
|
|
||||||
|
|
||||||
.note-book-card {
|
|
||||||
border-radius: 10px;
|
|
||||||
background-color: var(--accented-background-color);
|
|
||||||
padding: 15px;
|
|
||||||
padding-bottom: 5px;
|
|
||||||
margin: 5px;
|
|
||||||
margin-left: 0;
|
|
||||||
overflow: hidden;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
flex-shrink: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.note-book-card .note-book-card {
|
|
||||||
border: 1px solid var(--main-border-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
.note-book-content {
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.note-book-card.type-image .note-book-content, .note-book-card.type-file .note-book-content, .note-book-card.type-protected-session .note-book-content {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.note-book-card.type-image .note-book-content img, .note-book-card.type-text .note-book-content img {
|
|
||||||
max-width: 100%;
|
|
||||||
max-height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.note-book-title {
|
|
||||||
flex-grow: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.note-book-content {
|
|
||||||
flex-grow: 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.note-book-auto-message {
|
.note-book-auto-message {
|
||||||
@ -103,22 +20,13 @@ const TPL = `
|
|||||||
padding: 5px;
|
padding: 5px;
|
||||||
margin-top: 5px;
|
margin-top: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.note-detail-book-content {
|
||||||
|
flex-grow: 1;
|
||||||
|
min-height: 0;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<div class="btn-group floating-button" style="right: 20px; top: 20px;">
|
|
||||||
<button type="button"
|
|
||||||
class="expand-children-button btn icon-button bx bx-move-vertical"
|
|
||||||
title="Expand all children"></button>
|
|
||||||
|
|
||||||
<button type="button"
|
|
||||||
class="book-zoom-in-button btn icon-button bx bx-zoom-in"
|
|
||||||
title="Zoom In"></button>
|
|
||||||
|
|
||||||
<button type="button"
|
|
||||||
class="book-zoom-out-button btn icon-button bx bx-zoom-out"
|
|
||||||
title="Zoom Out"></button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="note-detail-book-help alert alert-warning" style="margin: 50px; padding: 20px;">
|
<div class="note-detail-book-help alert alert-warning" style="margin: 50px; padding: 20px;">
|
||||||
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.
|
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>
|
||||||
@ -132,68 +40,7 @@ export default class BookTypeWidget extends TypeWidget {
|
|||||||
doRender() {
|
doRender() {
|
||||||
this.$widget = $(TPL);
|
this.$widget = $(TPL);
|
||||||
this.$content = this.$widget.find('.note-detail-book-content');
|
this.$content = this.$widget.find('.note-detail-book-content');
|
||||||
this.$zoomInButton = this.$widget.find('.book-zoom-in-button');
|
|
||||||
this.$zoomOutButton = this.$widget.find('.book-zoom-out-button');
|
|
||||||
this.$expandChildrenButton = this.$widget.find('.expand-children-button');
|
|
||||||
this.$help = this.$widget.find('.note-detail-book-help');
|
this.$help = this.$widget.find('.note-detail-book-help');
|
||||||
|
|
||||||
this.$zoomInButton.on('click', () => this.setZoom(this.zoomLevel - 1));
|
|
||||||
this.$zoomOutButton.on('click', () => this.setZoom(this.zoomLevel + 1));
|
|
||||||
|
|
||||||
this.$expandChildrenButton.on('click', async () => {
|
|
||||||
for (let i = 1; i < 30; i++) { // protection against infinite cycle
|
|
||||||
const $unexpandedLinks = this.$content.find('.note-book-open-children-button:visible');
|
|
||||||
|
|
||||||
if ($unexpandedLinks.length === 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const link of $unexpandedLinks) {
|
|
||||||
const $card = $(link).closest(".note-book-card");
|
|
||||||
|
|
||||||
await this.expandCard($card);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
this.$content.on('click', '.note-book-open-children-button', async ev => {
|
|
||||||
const $card = $(ev.target).closest('.note-book-card');
|
|
||||||
|
|
||||||
await this.expandCard($card);
|
|
||||||
});
|
|
||||||
|
|
||||||
this.$content.on('click', '.note-book-hide-children-button', async ev => {
|
|
||||||
const $card = $(ev.target).closest('.note-book-card');
|
|
||||||
|
|
||||||
$card.find('.note-book-open-children-button').show();
|
|
||||||
$card.find('.note-book-hide-children-button').hide();
|
|
||||||
|
|
||||||
$card.find('.note-book-children-content').empty();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async expandCard($card) {
|
|
||||||
const noteId = $card.attr('data-note-id');
|
|
||||||
const note = await treeCache.getNote(noteId);
|
|
||||||
|
|
||||||
$card.find('.note-book-open-children-button').hide();
|
|
||||||
$card.find('.note-book-hide-children-button').show();
|
|
||||||
|
|
||||||
await this.renderIntoElement(note, $card.find('.note-book-children-content'));
|
|
||||||
}
|
|
||||||
|
|
||||||
setZoom(zoomLevel) {
|
|
||||||
if (!(zoomLevel in ZOOMS)) {
|
|
||||||
zoomLevel = this.getDefaultZoomLevel();
|
|
||||||
}
|
|
||||||
|
|
||||||
this.zoomLevel = zoomLevel;
|
|
||||||
|
|
||||||
this.$zoomInButton.prop("disabled", zoomLevel === MIN_ZOOM_LEVEL);
|
|
||||||
this.$zoomOutButton.prop("disabled", zoomLevel === MAX_ZOOM_LEVEL);
|
|
||||||
|
|
||||||
this.$content.find('.note-book-card').css("flex-basis", ZOOMS[zoomLevel].width);
|
|
||||||
this.$content.find('.note-book-content').css("max-height", ZOOMS[zoomLevel].height);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async doRefresh(note) {
|
async doRefresh(note) {
|
||||||
@ -213,73 +60,10 @@ export default class BookTypeWidget extends TypeWidget {
|
|||||||
.append(' if you want to add some text.'));
|
.append(' if you want to add some text.'));
|
||||||
}
|
}
|
||||||
|
|
||||||
const zoomLevel = parseInt(note.getLabelValue('bookZoomLevel')) || this.getDefaultZoomLevel();
|
// const zoomLevel = parseInt(note.getLabelValue('bookZoomLevel')) || this.getDefaultZoomLevel();
|
||||||
this.setZoom(zoomLevel);
|
// this.setZoom(zoomLevel);
|
||||||
|
|
||||||
await this.renderIntoElement(note, this.$content);
|
this.$content.append(await noteListRenderer.renderList(await note.getChildNotes()));
|
||||||
}
|
|
||||||
|
|
||||||
async renderIntoElement(note, $container) {
|
|
||||||
const childNotes = await note.getChildNotes();
|
|
||||||
|
|
||||||
if (childNotes.length === 0) {
|
|
||||||
this.$help.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
const imageLinks = note.getRelations('imageLink');
|
|
||||||
|
|
||||||
for (const childNote of childNotes) {
|
|
||||||
// image is already visible in the parent note so no need to display it separately in the book
|
|
||||||
if (imageLinks.find(rel => rel.value === childNote.noteId)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
const $card = await this.renderNote(childNote);
|
|
||||||
|
|
||||||
$container.append($card);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async renderNote(note) {
|
|
||||||
const notePath = this.notePath + '/' + note.noteId;
|
|
||||||
|
|
||||||
const $content = $('<div class="note-book-content">')
|
|
||||||
.css("max-height", ZOOMS[this.zoomLevel].height);
|
|
||||||
|
|
||||||
const $card = $('<div class="note-book-card">')
|
|
||||||
.attr('data-note-id', note.noteId)
|
|
||||||
.css("flex-basis", ZOOMS[this.zoomLevel].width)
|
|
||||||
.append($('<h5 class="note-book-title">').append(await linkService.createNoteLink(notePath, {showTooltip: false})))
|
|
||||||
.append($content);
|
|
||||||
|
|
||||||
try {
|
|
||||||
const {type, renderedContent} = await noteContentRenderer.getRenderedContent(note);
|
|
||||||
|
|
||||||
$card.addClass("type-" + type);
|
|
||||||
$content.append(renderedContent);
|
|
||||||
} catch (e) {
|
|
||||||
console.log(`Caught error while rendering note ${note.noteId} of type ${note.type}: ${e.message}, stack: ${e.stack}`);
|
|
||||||
|
|
||||||
$content.append("rendering error");
|
|
||||||
}
|
|
||||||
|
|
||||||
const imageLinks = note.getRelations('imageLink');
|
|
||||||
|
|
||||||
const childCount = note.getChildNoteIds()
|
|
||||||
.filter(childNoteId => !imageLinks.find(rel => rel.value === childNoteId))
|
|
||||||
.length;
|
|
||||||
|
|
||||||
if (childCount > 0) {
|
|
||||||
const label = `${childCount} child${childCount > 1 ? 'ren' : ''}`;
|
|
||||||
|
|
||||||
$card.append($('<div class="note-book-children">')
|
|
||||||
.append($(`<a class="note-book-open-children-button no-print" href="javascript:">+ Show ${label}</a>`))
|
|
||||||
.append($(`<a class="note-book-hide-children-button no-print" href="javascript:">- Hide ${label}</a>`).hide())
|
|
||||||
.append($('<div class="note-book-children-content">'))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $card;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @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 */
|
||||||
|
@ -1,15 +1,90 @@
|
|||||||
import TypeWidget from "./type_widget.js";
|
import TypeWidget from "./type_widget.js";
|
||||||
|
import noteAutocompleteService from "../../services/note_autocomplete.js";
|
||||||
|
|
||||||
const TPL = `
|
const TPL = `
|
||||||
<div class="note-detail-search note-detail-printable" style="padding: 20px;">
|
<div class="note-detail-search note-detail-printable">
|
||||||
<div style="display: flex; align-items: center; margin-right: 20px; margin-top: 15px;">
|
<style>
|
||||||
<strong>Search string: </strong>
|
.note-detail-search {
|
||||||
<textarea rows="4" style="width: auto !important; flex-grow: 4" class="search-string form-control"></textarea>
|
padding: 7px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-setting-table {
|
||||||
|
width: 100%;
|
||||||
|
border-collapse: separate;
|
||||||
|
border-spacing: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-setting-expander {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
color: var(--muted-text-color);
|
||||||
|
font-size: 90%;
|
||||||
|
margin: 3px 0 3px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.attribute-list hr {
|
||||||
|
height: 1px;
|
||||||
|
border-color: var(--main-border-color);
|
||||||
|
position: relative;
|
||||||
|
top: 4px;
|
||||||
|
margin-top: 5px;
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-setting-expander-text {
|
||||||
|
padding-left: 20px;
|
||||||
|
padding-right: 20px;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-setting-expander:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-setting-expander:hover hr {
|
||||||
|
border-color: var(--main-text-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-setting-expander:hover .search-setting-expander-text {
|
||||||
|
color: var(--main-text-color);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div class="area-expander">
|
||||||
|
<hr class="w-100">
|
||||||
|
|
||||||
|
<div class="area-expander-text">Search settings</div>
|
||||||
|
|
||||||
|
<hr class="w-100">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<br />
|
<div class="search-settings">
|
||||||
|
<table class="search-setting-table">
|
||||||
|
<tr>
|
||||||
|
<td>Search string:</td>
|
||||||
|
<td colspan="3">
|
||||||
|
<input type="text" class="form-control">
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Limit search to subtree:</td>
|
||||||
|
<td>
|
||||||
|
<div class="input-group">
|
||||||
|
<input class="limit-search-to-subtree form-control" placeholder="search for note by its name">
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td colspan="2" style="padding-top: 9px;">
|
||||||
|
<label title="By choosing to take into acount also note content, search can be slightly slower">
|
||||||
|
<input class="search-within-note-content" value="1" type="checkbox" checked>
|
||||||
|
|
||||||
<div class="note-detail-search-help"></div>
|
Search also within note content
|
||||||
|
</label>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<hr class="w-100 search-setting-empty-expander" style="margin-bottom: 10px;">
|
||||||
|
</div>
|
||||||
</div>`;
|
</div>`;
|
||||||
|
|
||||||
export default class SearchTypeWidget extends TypeWidget {
|
export default class SearchTypeWidget extends TypeWidget {
|
||||||
@ -19,7 +94,22 @@ export default class SearchTypeWidget extends TypeWidget {
|
|||||||
this.$widget = $(TPL);
|
this.$widget = $(TPL);
|
||||||
this.$searchString = this.$widget.find(".search-string");
|
this.$searchString = this.$widget.find(".search-string");
|
||||||
this.$component = this.$widget.find('.note-detail-search');
|
this.$component = this.$widget.find('.note-detail-search');
|
||||||
this.$help = this.$widget.find(".note-detail-search-help");
|
|
||||||
|
this.$settingsArea = this.$widget.find('.search-settings');
|
||||||
|
|
||||||
|
this.$limitSearchToSubtree = this.$widget.find('.limit-search-to-subtree');
|
||||||
|
noteAutocompleteService.initNoteAutocomplete(this.$limitSearchToSubtree);
|
||||||
|
|
||||||
|
this.$settingExpander = this.$widget.find('.area-expander');
|
||||||
|
this.$settingExpander.on('click', async () => {
|
||||||
|
const collapse = this.$settingsArea.is(":visible");
|
||||||
|
|
||||||
|
if (collapse) {
|
||||||
|
this.$settingsArea.slideUp(200);
|
||||||
|
} else {
|
||||||
|
this.$settingsArea.slideDown(200);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async doRefresh(note) {
|
async doRefresh(note) {
|
||||||
|
@ -650,6 +650,7 @@ a.external:not(.no-arrow):after, a[href^="http://"]:not(.no-arrow):after, a[href
|
|||||||
|
|
||||||
.component {
|
.component {
|
||||||
contain: size;
|
contain: size;
|
||||||
|
content-visibility: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.toast {
|
.toast {
|
||||||
@ -859,3 +860,36 @@ ul.fancytree-container li {
|
|||||||
.ck.ck-balloon-panel {
|
.ck.ck-balloon-panel {
|
||||||
z-index: 1101;
|
z-index: 1101;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.area-expander {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
color: var(--muted-text-color);
|
||||||
|
font-size: 90%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.area-expander hr {
|
||||||
|
height: 1px;
|
||||||
|
border-color: var(--main-border-color);
|
||||||
|
position: relative;
|
||||||
|
top: 4px;
|
||||||
|
margin-top: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.area-expander-text {
|
||||||
|
padding-left: 20px;
|
||||||
|
padding-right: 20px;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.area-expander:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.area-expander:hover hr {
|
||||||
|
border-color: var(--main-text-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.area-expander:hover .area-expander-text {
|
||||||
|
color: var(--main-text-color);
|
||||||
|
}
|
||||||
|
@ -14,10 +14,14 @@ function changePassword(currentPassword, newPassword) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const newPasswordVerificationKey = utils.toBase64(myScryptService.getVerificationHash(newPassword));
|
sql.transactional(() => {
|
||||||
const decryptedDataKey = passwordEncryptionService.getDataKey(currentPassword);
|
const decryptedDataKey = passwordEncryptionService.getDataKey(currentPassword);
|
||||||
|
|
||||||
sql.transactional(() => {
|
optionService.setOption('passwordVerificationSalt', utils.randomSecureToken(32));
|
||||||
|
optionService.setOption('passwordDerivedKeySalt', utils.randomSecureToken(32));
|
||||||
|
|
||||||
|
const newPasswordVerificationKey = utils.toBase64(myScryptService.getVerificationHash(newPassword));
|
||||||
|
|
||||||
passwordEncryptionService.setDataKey(newPassword, decryptedDataKey);
|
passwordEncryptionService.setDataKey(newPassword, decryptedDataKey);
|
||||||
|
|
||||||
optionService.setOption('passwordVerificationHash', newPasswordVerificationKey);
|
optionService.setOption('passwordVerificationHash', newPasswordVerificationKey);
|
||||||
|
@ -338,7 +338,7 @@ class Note {
|
|||||||
|
|
||||||
decrypt() {
|
decrypt() {
|
||||||
if (this.isProtected && !this.isDecrypted && protectedSessionService.isProtectedSessionAvailable()) {
|
if (this.isProtected && !this.isDecrypted && protectedSessionService.isProtectedSessionAvailable()) {
|
||||||
this.title = protectedSessionService.decryptString(note.title);
|
this.title = protectedSessionService.decryptString(this.title);
|
||||||
|
|
||||||
this.isDecrypted = true;
|
this.isDecrypted = true;
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ const sql = require('../sql.js');
|
|||||||
const eventService = require('../events.js');
|
const eventService = require('../events.js');
|
||||||
const noteCache = require('./note_cache');
|
const noteCache = require('./note_cache');
|
||||||
const sqlInit = require('../sql_init');
|
const sqlInit = require('../sql_init');
|
||||||
|
const log = require('../log');
|
||||||
const Note = require('./entities/note');
|
const Note = require('./entities/note');
|
||||||
const Branch = require('./entities/branch');
|
const Branch = require('./entities/branch');
|
||||||
const Attribute = require('./entities/attribute');
|
const Attribute = require('./entities/attribute');
|
||||||
@ -147,7 +148,12 @@ eventService.subscribe([eventService.ENTITY_CHANGED, eventService.ENTITY_DELETED
|
|||||||
});
|
});
|
||||||
|
|
||||||
eventService.subscribe(eventService.ENTER_PROTECTED_SESSION, () => {
|
eventService.subscribe(eventService.ENTER_PROTECTED_SESSION, () => {
|
||||||
|
try {
|
||||||
noteCache.decryptProtectedNotes();
|
noteCache.decryptProtectedNotes();
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
log.error(`Could not decrypt protected notes: ${e.message} ${e.stack}`);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const utils = require('./utils');
|
const utils = require('./utils');
|
||||||
|
const log = require('./log');
|
||||||
const dataEncryptionService = require('./data_encryption');
|
const dataEncryptionService = require('./data_encryption');
|
||||||
const cls = require('./cls');
|
const cls = require('./cls');
|
||||||
|
|
||||||
@ -35,11 +36,16 @@ function isProtectedSessionAvailable() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function decryptNotes(notes) {
|
function decryptNotes(notes) {
|
||||||
|
try {
|
||||||
for (const note of notes) {
|
for (const note of notes) {
|
||||||
if (note.isProtected) {
|
if (note.isProtected) {
|
||||||
note.title = decryptString(note.title);
|
note.title = decryptString(note.title);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
log.error(`Could not decrypt protected notes: ${e.message} ${e.stack}`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function encrypt(plainText) {
|
function encrypt(plainText) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user