diff options
author | Brian Kim <brian@tagg.id> | 2021-06-15 12:21:53 +0900 |
---|---|---|
committer | Brian Kim <brian@tagg.id> | 2021-06-15 12:21:53 +0900 |
commit | 6ee452c257d388913a1effd817c37bef638bc179 (patch) | |
tree | fbba8144adf7b3177c0014b687440a5450019818 | |
parent | bc2c093e9342ed8deb98652d1c278417dd6435f3 (diff) |
Fix bug in caption screen of suggestions not disappearing
-rw-r--r-- | src/components/comments/AddComment.tsx | 5 | ||||
-rw-r--r-- | src/components/comments/CommentTextField.tsx | 162 | ||||
-rw-r--r-- | src/components/comments/MentionInputControlled.tsx | 106 | ||||
-rw-r--r-- | src/components/comments/index.ts | 1 | ||||
-rw-r--r-- | src/screens/profile/CaptionScreen.tsx | 4 |
5 files changed, 210 insertions, 68 deletions
diff --git a/src/components/comments/AddComment.tsx b/src/components/comments/AddComment.tsx index db85d525..3c0e9a0a 100644 --- a/src/components/comments/AddComment.tsx +++ b/src/components/comments/AddComment.tsx @@ -18,8 +18,8 @@ import {RootState} from '../../store/rootreducer'; import {CommentThreadType, CommentType} from '../../types'; import {SCREEN_HEIGHT, SCREEN_WIDTH} from '../../utils'; import {mentionPartTypes} from '../../utils/comments'; -import {Avatar} from '../common'; -import {MentionInputControlled} from './MentionInputControlled'; +import {CommentTextField} from './CommentTextField'; +import MentionInputControlled from './MentionInputControlled'; import {normalize} from 'react-native-elements'; export interface AddCommentProps { @@ -124,6 +124,7 @@ const AddComment: React.FC<AddCommentProps> = ({momentId, placeholderText}) => { inputRef={ref} partTypes={mentionPartTypes('blue', 'comment')} addComment={addComment} + NewText={CommentTextField} /> </View> </View> diff --git a/src/components/comments/CommentTextField.tsx b/src/components/comments/CommentTextField.tsx new file mode 100644 index 00000000..61b489bb --- /dev/null +++ b/src/components/comments/CommentTextField.tsx @@ -0,0 +1,162 @@ +import React, { + FC, + MutableRefObject, + Ref, + useMemo, + useRef, + useState, + ReactFragment, +} from 'react'; +import { + NativeSyntheticEvent, + StyleSheet, + StyleProp, + Text, + TextInput, + TextInputProps, + TextInputSelectionChangeEventData, + TouchableOpacity, + View, + ViewStyle, +} from 'react-native'; +import {useDispatch, useSelector} from 'react-redux'; +import {TAGG_LIGHT_BLUE} from '../../constants'; +import { + Part, + PartType, + PatternPartType, + MentionPartType, + Suggestion, +} from 'react-native-controlled-mentions/dist/types'; +import { + defaultMentionTextStyle, + generateValueFromPartsAndChangedText, + generateValueWithAddedSuggestion, + getMentionPartSuggestionKeywords, + isMentionPartType, + parseValue, +} from 'react-native-controlled-mentions/dist/utils'; +import {Avatar} from '../common'; +import {normalize} from 'react-native-elements'; + +import UpArrowIcon from '../../assets/icons/up_arrow.svg'; +import {SCREEN_WIDTH, SCREEN_HEIGHT} from '../../utils'; + +type CommentTextFieldProps = { + containerStyle: StyleProp<ViewStyle>; + validateInput: any; + keyboardText: string; + partTypes: PartType[]; + renderMentionSuggestions: (mentionType: MentionPartType) => ReactFragment; + handleTextInputRef: (ref: TextInput) => null; + onChangeInput: (changedText: string) => null; + handleSelectionChange: ( + event: NativeSyntheticEvent<TextInputSelectionChangeEventData>, + ) => null; + parts: Part[]; + addComment: () => any; +}; + +const CommentTextField: FC<CommentTextFieldProps> = ({ + containerStyle, + validateInput, + keyboardText, + partTypes, + renderMentionSuggestions, + handleTextInputRef, + onChangeInput, + handleSelectionChange, + parts, + addComment, + ...textInputProps +}) => { + const {avatar} = useSelector((state: RootState) => state.user); + + return ( + <View style={containerStyle}> + {validateInput(keyboardText) + ? ( + partTypes.filter( + (one) => + isMentionPartType(one) && + one.renderSuggestions != null && + !one.isBottomMentionSuggestionsRender, + ) as MentionPartType[] + ).map(renderMentionSuggestions) + : null} + + <View style={styles.containerStyle}> + <Avatar style={styles.avatar} uri={avatar} /> + <TextInput + multiline + {...textInputProps} + ref={handleTextInputRef} + onChangeText={onChangeInput} + onSelectionChange={handleSelectionChange} + style={styles.text}> + <Text> + {parts.map(({text, partType, data}, index) => + partType ? ( + <Text + key={`${index}-${data?.trigger ?? 'pattern'}`} + style={partType.textStyle ?? defaultMentionTextStyle}> + {text} + </Text> + ) : ( + <Text key={index}>{text}</Text> + ), + )} + </Text> + </TextInput> + <View style={styles.submitButton}> + <TouchableOpacity style={styles.submitButton} onPress={addComment}> + <UpArrowIcon width={35} height={35} color={'white'} /> + </TouchableOpacity> + </View> + </View> + + {validateInput(keyboardText) + ? ( + partTypes.filter( + (one) => + isMentionPartType(one) && + one.renderSuggestions != null && + one.isBottomMentionSuggestionsRender, + ) as MentionPartType[] + ).map(renderMentionSuggestions) + : null} + </View> + ); +}; + +const styles = StyleSheet.create({ + avatar: { + height: 35, + width: 35, + borderRadius: 30, + marginRight: 10, + marginLeft: '3%', + marginVertical: '2%', + }, + containerStyle: { + flexDirection: 'row', + alignSelf: 'center', + alignItems: 'center', + justifyContent: 'center', + height: normalize(40), + }, + submitButton: { + height: 35, + width: 35, + backgroundColor: TAGG_LIGHT_BLUE, + borderRadius: 999, + justifyContent: 'center', + alignItems: 'center', + marginRight: '3%', + marginVertical: '2%', + alignSelf: 'flex-end', + }, + text: {flex: 1}, +}); + +export {CommentTextField}; diff --git a/src/components/comments/MentionInputControlled.tsx b/src/components/comments/MentionInputControlled.tsx index c37d2182..50762ac0 100644 --- a/src/components/comments/MentionInputControlled.tsx +++ b/src/components/comments/MentionInputControlled.tsx @@ -5,6 +5,7 @@ import React, { useMemo, useRef, useState, + ReactFragment, } from 'react'; import { NativeSyntheticEvent, @@ -51,7 +52,9 @@ type MentionInputControlledProps = Omit<TextInputProps, 'onChange'> & { containerStyle?: StyleProp<ViewStyle>; - addComment?: () => any; + addComment?: () => any | null; + + NewText?: FC<any>; }; const MentionInputControlled: FC<MentionInputControlledProps> = ({ @@ -68,6 +71,8 @@ const MentionInputControlled: FC<MentionInputControlledProps> = ({ addComment, + NewText, + ...textInputProps }) => { const textInput = useRef<TextInput | null>(null); @@ -76,8 +81,6 @@ const MentionInputControlled: FC<MentionInputControlledProps> = ({ const [keyboardText, setKeyboardText] = useState<string>(''); - const {avatar} = useSelector((state: RootState) => state.user); - const validRegex = () => { if (partTypes.length === 0) { return /.*@[^ ]*$/; @@ -185,7 +188,21 @@ const MentionInputControlled: FC<MentionInputControlledProps> = ({ return validRegex().test(testString); }; - return ( + return NewText ? ( + <NewText + {...textInputProps} + containerStyle={containerStyle} + validateInput={validateInput} + keyboardText={keyboardText} + partTypes={partTypes} + renderMentionSuggestions={renderMentionSuggestions} + handleTextInputRef={handleTextInputRef} + onChangeInput={onChangeInput} + handleSelectionChange={handleSelectionChange} + parts={parts} + addComment={addComment} + /> + ) : ( <View style={containerStyle}> {validateInput(keyboardText) ? ( @@ -198,35 +215,26 @@ const MentionInputControlled: FC<MentionInputControlledProps> = ({ ).map(renderMentionSuggestions) : null} - <View style={styles.containerStyle}> - <Avatar style={styles.avatar} uri={avatar} /> - <TextInput - multiline - {...textInputProps} - ref={handleTextInputRef} - onChangeText={onChangeInput} - onSelectionChange={handleSelectionChange} - style={styles.text}> - <Text> - {parts.map(({text, partType, data}, index) => - partType ? ( - <Text - key={`${index}-${data?.trigger ?? 'pattern'}`} - style={partType.textStyle ?? defaultMentionTextStyle}> - {text} - </Text> - ) : ( - <Text key={index}>{text}</Text> - ), - )} - </Text> - </TextInput> - <View style={styles.submitButton}> - <TouchableOpacity style={styles.submitButton} onPress={addComment}> - <UpArrowIcon width={35} height={35} color={'white'} /> - </TouchableOpacity> - </View> - </View> + <TextInput + multiline + {...textInputProps} + ref={handleTextInputRef} + onChangeText={onChangeInput} + onSelectionChange={handleSelectionChange}> + <Text> + {parts.map(({text, partType, data}, index) => + partType ? ( + <Text + key={`${index}-${data?.trigger ?? 'pattern'}`} + style={partType.textStyle ?? defaultMentionTextStyle}> + {text} + </Text> + ) : ( + <Text key={index}>{text}</Text> + ), + )} + </Text> + </TextInput> {validateInput(keyboardText) ? ( @@ -242,34 +250,4 @@ const MentionInputControlled: FC<MentionInputControlledProps> = ({ ); }; -const styles = StyleSheet.create({ - avatar: { - height: 35, - width: 35, - borderRadius: 30, - marginRight: 10, - marginLeft: '3%', - marginVertical: '2%', - }, - containerStyle: { - flexDirection: 'row', - alignSelf: 'center', - alignItems: 'center', - justifyContent: 'center', - height: normalize(40), - }, - submitButton: { - height: 35, - width: 35, - backgroundColor: TAGG_LIGHT_BLUE, - borderRadius: 999, - justifyContent: 'center', - alignItems: 'center', - marginRight: '3%', - marginVertical: '2%', - alignSelf: 'flex-end', - }, - text: {flex: 1}, -}); - -export {MentionInputControlled}; +export default MentionInputControlled; diff --git a/src/components/comments/index.ts b/src/components/comments/index.ts index 6293f799..653f594c 100644 --- a/src/components/comments/index.ts +++ b/src/components/comments/index.ts @@ -1,3 +1,4 @@ export {default as CommentsCount} from '../comments/CommentsCount'; export {default as CommentTile} from './CommentTile'; export {default as AddComment} from './AddComment'; +export {default as MentionInputControlled} from './MentionInputControlled'; diff --git a/src/screens/profile/CaptionScreen.tsx b/src/screens/profile/CaptionScreen.tsx index 05095d16..755c668b 100644 --- a/src/screens/profile/CaptionScreen.tsx +++ b/src/screens/profile/CaptionScreen.tsx @@ -13,7 +13,7 @@ import { TouchableWithoutFeedback, View, } from 'react-native'; -import {MentionInput} from 'react-native-controlled-mentions'; +import {MentionInputControlled} from '../../components'; import {Button, normalize} from 'react-native-elements'; import {useDispatch, useSelector} from 'react-redux'; import FrontArrow from '../../assets/icons/front-arrow.svg'; @@ -161,7 +161,7 @@ const CaptionScreen: React.FC<CaptionScreenProps> = ({route, navigation}) => { source={{uri: image.path}} resizeMode={'cover'} /> - <MentionInput + <MentionInputControlled containerStyle={styles.text} placeholder="Write something....." placeholderTextColor="gray" |