diff options
author | Ivan Chen <ivan@tagg.id> | 2021-03-29 17:36:21 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-03-29 17:36:21 -0400 |
commit | e7865305f77f801dd5f1c06c506c626192877fd8 (patch) | |
tree | 3ed42fb2a394eb3a8dd5fa1dadd5881ea87eb7cd | |
parent | ad2ad5d232473d38426c2f0f8283ba015dadfd4c (diff) | |
parent | e8d862e5e6dd8a6a517a93c65e30795813af936d (diff) |
Merge pull request #304 from TaggiD-Inc/tma-700-private-account-toggle
[TMA 700] : Private Account toggle + Settings Screen
38 files changed, 557 insertions, 12 deletions
diff --git a/src/assets/images/blocked-white@3x.png b/src/assets/images/blocked-white@3x.png Binary files differnew file mode 100644 index 00000000..06eeb651 --- /dev/null +++ b/src/assets/images/blocked-white@3x.png diff --git a/src/assets/images/edit-profile@3x.png b/src/assets/images/edit-profile@3x.png Binary files differnew file mode 100644 index 00000000..8ba76b18 --- /dev/null +++ b/src/assets/images/edit-profile@3x.png diff --git a/src/assets/images/privacypolicy@3x.png b/src/assets/images/privacypolicy@3x.png Binary files differnew file mode 100644 index 00000000..aa3402b2 --- /dev/null +++ b/src/assets/images/privacypolicy@3x.png diff --git a/src/assets/images/settings/blocked-white.png b/src/assets/images/settings/blocked-white.png Binary files differnew file mode 100644 index 00000000..ec3750af --- /dev/null +++ b/src/assets/images/settings/blocked-white.png diff --git a/src/assets/images/settings/blocked-white@2x.png b/src/assets/images/settings/blocked-white@2x.png Binary files differnew file mode 100644 index 00000000..1f39ba06 --- /dev/null +++ b/src/assets/images/settings/blocked-white@2x.png diff --git a/src/assets/images/settings/edit-profile.png b/src/assets/images/settings/edit-profile.png Binary files differnew file mode 100644 index 00000000..c096a32a --- /dev/null +++ b/src/assets/images/settings/edit-profile.png diff --git a/src/assets/images/settings/edit-profile@2x.png b/src/assets/images/settings/edit-profile@2x.png Binary files differnew file mode 100644 index 00000000..4753e0a3 --- /dev/null +++ b/src/assets/images/settings/edit-profile@2x.png diff --git a/src/assets/images/settings/lock-white.png b/src/assets/images/settings/lock-white.png Binary files differnew file mode 100644 index 00000000..04a0a55d --- /dev/null +++ b/src/assets/images/settings/lock-white.png diff --git a/src/assets/images/settings/lock-white@2x.png b/src/assets/images/settings/lock-white@2x.png Binary files differnew file mode 100644 index 00000000..b1927922 --- /dev/null +++ b/src/assets/images/settings/lock-white@2x.png diff --git a/src/assets/images/settings/lock-white@3x.png b/src/assets/images/settings/lock-white@3x.png Binary files differnew file mode 100644 index 00000000..da9ac212 --- /dev/null +++ b/src/assets/images/settings/lock-white@3x.png diff --git a/src/assets/images/settings/privacypolicy.png b/src/assets/images/settings/privacypolicy.png Binary files differnew file mode 100644 index 00000000..47792a3d --- /dev/null +++ b/src/assets/images/settings/privacypolicy.png diff --git a/src/assets/images/settings/privacypolicy@2x.png b/src/assets/images/settings/privacypolicy@2x.png Binary files differnew file mode 100644 index 00000000..31a1aeb2 --- /dev/null +++ b/src/assets/images/settings/privacypolicy@2x.png diff --git a/src/assets/images/settings/settings-white.png b/src/assets/images/settings/settings-white.png Binary files differnew file mode 100644 index 00000000..f571e4b0 --- /dev/null +++ b/src/assets/images/settings/settings-white.png diff --git a/src/assets/images/settings/settings-white@2x.png b/src/assets/images/settings/settings-white@2x.png Binary files differnew file mode 100644 index 00000000..6d59c672 --- /dev/null +++ b/src/assets/images/settings/settings-white@2x.png diff --git a/src/assets/images/settings/settings-white@3x.png b/src/assets/images/settings/settings-white@3x.png Binary files differnew file mode 100644 index 00000000..0019b29c --- /dev/null +++ b/src/assets/images/settings/settings-white@3x.png diff --git a/src/assets/images/settings/settings.png b/src/assets/images/settings/settings.png Binary files differnew file mode 100644 index 00000000..7445b8bf --- /dev/null +++ b/src/assets/images/settings/settings.png diff --git a/src/assets/images/settings/settings@2x.png b/src/assets/images/settings/settings@2x.png Binary files differnew file mode 100644 index 00000000..8a152c70 --- /dev/null +++ b/src/assets/images/settings/settings@2x.png diff --git a/src/assets/images/settings/termsofuse.png b/src/assets/images/settings/termsofuse.png Binary files differnew file mode 100644 index 00000000..82e90148 --- /dev/null +++ b/src/assets/images/settings/termsofuse.png diff --git a/src/assets/images/settings/termsofuse@2x.png b/src/assets/images/settings/termsofuse@2x.png Binary files differnew file mode 100644 index 00000000..5e0fe642 --- /dev/null +++ b/src/assets/images/settings/termsofuse@2x.png diff --git a/src/assets/images/settings/white-arrow.png b/src/assets/images/settings/white-arrow.png Binary files differnew file mode 100644 index 00000000..7c60d262 --- /dev/null +++ b/src/assets/images/settings/white-arrow.png diff --git a/src/assets/images/settings/white-arrow@2x.png b/src/assets/images/settings/white-arrow@2x.png Binary files differnew file mode 100644 index 00000000..13cce59a --- /dev/null +++ b/src/assets/images/settings/white-arrow@2x.png diff --git a/src/assets/images/settings/white-arrow@3x.png b/src/assets/images/settings/white-arrow@3x.png Binary files differnew file mode 100644 index 00000000..48ed872a --- /dev/null +++ b/src/assets/images/settings/white-arrow@3x.png diff --git a/src/assets/images/settings@3x.png b/src/assets/images/settings@3x.png Binary files differnew file mode 100644 index 00000000..4844d30f --- /dev/null +++ b/src/assets/images/settings@3x.png diff --git a/src/assets/images/termsofuse@3x.png b/src/assets/images/termsofuse@3x.png Binary files differnew file mode 100644 index 00000000..7d253196 --- /dev/null +++ b/src/assets/images/termsofuse@3x.png diff --git a/src/components/profile/ProfileMoreInfoDrawer.tsx b/src/components/profile/ProfileMoreInfoDrawer.tsx index a77a2e84..f70f90d0 100644 --- a/src/components/profile/ProfileMoreInfoDrawer.tsx +++ b/src/components/profile/ProfileMoreInfoDrawer.tsx @@ -3,7 +3,6 @@ import React from 'react'; import {Alert, Image, StyleSheet, TouchableOpacity} from 'react-native'; import {useSelector} from 'react-redux'; import MoreIcon from '../../assets/icons/more_horiz-24px.svg'; -import PersonOutline from '../../assets/ionicons/person-outline.svg'; import {TAGG_DARK_BLUE, TAGG_LIGHT_BLUE} from '../../constants'; import {ERROR_ATTEMPT_EDIT_SP} from '../../constants/strings'; import {RootState} from '../../store/rootreducer'; @@ -29,21 +28,19 @@ const ProfileMoreInfoDrawer: React.FC<ProfileMoreInfoDrawerProps> = (props) => { const isOwnProfile = !userXId || userXName === username; const goToEditProfile = () => { - navigation.push('EditProfile', { + navigation.navigate('EditProfile', { userId: userId, username: username, }); setIsOpen(false); }; - const goToUpdateSPProfile = () => { + const goToSettingsPage = () => { if (profile.suggested_people_linked === 0) { Alert.alert(ERROR_ATTEMPT_EDIT_SP); } else { // Sending undefined for updatedSelectedBadges to mark that there was no update yet - navigation.push('UpdateSPPicture', { - editing: true, - }); + navigation.navigate('SettingsScreen'); setIsOpen(false); } }; @@ -81,14 +78,21 @@ const ProfileMoreInfoDrawer: React.FC<ProfileMoreInfoDrawerProps> = (props) => { textColor={'black'} buttons={[ [ - 'Edit Suggested', - goToUpdateSPProfile, + 'Settings', + goToSettingsPage, <Image - source={require('../../assets/ionicons/suggested-outlined.png')} + source={require('../../assets/images/settings/settings.png')} + style={styles.image} + />, + ], + [ + 'Edit Profile', + goToEditProfile, + <Image + source={require('../../assets/images/settings/edit-profile.png')} style={styles.image} />, ], - ['Edit Profile', goToEditProfile, <PersonOutline color="black" />], ]} /> )} diff --git a/src/constants/api.ts b/src/constants/api.ts index 6afdf384..22890c33 100644 --- a/src/constants/api.ts +++ b/src/constants/api.ts @@ -64,3 +64,7 @@ export const DEEPLINK: string = 'https://tinyurl.com/y3o4aec5'; export const LINK_IG_OAUTH: string = `https://www.instagram.com/oauth/authorize/?client_id=205466150510738&redirect_uri=${DEEPLINK}&scope=user_profile,user_media&response_type=code`; export const LINK_FB_OAUTH: string = `https://www.facebook.com/v8.0/dialog/oauth?client_id=1308555659343609&redirect_uri=${DEEPLINK}&scope=user_posts,public_profile&response_type=code`; export const LINK_TWITTER_OAUTH: string = API_URL + 'link-twitter-request/'; + +// Profile Links +export const COMMUNITY_GUIDELINES: string = 'https://www.tagg.id/community-guidelines'; +export const PRIVACY_POLICY: string = 'https://www.tagg.id/privacy-policy'; diff --git a/src/constants/constants.ts b/src/constants/constants.ts index d24e352e..f533563d 100644 --- a/src/constants/constants.ts +++ b/src/constants/constants.ts @@ -186,3 +186,55 @@ export const SP_WIDTH = 375; export const SP_HEIGHT = 812; export const SP_PAGE_SIZE = 5; + +export const SETTINGS_DATA = { + SettingsAndPrivacy: [ + { + title: 'ACCOUNT', + data: [ + { + title: 'Suggested People Profile', + preimage: require('../assets/images/tagg-logo.png'), + postimage: require('../assets/images/settings/white-arrow.png'), + }, + { + title: 'Privacy', + preimage: require('../assets/images/settings/settings-white.png'), + postimage: require('../assets/images/settings/white-arrow.png'), + }, + ], + }, + { + title: 'GENERAL', + data: [ + { + title: 'Community Guidelines', + preimage: require('../assets/images/settings/termsofuse.png'), + postimage: require('../assets/images/settings/white-arrow.png'), + }, + { + title: 'Privacy Policy', + preimage: require('../assets/images/settings/privacypolicy.png'), + postimage: require('../assets/images/settings/white-arrow.png'), + }, + ], + }, + ], + PrivacyScreen: [ + { + title: '', + data: [ + { + title: 'Account Type', + preimage: require('../assets/images/settings/lock-white.png'), + postimage: require('../assets/images/settings/white-arrow.png'), + }, + // { + // title: 'Blocked Accounts', + // preimage: require('../assets/images/settings/blocked-white.png'), + // postimage: require('../assets/images/settings/white-arrow.png'), + // }, + ], + }, + ], +}; diff --git a/src/constants/strings.ts b/src/constants/strings.ts index 019d0bea..4f792dcc 100644 --- a/src/constants/strings.ts +++ b/src/constants/strings.ts @@ -31,6 +31,7 @@ export const ERROR_NEXT_PAGE = 'There was a problem while loading the next page export const ERROR_NOT_ONBOARDED = 'You are now on waitlist, please enter your invitation code if you have one'; export const ERROR_PHONE_IN_USE = 'Phone already in use, please try another one'; export const ERROR_PROFILE_CREATION_SHORT = 'Profile creation failed 😓'; +export const ERROR_PROFILE_UPDATE_SHORT = 'Profile update failed. 😔'; export const ERROR_PWD_ACCOUNT = (str: string) => `Please make sure that the email / username entered is registered with us. You may contact our customer support at ${str}`; export const ERROR_REGISTRATION = (str: string) => `Registration failed 😔, ${str}`; export const ERROR_SELECT_BIRTHDAY = 'Please select your birthday'; diff --git a/src/routes/main/MainStackNavigator.tsx b/src/routes/main/MainStackNavigator.tsx index 26d9943b..4563ec95 100644 --- a/src/routes/main/MainStackNavigator.tsx +++ b/src/routes/main/MainStackNavigator.tsx @@ -28,6 +28,9 @@ export type MainStackParams = { userXId: string | undefined; screenType: ScreenType; }; + SettingsScreen: {}; + PrivacyScreen: {}; + AccountTypeScreen: {}; SocialMediaTaggs: { socialMediaType: string; userXId: string | undefined; diff --git a/src/routes/main/MainStackScreen.tsx b/src/routes/main/MainStackScreen.tsx index 8cefd3cc..d855f0df 100644 --- a/src/routes/main/MainStackScreen.tsx +++ b/src/routes/main/MainStackScreen.tsx @@ -6,6 +6,7 @@ import {StyleSheet, Text} from 'react-native'; import {normalize} from 'react-native-elements'; import BackIcon from '../../assets/icons/back-arrow.svg'; import { + AccountType, AnimatedTutorial, BadgeSelection, CaptionScreen, @@ -20,12 +21,14 @@ import { MomentUploadPromptScreen, NotificationsScreen, ProfileScreen, + PrivacyScreen, RequestContactsAccess, SearchScreen, SocialMediaTaggs, SuggestedPeopleScreen, SuggestedPeopleUploadPictureScreen, SuggestedPeopleWelcomeScreen, + SettingsScreen, } from '../../screens'; import MutualBadgeHolders from '../../screens/suggestedPeople/MutualBadgeHolders'; import {ScreenType} from '../../types'; @@ -151,6 +154,27 @@ const MainStackScreen: React.FC<MainStackProps> = ({route}) => { }} /> <MainStack.Screen + name="SettingsScreen" + component={SettingsScreen} + options={{ + ...headerBarOptions('white', 'Settings and Privacy'), + }} + /> + <MainStack.Screen + name="PrivacyScreen" + component={PrivacyScreen} + options={{ + ...headerBarOptions('white', 'Privacy'), + }} + /> + <MainStack.Screen + name="AccountTypeScreen" + component={AccountType} + options={{ + ...headerBarOptions('white', 'Account Type'), + }} + /> + <MainStack.Screen name="AnimatedTutorial" component={AnimatedTutorial} options={{ diff --git a/src/screens/profile/AccountType.tsx b/src/screens/profile/AccountType.tsx new file mode 100644 index 00000000..60ed0668 --- /dev/null +++ b/src/screens/profile/AccountType.tsx @@ -0,0 +1,124 @@ +import React, {useState} from 'react'; +import { + ActivityIndicator, + StatusBar, + StyleSheet, + Switch, + Text, + View, +} from 'react-native'; +import {SafeAreaView} from 'react-native-safe-area-context'; +import {useDispatch, useSelector} from 'react-redux'; +import {Background} from '../../components'; +import {updateProfileVisibility} from '../../services'; +import {NO_PROFILE} from '../../store/initialStates'; +import {RootState} from '../../store/rootReducer'; +import {BackgroundGradientType} from '../../types'; +import {getTokenOrLogout} from '../../utils'; +import {normalize} from '../../utils/layouts'; + +const AccountType: React.FC = () => { + const [isPrivateAccount, setIsPrivateAccount] = useState(false); + const [isLoading, setIsLoading] = useState(false); + const { + user: {userId, username}, + profile: {is_private} = NO_PROFILE, + } = useSelector((state: RootState) => state.user); + + const dispatch = useDispatch(); + + const updateAccountVisibility = async () => { + setIsLoading(true); + const isPrivate = !isPrivateAccount; + setIsPrivateAccount(isPrivate); + const token = await getTokenOrLogout(dispatch); + await updateProfileVisibility( + token, + {userId, username}, + isPrivate, + dispatch, + ); + setIsLoading(false); + }; + + const getAccountText = () => { + return is_private ? 'Private Account' : 'Public Account'; + }; + + return ( + <> + <StatusBar barStyle="light-content" /> + <Background gradientType={BackgroundGradientType.Light}> + <SafeAreaView> + <View style={styles.container}> + <View style={styles.switchContainerStyle}> + <Text style={styles.title}>{getAccountText()}</Text> + <ActivityIndicator + animating={isLoading} + size="small" + color="white" + /> + {!isLoading && ( + <Switch + trackColor={{false: 'red', true: '#6EE7E7'}} + thumbColor={'white'} + ios_backgroundColor="transparent" + style={styles.switchStyles} + value={is_private} + onValueChange={updateAccountVisibility} + /> + )} + </View> + + <View style={styles.detailContainerStyle}> + <Text style={styles.detailTitleStyle}> + Enabling a public account will: + </Text> + <Text style={styles.detailContentStyle}> + {'\n'}Everyone can view my posts{'\n'} + {'\n'}Everyone can send me friend requests{'\n'} + {'\n'}Everyone can tagg me{'\n'} + {'\n'}Everyone can send me direct messages + </Text> + </View> + </View> + </SafeAreaView> + </Background> + </> + ); +}; + +const styles = StyleSheet.create({ + container: {marginHorizontal: '8%', marginTop: '20%'}, + title: { + alignSelf: 'center', + fontSize: normalize(18), + fontWeight: '600', + lineHeight: normalize(17.9), + color: 'white', + }, + switchContainerStyle: { + flexDirection: 'row', + alignContent: 'center', + justifyContent: 'space-between', + }, + detailContainerStyle: {marginTop: '40%'}, + detailTitleStyle: { + fontSize: normalize(19), + fontWeight: '700', + lineHeight: normalize(22.67), + color: 'white', + }, + detailContentStyle: { + fontSize: normalize(14), + fontWeight: '600', + lineHeight: normalize(16.71), + color: 'white', + }, + switchStyles: { + borderWidth: 2, + borderColor: 'white', + }, +}); + +export default AccountType; diff --git a/src/screens/profile/PrivacyScreen.tsx b/src/screens/profile/PrivacyScreen.tsx new file mode 100644 index 00000000..17872e24 --- /dev/null +++ b/src/screens/profile/PrivacyScreen.tsx @@ -0,0 +1,49 @@ +import React from 'react'; +import { + SectionList, + StatusBar, + StyleSheet, + View, + SafeAreaView, +} from 'react-native'; +import {useSelector} from 'react-redux'; +import {RootState} from 'src/store/rootReducer'; +import {Background} from '../../components'; +import {NO_PROFILE} from '../../store/initialStates'; +import {BackgroundGradientType} from '../../types'; +import {SCREEN_HEIGHT} from '../../utils/layouts'; +import SettingsCell from './SettingsCell'; +import {SETTINGS_DATA} from '../../constants/constants'; + +const PrivacyScreen: React.FC = () => { + const {profile: {is_private} = NO_PROFILE} = useSelector( + (state: RootState) => state.user, + ); + + return ( + <> + <StatusBar barStyle="light-content" /> + <Background gradientType={BackgroundGradientType.Light}> + <SafeAreaView> + <View style={styles.container}> + <SectionList + sections={SETTINGS_DATA.PrivacyScreen} + keyExtractor={(item, index) => item.title + index} + renderItem={({item: {title, preimage, postimage}}) => ( + <SettingsCell + {...{title, preimage, postimage, isPrivate: is_private}} + /> + )} + /> + </View> + </SafeAreaView> + </Background> + </> + ); +}; + +const styles = StyleSheet.create({ + container: {height: SCREEN_HEIGHT, marginHorizontal: '8%', marginTop: '8%'}, +}); + +export default PrivacyScreen; diff --git a/src/screens/profile/SettingsCell.tsx b/src/screens/profile/SettingsCell.tsx new file mode 100644 index 00000000..f5360242 --- /dev/null +++ b/src/screens/profile/SettingsCell.tsx @@ -0,0 +1,146 @@ +import {useNavigation} from '@react-navigation/core'; +import React from 'react'; +import { + Alert, + Image, + Linking, + StyleSheet, + Text, + TouchableOpacity, + View, +} from 'react-native'; +import InAppBrowser from 'react-native-inappbrowser-reborn'; +import {TAGG_PURPLE} from '../../constants'; +import {COMMUNITY_GUIDELINES, PRIVACY_POLICY} from '../../constants/api'; +import {ERROR_ATTEMPT_EDIT_SP} from '../../constants/strings'; +import {normalize, SCREEN_WIDTH} from '../../utils/layouts'; + +type SettingsCellProps = { + title: string; + preimage: number; + postimage: number; + isPrivate?: boolean; + suggested_people_linked?: number; +}; + +const SettingsCell: React.FC<SettingsCellProps> = ({ + title, + preimage, + postimage, + isPrivate, + suggested_people_linked, +}) => { + const navigation = useNavigation(); + const goToUpdateSPProfile = () => { + if (suggested_people_linked === 0) { + Alert.alert(ERROR_ATTEMPT_EDIT_SP); + } else { + // Sending undefined for updatedSelectedBadges to mark that there was no update yet + navigateTo('UpdateSPPicture', { + editing: true, + }); + } + }; + const getActions = (type: string) => { + switch (type) { + case 'Account Type': + navigateTo('AccountTypeScreen', {}); + break; + case 'Blocked Accounts': + //TODO: + break; + case 'Suggested People Profile': + goToUpdateSPProfile(); + break; + case 'Privacy': + navigateTo('PrivacyScreen', {}); + break; + case 'Community Guidelines': + openTaggLink(COMMUNITY_GUIDELINES); + break; + case 'Privacy Policy': + openTaggLink(PRIVACY_POLICY); + break; + default: + break; + } + }; + + const openTaggLink = async (url: string) => { + try { + if (await InAppBrowser.isAvailable()) { + await InAppBrowser.open(url, { + dismissButtonStyle: 'cancel', + preferredBarTintColor: TAGG_PURPLE, + preferredControlTintColor: 'white', + animated: true, + modalPresentationStyle: 'fullScreen', + modalTransitionStyle: 'coverVertical', + modalEnabled: true, + enableBarCollapsing: false, + animations: { + startEnter: 'slide_in_right', + startExit: 'slide_out_left', + endEnter: 'slide_in_left', + endExit: 'slide_out_right', + }, + }); + } else Linking.openURL(url); + } catch (error) { + Alert.alert(error.message); + } + }; + + const navigateTo = (screen: string, options: object) => { + navigation.navigate(screen, options); + }; + return ( + <TouchableOpacity + onPress={() => getActions(title)} + style={styles.itemStyles}> + <Image + resizeMode={'cover'} + style={styles.preImageStyles} + source={preimage} + /> + <View style={styles.titleContainerStyles}> + <Text style={styles.titleStyles}>{title}</Text> + </View> + <View style={[styles.itemStyles, styles.subItemStyles]}> + {title === 'Account Type' && ( + <Text style={[styles.titleStyles, styles.subtitleStyles]}> + {isPrivate ? 'Private' : 'Public'} + </Text> + )} + <Image style={styles.postImageStyles} source={postimage} /> + </View> + </TouchableOpacity> + ); +}; + +const styles = StyleSheet.create({ + container: {marginHorizontal: '8%'}, + itemStyles: { + marginTop: 36, + flexDirection: 'row', + justifyContent: 'flex-start', + alignItems: 'center', + }, + subItemStyles: {position: 'absolute', right: 0}, + preImageStyles: {width: SCREEN_WIDTH * 0.05, height: SCREEN_WIDTH * 0.05}, + postImageStyles: {width: 15, height: 15}, + titleContainerStyles: {marginLeft: '12%'}, + titleStyles: { + fontSize: normalize(15), + fontWeight: '600', + lineHeight: normalize(17.9), + color: 'white', + }, + subtitleStyles: {color: '#C4C4C4', marginRight: 13}, + tc: { + marginVertical: '5%', + top: '8%', + }, +}); + +export default SettingsCell; diff --git a/src/screens/profile/SettingsScreen.tsx b/src/screens/profile/SettingsScreen.tsx new file mode 100644 index 00000000..05e051b5 --- /dev/null +++ b/src/screens/profile/SettingsScreen.tsx @@ -0,0 +1,87 @@ +import React from 'react'; +import { + SafeAreaView, + SectionList, + StatusBar, + StyleSheet, + Text, + TouchableOpacity, + View, +} from 'react-native'; +import {useDispatch, useSelector} from 'react-redux'; +import {logout} from '../../store/actions'; +import {RootState} from 'src/store/rootReducer'; +import {Background} from '../../components'; +import {SETTINGS_DATA} from '../../constants/constants'; +import {BackgroundGradientType} from '../../types'; +import {normalize, SCREEN_HEIGHT} from '../../utils/layouts'; +import SettingsCell from './SettingsCell'; +import {useNavigation} from '@react-navigation/core'; + +const SettingsScreen: React.FC = () => { + const dispatch = useDispatch(); + const navigation = useNavigation(); + const {suggested_people_linked} = useSelector( + (state: RootState) => state.user.profile, + ); + + return ( + <> + <StatusBar barStyle="light-content" /> + <Background gradientType={BackgroundGradientType.Light}> + <SafeAreaView> + <View style={styles.container}> + <SectionList + stickySectionHeadersEnabled={false} + sections={SETTINGS_DATA.SettingsAndPrivacy} + keyExtractor={(item, index) => item.title + index} + renderItem={({item: {title, preimage, postimage}}) => ( + <SettingsCell + {...{title, preimage, postimage, suggested_people_linked}} + /> + )} + renderSectionHeader={({section: {title}}) => ( + <View style={styles.headerContainerStyles}> + <Text style={styles.headerTextStyles}>{title}</Text> + </View> + )} + ListFooterComponent={() => ( + <TouchableOpacity + style={styles.logoutContainerStyles} + onPress={() => { + dispatch(logout()); + navigation.reset({ + index: 0, + routes: [{name: 'SuggestedPeople'}], + }); + }}> + <Text style={styles.logoutTextStyles}>Logout</Text> + </TouchableOpacity> + )} + /> + </View> + </SafeAreaView> + </Background> + </> + ); +}; + +const styles = StyleSheet.create({ + container: {height: SCREEN_HEIGHT, marginHorizontal: '8%', marginTop: '8%'}, + headerContainerStyles: {marginTop: '14%'}, + headerTextStyles: { + fontSize: normalize(18), + fontWeight: '600', + lineHeight: normalize(21.48), + color: '#E9E9E9', + }, + logoutContainerStyles: {marginTop: '20%', marginLeft: '12%'}, + logoutTextStyles: { + fontSize: normalize(20), + fontWeight: '600', + lineHeight: normalize(23.87), + color: 'white', + }, +}); + +export default SettingsScreen; diff --git a/src/screens/profile/index.ts b/src/screens/profile/index.ts index f74946a6..b7efdd3b 100644 --- a/src/screens/profile/index.ts +++ b/src/screens/profile/index.ts @@ -7,3 +7,6 @@ export {default as FriendsListScreen} from './FriendsListScreen'; export {default as EditProfile} from './EditProfile'; export {default as MomentUploadPromptScreen} from './MomentUploadPromptScreen'; export {default as InviteFriendsScreen} from './InviteFriendsScreen'; +export {default as SettingsScreen} from './SettingsScreen'; +export {default as PrivacyScreen} from './PrivacyScreen'; +export {default as AccountType} from './AccountType'; diff --git a/src/services/UserProfileService.ts b/src/services/UserProfileService.ts index 085787c3..1ce1d0b5 100644 --- a/src/services/UserProfileService.ts +++ b/src/services/UserProfileService.ts @@ -1,6 +1,8 @@ import AsyncStorage from '@react-native-community/async-storage'; import moment from 'moment'; +import {useEffect} from 'react'; import {Alert} from 'react-native'; +import {loadUserData} from '../store/actions'; import { EDIT_PROFILE_ENDPOINT, GET_FB_POSTS_ENDPOINT, @@ -20,6 +22,7 @@ import { ERROR_DOUBLE_CHECK_CONNECTION, ERROR_DUP_OLD_PWD, ERROR_INVALID_PWD_CODE, + ERROR_PROFILE_UPDATE_SHORT, ERROR_PWD_ACCOUNT, ERROR_SOMETHING_WENT_WRONG, ERROR_SOMETHING_WENT_WRONG_REFRESH, @@ -27,7 +30,12 @@ import { SUCCESS_PWD_RESET, SUCCESS_VERIFICATION_CODE_SENT, } from '../constants/strings'; -import {ProfileInfoType, ProfileType, SocialAccountType} from '../types'; +import { + ProfileInfoType, + ProfileType, + SocialAccountType, + UserType, +} from '../types'; export const loadProfileInfo = async (token: string, userId: string) => { try { @@ -75,6 +83,44 @@ export const getProfilePic = async ( } }; +export const updateProfileVisibility = async ( + token: string, + user: UserType, + isPrivateAccount: Boolean, + dispatch: Function, +) => { + try { + const url = EDIT_PROFILE_ENDPOINT + `${user.userId}/`; + const request = new FormData(); + request.append('is_private', isPrivateAccount ? 'True' : 'False'); + let response = await fetch(url, { + method: 'PATCH', + headers: { + 'Content-Type': 'multipart/form-data', + Authorization: 'Token ' + token, + }, + body: request, + }); + const {status} = response; + let data = await response.json(); + if (status === 200) { + await dispatch(loadUserData(user)); + } else if (status >= 400) { + Alert.alert( + ERROR_PROFILE_UPDATE_SHORT, + data.error || 'Something went wrong! ðŸ˜', + ); + } + } catch (error) { + debugger; + Alert.alert(ERROR_PROFILE_UPDATE_SHORT, ERROR_DOUBLE_CHECK_CONNECTION); + return { + name: 'Profile update error', + description: error, + }; + } +}; + const integratedSocialPostsEndpoints: {[social: string]: string} = { Facebook: GET_FB_POSTS_ENDPOINT, Instagram: GET_IG_POSTS_ENDPOINT, diff --git a/src/store/actions/user.ts b/src/store/actions/user.ts index 46f96d9a..374154da 100644 --- a/src/store/actions/user.ts +++ b/src/store/actions/user.ts @@ -1,3 +1,4 @@ +import AsyncStorage from '@react-native-community/async-storage'; import {Action, ThunkAction} from '@reduxjs/toolkit'; import { getProfilePic, @@ -157,6 +158,7 @@ export const logout = (): ThunkAction< Action<string> > => async (dispatch) => { try { + await AsyncStorage.clear(); dispatch({type: userLoggedIn.type, payload: {userId: '', username: ''}}); } catch (error) { console.log(error); diff --git a/src/utils/users.ts b/src/utils/users.ts index f9d6d6b7..22c1c1f0 100644 --- a/src/utils/users.ts +++ b/src/utils/users.ts @@ -133,7 +133,7 @@ export const loadAllSocialsForUser = async (userId: string, token?: string) => { export const getTokenOrLogout = async (dispatch: Function): Promise<string> => { const token = await AsyncStorage.getItem('token'); if (!token) { - dispatch({type: userLoggedIn.type, payload: {userId: '', username: ''}}); + dispatch(logout()); return ''; } return token; |