Last active
September 29, 2018 17:34
-
-
Save jagomf/d7c90ebe206618228818ab9211750bc7 to your computer and use it in GitHub Desktop.
Retrieve a file and convert to base64 upon clicking on something
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Prompts to choose a file from filesystem, converts to base64 (in background), and returns base64 when conversion ends. | |
* @param {number} maxFileSize Maximum size of file. | |
* @param {boolean} multiple Indicates whether to accept one or more files. | |
* @param {string} contentType MIME type of media to require from filesystem (can be 'image/*', etc). | |
* @param {string} source (For mobile devices only) If set to 'camera', tells device to capture image from camera. | |
* @returns {Promise} A Promise that resolves when files are read; rejects with error text if files are heavier than allowed. | |
*/ | |
onClickSendMedia(maxFileSize, multiple = false, contentType = '*/*', source) { | |
return new Promise((resolve, reject) => { | |
// Create temporary input element | |
const element = document.createElement('input'); | |
// Assign properties to element. | |
element.removed = false; | |
element.type = 'file'; | |
element.id = 'addAttach'; | |
element.multiple = multiple; | |
element.accept = contentType; | |
if (source) { // Needed for file fetch to work on iOS | |
element.capture = source; | |
} | |
// Hide element | |
element.style.display = 'none'; | |
// Register what happens when element content has changed | |
element.addEventListener('change', ({ target }) => { | |
const filesObj = Array.from(target.files); | |
const allFilesFit = filesObj.every(file => file.size <= maxFileSize); | |
if (!allFilesFit) { | |
reject(`Files cannot be bigger than ${maxFileSize / (1024 * 1024)}MB.`); | |
} | |
const processes = filesObj.map(fileObj => new Promise(resolveInner => { | |
const webworkerReader = new FileReader(); | |
webworkerReader.onload = () => { | |
const base64Str = webworkerReader.result; | |
resolveInner(base64Str); | |
}; | |
webworkerReader.readAsDataURL(fileObj); | |
})); | |
Promise.all(processes).then(values => { | |
resolve(values); | |
}); | |
// Once file content is retrieved, destroy temporary input element | |
element.onblur = null; | |
if (!element.removed) { | |
element.removed = true; | |
element.remove(); | |
} | |
}); | |
// Append element to DOM. | |
document.querySelector('body').appendChild(element); | |
// Force click | |
element.click(); | |
}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment