diff --git a/lib/image-picker/index.js b/lib/image-picker/index.js index 9a4c901..a166c86 100644 --- a/lib/image-picker/index.js +++ b/lib/image-picker/index.js @@ -1,4 +1,5 @@ { + let FormData = window.FormData class ImagePicker { constructor(options) { let defaultOptions = { @@ -31,45 +32,80 @@ let fileInput = (this.domRefs.fileInput = dom.create('')) dom.append(element, fileInput) } + willUpload(formData) { + this.options.element.classList.add('uploading') + this.domRefs.fileInput.disabled = true + } + didUpload(formData) { + let { element } = this.options + element.classList.remove('uploading') + this.domRefs.fileInput.disabled = false + this.domRefs.fileInput.value = '' + dom.dispatchEvent(element, 'uploaded') + } + failedUpload(formData) { + this.domRefs.fileInput.disabled = false + this.domRefs.fileInput.value = '' + dom.dispatchEvent(element, 'uploadFailed') + } + willDownload(path) { + this.options.element.classList.add('downloading') + } + didDownload(path) { + this.domRefs.img.src = path + let { element } = this.options + element.classList.remove('downloading') + dom.dispatchEvent(element, 'uploadedImageLoaded') + } + failedDownload(path) { + let { element, fallbackImage } = this.options + element.classList.remove('downloading') + if (fallbackImage) { + this.domRefs.img.src = fallbackImage + } + dom.dispatchEvent(element, 'uploadedImageFailed') + } + upload(formData) { + let { element, upload, parseResponse } = this.options + http(upload.method, upload.url, formData).then( + responseBody => { + let path = parseResponse(responseBody) + this.didUpload(formData) + this.willDownload(path) + prefetch(path).then( + () => { + this.didDownload(path) + }, + () => { + this.failedDownload() + } + ) + }, + () => this.failedUpload(formData) + ) + } bindEvents() { - let { element, upload, parseResponse, fallbackImage } = this.options this.domRefs.fileInput.addEventListener('change', e => { - let f = e.target.files[0] - let formData = new window.FormData() - formData.append(upload.inputName, f) - - element.classList.add('uploading') - http(upload.method, upload.url, formData).then( - responseBody => { - element.classList.remove('uploading') - let path = parseResponse(responseBody) - let img = new Image() - img.onload = () => { - element.classList.remove('downloading') - this.domRefs.img.src = path - dom.dispatchEvent(element, 'uploadedImageLoaded') - } - img.onerror = () => { - element.classList.remove('downloading') - if (fallbackImage) { - this.domRefs.img.src = fallbackImage - } - dom.dispatchEvent(element, 'uploadedImageFailed') - } - element.classList.add('downloading') - img.src = path - dom.dispatchEvent(element, 'uploaded') - }, - () => { - dom.dispatchEvent(element, 'uploadFailed') - } - ) + let { upload } = this.options + let formData = new FormData() + formData.append(upload.inputName, e.target.files[0]) + this.willUpload(formData) + this.upload(formData) }) } } window.ImagePicker = ImagePicker + function prefetch(url) { + return new Promise((resolve, reject) => { + let img = new Image() + img.onload = resolve + img.onerror = reject + img.src = url + }) + } + function http(method, url, data) { return new Promise((resolve, reject) => { let xhr = new XMLHttpRequest()