mirror of
				https://github.com/tooot-app/app
				synced 2025-06-05 22:19:13 +02:00 
			
		
		
		
	Using proper image transformation
This commit is contained in:
		| @@ -4,6 +4,8 @@ PODS: | |||||||
|   - DoubleConversion (1.1.6) |   - DoubleConversion (1.1.6) | ||||||
|   - EASClient (0.2.1): |   - EASClient (0.2.1): | ||||||
|     - ExpoModulesCore |     - ExpoModulesCore | ||||||
|  |   - EXApplication (4.1.0): | ||||||
|  |     - ExpoModulesCore | ||||||
|   - EXAV (11.2.3): |   - EXAV (11.2.3): | ||||||
|     - ExpoModulesCore |     - ExpoModulesCore | ||||||
|     - React-runtimeexecutor |     - React-runtimeexecutor | ||||||
| @@ -23,6 +25,8 @@ PODS: | |||||||
|   - EXFirebaseCore (5.0.0): |   - EXFirebaseCore (5.0.0): | ||||||
|     - ExpoModulesCore |     - ExpoModulesCore | ||||||
|     - Firebase/Core (= 8.14.0) |     - Firebase/Core (= 8.14.0) | ||||||
|  |   - EXFont (10.1.0): | ||||||
|  |     - ExpoModulesCore | ||||||
|   - EXImageLoader (3.2.0): |   - EXImageLoader (3.2.0): | ||||||
|     - ExpoModulesCore |     - ExpoModulesCore | ||||||
|     - React-Core |     - React-Core | ||||||
| @@ -37,8 +41,13 @@ PODS: | |||||||
|     - ExpoModulesCore |     - ExpoModulesCore | ||||||
|   - ExpoHaptics (11.2.0): |   - ExpoHaptics (11.2.0): | ||||||
|     - ExpoModulesCore |     - ExpoModulesCore | ||||||
|  |   - ExpoImageManipulator (10.3.1): | ||||||
|  |     - EXImageLoader | ||||||
|  |     - ExpoModulesCore | ||||||
|   - ExpoImagePicker (13.1.1): |   - ExpoImagePicker (13.1.1): | ||||||
|     - ExpoModulesCore |     - ExpoModulesCore | ||||||
|  |   - ExpoKeepAwake (10.1.1): | ||||||
|  |     - ExpoModulesCore | ||||||
|   - ExpoLocalization (13.0.0): |   - ExpoLocalization (13.0.0): | ||||||
|     - ExpoModulesCore |     - ExpoModulesCore | ||||||
|   - ExpoModulesCore (0.9.2): |   - ExpoModulesCore (0.9.2): | ||||||
| @@ -590,6 +599,7 @@ DEPENDENCIES: | |||||||
|   - boost (from `../node_modules/react-native/third-party-podspecs/boost.podspec`) |   - boost (from `../node_modules/react-native/third-party-podspecs/boost.podspec`) | ||||||
|   - DoubleConversion (from `../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`) |   - DoubleConversion (from `../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`) | ||||||
|   - EASClient (from `../node_modules/expo-eas-client/ios`) |   - EASClient (from `../node_modules/expo-eas-client/ios`) | ||||||
|  |   - EXApplication (from `../node_modules/expo-application/ios`) | ||||||
|   - EXAV (from `../node_modules/expo-av/ios`) |   - EXAV (from `../node_modules/expo-av/ios`) | ||||||
|   - EXConstants (from `../node_modules/expo-constants/ios`) |   - EXConstants (from `../node_modules/expo-constants/ios`) | ||||||
|   - EXDevice (from `../node_modules/expo-device/ios`) |   - EXDevice (from `../node_modules/expo-device/ios`) | ||||||
| @@ -597,6 +607,7 @@ DEPENDENCIES: | |||||||
|   - EXFileSystem (from `../node_modules/expo-file-system/ios`) |   - EXFileSystem (from `../node_modules/expo-file-system/ios`) | ||||||
|   - EXFirebaseAnalytics (from `../node_modules/expo-firebase-analytics/ios`) |   - EXFirebaseAnalytics (from `../node_modules/expo-firebase-analytics/ios`) | ||||||
|   - EXFirebaseCore (from `../node_modules/expo-firebase-core/ios`) |   - EXFirebaseCore (from `../node_modules/expo-firebase-core/ios`) | ||||||
|  |   - EXFont (from `../node_modules/expo-font/ios`) | ||||||
|   - EXImageLoader (from `../node_modules/expo-image-loader/ios`) |   - EXImageLoader (from `../node_modules/expo-image-loader/ios`) | ||||||
|   - EXJSONUtils (from `../node_modules/expo-json-utils/ios`) |   - EXJSONUtils (from `../node_modules/expo-json-utils/ios`) | ||||||
|   - EXManifests (from `../node_modules/expo-manifests/ios`) |   - EXManifests (from `../node_modules/expo-manifests/ios`) | ||||||
| @@ -604,7 +615,9 @@ DEPENDENCIES: | |||||||
|   - Expo (from `../node_modules/expo/ios`) |   - Expo (from `../node_modules/expo/ios`) | ||||||
|   - ExpoCrypto (from `../node_modules/expo-crypto/ios`) |   - ExpoCrypto (from `../node_modules/expo-crypto/ios`) | ||||||
|   - ExpoHaptics (from `../node_modules/expo-haptics/ios`) |   - ExpoHaptics (from `../node_modules/expo-haptics/ios`) | ||||||
|  |   - ExpoImageManipulator (from `../node_modules/expo-image-manipulator/ios`) | ||||||
|   - ExpoImagePicker (from `../node_modules/expo-image-picker/ios`) |   - ExpoImagePicker (from `../node_modules/expo-image-picker/ios`) | ||||||
|  |   - ExpoKeepAwake (from `../node_modules/expo-keep-awake/ios`) | ||||||
|   - ExpoLocalization (from `../node_modules/expo-localization/ios`) |   - ExpoLocalization (from `../node_modules/expo-localization/ios`) | ||||||
|   - ExpoModulesCore (from `../node_modules/expo-modules-core/ios`) |   - ExpoModulesCore (from `../node_modules/expo-modules-core/ios`) | ||||||
|   - ExpoRandom (from `../node_modules/expo-random/ios`) |   - ExpoRandom (from `../node_modules/expo-random/ios`) | ||||||
| @@ -701,6 +714,8 @@ EXTERNAL SOURCES: | |||||||
|     :podspec: "../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec" |     :podspec: "../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec" | ||||||
|   EASClient: |   EASClient: | ||||||
|     :path: "../node_modules/expo-eas-client/ios" |     :path: "../node_modules/expo-eas-client/ios" | ||||||
|  |   EXApplication: | ||||||
|  |     :path: "../node_modules/expo-application/ios" | ||||||
|   EXAV: |   EXAV: | ||||||
|     :path: "../node_modules/expo-av/ios" |     :path: "../node_modules/expo-av/ios" | ||||||
|   EXConstants: |   EXConstants: | ||||||
| @@ -715,6 +730,8 @@ EXTERNAL SOURCES: | |||||||
|     :path: "../node_modules/expo-firebase-analytics/ios" |     :path: "../node_modules/expo-firebase-analytics/ios" | ||||||
|   EXFirebaseCore: |   EXFirebaseCore: | ||||||
|     :path: "../node_modules/expo-firebase-core/ios" |     :path: "../node_modules/expo-firebase-core/ios" | ||||||
|  |   EXFont: | ||||||
|  |     :path: "../node_modules/expo-font/ios" | ||||||
|   EXImageLoader: |   EXImageLoader: | ||||||
|     :path: "../node_modules/expo-image-loader/ios" |     :path: "../node_modules/expo-image-loader/ios" | ||||||
|   EXJSONUtils: |   EXJSONUtils: | ||||||
| @@ -729,8 +746,12 @@ EXTERNAL SOURCES: | |||||||
|     :path: "../node_modules/expo-crypto/ios" |     :path: "../node_modules/expo-crypto/ios" | ||||||
|   ExpoHaptics: |   ExpoHaptics: | ||||||
|     :path: "../node_modules/expo-haptics/ios" |     :path: "../node_modules/expo-haptics/ios" | ||||||
|  |   ExpoImageManipulator: | ||||||
|  |     :path: "../node_modules/expo-image-manipulator/ios" | ||||||
|   ExpoImagePicker: |   ExpoImagePicker: | ||||||
|     :path: "../node_modules/expo-image-picker/ios" |     :path: "../node_modules/expo-image-picker/ios" | ||||||
|  |   ExpoKeepAwake: | ||||||
|  |     :path: "../node_modules/expo-keep-awake/ios" | ||||||
|   ExpoLocalization: |   ExpoLocalization: | ||||||
|     :path: "../node_modules/expo-localization/ios" |     :path: "../node_modules/expo-localization/ios" | ||||||
|   ExpoModulesCore: |   ExpoModulesCore: | ||||||
| @@ -859,6 +880,7 @@ SPEC CHECKSUMS: | |||||||
|   boost: a7c83b31436843459a1961bfd74b96033dc77234 |   boost: a7c83b31436843459a1961bfd74b96033dc77234 | ||||||
|   DoubleConversion: 831926d9b8bf8166fd87886c4abab286c2422662 |   DoubleConversion: 831926d9b8bf8166fd87886c4abab286c2422662 | ||||||
|   EASClient: 93565f4d024559b75eac62bc7d50acaa354614f6 |   EASClient: 93565f4d024559b75eac62bc7d50acaa354614f6 | ||||||
|  |   EXApplication: d6562af1204162e0ac46d341a7d4e5dc720b33de | ||||||
|   EXAV: 88f61c5af8415715b7ee51f084c1020235b85c56 |   EXAV: 88f61c5af8415715b7ee51f084c1020235b85c56 | ||||||
|   EXConstants: fdbe52259365b6a6faaa5e99a3b82cfa6bc2eb61 |   EXConstants: fdbe52259365b6a6faaa5e99a3b82cfa6bc2eb61 | ||||||
|   EXDevice: 0115b360059ccd32c1701744e374e3259ffbdd3c |   EXDevice: 0115b360059ccd32c1701744e374e3259ffbdd3c | ||||||
| @@ -866,6 +888,7 @@ SPEC CHECKSUMS: | |||||||
|   EXFileSystem: 2aa2d9289f84bca9532b9ccbd81504fa31eb1ded |   EXFileSystem: 2aa2d9289f84bca9532b9ccbd81504fa31eb1ded | ||||||
|   EXFirebaseAnalytics: aeefc63f92277313c3ee86da6a7ecf892f345ed1 |   EXFirebaseAnalytics: aeefc63f92277313c3ee86da6a7ecf892f345ed1 | ||||||
|   EXFirebaseCore: bdfa87df74fa1b74a6b38957561456aabad28a4f |   EXFirebaseCore: bdfa87df74fa1b74a6b38957561456aabad28a4f | ||||||
|  |   EXFont: 04235cc22e6fef86028feb67db452978dc6f240f | ||||||
|   EXImageLoader: b88e053d760f85a82405b1db2de4abf11978fc9f |   EXImageLoader: b88e053d760f85a82405b1db2de4abf11978fc9f | ||||||
|   EXJSONUtils: 2a74b8f40f1523cc3f92af99c91aa78201737a77 |   EXJSONUtils: 2a74b8f40f1523cc3f92af99c91aa78201737a77 | ||||||
|   EXManifests: 0c6134b7b6f3236a93a778c3f44ba1cfb3f9fa3d |   EXManifests: 0c6134b7b6f3236a93a778c3f44ba1cfb3f9fa3d | ||||||
| @@ -873,7 +896,9 @@ SPEC CHECKSUMS: | |||||||
|   Expo: b9fff0a1eac0f424fc68ea49b4347fb308e52e17 |   Expo: b9fff0a1eac0f424fc68ea49b4347fb308e52e17 | ||||||
|   ExpoCrypto: d0d0f3e20875dc450b4ec88f0fb608da5c2c6c17 |   ExpoCrypto: d0d0f3e20875dc450b4ec88f0fb608da5c2c6c17 | ||||||
|   ExpoHaptics: ad58ec96a25e57579c14a47c7d71f0de0de8656a |   ExpoHaptics: ad58ec96a25e57579c14a47c7d71f0de0de8656a | ||||||
|  |   ExpoImageManipulator: b55580bbc7b10099c7707949903e7176a8542ee8 | ||||||
|   ExpoImagePicker: d9d6b4f29db437fc7796f13cee5f133f5b4b5f7c |   ExpoImagePicker: d9d6b4f29db437fc7796f13cee5f133f5b4b5f7c | ||||||
|  |   ExpoKeepAwake: c0c494b442ecd8122974c13b93ccfb57bd408e88 | ||||||
|   ExpoLocalization: 8f619bb6eec64575cd5220bfabbd7b4e2d6f33f8 |   ExpoLocalization: 8f619bb6eec64575cd5220bfabbd7b4e2d6f33f8 | ||||||
|   ExpoModulesCore: e4278a668e8c13c0269ed8b8a4200989deea2973 |   ExpoModulesCore: e4278a668e8c13c0269ed8b8a4200989deea2973 | ||||||
|   ExpoRandom: 14df0976aa363a71a730ceb7655250f3047c0e42 |   ExpoRandom: 14df0976aa363a71a730ceb7655250f3047c0e42 | ||||||
|   | |||||||
| @@ -56,6 +56,7 @@ | |||||||
|     "expo-file-system": "14.0.0", |     "expo-file-system": "14.0.0", | ||||||
|     "expo-firebase-analytics": "7.0.0", |     "expo-firebase-analytics": "7.0.0", | ||||||
|     "expo-haptics": "11.2.0", |     "expo-haptics": "11.2.0", | ||||||
|  |     "expo-image-manipulator": "^10.3.1", | ||||||
|     "expo-image-picker": "13.1.1", |     "expo-image-picker": "13.1.1", | ||||||
|     "expo-linking": "3.1.0", |     "expo-linking": "3.1.0", | ||||||
|     "expo-localization": "13.0.0", |     "expo-localization": "13.0.0", | ||||||
|   | |||||||
| @@ -178,11 +178,11 @@ const Screens: React.FC<Props> = ({ localCorrupt }) => { | |||||||
|       } |       } | ||||||
|  |  | ||||||
|       let text: string | undefined = undefined |       let text: string | undefined = undefined | ||||||
|       let media: { path: string; mime: string }[] = [] |       let media: { uri: string; mime: string }[] = [] | ||||||
|  |  | ||||||
|       const typesImage = ['png', 'jpg', 'jpeg', 'gif'] |       const typesImage = ['png', 'jpg', 'jpeg', 'gif'] | ||||||
|       const typesVideo = ['mp4', 'm4v', 'mov', 'webm', 'mpeg'] |       const typesVideo = ['mp4', 'm4v', 'mov', 'webm', 'mpeg'] | ||||||
|       const filterMedia = ({ path, mime }: { path: string; mime: string }) => { |       const filterMedia = ({ uri, mime }: { uri: string; mime: string }) => { | ||||||
|         if (mime.startsWith('image/')) { |         if (mime.startsWith('image/')) { | ||||||
|           if (!typesImage.includes(mime.split('/')[1])) { |           if (!typesImage.includes(mime.split('/')[1])) { | ||||||
|             console.warn('Image type not supported:', mime.split('/')[1]) |             console.warn('Image type not supported:', mime.split('/')[1]) | ||||||
| @@ -195,7 +195,7 @@ const Screens: React.FC<Props> = ({ localCorrupt }) => { | |||||||
|             }) |             }) | ||||||
|             return |             return | ||||||
|           } |           } | ||||||
|           media.push({ path, mime }) |           media.push({ uri, mime }) | ||||||
|         } else if (mime.startsWith('video/')) { |         } else if (mime.startsWith('video/')) { | ||||||
|           if (!typesVideo.includes(mime.split('/')[1])) { |           if (!typesVideo.includes(mime.split('/')[1])) { | ||||||
|             console.warn('Video type not supported:', mime.split('/')[1]) |             console.warn('Video type not supported:', mime.split('/')[1]) | ||||||
| @@ -208,17 +208,17 @@ const Screens: React.FC<Props> = ({ localCorrupt }) => { | |||||||
|             }) |             }) | ||||||
|             return |             return | ||||||
|           } |           } | ||||||
|           media.push({ path, mime }) |           media.push({ uri, mime }) | ||||||
|         } else { |         } else { | ||||||
|           if (typesImage.includes(path.split('.').pop() || '')) { |           if (typesImage.includes(uri.split('.').pop() || '')) { | ||||||
|             media.push({ path: path, mime: 'image/jpg' }) |             media.push({ uri, mime: 'image/jpg' }) | ||||||
|             return |             return | ||||||
|           } |           } | ||||||
|           if (typesVideo.includes(path.split('.').pop() || '')) { |           if (typesVideo.includes(uri.split('.').pop() || '')) { | ||||||
|             media.push({ path: path, mime: 'video/mp4' }) |             media.push({ uri, mime: 'video/mp4' }) | ||||||
|             return |             return | ||||||
|           } |           } | ||||||
|           text = !text ? path : text.concat(text, `\n${path}`) |           text = !text ? uri : text.concat(text, `\n${uri}`) | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
|  |  | ||||||
| @@ -230,7 +230,7 @@ const Screens: React.FC<Props> = ({ localCorrupt }) => { | |||||||
|  |  | ||||||
|           for (const d of item.data) { |           for (const d of item.data) { | ||||||
|             if (typeof d !== 'string') { |             if (typeof d !== 'string') { | ||||||
|               filterMedia({ path: d.data, mime: d.mimeType }) |               filterMedia({ uri: d.data, mime: d.mimeType }) | ||||||
|             } |             } | ||||||
|           } |           } | ||||||
|           break |           break | ||||||
| @@ -245,7 +245,7 @@ const Screens: React.FC<Props> = ({ localCorrupt }) => { | |||||||
|             tempData = item.data |             tempData = item.data | ||||||
|           } |           } | ||||||
|           for (const d of item.data) { |           for (const d of item.data) { | ||||||
|             filterMedia({ path: d, mime: item.mimeType }) |             filterMedia({ uri: d, mime: item.mimeType }) | ||||||
|           } |           } | ||||||
|           break |           break | ||||||
|       } |       } | ||||||
|   | |||||||
| @@ -2,9 +2,10 @@ import analytics from '@components/analytics' | |||||||
| import { ActionSheetOptions } from '@expo/react-native-action-sheet' | import { ActionSheetOptions } from '@expo/react-native-action-sheet' | ||||||
| import { store } from '@root/store' | import { store } from '@root/store' | ||||||
| import { getInstanceConfigurationStatusMaxAttachments } from '@utils/slices/instancesSlice' | import { getInstanceConfigurationStatusMaxAttachments } from '@utils/slices/instancesSlice' | ||||||
|  | import { manipulateAsync, SaveFormat } from 'expo-image-manipulator' | ||||||
| import * as ExpoImagePicker from 'expo-image-picker' | import * as ExpoImagePicker from 'expo-image-picker' | ||||||
| import i18next from 'i18next' | import i18next from 'i18next' | ||||||
| import { Alert, Linking } from 'react-native' | import { Alert, Linking, Platform } from 'react-native' | ||||||
| import ImagePicker, { | import ImagePicker, { | ||||||
|   Image, |   Image, | ||||||
|   ImageOrVideo |   ImageOrVideo | ||||||
| @@ -27,7 +28,7 @@ const mediaSelector = async ({ | |||||||
|   maximum, |   maximum, | ||||||
|   indicateMaximum = false, |   indicateMaximum = false, | ||||||
|   showActionSheetWithOptions |   showActionSheetWithOptions | ||||||
| }: Props): Promise<ImageOrVideo[]> => { | }: Props): Promise<({ uri: string } & Omit<ImageOrVideo, 'path'>)[]> => { | ||||||
|   const checkLibraryPermission = async (): Promise<boolean> => { |   const checkLibraryPermission = async (): Promise<boolean> => { | ||||||
|     const { status } = |     const { status } = | ||||||
|       await ExpoImagePicker.requestMediaLibraryPermissionsAsync() |       await ExpoImagePicker.requestMediaLibraryPermissionsAsync() | ||||||
| @@ -110,17 +111,40 @@ const mediaSelector = async ({ | |||||||
|         multiple: true, |         multiple: true, | ||||||
|         minFiles: 1, |         minFiles: 1, | ||||||
|         maxFiles: _maximum, |         maxFiles: _maximum, | ||||||
|         loadingLabelText: '', |         smartAlbums: ['UserLibrary'], | ||||||
|         compressImageMaxWidth: 4096, |         writeTempFile: false, | ||||||
|         compressImageMaxHeight: 4096 |         loadingLabelText: '' | ||||||
|       }).catch(() => {}) |       }).catch(() => {}) | ||||||
|  |  | ||||||
|       if (!images) { |       if (!images) { | ||||||
|         return reject() |         return reject() | ||||||
|       } |       } | ||||||
|  |  | ||||||
|  |       // react-native-image-crop-picker may return HEIC as JPG that causes upload failure | ||||||
|  |       if (Platform.OS === 'ios') { | ||||||
|  |         for (const [index, image] of images.entries()) { | ||||||
|  |           if (image.mime === 'image/heic') { | ||||||
|  |             const converted = await manipulateAsync(image.sourceURL!, [], { | ||||||
|  |               base64: false, | ||||||
|  |               compress: 0.8, | ||||||
|  |               format: SaveFormat.JPEG | ||||||
|  |             }) | ||||||
|  |             images[index] = { | ||||||
|  |               ...images[index], | ||||||
|  |               sourceURL: converted.uri, | ||||||
|  |               mime: 'image/jpeg' | ||||||
|  |             } | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |  | ||||||
|       if (!resize) { |       if (!resize) { | ||||||
|         return resolve(images) |         return resolve( | ||||||
|  |           images.map(image => ({ | ||||||
|  |             ...image, | ||||||
|  |             uri: image.sourceURL || `file://${image.path}` | ||||||
|  |           })) | ||||||
|  |         ) | ||||||
|       } else { |       } else { | ||||||
|         const croppedImages: Image[] = [] |         const croppedImages: Image[] = [] | ||||||
|         for (const image of images) { |         for (const image of images) { | ||||||
| @@ -135,7 +159,12 @@ const mediaSelector = async ({ | |||||||
|           }).catch(() => {}) |           }).catch(() => {}) | ||||||
|           croppedImage && croppedImages.push(croppedImage) |           croppedImage && croppedImages.push(croppedImage) | ||||||
|         } |         } | ||||||
|         return resolve(croppedImages) |         return resolve( | ||||||
|  |           croppedImages.map(image => ({ | ||||||
|  |             ...image, | ||||||
|  |             uri: `file://${image.path}` | ||||||
|  |           })) | ||||||
|  |         ) | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|     const selectVideo = async () => { |     const selectVideo = async () => { | ||||||
| @@ -146,7 +175,9 @@ const mediaSelector = async ({ | |||||||
|       }).catch(() => {}) |       }).catch(() => {}) | ||||||
|  |  | ||||||
|       if (video) { |       if (video) { | ||||||
|         return resolve([video]) |         return resolve([ | ||||||
|  |           { ...video, uri: video.sourceURL || `file://${video.path}` } | ||||||
|  |         ]) | ||||||
|       } else { |       } else { | ||||||
|         return reject() |         return reject() | ||||||
|       } |       } | ||||||
|   | |||||||
| @@ -128,8 +128,8 @@ const ComposeEditAttachmentImage: React.FC<Props> = ({ index }) => { | |||||||
|             height: imageDimensionis.height |             height: imageDimensionis.height | ||||||
|           }} |           }} | ||||||
|           source={{ |           source={{ | ||||||
|             uri: theAttachmentLocal?.path |             uri: theAttachmentLocal?.uri | ||||||
|               ? `file://${theAttachmentLocal?.path}` |               ? theAttachmentLocal.uri | ||||||
|               : theAttachmentRemote?.preview_url |               : theAttachmentRemote?.preview_url | ||||||
|           }} |           }} | ||||||
|         /> |         /> | ||||||
|   | |||||||
| @@ -34,7 +34,7 @@ const ComposeEditAttachmentRoot: React.FC<Props> = ({ index }) => { | |||||||
|               video={ |               video={ | ||||||
|                 video.local |                 video.local | ||||||
|                   ? ({ |                   ? ({ | ||||||
|                       url: `file://${video.local.path}`, |                       url: video.local.uri, | ||||||
|                       preview_url: video.local.local_thumbnail, |                       preview_url: video.local.local_thumbnail, | ||||||
|                       blurhash: video.remote?.blurhash |                       blurhash: video.remote?.blurhash | ||||||
|                     } as Mastodon.AttachmentVideo) |                     } as Mastodon.AttachmentVideo) | ||||||
|   | |||||||
| @@ -22,28 +22,25 @@ export const uploadAttachment = async ({ | |||||||
|   media |   media | ||||||
| }: { | }: { | ||||||
|   composeDispatch: Dispatch<ComposeAction> |   composeDispatch: Dispatch<ComposeAction> | ||||||
|   media: Pick<ImageOrVideo, 'path' | 'mime' | 'width' | 'height'> |   media: { uri: string } & Pick<ImageOrVideo, 'mime' | 'width' | 'height'> | ||||||
| }) => { | }) => { | ||||||
|   const hash = await Crypto.digestStringAsync( |   const hash = await Crypto.digestStringAsync( | ||||||
|     Crypto.CryptoDigestAlgorithm.SHA256, |     Crypto.CryptoDigestAlgorithm.SHA256, | ||||||
|     media.path + Math.random() |     media.uri + Math.random() | ||||||
|   ) |   ) | ||||||
|   let attachmentType: string |  | ||||||
|  |  | ||||||
|   switch (media.mime.split('/')[0]) { |   switch (media.mime.split('/')[0]) { | ||||||
|     case 'image': |     case 'image': | ||||||
|       attachmentType = `image/${media.path.split('.')[1]}` |  | ||||||
|       composeDispatch({ |       composeDispatch({ | ||||||
|         type: 'attachment/upload/start', |         type: 'attachment/upload/start', | ||||||
|         payload: { |         payload: { | ||||||
|           local: { ...media, type: 'image', local_thumbnail: media.path, hash }, |           local: { ...media, type: 'image', local_thumbnail: media.uri, hash }, | ||||||
|           uploading: true |           uploading: true | ||||||
|         } |         } | ||||||
|       }) |       }) | ||||||
|       break |       break | ||||||
|     case 'video': |     case 'video': | ||||||
|       attachmentType = `video/${media.path.split('.')[1]}` |       VideoThumbnails.getThumbnailAsync(media.uri) | ||||||
|       VideoThumbnails.getThumbnailAsync(media.path) |  | ||||||
|         .then(({ uri, width, height }) => |         .then(({ uri, width, height }) => | ||||||
|           composeDispatch({ |           composeDispatch({ | ||||||
|             type: 'attachment/upload/start', |             type: 'attachment/upload/start', | ||||||
| @@ -71,7 +68,6 @@ export const uploadAttachment = async ({ | |||||||
|         ) |         ) | ||||||
|       break |       break | ||||||
|     default: |     default: | ||||||
|       attachmentType = 'unknown' |  | ||||||
|       composeDispatch({ |       composeDispatch({ | ||||||
|         type: 'attachment/upload/start', |         type: 'attachment/upload/start', | ||||||
|         payload: { |         payload: { | ||||||
| @@ -105,9 +101,9 @@ export const uploadAttachment = async ({ | |||||||
|  |  | ||||||
|   const formData = new FormData() |   const formData = new FormData() | ||||||
|   formData.append('file', { |   formData.append('file', { | ||||||
|     uri: `file://${media.path}`, |     uri: media.uri, | ||||||
|     name: attachmentType, |     name: media.uri.match(new RegExp(/.*\/(.*)/))?.[1] || 'file.jpg', | ||||||
|     type: attachmentType |     type: media.mime | ||||||
|   } as any) |   } as any) | ||||||
|  |  | ||||||
|   return apiInstance<Mastodon.Attachment>({ |   return apiInstance<Mastodon.Attachment>({ | ||||||
|   | |||||||
| @@ -90,7 +90,7 @@ const ComposeTextInput: React.FC = () => { | |||||||
|           uploadAttachment({ |           uploadAttachment({ | ||||||
|             composeDispatch, |             composeDispatch, | ||||||
|             media: { |             media: { | ||||||
|               path: file.uri, |               uri: file.uri, | ||||||
|               mime: file.type, |               mime: file.type, | ||||||
|               width: 100, |               width: 100, | ||||||
|               height: 100 |               height: 100 | ||||||
|   | |||||||
| @@ -58,7 +58,7 @@ const composeReducer = ( | |||||||
|         attachments: { |         attachments: { | ||||||
|           ...state.attachments, |           ...state.attachments, | ||||||
|           uploads: state.attachments.uploads.map(upload => |           uploads: state.attachments.uploads.map(upload => | ||||||
|             upload.local?.path === action.payload.local?.path |             upload.local?.uri === action.payload.local?.uri | ||||||
|               ? { ...upload, remote: action.payload.remote, uploading: false } |               ? { ...upload, remote: action.payload.remote, uploading: false } | ||||||
|               : upload |               : upload | ||||||
|           ) |           ) | ||||||
|   | |||||||
							
								
								
									
										4
									
								
								src/screens/Compose/utils/types.d.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								src/screens/Compose/utils/types.d.ts
									
									
									
									
										vendored
									
									
								
							| @@ -2,7 +2,7 @@ import { ImageOrVideo } from 'react-native-image-crop-picker' | |||||||
|  |  | ||||||
| export type ExtendedAttachment = { | export type ExtendedAttachment = { | ||||||
|   remote?: Mastodon.Attachment |   remote?: Mastodon.Attachment | ||||||
|   local?: Pick<ImageOrVideo, 'path' | 'width' | 'height' | 'mime'> & { |   local?: { uri: string } & Pick<ImageOrVideo, 'width' | 'height' | 'mime'> & { | ||||||
|       type: 'image' | 'video' | 'unknown' |       type: 'image' | 'video' | 'unknown' | ||||||
|       local_thumbnail?: string |       local_thumbnail?: string | ||||||
|       hash?: string |       hash?: string | ||||||
| @@ -123,7 +123,7 @@ export type ComposeAction = | |||||||
|       type: 'attachment/upload/end' |       type: 'attachment/upload/end' | ||||||
|       payload: { |       payload: { | ||||||
|         remote: Mastodon.Attachment |         remote: Mastodon.Attachment | ||||||
|         local: Pick<ImageOrVideo, 'path' | 'width' | 'height' | 'mime'> |         local: { uri: string } & Pick<ImageOrVideo, 'width' | 'height' | 'mime'> | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|   | { |   | { | ||||||
|   | |||||||
| @@ -46,7 +46,7 @@ const ProfileAvatarHeader: React.FC<Props> = ({ type, messageRef }) => { | |||||||
|             failed: true |             failed: true | ||||||
|           }, |           }, | ||||||
|           type, |           type, | ||||||
|           data: image[0].path |           data: image[0].uri | ||||||
|         }) |         }) | ||||||
|       }} |       }} | ||||||
|     /> |     /> | ||||||
|   | |||||||
| @@ -42,7 +42,7 @@ export type RootStackParamList = { | |||||||
|     | { |     | { | ||||||
|         type: 'share' |         type: 'share' | ||||||
|         text?: string |         text?: string | ||||||
|         media?: { path: string; mime: string }[] |         media?: { uri: string; mime: string }[] | ||||||
|       } |       } | ||||||
|     | undefined |     | undefined | ||||||
|   'Screen-ImagesViewer': { |   'Screen-ImagesViewer': { | ||||||
|   | |||||||
| @@ -4428,6 +4428,13 @@ expo-image-loader@~3.2.0: | |||||||
|   resolved "https://registry.yarnpkg.com/expo-image-loader/-/expo-image-loader-3.2.0.tgz#d98b021660edef7243f7c5ec011b8d0545626d41" |   resolved "https://registry.yarnpkg.com/expo-image-loader/-/expo-image-loader-3.2.0.tgz#d98b021660edef7243f7c5ec011b8d0545626d41" | ||||||
|   integrity sha512-LU3Q2prn64/HxdToDmxgMIRXS1ZvD9Q3iCxRVTZn1fPQNNDciIQFE5okaa74Ogx20DFHs90r6WoUd7w9Af1OGQ== |   integrity sha512-LU3Q2prn64/HxdToDmxgMIRXS1ZvD9Q3iCxRVTZn1fPQNNDciIQFE5okaa74Ogx20DFHs90r6WoUd7w9Af1OGQ== | ||||||
|  |  | ||||||
|  | expo-image-manipulator@^10.3.1: | ||||||
|  |   version "10.3.1" | ||||||
|  |   resolved "https://registry.yarnpkg.com/expo-image-manipulator/-/expo-image-manipulator-10.3.1.tgz#e16dd76a550c7f5d653a2a666f26429eba311a6b" | ||||||
|  |   integrity sha512-D08dMD6MerxBu23DmCIhurySQih+eLP7VxKvY5mWqYz9payjDOS1cAGs3HvXPrEDusPQFQ0uIfqc+oqeMNFBIA== | ||||||
|  |   dependencies: | ||||||
|  |     expo-image-loader "~3.2.0" | ||||||
|  |  | ||||||
| expo-image-picker@13.1.1: | expo-image-picker@13.1.1: | ||||||
|   version "13.1.1" |   version "13.1.1" | ||||||
|   resolved "https://registry.yarnpkg.com/expo-image-picker/-/expo-image-picker-13.1.1.tgz#e039bf9748ccb7b89370ff2969c3ef07cc949192" |   resolved "https://registry.yarnpkg.com/expo-image-picker/-/expo-image-picker-13.1.1.tgz#e039bf9748ccb7b89370ff2969c3ef07cc949192" | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user