diff --git a/src/lib/images.ts b/src/lib/images.ts index f56308c4..6f0b6a4f 100644 --- a/src/lib/images.ts +++ b/src/lib/images.ts @@ -112,3 +112,19 @@ export async function compressIfNeeded( maxSize, }) } + +export interface Dim { + width: number + height: number +} +export function scaleDownDimensions(dim: Dim, max: Dim): Dim { + if (dim.width < max.width && dim.height < max.height) { + return dim + } + let wScale = dim.width > max.width ? max.width / dim.width : 1 + let hScale = dim.height > max.height ? max.height / dim.height : 1 + if (wScale < hScale) { + return {width: dim.width * wScale, height: dim.height * wScale} + } + return {width: dim.width * hScale, height: dim.height * hScale} +} diff --git a/src/state/models/user-local-photos.ts b/src/state/models/user-local-photos.ts index 9a145503..08b2b390 100644 --- a/src/state/models/user-local-photos.ts +++ b/src/state/models/user-local-photos.ts @@ -3,6 +3,8 @@ import {makeAutoObservable, runInAction} from 'mobx' import {CameraRoll} from '@react-native-camera-roll/camera-roll' import {RootStoreModel} from './root-store' +export type {PhotoIdentifier} from './../../../node_modules/@react-native-camera-roll/camera-roll/src/CameraRoll' + export class UserLocalPhotosModel { // state photos: PhotoIdentifier[] = [] diff --git a/src/view/com/composer/PhotoCarouselPicker.tsx b/src/view/com/composer/PhotoCarouselPicker.tsx index 12dac582..21e91fc9 100644 --- a/src/view/com/composer/PhotoCarouselPicker.tsx +++ b/src/view/com/composer/PhotoCarouselPicker.tsx @@ -6,10 +6,17 @@ import { openCamera, openCropper, } from 'react-native-image-crop-picker' -import {compressIfNeeded} from '../../../lib/images' +import { + UserLocalPhotosModel, + PhotoIdentifier, +} from '../../../state/models/user-local-photos' +import {compressIfNeeded, scaleDownDimensions} from '../../../lib/images' import {usePalette} from '../../lib/hooks/usePalette' import {useStores} from '../../../state' +const MAX_WIDTH = 1000 +const MAX_HEIGHT = 1000 + const IMAGE_PARAMS = { width: 1000, height: 1000, @@ -25,7 +32,7 @@ export const PhotoCarouselPicker = ({ }: { selectedPhotos: string[] onSelectPhotos: (v: string[]) => void - localPhotos: any + localPhotos: UserLocalPhotosModel }) => { const pal = usePalette('default') const store = useStores() @@ -45,12 +52,20 @@ export const PhotoCarouselPicker = ({ }, [store.log, selectedPhotos, onSelectPhotos]) const handleSelectPhoto = useCallback( - async (uri: string) => { + async (item: PhotoIdentifier) => { try { + // choose target dimensions based on the original + // this causes the photo cropper to start with the full image "selected" + const {width, height} = scaleDownDimensions( + {width: item.node.image.width, height: item.node.image.height}, + {width: MAX_WIDTH, height: MAX_HEIGHT}, + ) const cropperRes = await openCropper({ mediaType: 'photo', - path: uri, + path: item.node.image.uri, ...IMAGE_PARAMS, + width, + height, }) const img = await compressIfNeeded(cropperRes, 300000) onSelectPhotos([img.path, ...selectedPhotos]) @@ -71,10 +86,18 @@ export const PhotoCarouselPicker = ({ const result = [] for (const image of items) { + // choose target dimensions based on the original + // this causes the photo cropper to start with the full image "selected" + const {width, height} = scaleDownDimensions( + {width: image.width, height: image.height}, + {width: MAX_WIDTH, height: MAX_HEIGHT}, + ) const cropperRes = await openCropper({ mediaType: 'photo', path: image.path, ...IMAGE_PARAMS, + width, + height, }) const finalImg = await compressIfNeeded(cropperRes, 300000) result.push(finalImg.path) @@ -101,12 +124,12 @@ export const PhotoCarouselPicker = ({ onPress={handleOpenGallery}> - {localPhotos.photos.map((item: any, index: number) => ( + {localPhotos.photos.map((item: PhotoIdentifier, index: number) => ( handleSelectPhoto(item.node.image.uri)}> + onPress={() => handleSelectPhoto(item)}> ))}