This commit is contained in:
zadam
2023-06-29 20:54:58 +02:00
parent 788841d256
commit faa402fcda
32 changed files with 4286 additions and 4054 deletions

View File

@@ -29,10 +29,10 @@
<pre class="prettyprint source linenums"><code>import server from '../services/server.js';
import noteAttributeCache from "../services/note_attribute_cache.js";
import ws from "../services/ws.js";
import options from "../services/options.js";
import froca from "../services/froca.js";
import protectedSessionHolder from "../services/protected_session_holder.js";
import cssClassManager from "../services/css_class_manager.js";
import FAttachment from "./fattachment.js";
const LABEL = 'label';
const RELATION = 'relation';
@@ -79,6 +79,9 @@ class FNote {
/** @type {Object.&lt;string, string>} */
this.childToBranch = {};
/** @type {FAttachment[]|null} */
this.attachments = null; // lazy loaded
this.update(row);
}
@@ -220,7 +223,7 @@ class FNote {
}
// will sort the parents so that non-search &amp; non-archived are first and archived at the end
// this is done so that non-search &amp; non-archived paths are always explored as first when looking for note path
// this is done so that non-search &amp; non-archived paths are always explored as first when looking for a note path
sortParents() {
this.parents.sort((aNoteId, bNoteId) => {
const aBranchId = this.parentToBranch[aNoteId];
@@ -253,6 +256,45 @@ class FNote {
return await this.froca.getNotes(this.children);
}
/** @returns {Promise&lt;FAttachment[]>} */
async getAttachments() {
if (!this.attachments) {
this.attachments = await this.froca.getAttachmentsForNote(this.noteId);
}
return this.attachments;
}
/** @returns {Promise&lt;FAttachment>} */
async getAttachmentById(attachmentId) {
const attachments = await this.getAttachments();
return attachments.find(att => att.attachmentId === attachmentId);
}
isEligibleForConversionToAttachment() {
if (this.type !== 'image' || !this.isContentAvailable() || this.hasChildren() || this.getParentBranches().length !== 1) {
return false;
}
const targetRelations = this.getTargetRelations().filter(relation => relation.name === 'imageLink');
if (targetRelations.length > 1) {
return false;
}
const parentNote = this.getParentNotes()[0]; // at this point note can have only one parent
const referencingNote = targetRelations[0]?.getNote();
if (referencingNote &amp;&amp; referencingNote !== parentNote) {
return false;
} else if (parentNote.type !== 'text' || !parentNote.isContentAvailable()) {
return false;
}
return true;
}
/**
* @param {string} [type] - (optional) attribute type to filter
* @param {string} [name] - (optional) attribute name to filter
@@ -343,13 +385,10 @@ class FNote {
}
const parentNotes = this.getParentNotes().filter(note => note.type !== 'search');
let notePaths = [];
if (parentNotes.length === 1) { // optimization for most common case
notePaths = parentNotes[0].getAllNotePaths();
} else {
notePaths = parentNotes.flatMap(parentNote => parentNote.getAllNotePaths());
}
const notePaths = parentNotes.length === 1
? parentNotes[0].getAllNotePaths() // optimization for the most common case
: parentNotes.flatMap(parentNote => parentNote.getAllNotePaths());
for (const notePath of notePaths) {
notePath.push(this.noteId);
@@ -388,7 +427,7 @@ class FNote {
}
/**
* Returns note path considered to be the "best"
* Returns the note path considered to be the "best"
*
* @param {string} [hoistedNoteId='root']
* @return {string[]} array of noteIds constituting the particular note path
@@ -398,7 +437,7 @@ class FNote {
}
/**
* Returns note path considered to be the "best"
* Returns the note path considered to be the "best"
*
* @param {string} [hoistedNoteId='root']
* @return {string} serialized note path (e.g. 'root/a1h315/js725h')
@@ -538,17 +577,10 @@ class FNote {
return;
}
if (options.is("hideIncludedImages_main")) {
const imageLinks = this.getRelations('imageLink');
// image is already visible in the parent note so no need to display it separately in the book
childBranches = childBranches.filter(branch => !imageLinks.find(rel => rel.value === branch.noteId));
}
// we're not checking hideArchivedNotes since that would mean we need to lazy load the child notes
// which would seriously slow down everything.
// we check this flag only once user chooses to expand the parent. This has the negative consequence that
// note may appear as folder but not contain any children when all of them are archived
// note may appear as a folder but not contain any children when all of them are archived
return childBranches;
}
@@ -592,7 +624,7 @@ class FNote {
/**
* @param {string} type - attribute type (label, relation, etc.)
* @param {string} name - attribute name
* @returns {FAttribute} attribute of given type and name. If there's more such attributes, first is returned. Returns null if there's no such attribute belonging to this note.
* @returns {FAttribute} attribute of the given type and name. If there are more such attributes, first is returned. Returns null if there's no such attribute belonging to this note.
*/
getOwnedAttribute(type, name) {
const attributes = this.getOwnedAttributes();
@@ -603,7 +635,7 @@ class FNote {
/**
* @param {string} type - attribute type (label, relation, etc.)
* @param {string} name - attribute name
* @returns {FAttribute} attribute of given type and name. If there's more such attributes, first is returned. Returns null if there's no such attribute belonging to this note.
* @returns {FAttribute} attribute of the given type and name. If there are more such attributes, first is returned. Returns null if there's no such attribute belonging to this note.
*/
getAttribute(type, name) {
const attributes = this.getAttributes();
@@ -614,7 +646,7 @@ class FNote {
/**
* @param {string} type - attribute type (label, relation, etc.)
* @param {string} name - attribute name
* @returns {string} attribute value of given type and name or null if no such attribute exists.
* @returns {string} attribute value of the given type and name or null if no such attribute exists.
*/
getOwnedAttributeValue(type, name) {
const attr = this.getOwnedAttribute(type, name);
@@ -625,7 +657,7 @@ class FNote {
/**
* @param {string} type - attribute type (label, relation, etc.)
* @param {string} name - attribute name
* @returns {string} attribute value of given type and name or null if no such attribute exists.
* @returns {string} attribute value of the given type and name or null if no such attribute exists.
*/
getAttributeValue(type, name) {
const attr = this.getAttribute(type, name);
@@ -757,7 +789,7 @@ class FNote {
}
getPromotedDefinitionAttributes() {
if (this.hasLabel('hidePromotedAttributes')) {
if (this.isLabelTruthy('hidePromotedAttributes')) {
return [];
}
@@ -769,7 +801,7 @@ class FNote {
return def &amp;&amp; def.isPromoted;
});
// attrs are not resorted if position changes after initial load
// attrs are not resorted if position changes after the initial load
promotedAttrs.sort((a, b) => {
if (a.noteId === b.noteId) {
return a.position &lt; b.position ? -1 : 1;
@@ -835,7 +867,7 @@ class FNote {
/**
* Get relations which target this note
*
* @returns {FNote[]}
* @returns {Promise&lt;FNote[]>}
*/
async getTargetRelationSourceNotes() {
const targetRelations = this.getTargetRelations();
@@ -844,12 +876,19 @@ class FNote {
}
/**
* Return note complement which is most importantly note's content
*
* @returns {Promise&lt;FNoteComplement>}
* @deprecated use getBlob() instead
* @return {Promise&lt;FBlob>}
*/
async getNoteComplement() {
return await this.froca.getNoteComplement(this.noteId);
return this.getBlob();
}
/**
* @param [opts.preview=false] - retrieve only first 10 000 characters for a preview
* @return {Promise&lt;FBlob>}
*/
async getBlob(opts = {}) {
return await this.froca.getBlob('notes', this.noteId, opts);
}
toString() {
@@ -971,7 +1010,7 @@ export default FNote;
</div>
<nav>
<h2><a href="index.html">Home</a></h2><h3>Classes</h3><ul><li><a href="FAttribute.html">FAttribute</a></li><li><a href="FBranch.html">FBranch</a></li><li><a href="FNote.html">FNote</a></li><li><a href="FNoteComplement.html">FNoteComplement</a></li><li><a href="FrontendScriptApi.html">FrontendScriptApi</a></li></ul>
<h2><a href="index.html">Home</a></h2><h3>Classes</h3><ul><li><a href="FAttribute.html">FAttribute</a></li><li><a href="FBranch.html">FBranch</a></li><li><a href="FNote.html">FNote</a></li><li><a href="FrontendScriptApi.html">FrontendScriptApi</a></li></ul>
</nav>
<br class="clear">