83 lines
2.2 KiB
TypeScript
83 lines
2.2 KiB
TypeScript
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
|