···112112 maxSize,
113113 })
114114}
115115+116116+export interface Dim {
117117+ width: number
118118+ height: number
119119+}
120120+export function scaleDownDimensions(dim: Dim, max: Dim): Dim {
121121+ if (dim.width < max.width && dim.height < max.height) {
122122+ return dim
123123+ }
124124+ let wScale = dim.width > max.width ? max.width / dim.width : 1
125125+ let hScale = dim.height > max.height ? max.height / dim.height : 1
126126+ if (wScale < hScale) {
127127+ return {width: dim.width * wScale, height: dim.height * wScale}
128128+ }
129129+ return {width: dim.width * hScale, height: dim.height * hScale}
130130+}
+2
src/state/models/user-local-photos.ts
···33import {CameraRoll} from '@react-native-camera-roll/camera-roll'
44import {RootStoreModel} from './root-store'
5566+export type {PhotoIdentifier} from './../../../node_modules/@react-native-camera-roll/camera-roll/src/CameraRoll'
77+68export class UserLocalPhotosModel {
79 // state
810 photos: PhotoIdentifier[] = []
+29-6
src/view/com/composer/PhotoCarouselPicker.tsx
···66 openCamera,
77 openCropper,
88} from 'react-native-image-crop-picker'
99-import {compressIfNeeded} from '../../../lib/images'
99+import {
1010+ UserLocalPhotosModel,
1111+ PhotoIdentifier,
1212+} from '../../../state/models/user-local-photos'
1313+import {compressIfNeeded, scaleDownDimensions} from '../../../lib/images'
1014import {usePalette} from '../../lib/hooks/usePalette'
1115import {useStores} from '../../../state'
1616+1717+const MAX_WIDTH = 1000
1818+const MAX_HEIGHT = 1000
12191320const IMAGE_PARAMS = {
1421 width: 1000,
···2532}: {
2633 selectedPhotos: string[]
2734 onSelectPhotos: (v: string[]) => void
2828- localPhotos: any
3535+ localPhotos: UserLocalPhotosModel
2936}) => {
3037 const pal = usePalette('default')
3138 const store = useStores()
···4552 }, [store.log, selectedPhotos, onSelectPhotos])
46534754 const handleSelectPhoto = useCallback(
4848- async (uri: string) => {
5555+ async (item: PhotoIdentifier) => {
4956 try {
5757+ // choose target dimensions based on the original
5858+ // this causes the photo cropper to start with the full image "selected"
5959+ const {width, height} = scaleDownDimensions(
6060+ {width: item.node.image.width, height: item.node.image.height},
6161+ {width: MAX_WIDTH, height: MAX_HEIGHT},
6262+ )
5063 const cropperRes = await openCropper({
5164 mediaType: 'photo',
5252- path: uri,
6565+ path: item.node.image.uri,
5366 ...IMAGE_PARAMS,
6767+ width,
6868+ height,
5469 })
5570 const img = await compressIfNeeded(cropperRes, 300000)
5671 onSelectPhotos([img.path, ...selectedPhotos])
···7186 const result = []
72877388 for (const image of items) {
8989+ // choose target dimensions based on the original
9090+ // this causes the photo cropper to start with the full image "selected"
9191+ const {width, height} = scaleDownDimensions(
9292+ {width: image.width, height: image.height},
9393+ {width: MAX_WIDTH, height: MAX_HEIGHT},
9494+ )
7495 const cropperRes = await openCropper({
7596 mediaType: 'photo',
7697 path: image.path,
7798 ...IMAGE_PARAMS,
9999+ width,
100100+ height,
78101 })
79102 const finalImg = await compressIfNeeded(cropperRes, 300000)
80103 result.push(finalImg.path)
···101124 onPress={handleOpenGallery}>
102125 <FontAwesomeIcon icon="image" style={pal.link} size={24} />
103126 </TouchableOpacity>
104104- {localPhotos.photos.map((item: any, index: number) => (
127127+ {localPhotos.photos.map((item: PhotoIdentifier, index: number) => (
105128 <TouchableOpacity
106129 testID="openSelectPhotoButton"
107130 key={`local-image-${index}`}
108131 style={[pal.border, styles.photoButton]}
109109- onPress={() => handleSelectPhoto(item.node.image.uri)}>
132132+ onPress={() => handleSelectPhoto(item)}>
110133 <Image style={styles.photo} source={{uri: item.node.image.uri}} />
111134 </TouchableOpacity>
112135 ))}