Use expo-image-picker on Web (#847)
parent
a67eaa6ace
commit
bdcdb4e4dc
|
@ -0,0 +1,23 @@
|
|||
import {
|
||||
ImagePickerOptions,
|
||||
launchImageLibraryAsync,
|
||||
MediaTypeOptions,
|
||||
} from 'expo-image-picker'
|
||||
import {getDataUriSize} from './util'
|
||||
|
||||
export async function openPicker(opts?: ImagePickerOptions) {
|
||||
const response = await launchImageLibraryAsync({
|
||||
exif: false,
|
||||
mediaTypes: MediaTypeOptions.Images,
|
||||
quality: 1,
|
||||
...opts,
|
||||
})
|
||||
|
||||
return (response.assets ?? []).map(image => ({
|
||||
mime: 'image/jpeg',
|
||||
height: image.height,
|
||||
width: image.width,
|
||||
path: image.uri,
|
||||
size: getDataUriSize(image.uri),
|
||||
}))
|
||||
}
|
|
@ -5,12 +5,7 @@ import {
|
|||
} from 'react-native-image-crop-picker'
|
||||
import {RootStoreModel} from 'state/index'
|
||||
import {CameraOpts, CropperOptions} from './types'
|
||||
import {
|
||||
ImagePickerOptions,
|
||||
launchImageLibraryAsync,
|
||||
MediaTypeOptions,
|
||||
} from 'expo-image-picker'
|
||||
import {getDataUriSize} from './util'
|
||||
export {openPicker} from './picker.shared'
|
||||
|
||||
/**
|
||||
* NOTE
|
||||
|
@ -21,26 +16,6 @@ import {getDataUriSize} from './util'
|
|||
* -prf
|
||||
*/
|
||||
|
||||
export async function openPicker(
|
||||
_store: RootStoreModel,
|
||||
opts?: ImagePickerOptions,
|
||||
) {
|
||||
const response = await launchImageLibraryAsync({
|
||||
exif: false,
|
||||
mediaTypes: MediaTypeOptions.Images,
|
||||
quality: 1,
|
||||
...opts,
|
||||
})
|
||||
|
||||
return (response.assets ?? []).map(image => ({
|
||||
mime: 'image/jpeg',
|
||||
height: image.height,
|
||||
width: image.width,
|
||||
path: image.uri,
|
||||
size: getDataUriSize(image.uri),
|
||||
}))
|
||||
}
|
||||
|
||||
export async function openCamera(
|
||||
_store: RootStoreModel,
|
||||
opts: CameraOpts,
|
||||
|
|
|
@ -1,34 +1,9 @@
|
|||
/// <reference lib="dom" />
|
||||
|
||||
import {PickerOpts, CameraOpts, CropperOptions} from './types'
|
||||
import {CameraOpts, CropperOptions} from './types'
|
||||
import {RootStoreModel} from 'state/index'
|
||||
import {getImageDim} from 'lib/media/manip'
|
||||
import {extractDataUriMime} from './util'
|
||||
import {Image as RNImage} from 'react-native-image-crop-picker'
|
||||
|
||||
interface PickedFile {
|
||||
uri: string
|
||||
path: string
|
||||
size: number
|
||||
}
|
||||
|
||||
export async function openPicker(
|
||||
_store: RootStoreModel,
|
||||
opts?: PickerOpts,
|
||||
): Promise<RNImage[]> {
|
||||
const res = await selectFile(opts)
|
||||
const dim = await getImageDim(res.uri)
|
||||
const mime = extractDataUriMime(res.uri)
|
||||
return [
|
||||
{
|
||||
path: res.uri,
|
||||
mime,
|
||||
size: res.size,
|
||||
width: dim.width,
|
||||
height: dim.height,
|
||||
},
|
||||
]
|
||||
}
|
||||
export {openPicker} from './picker.shared'
|
||||
|
||||
export async function openCamera(
|
||||
_store: RootStoreModel,
|
||||
|
@ -57,44 +32,3 @@ export async function openCropper(
|
|||
})
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens the select file dialog in the browser.
|
||||
* NOTE:
|
||||
* If in the future someone updates this method to use:
|
||||
* https://developer.mozilla.org/en-US/docs/Web/API/window/showOpenFilePicker
|
||||
* Check that the `showOpenFilePicker` API does not require any permissions
|
||||
* granted to use. As of this writing, it does not, but that could change
|
||||
* in the future. If the user does need to go through a permissions granting
|
||||
* flow, then checkout the usePhotoLibraryPermission() hook in
|
||||
* src/lib/hooks/usePermissions.ts
|
||||
* so that it gets appropriately updated.
|
||||
*/
|
||||
function selectFile(opts?: PickerOpts): Promise<PickedFile> {
|
||||
return new Promise((resolve, reject) => {
|
||||
var input = document.createElement('input')
|
||||
input.type = 'file'
|
||||
input.accept = opts?.mediaType === 'photo' ? 'image/*' : '*/*'
|
||||
input.onchange = e => {
|
||||
const target = e.target as HTMLInputElement
|
||||
const file = target?.files?.[0]
|
||||
if (!file) {
|
||||
return reject(new Error('Canceled'))
|
||||
}
|
||||
|
||||
var reader = new FileReader()
|
||||
reader.readAsDataURL(file)
|
||||
reader.onload = readerEvent => {
|
||||
if (!readerEvent.target) {
|
||||
return reject(new Error('Canceled'))
|
||||
}
|
||||
resolve({
|
||||
uri: readerEvent.target.result as string,
|
||||
path: file.name,
|
||||
size: file.size,
|
||||
})
|
||||
}
|
||||
}
|
||||
input.click()
|
||||
})
|
||||
}
|
||||
|
|
|
@ -87,7 +87,7 @@ export class GalleryModel {
|
|||
}
|
||||
|
||||
async pick() {
|
||||
const images = await openPicker(this.rootStore, {
|
||||
const images = await openPicker({
|
||||
selectionLimit: 4 - this.size,
|
||||
allowsMultipleSelection: true,
|
||||
})
|
||||
|
|
|
@ -147,7 +147,7 @@ export function UserAvatar({
|
|||
return
|
||||
}
|
||||
|
||||
const items = await openPicker(store, {
|
||||
const items = await openPicker({
|
||||
aspect: [1, 1],
|
||||
})
|
||||
const item = items[0]
|
||||
|
|
|
@ -55,7 +55,7 @@ export function UserBanner({
|
|||
if (!(await requestPhotoAccessIfNeeded())) {
|
||||
return
|
||||
}
|
||||
const items = await openPicker(store)
|
||||
const items = await openPicker()
|
||||
|
||||
onSelectNewBanner?.(
|
||||
await openCropper(store, {
|
||||
|
|
Loading…
Reference in New Issue