aboutsummaryrefslogtreecommitdiff
path: root/src/components/moments/MomentPost.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/moments/MomentPost.tsx')
-rw-r--r--src/components/moments/MomentPost.tsx347
1 files changed, 311 insertions, 36 deletions
diff --git a/src/components/moments/MomentPost.tsx b/src/components/moments/MomentPost.tsx
index d87028e3..6eccf5ab 100644
--- a/src/components/moments/MomentPost.tsx
+++ b/src/components/moments/MomentPost.tsx
@@ -1,38 +1,77 @@
-import React, {useEffect, useState} from 'react';
-import {StyleSheet} from 'react-native';
-import {useSelector} from 'react-redux';
-import {MomentPostContent, MomentPostHeader} from '.';
+import {useNavigation} from '@react-navigation/native';
+import React, {useContext, useEffect, useRef, useState} from 'react';
+import {
+ Image,
+ KeyboardAvoidingView,
+ Platform,
+ StatusBar,
+ StyleSheet,
+ Text,
+ TouchableOpacity,
+ TouchableWithoutFeedback,
+ View,
+} from 'react-native';
+import Animated, {EasingNode} from 'react-native-reanimated';
+import {useDispatch, useSelector, useStore} from 'react-redux';
+import {headerBarOptions} from '../../routes';
+import {MomentContext} from '../../screens/profile/IndividualMoment';
import {deleteMomentTag, loadMomentTags} from '../../services';
+import {loadUserMoments} from '../../store/actions';
import {RootState} from '../../store/rootReducer';
-import {MomentPostType, MomentTagType, ScreenType} from '../../types';
-import {normalize, SCREEN_HEIGHT} from '../../utils';
-
+import {MomentPostType, MomentTagType, ScreenType, UserType} from '../../types';
+import {
+ getTimePosted,
+ HeaderHeight,
+ isIPhoneX,
+ navigateToProfile,
+ normalize,
+ SCREEN_HEIGHT,
+ SCREEN_WIDTH,
+} from '../../utils';
+import {mentionPartTypes, renderTextWithMentions} from '../../utils/comments';
+import {AddComment} from '../comments';
+import CommentsCount from '../comments/CommentsCount';
+import {MomentTags} from '../common';
+import {MomentMoreInfoDrawer, TaggAvatar} from '../profile';
+import IndividualMomentTitleBar from './IndividualMomentTitleBar';
interface MomentPostProps {
moment: MomentPostType;
userXId: string | undefined;
screenType: ScreenType;
- index: number;
}
const MomentPost: React.FC<MomentPostProps> = ({
moment,
userXId,
screenType,
- index,
}) => {
+ const navigation = useNavigation();
+ const dispatch = useDispatch();
const {userId: loggedInUserId, username: loggedInUsername} = useSelector(
(state: RootState) => state.user.user,
);
-
- const {
- user: {username},
- } = useSelector((state: RootState) =>
+ const {user} = useSelector((state: RootState) =>
userXId ? state.userX[screenType][userXId] : state.user,
);
+ const state: RootState = useStore().getState();
+ const isOwnProfile = user.username === loggedInUsername;
+
const [tags, setTags] = useState<MomentTagType[]>([]);
+ const [visible, setVisible] = useState(false);
+ const [drawerVisible, setDrawerVisible] = useState(false);
+ const [hideText, setHideText] = useState(false);
+
+ const [fadeValue, setFadeValue] = useState<Animated.Value<number>>(
+ new Animated.Value(0),
+ );
+ const [commentCount, setCommentCount] = useState<number>(
+ moment.comments_count,
+ );
+ const [aspectRatio, setAspectRatio] = useState<number>(1);
const [momentTagId, setMomentTagId] = useState<string>('');
- const isOwnProfile = username === loggedInUsername;
+ const imageRef = useRef(null);
+ const {keyboardVisible} = useContext(MomentContext);
/*
* Load tags on initial render to pass tags data to moment header and content
@@ -41,7 +80,7 @@ const MomentPost: React.FC<MomentPostProps> = ({
loadMomentTags(moment.moment_id).then((response) => {
setTags(response ? response : []);
});
- }, []);
+ }, [moment]);
/*
* Check if loggedInUser has been tagged in the picture and set the id
@@ -71,34 +110,270 @@ const MomentPost: React.FC<MomentPostProps> = ({
}
};
+ useEffect(
+ () =>
+ navigation.setOptions({
+ ...headerBarOptions('white', ''),
+ headerTitle: () => (
+ <IndividualMomentTitleBar title={moment.moment_category} />
+ ),
+ }),
+ [moment.moment_id],
+ );
+
+ /*
+ * Determines if an image is 9:16 to set aspect ratio of current image and
+ * determine if image must be displayed in full screen or not
+ */
+ useEffect(() => {
+ Image.getSize(
+ moment.moment_url,
+ (w, h) => {
+ setAspectRatio(w / h);
+ },
+ (err) => console.log(err),
+ );
+ }, []);
+
+ /*
+ * To animate tags display
+ */
+ useEffect(() => {
+ const fade = async () => {
+ Animated.timing(fadeValue, {
+ toValue: 1,
+ duration: 250,
+ easing: EasingNode.linear,
+ }).start();
+ };
+ fade();
+ }, [fadeValue]);
+
+ useEffect(() => {
+ if (!keyboardVisible && hideText) {
+ setHideText(false);
+ }
+ }, [keyboardVisible, hideText]);
+
+ const MomentPosterPreview = () => (
+ <View style={styles.momentPosterContainer}>
+ <TouchableOpacity
+ onPress={() =>
+ navigateToProfile(state, dispatch, navigation, screenType, user)
+ }
+ style={styles.header}>
+ <TaggAvatar
+ style={styles.avatar}
+ userXId={userXId}
+ screenType={screenType}
+ editable={false}
+ />
+ <Text style={styles.headerText}>{user.username}</Text>
+ </TouchableOpacity>
+ </View>
+ );
+
return (
<>
- <MomentPostHeader
- style={styles.postHeader}
- userXId={userXId}
- screenType={screenType}
- username={isOwnProfile ? loggedInUsername : username}
- momentTagId={momentTagId}
- removeTag={removeTag}
- moment={moment}
- tags={tags}
- />
- <MomentPostContent
- style={styles.postContent}
- moment={moment}
- screenType={screenType}
- momentTags={tags}
- index={index}
- />
+ <StatusBar barStyle={'light-content'} />
+ <View style={styles.mainContainer}>
+ <View style={styles.imageContainer}>
+ <Image
+ source={{uri: moment.moment_url}}
+ style={[
+ styles.image,
+ {
+ height: SCREEN_WIDTH / aspectRatio,
+ },
+ ]}
+ resizeMode={'contain'}
+ ref={imageRef}
+ />
+ </View>
+ {visible && (
+ <Animated.View style={[styles.tagsContainer, {opacity: fadeValue}]}>
+ <MomentTags
+ editing={false}
+ tags={tags}
+ setTags={() => null}
+ imageRef={imageRef}
+ />
+ </Animated.View>
+ )}
+ <TouchableWithoutFeedback
+ onPress={() => {
+ setVisible(!visible);
+ setFadeValue(new Animated.Value(0));
+ }}>
+ <View style={styles.contentContainer}>
+ <View style={styles.topContainer}>
+ <MomentMoreInfoDrawer
+ isOpen={drawerVisible}
+ setIsOpen={setDrawerVisible}
+ isOwnProfile={isOwnProfile}
+ momentTagId={momentTagId}
+ removeTag={removeTag}
+ dismissScreenAndUpdate={() => {
+ dispatch(loadUserMoments(loggedInUserId));
+ navigation.goBack();
+ }}
+ screenType={screenType}
+ moment={moment}
+ tags={tags}
+ />
+ </View>
+ <KeyboardAvoidingView
+ behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
+ keyboardVerticalOffset={-20}>
+ <View style={styles.bottomContainer}>
+ {tags.length > 0 && (
+ <Image
+ source={require('../../assets/icons/tag_indicate.png')}
+ style={styles.tagIcon}
+ />
+ )}
+ <View style={styles.commentsCountContainer}>
+ <CommentsCount moment={moment} screenType={screenType} />
+ </View>
+ <MomentPosterPreview />
+ {!hideText && (
+ <>
+ {moment.caption !== '' &&
+ renderTextWithMentions({
+ value: moment.caption,
+ styles: styles.captionText,
+ partTypes: mentionPartTypes('white', 'caption'),
+ onPress: (userLocal: UserType) =>
+ navigateToProfile(
+ state,
+ dispatch,
+ navigation,
+ screenType,
+ userLocal,
+ ),
+ })}
+ </>
+ )}
+ <View>
+ <AddComment
+ placeholderText={'Add a comment here!'}
+ momentId={moment.moment_id}
+ callback={() => {
+ setCommentCount(commentCount + 1);
+ }}
+ onFocus={() => {
+ setHideText(true);
+ }}
+ isKeyboardAvoiding={false}
+ theme={'dark'}
+ />
+ <Text style={styles.text}>
+ {getTimePosted(moment.date_created)}
+ </Text>
+ </View>
+ </View>
+ </KeyboardAvoidingView>
+ </View>
+ </TouchableWithoutFeedback>
+ </View>
</>
);
};
const styles = StyleSheet.create({
- postHeader: {},
- postContent: {
- minHeight: SCREEN_HEIGHT * 0.8,
- paddingBottom: normalize(20),
+ image: {
+ zIndex: 0,
+ },
+ imageContainer: {
+ height: SCREEN_HEIGHT,
+ width: SCREEN_WIDTH,
+ flexDirection: 'column',
+ justifyContent: 'center',
+ overflow: 'hidden',
+ },
+ text: {
+ marginHorizontal: '5%',
+ color: 'white',
+ fontWeight: '500',
+ textAlign: 'right',
+ marginTop: 5,
+ },
+ captionText: {
+ position: 'relative',
+ marginHorizontal: '5%',
+ color: '#ffffff',
+ fontWeight: '500',
+ fontSize: normalize(13),
+ lineHeight: normalize(15.51),
+ letterSpacing: normalize(0.6),
+ marginBottom: normalize(5),
+ width: SCREEN_WIDTH * 0.79,
+ },
+ tagIcon: {
+ width: normalize(30),
+ height: normalize(30),
+ bottom: normalize(20),
+ left: '5%',
+ },
+ avatar: {
+ width: 48,
+ aspectRatio: 1,
+ borderRadius: 100,
+ marginLeft: '3%',
+ },
+ headerText: {
+ fontSize: 15,
+ fontWeight: 'bold',
+ color: 'white',
+ paddingHorizontal: '3%',
+ },
+ header: {
+ alignItems: 'center',
+ flexDirection: 'row',
+ marginBottom: normalize(15),
+ alignSelf: 'flex-start',
+ },
+ momentPosterContainer: {
+ flexDirection: 'column',
+ justifyContent: 'center',
+ alignItems: 'center',
+ },
+ commentsCountContainer: {
+ position: 'absolute',
+ right: '2%',
+ bottom: SCREEN_HEIGHT * 0.12,
+ },
+ bottomContainer: {
+ flexDirection: 'column',
+ justifyContent: 'flex-end',
+ },
+ topContainer: {
+ paddingTop: isIPhoneX() ? HeaderHeight : '6%',
+ alignSelf: 'flex-end',
+ paddingRight: '8%',
+ },
+ contentContainer: {
+ position: 'absolute',
+ width: SCREEN_WIDTH,
+ height: SCREEN_HEIGHT,
+ flexDirection: 'column',
+ justifyContent: 'space-between',
+ paddingBottom: '24%',
+ },
+ tagsContainer: {
+ position: 'absolute',
+ top: 0,
+ bottom: 0,
+ left: 0,
+ right: 0,
+ marginBottom: '3%',
+ },
+ mainContainer: {
+ backgroundColor: 'black',
+ width: SCREEN_WIDTH,
+ height: SCREEN_HEIGHT,
+ flexDirection: 'column',
+ justifyContent: 'center',
},
});