diff options
| author | Ivan Chen <ivan@thetaggid.com> | 2020-12-08 23:17:23 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-12-08 23:17:23 -0500 |
| commit | 792115326fc6af583f422082537885bc8061d051 (patch) | |
| tree | c397e80a5573cd791c45cc006b36570efa91d73c /src/screens | |
| parent | 84616a6143fea58899eafa915a73592eaad25361 (diff) | |
[TMA-410] Edit Non-Integrated Socials (#126)
* removed refs, added KB avoidance, UI done
* missed some things
* now parsing response correctly from backend
* fixed naming
* now allow empty strings to un-link a social
* hide field if empty, allow empty string, fixed taggs bar not updating bug
* Fix bug where non integrated socials do not show up on edit profile page
Co-authored-by: Ashm Walia <40498934+ashmgarv@users.noreply.github.com>
Co-authored-by: Ashm Walia <ashmwalia@outlook.com>
Diffstat (limited to 'src/screens')
| -rw-r--r-- | src/screens/profile/EditProfile.tsx | 348 |
1 files changed, 195 insertions, 153 deletions
diff --git a/src/screens/profile/EditProfile.tsx b/src/screens/profile/EditProfile.tsx index ab58db41..97c58177 100644 --- a/src/screens/profile/EditProfile.tsx +++ b/src/screens/profile/EditProfile.tsx @@ -11,6 +11,9 @@ import { Alert, View, SafeAreaView, + KeyboardAvoidingView, + Platform, + Keyboard, } from 'react-native'; import {Button} from 'react-native-elements'; import { @@ -21,7 +24,6 @@ import { BirthDatePicker, TabsGradient, } from '../../components'; -import {OnboardingStackParams} from '../../routes/onboarding'; import ImagePicker from 'react-native-image-crop-picker'; import { EDIT_PROFILE_ENDPOINT, @@ -30,23 +32,21 @@ import { genderRegex, } from '../../constants'; import AsyncStorage from '@react-native-community/async-storage'; +import {ProfileStackParams} from '../../routes'; import Animated from 'react-native-reanimated'; import {HeaderHeight, SCREEN_HEIGHT} from '../../utils'; import {RootState} from '../../store/rootReducer'; import {useDispatch, useSelector} from 'react-redux'; import {loadUserData} from '../../store/actions'; -type ProfileOnboardingScreenRouteProp = RouteProp< - OnboardingStackParams, - 'ProfileOnboarding' +type EditProfileNavigationProp = StackNavigationProp< + ProfileStackParams, + 'EditProfile' >; -type ProfileOnboardingScreenNavigationProp = StackNavigationProp< - OnboardingStackParams, - 'ProfileOnboarding' ->; -interface ProfileOnboardingProps { - route: ProfileOnboardingScreenRouteProp; - navigation: ProfileOnboardingScreenNavigationProp; + +interface EditProfileProps { + route: RouteProp<ProfileStackParams, 'EditProfile'>; + navigation: EditProfileNavigationProp; } /** @@ -54,14 +54,11 @@ interface ProfileOnboardingProps { * @param navigation react-navigation navigation object */ -const ProfileOnboarding: React.FC<ProfileOnboardingProps> = ({ - route, - navigation, -}) => { +const EditProfile: React.FC<EditProfileProps> = ({route, navigation}) => { const y: Animated.Value<number> = Animated.useValue(0); const {userId, username} = route.params; const { - profile: {website, biography, birthday, gender}, + profile: {website, biography, birthday, gender, snapchat, tiktok}, avatar, cover, } = useSelector((state: RootState) => state.user); @@ -73,7 +70,8 @@ const ProfileOnboarding: React.FC<ProfileOnboardingProps> = ({ if (needsUpdate) { dispatch(loadUserData({userId, username})); } - }, [loadUserData, needsUpdate]); + + }, [dispatch, needsUpdate, userId, username]); const [isCustomGender, setIsCustomGender] = React.useState<boolean>( gender !== '' && gender !== 'female' && gender !== 'male', @@ -87,42 +85,15 @@ const ProfileOnboarding: React.FC<ProfileOnboardingProps> = ({ birthdate: birthday && moment(birthday).format('YYYY-MM-DD'), gender: isCustomGender ? 'custom' : gender, customGenderText: isCustomGender ? gender : '', + snapchat: snapchat, + tiktok: tiktok, isValidWebsite: true, isValidBio: true, isValidGender: true, + isValidSnapchat: true, + isValidTiktok: true, attemptedSubmit: false, }); - // refs for changing focus - const bioRef = React.useRef(); - const birthdateRef = React.useRef(); - const genderRef = React.useRef(); - const customGenderRef = React.useRef(); - /** - * Handles focus change to the next input field. - * @param field key for field to move focus onto - */ - const handleFocusChange = (field: string): void => { - switch (field) { - case 'bio': - const bioField: any = bioRef.current; - bioField.focus(); - break; - case 'birthdate': - const birthdateField: any = birthdateRef.current; - birthdateField.focus(); - break; - case 'gender': - const genderField: any = genderRef.current; - genderField.focus(); - break; - case 'customGender': - const customGenderField: any = customGenderRef.current; - customGenderField.focus(); - break; - default: - return; - } - }; /** * Profile screen "Add header image" button @@ -256,6 +227,24 @@ const ProfileOnboarding: React.FC<ProfileOnboardingProps> = ({ }); }; + const handleSnapchatUpdate = (newUsername: string) => { + // Allow any username, empty means to "un-link" it + // TODO: refresh taggs bar after + setForm({ + ...form, + snapchat: newUsername, + }); + }; + + const handleTikTokUpdate = (newUsername: string) => { + // Allow any username, empty means to "un-link" it + // TODO: refresh taggs bar after + setForm({ + ...form, + tiktok: newUsername, + }); + }; + const handleSubmit = useCallback(async () => { if (!form.largePic) { Alert.alert('Please select a Header image!'); @@ -325,6 +314,22 @@ const ProfileOnboarding: React.FC<ProfileOnboardingProps> = ({ } } + if (form.isValidSnapchat) { + request.append('snapchat', form.snapchat); + } else { + setForm({...form, attemptedSubmit: false}); + setTimeout(() => setForm({...form, attemptedSubmit: true})); + invalidFields = true; + } + + if (form.isValidTiktok) { + request.append('tiktok', form.tiktok); + } else { + setForm({...form, attemptedSubmit: false}); + setTimeout(() => setForm({...form, attemptedSubmit: true})); + invalidFields = true; + } + if (invalidFields) { return; } @@ -357,10 +362,7 @@ const ProfileOnboarding: React.FC<ProfileOnboardingProps> = ({ ); } } catch (error) { - Alert.alert( - 'Profile creation failed 😓', - 'Please double-check your network connection and retry.', - ); + Alert.alert('Please double-check your network connection and retry.'); return { name: 'Profile creation error', description: error, @@ -384,118 +386,158 @@ const ProfileOnboarding: React.FC<ProfileOnboardingProps> = ({ return ( <Background centered> <SafeAreaView> - <Animated.ScrollView - style={styles.container} - onScroll={(e) => y.setValue(e.nativeEvent.contentOffset.y)} - showsHorizontalScrollIndicator={false} - showsVerticalScrollIndicator={true} - scrollEventThrottle={1} - alwaysBounceVertical - contentContainerStyle={{paddingBottom: SCREEN_HEIGHT / 15}}> - <StatusBar barStyle="light-content" translucent={false} /> - <View - style={{ - position: 'relative', - alignSelf: 'center', - }}> - <View> - <View style={styles.profile}> - <LargeProfilePic /> - <SmallProfilePic /> - </View> - <View - style={{ - position: 'relative', - width: 280, - alignSelf: 'center', - }}> - <TaggInput - accessibilityHint="Enter a website." - accessibilityLabel="Website input field." - placeholder="Website" - autoCompleteType="off" - textContentType="URL" - autoCapitalize="none" - returnKeyType="next" - onChangeText={handleWebsiteUpdate} - onSubmitEditing={() => handleFocusChange('bio')} - blurOnSubmit={false} - valid={form.isValidWebsite} - attemptedSubmit={form.attemptedSubmit} - invalidWarning={ - 'Website must be a valid link to your website' - } - width={280} - value={form.website} - /> - <TaggBigInput - accessibilityHint="Enter a bio." - accessibilityLabel="Bio input field." - placeholder="Bio" - autoCompleteType="off" - textContentType="none" - autoCapitalize="none" - returnKeyType="next" - onChangeText={handleBioUpdate} - onSubmitEditing={() => handleFocusChange('bio')} - blurOnSubmit={false} - ref={bioRef} - valid={form.isValidBio} - attemptedSubmit={form.attemptedSubmit} - invalidWarning={ - 'Bio must be less than 150 characters and must contain valid characters' - } - width={280} - value={form.bio} - /> - <BirthDatePicker - ref={birthdateRef} - handleBDUpdate={handleBirthdateUpdate} - width={280} - date={form.birthdate} - showPresetdate={true} - /> - - <TaggDropDown - value={form.gender} - onValueChange={(value: string) => handleGenderUpdate(value)} - items={[ - {label: 'Male', value: 'male'}, - {label: 'Female', value: 'female'}, - {label: 'Custom', value: 'custom'}, - ]} - placeholder={{ - label: 'Gender', - value: null, - color: '#fff', - }} - /> - {isCustomGender && ( + <KeyboardAvoidingView + behavior={Platform.OS === 'ios' ? 'padding' : 'height'}> + <Animated.ScrollView + style={styles.container} + onScroll={(e) => y.setValue(e.nativeEvent.contentOffset.y)} + showsHorizontalScrollIndicator={false} + showsVerticalScrollIndicator={false} + scrollEventThrottle={1} + alwaysBounceVertical + contentContainerStyle={{paddingBottom: SCREEN_HEIGHT / 15}}> + <StatusBar barStyle="light-content" translucent={false} /> + <View + style={{ + position: 'relative', + alignSelf: 'center', + }}> + <View> + <View style={styles.profile}> + <LargeProfilePic /> + <SmallProfilePic /> + </View> + <View + style={{ + position: 'relative', + width: 280, + alignSelf: 'center', + }}> <TaggInput - style={styles.customGenderInput} - value={form.customGenderText} - accessibilityHint="Custom" - accessibilityLabel="Gender input field." - placeholder="Enter your gender" + accessibilityHint="Enter a website." + accessibilityLabel="Website input field." + placeholder="Website" + autoCompleteType="off" + textContentType="URL" + autoCapitalize="none" + returnKeyType="done" + onChangeText={handleWebsiteUpdate} + blurOnSubmit={false} + valid={form.isValidWebsite} + attemptedSubmit={form.attemptedSubmit} + invalidWarning={ + 'Website must be a valid link to your website' + } + width={280} + value={form.website} + /> + <TaggBigInput + accessibilityHint="Enter a bio." + accessibilityLabel="Bio input field." + placeholder="Bio" autoCompleteType="off" textContentType="none" autoCapitalize="none" returnKeyType="next" + onChangeText={handleBioUpdate} blurOnSubmit={false} - ref={customGenderRef} - onChangeText={handleCustomGenderUpdate} - onSubmitEditing={() => handleSubmit()} - valid={form.isValidGender} + valid={form.isValidBio} attemptedSubmit={form.attemptedSubmit} invalidWarning={ - 'Custom field can only contain letters and hyphens' + 'Bio must be less than 150 characters and must contain valid characters' } + width={280} + value={form.bio} + /> + <BirthDatePicker + handleBDUpdate={handleBirthdateUpdate} + width={280} + date={moment(form.birthdate).toDate()} + showPresetdate={true} + /> + + <TaggDropDown + value={form.gender} + onValueChange={(value: string) => handleGenderUpdate(value)} + items={[ + {label: 'Male', value: 'male'}, + {label: 'Female', value: 'female'}, + {label: 'Custom', value: 'custom'}, + ]} + placeholder={{ + label: 'Gender', + value: null, + color: '#fff', + }} /> - )} + {isCustomGender && ( + <TaggInput + accessibilityHint="Custom" + accessibilityLabel="Gender input field." + attemptedSubmit={form.attemptedSubmit} + autoCapitalize="none" + autoCompleteType="off" + blurOnSubmit={false} + invalidWarning={ + 'Custom field can only contain letters and hyphens' + } + onChangeText={handleCustomGenderUpdate} + onSubmitEditing={() => handleSubmit()} + placeholder="Enter your gender" + returnKeyType="done" + style={styles.customGenderInput} + textContentType="none" + valid={form.isValidGender} + value={form.customGenderText} + /> + )} + {snapchat !== '' && ( + <TaggInput + accessibilityHint="Snapchat Username" + accessibilityLabel="Snapchat Username Input Field." + attemptedSubmit={form.attemptedSubmit} + autoCapitalize="none" + autoCompleteType="off" + autoCorrect={false} + blurOnSubmit={false} + enablesReturnKeyAutomatically={true} + invalidWarning={'Please enter something!'} + onChangeText={handleSnapchatUpdate} + onSubmitEditing={Keyboard.dismiss} + placeholder="Snapchat Username" + returnKeyType="done" + textContentType="none" + valid={form.isValidSnapchat} + value={form.snapchat && form.snapchat} + width={280} + /> + )} + {tiktok !== '' && ( + <TaggInput + accessibilityHint="TikTok Username" + accessibilityLabel="TikTok Username Input Field." + attemptedSubmit={form.attemptedSubmit} + autoCapitalize="none" + autoCompleteType="off" + autoCorrect={false} + blurOnSubmit={false} + enablesReturnKeyAutomatically={true} + invalidWarning={'Please enter something!'} + onChangeText={handleTikTokUpdate} + onSubmitEditing={Keyboard.dismiss} + placeholder="TikTok Username" + returnKeyType="done" + textContentType="none" + valid={form.isValidTiktok} + value={form.tiktok} + width={280} + /> + )} + </View> </View> </View> - </View> - </Animated.ScrollView> + </Animated.ScrollView> + </KeyboardAvoidingView> </SafeAreaView> <TabsGradient /> </Background> @@ -585,4 +627,4 @@ const styles = StyleSheet.create({ }, }); -export default ProfileOnboarding; +export default EditProfile; |
