aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJustin Shillingford <jgs272@cornell.edu>2020-08-14 16:39:26 -0400
committerGitHub <noreply@github.com>2020-08-14 16:39:26 -0400
commit59ea758ba64dd4e00f12b5ceb941d0ea5e273210 (patch)
tree6a698457be38c484bb9f93e3caf2f8e32bb7be8d /src
parent1979a2b55ebe560b9d20862bd835343516b40379 (diff)
[TMA-19] Social Media Post Container (#31)
* Basic mostly functional implementation Need to figure out why API is being called so much * Hey it works now! Without a million API calls! * Fixed bug where app would crash upon login Also updated property names to be more appropriate * Added post datetime and social icon * Updated error message * Fixed typecheck errors I don't know that these fixes are the best since I don't think they're generalizable * Formatted datetime in PostHeader
Diffstat (limited to 'src')
-rw-r--r--src/components/common/post/Post.tsx12
-rw-r--r--src/components/common/post/PostHeader.tsx68
-rw-r--r--src/components/profile/Feed.tsx14
-rw-r--r--src/constants/api.ts1
-rw-r--r--src/routes/authentication/AuthProvider.tsx24
-rw-r--r--src/types/types.ts12
6 files changed, 116 insertions, 15 deletions
diff --git a/src/components/common/post/Post.tsx b/src/components/common/post/Post.tsx
index d6c5a7d6..e5f68917 100644
--- a/src/components/common/post/Post.tsx
+++ b/src/components/common/post/Post.tsx
@@ -1,5 +1,5 @@
import React from 'react';
-import {StyleSheet, View} from 'react-native';
+import {StyleSheet, View, Image} from 'react-native';
import {PostType} from '../../../types';
import PostHeader from './PostHeader';
import {SCREEN_WIDTH} from '../../../utils';
@@ -7,11 +7,15 @@ import {SCREEN_WIDTH} from '../../../utils';
interface PostProps {
post: PostType;
}
-const Post: React.FC<PostProps> = ({post: {owner}}) => {
+const Post: React.FC<PostProps> = ({post: {owner, instagram, social}}) => {
return (
<>
- <PostHeader owner={owner} />
- <View style={styles.image} />
+ <PostHeader post={instagram} owner={owner} social={social} />
+ <View style={styles.image}>
+ {instagram && (
+ <Image style={styles.image} source={{uri: instagram.media_url}} />
+ )}
+ </View>
</>
);
};
diff --git a/src/components/common/post/PostHeader.tsx b/src/components/common/post/PostHeader.tsx
index 8558d21d..a07efd10 100644
--- a/src/components/common/post/PostHeader.tsx
+++ b/src/components/common/post/PostHeader.tsx
@@ -1,17 +1,57 @@
import React from 'react';
-import {UserType} from '../../../types';
+import {UserType, InstagramPostType} from '../../../types';
import {View, StyleSheet, Image, Text} from 'react-native';
import {AuthContext} from '../../../routes/authentication';
+import moment from 'moment';
const AVATAR_DIM = 35;
interface PostHeaderProps {
owner: UserType;
+ post: InstagramPostType | undefined;
+ social: string;
}
-const PostHeader: React.FC<PostHeaderProps> = ({owner: {username}}) => {
+const PostHeader: React.FC<PostHeaderProps> = ({
+ owner: {username},
+ post,
+ social,
+}) => {
const {avatar} = React.useContext(AuthContext);
+ switch (social) {
+ case 'Instagram':
+ var icon = require('../../../assets/images/instagram-icon.png');
+ break;
+ case 'Facebook':
+ var icon = require('../../../assets/images/facebook-icon.png');
+ break;
+ case 'Twitter':
+ var icon = require('../../../assets/images/twitter-icon.png');
+ break;
+ case 'Twitch':
+ var icon = require('../../../assets/images/twitch-icon.png');
+ break;
+ case 'Pinterest':
+ var icon = require('../../../assets/images/pinterest-icon.png');
+ break;
+ case 'Whatsapp':
+ var icon = require('../../../assets/images/whatsapp-icon.png');
+ break;
+ case 'Linkedin':
+ var icon = require('../../../assets/images/linkedin-icon.png');
+ break;
+ case 'Snapchat':
+ var icon = require('../../../assets/images/snapchat-icon.png');
+ break;
+ case 'Youtube':
+ var icon = require('../../../assets/images/youtube-icon.png');
+ break;
+ default:
+ var icon = require('../../../assets/images/logo.png');
+ break;
+ }
+
return (
<View style={styles.container}>
- <View style={styles.leftElem}>
+ <View style={styles.topRow}>
<Image
style={styles.avatar}
source={
@@ -21,19 +61,26 @@ const PostHeader: React.FC<PostHeaderProps> = ({owner: {username}}) => {
}
/>
<Text style={styles.username}>{username}</Text>
+ {post && <Image style={styles.icon} source={icon} />}
</View>
+ {post && (
+ <Text style={styles.timestamp}>
+ {moment(post.timestamp).format('LL')} at{' '}
+ {moment(post.timestamp).format('LT')}
+ </Text>
+ )}
</View>
);
};
const styles = StyleSheet.create({
container: {
- flexDirection: 'row',
+ flexDirection: 'column',
justifyContent: 'space-between',
padding: 10,
backgroundColor: 'white',
},
- leftElem: {
+ topRow: {
flexDirection: 'row',
alignItems: 'center',
},
@@ -43,9 +90,20 @@ const styles = StyleSheet.create({
borderRadius: AVATAR_DIM / 2,
marginRight: 10,
},
+ icon: {
+ width: AVATAR_DIM,
+ height: AVATAR_DIM,
+ borderRadius: AVATAR_DIM / 2,
+ marginLeft: '55%',
+ },
username: {
fontSize: 18,
},
+ timestamp: {
+ color: '#6A757D',
+ fontSize: 11,
+ marginLeft: AVATAR_DIM + 10,
+ },
});
export default PostHeader;
diff --git a/src/components/profile/Feed.tsx b/src/components/profile/Feed.tsx
index 6780f8c5..a10d8d6d 100644
--- a/src/components/profile/Feed.tsx
+++ b/src/components/profile/Feed.tsx
@@ -1,17 +1,21 @@
import React from 'react';
import {PostType, UserType} from '../../types';
import {Post} from '../common';
+import {AuthContext} from '../../routes/authentication';
interface FeedProps {
user: UserType;
}
const Feed: React.FC<FeedProps> = ({user}) => {
+ const {instaPosts} = React.useContext(AuthContext);
const posts: Array<PostType> = [];
- const dummyPost: PostType = {
- owner: user,
- };
- for (let i = 0; i < 20; i++) {
- posts.push(dummyPost);
+ for (let i = 0; i < 10; i++) {
+ const testPost: PostType = {
+ owner: user,
+ instagram: instaPosts[i],
+ social: 'Instagram',
+ };
+ posts.push(testPost);
}
return (
<>
diff --git a/src/constants/api.ts b/src/constants/api.ts
index fd654c53..057b5da7 100644
--- a/src/constants/api.ts
+++ b/src/constants/api.ts
@@ -8,3 +8,4 @@ export const VERIFY_OTP_ENDPOINT: string = API_URL + 'verify-otp/';
export const PROFILE_INFO_ENDPOINT: string = API_URL + 'user-profile-info/';
export const COVER_PHOTO_ENDPOINT: string = API_URL + 'large-profile-pic/';
export const AVATAR_PHOTO_ENDPOINT: string = API_URL + 'small-profile-pic/';
+export const GET_IG_POSTS_ENDPOINT: string = API_URL + 'posts-ig/';
diff --git a/src/routes/authentication/AuthProvider.tsx b/src/routes/authentication/AuthProvider.tsx
index bd5706f3..e52d56bc 100644
--- a/src/routes/authentication/AuthProvider.tsx
+++ b/src/routes/authentication/AuthProvider.tsx
@@ -1,11 +1,12 @@
import React, {useEffect} from 'react';
import {createContext, useState} from 'react';
import RNFetchBlob from 'rn-fetch-blob';
-import {UserType, ProfileType} from '../../types';
+import {UserType, ProfileType, InstagramPostType} from '../../types';
import {
PROFILE_INFO_ENDPOINT,
AVATAR_PHOTO_ENDPOINT,
COVER_PHOTO_ENDPOINT,
+ GET_IG_POSTS_ENDPOINT,
} from '../../constants';
interface AuthContextProps {
@@ -15,6 +16,7 @@ interface AuthContextProps {
logout: () => void;
avatar: string | null;
cover: string | null;
+ instaPosts: Array<InstagramPostType>;
}
const NO_USER: UserType = {
userId: '',
@@ -32,6 +34,7 @@ export const AuthContext = createContext<AuthContextProps>({
logout: () => {},
avatar: null,
cover: null,
+ instaPosts: [],
});
/**
@@ -42,6 +45,7 @@ const AuthProvider: React.FC = ({children}) => {
const [profile, setProfile] = useState<ProfileType>(NO_PROFILE);
const [avatar, setAvatar] = useState<string | null>(null);
const [cover, setCover] = useState<string | null>(null);
+ const [instaPosts, setInstaPosts] = useState<Array<InstagramPostType>>([]);
const {userId} = user;
useEffect(() => {
@@ -95,9 +99,26 @@ const AuthProvider: React.FC = ({children}) => {
console.log(error);
}
};
+ const loadInstaPosts = async () => {
+ try {
+ const response = await fetch(GET_IG_POSTS_ENDPOINT + `${userId}/`, {
+ method: 'GET',
+ });
+ const status = response.status;
+ if (status === 200) {
+ let ig_posts = await response.json();
+ setInstaPosts(ig_posts);
+ } else {
+ setInstaPosts([]);
+ }
+ } catch (error) {
+ console.log(error);
+ }
+ };
loadProfileInfo();
loadAvatar();
loadCover();
+ loadInstaPosts();
}, [userId]);
return (
@@ -107,6 +128,7 @@ const AuthProvider: React.FC = ({children}) => {
profile,
avatar,
cover,
+ instaPosts,
login: (id, username) => {
setUser({...user, userId: id, username});
},
diff --git a/src/types/types.ts b/src/types/types.ts
index d6f69b85..6dabc0bc 100644
--- a/src/types/types.ts
+++ b/src/types/types.ts
@@ -9,8 +9,20 @@ export interface ProfileType {
website: string;
}
+export interface InstagramPostType {
+ post_id: string;
+ username: string;
+ media_url: string;
+ media_type: string;
+ caption: string;
+ timestamp: string;
+ permalink: string;
+}
+
export interface PostType {
owner: UserType;
+ social: string;
+ instagram: InstagramPostType | undefined;
}
export interface LinkerType {