aboutsummaryrefslogtreecommitdiff
path: root/src/components/comments
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/comments')
-rw-r--r--src/components/comments/AddComment.tsx6
-rw-r--r--src/components/comments/CommentTile.tsx129
-rw-r--r--src/components/comments/CommentsContainer.tsx15
3 files changed, 114 insertions, 36 deletions
diff --git a/src/components/comments/AddComment.tsx b/src/components/comments/AddComment.tsx
index 46086e81..44f49748 100644
--- a/src/components/comments/AddComment.tsx
+++ b/src/components/comments/AddComment.tsx
@@ -40,8 +40,12 @@ const AddComment: React.FC<AddCommentProps> = ({
const {avatar} = useSelector((state: RootState) => state.user);
const addComment = async () => {
+ const trimmed = comment.trim();
+ if (trimmed === '') {
+ return;
+ }
const postedComment = await postComment(
- comment.trim(),
+ trimmed,
objectId,
isCommentInFocus,
);
diff --git a/src/components/comments/CommentTile.tsx b/src/components/comments/CommentTile.tsx
index 39605f2c..c6dd9fc1 100644
--- a/src/components/comments/CommentTile.tsx
+++ b/src/components/comments/CommentTile.tsx
@@ -1,14 +1,18 @@
-import React, {useState} from 'react';
+import React, {Fragment, useEffect, useRef, useState} from 'react';
import {Text, View} from 'react-native-animatable';
import {ProfilePreview} from '../profile';
import {CommentType, ScreenType, TypeOfComment} from '../../types';
-import {StyleSheet} from 'react-native';
+import {Alert, Animated, StyleSheet} from 'react-native';
import ClockIcon from '../../assets/icons/clock-icon-01.svg';
import {TAGG_LIGHT_BLUE} from '../../constants';
-import {TouchableOpacity} from 'react-native-gesture-handler';
+import {RectButton, TouchableOpacity} from 'react-native-gesture-handler';
import {getTimePosted, normalize, 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';
/**
* Displays users's profile picture, comment posted by them and the time difference between now and when a comment was posted.
@@ -19,6 +23,9 @@ interface CommentTileProps {
screenType: ScreenType;
typeOfComment: TypeOfComment;
setCommentObjectInFocus?: (comment: CommentType | undefined) => void;
+ newCommentsAvailable: boolean;
+ setNewCommentsAvailable: (available: boolean) => void;
+ canDelete: boolean;
}
const CommentTile: React.FC<CommentTileProps> = ({
@@ -26,9 +33,24 @@ const CommentTile: React.FC<CommentTileProps> = ({
screenType,
typeOfComment,
setCommentObjectInFocus,
+ newCommentsAvailable,
+ setNewCommentsAvailable,
+ canDelete,
}) => {
const timePosted = getTimePosted(comment_object.date_created);
const [showReplies, setShowReplies] = useState<boolean>(false);
+ const [newThreadAvailable, setNewThreadAvailable] = useState(true);
+ const swipeRef = useRef<Swipeable>(null);
+ const isThread = typeOfComment === 'Thread';
+
+ /**
+ * Bubbling up, for handling a new comment in a thread.
+ */
+ useEffect(() => {
+ if (newCommentsAvailable) {
+ setNewThreadAvailable(true);
+ }
+ }, [newCommentsAvailable]);
/**
* Case : A COMMENT IS IN FOCUS && REPLY SECTION IS HIDDEN
@@ -42,6 +64,8 @@ const CommentTile: React.FC<CommentTileProps> = ({
if (!showReplies) {
setCommentObjectInFocus(comment_object);
} else {
+ setNewThreadAvailable(true);
+ setNewCommentsAvailable(true);
setCommentObjectInFocus(undefined);
}
}
@@ -58,13 +82,46 @@ const CommentTile: React.FC<CommentTileProps> = ({
? `Replies (${comment_object.replies_count})`
: 'Replies';
+ const renderRightAction = (text: string, color: string, progress) => {
+ const pressHandler = async () => {
+ swipeRef.current?.close();
+ const success = await deleteComment(comment_object.comment_id, isThread);
+ if (success) {
+ setNewCommentsAvailable(true);
+ } else {
+ Alert.alert(ERROR_FAILED_TO_DELETE_COMMENT);
+ }
+ };
+ return (
+ <Animated.View>
+ <RectButton
+ style={[styles.rightAction, {backgroundColor: color}]}
+ onPress={pressHandler}>
+ <Trash width={normalize(25)} height={normalize(25)} color={'white'} />
+ <Text style={styles.actionText}>{text}</Text>
+ </RectButton>
+ </Animated.View>
+ );
+ };
+
+ const renderRightActions = (progress) =>
+ canDelete ? (
+ <View style={styles.swipeActions}>
+ {renderRightAction('Delete', '#c42634', progress)}
+ </View>
+ ) : (
+ <Fragment />
+ );
+
return (
- <>
+ <Swipeable
+ ref={swipeRef}
+ renderRightActions={renderRightActions}
+ rightThreshold={40}
+ friction={2}
+ containerStyle={styles.swipableContainer}>
<View
- style={[
- styles.container,
- typeOfComment === 'Thread' ? styles.moreMarginWithThread : {},
- ]}>
+ style={[styles.container, isThread ? styles.moreMarginWithThread : {}]}>
<ProfilePreview
profilePreview={{
id: comment_object.commenter.id,
@@ -104,40 +161,40 @@ const CommentTile: React.FC<CommentTileProps> = ({
{/*** Show replies if toggle state is true */}
{showReplies && (
- <View
- style={{
- width: SCREEN_WIDTH,
- }}>
- <CommentsContainer
- objectId={comment_object.comment_id}
- screenType={screenType}
- setNewCommentsAvailable={() => {}}
- newCommentsAvailable={true}
- typeOfComment={'Thread'}
- />
- </View>
+ <CommentsContainer
+ objectId={comment_object.comment_id}
+ screenType={screenType}
+ setNewCommentsAvailable={setNewThreadAvailable}
+ newCommentsAvailable={newThreadAvailable}
+ typeOfComment={'Thread'}
+ />
)}
- </>
+ </Swipeable>
);
};
const styles = StyleSheet.create({
container: {
- marginHorizontal: '3%',
borderBottomWidth: 1,
borderColor: 'lightgray',
- marginBottom: '3%',
+ backgroundColor: 'white',
+ paddingTop: '3%',
flexDirection: 'column',
flex: 1,
+ marginLeft: '7%',
+ },
+ swipeActions: {
+ flexDirection: 'row',
},
moreMarginWithThread: {
- marginHorizontal: '7%',
+ marginLeft: '14%',
},
body: {
marginLeft: 56,
},
comment: {
marginBottom: '2%',
+ marginRight: '2%',
top: -5,
},
date_time: {
@@ -153,35 +210,47 @@ const styles = StyleSheet.create({
flexDirection: 'row',
marginBottom: '3%',
},
-
flexer: {
flex: 1,
},
-
repliesTextAndIconContainer: {
flexDirection: 'row',
alignItems: 'center',
},
-
repliesText: {
color: TAGG_LIGHT_BLUE,
fontWeight: '500',
fontSize: normalize(12),
- marginRight: '3%',
+ marginRight: '5%',
},
repliesBody: {
width: SCREEN_WIDTH,
},
-
repliesDownArrow: {
transform: [{rotate: '270deg'}],
marginTop: '7%',
},
-
repliesUpArrow: {
transform: [{rotate: '90deg'}],
marginTop: '7%',
},
+ actionText: {
+ color: 'white',
+ fontSize: normalize(12),
+ fontWeight: '500',
+ backgroundColor: 'transparent',
+ paddingHorizontal: '5%',
+ marginTop: '5%',
+ },
+ rightAction: {
+ alignItems: 'center',
+ flex: 1,
+ justifyContent: 'center',
+ flexDirection: 'column',
+ },
+ swipableContainer: {
+ backgroundColor: 'white',
+ },
});
export default CommentTile;
diff --git a/src/components/comments/CommentsContainer.tsx b/src/components/comments/CommentsContainer.tsx
index 0a19694b..d8134caf 100644
--- a/src/components/comments/CommentsContainer.tsx
+++ b/src/components/comments/CommentsContainer.tsx
@@ -1,9 +1,10 @@
-import React, {useRef, useEffect, useState} from 'react';
+import React, {useEffect, useRef, useState} from 'react';
import {StyleSheet} from 'react-native';
import {ScrollView} from 'react-native-gesture-handler';
-import {useDispatch} from 'react-redux';
+import {useDispatch, useSelector} from 'react-redux';
import {CommentTile} from '.';
import {getComments} from '../../services';
+import {RootState} from '../../store/rootReducer';
import {CommentType, ScreenType, TypeOfComment} from '../../types';
export type CommentsContainerProps = {
screenType: ScreenType;
@@ -32,6 +33,9 @@ const CommentsContainer: React.FC<CommentsContainerProps> = ({
setCommentObjectInFocus,
commentObjectInFocus,
}) => {
+ const {username: loggedInUsername} = useSelector(
+ (state: RootState) => state.user.user,
+ );
const [commentsList, setCommentsList] = useState<CommentType[]>([]);
const dispatch = useDispatch();
const ref = useRef<ScrollView>(null);
@@ -79,6 +83,9 @@ const CommentsContainer: React.FC<CommentsContainerProps> = ({
screenType={screenType}
typeOfComment={typeOfComment}
setCommentObjectInFocus={setCommentObjectInFocus}
+ newCommentsAvailable={newCommentsAvailable}
+ setNewCommentsAvailable={setNewCommentsAvailable}
+ canDelete={comment.commenter.username === loggedInUsername}
/>
))}
</ScrollView>
@@ -86,9 +93,7 @@ const CommentsContainer: React.FC<CommentsContainerProps> = ({
};
const styles = StyleSheet.create({
- scrollView: {
- paddingHorizontal: 20,
- },
+ scrollView: {},
scrollViewContent: {
justifyContent: 'center',
},