Skip to content

Commit b38e722

Browse files
committed
# If applied, this commit will...
prettify the whole file and allow other components that include the word "image" in them to be used by the photo uploader. # Provide links to any relevant tickets, articles or other resources Closes: # Progresses : #
1 parent 6813b29 commit b38e722

File tree

1 file changed

+155
-145
lines changed

1 file changed

+155
-145
lines changed

index.js

Lines changed: 155 additions & 145 deletions
Original file line numberDiff line numberDiff line change
@@ -1,152 +1,162 @@
1-
import React from 'react'
2-
import PropTypes from 'prop-types'
1+
import React from "react"
2+
import PropTypes from "prop-types"
33
import {
4-
View,
5-
Image,
6-
StyleSheet,
7-
TouchableOpacity,
8-
Platform
9-
} from 'react-native'
10-
import ImagePicker from 'react-native-image-picker'
11-
import ImageResizer from 'react-native-image-resizer'
12-
import RNFS from 'react-native-fs'
4+
View,
5+
Image,
6+
StyleSheet,
7+
TouchableOpacity,
8+
Platform
9+
} from "react-native"
10+
import ImagePicker from "react-native-image-picker"
11+
import ImageResizer from "react-native-image-resizer"
12+
import RNFS from "react-native-fs"
1313

