dawarich/app/javascript/controllers/direct_upload_controller.js
2025-05-03 20:36:09 +02:00

56 lines
1.8 KiB
JavaScript

import { Controller } from "@hotwired/stimulus"
import { DirectUpload } from "@rails/activestorage"
export default class extends Controller {
static targets = ["input", "progress", "submit"]
static values = {
url: String
}
connect() {
this.inputTarget.addEventListener("change", this.upload.bind(this))
}
upload() {
const files = this.inputTarget.files
if (files.length === 0) return
// Disable submit button during upload
this.submitTarget.disabled = true
// Create progress bar if it doesn't exist
if (!this.hasProgressTarget) {
const progressBar = document.createElement("div")
progressBar.setAttribute("data-direct-upload-target", "progress")
progressBar.className = "w-full bg-gray-200 rounded-full h-2.5 mt-2"
this.inputTarget.parentNode.appendChild(progressBar)
}
Array.from(files).forEach(file => {
const upload = new DirectUpload(file, this.urlValue, this)
upload.create((error, blob) => {
if (error) {
console.error("Error uploading file:", error)
} else {
const hiddenField = document.createElement("input")
hiddenField.setAttribute("type", "hidden")
hiddenField.setAttribute("name", this.inputTarget.name)
hiddenField.setAttribute("value", blob.signed_id)
this.element.appendChild(hiddenField)
}
})
})
}
directUploadWillStoreFileWithXHR(request) {
request.upload.addEventListener("progress", event => {
const progress = (event.loaded / event.total) * 100
this.progressTarget.style.width = `${progress}%`
})
}
directUploadDidProgress(event) {
// This method is called by ActiveStorage during the upload
// We're handling progress in directUploadWillStoreFileWithXHR instead
}
}