diff options
Diffstat (limited to 'src/components/onboarding/LinkSocialMedia.tsx')
-rw-r--r-- | src/components/onboarding/LinkSocialMedia.tsx | 167 |
1 files changed, 47 insertions, 120 deletions
diff --git a/src/components/onboarding/LinkSocialMedia.tsx b/src/components/onboarding/LinkSocialMedia.tsx index 03ca3a29..c7b0a6b4 100644 --- a/src/components/onboarding/LinkSocialMedia.tsx +++ b/src/components/onboarding/LinkSocialMedia.tsx @@ -1,9 +1,4 @@ -/** - * This is a duplicate file, adding this now to avoid conflicts with incoming changes on the original 'SocialMediaLinker' - */ - -import AsyncStorage from '@react-native-community/async-storage'; -import React from 'react'; +import React, {useState} from 'react'; import { Alert, Image, @@ -12,17 +7,17 @@ import { TouchableOpacity, TouchableOpacityProps, } from 'react-native'; -import InAppBrowser from 'react-native-inappbrowser-reborn'; -import {LinkerType} from 'src/types'; +import {SocialLinkModal} from '..'; +import { + INTEGRATED_SOCIAL_LIST, + SOCIAL_FONT_COLORS, + TAGG_ICON_DIM, +} from '../../constants/constants'; import { - LINK_FB_ENDPOINT, - LINK_FB_OAUTH, - LINK_IG_ENDPOINT, - LINK_IG_OAUTH, - LINK_TWITTER_ENDPOINT, - LINK_TWITTER_OAUTH, -} from '../../constants'; -import {SOCIAL_FONT_COLORS, TAGG_ICON_DIM} from '../../constants/constants'; + handlePressForAuthBrowser, + registerNonIntegratedSocialLink, +} from '../../services'; +import {LinkerType} from '../../types'; import SocialIcon from '../common/SocialIcon'; interface SocialMediaLinkerProps extends TouchableOpacityProps { @@ -32,104 +27,8 @@ interface SocialMediaLinkerProps extends TouchableOpacityProps { const SocialMediaLinker: React.FC<SocialMediaLinkerProps> = ({ social: {label}, }) => { - const [state, setState] = React.useState({ - authenticated: false, - }); - - const integrated_endpoints: {[label: string]: [string, string]} = { - Instagram: [LINK_IG_OAUTH, LINK_IG_ENDPOINT], - Facebook: [LINK_FB_OAUTH, LINK_FB_ENDPOINT], - Twitter: [LINK_TWITTER_OAUTH, LINK_TWITTER_ENDPOINT], - }; - - const registerSocialLink: (token: string) => Promise<boolean> = async ( - callback_url, - ) => { - if (!(label in integrated_endpoints)) { - // This error is already handled earlier, more of a safety check here - return false; - } - const user_token = await AsyncStorage.getItem('token'); - const response = await fetch(integrated_endpoints[label][1], { - method: 'POST', - headers: { - Authorization: `Token ${user_token}`, - }, - body: JSON.stringify({ - callback_url: callback_url, - }), - }); - if (!(response.status === 201)) { - console.log(await response.json()); - } - return response.status === 201; - }; - - const handlePress = async () => { - try { - const isAvailable = await InAppBrowser.isAvailable(); - if (!(label in integrated_endpoints)) { - // TODO handle non-integrated social links with a modal - // TODO remove the alert below - Alert.alert('Coming soon!'); - return; - } - let url = integrated_endpoints[label][0]; - - // We will need to do an extra step for twitter sign-in - if (label === 'Twitter') { - const user_token = await AsyncStorage.getItem('token'); - const response = await fetch(url, { - method: 'GET', - headers: { - Authorization: `Token ${user_token}`, - }, - }); - url = response.url; - } - - if (isAvailable) { - InAppBrowser.openAuth(url, 'taggid://callback', { - ephemeralWebSession: true, - }) - .then(async (response) => { - console.log(response); - if (response.type === 'success' && response.url) { - const success = await registerSocialLink(response.url); - if (!success) { - throw new Error('Unable to register with backend'); - } - setState({ - ...state, - authenticated: true, - }); - Alert.alert(`Successfully linked ${label} 🎉`); - } else { - throw new Error(`Unable to link with ${label} API`); - } - }) - .catch((error) => { - console.log(error); - Alert.alert(`Something went wrong, we can't link with ${label} 😔`); - }); - } else { - // Okay... to open an external browser and have it link back to - // the app is a bit tricky, we will need to have navigation routes - // setup for this screen and have it hooked up. - // See https://github.com/proyecto26/react-native-inappbrowser#authentication-flow-using-deep-linking - // Though this isn't the end of the world, from the documentation, - // the in-app browser should be supported from iOS 11, which - // is about 98.5% of all iOS devices in the world. - // See https://support.apple.com/en-gb/HT209574 - Alert.alert( - 'Sorry! Your device was unable to open a browser to let you sign-in! 😔', - ); - } - } catch (error) { - console.log(error); - Alert.alert(`Something went wrong, we can't link with ${label} 😔`); - } - }; + const [modalVisible, setModalVisible] = useState(false); + const [authenticated, setAuthenticated] = React.useState(false); switch (label) { case 'Instagram': @@ -163,19 +62,47 @@ const SocialMediaLinker: React.FC<SocialMediaLinkerProps> = ({ var font_color = '#fff'; } + const linkNonIntegratedSocial = async (username: string) => { + if (await registerNonIntegratedSocialLink(label, username)) { + Alert.alert(`Successfully linked ${label} 🎉`); + setAuthenticated(true); + } else { + // If we display too fast the alert will get dismissed with the modal + setTimeout(() => { + Alert.alert(`Something went wrong, we can't link with ${label} 😔`); + }, 500); + } + }; + + const modelOrAuthBrowser = async () => { + // check if it's integrated + if (INTEGRATED_SOCIAL_LIST.indexOf(label) >= 0) { + handlePressForAuthBrowser(label).then((success) => { + setAuthenticated(success); + }); + } else { + setModalVisible(true); + } + }; + return ( <TouchableOpacity activeOpacity={0.7} - onPress={handlePress} + onPress={modelOrAuthBrowser} style={styles.container}> <SocialIcon social={label} style={styles.icon} /> <Text style={[styles.label, {color: font_color}]}>{label}</Text> - {state.authenticated && ( + {authenticated && ( <Image source={require('../../assets/images/link-tick.png')} style={styles.tick} /> )} + <SocialLinkModal + modalVisible={modalVisible} + setModalVisible={setModalVisible} + completionCallback={linkNonIntegratedSocial} + /> </TouchableOpacity> ); }; @@ -183,24 +110,24 @@ const SocialMediaLinker: React.FC<SocialMediaLinkerProps> = ({ const styles = StyleSheet.create({ container: { width: '28%', - height: '100%', + maxHeight: 150, backgroundColor: '#4c409a', borderRadius: 8, marginHorizontal: '2%', marginVertical: '2%', alignItems: 'center', + paddingVertical: '2%', }, icon: { - top: '15%', width: TAGG_ICON_DIM, height: TAGG_ICON_DIM, + marginVertical: '8%', }, label: { fontWeight: '500', - top: '25%', }, tick: { - top: '30%', + marginTop: '5%', }, }); export default SocialMediaLinker; |