mirror of https://github.com/docusealco/docuseal
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.
143 lines
3.6 KiB
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')
|
|
}
|
|
})
|