diff options
Diffstat (limited to 'src/components')
-rw-r--r-- | src/components/comments/CommentTile.tsx | 34 | ||||
-rw-r--r-- | src/components/comments/CommentsContainer.tsx | 76 | ||||
-rw-r--r-- | src/components/notifications/Notification.tsx | 29 |
3 files changed, 103 insertions, 36 deletions
diff --git a/src/components/comments/CommentTile.tsx b/src/components/comments/CommentTile.tsx index b631a985..e775a609 100644 --- a/src/components/comments/CommentTile.tsx +++ b/src/components/comments/CommentTile.tsx @@ -6,13 +6,19 @@ import {Alert, Animated, StyleSheet} from 'react-native'; import ClockIcon from '../../assets/icons/clock-icon-01.svg'; import {TAGG_LIGHT_BLUE} from '../../constants'; import {RectButton, TouchableOpacity} from 'react-native-gesture-handler'; -import {getTimePosted, normalize, SCREEN_WIDTH} from '../../utils'; +import { + getTimePosted, + normalize, + SCREEN_HEIGHT, + SCREEN_WIDTH, +} from '../../utils'; import Arrow from '../../assets/icons/back-arrow-colored.svg'; import Trash from '../../assets/ionicons/trash-outline.svg'; import CommentsContainer from './CommentsContainer'; import Swipeable from 'react-native-gesture-handler/Swipeable'; import {deleteComment} from '../../services'; import {ERROR_FAILED_TO_DELETE_COMMENT} from '../../constants/strings'; +import {min} from 'moment'; /** * Displays users's profile picture, comment posted by them and the time difference between now and when a comment was posted. @@ -155,14 +161,22 @@ const CommentTile: React.FC<CommentTileProps> = ({ </View> {/*** Show replies if toggle state is true */} - {showReplies && ( - <CommentsContainer - objectId={comment_object.comment_id} - screenType={screenType} - setNewCommentsAvailable={setNewThreadAvailable} - newCommentsAvailable={newThreadAvailable} - typeOfComment={'Thread'} - /> + {showReplies && comment_object.replies_count > 0 && ( + <View + style={{ + height: Math.min( + SCREEN_HEIGHT / 2.4, + (SCREEN_HEIGHT / 7.5) * comment_object.replies_count, + ), + }}> + <CommentsContainer + objectId={comment_object.comment_id} + screenType={screenType} + setNewCommentsAvailable={setNewThreadAvailable} + newCommentsAvailable={newThreadAvailable} + typeOfComment={'Thread'} + /> + </View> )} </Swipeable> ); @@ -173,9 +187,9 @@ const styles = StyleSheet.create({ borderBottomWidth: 1, borderColor: 'lightgray', backgroundColor: 'white', - paddingTop: '3%', flexDirection: 'column', flex: 1, + paddingTop: '3%', marginLeft: '7%', }, swipeActions: { diff --git a/src/components/comments/CommentsContainer.tsx b/src/components/comments/CommentsContainer.tsx index d8134caf..a0e94828 100644 --- a/src/components/comments/CommentsContainer.tsx +++ b/src/components/comments/CommentsContainer.tsx @@ -1,16 +1,17 @@ import React, {useEffect, useRef, useState} from 'react'; import {StyleSheet} from 'react-native'; -import {ScrollView} from 'react-native-gesture-handler'; +import {FlatList} from 'react-native-gesture-handler'; import {useDispatch, useSelector} from 'react-redux'; import {CommentTile} from '.'; import {getComments} from '../../services'; import {RootState} from '../../store/rootReducer'; import {CommentType, ScreenType, TypeOfComment} from '../../types'; +import {SCREEN_HEIGHT} from '../../utils'; export type CommentsContainerProps = { screenType: ScreenType; - //objectId can be either moment_id or comment_id objectId: string; + commentId?: string; setCommentsLength?: (count: number) => void; newCommentsAvailable: boolean; setNewCommentsAvailable: (value: boolean) => void; @@ -32,18 +33,21 @@ const CommentsContainer: React.FC<CommentsContainerProps> = ({ typeOfComment, setCommentObjectInFocus, commentObjectInFocus, + commentId, }) => { const {username: loggedInUsername} = useSelector( (state: RootState) => state.user.user, ); const [commentsList, setCommentsList] = useState<CommentType[]>([]); const dispatch = useDispatch(); - const ref = useRef<ScrollView>(null); + const ref = useRef<FlatList<CommentType>>(null); + const [initialIndex, setInitialIndex] = useState<number>(0); useEffect(() => { //Scroll only if a new comment and not a reply was posted const shouldScroll = () => - typeOfComment === 'Comment' && !commentObjectInFocus; + (typeOfComment === 'Comment' && !commentObjectInFocus) || + typeOfComment === 'Thread'; const loadComments = async () => { const comments = await getComments(objectId, typeOfComment === 'Thread'); setCommentsList(comments); @@ -55,9 +59,16 @@ const CommentsContainer: React.FC<CommentsContainerProps> = ({ if (newCommentsAvailable) { loadComments(); if (shouldScroll()) { - setTimeout(() => { - ref.current?.scrollToEnd(); - }, 500); + if (commentId) { + const index = commentsList.findIndex( + (item) => item.comment_id === commentId, + ); + setInitialIndex(index); + } else { + setTimeout(() => { + ref.current?.scrollToEnd({animated: true}); + }, 500); + } } } }, [ @@ -68,27 +79,44 @@ const CommentsContainer: React.FC<CommentsContainerProps> = ({ setCommentsLength, typeOfComment, commentObjectInFocus, + commentId, + commentsList, ]); + const ITEM_HEIGHT = SCREEN_HEIGHT / 7.5; + + const renderComment = ({item}: {item: CommentType}) => ( + <CommentTile + key={item.comment_id} + comment_object={item} + screenType={screenType} + typeOfComment={typeOfComment} + setCommentObjectInFocus={setCommentObjectInFocus} + newCommentsAvailable={newCommentsAvailable} + setNewCommentsAvailable={setNewCommentsAvailable} + canDelete={item.commenter.username === loggedInUsername} + /> + ); + return ( - <ScrollView + <FlatList + data={commentsList} ref={ref} - style={styles.scrollView} - contentContainerStyle={styles.scrollViewContent}> - {commentsList && - commentsList.map((comment: CommentType) => ( - <CommentTile - key={comment.comment_id} - comment_object={comment} - screenType={screenType} - typeOfComment={typeOfComment} - setCommentObjectInFocus={setCommentObjectInFocus} - newCommentsAvailable={newCommentsAvailable} - setNewCommentsAvailable={setNewCommentsAvailable} - canDelete={comment.commenter.username === loggedInUsername} - /> - ))} - </ScrollView> + keyExtractor={(item, index) => index.toString()} + decelerationRate={'fast'} + snapToAlignment={'start'} + snapToInterval={ITEM_HEIGHT} + renderItem={renderComment} + showsVerticalScrollIndicator={false} + initialScrollIndex={initialIndex} + contentContainerStyle={styles.scrollViewContent} + getItemLayout={(data, index) => ({ + length: ITEM_HEIGHT, + offset: ITEM_HEIGHT * index, + index, + })} + pagingEnabled + /> ); }; diff --git a/src/components/notifications/Notification.tsx b/src/components/notifications/Notification.tsx index e648b554..c754f941 100644 --- a/src/components/notifications/Notification.tsx +++ b/src/components/notifications/Notification.tsx @@ -85,19 +85,44 @@ const Notification: React.FC<NotificationProps> = (props) => { break; case 'CMT': // find the moment we need to display - const moment = loggedInUserMoments?.find( + let moment: MomentType | undefined = loggedInUserMoments?.find( (m) => m.moment_id === notification_object?.moment_id, ); + let userXId; + + //This needs to be done if user replies to a comment on a moment that is not user's own moment + if (!moment) { + try { + if (!userXInStore(state, screenType, id)) { + await fetchUserX( + dispatch, + {userId: id, username: username}, + screenType, + ); + } + + //Wait for data to be loaded + setTimeout(() => {}, 200); + const {moments} = state.userX[screenType][id]; + moment = moments?.find( + (m) => m.moment_id === notification_object?.moment_id, + ); + userXId = id; + } catch (err) { + console.log(err); + } + } if (moment) { navigation.push('IndividualMoment', { moment, - userXId: undefined, // we're only viewing our own moment here + userXId: userXId, // we're only viewing our own moment here screenType, }); setTimeout(() => { navigation.push('MomentCommentsScreen', { moment_id: moment.moment_id, screenType, + comment_id: notification_object?.comment_id, }); }, 500); } |