aboutsummaryrefslogtreecommitdiff
path: root/src/components
diff options
context:
space:
mode:
Diffstat (limited to 'src/components')
-rw-r--r--src/components/common/SocialIcon.tsx3
-rw-r--r--src/components/onboarding/LinkSocialMedia.tsx204
-rw-r--r--src/components/onboarding/RegistrationWizard.tsx12
-rw-r--r--src/components/onboarding/index.ts1
4 files changed, 218 insertions, 2 deletions
diff --git a/src/components/common/SocialIcon.tsx b/src/components/common/SocialIcon.tsx
index 5c1098af..a46b1445 100644
--- a/src/components/common/SocialIcon.tsx
+++ b/src/components/common/SocialIcon.tsx
@@ -40,6 +40,9 @@ const SocialIcon: React.FC<SocialIconProps> = ({
case 'Youtube':
var icon = require('../../assets/images/youtube-icon.png');
break;
+ case 'TikTok':
+ var icon = require('../../assets/images/tiktok-icon.png');
+ break;
default:
var icon = require('../../assets/images/logo.png');
break;
diff --git a/src/components/onboarding/LinkSocialMedia.tsx b/src/components/onboarding/LinkSocialMedia.tsx
new file mode 100644
index 00000000..5f95fac8
--- /dev/null
+++ b/src/components/onboarding/LinkSocialMedia.tsx
@@ -0,0 +1,204 @@
+/**
+ * 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 {
+ Alert,
+ Image,
+ StyleSheet,
+ Text,
+ TouchableOpacity,
+ TouchableOpacityProps,
+} from 'react-native';
+import InAppBrowser from 'react-native-inappbrowser-reborn';
+import {LinkerType} from 'src/types';
+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} from '../../constants/constants';
+import SocialIcon from '../common/SocialIcon';
+
+interface SocialMediaLinkerProps extends TouchableOpacityProps {
+ social: LinkerType;
+}
+
+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} 😔`);
+ }
+ };
+
+ switch (label) {
+ case 'Instagram':
+ var font_color = SOCIAL_FONT_COLORS.INSTAGRAM;
+ break;
+ case 'Facebook':
+ var font_color = SOCIAL_FONT_COLORS.FACEBOOK;
+ break;
+ case 'Twitter':
+ var font_color = SOCIAL_FONT_COLORS.TWITTER;
+ break;
+ case 'Twitch':
+ var font_color = SOCIAL_FONT_COLORS.TWITCH;
+ break;
+ case 'Pinterest':
+ var font_color = SOCIAL_FONT_COLORS.PINTEREST;
+ break;
+ case 'Whatsapp':
+ var font_color = SOCIAL_FONT_COLORS.WHATSAPP;
+ break;
+ case 'Linkedin':
+ var font_color = SOCIAL_FONT_COLORS.LINKEDIN;
+ break;
+ case 'Snapchat':
+ var font_color = SOCIAL_FONT_COLORS.SNAPCHAT;
+ break;
+ case 'Youtube':
+ var font_color = SOCIAL_FONT_COLORS.YOUTUBE;
+ break;
+ default:
+ var font_color = '#fff';
+ }
+
+ return (
+ <TouchableOpacity
+ activeOpacity={0.7}
+ onPress={handlePress}
+ style={styles.container}>
+ <SocialIcon social={label} style={styles.icon} />
+ <Text style={[styles.label, {color: font_color}]}>{label}</Text>
+ {state.authenticated && (
+ <Image
+ source={require('../../assets/images/link-tick.png')}
+ style={styles.tick}
+ />
+ )}
+ </TouchableOpacity>
+ );
+};
+
+const styles = StyleSheet.create({
+ container: {
+ width: '28%',
+ height: '100%',
+ backgroundColor: '#4c409a',
+ borderRadius: 8,
+ marginHorizontal: '2%',
+ marginVertical: '2%',
+ alignItems: 'center',
+ },
+ icon: {
+ top: '15%',
+ },
+ label: {
+ fontWeight: '500',
+ top: '25%',
+ },
+ tick: {
+ top: '30%',
+ },
+});
+export default SocialMediaLinker;
diff --git a/src/components/onboarding/RegistrationWizard.tsx b/src/components/onboarding/RegistrationWizard.tsx
index 8d747b01..437e7cfb 100644
--- a/src/components/onboarding/RegistrationWizard.tsx
+++ b/src/components/onboarding/RegistrationWizard.tsx
@@ -3,7 +3,7 @@ import {View, StyleSheet, ViewProps, Keyboard} from 'react-native';
import * as Animatable from 'react-native-animatable';
interface RegistrationWizardProps extends ViewProps {
- step: 'one' | 'two' | 'three' | 'four' | 'five' | 'six';
+ step: 'one' | 'two' | 'three' | 'four' | 'five' | 'six' | 'seven';
}
const RegistrationWizard = (props: RegistrationWizardProps) => {
@@ -43,6 +43,10 @@ const RegistrationWizard = (props: RegistrationWizardProps) => {
<View style={props.step === 'five' ? stepActiveStyle : stepStyle} />
<View style={styles.progress} />
<View style={props.step === 'six' ? stepActiveStyle : stepStyle} />
+ <View style={styles.progress} />
+ <View
+ style={props.step === 'seven' ? stepActiveStyle : stepStyle}
+ />
</View>
</Animatable.View>
)}
@@ -62,6 +66,10 @@ const RegistrationWizard = (props: RegistrationWizardProps) => {
<View style={props.step === 'five' ? stepActiveStyle : stepStyle} />
<View style={styles.progress} />
<View style={props.step === 'six' ? stepActiveStyle : stepStyle} />
+ <View style={styles.progress} />
+ <View
+ style={props.step === 'seven' ? stepActiveStyle : stepStyle}
+ />
</View>
</Animatable.View>
)}
@@ -86,7 +94,7 @@ const styles = StyleSheet.create({
backgroundColor: '#e1f0ff',
},
progress: {
- width: '13%',
+ width: '10%',
height: 2,
backgroundColor: '#e1f0ff',
},
diff --git a/src/components/onboarding/index.ts b/src/components/onboarding/index.ts
index 627412df..aaad7a62 100644
--- a/src/components/onboarding/index.ts
+++ b/src/components/onboarding/index.ts
@@ -8,3 +8,4 @@ export {default as TaggBigInput} from './TaggBigInput';
export {default as TaggDatePicker} from './TaggDatePicker';
export {default as TaggDropDown} from './TaggDropDown';
export {default as SocialMediaLinker} from './SocialMediaLinker';
+export {default as LinkSocialMedia} from './LinkSocialMedia';