diff options
author | Shravya Ramesh <37447613+shravyaramesh@users.noreply.github.com> | 2020-10-13 13:34:42 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-10-13 16:34:42 -0400 |
commit | 22142e2f8aa7d5eed8de1e520fd5ce825d2c63ca (patch) | |
tree | 46dd2646359fadd99dd41d8d3e67d11c8cade8a5 /src | |
parent | 2bd196c6165cbf45544dbc0a021daf5d313fde3c (diff) |
TMA - 232 Create caption screen with image picker (#53)
* Added image picture functionality
* Created caption screen and uploads to moments endpoint consisting of the picture and caption only
Co-authored-by: Husam Salhab <47015061+hsalhab@users.noreply.github.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/components/profile/CaptionScreenHeader.tsx | 37 | ||||
-rw-r--r-- | src/components/profile/Moment.tsx | 19 | ||||
-rw-r--r-- | src/components/profile/index.ts | 1 | ||||
-rw-r--r-- | src/constants/api.ts | 1 | ||||
-rw-r--r-- | src/routes/profile/Profile.tsx | 3 | ||||
-rw-r--r-- | src/routes/profile/ProfileStack.tsx | 1 | ||||
-rw-r--r-- | src/screens/profile/CaptionScreen.tsx | 156 | ||||
-rw-r--r-- | src/screens/profile/index.ts | 1 |
8 files changed, 215 insertions, 4 deletions
diff --git a/src/components/profile/CaptionScreenHeader.tsx b/src/components/profile/CaptionScreenHeader.tsx new file mode 100644 index 00000000..4715b4ef --- /dev/null +++ b/src/components/profile/CaptionScreenHeader.tsx @@ -0,0 +1,37 @@ +import React from 'react'; +import {Text, View, StyleSheet, ViewProps} from 'react-native'; +interface CaptionScreenHeaderProps extends ViewProps { + title: string; +} +const CaptionScreenHeader: React.FC<CaptionScreenHeaderProps> = ({ + title, + style, +}) => { + return ( + <View style={[styles.container, style]}> + <View style={styles.headerContainer}> + <Text style={styles.header}>{title}</Text> + </View> + </View> + ); +}; + +const styles = StyleSheet.create({ + container: { + flexDirection: 'row', + justifyContent: 'center', + height: 30, + }, + headerContainer: { + position: 'absolute', + left: '50%', + }, + header: { + position: 'relative', + right: '50%', + fontSize: 20, + fontWeight: 'bold', + color: 'white', + }, +}); +export default CaptionScreenHeader; diff --git a/src/components/profile/Moment.tsx b/src/components/profile/Moment.tsx index 0fbabe8f..6ae8d38e 100644 --- a/src/components/profile/Moment.tsx +++ b/src/components/profile/Moment.tsx @@ -1,6 +1,6 @@ import {useNavigation} from '@react-navigation/native'; import React from 'react'; -import {Alert, StyleSheet, View} from 'react-native'; +import {StyleSheet, View} from 'react-native'; import {Text} from 'react-native-animatable'; import {ScrollView, TouchableOpacity} from 'react-native-gesture-handler'; import LinearGradient from 'react-native-linear-gradient'; @@ -8,6 +8,7 @@ import PlusIcon from '../../assets/icons/plus_icon-01.svg'; import BigPlusIcon from '../../assets/icons/plus_icon-02.svg'; import {MOMENTS_TITLE_COLOR} from '../../constants'; import {SCREEN_WIDTH} from '../../utils'; +import ImagePicker from 'react-native-image-crop-picker'; interface MomentProps { title: string; @@ -16,9 +17,21 @@ interface MomentProps { const Moment: React.FC<MomentProps> = ({title, images}) => { const navigation = useNavigation(); + const navigateToImagePicker = () => { - Alert.alert('Perform navigation to Image Picker with Caption screen'); - // navigation.navigate('') + ImagePicker.openPicker({ + width: 580, + height: 580, + cropping: true, + cropperToolbarTitle: 'Upload a moment', + mediaType: 'photo', + }) + .then((picture) => { + if ('path' in picture) { + navigation.navigate('CaptionScreen', {title: title, image: picture}); + } + }) + .catch(() => {}); }; return ( <View style={styles.container}> diff --git a/src/components/profile/index.ts b/src/components/profile/index.ts index 2d16c830..4eb435df 100644 --- a/src/components/profile/index.ts +++ b/src/components/profile/index.ts @@ -5,3 +5,4 @@ export {default as ProfileCutout} from './ProfileCutout'; export {default as ProfileBody} from './ProfileBody'; export {default as ProfileHeader} from './ProfileHeader'; export {default as Feed} from './Feed'; +export {default as CaptionScreenHeader} from './CaptionScreenHeader'; diff --git a/src/constants/api.ts b/src/constants/api.ts index fa8cd0b3..b1ec19aa 100644 --- a/src/constants/api.ts +++ b/src/constants/api.ts @@ -12,4 +12,5 @@ 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/'; export const SEARCH_ENDPOINT: string = API_URL + 'search/'; +export const MOMENTS_UPLOAD_ENDPOINT: string = API_URL + 'upload-moments/'; export const VERIFY_INVITATION_CODE_ENDPOUNT: string = API_URL + 'verify-code/'; diff --git a/src/routes/profile/Profile.tsx b/src/routes/profile/Profile.tsx index caa75f3b..eaf5f3aa 100644 --- a/src/routes/profile/Profile.tsx +++ b/src/routes/profile/Profile.tsx @@ -1,6 +1,6 @@ import React from 'react'; import {AvatarTitle} from '../../components'; -import {ProfileScreen, SocialMediaTaggs} from '../../screens'; +import {ProfileScreen, CaptionScreen, SocialMediaTaggs} from '../../screens'; import {ProfileStack} from './ProfileStack'; const Profile: React.FC = () => { @@ -20,6 +20,7 @@ const Profile: React.FC = () => { headerTitle: () => <AvatarTitle />, }} /> + <ProfileStack.Screen name="CaptionScreen" component={CaptionScreen} /> </ProfileStack.Navigator> ); }; diff --git a/src/routes/profile/ProfileStack.tsx b/src/routes/profile/ProfileStack.tsx index 9a39aa97..c1da67c1 100644 --- a/src/routes/profile/ProfileStack.tsx +++ b/src/routes/profile/ProfileStack.tsx @@ -6,6 +6,7 @@ export type ProfileStackParams = { socialMediaType: string; socialMediaHandle: string; }; + CaptionScreen: {title: string; image: object}; }; export const ProfileStack = createStackNavigator<ProfileStackParams>(); diff --git a/src/screens/profile/CaptionScreen.tsx b/src/screens/profile/CaptionScreen.tsx new file mode 100644 index 00000000..3eb6c47b --- /dev/null +++ b/src/screens/profile/CaptionScreen.tsx @@ -0,0 +1,156 @@ +import React, {useState} from 'react'; +import {StyleSheet, View, Image, Alert} from 'react-native'; +import {Button} from 'react-native-elements'; +import {SearchBackground, TabsGradient, TaggBigInput} from '../../components'; +import {SCREEN_HEIGHT, SCREEN_WIDTH, StatusBarHeight} from '../../utils'; +import AsyncStorage from '@react-native-community/async-storage'; +import {UserType} from '../../types'; +import {RouteProp} from '@react-navigation/native'; +import {ProfileStackParams} from 'src/routes'; +import {StackNavigationProp} from '@react-navigation/stack'; +import {CaptionScreenHeader} from '../../components/profile'; +import {MOMENTS_UPLOAD_ENDPOINT} from '../../constants'; +import {AuthContext} from '../../routes/authentication'; + +const NO_USER: UserType = { + userId: '', + username: '', +}; + +/** + * Upload Screen to allow users to upload posts to Tagg + */ +type CaptionScreenRouteProp = RouteProp<ProfileStackParams, 'CaptionScreen'>; +type CaptionScreenNavigationProp = StackNavigationProp< + ProfileStackParams, + 'CaptionScreen' +>; +interface CaptionScreenProps { + route: CaptionScreenRouteProp; + navigation: CaptionScreenNavigationProp; +} + +const CaptionScreen: React.FC<CaptionScreenProps> = ({route, navigation}) => { + const {title, image} = route.params; + const { + user: {userId}, + } = React.useContext(AuthContext); + const [user, setUser] = useState<UserType>(NO_USER); + const [caption, setCaption] = React.useState(''); + + const handleCaptionUpdate = (caption: string) => { + setCaption(caption); + }; + + const handleShare = async () => { + try { + const token = await AsyncStorage.getItem('token'); + if (!token) { + setUser(NO_USER); + return; + } + const request = new FormData(); + const uri = image.path; + const name = image.filename; + request.append('image', { + uri: uri, + name: name, + type: 'image/jpg', + }); + request.append('moment', title); + request.append('user_id', userId); + request.append('caption', caption); + let response = await fetch(MOMENTS_UPLOAD_ENDPOINT, { + method: 'POST', + headers: { + 'Content-Type': 'multipart/form-data', + Authorization: 'Token ' + token, + }, + body: request, + }); + let statusCode = response.status; + if (statusCode === 200) { + navigation.navigate('Profile'); + } else { + Alert.alert('An error occured while uploading. Please try again!'); + } + } catch (err) { + Alert.alert('An error occured during authenticaion. Please login again!'); + } + }; + return ( + <SearchBackground> + <View style={styles.contentContainer}> + <View style={styles.buttonsContainer}> + <Button + title="Cancel" + buttonStyle={styles.button} + onPress={() => { + navigation.navigate('Profile'); + }} + /> + <Button + title="Share" + titleStyle={styles.shareButtonTitle} + buttonStyle={styles.button} + onPress={handleShare} + /> + </View> + <CaptionScreenHeader style={styles.header} {...{title: title}} /> + <Image + style={styles.image} + source={{uri: image.path}} + resizeMode={'cover'} + /> + <TaggBigInput + style={styles.text} + multiline + placeholder="Write something....." + placeholderTextColor="gray" + onChangeText={handleCaptionUpdate} + /> + </View> + <TabsGradient /> + </SearchBackground> + ); +}; +const styles = StyleSheet.create({ + contentContainer: { + paddingTop: StatusBarHeight, + paddingBottom: SCREEN_HEIGHT, + }, + buttonsContainer: { + flexDirection: 'row', + justifyContent: 'space-between', + marginLeft: '5%', + marginRight: '5%', + }, + button: { + backgroundColor: 'transparent', + }, + shareButtonTitle: { + fontWeight: 'bold', + color: '#6EE7E7', + }, + header: { + marginVertical: 20, + }, + image: { + position: 'relative', + width: SCREEN_WIDTH, + aspectRatio: 1, + marginBottom: '3%', + }, + text: { + position: 'relative', + backgroundColor: 'white', + width: '100%', + paddingLeft: '2%', + paddingRight: '2%', + paddingBottom: '1%', + paddingTop: '1%', + height: 60, + }, +}); + +export default CaptionScreen; diff --git a/src/screens/profile/index.ts b/src/screens/profile/index.ts index bc86031f..5d2cde7c 100644 --- a/src/screens/profile/index.ts +++ b/src/screens/profile/index.ts @@ -1,2 +1,3 @@ export {default as ProfileScreen} from './ProfileScreen'; export {default as SocialMediaTaggs} from './SocialMediaTaggs'; +export {default as CaptionScreen} from './CaptionScreen'; |