Give a more sensible default crop in the post image picker (related #39)

zio/stable
Paul Frazee 2023-01-17 18:35:37 -06:00
parent fb334b1b3f
commit bccc8a64d0
3 changed files with 47 additions and 6 deletions

View File

@ -112,3 +112,19 @@ export async function compressIfNeeded(
maxSize, 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}
}

View File

@ -3,6 +3,8 @@ import {makeAutoObservable, runInAction} from 'mobx'
import {CameraRoll} from '@react-native-camera-roll/camera-roll' import {CameraRoll} from '@react-native-camera-roll/camera-roll'
import {RootStoreModel} from './root-store' import {RootStoreModel} from './root-store'
export type {PhotoIdentifier} from './../../../node_modules/@react-native-camera-roll/camera-roll/src/CameraRoll'
export class UserLocalPhotosModel { export class UserLocalPhotosModel {
// state // state
photos: PhotoIdentifier[] = [] photos: PhotoIdentifier[] = []

View File

@ -6,10 +6,17 @@ import {
openCamera, openCamera,
openCropper, openCropper,
} from 'react-native-image-crop-picker' } 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 {usePalette} from '../../lib/hooks/usePalette'
import {useStores} from '../../../state' import {useStores} from '../../../state'
const MAX_WIDTH = 1000
const MAX_HEIGHT = 1000
const IMAGE_PARAMS = { const IMAGE_PARAMS = {
width: 1000, width: 1000,
height: 1000, height: 1000,
@ -25,7 +32,7 @@ export const PhotoCarouselPicker = ({
}: { }: {
selectedPhotos: string[] selectedPhotos: string[]
onSelectPhotos: (v: string[]) => void onSelectPhotos: (v: string[]) => void
localPhotos: any localPhotos: UserLocalPhotosModel
}) => { }) => {
const pal = usePalette('default') const pal = usePalette('default')
const store = useStores() const store = useStores()
@ -45,12 +52,20 @@ export const PhotoCarouselPicker = ({
}, [store.log, selectedPhotos, onSelectPhotos]) }, [store.log, selectedPhotos, onSelectPhotos])
const handleSelectPhoto = useCallback( const handleSelectPhoto = useCallback(
async (uri: string) => { async (item: PhotoIdentifier) => {
try { 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({ const cropperRes = await openCropper({
mediaType: 'photo', mediaType: 'photo',
path: uri, path: item.node.image.uri,
...IMAGE_PARAMS, ...IMAGE_PARAMS,
width,
height,
}) })
const img = await compressIfNeeded(cropperRes, 300000) const img = await compressIfNeeded(cropperRes, 300000)
onSelectPhotos([img.path, ...selectedPhotos]) onSelectPhotos([img.path, ...selectedPhotos])
@ -71,10 +86,18 @@ export const PhotoCarouselPicker = ({
const result = [] const result = []
for (const image of items) { 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({ const cropperRes = await openCropper({
mediaType: 'photo', mediaType: 'photo',
path: image.path, path: image.path,
...IMAGE_PARAMS, ...IMAGE_PARAMS,
width,
height,
}) })
const finalImg = await compressIfNeeded(cropperRes, 300000) const finalImg = await compressIfNeeded(cropperRes, 300000)
result.push(finalImg.path) result.push(finalImg.path)
@ -101,12 +124,12 @@ export const PhotoCarouselPicker = ({
onPress={handleOpenGallery}> onPress={handleOpenGallery}>
<FontAwesomeIcon icon="image" style={pal.link} size={24} /> <FontAwesomeIcon icon="image" style={pal.link} size={24} />
</TouchableOpacity> </TouchableOpacity>
{localPhotos.photos.map((item: any, index: number) => ( {localPhotos.photos.map((item: PhotoIdentifier, index: number) => (
<TouchableOpacity <TouchableOpacity
testID="openSelectPhotoButton" testID="openSelectPhotoButton"
key={`local-image-${index}`} key={`local-image-${index}`}
style={[pal.border, styles.photoButton]} style={[pal.border, styles.photoButton]}
onPress={() => handleSelectPhoto(item.node.image.uri)}> onPress={() => handleSelectPhoto(item)}>
<Image style={styles.photo} source={{uri: item.node.image.uri}} /> <Image style={styles.photo} source={{uri: item.node.image.uri}} />
</TouchableOpacity> </TouchableOpacity>
))} ))}