Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 10 additions & 4 deletions App.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
ImageScreen,
LoginScreen,
RegistrationScreen,
BioScreen,
} from './src/screens';
import HeaderIcons from './src/components/HeaderIcons';
import {AuthContext} from './src/lib/context/AuthContext/AuthContextProvider';
Expand Down Expand Up @@ -57,10 +58,15 @@ export default function App({navigation}) {
component={ImageScreen}
options={() => ({
headerTransparent: true,
headerStyle: {
backgroundColor: '#000',
opacity: 0.5,
},
headerTitle: false,
headerLeft: () => <BackButton />,
})}
/>
<Stack.Screen
name="Bio"
component={BioScreen}
options={() => ({
headerTransparent: true,
headerTitle: false,
headerLeft: () => <BackButton />,
})}
Expand Down
43 changes: 43 additions & 0 deletions src/components/ImageSquare.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import React from 'react';
import {
View,
Image,
StatusBar,
StyleSheet,
TouchableOpacity,
} from 'react-native';
import {useNavigation} from '@react-navigation/native';

const ImageSquare = ({photo}) => {
const navigation = useNavigation();

const onImagePress = () => {
navigation.push('Image', {photo});
};

return (
<View style={styles.container} key={photo.id}>
<StatusBar barStyle="light-content" />
<TouchableOpacity style={styles.photoContainer} onPress={onImagePress}>
<Image style={styles.image} source={{uri: photo?.urls.regular}} />
</TouchableOpacity>
</View>
);
};

const styles = StyleSheet.create({
container: {
flex: 1,
width: '90%',
},
photoContainer: {
alignItems: 'center',
},
image: {
width: '100%',
height: 196,
borderRadius: 4,
},
});

export default ImageSquare;
23 changes: 18 additions & 5 deletions src/components/ImageToolbar.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,23 @@
import React from 'react';
import {Text, View, Image, StyleSheet} from 'react-native';
import {Text, View, Image, StyleSheet, TouchableOpacity} from 'react-native';
import {useNavigation} from '@react-navigation/native';

import Heart from '../assets/Heart';

const ImageToolbar = ({photo, fullScreen}) => {
const navigation = useNavigation();

const onUserPress = () => {
navigation.navigate('Bio', {photo});
};

return (
<View
style={
fullScreen
? {
...styles.bottomToolbar,
...styles.bottomToolbarFillSize,
...styles.bottomToolbarFullSize,
}
: styles.bottomToolbar
}>
Expand All @@ -18,7 +26,9 @@ const ImageToolbar = ({photo, fullScreen}) => {
source={{uri: photo?.user.profile_image.small}}
/>

<Text style={styles.username}>{photo?.user.username}</Text>
<TouchableOpacity style={styles.usernameContainer} onPress={onUserPress}>
<Text style={styles.username}>{photo?.user.username}</Text>
</TouchableOpacity>
<View style={styles.heartIcon}>
<Heart />
</View>
Expand All @@ -36,7 +46,7 @@ const styles = StyleSheet.create({
flexDirection: 'row',
backgroundColor: 'rgba(0, 0, 0, 0.3)',
},
bottomToolbarFillSize: {
bottomToolbarFullSize: {
width: '100%',
height: '10%',
paddingBottom: 5,
Expand All @@ -47,14 +57,17 @@ const styles = StyleSheet.create({
borderRadius: 16,
marginLeft: 7,
},
username: {
usernameContainer: {
fontFamily: 'Helvetica Neue',
fontWeight: '300',
fontSize: 13,
color: '#FFF',
paddingLeft: 6,
flex: 1,
},
username: {
color: '#FFF',
},
heartIcon: {
marginRight: 12,
},
Expand Down
124 changes: 124 additions & 0 deletions src/screens/BioScreen.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
import React, {useEffect, useState} from 'react';
import {
View,
StatusBar,
Image,
Text,
StyleSheet,
FlatList,
Dimensions,
ImageBackground,
} from 'react-native';
import config from 'react-native-config';

import ImageSquare from '../components/ImageSquare';

const screenWidth = Dimensions.get('window').width;

const BioScreen = ({route}) => {
const {photo} = route.params;
const [photos, setPhotos] = useState([]);
const [pageNumber, setPageNumber] = useState(1);

useEffect(() => {
loadUserPhotos();
}, []);

const loadUserPhotos = () => {
fetch(
`https://api.unsplash.com/users/${photo.user.username}/photos/?client_id=${config.UNSPLASH_APP_CLIENT_ID}&page=${pageNumber}`,
)
.then(response => response.json())
.then(data => {
const photosArray = [...photos, ...data];
setPhotos(photosArray);
setPageNumber(pageNumber + 1);
})
.catch(e => {
alert(e.message);
});
};
const renderPhoto = ({item}) => {
return (
<View style={styles.imageSquareContainer}>
<ImageSquare photo={item} />
</View>
);
};
const renderHeader = () => {
return (
<>
<ImageBackground
source={{uri: photo?.urls.regular}}
style={styles.userCoverImage}>
<View style={styles.userBioContainer}>
<Image
source={{uri: photo?.user.profile_image.large}}
style={styles.userBioImage}
/>
<Text style={styles.usernameBio}>{photo?.user.username}</Text>
<Text style={styles.descriptionBio}>{photo?.user?.bio}</Text>
</View>
</ImageBackground>
</>
);
};

return (
<View style={styles.container}>
<StatusBar barStyle="light-content" />
<FlatList
data={photos}
ListHeaderComponent={renderHeader}
onEndReached={loadUserPhotos}
onEndReachedThreshold={0.5}
renderItem={renderPhoto}
numColumns={3}
columnWrapperStyle={styles.columns}
/>
</View>
);
};

const styles = StyleSheet.create({
container: {
flex: 1,
},
descriptionBio: {
fontSize: 20,
textAlign: 'center',
},
columns: {
padding: 10,
},
usernameBio: {
fontWeight: 'bold',
textAlign: 'center',
fontSize: 24,
paddingBottom: 10,
},
userBioImage: {
width: 180,
height: 180,
borderRadius: 180 / 2,
},
userBioContainer: {
paddingTop: '35%',
paddingBottom: 25,
width: '90%',
alignItems: 'center',
flex: 1,
},
userCoverImage: {
position: 'relative',
width: '100%',
flex: 1,
height: '50%',
justifyContent: 'center',
alignItems: 'center',
},
imageSquareContainer: {
width: screenWidth / 3,
},
});
export default BioScreen;
1 change: 0 additions & 1 deletion src/screens/HomeScreen.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import React, {useEffect, useState} from 'react';
import {FlatList, StyleSheet} from 'react-native';
import config from 'react-native-config';
import Reactotron from 'reactotron-react-native';

import VerticalImageIndex from '../components/VerticalImageIndex';

Expand Down
2 changes: 2 additions & 0 deletions src/screens/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@ export {default as HomeScreen} from './HomeScreen';
export {default as ImageScreen} from './ImageScreen';

export {default as RegistrationScreen} from './RegistrationScreen';

export {default as BioScreen} from './BioScreen';