diff options
-rw-r--r-- | ios/Frontend.xcodeproj/project.pbxproj | 42 | ||||
-rw-r--r-- | ios/Podfile.lock | 16 | ||||
-rw-r--r-- | package.json | 1 | ||||
-rw-r--r-- | src/routes/Routes.tsx | 7 | ||||
-rw-r--r-- | src/screens/onboarding/Camera.tsx | 28 | ||||
-rw-r--r-- | src/screens/onboarding/Profile.tsx | 135 | ||||
-rw-r--r-- | src/screens/onboarding/Verification.tsx | 5 | ||||
-rw-r--r-- | src/screens/onboarding/index.ts | 1 | ||||
-rw-r--r-- | yarn.lock | 5 |
9 files changed, 183 insertions, 57 deletions
diff --git a/ios/Frontend.xcodeproj/project.pbxproj b/ios/Frontend.xcodeproj/project.pbxproj index d49d2fb2..03406070 100644 --- a/ios/Frontend.xcodeproj/project.pbxproj +++ b/ios/Frontend.xcodeproj/project.pbxproj @@ -208,6 +208,7 @@ 00E356EA1AD99517003FC87E /* Sources */, 00E356EB1AD99517003FC87E /* Frameworks */, 00E356EC1AD99517003FC87E /* Resources */, + 6052DFFE4C25A50B464D7EDD /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -229,6 +230,7 @@ 13B07F8C1A680F5B00A75B9A /* Frameworks */, 13B07F8E1A680F5B00A75B9A /* Resources */, 00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */, + 5F19A5045F2557A3A7A71AA2 /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -456,6 +458,46 @@ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; + 5F19A5045F2557A3A7A71AA2 /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Frontend/Pods-Frontend-resources.sh", + "${PODS_CONFIGURATION_BUILD_DIR}/RNImageCropPicker/QBImagePicker.bundle", + "${PODS_CONFIGURATION_BUILD_DIR}/TOCropViewController/TOCropViewControllerBundle.bundle", + ); + name = "[CP] Copy Pods Resources"; + outputPaths = ( + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/QBImagePicker.bundle", + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/TOCropViewControllerBundle.bundle", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Frontend/Pods-Frontend-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; + 6052DFFE4C25A50B464D7EDD /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Frontend-FrontendTests/Pods-Frontend-FrontendTests-resources.sh", + "${PODS_CONFIGURATION_BUILD_DIR}/RNImageCropPicker/QBImagePicker.bundle", + "${PODS_CONFIGURATION_BUILD_DIR}/TOCropViewController/TOCropViewControllerBundle.bundle", + ); + name = "[CP] Copy Pods Resources"; + outputPaths = ( + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/QBImagePicker.bundle", + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/TOCropViewControllerBundle.bundle", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Frontend-FrontendTests/Pods-Frontend-FrontendTests-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; 7BCEB0E5F3DB51ADCE257331 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; diff --git a/ios/Podfile.lock b/ios/Podfile.lock index fcff1410..061a9b9d 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -300,10 +300,20 @@ PODS: - React - RNGestureHandler (1.6.1): - React + - RNImageCropPicker (0.32.2): + - React-Core + - React-RCTImage + - RNImageCropPicker/QBImagePickerController (= 0.32.2) + - TOCropViewController + - RNImageCropPicker/QBImagePickerController (0.32.2): + - React-Core + - React-RCTImage + - TOCropViewController - RNReanimated (1.9.0): - React - RNScreens (2.9.0): - React + - TOCropViewController (2.5.3) - Yoga (1.14.0) - YogaKit (1.18.1): - Yoga (~> 1.14) @@ -359,6 +369,7 @@ DEPENDENCIES: - ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`) - "RNCMaskedView (from `../node_modules/@react-native-community/masked-view`)" - RNGestureHandler (from `../node_modules/react-native-gesture-handler`) + - RNImageCropPicker (from `../node_modules/react-native-image-crop-picker`) - RNReanimated (from `../node_modules/react-native-reanimated`) - RNScreens (from `../node_modules/react-native-screens`) - Yoga (from `../node_modules/react-native/ReactCommon/yoga`) @@ -376,6 +387,7 @@ SPEC REPOS: - Flipper-RSocket - FlipperKit - OpenSSL-Universal + - TOCropViewController - YogaKit EXTERNAL SOURCES: @@ -435,6 +447,8 @@ EXTERNAL SOURCES: :path: "../node_modules/@react-native-community/masked-view" RNGestureHandler: :path: "../node_modules/react-native-gesture-handler" + RNImageCropPicker: + :path: "../node_modules/react-native-image-crop-picker" RNReanimated: :path: "../node_modules/react-native-reanimated" RNScreens: @@ -482,8 +496,10 @@ SPEC CHECKSUMS: ReactCommon: ed4e11d27609d571e7eee8b65548efc191116eb3 RNCMaskedView: 5a8ec07677aa885546a0d98da336457e2bea557f RNGestureHandler: 8f09cd560f8d533eb36da5a6c5a843af9f056b38 + RNImageCropPicker: f0557a908758c4a3f83978894ec7227651529b45 RNReanimated: b5ccb50650ba06f6e749c7c329a1bc3ae0c88b43 RNScreens: c526239bbe0e957b988dacc8d75ac94ec9cb19da + TOCropViewController: 20a14b6a7a098308bf369e7c8d700dc983a974e6 Yoga: 3ebccbdd559724312790e7742142d062476b698e YogaKit: f782866e155069a2cca2517aafea43200b01fd5a diff --git a/package.json b/package.json index 142bde68..64647d18 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ "react-native-animatable": "^1.3.3", "react-native-confirmation-code-field": "^6.5.0", "react-native-gesture-handler": "^1.6.1", + "react-native-image-crop-picker": "^0.32.2", "react-native-linear-gradient": "^2.5.6", "react-native-reanimated": "^1.9.0", "react-native-safe-area-context": "^3.0.6", diff --git a/src/routes/Routes.tsx b/src/routes/Routes.tsx index c6365613..93c16fc9 100644 --- a/src/routes/Routes.tsx +++ b/src/routes/Routes.tsx @@ -6,7 +6,6 @@ import { Registration, Verification, Profile, - Camera, } from '../screens/onboarding'; export type RootStackParamList = { @@ -14,7 +13,6 @@ export type RootStackParamList = { Registration: undefined; Verification: {username: string; email: string} | undefined; Profile: undefined; - Camera: undefined; }; const RootStack = createStackNavigator<RootStackParamList>(); @@ -44,11 +42,6 @@ const Routes: React.FC<RoutesProps> = ({}) => { component={Profile} options={{headerShown: false}} /> - <RootStack.Screen - name="Camera" - component={Camera} - options={{headerShown: false}} - /> </RootStack.Navigator> ); }; diff --git a/src/screens/onboarding/Camera.tsx b/src/screens/onboarding/Camera.tsx deleted file mode 100644 index 23776e2d..00000000 --- a/src/screens/onboarding/Camera.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import React from 'react'; -import {RouteProp} from '@react-navigation/native'; -import {StackNavigationProp} from '@react-navigation/stack'; -import {RootStackParamList} from '../../routes'; -import {Background, CenteredView} from '../../components'; -import {Text} from 'react-native-animatable'; - -type CameraScreenRouteProp = RouteProp<RootStackParamList, 'Camera'>; -type CameraScreenNavigationProp = StackNavigationProp< - RootStackParamList, - 'Camera' ->; -interface CameraProps { - route: CameraScreenRouteProp; - navigation: CameraScreenNavigationProp; -} - -const Camera: React.FC<CameraProps> = ({}) => { - return ( - <Background> - <CenteredView> - <Text>Camera!</Text> - </CenteredView> - </Background> - ); -}; - -export default Camera; diff --git a/src/screens/onboarding/Profile.tsx b/src/screens/onboarding/Profile.tsx index 9b1dfd31..cb4a2728 100644 --- a/src/screens/onboarding/Profile.tsx +++ b/src/screens/onboarding/Profile.tsx @@ -1,9 +1,17 @@ import React from 'react'; import {RouteProp} from '@react-navigation/native'; import {StackNavigationProp} from '@react-navigation/stack'; -import {View, Text, StatusBar, StyleSheet} from 'react-native'; +import { + View, + Text, + StatusBar, + StyleSheet, + Image, + TouchableOpacity, +} from 'react-native'; import {RootStackParamList} from '../../routes'; -import {Background, CenteredView} from '../../components'; +import {Background} from '../../components'; +import ImagePicker from 'react-native-image-crop-picker'; type ProfileScreenRouteProp = RouteProp<RootStackParamList, 'Profile'>; type ProfileScreenNavigationProp = StackNavigationProp< @@ -14,25 +22,50 @@ interface ProfileProps { route: ProfileScreenRouteProp; navigation: ProfileScreenNavigationProp; } + /** * Create Profile screen for onboarding. * @param navigation react-navigation navigation object. */ -const Profile: React.FC<ProfileProps> = ({navigation}) => { +const Profile: React.FC<ProfileProps> = ({}) => { + const [largePicture, setLargePicture] = React.useState({ + path: '', + height: 0, + width: 0, + }); + const [smallPicture, setSmallPicture] = React.useState({ + path: '', + height: 0, + width: 0, + }); + const [showLargeText, setShowLargeText] = React.useState(true); + const [showSmallText, setShowSmallText] = React.useState(true); + /** * Profile screen "Add Large Profile Pic Here" button */ const LargeProfilePic = () => ( <View style={styles.container}> <View style={styles.largeButton}> - <Text + <TouchableOpacity accessible={true} accessibilityLabel="ADD LARGE PROFILE PIC HERE" - style={styles.addLargeProfilePicText} - onPress={goToCamera}> - ADD LARGE PROFILE PIC HERE - </Text> + onPress={goToGalleryLargePic} + style={styles.largeButtonContainer}> + {showLargeText ? ( + <Text style={styles.addLargeProfilePicText}> + ADD LARGE PROFILE PIC HERE + </Text> + ) : null} + + {largePicture.path !== '' && ( + <Image + source={{uri: largePicture.path}} + style={styles.largeProfilePic} + /> + )} + </TouchableOpacity> </View> </View> ); @@ -43,31 +76,78 @@ const Profile: React.FC<ProfileProps> = ({navigation}) => { const SmallProfilePic = () => ( <View style={styles.container}> <View style={styles.smallButton}> - <Text + <TouchableOpacity accessible={true} accessibilityLabel="ADD SMALLER PIC" - style={styles.addSmallProfilePicText} - onPress={goToCamera}> - ADD SMALLER PIC - </Text> + onPress={goToGallerySmallPic}> + {showSmallText ? ( + <Text style={styles.addSmallProfilePicText}>ADD SMALLER PIC</Text> + ) : null} + + {smallPicture.path !== '' && ( + <Image + source={{uri: smallPicture.path}} + style={styles.smallProfilePic} + /> + )} + </TouchableOpacity> </View> </View> ); /* * Handles tap on add profile picture buttons by navigating to camera access + * and selecting a picture from gallery for large profile picture + */ + const goToGalleryLargePic = () => { + ImagePicker.openPicker({ + width: 580, + height: 580, + cropping: true, + cropperCircleOverlay: true, + }) + .then((picture) => { + if ('path' in picture) { + setLargePicture({ + path: picture.path, + height: picture.height, + width: picture.width, + }); + setShowLargeText(false); + } + }) + .catch(() => {}); + }; + + /* + * Handles tap on add profile picture buttons by navigating to camera access + * and selecting a picture from gallery for small profile picture */ - const goToCamera = () => { - navigation.navigate('Camera'); + const goToGallerySmallPic = () => { + ImagePicker.openPicker({ + width: 580, + height: 580, + cropping: true, + cropperCircleOverlay: true, + }) + .then((picture) => { + if ('path' in picture) { + setSmallPicture({ + path: picture.path, + height: picture.height, + width: picture.width, + }); + setShowSmallText(false); + } + }) + .catch(() => {}); }; return ( <Background> <StatusBar barStyle="light-content" /> - <CenteredView> - <LargeProfilePic /> - <SmallProfilePic /> - </CenteredView> + <LargeProfilePic /> + <SmallProfilePic /> </Background> ); }; @@ -79,13 +159,17 @@ const styles = StyleSheet.create({ justifyContent: 'center', alignItems: 'center', }, + largeButtonContainer: { + flex: 1, + justifyContent: 'center', + }, largeButton: { padding: 5, height: 180, width: 180, borderRadius: 400, backgroundColor: '#fff', - justifyContent: 'center', + alignItems: 'center', marginTop: '100%', marginRight: '12%', zIndex: 2, @@ -97,6 +181,11 @@ const styles = StyleSheet.create({ color: '#863FF9', textAlign: 'center', }, + largeProfilePic: { + height: 180, + width: 180, + borderRadius: 400, + }, smallButton: { position: 'relative', padding: 5, @@ -105,6 +194,7 @@ const styles = StyleSheet.create({ borderRadius: 400, backgroundColor: '#E1F0FF', justifyContent: 'center', + alignItems: 'center', zIndex: 1, marginTop: '128%', marginLeft: '30%', @@ -116,6 +206,11 @@ const styles = StyleSheet.create({ color: '#806DF4', textAlign: 'center', }, + smallProfilePic: { + height: 110, + width: 110, + borderRadius: 400, + }, }); export default Profile; diff --git a/src/screens/onboarding/Verification.tsx b/src/screens/onboarding/Verification.tsx index 1c456e01..77a43a6d 100644 --- a/src/screens/onboarding/Verification.tsx +++ b/src/screens/onboarding/Verification.tsx @@ -90,7 +90,10 @@ const Verification: React.FC<VerificationProps> = ({route, navigation}) => { let sendOtpStatusCode = sendOtpResponse.status; if (sendOtpStatusCode === 200) { setValue(''); - Alert.alert('New verification code sent!', 'Check your email for your code.'); + Alert.alert( + 'New verification code sent!', + 'Check your email for your code.', + ); } else { Alert.alert('Something went wrong!'); } diff --git a/src/screens/onboarding/index.ts b/src/screens/onboarding/index.ts index a45daa5d..919ad7fd 100644 --- a/src/screens/onboarding/index.ts +++ b/src/screens/onboarding/index.ts @@ -1,5 +1,4 @@ export {default as Login} from './Login'; export {default as Registration} from './Registration'; export {default as Verification} from './Verification'; -export {default as Camera} from './Camera'; export {default as Profile} from './Profile'; @@ -5114,6 +5114,11 @@ react-native-gesture-handler@^1.6.1: invariant "^2.2.4" prop-types "^15.7.2" +react-native-image-crop-picker@^0.32.2: + version "0.32.2" + resolved "https://registry.yarnpkg.com/react-native-image-crop-picker/-/react-native-image-crop-picker-0.32.2.tgz#862bddc99f7a8e17b7f584846a0c46bfad233917" + integrity sha512-x1rwdpVKL6v1AY38rLNYUkLEJIxOK/3C8ipmNbcYFUKunVcmsEvhGLX2ll9kMjp/q+vGOmx4YO38eGp0axYoxg== + react-native-iphone-x-helper@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/react-native-iphone-x-helper/-/react-native-iphone-x-helper-1.2.1.tgz#645e2ffbbb49e80844bb4cbbe34a126fda1e6772" |