1414
export default class PhotoUpload extends React.Component {
15-
static propTypes = {
16-
containerStyle: PropTypes.object,
17-
photoPickerTitle: PropTypes.string,
18-
maxHeight: PropTypes.number,
19-
maxWidth: PropTypes.number,
20-
format: PropTypes.string,
21-
quality: PropTypes.number,
22-
onPhotoSelect: PropTypes.func, // returns the base64 string of uploaded photo
23-
onError: PropTypes.func, // if any error occur with response
24-
onTapCustomButton: PropTypes.func, // on tap custom button
25-
onStart: PropTypes.func, // when user starts (useful for loading, etc)
26-
onCancel: PropTypes.func, // when user cancel
27-
onResponse: PropTypes.func, // on response exists!
28-
onRender: PropTypes.func, // after render
29-
onResizedImageUri: PropTypes.func, // when image resized is ready
30-
imagePickerProps: PropTypes.object // react-native-image-picker props
31-
}
32-
33-
state = {
34-
maxHeight: this.props.height || 600,
35-
maxWidth: this.props.width || 600,
36-
format: this.props.format || 'JPEG',
37-
quality: this.props.quality || 100,
38-
buttonDisabled: false
39-
}
40-
41-
options = {
42-
title: this.props.photoPickerTitle || 'Select Photo',
43-
storageOptions: {
44-
skipBackup: true,
45-
path: 'images'
46-
},
47-
...this.props.imagePickerProps
48-
}
49-
50-
openImagePicker = () => {
51-
this.setState({buttonDisabled: true})
52-
if (this.props.onStart) this.props.onStart()
53-
54-
// get image from image picker
55-
ImagePicker.showImagePicker(this.options, async response => {
56-
this.setState({buttonDisabled: false})
57-
58-
let rotation = 0
59-
const {originalRotation} = response
60-
61-
62-
if (this.props.onResponse) this.props.onResponse(response)
63-
64-
if (response.didCancel) {
65-
console.log('User cancelled image picker')
66-
if (this.props.onCancel) this.props.onCancel('User cancelled image picker')
67-
return
68-
} else if (response.error) {
69-
console.log('ImagePicker Error: ', response.error)
70-
if (this.props.onError) this.props.onError(response.error)
71-
return
72-
} else if (response.customButton) {
73-
console.log('User tapped custom button: ', response.customButton)
74-
if (this.props.onTapCustomButton) this.props.onTapCustomButton(response.customButton)
75-
return
76-
}
77-
78-
let { maxHeight, maxWidth, quality, format } = this.state
79-
80-
//Determining rotation param
81-
if ( originalRotation === 90) {
82-
rotation = 90
83-
} else if (originalRotation === 180) {
84-
//For a few images rotation is 180.
85-
rotation = -180
86-
} else if ( originalRotation === 270 ) {
87-
//When taking images with the front camera (selfie), the rotation is 270.
88-
rotation = -90
89-
}
90-
// resize image
91-
const resizedImageUri = await ImageResizer.createResizedImage(
92-
`data:image/jpeg;base64,${response.data}`,
93-
maxHeight,
94-
maxWidth,
95-
format,
96-
quality,
97-
rotation
98-
)
99-
100-
if (this.props.onResizedImageUri) this.props.onResizedImageUri(resizedImageUri)
101-
102-
const filePath = Platform.OS === 'android' && resizedImageUri.uri.replace
103-
? resizedImageUri.uri.replace('file:/data', '/data')
104-
: resizedImageUri.uri
105-
106-
// convert image back to base64 string
107-
const photoData = await RNFS.readFile(filePath, 'base64')
108-
let source = { uri: resizedImageUri.uri }
109-
this.setState({
110-
avatarSource: source
111-
})
112-
113-
// handle photo in props functions as data string
114-
if (this.props.onPhotoSelect) this.props.onPhotoSelect(photoData)
115-
})
116-
}
117-
118-
renderChildren = props => {
119-
return React.Children.map(props.children, child => {
120-
if (child && child.type === Image && this.state.avatarSource) {
121-
return React.cloneElement(child, {
122-
source: this.state.avatarSource
123-
})
124-
} else return child
125-
})
126-
}
127-
128-
componentDidUpdate() {
129-
if (this.props.onAfterRender) this.props.onAfterRender(this.state)
130-
}
131-
132-
render() {
133-
return (
134-
<View style={[styles.container, this.props.containerStyle]}>
135-
<TouchableOpacity
136-
onPress={this.openImagePicker}
137-
disabled={this.state.buttonDisabled}
138-
>
139-
{this.renderChildren(this.props)}
140-
</TouchableOpacity>
141-
</View>
142-
)
143-
}
15+
static propTypes = {
16+
containerStyle: PropTypes.object,
17+
photoPickerTitle: PropTypes.string,
18+
maxHeight: PropTypes.number,
19+
maxWidth: PropTypes.number,
20+
format: PropTypes.string,
21+
quality: PropTypes.number,
22+
onPhotoSelect: PropTypes.func, // returns the base64 string of uploaded photo
23+
onError: PropTypes.func, // if any error occur with response
24+
onTapCustomButton: PropTypes.func, // on tap custom button
25+
onStart: PropTypes.func, // when user starts (useful for loading, etc)
26+
onCancel: PropTypes.func, // when user cancel
27+
onResponse: PropTypes.func, // on response exists!
28+
onRender: PropTypes.func, // after render
29+
onResizedImageUri: PropTypes.func, // when image resized is ready
30+
imagePickerProps: PropTypes.object // react-native-image-picker props
31+
}
32+
33+
state = {
34+
maxHeight: this.props.height || 600,
35+
maxWidth: this.props.width || 600,
36+
format: this.props.format || "JPEG",
37+
quality: this.props.quality || 100,
38+
buttonDisabled: false
39+
}
40+
41+
options = {
42+
title: this.props.photoPickerTitle || "Select Photo",
43+
storageOptions: {
44+
skipBackup: true,
45+
path: "images"
46+
},
47+
...this.props.imagePickerProps
48+
}
49+
50+
openImagePicker = () => {
51+
this.setState({ buttonDisabled: true })
52+
if (this.props.onStart) this.props.onStart()
53+
54+
// get image from image picker
55+
ImagePicker.showImagePicker(this.options, async response => {
56+
this.setState({ buttonDisabled: false })
57+
58+
let rotation = 0
59+
const { originalRotation } = response
60+
61+
if (this.props.onResponse) this.props.onResponse(response)
62+
63+
if (response.didCancel) {
64+
console.log("User cancelled image picker")
65+
if (this.props.onCancel)
66+
this.props.onCancel("User cancelled image picker")
67+
return
68+
} else if (response.error) {
69+
console.log("ImagePicker Error: ", response.error)
70+
if (this.props.onError) this.props.onError(response.error)
71+
return
72+
} else if (response.customButton) {
73+
console.log(
74+
"User tapped custom button: ",
75+
response.customButton
76+
)
77+
if (this.props.onTapCustomButton)
78+
this.props.onTapCustomButton(response.customButton)
79+
return
80+
}
81+
82+
let { maxHeight, maxWidth, quality, format } = this.state
83+
84+
//Determining rotation param
85+
if (originalRotation === 90) {
86+
rotation = 90
87+
} else if (originalRotation === 180) {
88+
//For a few images rotation is 180.
89+
rotation = -180
90+
} else if (originalRotation === 270) {
91+
//When taking images with the front camera (selfie), the rotation is 270.
92+
rotation = -90
93+
}
94+
// resize image
95+
const resizedImageUri = await ImageResizer.createResizedImage(
96+
`data:image/jpeg;base64,${response.data}`,
97+
maxHeight,
98+
maxWidth,
99+
format,
100+
quality,
101+
rotation
102+
)
103+
104+
if (this.props.onResizedImageUri)
105+
this.props.onResizedImageUri(resizedImageUri)
106+
107+
const filePath =
108+
Platform.OS === "android" && resizedImageUri.uri.replace
109+
? resizedImageUri.uri.replace("file:/data", "/data")
110+
: resizedImageUri.uri
111+
112+
// convert image back to base64 string
113+
const photoData = await RNFS.readFile(filePath, "base64")
114+
let source = { uri: resizedImageUri.uri }
115+
this.setState({
116+
avatarSource: source
117+
})
118+
119+
// handle photo in props functions as data string
120+
if (this.props.onPhotoSelect) this.props.onPhotoSelect(photoData)
121+
})
122+
}
123+
124+
renderChildren = props => {
125+
return React.Children.map(props.children, child => {
126+
if (
127+
child &&
128+
child.type.displayName.includes("Image") &&
129+
this.state.avatarSource
130+
) {
131+
return React.cloneElement(child, {
132+
source: this.state.avatarSource
133+
})
134+
} else return child
135+
})
136+
}
137+
138+
componentDidUpdate() {
139+
if (this.props.onAfterRender) this.props.onAfterRender(this.state)
140+
}
141+
142+
render() {
143+
return (
144+
<View style={[styles.container, this.props.containerStyle]}>
145+
<TouchableOpacity
146+
onPress={this.openImagePicker}
147+
disabled={this.state.buttonDisabled}
148+
>
149+
{this.renderChildren(this.props)}
150+
</TouchableOpacity>
151+
</View>
152+
)
153+
}
144154
}
145155

146156
const styles = StyleSheet.create({
147-
container: {
148-
flex: 1,
149-
justifyContent: 'center',
150-
alignItems: 'center'
151-
}
157+
container: {
158+
flex: 1,
159+
justifyContent: "center",
160+
alignItems: "center"
161+
}
152162
})

0 commit comments

Comments
 (0)