From 2f9ecfb9bc89c7c6e7ac09952b97d3f3813075bc Mon Sep 17 00:00:00 2001 From: Ivan Chen Date: Thu, 10 Jun 2021 19:20:19 -0400 Subject: Add logic for keyboard focus --- src/screens/profile/IndividualMoment.tsx | 102 ++++++++++++++++++++------- src/screens/profile/MomentCommentsScreen.tsx | 5 +- 2 files changed, 79 insertions(+), 28 deletions(-) (limited to 'src/screens') 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; + type IndividualMomentNavigationProp = StackNavigationProp< MainStackParams, 'IndividualMoment' >; + interface IndividualMomentProps { route: IndividualMomentRouteProp; navigation: IndividualMomentNavigationProp; @@ -27,39 +38,78 @@ const IndividualMoment: React.FC = ({ 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>(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(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 ( - - navigation.goBack()} - title={moment_category} - /> - ( - - )} - keyExtractor={(item, _) => item.moment_id} - showsVerticalScrollIndicator={false} - initialScrollIndex={initialIndex} - /> - + + + navigation.goBack()} + title={moment_category} + /> + ( + + )} + keyExtractor={(item, _) => item.moment_id} + showsVerticalScrollIndicator={false} + initialScrollIndex={initialIndex} + /> + + ); }; 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 = ({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(); + const [commentTapped, setCommentTapped] = useState< + CommentType | CommentThreadType | undefined + >(); useEffect(() => { navigation.setOptions({ -- cgit v1.2.3-70-g09d2