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)
|
|
target_div.classList.add('asset', 'loading')
|
|
target_div.innerHTML = '<span class="progress">0</span>'
|
|
|
|
// if (this.targetValue == 'attachments') {
|
|
// target_div.classList.add('attachment', 'loading')
|
|
// target_div.innerHTML = '<span class="progress">0</span>'
|
|
// } else if (this.targetValue == 'tree-nodes') {
|
|
// target_div.classList.add('row')
|
|
// target_div.innerHTML = '<div class="cell"><span class="node-link progress" data-icon="description">0</span></div>'
|
|
// }
|
|
container.prepend(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
|
|
}
|
|
}
|