diff options
author | Ashm Walia <40498934+ashmgarv@users.noreply.github.com> | 2020-10-18 16:37:32 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-10-18 19:37:32 -0400 |
commit | ab7fa09af967e0a8cf2ca53dfb24f8bc8a6886f7 (patch) | |
tree | 898e7aa42529eda91964ac1a18aa1881689554f2 /src/components | |
parent | 79d237f616c37940f5d476eb1dca6b5d05cf148a (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.tsx | 12 | ||||
-rw-r--r-- | src/components/profile/Avatar.tsx | 9 | ||||
-rw-r--r-- | src/components/profile/Content.tsx | 24 | ||||
-rw-r--r-- | src/components/profile/Cover.tsx | 9 | ||||
-rw-r--r-- | src/components/profile/ProfileBody.tsx | 9 | ||||
-rw-r--r-- | src/components/profile/ProfileHeader.tsx | 14 | ||||
-rw-r--r-- | src/components/search/SearchResult.tsx | 21 | ||||
-rw-r--r-- | src/components/taggs/Tagg.tsx | 10 | ||||
-rw-r--r-- | src/components/taggs/TaggsBar.tsx | 11 |
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: [ |