Created
August 25, 2022 01:43
-
-
Save arshadazaad3/c85169d0a340cca0a3458e90f0c7b60d to your computer and use it in GitHub Desktop.
React Native Image Upload With Action Sheet
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { useState } from "react"; | |
import { Platform, SafeAreaView, ScrollView, TouchableOpacity, View } from "react-native"; | |
import { Stack, Text, Actionsheet, Image } from "native-base"; | |
import DocumentPicker from "react-native-document-picker"; | |
import LinearGradient from "react-native-linear-gradient"; | |
import { scale } from "react-native-size-matters"; | |
import Toast from "react-native-toast-message"; | |
import PropTypes from "prop-types"; | |
/** | |
* Container to Upload Image | |
* @param {*} props | |
* @returns {React.FunctionComponent} | |
*/ | |
function ImageUploadWithActionSheet(props) { | |
// user data | |
const [formData, setFormData] = useState({}); | |
const [images, setImages] = useState({ | |
profilePictureUrl: null, | |
}); | |
// component state | |
const [screenLoading, setScreenLoading] = useState(0); | |
const [profilePictureActionSheet, setProfilePictureActionSheet] = useState(false); | |
** | |
* Image Picker Storage Handler | |
*/ | |
const handleGalleryOpen = async () => { | |
let selectedPic = await singleImagePicker(); | |
handleUploadImage(selectedPic); | |
}; | |
** | |
* Single Document Picker | |
*/ | |
const singleImagePicker = async () => { | |
try { | |
const res = await DocumentPicker.pick({ | |
type: [DocumentPicker.types.images], | |
}); | |
return res; | |
} catch (err) { | |
if (DocumentPicker.isCancel(err)) { | |
return null; | |
// User cancelled the picker, exit any dialogs or menus and move on | |
} else { | |
throw err; | |
} | |
} | |
}; | |
/** | |
* Build Form Data | |
* The attachment data is altered to ben sent to the backend | |
* @param {object} attachment | |
* @returns {FormData} | |
*/ | |
const buildFormData = (attachment) => { | |
const attachmentData = new FormData(); | |
attachmentData.append("file", { | |
name: attachment?.type?.substr(6), | |
type: attachment?.type, | |
uri: Platform.OS !== "android" ? "file://" + attachment?.uri : attachment?.uri, | |
}); | |
return attachmentData; | |
}; | |
/** | |
* Handle Upload Profile Picture | |
* @param {array} selectedPic - Selected Image From Storage | |
*/ | |
const handleUploadImage = async (selectedPic) => { | |
try { | |
setScreenLoading((prevState) => prevState + 1); | |
let isSuccess = false; | |
if (selectedPic && selectedPic.length > 0) { | |
selectedPic = selectedPic[0]; | |
if (formData.profilePictureUrl) { | |
const profilePictureImageData = buildFormData(selectedPic); | |
try { | |
const { data } = await updateAttachmentService(formData.profilePictureUrl, profilePictureImageData); | |
if (data && data.key) { | |
const response = await updateProfileService(formData._id, { | |
profilePictureUrl: data.key, | |
}); | |
if (response.data) { | |
updateLocalUser({ ...formData, ...response.data }); | |
setFormData({ ...formData, ...response.data }); | |
isSuccess = true; | |
} | |
} | |
} catch (e) { | |
console.log(e); | |
Toast.show(TOAST_STYLES("error", "Error", `Something went wrong`)); | |
} | |
} else { | |
const profilePictureImageData = buildFormData(selectedPic); | |
try { | |
const { data } = await createAttachmentService(profilePictureImageData); | |
if (data && data.key) { | |
const response = await updateProfileService(formData._id, { | |
profilePictureUrl: data.key, | |
}); | |
if (response.data) { | |
updateLocalUser({ ...formData, ...response.data }); | |
setFormData({ ...formData, ...response.data }); | |
isSuccess = true; | |
} | |
} | |
} catch (e) { | |
console.log(e); | |
Toast.show(TOAST_STYLES("error", "Error", `Something went wrong`)); | |
} | |
} | |
} | |
if (isSuccess) { | |
Toast.show( | |
TOAST_STYLES( | |
"success", | |
"Success", | |
`Successfully ${formData.profilePictureUrl ? "updated" : "saved"} profile picture ` | |
) | |
); | |
} | |
} catch (e) { | |
console.log(e); | |
Toast.show(TOAST_STYLES("error", "Error", `Something Went Wrong`)); | |
} | |
setScreenLoading((prevState) => prevState - 1); | |
}; | |
/** | |
* Open Camera Component | |
*/ | |
const handleCameraOpenForProfilePicture = async () => { | |
setProfilePictureActionSheet(false); | |
setIsCameraActive(true); | |
setCameraType("profile-picture"); | |
}; | |
/** JSX */ | |
return ( | |
<> | |
<SafeAreaView> | |
<ScrollView> | |
<Stack> | |
<LinearGradient locations={[0.2, 0.7, 1]} colors={["#eb9214", "#e89623", "#e6a20e"]}> | |
<Stack> | |
<TouchableOpacity onPress={() => setProfilePictureActionSheet(true)}> | |
{images.profilePictureUrl ? ( | |
<Image | |
alt="Profile Image" | |
source={{ | |
uri: images.profilePictureUrl, | |
}} | |
/> | |
) : ( | |
<View | |
style={{ | |
backgroundColor: "#364f6b", | |
width: scale(70), | |
height: scale(70), | |
borderRadius: 100 / 2, | |
marginTop: 10, | |
borderColor: "#364f6b", | |
}}> | |
<Text fontSize="2xl" color="#FFF"> | |
{formData.fullName} | |
</Text> | |
</View> | |
)} | |
</TouchableOpacity> | |
</Stack> | |
</LinearGradient> | |
</Stack> | |
</ScrollView> | |
</SafeAreaView> | |
<Actionsheet isOpen={profilePictureActionSheet} onClose={() => setProfilePictureActionSheet(false)}> | |
<Actionsheet.Content> | |
<Actionsheet.Item onPress={handleGalleryOpen}>Open Gallery</Actionsheet.Item> | |
<Actionsheet.Item onPress={handleCameraOpenForProfilePicture}>Open Camera</Actionsheet.Item> | |
</Actionsheet.Content> | |
</Actionsheet> | |
</> | |
); | |
} | |
ImageUploadWithActionSheet.propTypes = { | |
authState: PropTypes.shape({ | |
user: PropTypes.object, | |
}), | |
}; | |
export default ImageUploadWithActionSheet; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment