From b7482f61fc5c9d62651842e7647d2ff95d47c785 Mon Sep 17 00:00:00 2001
From: Ivan Chen <ivan@tagg.id>
Date: Thu, 29 Apr 2021 19:35:42 -0400
Subject: finished logic with bugs

---
 src/components/comments/AddComment.tsx | 67 ++++++++++++++++++++++++----------
 1 file changed, 47 insertions(+), 20 deletions(-)

(limited to 'src/components/comments/AddComment.tsx')

diff --git a/src/components/comments/AddComment.tsx b/src/components/comments/AddComment.tsx
index 79d4d970..97c87299 100644
--- a/src/components/comments/AddComment.tsx
+++ b/src/components/comments/AddComment.tsx
@@ -8,13 +8,14 @@ import {
   View,
 } from 'react-native';
 import {TouchableOpacity} from 'react-native-gesture-handler';
-import ParsedText from 'react-native-parsed-text';
+import ParsedText, {ParseShape} from 'react-native-parsed-text';
 import {useDispatch, useSelector} from 'react-redux';
 import UpArrowIcon from '../../assets/icons/up_arrow.svg';
 import {TAGG_LIGHT_BLUE} from '../../constants';
 import {postComment} from '../../services';
 import {updateReplyPosted} from '../../store/actions';
 import {RootState} from '../../store/rootreducer';
+import {ProfilePreviewType} from '../../types';
 import {SCREEN_HEIGHT, SCREEN_WIDTH} from '../../utils';
 import {Avatar, TaggTypeahead} from '../common';
 
@@ -37,13 +38,16 @@ const AddComment: React.FC<AddCommentProps> = ({
   placeholderText,
   isCommentInFocus,
 }) => {
-  const [comment, setComment] = React.useState('');
+  const [comment, setComment] = useState('');
   const [keyboardVisible, setKeyboardVisible] = useState(false);
   const [isMentioning, setIsMentioning] = useState(false);
-  const [mentionSearch, setMentionSearch] = useState('');
-
+  const [mentionQuery, setMentionQuery] = useState('');
+  const [selectedMention, setSelectedMention] = useState<ProfilePreviewType>();
+  const [mentions, setMentions] = useState<ProfilePreviewType[]>([]);
   const {avatar} = useSelector((state: RootState) => state.user);
   const dispatch = useDispatch();
+  const ref = useRef<TextInput>(null);
+  const [parsePatterns, setParsePatterns] = useState<ParseShape[]>([]);
 
   const addComment = async () => {
     const trimmed = comment.trim();
@@ -74,6 +78,30 @@ const AddComment: React.FC<AddCommentProps> = ({
     }
   };
 
+  useEffect(() => {
+    setParsePatterns(
+      mentions.map((m) => ({
+        pattern: new RegExp(`@${m.username}`),
+        style: {color: TAGG_LIGHT_BLUE},
+      })),
+    );
+  }, [mentions]);
+
+  useEffect(() => {
+    if (selectedMention) {
+      setComment(
+        comment.replace(
+          new RegExp(`@${mentionQuery}`),
+          `@${selectedMention.username} `,
+        ),
+      );
+      setMentions([...mentions, selectedMention]);
+      setSelectedMention(undefined);
+      setMentionQuery('');
+      setIsMentioning(false);
+    }
+  }, [selectedMention]);
+
   useEffect(() => {
     const showKeyboard = () => setKeyboardVisible(true);
     Keyboard.addListener('keyboardWillShow', showKeyboard);
@@ -86,8 +114,6 @@ const AddComment: React.FC<AddCommentProps> = ({
     return () => Keyboard.removeListener('keyboardWillHide', hideKeyboard);
   }, []);
 
-  const ref = useRef<TextInput>(null);
-
   //If a comment is in Focus, bring the keyboard up so user is able to type in a reply
   useEffect(() => {
     if (isCommentInFocus) {
@@ -99,7 +125,12 @@ const AddComment: React.FC<AddCommentProps> = ({
     <KeyboardAvoidingView
       behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
       keyboardVerticalOffset={SCREEN_HEIGHT * 0.1}>
-      {isMentioning && <TaggTypeahead search={mentionSearch} />}
+      {isMentioning && (
+        <TaggTypeahead
+          query={mentionQuery}
+          setSelectedMention={setSelectedMention}
+        />
+      )}
       <View
         style={[
           styles.container,
@@ -113,32 +144,28 @@ const AddComment: React.FC<AddCommentProps> = ({
             placeholderTextColor="grey"
             onChangeText={(newText: string) => {
               const newestChar = newText[newText.length - 1];
-              if (newestChar === ' ') {
+              const deletedChar =
+                newText.length === comment.length - 1
+                  ? comment[comment.length - 1]
+                  : undefined;
+              if (newestChar === ' ' || deletedChar === '@') {
                 setIsMentioning(false);
-                setMentionSearch('');
+                setMentionQuery('');
               }
               if (newestChar === '@') {
                 setIsMentioning(true);
               }
               if (isMentioning) {
-                const match = newText.match(/@(.*)$/);
+                const match = newText.match(/.*@(.*)$/);
                 if (match) {
-                  setMentionSearch(match[1]);
+                  setMentionQuery(match[1]);
                 }
               }
               setComment(newText);
             }}
             multiline={true}
             ref={ref}>
-            <ParsedText
-              style={styles.text}
-              parse={[
-                {
-                  pattern: /@\{.*\}/,
-                  style: {color: 'red'},
-                  renderText: (text: string) => '@fooo',
-                },
-              ]}>
+            <ParsedText style={styles.text} parse={parsePatterns}>
               {comment}
             </ParsedText>
           </TextInput>
-- 
cgit v1.2.3-70-g09d2

