Give a more sensible default crop in the post image picker (related #39)
parent
fb334b1b3f
commit
bccc8a64d0
|
@ -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}
|
||||||
|
}
|
||||||
|
|
|
@ -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[] = []
|
||||||
|
|
|
@ -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>
|
||||||
))}
|
))}
|
||||||
|
|
Loading…
Reference in New Issue