Skip to content

Instantly share code, notes, and snippets.

@arshadazaad3
Created August 25, 2022 01:43
Show Gist options
  • Save arshadazaad3/c85169d0a340cca0a3458e90f0c7b60d to your computer and use it in GitHub Desktop.
Save arshadazaad3/c85169d0a340cca0a3458e90f0c7b60d to your computer and use it in GitHub Desktop.
React Native Image Upload With Action Sheet
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