aboutsummaryrefslogtreecommitdiff
path: root/src/components/onboarding
diff options
context:
space:
mode:
authorIvan Chen <ivan@thetaggid.com>2020-11-04 11:30:26 -0500
committerGitHub <noreply@github.com>2020-11-04 11:30:26 -0500
commit8461f2798d015cd732f3edcf2caaea4812fb43cb (patch)
treea14a6c5bc9b770643fd723b264c7566b5f55bfd8 /src/components/onboarding
parentd9995cd016d540c54fa10ed0eed38e247c19e4bf (diff)
[TMA-335] Fixed social linking for non-integrated during onboarding (#102)
* handled linker logic and uses soical linking service * Fixed layout
Diffstat (limited to 'src/components/onboarding')
-rw-r--r--src/components/onboarding/LinkSocialMedia.tsx167
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;