1import { Platform } from 'expo-modules-core'; 2 3import { DocumentPickerAsset, DocumentPickerOptions, DocumentPickerResult } from './types'; 4 5export default { 6 get name(): string { 7 return 'ExpoDocumentPicker'; 8 }, 9 10 async getDocumentAsync({ 11 type = '*/*', 12 multiple = false, 13 }: DocumentPickerOptions): Promise<DocumentPickerResult> { 14 // SSR guard 15 if (!Platform.isDOMAvailable) { 16 return { canceled: true, assets: null }; 17 } 18 19 const input = document.createElement('input'); 20 input.style.display = 'none'; 21 input.setAttribute('type', 'file'); 22 input.setAttribute('accept', Array.isArray(type) ? type.join(',') : type); 23 input.setAttribute('id', String(Math.random())); 24 if (multiple) { 25 input.setAttribute('multiple', 'multiple'); 26 } 27 28 document.body.appendChild(input); 29 30 return new Promise((resolve, reject) => { 31 input.addEventListener('change', async () => { 32 if (input.files) { 33 const results: Promise<DocumentPickerAsset>[] = []; 34 for (let i = 0; i < input.files.length; i++) { 35 results.push(readFileAsync(input.files[i])); 36 } 37 try { 38 const assets = await Promise.all(results); 39 resolve({ canceled: false, assets, output: input.files }); 40 } catch (e) { 41 reject(e); 42 } 43 } else { 44 resolve({ canceled: true, assets: null }); 45 } 46 47 document.body.removeChild(input); 48 }); 49 50 const event = new MouseEvent('click'); 51 input.dispatchEvent(event); 52 }); 53 }, 54}; 55 56function readFileAsync(targetFile: File): Promise<DocumentPickerAsset> { 57 return new Promise((resolve, reject) => { 58 const mimeType = targetFile.type; 59 60 const reader = new FileReader(); 61 reader.onerror = () => { 62 reject(new Error(`Failed to read the selected media because the operation failed.`)); 63 }; 64 reader.onload = ({ target }) => { 65 const uri = (target as any).result; 66 resolve({ 67 uri, 68 mimeType, 69 name: targetFile.name, 70 lastModified: targetFile.lastModified, 71 size: targetFile.size, 72 file: targetFile, 73 }); 74 }; 75 76 // Read in the image file as a binary string. 77 reader.readAsDataURL(targetFile); 78 }); 79} 80