diff --git a/src/becca/entities/battachment.js b/src/becca/entities/battachment.js
index 7c1f9e50b..2f60d54ec 100644
--- a/src/becca/entities/battachment.js
+++ b/src/becca/entities/battachment.js
@@ -147,6 +147,8 @@ class BAttachment extends AbstractBeccaEntity {
if (fixedContent !== origContent) {
parentNote.setContent(fixedContent);
}
+
+ noteService.asyncPostProcessContent(note, fixedContent);
}
return { note, branch };
diff --git a/src/public/app/menus/tree_context_menu.js b/src/public/app/menus/tree_context_menu.js
index 5b792da72..2439371b3 100644
--- a/src/public/app/menus/tree_context_menu.js
+++ b/src/public/app/menus/tree_context_menu.js
@@ -5,6 +5,9 @@ import noteCreateService from "../services/note_create.js";
import contextMenu from "./context_menu.js";
import appContext from "../components/app_context.js";
import noteTypesService from "../services/note_types.js";
+import server from "../services/server.js";
+import toastService from "../services/toast.js";
+import dialogService from "../services/dialog.js";
export default class TreeContextMenu {
/**
@@ -66,7 +69,8 @@ export default class TreeContextMenu {
{ title: 'Collapse subtree ', command: "collapseSubtree", uiIcon: "bx bx-collapse", enabled: noSelectedNotes },
{ title: "Force note sync", command: "forceNoteSync", uiIcon: "bx bx-refresh", enabled: noSelectedNotes },
{ title: 'Sort by ... ', command: "sortChildNotes", uiIcon: "bx bx-empty", enabled: noSelectedNotes && notSearch },
- { title: 'Recent changes in subtree', command: "recentChangesInSubtree", uiIcon: "bx bx-history", enabled: noSelectedNotes }
+ { title: 'Recent changes in subtree', command: "recentChangesInSubtree", uiIcon: "bx bx-history", enabled: noSelectedNotes },
+ { title: 'Convert to attachment', command: "convertNoteToAttachment", uiIcon: "bx bx-empty", enabled: isNotRoot && !isHoisted }
] },
{ title: "----" },
{ title: "Protect subtree", command: "protectSubtree", uiIcon: "bx bx-check-shield", enabled: noSelectedNotes },
@@ -129,6 +133,27 @@ export default class TreeContextMenu {
this.treeWidget.triggerCommand("openNewNoteSplit", {ntxId, notePath});
}
+ else if (command === 'convertNoteToAttachment') {
+ if (!await dialogService.confirm(`Are you sure you want to convert note selected notes into attachments of their parent notes?`)) {
+ return;
+ }
+
+ let converted = 0;
+
+ for (const noteId of this.treeWidget.getSelectedOrActiveNoteIds(this.node)) {
+ const note = await froca.getNote(noteId);
+
+ if (note.isEligibleForConversionToAttachment()) {
+ const {attachment} = await server.post(`notes/${note.noteId}/convert-to-attachment`);
+
+ if (attachment) {
+ converted++;
+ }
+ }
+ }
+
+ toastService.showMessage(`${converted} notes have been converted to attachments.`);
+ }
else {
this.treeWidget.triggerCommand(command, {
node: this.node,
diff --git a/src/services/notes.js b/src/services/notes.js
index ec50c3be8..796c89070 100644
--- a/src/services/notes.js
+++ b/src/services/notes.js
@@ -874,7 +874,7 @@ function eraseAttachments(attachmentIdsToErase) {
function eraseUnusedBlobs() {
const unusedBlobIds = sql.getColumn(`
- SELECT blobId
+ SELECT blobs.blobId
FROM blobs
LEFT JOIN notes ON notes.blobId = blobs.blobId
LEFT JOIN attachments ON attachments.blobId = blobs.blobId