about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--package.json2
-rw-r--r--src/lib/media/picker.tsx49
-rw-r--r--src/state/models/media/gallery.ts10
-rw-r--r--src/state/models/media/image.ts2
-rw-r--r--src/view/com/modals/EditProfile.tsx4
-rw-r--r--src/view/com/util/UserAvatar.tsx22
-rw-r--r--src/view/com/util/UserBanner.tsx6
-rw-r--r--yarn.lock2
8 files changed, 51 insertions, 46 deletions
diff --git a/package.json b/package.json
index a3b0bc373..5c5f30574 100644
--- a/package.json
+++ b/package.json
@@ -75,7 +75,7 @@
     "expo-device": "~5.2.1",
     "expo-image": "^1.2.1",
     "expo-image-manipulator": "^11.1.1",
-    "expo-image-picker": "~14.1.1",
+    "expo-image-picker": "^14.1.1",
     "expo-localization": "~14.1.1",
     "expo-media-library": "~15.2.3",
     "expo-sharing": "~11.2.2",
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',
diff --git a/yarn.lock b/yarn.lock
index 9a2e64fe2..54006d89d 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -8731,7 +8731,7 @@ expo-image-manipulator@^11.1.1:
   dependencies:
     expo-image-loader "~4.1.0"
 
-expo-image-picker@~14.1.1:
+expo-image-picker@^14.1.1:
   version "14.1.1"
   resolved "https://registry.yarnpkg.com/expo-image-picker/-/expo-image-picker-14.1.1.tgz#181f1348ba6a43df7b87cee4a601d45c79b7c2d7"
   integrity sha512-SvWtnkLW7jp5Ntvk3lVcRQmhFYja8psmiR7O6P/+7S6f4llt3vaFwb4I3+pUXqJxxpi7BHc2+95qOLf0SFOIag==