aboutsummaryrefslogtreecommitdiff
path: root/src/components/moments
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/moments')
-rw-r--r--src/components/moments/IndividualMomentTitleBar.tsx12
-rw-r--r--src/components/moments/MomentCommentPreview.tsx97
-rw-r--r--src/components/moments/MomentPost.tsx67
-rw-r--r--src/components/moments/MomentPostContent.tsx157
-rw-r--r--src/components/moments/MomentPostHeader.tsx15
5 files changed, 230 insertions, 118 deletions
diff --git a/src/components/moments/IndividualMomentTitleBar.tsx b/src/components/moments/IndividualMomentTitleBar.tsx
index 79453ade..4ae9471f 100644
--- a/src/components/moments/IndividualMomentTitleBar.tsx
+++ b/src/components/moments/IndividualMomentTitleBar.tsx
@@ -1,8 +1,13 @@
import React from 'react';
-import {TouchableOpacity} from 'react-native';
-import {Text, View, StyleSheet, ViewProps} from 'react-native';
-import {normalize} from '../../utils';
+import {
+ StyleSheet,
+ Text,
+ TouchableOpacity,
+ View,
+ ViewProps,
+} from 'react-native';
import CloseIcon from '../../assets/ionicons/close-outline.svg';
+import {normalize} from '../../utils';
interface IndividualMomentTitleBarProps extends ViewProps {
title: string;
@@ -30,7 +35,6 @@ const styles = StyleSheet.create({
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'flex-start',
- height: '5%',
},
headerContainer: {
width: '80%',
diff --git a/src/components/moments/MomentCommentPreview.tsx b/src/components/moments/MomentCommentPreview.tsx
new file mode 100644
index 00000000..e53ed258
--- /dev/null
+++ b/src/components/moments/MomentCommentPreview.tsx
@@ -0,0 +1,97 @@
+import {useNavigation} from '@react-navigation/native';
+import React from 'react';
+import {Image, StyleSheet, Text, View} from 'react-native';
+import {TouchableOpacity} from 'react-native-gesture-handler';
+import {useDispatch, useStore} from 'react-redux';
+import {MomentCommentPreviewType, ScreenType, UserType} from '../../types';
+import {navigateToProfile, normalize} from '../../utils';
+import {mentionPartTypes, renderTextWithMentions} from '../../utils/comments';
+
+interface MomentCommentPreviewProps {
+ momentId: string;
+ commentsCount: number;
+ commentPreview: MomentCommentPreviewType | null;
+ screenType: ScreenType;
+}
+
+const MomentCommentPreview: React.FC<MomentCommentPreviewProps> = ({
+ momentId,
+ commentsCount,
+ commentPreview,
+ screenType,
+}) => {
+ const navigation = useNavigation();
+ const state = useStore().getState();
+ const commentCountText =
+ commentsCount === 0 ? 'No Comments' : commentsCount + ' comments';
+
+ return (
+ <TouchableOpacity
+ style={styles.commentsPreviewContainer}
+ onPress={() =>
+ navigation.push('MomentCommentsScreen', {
+ moment_id: momentId,
+ screenType,
+ })
+ }>
+ <Text style={styles.whiteBold}>{commentCountText}</Text>
+ {commentPreview !== null && (
+ <View style={styles.previewContainer}>
+ <Image
+ source={{
+ uri: commentPreview.commenter.thumbnail_url,
+ }}
+ style={styles.avatar}
+ />
+ <Text style={styles.whiteBold} numberOfLines={1}>
+ <Text> </Text>
+ <Text>{commentPreview.commenter.username}</Text>
+ <Text> </Text>
+ {renderTextWithMentions({
+ value: commentPreview.comment,
+ styles: styles.normalFont,
+ partTypes: mentionPartTypes('white'),
+ onPress: (user: UserType) =>
+ navigateToProfile(
+ state,
+ useDispatch,
+ navigation,
+ screenType,
+ user,
+ ),
+ })}
+ </Text>
+ </View>
+ )}
+ </TouchableOpacity>
+ );
+};
+
+const styles = StyleSheet.create({
+ commentsPreviewContainer: {
+ height: normalize(50),
+ flexDirection: 'column',
+ justifyContent: 'space-around',
+ marginHorizontal: '5%',
+ marginBottom: '2%',
+ },
+ whiteBold: {
+ fontWeight: '700',
+ color: 'white',
+ fontSize: normalize(13),
+ },
+ previewContainer: {
+ flexDirection: 'row',
+ width: '95%',
+ },
+ avatar: {
+ height: normalize(16),
+ width: normalize(16),
+ borderRadius: 99,
+ },
+ normalFont: {
+ fontWeight: 'normal',
+ },
+});
+
+export default MomentCommentPreview;
diff --git a/src/components/moments/MomentPost.tsx b/src/components/moments/MomentPost.tsx
index 7149a5b4..d87028e3 100644
--- a/src/components/moments/MomentPost.tsx
+++ b/src/components/moments/MomentPost.tsx
@@ -1,21 +1,25 @@
import React, {useEffect, useState} from 'react';
-import {StyleSheet, View} from 'react-native';
+import {StyleSheet} from 'react-native';
import {useSelector} from 'react-redux';
import {MomentPostContent, MomentPostHeader} from '.';
import {deleteMomentTag, loadMomentTags} from '../../services';
import {RootState} from '../../store/rootReducer';
-import {MomentTagType, MomentType, ScreenType} from '../../types';
-import {SCREEN_HEIGHT, SCREEN_WIDTH, StatusBarHeight} from '../../utils';
+import {MomentPostType, MomentTagType, ScreenType} from '../../types';
+import {normalize, SCREEN_HEIGHT} from '../../utils';
interface MomentPostProps {
- item: MomentType;
+ moment: MomentPostType;
userXId: string | undefined;
screenType: ScreenType;
+ index: number;
}
-const ITEM_HEIGHT = SCREEN_HEIGHT * 0.9;
-
-const MomentPost: React.FC<MomentPostProps> = ({item, userXId, screenType}) => {
+const MomentPost: React.FC<MomentPostProps> = ({
+ moment,
+ userXId,
+ screenType,
+ index,
+}) => {
const {userId: loggedInUserId, username: loggedInUsername} = useSelector(
(state: RootState) => state.user.user,
);
@@ -30,16 +34,13 @@ const MomentPost: React.FC<MomentPostProps> = ({item, userXId, screenType}) => {
const isOwnProfile = username === loggedInUsername;
- const loadTags = async () => {
- const response = await loadMomentTags(item.moment_id);
- setTags(response ? response : []);
- };
-
/*
* Load tags on initial render to pass tags data to moment header and content
*/
useEffect(() => {
- loadTags();
+ loadMomentTags(moment.moment_id).then((response) => {
+ setTags(response ? response : []);
+ });
}, []);
/*
@@ -71,52 +72,34 @@ const MomentPost: React.FC<MomentPostProps> = ({item, userXId, screenType}) => {
};
return (
- <View style={styles.postContainer}>
+ <>
<MomentPostHeader
+ style={styles.postHeader}
userXId={userXId}
screenType={screenType}
username={isOwnProfile ? loggedInUsername : username}
- momentId={item.moment_id}
- style={styles.postHeader}
momentTagId={momentTagId}
removeTag={removeTag}
+ moment={moment}
+ tags={tags}
/>
<MomentPostContent
style={styles.postContent}
- momentId={item.moment_id}
- caption={item.caption}
- pathHash={item.moment_url}
- dateTime={item.date_created}
+ moment={moment}
screenType={screenType}
momentTags={tags}
+ index={index}
/>
- </View>
+ </>
);
};
const styles = StyleSheet.create({
- contentContainer: {
- width: SCREEN_WIDTH,
- height: SCREEN_HEIGHT,
- paddingTop: StatusBarHeight,
- flex: 1,
- paddingBottom: 0,
- },
- content: {
- flex: 9,
- },
- header: {
- flex: 1,
- },
- postContainer: {
- height: ITEM_HEIGHT,
- width: SCREEN_WIDTH,
- flex: 1,
- },
- postHeader: {
- flex: 1,
+ postHeader: {},
+ postContent: {
+ minHeight: SCREEN_HEIGHT * 0.8,
+ paddingBottom: normalize(20),
},
- postContent: {flex: 9},
});
export default MomentPost;
diff --git a/src/components/moments/MomentPostContent.tsx b/src/components/moments/MomentPostContent.tsx
index 4a1f3894..aca2999c 100644
--- a/src/components/moments/MomentPostContent.tsx
+++ b/src/components/moments/MomentPostContent.tsx
@@ -1,77 +1,81 @@
import {useNavigation} from '@react-navigation/native';
-import React, {useEffect, useRef, useState} from 'react';
+import React, {useContext, useEffect, useRef, useState} from 'react';
import {Image, StyleSheet, Text, View, ViewProps} from 'react-native';
import {TouchableWithoutFeedback} from 'react-native-gesture-handler';
-import Animated, {Easing} from 'react-native-reanimated';
+import Animated, {EasingNode} from 'react-native-reanimated';
import {useDispatch, useStore} from 'react-redux';
-import {getCommentsCount} from '../../services';
+import {MomentContext} from '../../screens/profile/IndividualMoment';
import {RootState} from '../../store/rootReducer';
-import {MomentTagType, ScreenType, UserType} from '../../types';
import {
+ MomentCommentPreviewType,
+ MomentPostType,
+ MomentTagType,
+ ScreenType,
+ UserType,
+} from '../../types';
+import {
+ getLoggedInUserAsProfilePreview,
getTimePosted,
navigateToProfile,
normalize,
- SCREEN_HEIGHT,
SCREEN_WIDTH,
} from '../../utils';
import {mentionPartTypes, renderTextWithMentions} from '../../utils/comments';
-import {CommentsCount} from '../comments';
+import {AddComment} from '../comments';
import {MomentTags} from '../common';
+import MomentCommentPreview from './MomentCommentPreview';
interface MomentPostContentProps extends ViewProps {
screenType: ScreenType;
- momentId: string;
- caption: string;
- pathHash: string;
- dateTime: string;
+ moment: MomentPostType;
momentTags: MomentTagType[];
+ index: number;
}
const MomentPostContent: React.FC<MomentPostContentProps> = ({
screenType,
- momentId,
- caption,
- pathHash,
- dateTime,
+ moment,
style,
momentTags,
+ index,
}) => {
+ const [tags, setTags] = useState<MomentTagType[]>(momentTags);
const state: RootState = useStore().getState();
const navigation = useNavigation();
const dispatch = useDispatch();
- const [elapsedTime, setElapsedTime] = useState('');
- const [comments_count, setCommentsCount] = useState('');
- const [tags, setTags] = useState<MomentTagType[]>(momentTags);
const imageRef = useRef(null);
const [visible, setVisible] = useState(false);
-
const [fadeValue, setFadeValue] = useState<Animated.Value<number>>(
new Animated.Value(0),
);
+ const [commentCount, setCommentCount] = useState<number>(
+ moment.comments_count,
+ );
+ const [commentPreview, setCommentPreview] =
+ useState<MomentCommentPreviewType | null>(moment.comment_preview);
+ const {keyboardVisible, scrollTo} = useContext(MomentContext);
+ const [hideText, setHideText] = useState(false);
useEffect(() => {
setTags(momentTags);
}, [momentTags]);
useEffect(() => {
- const fetchCommentsCount = async () => {
- const count = await getCommentsCount(momentId, false);
- setCommentsCount(count);
- };
- setElapsedTime(getTimePosted(dateTime));
- fetchCommentsCount();
- }, [dateTime, momentId]);
-
- useEffect(() => {
const fade = async () => {
Animated.timing(fadeValue, {
toValue: 1,
duration: 250,
- easing: Easing.linear,
+ easing: EasingNode.linear,
}).start();
};
fade();
}, [fadeValue]);
+ useEffect(() => {
+ if (!keyboardVisible && hideText) {
+ setHideText(false);
+ }
+ }, [keyboardVisible, hideText]);
+
return (
<View style={[styles.container, style]}>
<TouchableWithoutFeedback
@@ -82,76 +86,95 @@ const MomentPostContent: React.FC<MomentPostContentProps> = ({
<Image
ref={imageRef}
style={styles.image}
- source={{uri: pathHash}}
+ source={{uri: moment.moment_url}}
resizeMode={'cover'}
/>
{tags.length > 0 && (
<Image
source={require('../../assets/icons/tag_indicate.png')}
- style={[styles.tagIcon]}
+ style={styles.tagIcon}
/>
)}
</TouchableWithoutFeedback>
{visible && (
<Animated.View style={[styles.tapTag, {opacity: fadeValue}]}>
- <MomentTags editing={false} tags={tags} imageRef={imageRef} />
+ <MomentTags
+ editing={false}
+ tags={tags}
+ setTags={() => null}
+ imageRef={imageRef}
+ />
</Animated.View>
)}
- <View style={styles.footerContainer}>
- <CommentsCount
- commentsCount={comments_count}
- momentId={momentId}
- screenType={screenType}
- />
- <Text style={styles.text}>{elapsedTime}</Text>
- </View>
- {renderTextWithMentions({
- value: caption,
- styles: styles.captionText,
- partTypes: mentionPartTypes('white'),
- onPress: (user: UserType) =>
- navigateToProfile(state, dispatch, navigation, screenType, user),
- })}
+ {!hideText && (
+ <>
+ {moment.caption !== '' &&
+ renderTextWithMentions({
+ value: moment.caption,
+ styles: styles.captionText,
+ partTypes: mentionPartTypes('white'),
+ onPress: (user: UserType) =>
+ navigateToProfile(
+ state,
+ dispatch,
+ navigation,
+ screenType,
+ user,
+ ),
+ })}
+ <MomentCommentPreview
+ momentId={moment.moment_id}
+ commentsCount={commentCount}
+ commentPreview={commentPreview}
+ screenType={screenType}
+ />
+ </>
+ )}
+ <AddComment
+ placeholderText={'Add a comment here!'}
+ momentId={moment.moment_id}
+ callback={(message) => {
+ setCommentPreview({
+ commenter: getLoggedInUserAsProfilePreview(state),
+ comment: message,
+ });
+ setCommentCount(commentCount + 1);
+ }}
+ onFocus={() => {
+ setHideText(true);
+ scrollTo(index);
+ }}
+ isKeyboardAvoiding={false}
+ theme={'dark'}
+ />
+ <Text style={styles.text}>{getTimePosted(moment.date_created)}</Text>
</View>
);
};
const styles = StyleSheet.create({
- container: {
- height: SCREEN_HEIGHT,
- },
+ container: {},
image: {
width: SCREEN_WIDTH,
aspectRatio: 1,
marginBottom: '3%',
},
- footerContainer: {
- flexDirection: 'row',
- justifyContent: 'space-between',
- marginLeft: '7%',
- marginRight: '5%',
- marginBottom: '2%',
- },
text: {
- position: 'relative',
- paddingBottom: '1%',
- paddingTop: '1%',
- marginLeft: '7%',
- marginRight: '2%',
- color: '#ffffff',
- fontWeight: 'bold',
+ marginHorizontal: '5%',
+ color: 'white',
+ fontWeight: '500',
+ textAlign: 'right',
+ marginTop: 5,
},
captionText: {
position: 'relative',
- paddingBottom: '34%',
- paddingTop: '1%',
- marginLeft: '5%',
- marginRight: '5%',
+ marginHorizontal: '5%',
color: '#ffffff',
fontWeight: '500',
fontSize: normalize(13),
lineHeight: normalize(15.51),
letterSpacing: normalize(0.6),
+ marginBottom: normalize(18),
},
tapTag: {
position: 'absolute',
diff --git a/src/components/moments/MomentPostHeader.tsx b/src/components/moments/MomentPostHeader.tsx
index dc6a3cd9..5f26951a 100644
--- a/src/components/moments/MomentPostHeader.tsx
+++ b/src/components/moments/MomentPostHeader.tsx
@@ -10,7 +10,7 @@ import {
import {useDispatch, useSelector, useStore} from 'react-redux';
import {loadUserMoments} from '../../store/actions';
import {RootState} from '../../store/rootReducer';
-import {ScreenType} from '../../types';
+import {MomentTagType, MomentType, ScreenType} from '../../types';
import {fetchUserX, userXInStore} from '../../utils';
import {MomentMoreInfoDrawer} from '../profile';
import TaggAvatar from '../profile/TaggAvatar';
@@ -19,19 +19,21 @@ interface MomentPostHeaderProps extends ViewProps {
userXId?: string;
screenType: ScreenType;
username: string;
- momentId: string;
momentTagId: string;
removeTag: () => Promise<void>;
+ moment: MomentType;
+ tags: MomentTagType[];
}
const MomentPostHeader: React.FC<MomentPostHeaderProps> = ({
userXId,
screenType,
username,
- momentId,
style,
momentTagId,
removeTag,
+ moment,
+ tags,
}) => {
const [drawerVisible, setDrawerVisible] = useState(false);
const dispatch = useDispatch();
@@ -62,20 +64,23 @@ const MomentPostHeader: React.FC<MomentPostHeaderProps> = ({
style={styles.avatar}
userXId={userXId}
screenType={screenType}
+ editable={false}
/>
<Text style={styles.headerText}>{username}</Text>
</TouchableOpacity>
<MomentMoreInfoDrawer
isOpen={drawerVisible}
setIsOpen={setDrawerVisible}
- momentId={momentId}
isOwnProfile={isOwnProfile}
momentTagId={momentTagId}
removeTag={removeTag}
dismissScreenAndUpdate={() => {
dispatch(loadUserMoments(loggedInUserId));
- navigation.pop();
+ navigation.goBack();
}}
+ screenType={screenType}
+ moment={moment}
+ tags={tags}
/>
</View>
);