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