From 7de499af625b28074e86854b997e66257ffab8c8 Mon Sep 17 00:00:00 2001
From: Ivan Chen <ivan@tagg.id>
Date: Tue, 8 Jun 2021 16:18:30 -0400
Subject: Adjust styling

---
 src/components/comments/AddComment.tsx | 34 ++++++++++++++++++++++++----------
 1 file changed, 24 insertions(+), 10 deletions(-)

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

diff --git a/src/components/comments/AddComment.tsx b/src/components/comments/AddComment.tsx
index b229d010..24ff830a 100644
--- a/src/components/comments/AddComment.tsx
+++ b/src/components/comments/AddComment.tsx
@@ -24,10 +24,15 @@ import {MentionInputControlled} from './MentionInputControlled';
 export interface AddCommentProps {
   momentId: string;
   placeholderText: string;
+  theme?: 'dark' | 'white';
 }
 
-const AddComment: React.FC<AddCommentProps> = ({momentId, placeholderText}) => {
-  const {setShouldUpdateAllComments, commentTapped} =
+const AddComment: React.FC<AddCommentProps> = ({
+  momentId,
+  placeholderText,
+  theme = 'white',
+}) => {
+  const {setShouldUpdateAllComments = () => null, commentTapped} =
     useContext(CommentContext);
   const [inReplyToMention, setInReplyToMention] = useState('');
   const [comment, setComment] = useState('');
@@ -106,13 +111,14 @@ const AddComment: React.FC<AddCommentProps> = ({momentId, placeholderText}) => {
       keyboardVerticalOffset={SCREEN_HEIGHT * 0.1}>
       <View
         style={[
-          styles.container,
-          keyboardVisible ? styles.whiteBackround : {},
+          theme === 'white' ? styles.containerWhite : styles.containerDark,
+          keyboardVisible && theme !== 'dark' ? styles.whiteBackround : {},
         ]}>
         <View style={styles.textContainer}>
           <Avatar style={styles.avatar} uri={avatar} />
           <MentionInputControlled
             containerStyle={styles.text}
+            placeholderTextColor={theme === 'dark' ? '#828282' : undefined}
             placeholder={placeholderText}
             value={inReplyToMention + comment}
             onChange={(newText: string) => {
@@ -124,11 +130,15 @@ const AddComment: React.FC<AddCommentProps> = ({momentId, placeholderText}) => {
             inputRef={ref}
             partTypes={mentionPartTypes('blue')}
           />
-          <View style={styles.submitButton}>
-            <TouchableOpacity style={styles.submitButton} onPress={addComment}>
-              <UpArrowIcon width={35} height={35} color={'white'} />
-            </TouchableOpacity>
-          </View>
+          {(theme === 'white' || (theme === 'dark' && keyboardVisible)) && (
+            <View style={styles.submitButton}>
+              <TouchableOpacity
+                style={styles.submitButton}
+                onPress={addComment}>
+                <UpArrowIcon width={35} height={35} color={'white'} />
+              </TouchableOpacity>
+            </View>
+          )}
         </View>
       </View>
     </KeyboardAvoidingView>
@@ -136,7 +146,11 @@ const AddComment: React.FC<AddCommentProps> = ({momentId, placeholderText}) => {
 };
 
 const styles = StyleSheet.create({
-  container: {
+  containerDark: {
+    alignItems: 'center',
+    width: SCREEN_WIDTH,
+  },
+  containerWhite: {
     backgroundColor: '#f7f7f7',
     alignItems: 'center',
     width: SCREEN_WIDTH,
-- 
cgit v1.2.3-70-g09d2


From 6837eac533bdf39013bde22ab8df2eb687a06a2e Mon Sep 17 00:00:00 2001
From: Ivan Chen <ivan@tagg.id>
Date: Tue, 8 Jun 2021 16:52:05 -0400
Subject: Move things around, Add logic to disable button

---
 src/components/comments/AddComment.tsx       | 10 +++++++++-
 src/components/moments/MomentPostContent.tsx | 16 ++++++++--------
 2 files changed, 17 insertions(+), 9 deletions(-)

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

diff --git a/src/components/comments/AddComment.tsx b/src/components/comments/AddComment.tsx
index 24ff830a..12fd7e4d 100644
--- a/src/components/comments/AddComment.tsx
+++ b/src/components/comments/AddComment.tsx
@@ -133,7 +133,12 @@ const AddComment: React.FC<AddCommentProps> = ({
           {(theme === 'white' || (theme === 'dark' && keyboardVisible)) && (
             <View style={styles.submitButton}>
               <TouchableOpacity
-                style={styles.submitButton}
+                style={
+                  comment === ''
+                    ? [styles.submitButton, styles.greyButton]
+                    : styles.submitButton
+                }
+                disabled={comment === ''}
                 onPress={addComment}>
                 <UpArrowIcon width={35} height={35} color={'white'} />
               </TouchableOpacity>
@@ -190,6 +195,9 @@ const styles = StyleSheet.create({
     marginVertical: '2%',
     alignSelf: 'flex-end',
   },
+  greyButton: {
+    backgroundColor: 'grey',
+  },
   whiteBackround: {
     backgroundColor: '#fff',
   },
diff --git a/src/components/moments/MomentPostContent.tsx b/src/components/moments/MomentPostContent.tsx
index e76a8ceb..582cba25 100644
--- a/src/components/moments/MomentPostContent.tsx
+++ b/src/components/moments/MomentPostContent.tsx
@@ -88,14 +88,6 @@ const MomentPostContent: React.FC<MomentPostContentProps> = ({
           />
         </Animated.View>
       )}
-      <View style={styles.footerContainer}>
-        <CommentsCount
-          commentsCount={moment.comments_count.toString()}
-          momentId={moment.moment_id}
-          screenType={screenType}
-        />
-        <Text style={styles.text}>{elapsedTime}</Text>
-      </View>
       {moment.caption !== '' &&
         renderTextWithMentions({
           value: moment.caption,
@@ -104,6 +96,14 @@ const MomentPostContent: React.FC<MomentPostContentProps> = ({
           onPress: (user: UserType) =>
             navigateToProfile(state, dispatch, navigation, screenType, user),
         })}
+      <View style={styles.footerContainer}>
+        <CommentsCount
+          commentsCount={moment.comments_count.toString()}
+          momentId={moment.moment_id}
+          screenType={screenType}
+        />
+        <Text style={styles.text}>{elapsedTime}</Text>
+      </View>
       <AddComment
         placeholderText={'Add a comment here!'}
         momentId={moment.moment_id}
-- 
cgit v1.2.3-70-g09d2


From 770dcf385fa99fbb93c4ae89a51b09fd96d23bf9 Mon Sep 17 00:00:00 2001
From: Ivan Chen <ivan@tagg.id>
Date: Thu, 10 Jun 2021 17:23:47 -0400
Subject: Add util function, Add logic for updating comment preview

---
 src/components/comments/AddComment.tsx          |  6 +++++-
 src/components/moments/MomentCommentPreview.tsx | 25 +++++++++++++------------
 src/components/moments/MomentPostContent.tsx    | 24 ++++++++++++++++++++++--
 src/types/types.ts                              | 10 ++++++----
 src/utils/users.ts                              | 18 ++++++++++++++++++
 5 files changed, 64 insertions(+), 19 deletions(-)

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

diff --git a/src/components/comments/AddComment.tsx b/src/components/comments/AddComment.tsx
index 12fd7e4d..18b9c24e 100644
--- a/src/components/comments/AddComment.tsx
+++ b/src/components/comments/AddComment.tsx
@@ -24,12 +24,14 @@ import {MentionInputControlled} from './MentionInputControlled';
 export interface AddCommentProps {
   momentId: string;
   placeholderText: string;
+  callback?: (message: string) => void;
   theme?: 'dark' | 'white';
 }
 
 const AddComment: React.FC<AddCommentProps> = ({
   momentId,
   placeholderText,
+  callback = (msg) => null,
   theme = 'white',
 }) => {
   const {setShouldUpdateAllComments = () => null, commentTapped} =
@@ -55,13 +57,15 @@ const AddComment: React.FC<AddCommentProps> = ({
     if (trimmed === '') {
       return;
     }
+    const message = inReplyToMention + trimmed;
     const postedComment = await postComment(
-      inReplyToMention + trimmed,
+      message,
       objectId,
       isReplyingToComment || isReplyingToReply,
     );
 
     if (postedComment) {
+      callback(message);
       setComment('');
       setInReplyToMention('');
 
diff --git a/src/components/moments/MomentCommentPreview.tsx b/src/components/moments/MomentCommentPreview.tsx
index 94fcb008..092f8936 100644
--- a/src/components/moments/MomentCommentPreview.tsx
+++ b/src/components/moments/MomentCommentPreview.tsx
@@ -3,50 +3,52 @@ 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 {MomentPostType, ScreenType, UserType} from '../../types';
+import {MomentCommentPreviewType, ScreenType, UserType} from '../../types';
 import {navigateToProfile, normalize} from '../../utils';
 import {mentionPartTypes, renderTextWithMentions} from '../../utils/comments';
 
 interface MomentCommentPreviewProps {
-  moment: MomentPostType;
+  momentId: string;
+  commentsCount: number;
+  commentPreview: MomentCommentPreviewType | null;
   screenType: ScreenType;
 }
 
 const MomentCommentPreview: React.FC<MomentCommentPreviewProps> = ({
-  moment,
+  momentId,
+  commentsCount,
+  commentPreview,
   screenType,
 }) => {
   const navigation = useNavigation();
   const state = useStore().getState();
   const commentCountText =
-    moment.comments_count === 0
-      ? 'No Comments'
-      : moment.comments_count + ' comments';
+    commentsCount === 0 ? 'No Comments' : commentsCount + ' comments';
 
   return (
     <TouchableOpacity
       style={styles.commentsPreviewContainer}
       onPress={() =>
         navigation.push('MomentCommentsScreen', {
-          moment_id: moment.moment_id,
+          moment_id: momentId,
           screenType,
         })
       }>
       <Text style={styles.whiteBold}>{commentCountText}</Text>
-      {moment.comment_preview !== null && (
+      {commentPreview !== null && (
         <View style={styles.previewContainer}>
           <Image
             source={{
-              uri: moment.comment_preview.commenter.thumbnail_url,
+              uri: commentPreview.commenter.thumbnail_url,
             }}
             style={styles.avatar}
           />
           <Text style={styles.whiteBold} numberOfLines={1}>
             <Text> </Text>
-            <Text>{moment.comment_preview.commenter.username}</Text>
+            <Text>{commentPreview.commenter.username}</Text>
             <Text> </Text>
             {renderTextWithMentions({
-              value: moment.comment_preview.comment,
+              value: commentPreview.comment,
               styles: styles.normalFont,
               partTypes: mentionPartTypes('commentPreview'),
               onPress: (user: UserType) =>
@@ -88,7 +90,6 @@ const styles = StyleSheet.create({
     borderRadius: 99,
   },
   normalFont: {
-    // top: -5,
     fontWeight: 'normal',
   },
 });
diff --git a/src/components/moments/MomentPostContent.tsx b/src/components/moments/MomentPostContent.tsx
index 378931d1..5192fdf0 100644
--- a/src/components/moments/MomentPostContent.tsx
+++ b/src/components/moments/MomentPostContent.tsx
@@ -5,12 +5,19 @@ import {TouchableWithoutFeedback} from 'react-native-gesture-handler';
 import Animated, {EasingNode} from 'react-native-reanimated';
 import {useDispatch, useStore} from 'react-redux';
 import {RootState} from '../../store/rootReducer';
-import {MomentPostType, MomentTagType, ScreenType, UserType} from '../../types';
+import {
+  MomentCommentPreviewType,
+  MomentPostType,
+  MomentTagType,
+  ScreenType,
+  UserType,
+} from '../../types';
 import {
   getTimePosted,
   navigateToProfile,
   normalize,
   SCREEN_WIDTH,
+  getLoggedInUserAsProfilePreview,
 } from '../../utils';
 import {mentionPartTypes, renderTextWithMentions} from '../../utils/comments';
 import {AddComment} from '../comments';
@@ -37,6 +44,8 @@ const MomentPostContent: React.FC<MomentPostContentProps> = ({
   const [fadeValue, setFadeValue] = useState<Animated.Value<number>>(
     new Animated.Value(0),
   );
+  const [commentPreview, setCommentPreview] =
+    useState<MomentCommentPreviewType | null>(moment.comment_preview);
 
   useEffect(() => {
     setTags(momentTags);
@@ -91,10 +100,21 @@ const MomentPostContent: React.FC<MomentPostContentProps> = ({
           onPress: (user: UserType) =>
             navigateToProfile(state, dispatch, navigation, screenType, user),
         })}
-      <MomentCommentPreview moment={moment} screenType={screenType} />
+      <MomentCommentPreview
+        momentId={moment.moment_id}
+        commentsCount={moment.comments_count}
+        commentPreview={commentPreview}
+        screenType={screenType}
+      />
       <AddComment
         placeholderText={'Add a comment here!'}
         momentId={moment.moment_id}
+        callback={(message) =>
+          setCommentPreview({
+            commenter: getLoggedInUserAsProfilePreview(state),
+            comment: message,
+          })
+        }
         theme={'dark'}
       />
       <Text style={styles.text}>{getTimePosted(moment.date_created)}</Text>
diff --git a/src/types/types.ts b/src/types/types.ts
index 1bdade5c..3ac7ec2f 100644
--- a/src/types/types.ts
+++ b/src/types/types.ts
@@ -121,10 +121,12 @@ export interface MomentType {
 
 export interface MomentPostType extends MomentType {
   comments_count: number;
-  comment_preview: {
-    commenter: ProfilePreviewType;
-    comment: string;
-  };
+  comment_preview: MomentCommentPreviewType;
+}
+
+export interface MomentCommentPreviewType {
+  commenter: ProfilePreviewType;
+  comment: string;
 }
 
 export interface MomentTagType {
diff --git a/src/utils/users.ts b/src/utils/users.ts
index 64ad10e9..c1c3b8bc 100644
--- a/src/utils/users.ts
+++ b/src/utils/users.ts
@@ -306,3 +306,21 @@ export const patchProfile = async (
       return false;
     });
 };
+
+/**
+ * Returns the logged-in user's info in ProfilePreviewType from redux store.
+ * @param state the current state of the redux store
+ * @returns logged-in user in ProfilePreviewType
+ */
+export const getLoggedInUserAsProfilePreview: (
+  state: RootState,
+) => ProfilePreviewType = (state) => {
+  const nameSplit = state.user.profile.name.split(' ');
+  return {
+    id: state.user.user.userId,
+    username: state.user.user.username,
+    first_name: nameSplit[0],
+    last_name: nameSplit[1],
+    thumbnail_url: state.user.avatar ?? '', // in full res
+  };
+};
-- 
cgit v1.2.3-70-g09d2


From 2f9ecfb9bc89c7c6e7ac09952b97d3f3813075bc Mon Sep 17 00:00:00 2001
From: Ivan Chen <ivan@tagg.id>
Date: Thu, 10 Jun 2021 19:20:19 -0400
Subject: Add logic for keyboard focus

---
 src/App.tsx                                        |  19 ++--
 src/components/comments/AddComment.tsx             |   5 +-
 .../moments/IndividualMomentTitleBar.tsx           |  11 ++-
 src/components/moments/MomentPost.tsx              |   3 +
 src/components/moments/MomentPostContent.tsx       |  52 +++++++----
 src/screens/profile/IndividualMoment.tsx           | 102 +++++++++++++++------
 src/screens/profile/MomentCommentsScreen.tsx       |   5 +-
 7 files changed, 135 insertions(+), 62 deletions(-)

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

diff --git a/src/App.tsx b/src/App.tsx
index 92e7abee..64f40bae 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -27,16 +27,15 @@ export const ChatContext = React.createContext({} as ChatContextType);
 const App = () => {
   const routeNameRef = useRef();
   const [channel, setChannel] = useState<ChannelGroupedType>();
-  const chatClient =
-    StreamChat.getInstance<
-      LocalAttachmentType,
-      LocalChannelType,
-      LocalCommandType,
-      LocalEventType,
-      LocalMessageType,
-      LocalResponseType,
-      LocalUserType
-    >(STREAM_CHAT_API);
+  const chatClient = StreamChat.getInstance<
+    LocalAttachmentType,
+    LocalChannelType,
+    LocalCommandType,
+    LocalEventType,
+    LocalMessageType,
+    LocalResponseType,
+    LocalUserType
+  >(STREAM_CHAT_API);
   return (
     <Provider store={store}>
       <NavigationContainer
diff --git a/src/components/comments/AddComment.tsx b/src/components/comments/AddComment.tsx
index 18b9c24e..9d9824db 100644
--- a/src/components/comments/AddComment.tsx
+++ b/src/components/comments/AddComment.tsx
@@ -25,13 +25,15 @@ export interface AddCommentProps {
   momentId: string;
   placeholderText: string;
   callback?: (message: string) => void;
+  onFocus?: () => void;
   theme?: 'dark' | 'white';
 }
 
 const AddComment: React.FC<AddCommentProps> = ({
   momentId,
   placeholderText,
-  callback = (msg) => null,
+  callback = (_) => null,
+  onFocus = () => null,
   theme = 'white',
 }) => {
   const {setShouldUpdateAllComments = () => null, commentTapped} =
@@ -125,6 +127,7 @@ const AddComment: React.FC<AddCommentProps> = ({
             placeholderTextColor={theme === 'dark' ? '#828282' : undefined}
             placeholder={placeholderText}
             value={inReplyToMention + comment}
+            onFocus={onFocus}
             onChange={(newText: string) => {
               // skipping the `inReplyToMention` text
               setComment(
diff --git a/src/components/moments/IndividualMomentTitleBar.tsx b/src/components/moments/IndividualMomentTitleBar.tsx
index 2bebafa7..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;
diff --git a/src/components/moments/MomentPost.tsx b/src/components/moments/MomentPost.tsx
index 02dbffa3..7a588325 100644
--- a/src/components/moments/MomentPost.tsx
+++ b/src/components/moments/MomentPost.tsx
@@ -11,12 +11,14 @@ interface MomentPostProps {
   moment: MomentPostType;
   userXId: string | undefined;
   screenType: ScreenType;
+  index: number;
 }
 
 const MomentPost: React.FC<MomentPostProps> = ({
   moment,
   userXId,
   screenType,
+  index,
 }) => {
   const {userId: loggedInUserId, username: loggedInUsername} = useSelector(
     (state: RootState) => state.user.user,
@@ -88,6 +90,7 @@ const MomentPost: React.FC<MomentPostProps> = ({
         moment={moment}
         screenType={screenType}
         momentTags={tags}
+        index={index}
       />
     </>
   );
diff --git a/src/components/moments/MomentPostContent.tsx b/src/components/moments/MomentPostContent.tsx
index 5192fdf0..eb89fd03 100644
--- a/src/components/moments/MomentPostContent.tsx
+++ b/src/components/moments/MomentPostContent.tsx
@@ -1,9 +1,10 @@
 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, {EasingNode} from 'react-native-reanimated';
 import {useDispatch, useStore} from 'react-redux';
+import {MomentContext} from '../../screens/profile/IndividualMoment';
 import {RootState} from '../../store/rootReducer';
 import {
   MomentCommentPreviewType,
@@ -13,11 +14,11 @@ import {
   UserType,
 } from '../../types';
 import {
+  getLoggedInUserAsProfilePreview,
   getTimePosted,
   navigateToProfile,
   normalize,
   SCREEN_WIDTH,
-  getLoggedInUserAsProfilePreview,
 } from '../../utils';
 import {mentionPartTypes, renderTextWithMentions} from '../../utils/comments';
 import {AddComment} from '../comments';
@@ -28,12 +29,14 @@ interface MomentPostContentProps extends ViewProps {
   screenType: ScreenType;
   moment: MomentPostType;
   momentTags: MomentTagType[];
+  index: number;
 }
 const MomentPostContent: React.FC<MomentPostContentProps> = ({
   screenType,
   moment,
   style,
   momentTags,
+  index,
 }) => {
   const state: RootState = useStore().getState();
   const navigation = useNavigation();
@@ -46,6 +49,7 @@ const MomentPostContent: React.FC<MomentPostContentProps> = ({
   );
   const [commentPreview, setCommentPreview] =
     useState<MomentCommentPreviewType | null>(moment.comment_preview);
+  const {keyboardVisible, setScrollToTargetIndex} = useContext(MomentContext);
 
   useEffect(() => {
     setTags(momentTags);
@@ -92,20 +96,30 @@ const MomentPostContent: React.FC<MomentPostContentProps> = ({
           />
         </Animated.View>
       )}
-      {moment.caption !== '' &&
-        renderTextWithMentions({
-          value: moment.caption,
-          styles: styles.captionText,
-          partTypes: mentionPartTypes('momentCaption'),
-          onPress: (user: UserType) =>
-            navigateToProfile(state, dispatch, navigation, screenType, user),
-        })}
-      <MomentCommentPreview
-        momentId={moment.moment_id}
-        commentsCount={moment.comments_count}
-        commentPreview={commentPreview}
-        screenType={screenType}
-      />
+      {!keyboardVisible && (
+        <>
+          {moment.caption !== '' &&
+            renderTextWithMentions({
+              value: moment.caption,
+              styles: styles.captionText,
+              partTypes: mentionPartTypes('momentCaption'),
+              onPress: (user: UserType) =>
+                navigateToProfile(
+                  state,
+                  dispatch,
+                  navigation,
+                  screenType,
+                  user,
+                ),
+            })}
+          <MomentCommentPreview
+            momentId={moment.moment_id}
+            commentsCount={moment.comments_count}
+            commentPreview={commentPreview}
+            screenType={screenType}
+          />
+        </>
+      )}
       <AddComment
         placeholderText={'Add a comment here!'}
         momentId={moment.moment_id}
@@ -115,6 +129,7 @@ const MomentPostContent: React.FC<MomentPostContentProps> = ({
             comment: message,
           })
         }
+        onFocus={() => setScrollToTargetIndex(index)}
         theme={'dark'}
       />
       <Text style={styles.text}>{getTimePosted(moment.date_created)}</Text>
@@ -123,9 +138,7 @@ const MomentPostContent: React.FC<MomentPostContentProps> = ({
 };
 
 const styles = StyleSheet.create({
-  container: {
-    borderWidth: 1,
-  },
+  container: {},
   image: {
     width: SCREEN_WIDTH,
     aspectRatio: 1,
@@ -147,7 +160,6 @@ const styles = StyleSheet.create({
     lineHeight: normalize(15.51),
     letterSpacing: normalize(0.6),
     marginBottom: normalize(18),
-    borderWidth: 1,
   },
   tapTag: {
     position: 'absolute',
diff --git a/src/screens/profile/IndividualMoment.tsx b/src/screens/profile/IndividualMoment.tsx
index 447ba2a9..a91f1913 100644
--- a/src/screens/profile/IndividualMoment.tsx
+++ b/src/screens/profile/IndividualMoment.tsx
@@ -1,10 +1,11 @@
 import {BlurView} from '@react-native-community/blur';
 import {RouteProp} from '@react-navigation/native';
 import {StackNavigationProp} from '@react-navigation/stack';
-import React from 'react';
-import {FlatList, StyleSheet} from 'react-native';
+import React, {useEffect, useRef, useState} from 'react';
+import {FlatList, Keyboard, StyleSheet} from 'react-native';
 import {useSelector} from 'react-redux';
 import {IndividualMomentTitleBar, MomentPost} from '../../components';
+import {AVATAR_DIM} from '../../constants';
 import {MainStackParams} from '../../routes';
 import {RootState} from '../../store/rootreducer';
 import {MomentPostType} from '../../types';
@@ -13,11 +14,21 @@ import {normalize, StatusBarHeight} from '../../utils';
 /**
  * Individual moment view opened when user clicks on a moment tile
  */
+
+type MomentContextType = {
+  keyboardVisible: boolean;
+  setScrollToTargetIndex: (index: number) => void;
+};
+
+export const MomentContext = React.createContext({} as MomentContextType);
+
 type IndividualMomentRouteProp = RouteProp<MainStackParams, 'IndividualMoment'>;
+
 type IndividualMomentNavigationProp = StackNavigationProp<
   MainStackParams,
   'IndividualMoment'
 >;
+
 interface IndividualMomentProps {
   route: IndividualMomentRouteProp;
   navigation: IndividualMomentNavigationProp;
@@ -27,39 +38,78 @@ const IndividualMoment: React.FC<IndividualMomentProps> = ({
   route,
   navigation,
 }) => {
-  const {moment_category, moment_id} = route.params.moment;
-  const {userXId, screenType} = route.params;
-
+  const {
+    userXId,
+    screenType,
+    moment: {moment_category, moment_id},
+  } = route.params;
   const {moments} = useSelector((state: RootState) =>
     userXId ? state.userX[screenType][userXId] : state.moments,
   );
-
+  const scrollRef = useRef<FlatList<MomentPostType>>(null);
   const momentData = moments.filter(
     (m) => m.moment_category === moment_category,
   );
   const initialIndex = momentData.findIndex((m) => m.moment_id === moment_id);
+  const [scrollToTargetIndex, setScrollToTargetIndex] =
+    useState<number>(initialIndex);
+  const [keyboardVisible, setKeyboardVisible] = React.useState(false);
+
+  useEffect(() => {
+    const showKeyboard = () => setKeyboardVisible(true);
+    Keyboard.addListener('keyboardWillShow', showKeyboard);
+    return () => Keyboard.removeListener('keyboardWillShow', showKeyboard);
+  }, []);
+
+  useEffect(() => {
+    const hideKeyboard = () => setKeyboardVisible(false);
+    Keyboard.addListener('keyboardWillHide', hideKeyboard);
+    return () => Keyboard.removeListener('keyboardWillHide', hideKeyboard);
+  }, []);
+
+  useEffect(() => {
+    if (keyboardVisible) {
+      scrollRef.current?.scrollToIndex({
+        index: scrollToTargetIndex,
+        // viewOffset: -(AVATAR_DIM + normalize(120)),
+        viewOffset: -(AVATAR_DIM + normalize(90)),
+      });
+    }
+  }, [scrollToTargetIndex, keyboardVisible]);
 
   return (
-    <BlurView
-      blurType="light"
-      blurAmount={30}
-      reducedTransparencyFallbackColor="white"
-      style={styles.contentContainer}>
-      <IndividualMomentTitleBar
-        style={styles.header}
-        close={() => navigation.goBack()}
-        title={moment_category}
-      />
-      <FlatList
-        data={momentData}
-        renderItem={({item}: {item: MomentPostType}) => (
-          <MomentPost moment={item} userXId={userXId} screenType={screenType} />
-        )}
-        keyExtractor={(item, _) => item.moment_id}
-        showsVerticalScrollIndicator={false}
-        initialScrollIndex={initialIndex}
-      />
-    </BlurView>
+    <MomentContext.Provider
+      value={{
+        keyboardVisible,
+        setScrollToTargetIndex,
+      }}>
+      <BlurView
+        blurType="light"
+        blurAmount={30}
+        reducedTransparencyFallbackColor="white"
+        style={styles.contentContainer}>
+        <IndividualMomentTitleBar
+          style={styles.header}
+          close={() => navigation.goBack()}
+          title={moment_category}
+        />
+        <FlatList
+          ref={scrollRef}
+          data={momentData}
+          renderItem={({item, index}) => (
+            <MomentPost
+              moment={item}
+              userXId={userXId}
+              screenType={screenType}
+              index={index}
+            />
+          )}
+          keyExtractor={(item, _) => item.moment_id}
+          showsVerticalScrollIndicator={false}
+          initialScrollIndex={initialIndex}
+        />
+      </BlurView>
+    </MomentContext.Provider>
   );
 };
 const styles = StyleSheet.create({
diff --git a/src/screens/profile/MomentCommentsScreen.tsx b/src/screens/profile/MomentCommentsScreen.tsx
index 402e5f44..7dfe8ae9 100644
--- a/src/screens/profile/MomentCommentsScreen.tsx
+++ b/src/screens/profile/MomentCommentsScreen.tsx
@@ -48,8 +48,9 @@ const MomentCommentsScreen: React.FC<MomentCommentsScreenProps> = ({route}) => {
     React.useState(true);
 
   //Keeps track of the current comments object in focus so that the application knows which comment to post a reply to
-  const [commentTapped, setCommentTapped] =
-    useState<CommentType | CommentThreadType | undefined>();
+  const [commentTapped, setCommentTapped] = useState<
+    CommentType | CommentThreadType | undefined
+  >();
 
   useEffect(() => {
     navigation.setOptions({
-- 
cgit v1.2.3-70-g09d2


From e4dd6cf05a631197be4d192901d532e8625900bb Mon Sep 17 00:00:00 2001
From: Ivan Chen <ivan@tagg.id>
Date: Fri, 11 Jun 2021 15:41:50 -0400
Subject: Cleanup scrolling logic, Fix scrollTo logic

---
 src/components/comments/AddComment.tsx       | 85 +++++++++++++++-------------
 src/components/moments/MomentPostContent.tsx | 18 ++++--
 src/screens/profile/IndividualMoment.tsx     | 17 ++----
 3 files changed, 64 insertions(+), 56 deletions(-)

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

diff --git a/src/components/comments/AddComment.tsx b/src/components/comments/AddComment.tsx
index 9d9824db..9667046c 100644
--- a/src/components/comments/AddComment.tsx
+++ b/src/components/comments/AddComment.tsx
@@ -26,6 +26,7 @@ export interface AddCommentProps {
   placeholderText: string;
   callback?: (message: string) => void;
   onFocus?: () => void;
+  isKeyboardAvoiding?: boolean;
   theme?: 'dark' | 'white';
 }
 
@@ -34,6 +35,7 @@ const AddComment: React.FC<AddCommentProps> = ({
   placeholderText,
   callback = (_) => null,
   onFocus = () => null,
+  isKeyboardAvoiding = true,
   theme = 'white',
 }) => {
   const {setShouldUpdateAllComments = () => null, commentTapped} =
@@ -111,49 +113,54 @@ const AddComment: React.FC<AddCommentProps> = ({
     }
   }, [isReplyingToComment, isReplyingToReply, commentTapped]);
 
-  return (
+  const mainContent = () => (
+    <View
+      style={[
+        theme === 'white' ? styles.containerWhite : styles.containerDark,
+        keyboardVisible && theme !== 'dark' ? styles.whiteBackround : {},
+      ]}>
+      <View style={styles.textContainer}>
+        <Avatar style={styles.avatar} uri={avatar} />
+        <MentionInputControlled
+          containerStyle={styles.text}
+          placeholderTextColor={theme === 'dark' ? '#828282' : undefined}
+          placeholder={placeholderText}
+          value={inReplyToMention + comment}
+          onFocus={onFocus}
+          onChange={(newText: string) => {
+            // skipping the `inReplyToMention` text
+            setComment(
+              newText.substring(inReplyToMention.length, newText.length),
+            );
+          }}
+          inputRef={ref}
+          partTypes={mentionPartTypes('blue')}
+        />
+        {(theme === 'white' || (theme === 'dark' && keyboardVisible)) && (
+          <View style={styles.submitButton}>
+            <TouchableOpacity
+              style={
+                comment === ''
+                  ? [styles.submitButton, styles.greyButton]
+                  : styles.submitButton
+              }
+              disabled={comment === ''}
+              onPress={addComment}>
+              <UpArrowIcon width={35} height={35} color={'white'} />
+            </TouchableOpacity>
+          </View>
+        )}
+      </View>
+    </View>
+  );
+  return isKeyboardAvoiding ? (
     <KeyboardAvoidingView
       behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
       keyboardVerticalOffset={SCREEN_HEIGHT * 0.1}>
-      <View
-        style={[
-          theme === 'white' ? styles.containerWhite : styles.containerDark,
-          keyboardVisible && theme !== 'dark' ? styles.whiteBackround : {},
-        ]}>
-        <View style={styles.textContainer}>
-          <Avatar style={styles.avatar} uri={avatar} />
-          <MentionInputControlled
-            containerStyle={styles.text}
-            placeholderTextColor={theme === 'dark' ? '#828282' : undefined}
-            placeholder={placeholderText}
-            value={inReplyToMention + comment}
-            onFocus={onFocus}
-            onChange={(newText: string) => {
-              // skipping the `inReplyToMention` text
-              setComment(
-                newText.substring(inReplyToMention.length, newText.length),
-              );
-            }}
-            inputRef={ref}
-            partTypes={mentionPartTypes('blue')}
-          />
-          {(theme === 'white' || (theme === 'dark' && keyboardVisible)) && (
-            <View style={styles.submitButton}>
-              <TouchableOpacity
-                style={
-                  comment === ''
-                    ? [styles.submitButton, styles.greyButton]
-                    : styles.submitButton
-                }
-                disabled={comment === ''}
-                onPress={addComment}>
-                <UpArrowIcon width={35} height={35} color={'white'} />
-              </TouchableOpacity>
-            </View>
-          )}
-        </View>
-      </View>
+      {mainContent()}
     </KeyboardAvoidingView>
+  ) : (
+    mainContent()
   );
 };
 
diff --git a/src/components/moments/MomentPostContent.tsx b/src/components/moments/MomentPostContent.tsx
index da04211f..89f2a281 100644
--- a/src/components/moments/MomentPostContent.tsx
+++ b/src/components/moments/MomentPostContent.tsx
@@ -49,8 +49,8 @@ const MomentPostContent: React.FC<MomentPostContentProps> = ({
   );
   const [commentPreview, setCommentPreview] =
     useState<MomentCommentPreviewType | null>(moment.comment_preview);
-  const {keyboardVisible, currentScrollToIndex, scrollTo} =
-    useContext(MomentContext);
+  const {keyboardVisible, scrollTo} = useContext(MomentContext);
+  const [hideText, setHideText] = useState(false);
 
   useEffect(() => {
     setTags(momentTags);
@@ -67,6 +67,12 @@ const MomentPostContent: React.FC<MomentPostContentProps> = ({
     fade();
   }, [fadeValue]);
 
+  useEffect(() => {
+    if (!keyboardVisible && hideText) {
+      setHideText(false);
+    }
+  }, [keyboardVisible, hideText]);
+
   return (
     <View style={[styles.container, style]}>
       <TouchableWithoutFeedback
@@ -97,7 +103,7 @@ const MomentPostContent: React.FC<MomentPostContentProps> = ({
           />
         </Animated.View>
       )}
-      {(!keyboardVisible || currentScrollToIndex !== index) && (
+      {!hideText && (
         <>
           {moment.caption !== '' &&
             renderTextWithMentions({
@@ -130,7 +136,11 @@ const MomentPostContent: React.FC<MomentPostContentProps> = ({
             comment: message,
           })
         }
-        onFocus={() => scrollTo(index)}
+        onFocus={() => {
+          setHideText(true);
+          scrollTo(index);
+        }}
+        isKeyboardAvoiding={false}
         theme={'dark'}
       />
       <Text style={styles.text}>{getTimePosted(moment.date_created)}</Text>
diff --git a/src/screens/profile/IndividualMoment.tsx b/src/screens/profile/IndividualMoment.tsx
index ddf4c478..b14b31fa 100644
--- a/src/screens/profile/IndividualMoment.tsx
+++ b/src/screens/profile/IndividualMoment.tsx
@@ -17,7 +17,6 @@ import {normalize, StatusBarHeight} from '../../utils';
 
 type MomentContextType = {
   keyboardVisible: boolean;
-  currentScrollToIndex: number;
   scrollTo: (index: number) => void;
 };
 
@@ -52,8 +51,6 @@ const IndividualMoment: React.FC<IndividualMomentProps> = ({
     (m) => m.moment_category === moment_category,
   );
   const initialIndex = momentData.findIndex((m) => m.moment_id === moment_id);
-  const [currentScrollToIndex, setCurrentScrollToIndex] =
-    useState<number>(initialIndex);
   const [keyboardVisible, setKeyboardVisible] = useState(false);
 
   useEffect(() => {
@@ -68,22 +65,16 @@ const IndividualMoment: React.FC<IndividualMomentProps> = ({
   }, []);
 
   const scrollTo = (index: number) => {
-    setCurrentScrollToIndex(index);
-    setTimeout(() => {
-      console.log('scrolling to', index);
-      scrollRef.current?.scrollToIndex({
-        index: index,
-        // viewOffset: -(AVATAR_DIM + normalize(120)),
-        viewOffset: -(AVATAR_DIM + normalize(90)),
-      });
-    }, 100);
+    scrollRef.current?.scrollToIndex({
+      index: index,
+      viewOffset: -(AVATAR_DIM + normalize(90)),
+    });
   };
 
   return (
     <MomentContext.Provider
       value={{
         keyboardVisible,
-        currentScrollToIndex,
         scrollTo,
       }}>
       <BlurView
-- 
cgit v1.2.3-70-g09d2

