aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShravya Ramesh <37447613+shravyaramesh@users.noreply.github.com>2020-10-19 12:42:15 -0700
committerGitHub <noreply@github.com>2020-10-19 15:42:15 -0400
commit1b7fef188ec2aee0706fc1204432315db3d4fec6 (patch)
tree0f07d060f9f0f7343442f968d1a4be9b1ceff03f
parentf5853b77ef9506df056029282c475e5628fb6ab0 (diff)
Tma235/231 Individual view and horizontal view (#59)
* Implemented modal stack navigation for moment view, created a rough UI for individual moment view [incl: title, image(not displayed)] * bare bones beginnning * Created individual moment screen, moment tile for horizontal view * Alert * Fix initial route Co-authored-by: Ashm Walia <ashmwalia@outlook.com> Co-authored-by: Ashm Walia <40498934+ashmgarv@users.noreply.github.com>
-rw-r--r--package.json3
-rw-r--r--src/components/profile/Content.tsx79
-rw-r--r--src/components/profile/Moment.tsx41
-rw-r--r--src/components/profile/MomentTile.tsx33
-rw-r--r--src/constants/api.ts2
-rw-r--r--src/routes/authentication/AuthProvider.tsx9
-rw-r--r--src/routes/profile/MomentStack.tsx11
-rw-r--r--src/routes/profile/MomentStackScreen.tsx46
-rw-r--r--src/routes/profile/ProfileStack.tsx5
-rw-r--r--src/routes/profile/index.ts2
-rw-r--r--src/routes/tabs/NavigationBar.tsx11
-rw-r--r--src/screens/profile/CaptionScreen.tsx14
-rw-r--r--src/screens/profile/IndividualMoment.tsx162
-rw-r--r--src/screens/profile/index.ts1
-rw-r--r--src/types/types.ts8
15 files changed, 386 insertions, 41 deletions
diff --git a/package.json b/package.json
index c95b8f3f..e21b52c7 100644
--- a/package.json
+++ b/package.json
@@ -17,8 +17,9 @@
"@react-navigation/native": "^5.6.1",
"@react-navigation/stack": "^5.6.2",
"@types/react-native-vector-icons": "^6.4.5",
- "moment": "^2.27.0",
+ "moment": "^2.29.1",
"react": "16.13.1",
+ "react-moment": "^1.0.0",
"react-native": "0.63.3",
"react-native-animatable": "^1.3.3",
"react-native-confirmation-code-field": "^6.5.0",
diff --git a/src/components/profile/Content.tsx b/src/components/profile/Content.tsx
index 8d368747..d52696a7 100644
--- a/src/components/profile/Content.tsx
+++ b/src/components/profile/Content.tsx
@@ -1,8 +1,11 @@
-import React, {useState} from 'react';
-import {LayoutChangeEvent, StyleSheet, View} from 'react-native';
-import {Text} from 'react-native-animatable';
+import AsyncStorage from '@react-native-community/async-storage';
+import React, {useCallback, useEffect, useState} from 'react';
+import {Alert, LayoutChangeEvent, StyleSheet, View} from 'react-native';
+<!-- import {Text} from 'react-native-animatable'; -->
import Animated from 'react-native-reanimated';
-import {defaultMoments} from '../../constants';
+import {AuthContext} from '../../routes/authentication';
+import {MomentType, UserType} from 'src/types';
+import {defaultMoments, MOMENTS_ENDPOINT} from '../../constants';
import {SCREEN_HEIGHT} from '../../utils';
import TaggsBar from '../taggs/TaggsBar';
import Moment from './Moment';
@@ -14,12 +17,70 @@ interface ContentProps {
y: Animated.Value<number>;
isProfileView: boolean;
}
+
const Content: React.FC<ContentProps> = ({y, isProfileView}) => {
const [profileBodyHeight, setProfileBodyHeight] = useState(0);
+ const {newMomentsAvailable, updateMoments} = React.useContext(AuthContext);
+
+ const [imagesList, setImagesList] = useState<MomentType[]>([]);
+ const [imagesMap, setImagesMap] = useState<Map<string, MomentType[]>>(
+ new Map(),
+ );
const onLayout = (e: LayoutChangeEvent) => {
const {height} = e.nativeEvent.layout;
setProfileBodyHeight(height);
};
+
+ const {userId, username} = user;
+
+ const createImagesMap = useCallback(() => {
+ var map = new Map();
+ imagesList.forEach(function (imageObject) {
+ var moment_category = imageObject.moment_category;
+ if (map.has(moment_category)) {
+ map.get(moment_category).push(imageObject);
+ } else {
+ map.set(moment_category, [imageObject]);
+ }
+ });
+
+ setImagesMap(map);
+ console.log(map);
+ }, [imagesList]);
+
+ useEffect(() => {
+ if (!userId) {
+ return;
+ }
+
+ const retrieveMoments = async () => {
+ try {
+ const token = await AsyncStorage.getItem('token');
+ const response = await fetch(MOMENTS_ENDPOINT + `${userId}/`, {
+ method: 'GET',
+ headers: {
+ Authorization: 'Token ' + token,
+ },
+ });
+ const status = response.status;
+ if (status === 200) {
+ const data = await response.json();
+ setImagesList(data);
+ updateMoments(!newMomentsAvailable);
+ } else {
+ Alert.alert('Could not load moments!');
+ }
+ } catch (err) {
+ Alert.alert('Could not load moments!');
+ }
+ };
+
+ if (newMomentsAvailable) {
+ retrieveMoments();
+ createImagesMap();
+ }
+ }, [userId, createImagesMap, updateMoments, newMomentsAvailable]);
+
return (
<Animated.ScrollView
style={styles.container}
@@ -30,14 +91,16 @@ const Content: React.FC<ContentProps> = ({y, isProfileView}) => {
<ProfileCutout>
<ProfileHeader {...{isProfileView}} />
</ProfileCutout>
+ <ProfileBody {...{onLayout}} />
+ <TaggsBar {...{y, profileBodyHeight}} />
<ProfileBody {...{onLayout, isProfileView}} />
<TaggsBar {...{y, profileBodyHeight, isProfileView}} />
{!isProfileView ? (
<View style={styles.momentsContainer}>
- {defaultMoments.map((title, index) => (
- <Moment key={index} title={title} images={[]} />
- ))}
- </View>
+ {defaultMoments.map((title, index) => (
+ <Moment key={index} title={title} images={imagesMap.get(title)} />
+ ))}
+ </View>
) : (
<React.Fragment />
)}
diff --git a/src/components/profile/Moment.tsx b/src/components/profile/Moment.tsx
index 6ae8d38e..be7cbfba 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 {StyleSheet, View} from 'react-native';
+import {Alert, 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';
@@ -9,10 +9,12 @@ 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';
+import MomentTile from './MomentTile';
+import {MomentType} from 'src/types';
interface MomentProps {
title: string;
- images: Array<string>;
+ images: MomentType[] | undefined;
}
const Moment: React.FC<MomentProps> = ({title, images}) => {
@@ -28,10 +30,13 @@ const Moment: React.FC<MomentProps> = ({title, images}) => {
})
.then((picture) => {
if ('path' in picture) {
- navigation.navigate('CaptionScreen', {title: title, image: picture});
+ navigation.navigate('CaptionScreen', {
+ title: title,
+ image: picture,
+ });
}
})
- .catch(() => {});
+ .catch((err) => {Alert.alert('Unable to upload moment!');});
};
return (
<View style={styles.container}>
@@ -47,17 +52,23 @@ const Moment: React.FC<MomentProps> = ({title, images}) => {
horizontal
showsHorizontalScrollIndicator={false}
style={styles.scrollContainer}>
- <TouchableOpacity onPress={() => navigateToImagePicker()}>
- <LinearGradient
- colors={['rgba(105, 141, 211, 1)', 'rgba(105, 141, 211, 0.3)']}>
- <View style={styles.defaultImage}>
- <BigPlusIcon width={50} height={50} />
- <Text style={styles.defaultImageText}>
- Add a moment of your {title.toLowerCase()}!
- </Text>
- </View>
- </LinearGradient>
- </TouchableOpacity>
+ {images &&
+ images.map((imageObj: MomentType) => (
+ <MomentTile key={imageObj.moment_id} moment={imageObj} />
+ ))}
+ {(images === undefined || images.length === 0) && (
+ <TouchableOpacity onPress={() => navigateToImagePicker()}>
+ <LinearGradient
+ colors={['rgba(105, 141, 211, 1)', 'rgba(105, 141, 211, 0.3)']}>
+ <View style={styles.defaultImage}>
+ <BigPlusIcon width={50} height={50} />
+ <Text style={styles.defaultImageText}>
+ Add a moment of your {title.toLowerCase()}!
+ </Text>
+ </View>
+ </LinearGradient>
+ </TouchableOpacity>
+ )}
</ScrollView>
</View>
);
diff --git a/src/components/profile/MomentTile.tsx b/src/components/profile/MomentTile.tsx
new file mode 100644
index 00000000..70b20d40
--- /dev/null
+++ b/src/components/profile/MomentTile.tsx
@@ -0,0 +1,33 @@
+import {useNavigation} from '@react-navigation/native';
+import React from 'react';
+import {StyleSheet, View, Image, TouchableOpacity} from 'react-native';
+import {MomentType} from 'src/types';
+
+interface MomentTileProps {
+ moment: MomentType;
+}
+const MomentTile: React.FC<MomentTileProps> = ({moment}) => {
+ const navigation = useNavigation();
+ const {path_hash} = moment;
+ return (
+ <TouchableOpacity
+ onPress={() => {
+ navigation.navigate('IndividualMoment', {moment});
+ }}>
+ <View style={styles.image}>
+ <Image style={styles.image} source={{uri: path_hash}} />
+ </View>
+ </TouchableOpacity>
+ );
+};
+
+const styles = StyleSheet.create({
+ image: {
+ aspectRatio: 1,
+ height: '100%',
+ alignItems: 'center',
+ justifyContent: 'center',
+ flexDirection: 'column',
+ },
+});
+export default MomentTile;
diff --git a/src/constants/api.ts b/src/constants/api.ts
index 8e935714..93a68d65 100644
--- a/src/constants/api.ts
+++ b/src/constants/api.ts
@@ -12,7 +12,7 @@ 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 + 'moments/';
+export const MOMENTS_ENDPOINT: string = API_URL + 'moments/';
export const VERIFY_INVITATION_CODE_ENDPOUNT: string = API_URL + 'verify-code/';
// Social Link
diff --git a/src/routes/authentication/AuthProvider.tsx b/src/routes/authentication/AuthProvider.tsx
index 6f577a73..8dd9fd73 100644
--- a/src/routes/authentication/AuthProvider.tsx
+++ b/src/routes/authentication/AuthProvider.tsx
@@ -24,6 +24,8 @@ interface AuthContextProps {
cover: string | null;
instaPosts: Array<InstagramPostType>;
recentSearches: Array<ProfilePreviewType>;
+ newMomentsAvailable: boolean;
+ updateMoments: (value: boolean) => void;
}
const NO_USER: UserType = {
userId: '',
@@ -43,6 +45,8 @@ export const AuthContext = createContext<AuthContextProps>({
cover: null,
instaPosts: [],
recentSearches: [],
+ newMomentsAvailable: true,
+ updateMoments: () => {},
});
/**
@@ -57,6 +61,7 @@ const AuthProvider: React.FC = ({children}) => {
const [recentSearches, setRecentSearches] = useState<
Array<ProfilePreviewType>
>([]);
+ const [newMomentsAvailable, setNewMomentsAvailable] = useState<boolean>(true);
const {userId} = user;
useEffect(() => {
if (!userId) {
@@ -90,6 +95,7 @@ const AuthProvider: React.FC = ({children}) => {
avatar,
cover,
instaPosts,
+ newMomentsAvailable,
login: (id, username) => {
setUser({...user, userId: id, username});
},
@@ -105,6 +111,9 @@ const AuthProvider: React.FC = ({children}) => {
}
},
recentSearches,
+ updateMoments: (value) => {
+ setNewMomentsAvailable(value);
+ },
}}>
{children}
</AuthContext.Provider>
diff --git a/src/routes/profile/MomentStack.tsx b/src/routes/profile/MomentStack.tsx
new file mode 100644
index 00000000..83853c99
--- /dev/null
+++ b/src/routes/profile/MomentStack.tsx
@@ -0,0 +1,11 @@
+import {createStackNavigator} from '@react-navigation/stack';
+import {MomentType} from '../../types';
+
+export type MomentStackParams = {
+ Profile: undefined;
+ IndividualMoment: {
+ moment: MomentType;
+ };
+};
+
+export const MomentStack = createStackNavigator<MomentStackParams>();
diff --git a/src/routes/profile/MomentStackScreen.tsx b/src/routes/profile/MomentStackScreen.tsx
new file mode 100644
index 00000000..8768199a
--- /dev/null
+++ b/src/routes/profile/MomentStackScreen.tsx
@@ -0,0 +1,46 @@
+import React from 'react';
+import {IndividualMoment} from '../../screens';
+import {MomentStack} from './MomentStack';
+import Profile from './Profile';
+
+const MomentStackScreen: React.FC = () => {
+ return (
+ <MomentStack.Navigator
+ screenOptions={{
+ headerShown: false,
+ cardStyle: {backgroundColor: 'transparent'},
+ cardOverlayEnabled: true,
+ cardStyleInterpolator: ({current: {progress}}) => ({
+ cardStyle: {
+ opacity: progress.interpolate({
+ inputRange: [0, 0.5, 0.9, 1],
+ outputRange: [0, 0.25, 0.7, 1],
+ }),
+ },
+ overlayStyle: {
+ backgroundColor: '#808080',
+ opacity: progress.interpolate({
+ inputRange: [0, 1],
+ outputRange: [0, 0.9],
+ extrapolate: 'clamp',
+ }),
+ },
+ }),
+ }}
+ initialRouteName="Profile"
+ mode="modal">
+ <MomentStack.Screen
+ name="Profile"
+ component={Profile}
+ options={{headerShown: false}}
+ />
+ <MomentStack.Screen
+ name="IndividualMoment"
+ component={IndividualMoment}
+ options={{headerShown: false}}
+ />
+ </MomentStack.Navigator>
+ );
+};
+
+export default MomentStackScreen;
diff --git a/src/routes/profile/ProfileStack.tsx b/src/routes/profile/ProfileStack.tsx
index 63ab9a10..df4d234f 100644
--- a/src/routes/profile/ProfileStack.tsx
+++ b/src/routes/profile/ProfileStack.tsx
@@ -10,7 +10,10 @@ export type ProfileStackParams = {
socialMediaHandle: string;
isProfileView: boolean;
};
- CaptionScreen: {title: string; image: object};
+ CaptionScreen: {
+ title: string;
+ image: object;
+ };
};
export const ProfileStack = createStackNavigator<ProfileStackParams>();
diff --git a/src/routes/profile/index.ts b/src/routes/profile/index.ts
index 367f4cc6..1ab9cb7e 100644
--- a/src/routes/profile/index.ts
+++ b/src/routes/profile/index.ts
@@ -1,2 +1,4 @@
export * from './ProfileStack';
+export * from './MomentStack';
+export * from './MomentStackScreen';
export {default} from './Profile';
diff --git a/src/routes/tabs/NavigationBar.tsx b/src/routes/tabs/NavigationBar.tsx
index 2852b565..f05a512b 100644
--- a/src/routes/tabs/NavigationBar.tsx
+++ b/src/routes/tabs/NavigationBar.tsx
@@ -3,6 +3,7 @@ import React from 'react';
import {NavigationIcon} from '../../components';
import {Home, Notifications, Upload} from '../../screens';
import Profile from '../profile';
+import MomentStackScreen from '../profile/MomentStackScreen';
const Tabs = createBottomTabNavigator();
@@ -35,7 +36,7 @@ const NavigationBar: React.FC = () => {
) : (
<NavigationIcon tab="Notifications" disabled={true} />
);
- } else if (route.name === 'Profile') {
+ } else if (route.name === 'MomentStackScreen') {
return focused ? (
<NavigationIcon tab="Profile" disabled={false} />
) : (
@@ -44,7 +45,7 @@ const NavigationBar: React.FC = () => {
}
},
})}
- initialRouteName="Profile"
+ initialRouteName="MomentStackScreen"
tabBarOptions={{
showLabel: false,
style: {
@@ -64,11 +65,7 @@ const NavigationBar: React.FC = () => {
/>
<Tabs.Screen name="Upload" component={Upload} />
<Tabs.Screen name="Notifications" component={Notifications} />
- <Tabs.Screen
- name="Profile"
- component={Profile}
- initialParams={{isProfileView: false}}
- />
+ <Tabs.Screen name="MomentStackScreen" component={MomentStackScreen} />
</Tabs.Navigator>
);
};
diff --git a/src/screens/profile/CaptionScreen.tsx b/src/screens/profile/CaptionScreen.tsx
index 53c47a6d..d65a8451 100644
--- a/src/screens/profile/CaptionScreen.tsx
+++ b/src/screens/profile/CaptionScreen.tsx
@@ -9,7 +9,7 @@ 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 {MOMENTS_ENDPOINT} from '../../constants';
import {AuthContext} from '../../routes/authentication';
const NO_USER: UserType = {
@@ -34,8 +34,8 @@ const CaptionScreen: React.FC<CaptionScreenProps> = ({route, navigation}) => {
const {title, image} = route.params;
const {
user: {userId},
+ updateMoments,
} = React.useContext(AuthContext);
- const [user, setUser] = useState<UserType>(NO_USER);
const [caption, setCaption] = React.useState('');
const handleCaptionUpdate = (caption: string) => {
@@ -53,11 +53,6 @@ const CaptionScreen: React.FC<CaptionScreenProps> = ({route, navigation}) => {
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;
@@ -69,7 +64,8 @@ const CaptionScreen: React.FC<CaptionScreenProps> = ({route, navigation}) => {
request.append('moment', title);
request.append('user_id', userId);
request.append('captions', JSON.stringify({image: caption}));
- let response = await fetch(MOMENTS_UPLOAD_ENDPOINT, {
+ const token = await AsyncStorage.getItem('token');
+ let response = await fetch(MOMENTS_ENDPOINT, {
method: 'POST',
headers: {
'Content-Type': 'multipart/form-data',
@@ -81,6 +77,7 @@ const CaptionScreen: React.FC<CaptionScreenProps> = ({route, navigation}) => {
let data = await response.json();
if (statusCode === 200 && checkImageUploadStatus(data)) {
Alert.alert('The picture was uploaded successfully!');
+ updateMoments(true);
navigation.navigate('Profile');
} else {
Alert.alert('An error occured while uploading. Please try again!');
@@ -89,6 +86,7 @@ const CaptionScreen: React.FC<CaptionScreenProps> = ({route, navigation}) => {
Alert.alert('An error occured during authenticaion. Please login again!');
}
};
+
return (
<SearchBackground>
<View style={styles.contentContainer}>
diff --git a/src/screens/profile/IndividualMoment.tsx b/src/screens/profile/IndividualMoment.tsx
new file mode 100644
index 00000000..377898c1
--- /dev/null
+++ b/src/screens/profile/IndividualMoment.tsx
@@ -0,0 +1,162 @@
+import React, {useEffect, useState} from 'react';
+import {StyleSheet, View, Image} from 'react-native';
+import {Button} from 'react-native-elements';
+import {SCREEN_HEIGHT, SCREEN_WIDTH, StatusBarHeight} from '../../utils';
+import {UserType} from '../../types';
+import {RouteProp} from '@react-navigation/native';
+import {StackNavigationProp} from '@react-navigation/stack';
+import {CaptionScreenHeader} from '../../components/profile';
+import {AuthContext} from '../../routes/authentication';
+import {MomentStackParams} from 'src/routes/profile/MomentStack';
+import moment from 'moment';
+import Animated from 'react-native-reanimated';
+
+const NO_USER: UserType = {
+ userId: '',
+ username: '',
+};
+
+/**
+ * Individual moment view opened when user clicks on a moment tile
+ */
+type IndividualMomentRouteProp = RouteProp<
+ MomentStackParams,
+ 'IndividualMoment'
+>;
+type IndividualMomentNavigationProp = StackNavigationProp<
+ MomentStackParams,
+ 'IndividualMoment'
+>;
+interface IndividualMomentProps {
+ route: IndividualMomentRouteProp;
+ navigation: IndividualMomentNavigationProp;
+}
+
+const IndividualMoment: React.FC<IndividualMomentProps> = ({
+ route,
+ navigation,
+}) => {
+ const {
+ moment_category,
+ path_hash,
+ date_time,
+ moment_id,
+ } = route.params.moment;
+ const {
+ user: {userId},
+ } = React.useContext(AuthContext);
+ const [user, setUser] = useState<UserType>(NO_USER);
+ const [caption, setCaption] = React.useState(route.params.moment.caption);
+ const [elapsedTime, setElapsedTime] = React.useState<string>();
+ const handleCaptionUpdate = (caption: string) => {
+ setCaption(caption);
+ };
+
+ useEffect(() => {
+ if (!userId) {
+ setUser(NO_USER);
+ }
+ const timePeriod = async () => {
+ const datePosted = moment(date_time);
+ const now = moment();
+ var time = date_time;
+ var difference = now.diff(datePosted, 'seconds');
+
+ //Creating elapsedTime string to display to user
+ // 0 to less than 1 minute
+ if (difference < 60) {
+ time = difference + 'seconds';
+ }
+ // 1 minute to less than 1 hour
+ else if (difference >= 60 && difference < 60 * 60) {
+ difference = now.diff(datePosted, 'minutes');
+ time = difference + (difference === 1 ? 'minute' : 'minutes');
+ }
+ //1 hour to less than 1 day
+ else if (difference >= 60 * 60 && difference < 24 * 60 * 60) {
+ difference = now.diff(datePosted, 'hours');
+ time = difference + (difference === 1 ? 'hour' : 'hours');
+ }
+ //1 day to less than 7 days
+ else if (difference >= 24 * 60 * 60 && difference < 7 * 24 * 60 * 60) {
+ difference = now.diff(datePosted, 'days');
+ time = difference + (difference === 1 ? 'day' : 'days');
+ }
+
+ setElapsedTime(time);
+ };
+ timePeriod();
+ }, [date_time, userId]);
+
+ return (
+ <View style={styles.contentContainer}>
+ <View style={styles.buttonsContainer}>
+ <Button
+ title="Close"
+ buttonStyle={styles.button}
+ onPress={() => {
+ navigation.navigate('Profile');
+ }}
+ />
+ </View>
+ <CaptionScreenHeader
+ style={styles.header}
+ {...{title: moment_category}}
+ />
+ <Image
+ style={styles.image}
+ source={{uri: path_hash}}
+ resizeMode={'cover'}
+ />
+ <View style={styles.bodyContainer}>
+ <Animated.Text style={styles.text}>{caption}</Animated.Text>
+ <Animated.Text style={styles.text}>{elapsedTime}</Animated.Text>
+ </View>
+ </View>
+ );
+};
+const styles = StyleSheet.create({
+ contentContainer: {
+ width: SCREEN_WIDTH,
+ paddingTop: StatusBarHeight,
+ paddingBottom: SCREEN_HEIGHT,
+ backgroundColor: 'transparent',
+ },
+ buttonsContainer: {
+ flexDirection: 'row',
+ justifyContent: 'space-between',
+ marginLeft: '3%',
+ marginRight: '3%',
+ },
+ button: {
+ backgroundColor: 'transparent',
+ },
+ shareButtonTitle: {
+ fontWeight: 'bold',
+ color: '#6EE7E7',
+ },
+ header: {
+ marginVertical: 20,
+ },
+ image: {
+ position: 'relative',
+ width: SCREEN_WIDTH,
+ aspectRatio: 1,
+ marginBottom: '3%',
+ },
+ bodyContainer: {
+ flexDirection: 'row',
+ justifyContent: 'space-between',
+ marginLeft: '5%',
+ marginRight: '5%',
+ },
+ text: {
+ position: 'relative',
+ paddingBottom: '1%',
+ paddingTop: '1%',
+ color: '#ffffff',
+ fontWeight: 'bold',
+ },
+});
+
+export default IndividualMoment;
diff --git a/src/screens/profile/index.ts b/src/screens/profile/index.ts
index 5d2cde7c..6319c17d 100644
--- a/src/screens/profile/index.ts
+++ b/src/screens/profile/index.ts
@@ -1,3 +1,4 @@
export {default as ProfileScreen} from './ProfileScreen';
export {default as SocialMediaTaggs} from './SocialMediaTaggs';
export {default as CaptionScreen} from './CaptionScreen';
+export {default as IndividualMoment} from './IndividualMoment';
diff --git a/src/types/types.ts b/src/types/types.ts
index d8dc95fe..4473878f 100644
--- a/src/types/types.ts
+++ b/src/types/types.ts
@@ -39,3 +39,11 @@ export interface PostType {
export interface LinkerType {
label: string;
}
+
+export interface MomentType {
+ caption: string;
+ date_time: string;
+ moment_category: string;
+ path_hash: string;
+ moment_id: string;
+}