diff --git a/app/components/avo/fields/trix_field/edit_component.html.erb b/app/components/avo/fields/trix_field/edit_component.html.erb index 7318cffc7e..4c50590840 100644 --- a/app/components/avo/fields/trix_field/edit_component.html.erb +++ b/app/components/avo/fields/trix_field/edit_component.html.erb @@ -10,6 +10,8 @@ class: 'trix-content', data: { "trix-field-target": "editor", + "direct-upload-url": helpers.main_app.rails_direct_uploads_url, + "blob-url-template": helpers.main_app.rails_service_blob_url(":signed_id", ":filename"), **@field.get_html(:data, view: view, element: :input) }, input: trix_id, diff --git a/app/javascript/js/controllers/fields/trix_field_controller.js b/app/javascript/js/controllers/fields/trix_field_controller.js index 9b9796c352..97f2e764f7 100644 --- a/app/javascript/js/controllers/fields/trix_field_controller.js +++ b/app/javascript/js/controllers/fields/trix_field_controller.js @@ -72,10 +72,11 @@ export default class extends Controller { }) window.addEventListener('trix-attachment-add', (event) => { - if (event.target === this.editorTarget) { - if (event.attachment.file) { - this.uploadFileAttachment(event.attachment) - } + const { attachment, target } = event + + if (target === this.editorTarget && attachment.file) { + const upload = new AttachmentUpload(attachment, target) + upload.start() } }) } @@ -152,3 +153,68 @@ export default class extends Controller { return data } } + + +import { DirectUpload, dispatchEvent } from "@rails/activestorage" + +// Code from https://github.com/rails/rails/blob/main/actiontext/app/javascript/actiontext/attachment_upload.js +export class AttachmentUpload { + constructor(attachment, element) { + this.attachment = attachment + this.element = element + this.directUpload = new DirectUpload(attachment.file, this.directUploadUrl, this) + } + + start() { + this.directUpload.create(this.directUploadDidComplete.bind(this)) + this.dispatch("start") + } + + directUploadWillStoreFileWithXHR(xhr) { + xhr.upload.addEventListener("progress", event => { + const progress = event.loaded / event.total * 100 + this.attachment.setUploadProgress(progress) + if (progress) { + this.dispatch("progress", { progress: progress }) + } + }) + } + + directUploadDidComplete(error, attributes) { + if (error) { + this.dispatchError(error) + } else { + this.attachment.setAttributes({ + sgid: attributes.attachable_sgid, + url: this.createBlobUrl(attributes.signed_id, attributes.filename) + }) + this.dispatch("end") + } + } + + createBlobUrl(signedId, filename) { + return this.blobUrlTemplate + .replace(":signed_id", signedId) + .replace(":filename", encodeURIComponent(filename)) + } + + dispatch(name, detail = {}) { + detail.attachment = this.attachment + return dispatchEvent(this.element, `direct-upload:${name}`, { detail }) + } + + dispatchError(error) { + const event = this.dispatch("error", { error }) + if (!event.defaultPrevented) { + alert(error); + } + } + + get directUploadUrl() { + return this.element.dataset.directUploadUrl + } + + get blobUrlTemplate() { + return this.element.dataset.blobUrlTemplate + } +} \ No newline at end of file