Skip to content

Commit

Permalink
Add image uploads to the EasyMDE editor
Browse files Browse the repository at this point in the history
  • Loading branch information
erozas committed Jan 27, 2025
1 parent e30fc28 commit 2120913
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
view: view,
'easy-mde-target': 'element',
'component-options': @field.options.to_json,
upload_url: @field.options[:upload_url]
},
disabled: disabled?,
placeholder: @field.placeholder,
Expand Down
69 changes: 69 additions & 0 deletions app/javascript/js/controllers/fields/easy_mde_controller.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Controller } from '@hotwired/stimulus'
import EasyMDE from 'easymde'
import { DirectUpload } from '@rails/activestorage'

export default class extends Controller {
static targets = ['element']
Expand All @@ -17,6 +18,7 @@ export default class extends Controller {
}

connect() {

const options = {
element: this.elementTarget,
spellChecker: this.componentOptions.spell_checker,
Expand All @@ -28,9 +30,76 @@ export default class extends Controller {
options.status = false
}


if (this.componentOptions.image_upload) {
this.#configureImageUploads(options)
}

const easyMde = new EasyMDE(options)
if (this.view === 'show') {
easyMde.codemirror.options.readOnly = true
}
}

#configureImageUploads(options) {
options.uploadImage = true
options.imageUploadEndpoint = this.elementTarget.dataset.uploadUrl
options.imageUploadFunction = this.#handleImageUpload.bind(this)
options.imageAccept = 'image/*'
options.previewImagesInEditor = true
options.toolbar = this.toolbarItems
return options
}

#handleImageUpload(file, onSuccess, onError) {
const upload = new DirectUpload(file, this.elementTarget.dataset.uploadUrl)
upload.create((error, blob) => {
if (error) return onError(error)
const imageUrl = this.#encodedImageUrl(blob)
onSuccess(imageUrl)
})
}

#encodedImageUrl(blob) {
return `/rails/active_storage/blobs/redirect/${
blob.signed_id
}/${encodeURIComponent(blob.filename)}`
}

get toolbarItems() {
const baseItems = [
'bold',
'italic',
'heading',
'|',
'quote',
'unordered-list',
'ordered-list',
'|',
'link',
'image',
]

const uploadImageItem = this.componentOptions.image_upload
? [
{
name: 'upload-image',
action: EasyMDE.drawUploadedImage,
className: 'fa fa-file-picture-o',
title: 'Upload & insert image',
},
]
: []

return [
...baseItems,
...uploadImageItem,
'|',
'preview',
'side-by-side',
'fullscreen',
'|',
'guide',
]
}
}
12 changes: 11 additions & 1 deletion lib/avo/fields/easy_mde_field.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,23 @@ def initialize(id, **args, &block)

@always_show = args[:always_show].present? ? args[:always_show] : false
@height = args[:height].present? ? args[:height].to_s : "auto"
@upload_url = args[:upload_url].present? ? args[:upload_url] : direct_uploads_url
@image_upload = args[:image_upload].present? ? args[:image_upload] : false
@spell_checker = args[:spell_checker].present? ? args[:spell_checker] : false
@options = {
spell_checker: @spell_checker,
always_show: @always_show,
height: @height
height: @height,
image_upload: @image_upload,
upload_url: direct_uploads_url
}
end

private

def direct_uploads_url
"/rails/active_storage/direct_uploads"
end
end
end
end
2 changes: 1 addition & 1 deletion spec/dummy/app/avo/resources/project.rb
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ def fields
relative: true,
timezone: "EET",
format: "MMMM dd, y HH:mm:ss z"
field :description, as: :easy_mde, height: "350px"
field :description, as: :easy_mde, height: "350px", image_upload: true
field :files,
as: :files,
translation_key: "avo.field_translations.files",
Expand Down

0 comments on commit 2120913

Please sign in to comment.