import React from 'react'; import { Text } from 'react-native'; import { launchImageLibraryAsync, launchCameraAsync, useCameraPermissions, useMediaLibraryPermissions, } from 'expo-image-picker'; import TouchableOpacity from '../TouchableOpacity'; import type { ImagePickerProps, PickerImageInfo } from './types'; import { useThemeFactory } from '../Theme'; import { createUploaderStyles } from './style'; import { Dialog } from '../Dialog'; export type UploaderProps = Pick< ImagePickerProps, | 'uploadIcon' | 'disabled' | 'readOnly' | 'previewSize' | 'uploadText' | 'capture' | 'multiple' | 'maxSize' | 'beforeUpload' | 'onOversize' > & { upload: (files: PickerImageInfo[]) => void; }; const Uploader = (props: UploaderProps): JSX.Element => { const { previewSize, uploadText, capture, multiple = false, disabled, maxSize, onOversize, beforeUpload, upload, } = props; const { styles, theme } = useThemeFactory(createUploaderStyles); const [cameraStatus, requestCameraPermission] = useCameraPermissions(); const [mediaLibraryStatus, requestmediaLibraryPermission] = useMediaLibraryPermissions(); // const fetchImageFromUri = async (uri: string) => { // const response = await fetch(uri); // const blob = await response.blob(); // return blob; // }; // 获取权限 const getPermissions = async (): Promise => { if (capture) { if (cameraStatus?.status === 'granted') { return true; } return requestCameraPermission().then(({ status }) => status === 'granted'); } if (mediaLibraryStatus?.status === 'granted') { return true; } return requestmediaLibraryPermission().then(({ status }) => status === 'granted'); }; const handlePicker = async () => { if (disabled) return; const hasPermission = await getPermissions(); if (hasPermission) { const pickerResult = await (capture ? launchCameraAsync({ allowsMultipleSelection: multiple }) : launchImageLibraryAsync({ allowsMultipleSelection: multiple })); if (pickerResult.cancelled) return; let pickerFiles: PickerImageInfo[] = (pickerResult as any)?.selected ?? [pickerResult]; // 根据图片大小筛选图片 if (maxSize) { const exceedFiles = pickerFiles.filter(it => it.fileSize && it.fileSize > maxSize); if (exceedFiles.length > 0) { onOversize?.(exceedFiles); return; } } // 上传前回调 if (beforeUpload) { await Promise.all(pickerFiles.map(file => beforeUpload(file, pickerFiles))).then( filesList => { pickerFiles = filesList.filter(Boolean) as PickerImageInfo[]; } ); } upload(pickerFiles); } else { Dialog.alert({ message: 'Sorry, we need these permissions to make this work!' }); } }; const renderUploadIcon = () => { if (props.uploadIcon) { return React.cloneElement(props.uploadIcon as React.ReactElement, { color: theme.image_picker_icon_color, size: theme.image_picker_icon_size, }); } return null; }; return ( {renderUploadIcon()} {uploadText && {uploadText}} ); }; export default Uploader;