feat: add image picker utility and integrate image upload in DynamicForm component
This commit is contained in:
82
lib/imgPicker.ts
Normal file
82
lib/imgPicker.ts
Normal file
@@ -0,0 +1,82 @@
|
||||
import * as ImagePicker from 'expo-image-picker'
|
||||
import Toast from '@/components/ui/Toast'
|
||||
|
||||
// 定义图片选择器参数类型
|
||||
type PickerBaseParams = Omit<
|
||||
ImagePicker.ImagePickerOptions,
|
||||
'mediaTypes' | 'allowsMultipleSelection' | 'selectionLimit'
|
||||
> & {
|
||||
/** 最大选择图片数量,默认 1 */
|
||||
maxImages?: number
|
||||
/** 媒体类型,默认仅图片 */
|
||||
type?: ImagePicker.MediaTypeOptions
|
||||
}
|
||||
|
||||
type PickerUriParams = PickerBaseParams & {
|
||||
/** 返回类型:uri 返回字符串数组 */
|
||||
resultType?: 'uri'
|
||||
}
|
||||
|
||||
type PickerAssetParams = PickerBaseParams & {
|
||||
/** 返回类型:asset 返回完整资源对象 */
|
||||
resultType: 'asset'
|
||||
}
|
||||
|
||||
/**
|
||||
* 图片选择器工具
|
||||
* 直接打开系统相册选择图片
|
||||
*
|
||||
* @example
|
||||
* // 选择单张图片,返回 URI
|
||||
* const [uri] = await imgPicker({ maxImages: 1 })
|
||||
*
|
||||
* // 选择多张图片,返回 URI 数组
|
||||
* const uris = await imgPicker({ maxImages: 9 })
|
||||
*
|
||||
* // 返回完整资源对象(包含宽高等信息)
|
||||
* const assets = await imgPicker({ maxImages: 1, resultType: 'asset' })
|
||||
*/
|
||||
export async function imgPicker(params: PickerUriParams): Promise<string[]>
|
||||
export async function imgPicker(params: PickerAssetParams): Promise<ImagePicker.ImagePickerAsset[]>
|
||||
export async function imgPicker(
|
||||
params: PickerUriParams | PickerAssetParams
|
||||
): Promise<string[] | ImagePicker.ImagePickerAsset[]> {
|
||||
const {
|
||||
maxImages = 1,
|
||||
type = ImagePicker.MediaTypeOptions.Images,
|
||||
resultType = 'uri',
|
||||
...rest
|
||||
} = params
|
||||
|
||||
const isMultiple = maxImages > 1
|
||||
|
||||
// 请求相册权限
|
||||
const { status } = await ImagePicker.requestMediaLibraryPermissionsAsync()
|
||||
if (status !== 'granted') {
|
||||
Toast.show('请开启相册权限')
|
||||
throw new Error('请开启相册权限')
|
||||
}
|
||||
|
||||
// 打开相册选择图片
|
||||
const result = await ImagePicker.launchImageLibraryAsync({
|
||||
mediaTypes: type,
|
||||
quality: 0.9,
|
||||
allowsMultipleSelection: isMultiple,
|
||||
selectionLimit: maxImages,
|
||||
...rest,
|
||||
})
|
||||
|
||||
// 用户取消选择
|
||||
if (result.canceled || !result.assets?.length) {
|
||||
throw new Error('未选择任何图片')
|
||||
}
|
||||
|
||||
// 根据 resultType 返回不同格式
|
||||
if (resultType === 'uri') {
|
||||
return result.assets.map((asset) => asset.uri)
|
||||
}
|
||||
|
||||
return result.assets
|
||||
}
|
||||
|
||||
export default imgPicker
|
||||
Reference in New Issue
Block a user