I am trying to get the tui-image editor to work with filepond in Ruby on Rails. I tried a few other editors, but the pricing wasn't acceptable to my wallet.
It seems I need to disable direct upload until the image has been edited, but I'm unable to figure out that step without completely disabling the process step.
It feels like there is only something minor that I am failing to realize.
Below is the code that I do have.
import * as ActiveStorage from "@rails/activestorage"
import { DirectUpload } from "@rails/activestorage"
import * as FilePond from "filepond"
import FilePondPluginFileValidateSize from "filepond-plugin-file-validate-size"
import FilePondPluginFileValidateType from "filepond-plugin-file-validate-type"
import FilePondPluginImageCrop from "filepond-plugin-image-crop"
import FilePondPluginImageEdit from "filepond-plugin-image-edit"
import FilePondPluginImageExifOrientation from "filepond-plugin-image-exif-orientation"
import FilePondPluginImagePreview from "filepond-plugin-image-preview"
import FilePondPluginImageResize from "filepond-plugin-image-resize"
import FilePondPluginImageTransform from "filepond-plugin-image-transform"
import ImageEditor from "tui-image-editor"
ActiveStorage.start()
FilePond.registerPlugin(
FilePondPluginFileValidateSize,
FilePondPluginFileValidateType,
FilePondPluginImagePreview,
FilePondPluginImageCrop,
FilePondPluginImageResize,
FilePondPluginImageTransform,
FilePondPluginImageExifOrientation,
FilePondPluginImageEdit,
)
function openImageEditor(file) {
// Create a temporary URL for the file
const editorElement = document.querySelector("#tui-image-editor")
console.log(editorElement)
const imageURL = window.URL.createObjectURL(file)
const imageEditor = new ImageEditor(
editorElement,
{
includeUI: {
loadImage: {
path: imageURL,
name: "event",
},
menu: ["shape", "crop"],
menuBarPosition: "bottom",
},
cssMaxWidth: 700,
cssMaxHeight: 500,
selectionStyle: {
cornerSize: 20,
rotatingPointOffset: 70,
},
},
)
}
function handleEditedImage(imageBlob) {
// Convert the Blob to a File object, if necessary
const editedFile = new File([imageBlob], "editedImage.png", { type: "image/png" });
// Manually add the edited file to FilePond
FilePond.addFile(editedFile);
// Now, you can manually trigger FilePond's upload process if it's not automatic
FilePond.processFile(editedFile);
}
const FilePondRails = {
allowReorder: true,
filePosterMaxHeight: 256,
directUploadUrl: null,
input: null,
default_options: {
onaddfile: (err, fileItem) => {
openImageEditor(fileItem.file)
},
allowFileSizeValidation: true,
maxFileSize: "10MB",
labelMaxFileSizeExceeded: "File is too large",
server: {
process: (
fieldName,
file,
metadata,
load,
error,
progress,
abort,
transfer,
options,
) => {
const uploader = new DirectUpload(file, FilePondRails.directUploadUrl, {
directUploadWillStoreFileWithXHR: (request) => {
request.upload.addEventListener("progress", (event) =>
progress(event.lengthComputable, event.loaded, event.total),
)
},
})
uploader.create((errorResponse, blob) => {
if (errorResponse) {
error(`Something went wrong: ${errorResponse}`)
} else {
const hiddenField = document.createElement("input")
hiddenField.setAttribute("type", "hidden")
hiddenField.setAttribute("value", blob.signed_id)
hiddenField.name = FilePondRails.input.name
document.querySelector("form").appendChild(hiddenField)
load(blob.signed_id)
}
})
return {
abort: () => abort(),
}
},
fetch: {
url: "/filepond/active_storage/fetch",
method: "POST",
onload: (response) => {
return response
},
ondata: (response) => {
return response
},
},
revert: {
url: "/filepond/active_storage/remove",
},
headers: {
"X-CSRF-Token": document.head.querySelector("[name='csrf-token']")
.content,
},
},
},
// Convenience method to initialize FilePond based on the way this gem expects things to work
create: (input) => {
FilePondRails.directUploadUrl = input.dataset.directUploadUrl
FilePondRails.input = input
// Initialize FilePond on our element
return FilePond.create(input, FilePondRails.default_options)
},
}
document.addEventListener("turbo:load", () => {
if (document.querySelector(".filepond")) {
FilePondRails.create(document.querySelector(".filepond"))
}
if (document.getElementById("image_preview")) {
document.getElementById("image_preview").submit()
}
})
window.FilePond = FilePond
window.FilePondRails = FilePondRails