bsky-app/src/view/com/composer/PhotoCarouselPicker.tsx
João Ferreiro 5abcc8e336 Unit Testing (#35)
* add testing lib

* remove coverage folder from git

* finished basic test setup

* fix tests typescript and import paths

* add first snapshot

* testing utils

* rename test files; update script flags; ++tests

* testing utils functions

* testing downloadAndResize wip

* remove download test

* specify unwanted coverage paths;
remove update snapshots flag

* fix strings tests

* testing downloadAndResize method

* increasing testing

* fixing snapshots wip

* fixed shell mobile snapshot

* adding snapshots for the screens

* fix onboard snapshot

* fix typescript issues

* fix TabsSelector snapshot

* Account for testing device's locale in ago() tests

* Remove platform detection on regex

* mocking store state wip

* mocking store state

* increasing test coverage

* increasing test coverage

* increasing test coverage on src/screens

* src/screens (except for profile) above 80% cov

* testing profile screen wip

* increase coverage on Menu and TabsSelector

* mocking profile ui state wip

* mocking profile ui state wip

* fixing mobileshell tests wip

* snapshots using testing-library

* fixing profile tests wip

* removing mobile shell tests

* src/view/com tests wip

* remove unnecessary patch-package

* fixed profile test error

* clear mocks after every test

* fix base mocked store values (getters)

* fix base mocked store values
(hasLoaded, nonReplyFeed)

* profile screen above 80% coverage

* testing custom hooks

* improving composer coverage

* fix tests after merge

* finishing composer coverage

* improving src/com/discover coverage

* improve src/view/com/login coverage
fix SuggestedFollows tests
adding some comments

* fix SuggestedFollows tests

* improve src/view/com/profile coverage
extra minor fixes

* improve src/view/com/notifications coverage

* update coverage ignore patterns

* rename errorMessageTryAgainButton
increase SuggestedFollows converage

* improve src/view/com/posts coverage

* improve src/view/com/onboard coverage

* update snapshot

* improve src/view/com/post coverage

* improve src/view/com/post-thread coverage
rename ErrorMessage tests
test Debug and Log components

* init testing state

* testing root-store

* updating comments

* small fixes

* removed extra console logs

* improve src/state/models coverage
refactor rootStore
rename some spies

* adding cleanup method after tests

* improve src/state/models coverage

* improve src/state/models coverage

* improve src/state/models coverage

* improve src/state/models coverage

* test setInterval in setupState

* Clean up tests and update Home screen state management

* Remove some tests we dont need

* Remove snapshot tests

* Remove any tests that dont demonstrate clear value

* Cleanup

Co-authored-by: Paul Frazee <pfrazee@gmail.com>
2023-01-17 10:06:00 -06:00

142 lines
3.8 KiB
TypeScript

import React, {useCallback} from 'react'
import {Image, StyleSheet, TouchableOpacity, ScrollView} from 'react-native'
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
import {
openPicker,
openCamera,
openCropper,
} from 'react-native-image-crop-picker'
import {compressIfNeeded} from '../../../lib/images'
import {usePalette} from '../../lib/hooks/usePalette'
import {useStores} from '../../../state'
const IMAGE_PARAMS = {
width: 1000,
height: 1000,
freeStyleCropEnabled: true,
forceJpg: true, // ios only
compressImageQuality: 1.0,
}
export const PhotoCarouselPicker = ({
selectedPhotos,
onSelectPhotos,
localPhotos,
}: {
selectedPhotos: string[]
onSelectPhotos: (v: string[]) => void
localPhotos: any
}) => {
const pal = usePalette('default')
const store = useStores()
const handleOpenCamera = useCallback(async () => {
try {
const cameraRes = await openCamera({
mediaType: 'photo',
cropping: true,
...IMAGE_PARAMS,
})
const img = await compressIfNeeded(cameraRes, 300000)
onSelectPhotos([img.path, ...selectedPhotos])
} catch (err: any) {
// ignore
store.log.warn('Error using camera', err)
}
}, [store.log, selectedPhotos, onSelectPhotos])
const handleSelectPhoto = useCallback(
async (uri: string) => {
try {
const cropperRes = await openCropper({
mediaType: 'photo',
path: uri,
...IMAGE_PARAMS,
})
const img = await compressIfNeeded(cropperRes, 300000)
onSelectPhotos([img.path, ...selectedPhotos])
} catch (err: any) {
// ignore
store.log.warn('Error selecting photo', err)
}
},
[store.log, selectedPhotos, onSelectPhotos],
)
const handleOpenGallery = useCallback(() => {
openPicker({
multiple: true,
maxFiles: 4 - selectedPhotos.length,
mediaType: 'photo',
}).then(async items => {
const result = []
for (const image of items) {
const cropperRes = await openCropper({
mediaType: 'photo',
path: image.path,
...IMAGE_PARAMS,
})
const finalImg = await compressIfNeeded(cropperRes, 300000)
result.push(finalImg.path)
}
onSelectPhotos([...result, ...selectedPhotos])
})
}, [selectedPhotos, onSelectPhotos])
return (
<ScrollView
testID="photoCarouselPickerView"
horizontal
style={[pal.view, styles.photosContainer]}
showsHorizontalScrollIndicator={false}>
<TouchableOpacity
testID="openCameraButton"
style={[styles.galleryButton, pal.border, styles.photo]}
onPress={handleOpenCamera}>
<FontAwesomeIcon icon="camera" size={24} style={pal.link} />
</TouchableOpacity>
<TouchableOpacity
testID="openGalleryButton"
style={[styles.galleryButton, pal.border, styles.photo]}
onPress={handleOpenGallery}>
<FontAwesomeIcon icon="image" style={pal.link} size={24} />
</TouchableOpacity>
{localPhotos.photos.map((item: any, index: number) => (
<TouchableOpacity
testID="openSelectPhotoButton"
key={`local-image-${index}`}
style={[pal.border, styles.photoButton]}
onPress={() => handleSelectPhoto(item.node.image.uri)}>
<Image style={styles.photo} source={{uri: item.node.image.uri}} />
</TouchableOpacity>
))}
</ScrollView>
)
}
const styles = StyleSheet.create({
photosContainer: {
width: '100%',
maxHeight: 96,
padding: 8,
overflow: 'hidden',
},
galleryButton: {
borderWidth: 1,
alignItems: 'center',
justifyContent: 'center',
},
photoButton: {
width: 75,
height: 75,
marginRight: 8,
borderWidth: 1,
borderRadius: 16,
},
photo: {
width: 75,
height: 75,
marginRight: 8,
borderRadius: 16,
},
})