import { Controller } from "@hotwired/stimulus"
import { DirectUpload } from "@rails/activestorage"
// Connects to data-controller="upload"
export default class extends Controller {
static values = {
url: String,
createUrl: String,
parentId: Number,
target: String
}
connect() {
// console.info(this.urlValue)
// console.info('URL', this.createUrlValue)
}
// This will be triggered when a file is selected or dropped
upload(event) {
event.preventDefault()
const container = document.getElementById(this.targetValue)
const files = event.target.files || event.dataTransfer.files;
Array.from(files).forEach((file, index) => {
const uid = 'new_' + Date.now() + '_' + index
const target_div = document.createElement('div')
target_div.setAttribute('id', uid)
if (this.targetValue == 'attachments') {
target_div.classList.add('attachment', 'loading')
target_div.innerHTML = '0'
} else if (this.targetValue == 'tree-nodes') {
target_div.classList.add('row')
target_div.innerHTML = '
0
'
}
container.append(target_div)
new Uploader(this, file, uid).start()
});
}
// Drag over event handler
dragover(event) {
event.preventDefault();
this.element.classList.add('drag-over');
}
// Drag leave event handler
dragleave(event) {
event.preventDefault();
this.element.classList.remove('drag-over');
}
// Drop event handler
drop(event) {
event.preventDefault();
this.element.classList.remove('drag-over');
// Call the upload method and pass in the drop event
this.upload(event);
}
}
class Uploader {
constructor(source, file, uid) {
this.source = source
this.uid = uid
this.upload = new DirectUpload(file, source.urlValue, this)
}
start() {
this.upload.create((error, blob) => {
if (error) {
// Handle the error
} else {
const token = document.querySelector('meta[name="csrf-token"]').getAttribute('content')
const formData = new FormData()
if (this.source.parentIdValue > 0) {
formData.append('id', this.source.parentIdValue)
}
formData.append('signed_id', blob.signed_id)
formData.append('uid', this.uid)
fetch(this.source.createUrlValue, {
method: 'POST',
headers: {
'Accept': "text/vnd.turbo-stream.html",
'X-CSRF-Token': token
},
body: formData
})
.then (response => response.text())
.then(html => Turbo.renderStreamMessage(html))
.catch((err) => {
console.info('rejected', err)
})
}
})
}
directUploadWillStoreFileWithXHR(request) {
request.upload.addEventListener("progress",
event => this.directUploadDidProgress(event))
}
directUploadDidProgress(event) {
const target = document.getElementById(this.uid).querySelector('.progress')
const loaded = Math.round((event.loaded / event.total) * 100)
target.innerHTML = loaded
}
}