diff options
author | Ollie H <renahlee@outlook.com> | 2023-05-16 15:38:32 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-05-16 17:38:32 -0500 |
commit | 5f66adc9a656b79b76986395a73def9eed3d9776 (patch) | |
tree | 5c42de343a9cbe06bf382784f82c4e6930bbbe77 /src | |
parent | d5bec4ff37fb3423b8f083dd9fe95c066b4cf90e (diff) | |
download | voidsky-5f66adc9a656b79b76986395a73def9eed3d9776.tar.zst |
Replace image picker with expo-image-picker (#649)
* Replace image picker with expo-image-picker * Fix cropper & picker on web --------- Co-authored-by: Paul Frazee <pfrazee@gmail.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/media/picker.tsx | 49 | ||||
-rw-r--r-- | src/state/models/media/gallery.ts | 10 | ||||
-rw-r--r-- | src/state/models/media/image.ts | 2 | ||||
-rw-r--r-- | src/view/com/modals/EditProfile.tsx | 4 | ||||
-rw-r--r-- | src/view/com/util/UserAvatar.tsx | 22 | ||||
-rw-r--r-- | src/view/com/util/UserBanner.tsx | 6 |
6 files changed, 49 insertions, 44 deletions
diff --git a/src/lib/media/picker.tsx b/src/lib/media/picker.tsx index af4a3e4d3..7c6dfcc44 100644 --- a/src/lib/media/picker.tsx +++ b/src/lib/media/picker.tsx @@ -1,12 +1,16 @@ import { - openPicker as openPickerFn, openCamera as openCameraFn, openCropper as openCropperFn, - ImageOrVideo, + Image as RNImage, } from 'react-native-image-crop-picker' import {RootStoreModel} from 'state/index' -import {PickerOpts, CameraOpts, CropperOptions} from './types' -import {Image as RNImage} from 'react-native-image-crop-picker' +import {CameraOpts, CropperOptions} from './types' +import { + ImagePickerOptions, + launchImageLibraryAsync, + MediaTypeOptions, +} from 'expo-image-picker' +import {getDataUriSize} from './util' /** * NOTE @@ -19,27 +23,22 @@ import {Image as RNImage} from 'react-native-image-crop-picker' export async function openPicker( _store: RootStoreModel, - opts?: PickerOpts, -): Promise<RNImage[]> { - const items = await openPickerFn({ - mediaType: 'photo', // TODO: eventually add other media types - multiple: opts?.multiple, - maxFiles: opts?.maxFiles, - forceJpg: true, // ios only - compressImageQuality: 0.8, + opts?: ImagePickerOptions, +) { + const response = await launchImageLibraryAsync({ + exif: false, + mediaTypes: MediaTypeOptions.Images, + quality: 1, + ...opts, }) - const toMedia = (item: ImageOrVideo) => ({ - path: item.path, - mime: item.mime, - size: item.size, - width: item.width, - height: item.height, - }) - if (Array.isArray(items)) { - return items.map(toMedia) - } - return [toMedia(items)] + 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( @@ -55,6 +54,7 @@ export async function openCamera( forceJpg: true, // ios only compressImageQuality: 0.8, }) + return { path: item.path, mime: item.mime, @@ -67,11 +67,10 @@ export async function openCamera( export async function openCropper( _store: RootStoreModel, opts: CropperOptions, -): Promise<RNImage> { +) { const item = await openCropperFn({ ...opts, forceJpg: true, // ios only - compressImageQuality: 0.8, }) return { diff --git a/src/state/models/media/gallery.ts b/src/state/models/media/gallery.ts index 89f0d0129..67f8d2ea1 100644 --- a/src/state/models/media/gallery.ts +++ b/src/state/models/media/gallery.ts @@ -102,10 +102,14 @@ export class GalleryModel { async pick() { const images = await openPicker(this.rootStore, { - multiple: true, - maxFiles: 4 - this.images.length, + selectionLimit: 4 - this.size, + allowsMultipleSelection: true, }) - await Promise.all(images.map(image => this.add(image))) + return await Promise.all( + images.map(image => { + this.add(image) + }), + ) } } diff --git a/src/state/models/media/image.ts b/src/state/models/media/image.ts index 6edf88d9d..ec93bf5b6 100644 --- a/src/state/models/media/image.ts +++ b/src/state/models/media/image.ts @@ -135,7 +135,7 @@ export class ImageModel implements RNImage { // Only for mobile async crop() { try { - const cropped = await openCropper(this.rootStore, { + const cropped = await openCropper({ mediaType: 'photo', path: this.path, freeStyleCropEnabled: true, diff --git a/src/view/com/modals/EditProfile.tsx b/src/view/com/modals/EditProfile.tsx index c26592fa9..f37a0f71a 100644 --- a/src/view/com/modals/EditProfile.tsx +++ b/src/view/com/modals/EditProfile.tsx @@ -65,7 +65,7 @@ export function Component({ } const onSelectNewAvatar = useCallback( async (img: RNImage | null) => { - if (!img) { + if (img === null) { setNewUserAvatar(null) setUserAvatar(null) return @@ -81,6 +81,7 @@ export function Component({ }, [track, setNewUserAvatar, setUserAvatar, setError], ) + const onSelectNewBanner = useCallback( async (img: RNImage | null) => { if (!img) { @@ -99,6 +100,7 @@ export function Component({ }, [track, setNewUserBanner, setUserBanner, setError], ) + const onPressSave = useCallback(async () => { track('EditProfile:Save') setProcessing(true) diff --git a/src/view/com/util/UserAvatar.tsx b/src/view/com/util/UserAvatar.tsx index a2e607e47..f3679326f 100644 --- a/src/view/com/util/UserAvatar.tsx +++ b/src/view/com/util/UserAvatar.tsx @@ -66,6 +66,7 @@ export function UserAvatar({ if (!(await requestCameraAccessIfNeeded())) { return } + onSelectNewAvatar?.( await openCamera(store, { width: 1000, @@ -83,20 +84,21 @@ export function UserAvatar({ if (!(await requestPhotoAccessIfNeeded())) { return } + const items = await openPicker(store, { + aspect: [1, 1], + }) + const item = items[0] + + const croppedImage = await openCropper(store, { mediaType: 'photo', - multiple: false, + cropperCircleOverlay: true, + height: item.height, + width: item.width, + path: item.path, }) - onSelectNewAvatar?.( - await openCropper(store, { - mediaType: 'photo', - path: items[0].path, - width: 1000, - height: 1000, - cropperCircleOverlay: true, - }), - ) + onSelectNewAvatar?.(croppedImage) }, }, { diff --git a/src/view/com/util/UserBanner.tsx b/src/view/com/util/UserBanner.tsx index 51cfbccbb..6e08be505 100644 --- a/src/view/com/util/UserBanner.tsx +++ b/src/view/com/util/UserBanner.tsx @@ -55,10 +55,8 @@ export function UserBanner({ if (!(await requestPhotoAccessIfNeeded())) { return } - const items = await openPicker(store, { - mediaType: 'photo', - multiple: false, - }) + const items = await openPicker(store) + onSelectNewBanner?.( await openCropper(store, { mediaType: 'photo', |