aboutsummaryrefslogtreecommitdiff
path: root/src/components
diff options
context:
space:
mode:
authorAshm Walia <40498934+ashmgarv@users.noreply.github.com>2020-10-18 16:37:32 -0700
committerGitHub <noreply@github.com>2020-10-18 19:37:32 -0400
commitab7fa09af967e0a8cf2ca53dfb24f8bc8a6886f7 (patch)
tree898e7aa42529eda91964ac1a18aa1881689554f2 /src/components
parent79d237f616c37940f5d476eb1dca6b5d05cf148a (diff)
[TMA 279] Ability to search and view someone's profile (#58)
* Batch one : major changes * WIP checkpoint * The one before the final touch * Probable final touch * ran yarn lint D: * linter broke something * fixed a small bug * Addressed a small nitpick * Well abstracted now Co-authored-by: Ivan Chen <ivan@thetaggid.com>
Diffstat (limited to 'src/components')
-rw-r--r--src/components/common/AvatarTitle.tsx12
-rw-r--r--src/components/profile/Avatar.tsx9
-rw-r--r--src/components/profile/Content.tsx24
-rw-r--r--src/components/profile/Cover.tsx9
-rw-r--r--src/components/profile/ProfileBody.tsx9
-rw-r--r--src/components/profile/ProfileHeader.tsx14
-rw-r--r--src/components/search/SearchResult.tsx21
-rw-r--r--src/components/taggs/Tagg.tsx10
-rw-r--r--src/components/taggs/TaggsBar.tsx11
9 files changed, 85 insertions, 34 deletions
diff --git a/src/components/common/AvatarTitle.tsx b/src/components/common/AvatarTitle.tsx
index 8c82dca9..e9998113 100644
--- a/src/components/common/AvatarTitle.tsx
+++ b/src/components/common/AvatarTitle.tsx
@@ -2,13 +2,19 @@ import React from 'react';
import {Image, StyleSheet} from 'react-native';
import LinearGradient from 'react-native-linear-gradient';
import {AVATAR_DIM, AVATAR_GRADIENT_DIM, TAGGS_GRADIENT} from '../../constants';
-import {AuthContext} from '../../routes/authentication';
+import {AuthContext, ProfileContext} from '../../routes/';
/**
* An image component that returns the <Image> of the icon for a specific social media platform.
*/
-const AvatarTitle: React.FC = () => {
- const {avatar} = React.useContext(AuthContext);
+
+type AvatarTitleProps = {
+ isProfileView: boolean;
+};
+const AvatarTitle: React.FC<AvatarTitleProps> = ({isProfileView}) => {
+ const {avatar} = isProfileView
+ ? React.useContext(ProfileContext)
+ : React.useContext(AuthContext);
return (
<LinearGradient
colors={[TAGGS_GRADIENT.start, TAGGS_GRADIENT.end]}
diff --git a/src/components/profile/Avatar.tsx b/src/components/profile/Avatar.tsx
index a0f7596c..aca3bf4d 100644
--- a/src/components/profile/Avatar.tsx
+++ b/src/components/profile/Avatar.tsx
@@ -1,13 +1,16 @@
import React from 'react';
import {Image, StyleSheet} from 'react-native';
-import {AuthContext} from '../../routes/authentication';
+import {AuthContext, ProfileContext} from '../../routes/';
const PROFILE_DIM = 100;
interface AvatarProps {
style: object;
+ isProfileView: boolean;
}
-const Avatar: React.FC<AvatarProps> = ({style}) => {
- const {avatar} = React.useContext(AuthContext);
+const Avatar: React.FC<AvatarProps> = ({style, isProfileView}) => {
+ const {avatar} = isProfileView
+ ? React.useContext(ProfileContext)
+ : React.useContext(AuthContext);
return (
<Image
style={[styles.image, style]}
diff --git a/src/components/profile/Content.tsx b/src/components/profile/Content.tsx
index a3b9e74a..8d368747 100644
--- a/src/components/profile/Content.tsx
+++ b/src/components/profile/Content.tsx
@@ -1,5 +1,6 @@
import React, {useState} from 'react';
import {LayoutChangeEvent, StyleSheet, View} from 'react-native';
+import {Text} from 'react-native-animatable';
import Animated from 'react-native-reanimated';
import {defaultMoments} from '../../constants';
import {SCREEN_HEIGHT} from '../../utils';
@@ -11,8 +12,9 @@ import ProfileHeader from './ProfileHeader';
interface ContentProps {
y: Animated.Value<number>;
+ isProfileView: boolean;
}
-const Content: React.FC<ContentProps> = ({y}) => {
+const Content: React.FC<ContentProps> = ({y, isProfileView}) => {
const [profileBodyHeight, setProfileBodyHeight] = useState(0);
const onLayout = (e: LayoutChangeEvent) => {
const {height} = e.nativeEvent.layout;
@@ -26,15 +28,19 @@ const Content: React.FC<ContentProps> = ({y}) => {
scrollEventThrottle={1}
stickyHeaderIndices={[2, 4]}>
<ProfileCutout>
- <ProfileHeader />
+ <ProfileHeader {...{isProfileView}} />
</ProfileCutout>
- <ProfileBody {...{onLayout}} />
- <TaggsBar {...{y, profileBodyHeight}} />
- <View style={styles.momentsContainer}>
- {defaultMoments.map((title, index) => (
- <Moment key={index} title={title} images={[]} />
- ))}
- </View>
+ <ProfileBody {...{onLayout, isProfileView}} />
+ <TaggsBar {...{y, profileBodyHeight, isProfileView}} />
+ {!isProfileView ? (
+ <View style={styles.momentsContainer}>
+ {defaultMoments.map((title, index) => (
+ <Moment key={index} title={title} images={[]} />
+ ))}
+ </View>
+ ) : (
+ <React.Fragment />
+ )}
</Animated.ScrollView>
);
};
diff --git a/src/components/profile/Cover.tsx b/src/components/profile/Cover.tsx
index 01199f06..37ecb9bd 100644
--- a/src/components/profile/Cover.tsx
+++ b/src/components/profile/Cover.tsx
@@ -2,14 +2,17 @@ import React from 'react';
import {Image, StyleSheet} from 'react-native';
import Animated from 'react-native-reanimated';
import {IMAGE_WIDTH, COVER_HEIGHT} from '../../constants';
-import {AuthContext} from '../../routes/authentication';
+import {AuthContext, ProfileContext} from '../../routes/';
const {interpolate, Extrapolate} = Animated;
interface CoverProps {
y: Animated.Value<number>;
+ isProfileView: boolean;
}
-const Cover: React.FC<CoverProps> = ({y}) => {
- const {cover} = React.useContext(AuthContext);
+const Cover: React.FC<CoverProps> = ({y, isProfileView}) => {
+ const {cover} = isProfileView
+ ? React.useContext(ProfileContext)
+ : React.useContext(AuthContext);
const scale: Animated.Node<number> = interpolate(y, {
inputRange: [-COVER_HEIGHT, 0],
outputRange: [1.5, 1.25],
diff --git a/src/components/profile/ProfileBody.tsx b/src/components/profile/ProfileBody.tsx
index e8d8de62..53b86708 100644
--- a/src/components/profile/ProfileBody.tsx
+++ b/src/components/profile/ProfileBody.tsx
@@ -1,15 +1,18 @@
import React from 'react';
import {StyleSheet, View, Text, LayoutChangeEvent} from 'react-native';
-import {AuthContext} from '../../routes/authentication';
+import {AuthContext, ProfileContext} from '../../routes/';
interface ProfileBodyProps {
onLayout: (event: LayoutChangeEvent) => void;
+ isProfileView: boolean;
}
-const ProfileBody: React.FC<ProfileBodyProps> = ({onLayout}) => {
+const ProfileBody: React.FC<ProfileBodyProps> = ({onLayout, isProfileView}) => {
const {
profile,
user: {username},
- } = React.useContext(AuthContext);
+ } = isProfileView
+ ? React.useContext(ProfileContext)
+ : React.useContext(AuthContext);
const {biography, website} = profile;
return (
<View onLayout={onLayout} style={styles.container}>
diff --git a/src/components/profile/ProfileHeader.tsx b/src/components/profile/ProfileHeader.tsx
index ec382357..62c103fd 100644
--- a/src/components/profile/ProfileHeader.tsx
+++ b/src/components/profile/ProfileHeader.tsx
@@ -4,16 +4,22 @@ import Avatar from './Avatar';
import FollowCount from './FollowCount';
import {View, Text, StyleSheet} from 'react-native';
import {SCREEN_HEIGHT, SCREEN_WIDTH} from '../../utils';
-import {AuthContext} from '../../routes/authentication';
+import {AuthContext, ProfileContext} from '../../routes/';
-const ProfileHeader: React.FC = () => {
+type ProfileHeaderProps = {
+ isProfileView: boolean;
+};
+
+const ProfileHeader: React.FC<ProfileHeaderProps> = ({isProfileView}) => {
const {
profile: {name},
- } = React.useContext(AuthContext);
+ } = isProfileView
+ ? React.useContext(ProfileContext)
+ : React.useContext(AuthContext);
return (
<View style={styles.container}>
<View style={styles.row}>
- <Avatar style={styles.avatar} />
+ <Avatar style={styles.avatar} isProfileView={isProfileView} />
<View style={styles.header}>
<Text style={styles.name}>{name}</Text>
<View style={styles.row}>
diff --git a/src/components/search/SearchResult.tsx b/src/components/search/SearchResult.tsx
index 952f08f7..cc960308 100644
--- a/src/components/search/SearchResult.tsx
+++ b/src/components/search/SearchResult.tsx
@@ -1,4 +1,4 @@
-import React, {useEffect, useState} from 'react';
+import React, {useEffect, useState, useContext} from 'react';
import {ProfilePreviewType} from '../../types';
import {
View,
@@ -8,10 +8,12 @@ import {
ViewProps,
TouchableOpacity,
} from 'react-native';
+import {useNavigation} from '@react-navigation/native';
import RNFetchBlob from 'rn-fetch-blob';
import AsyncStorage from '@react-native-community/async-storage';
import {AVATAR_PHOTO_ENDPOINT} from '../../constants';
import {UserType} from '../../types';
+import {ProfileContext} from '../../routes/viewProfile';
const NO_USER: UserType = {
userId: '',
username: '',
@@ -24,6 +26,8 @@ const SearchResult: React.FC<SearchResultProps> = ({
profilePreview: {username, first_name, last_name, id},
style,
}) => {
+ const navigation = useNavigation();
+ const {loadProfile} = useContext(ProfileContext);
const [avatarURI, setAvatarURI] = useState<string | null>(null);
const [user, setUser] = useState<UserType>(NO_USER);
useEffect(() => {
@@ -38,7 +42,7 @@ const SearchResult: React.FC<SearchResultProps> = ({
const response = await RNFetchBlob.config({
fileCache: true,
appendExt: 'jpg',
- }).fetch('GET', AVATAR_PHOTO_ENDPOINT + `${id}`, {
+ }).fetch('GET', AVATAR_PHOTO_ENDPOINT + `${id}/`, {
Authorization: 'Token ' + token,
});
const status = response.info().status;
@@ -66,7 +70,7 @@ const SearchResult: React.FC<SearchResultProps> = ({
* Cache maintains 10 recently searched users, popping off the oldest one if
* needed to make space.
*/
- const addToRecentlyStored = async () => {
+ const addToRecentlyStoredAndNavigateToProfile = async () => {
let user: ProfilePreviewType = {
id,
username,
@@ -95,6 +99,15 @@ const SearchResult: React.FC<SearchResultProps> = ({
} else {
recentlySearchedList = [user];
}
+
+ //Load user profile and navigate to ProfileView
+ //Load user profile makes sure that we actually load profile of the user the logged in user want to view
+ //Not sure if we should make this call before caching the search results ??
+ loadProfile(user.id, user.username);
+ navigation.navigate('Profile', {
+ isProfileView: true,
+ });
+
try {
let recentlySearchedListString = JSON.stringify(recentlySearchedList);
await AsyncStorage.setItem(
@@ -111,7 +124,7 @@ const SearchResult: React.FC<SearchResultProps> = ({
return (
<TouchableOpacity
- onPress={addToRecentlyStored}
+ onPress={addToRecentlyStoredAndNavigateToProfile}
style={[styles.container, style]}>
<Image
style={styles.avatar}
diff --git a/src/components/taggs/Tagg.tsx b/src/components/taggs/Tagg.tsx
index 341a713a..d6cffee5 100644
--- a/src/components/taggs/Tagg.tsx
+++ b/src/components/taggs/Tagg.tsx
@@ -1,12 +1,15 @@
import {useNavigation} from '@react-navigation/native';
import React from 'react';
-import {StyleSheet, TouchableOpacity, View, ViewProps} from 'react-native';
+import {StyleSheet, TouchableOpacity, View} from 'react-native';
import LinearGradient from 'react-native-linear-gradient';
import {TAGGS_GRADIENT} from '../../constants';
-interface TaggProps extends ViewProps {}
+interface TaggProps {
+ style: object;
+ isProfileView: boolean;
+}
-const Tagg: React.FC<TaggProps> = ({style}) => {
+const Tagg: React.FC<TaggProps> = ({style, isProfileView}) => {
const navigation = useNavigation();
return (
@@ -14,6 +17,7 @@ const Tagg: React.FC<TaggProps> = ({style}) => {
onPress={() =>
navigation.navigate('SocialMediaTaggs', {
socialMediaType: 'Instagram',
+ isProfileView: isProfileView,
})
}>
<LinearGradient
diff --git a/src/components/taggs/TaggsBar.tsx b/src/components/taggs/TaggsBar.tsx
index 1022c4fc..933f355d 100644
--- a/src/components/taggs/TaggsBar.tsx
+++ b/src/components/taggs/TaggsBar.tsx
@@ -10,11 +10,18 @@ const {View, ScrollView, interpolate, Extrapolate} = Animated;
interface TaggsBarProps {
y: Animated.Value<number>;
profileBodyHeight: number;
+ isProfileView: boolean;
}
-const TaggsBar: React.FC<TaggsBarProps> = ({y, profileBodyHeight}) => {
+const TaggsBar: React.FC<TaggsBarProps> = ({
+ y,
+ profileBodyHeight,
+ isProfileView,
+}) => {
const taggs: Array<JSX.Element> = [];
for (let i = 0; i < 10; i++) {
- taggs.push(<Tagg key={i} style={styles.tagg} />);
+ taggs.push(
+ <Tagg key={i} style={styles.tagg} isProfileView={isProfileView} />,
+ );
}
const shadowOpacity: Animated.Node<number> = interpolate(y, {
inputRange: [