diff --git a/src/becca/entities/bnote.js b/src/becca/entities/bnote.js index 20cfe9f20..1a97b9cf8 100644 --- a/src/becca/entities/bnote.js +++ b/src/becca/entities/bnote.js @@ -1545,7 +1545,7 @@ class BNote extends AbstractBeccaEntity { */ saveNoteRevision() { return sql.transactional(() => { - const content = this.getContent(); + let noteContent = this.getContent(); const contentMetadata = this.getContentMetadata(); const noteRevision = new BNoteRevision({ @@ -1566,19 +1566,24 @@ class BNote extends AbstractBeccaEntity { dateCreated: dateUtils.localNowDateTime() }, true); - noteRevision.setContent(content, { forceSave: true }); + noteRevision.save(); // to generate noteRevisionId which is then used to save attachments for (const noteAttachment of this.getAttachments()) { - const content = noteAttachment.getContent(); + const attachmentContent = noteAttachment.getContent(); const revisionAttachment = noteAttachment.copy(); revisionAttachment.parentId = noteRevision.noteRevisionId; - revisionAttachment.setContent(content, { + revisionAttachment.setContent(attachmentContent, { forceSave: true, forceCold: true }); + + // content is rewritten to point to the revision attachments + noteContent = noteContent.replaceAll(`attachments/${noteAttachment.attachmentId}`, `attachments/${revisionAttachment.attachmentId}`); } + noteRevision.setContent(noteContent, { forceSave: true }); + return noteRevision; }); } diff --git a/src/public/app/services/froca.js b/src/public/app/services/froca.js index 1d775ec11..3e67f583b 100644 --- a/src/public/app/services/froca.js +++ b/src/public/app/services/froca.js @@ -4,6 +4,7 @@ import FAttribute from "../entities/fattribute.js"; import server from "./server.js"; import appContext from "../components/app_context.js"; import FNoteComplement from "../entities/fnote_complement.js"; +import FAttachment from "../entities/fattachment.js"; /** * Froca (FROntend CAche) keeps a read only cache of note tree structure in frontend's memory. @@ -314,6 +315,12 @@ class Froca { return child.parentToBranch[parentNoteId]; } + async getAttachment(attachmentId) { + const attachmentRow = await server.get(`attachments/${attachmentId}`); + + return attachmentRow ? new FAttachment(this, attachmentRow) : null; + } + /** * // FIXME * @returns {Promise} diff --git a/src/public/app/widgets/attachment_detail.js b/src/public/app/widgets/attachment_detail.js index 31c4fcd82..1f5ef41f8 100644 --- a/src/public/app/widgets/attachment_detail.js +++ b/src/public/app/widgets/attachment_detail.js @@ -123,7 +123,7 @@ export default class AttachmentDetailWidget extends BasicWidget { if (attachmentChange.isDeleted) { this.toggleInt(false); } else { - this.attachment = await server.get(`notes/${this.attachment.parentId}/attachments/${this.attachment.attachmentId}?includeContent=true`); + this.attachment = await server.get(`attachments/${this.attachment.attachmentId}?includeContent=true`); this.refresh(); } diff --git a/src/public/app/widgets/buttons/attachments_actions.js b/src/public/app/widgets/buttons/attachments_actions.js index 053b37661..022c3c0af 100644 --- a/src/public/app/widgets/buttons/attachments_actions.js +++ b/src/public/app/widgets/buttons/attachments_actions.js @@ -48,7 +48,7 @@ export default class AttachmentActionsWidget extends BasicWidget { async deleteAttachmentCommand() { if (await dialogService.confirm(`Are you sure you want to delete attachment '${this.attachment.title}'?`)) { - await server.remove(`notes/${this.attachment.parentId}/attachments/${this.attachment.attachmentId}`); + await server.remove(`attachments/${this.attachment.attachmentId}`); toastService.showMessage(`Attachment '${this.attachment.title}' has been deleted.`); } @@ -56,7 +56,7 @@ export default class AttachmentActionsWidget extends BasicWidget { async convertAttachmentIntoNoteCommand() { if (await dialogService.confirm(`Are you sure you want to convert attachment '${this.attachment.title}' into a separate note?`)) { - const {note: newNote} = await server.post(`notes/${this.attachment.parentId}/attachments/${this.attachment.attachmentId}/convert-to-note`) + const {note: newNote} = await server.post(`attachments/${this.attachment.attachmentId}/convert-to-note`) toastService.showMessage(`Attachment '${this.attachment.title}' has been converted to note.`); diff --git a/src/public/app/widgets/type_widgets/abstract_text_type_widget.js b/src/public/app/widgets/type_widgets/abstract_text_type_widget.js index 7f6fa52bd..6b96caac3 100644 --- a/src/public/app/widgets/type_widgets/abstract_text_type_widget.js +++ b/src/public/app/widgets/type_widgets/abstract_text_type_widget.js @@ -23,8 +23,8 @@ export default class AbstractTextTypeWidget extends TypeWidget { }); } - openImageInCurrentTab($img) { - const { noteId, viewScope } = this.parseFromImage($img); + async openImageInCurrentTab($img) { + const { noteId, viewScope } = await this.parseFromImage($img); if (noteId) { appContext.tabManager.getActiveContext().setNote(noteId, { viewScope }); @@ -43,7 +43,7 @@ export default class AbstractTextTypeWidget extends TypeWidget { } } - parseFromImage($img) { + async parseFromImage($img) { let noteId, viewScope; const imgSrc = $img.prop("src"); @@ -56,13 +56,16 @@ export default class AbstractTextTypeWidget extends TypeWidget { } } - const attachmentMatch = imgSrc.match(/\/api\/notes\/([A-Za-z0-9_]+)\/images\/([A-Za-z0-9_]+)\//); + const attachmentMatch = imgSrc.match(/\/api\/attachments\/([A-Za-z0-9_]+)\/image\//); if (attachmentMatch) { + const attachmentId = attachmentMatch[1]; + const attachment = await froca.getAttachment(attachmentId); + return { - noteId: attachmentMatch[1], + noteId: attachment.parentId, viewScope: { viewMode: 'attachments', - attachmentId: attachmentMatch[2] + attachmentId: attachmentId } } } diff --git a/src/public/app/widgets/type_widgets/attachment_detail.js b/src/public/app/widgets/type_widgets/attachment_detail.js index 3e390c974..f1abecc17 100644 --- a/src/public/app/widgets/type_widgets/attachment_detail.js +++ b/src/public/app/widgets/type_widgets/attachment_detail.js @@ -30,7 +30,7 @@ export default class AttachmentDetailTypeWidget extends TypeWidget { this.children = []; this.renderedAttachmentIds = new Set(); - const attachment = await server.get(`notes/${this.noteId}/attachments/${this.noteContext.viewScope.attachmentId}/?includeContent=true`); + const attachment = await server.get(`attachments/${this.noteContext.viewScope.attachmentId}/?includeContent=true`); if (!attachment) { this.$wrapper.html("This attachment has been deleted.");