You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
docuseal/app/javascript/photo.js

143 lines
3.6 KiB

window.customElements.define('file-photo', class extends HTMLElement {
connectedCallback () {
this.clearButton.addEventListener('click', (e) => {
e.preventDefault()
this.valueInput.value = null
this.inputFile.click()
})
this.inputFile.addEventListener('change', (e) => {
e.preventDefault()
this.updateSubmitButtonVisibility()
this.uploadFiles(this.inputFile.files)
})
this.form.addEventListener('submit', (e) => {
e.preventDefault();
this.submitButton.disabled = true
fetch(this.form.action, {
method: 'PUT',
body: new FormData(this.form)
}).then((response) => {
this.form.classList.add('hidden')
this.success.classList.remove('hidden')
return response
}).finally(() => {
this.submitButton.disabled = false
})
})
}
toggleLoading = (e) => {
this.updateSubmitButtonVisibility()
if (e && e.target && !e.target.contains(this)) {
return
}
this.loading.classList.toggle('hidden')
this.icon.classList.toggle('hidden')
this.classList.toggle('opacity-50')
}
async uploadFiles (files) {
this.toggleLoading()
return await Promise.all(
Array.from(files).map(async (file) => {
const formData = new FormData()
if (file.type === 'image/bmp') {
file = await this.convertBmpToPng(file)
}
formData.append('file', file)
formData.append('submitter_slug', this.dataset.slug)
formData.append('name', 'attachments')
return fetch('/api/attachments', {
method: 'POST',
body: formData
}).then(resp => resp.json()).then((data) => {
return data
})
})).then((result) => {
this.valueInput.value = result[0].uuid
return result[0]
}).finally(() => {
this.toggleLoading()
})
}
convertBmpToPng (bmpFile) {
return new Promise((resolve, reject) => {
const reader = new FileReader()
reader.onload = function (event) {
const img = new Image()
img.onload = function () {
const canvas = document.createElement('canvas')
const ctx = canvas.getContext('2d')
canvas.width = img.width
canvas.height = img.height
ctx.drawImage(img, 0, 0)
canvas.toBlob(function (blob) {
const newFile = new File([blob], bmpFile.name.replace(/\.\w+$/, '.png'), { type: 'image/png' })
resolve(newFile)
}, 'image/png')
}
img.src = event.target.result
}
reader.onerror = reject
reader.readAsDataURL(bmpFile)
})
}
updateSubmitButtonVisibility () {
if (!this.valueInput.value) {
this.submitButton.style.display = 'none'
this.placeholderButton.style.display = 'block'
} else {
this.submitButton.style.display = 'block'
this.placeholderButton.style.display = 'none'
}
}
get submitButton () {
return this.querySelector('button[type="submit"]')
}
get clearButton () {
return this.querySelector('button[aria-label="Clear"]')
}
get placeholderButton () {
return this.querySelector('button[disabled]')
}
get valueInput () {
return this.querySelector('input[name^="values"]')
}
get inputFile () {
return this.querySelector('input[id="file"]')
}
get icon () {
return this.querySelector('#file-photo-icon')
}
get loading () {
return this.querySelector('#file-photo-loading')
}
get form () {
return this.querySelector('form')
}
get success () {
return this.querySelector('#success')
}
})