Skip to content

Commit

Permalink
Merge pull request rails#52680 from MatheusRich/action-text-attachmen…
Browse files Browse the repository at this point in the history
…t-events

Dispatch direct-upload events on attachment uploads
  • Loading branch information
rafaelfranca authored Aug 27, 2024
2 parents 48aaffd + 8f0b911 commit 5a0b2fa
Show file tree
Hide file tree
Showing 8 changed files with 102 additions and 20 deletions.
12 changes: 12 additions & 0 deletions actiontext/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
* Dispatch direct-upload events on attachment uploads

When using Action Text's rich textarea, it's possible to attach files to the
editor. Previously, that action didn't dispatch any events, which made it hard
to react to the file uploads. For instance, if an upload failed, there was no
way to notify the user about it, or remove the attachment from the editor.

This commits adds new events - `direct-upload:start`, `direct-upload:progress`,
and `direct-upload:end` - similar to how Active Storage's direct uploads work.

*Matheus Richard*, *Brad Rees*

* Add `store_if_blank` option to `has_rich_text`

Pass `store_if_blank: false` to not create `ActionText::RichText` records when saving with a blank attribute, such as from an optional form parameter.
Expand Down
32 changes: 27 additions & 5 deletions actiontext/app/assets/javascripts/actiontext.esm.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

32 changes: 27 additions & 5 deletions actiontext/app/assets/javascripts/actiontext.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

31 changes: 24 additions & 7 deletions actiontext/app/javascript/actiontext/attachment_upload.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { DirectUpload } from "@rails/activestorage"
import { DirectUpload, dispatchEvent } from "@rails/activestorage"

export class AttachmentUpload {
constructor(attachment, element) {
Expand All @@ -9,24 +9,29 @@ export class AttachmentUpload {

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) {
throw new Error(`Direct upload failed: ${error}`)
this.dispatchError(error)
} else {
this.attachment.setAttributes({
sgid: attributes.attachable_sgid,
url: this.createBlobUrl(attributes.signed_id, attributes.filename)
})
this.dispatch("end")
}

this.attachment.setAttributes({
sgid: attributes.attachable_sgid,
url: this.createBlobUrl(attributes.signed_id, attributes.filename)
})
}

createBlobUrl(signedId, filename) {
Expand All @@ -35,6 +40,18 @@ export class AttachmentUpload {
.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
}
Expand Down
2 changes: 1 addition & 1 deletion activestorage/app/assets/javascripts/activestorage.esm.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions activestorage/app/assets/javascripts/activestorage.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion activestorage/app/javascript/activestorage/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import { start } from "./ujs"
import { DirectUpload } from "./direct_upload"
import { DirectUploadController } from "./direct_upload_controller"
import { DirectUploadsController } from "./direct_uploads_controller"
export { start, DirectUpload, DirectUploadController, DirectUploadsController }
import { dispatchEvent } from "./helpers"
export { start, DirectUpload, DirectUploadController, DirectUploadsController, dispatchEvent }

function autostart() {
if (window.ActiveStorage) {
Expand Down
9 changes: 8 additions & 1 deletion guides/source/action_text_overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,6 @@ To customize the HTML rendered for embedded images and other attachments (known
as blobs), edit the `app/views/active_storage/blobs/_blob.html.erb` template
created by the installer:
```html+erb
<%# app/views/active_storage/blobs/_blob.html.erb %>
<figure class="attachment attachment--<%= blob.representable? ? "preview" : "file" %> attachment--<%= blob.filename.extension %>">
Expand Down Expand Up @@ -270,6 +269,14 @@ encounter when working with Action Text and Active Storage is that images do not
render correctly in the editor. This is usually due to the `libvips` dependency
not being installed.
#### Attachment Direct Upload JavaScript Events
| Event name | Event target | Event data (`event.detail`) | Description |
| --- | --- | --- | --- |
| `direct-upload:start` | `<input>` | `{id, file}` | A direct upload is starting. |
| `direct-upload:progress` | `<input>` | `{id, file, progress}` | As requests to store files progress. |
| `direct-upload:error` | `<input>` | `{id, file, error}` | An error occurred. An `alert` will display unless this event is canceled. |
| `direct-upload:end` | `<input>` | `{id, file}` | A direct upload has ended. |
### Signed GlobalID
Expand Down

0 comments on commit 5a0b2fa

Please sign in to comment.