UNPKG

expo-document-picker

Version:

Provides access to the system's UI for selecting documents from the available providers on the user's device.

92 lines (81 loc) 2.68 kB
import { Platform } from 'expo-modules-core'; import { DocumentPickerAsset, DocumentPickerOptions, DocumentPickerResult } from './types'; export default { async getDocumentAsync({ type = '*/*', multiple = false, base64 = false, }: DocumentPickerOptions): Promise<DocumentPickerResult> { // SSR guard if (!Platform.isDOMAvailable) { return { canceled: true, assets: null }; } const input = document.createElement('input'); input.style.display = 'none'; input.setAttribute('type', 'file'); input.setAttribute('accept', Array.isArray(type) ? type.join(',') : type); input.setAttribute('id', String(Math.random())); if (multiple) { input.setAttribute('multiple', 'multiple'); } document.body.appendChild(input); return new Promise((resolve, reject) => { input.addEventListener('change', async () => { if (input.files) { const results: Promise<DocumentPickerAsset>[] = []; for (let i = 0; i < input.files.length; i++) { results.push(readFileAsync(input.files[i], base64)); } try { const assets = await Promise.all(results); resolve({ canceled: false, assets, output: input.files }); } catch (e) { reject(e); } } else { resolve({ canceled: true, assets: null }); } document.body.removeChild(input); }); input.addEventListener('cancel', () => { resolve({ canceled: true, assets: null }); }); const event = new MouseEvent('click'); input.dispatchEvent(event); }); }, }; function readFileAsync(targetFile: File, base64: boolean = true): Promise<DocumentPickerAsset> { return new Promise((resolve, reject) => { const mimeType = targetFile.type; if (!base64) { resolve({ uri: URL.createObjectURL(targetFile), mimeType, name: targetFile.name, lastModified: targetFile.lastModified, size: targetFile.size, file: targetFile, }); return; } const reader = new FileReader(); reader.onerror = () => { reject(new Error(`Failed to read the selected media because the operation failed.`)); }; reader.onload = ({ target }) => { const base64 = (target as any).result; resolve({ uri: URL.createObjectURL(targetFile), base64, mimeType, name: targetFile.name, lastModified: targetFile.lastModified, size: targetFile.size, file: targetFile, }); }; // Read in the image file as a binary string. reader.readAsDataURL(targetFile); }); }