From 9322aede82815ba5a6bddf5b289692955d6e1d96 Mon Sep 17 00:00:00 2001 From: Ivan Chen Date: Fri, 30 Apr 2021 18:05:28 -0400 Subject: added display text parsing --- src/utils/comments.tsx | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 src/utils/comments.tsx (limited to 'src/utils/comments.tsx') diff --git a/src/utils/comments.tsx b/src/utils/comments.tsx new file mode 100644 index 00000000..a1f353d6 --- /dev/null +++ b/src/utils/comments.tsx @@ -0,0 +1,67 @@ +import React from 'react'; +import {Text} from 'react-native'; +import { + isMentionPartType, + parseValue, + Part, + PartType, +} from 'react-native-controlled-mentions'; +import TaggTypeahead from '../components/common/TaggTypeahead'; +import {TAGG_LIGHT_BLUE} from '../constants'; + +/** + * Part renderer + * + * https://github.com/dabakovich/react-native-controlled-mentions#rendering-mentioninputs-value + * + * @param part + * @param index + */ +const renderPart = (part: Part, index: number) => { + // Just plain text + if (!part.partType) { + return {part.text}; + } + + // Mention type part + if (isMentionPartType(part.partType)) { + return ( + console.log('Pressed', part.data)}> + {part.text} + + ); + } + + // Other styled part types + return ( + + {part.text} + + ); +}; + +/** + * Value renderer. Parsing value to parts array and then mapping the array using 'renderPart' + * + * https://github.com/dabakovich/react-native-controlled-mentions#rendering-mentioninputs-value + * + * @param value - value from MentionInput + * @param partTypes - the part types array that you providing to MentionInput + */ +export const renderValue: React.FC = (value: string, partTypes: PartType[]) => { + const {parts} = parseValue(value, partTypes); + return {parts.map(renderPart)}; +}; + +export const mentionPartTypes: PartType[] = [ + { + trigger: '@', + renderSuggestions: (props) => , + allowedSpacesCount: 0, + isInsertSpaceAfterMention: true, + textStyle: {color: TAGG_LIGHT_BLUE}, + }, +]; -- cgit v1.2.3-70-g09d2 From c23feea922da063d88d031f25b72b53ba593ec04 Mon Sep 17 00:00:00 2001 From: Ivan Chen Date: Tue, 4 May 2021 20:07:03 -0400 Subject: fixed type warning --- src/components/comments/CommentTile.tsx | 7 +++++-- src/utils/comments.tsx | 10 +++++++++- 2 files changed, 14 insertions(+), 3 deletions(-) (limited to 'src/utils/comments.tsx') diff --git a/src/components/comments/CommentTile.tsx b/src/components/comments/CommentTile.tsx index 37a249a8..12f32c95 100644 --- a/src/components/comments/CommentTile.tsx +++ b/src/components/comments/CommentTile.tsx @@ -14,7 +14,7 @@ import {deleteComment, getCommentsCount} from '../../services'; import {RootState} from '../../store/rootReducer'; import {CommentThreadType, CommentType, ScreenType} from '../../types'; import {getTimePosted, normalize, SCREEN_WIDTH} from '../../utils'; -import {mentionPartTypes, renderValue} from '../../utils/comments'; +import {mentionPartTypes, renderTextWithMentions} from '../../utils/comments'; import {ProfilePreview} from '../profile'; import CommentsContainer from './CommentsContainer'; @@ -136,7 +136,10 @@ const CommentTile: React.FC = ({ /> - {renderValue(commentObject.comment, mentionPartTypes)} + {renderTextWithMentions({ + value: commentObject.comment, + partTypes: mentionPartTypes, + })} diff --git a/src/utils/comments.tsx b/src/utils/comments.tsx index a1f353d6..c0b522f2 100644 --- a/src/utils/comments.tsx +++ b/src/utils/comments.tsx @@ -43,6 +43,11 @@ const renderPart = (part: Part, index: number) => { ); }; +interface RenderProps { + value: string; + partTypes: PartType[]; +} + /** * Value renderer. Parsing value to parts array and then mapping the array using 'renderPart' * @@ -51,7 +56,10 @@ const renderPart = (part: Part, index: number) => { * @param value - value from MentionInput * @param partTypes - the part types array that you providing to MentionInput */ -export const renderValue: React.FC = (value: string, partTypes: PartType[]) => { +export const renderTextWithMentions: React.FC = ({ + value, + partTypes, +}) => { const {parts} = parseValue(value, partTypes); return {parts.map(renderPart)}; }; -- cgit v1.2.3-70-g09d2 From 7f9799c6693254f8eb6729c0977826694c28c437 Mon Sep 17 00:00:00 2001 From: Ivan Chen Date: Tue, 4 May 2021 20:46:27 -0400 Subject: added navigation to profile --- src/components/comments/CommentTile.tsx | 34 ++++++++++++++------ src/components/moments/MomentPostContent.tsx | 23 ++++++++++++-- src/screens/profile/CaptionScreen.tsx | 17 +++++----- src/utils/comments.tsx | 46 ++++++++++++++++++---------- src/utils/users.ts | 24 +++++++++++++++ 5 files changed, 105 insertions(+), 39 deletions(-) (limited to 'src/utils/comments.tsx') diff --git a/src/components/comments/CommentTile.tsx b/src/components/comments/CommentTile.tsx index 12f32c95..ce346af5 100644 --- a/src/components/comments/CommentTile.tsx +++ b/src/components/comments/CommentTile.tsx @@ -1,9 +1,10 @@ +import {useNavigation} from '@react-navigation/native'; import React, {Fragment, useContext, useEffect, useRef, useState} from 'react'; import {Alert, Animated, StyleSheet} from 'react-native'; import {Text, View} from 'react-native-animatable'; import {RectButton, TouchableOpacity} from 'react-native-gesture-handler'; import Swipeable from 'react-native-gesture-handler/Swipeable'; -import {useSelector} from 'react-redux'; +import {useDispatch, useSelector, useStore} from 'react-redux'; import Arrow from '../../assets/icons/back-arrow-colored.svg'; import ClockIcon from '../../assets/icons/clock-icon-01.svg'; import Trash from '../../assets/ionicons/trash-outline.svg'; @@ -12,9 +13,19 @@ import {ERROR_FAILED_TO_DELETE_COMMENT} from '../../constants/strings'; import {CommentContext} from '../../screens/profile/MomentCommentsScreen'; import {deleteComment, getCommentsCount} from '../../services'; import {RootState} from '../../store/rootReducer'; -import {CommentThreadType, CommentType, ScreenType} from '../../types'; -import {getTimePosted, normalize, SCREEN_WIDTH} from '../../utils'; -import {mentionPartTypes, renderTextWithMentions} from '../../utils/comments'; +import { + CommentThreadType, + CommentType, + ScreenType, + UserType, +} from '../../types'; +import { + getTimePosted, + navigateToProfile, + normalize, + SCREEN_WIDTH, +} from '../../utils'; +import {renderTextWithMentions} from '../../utils/comments'; import {ProfilePreview} from '../profile'; import CommentsContainer from './CommentsContainer'; @@ -46,6 +57,9 @@ const CommentTile: React.FC = ({ const [shouldUpdateChild, setShouldUpdateChild] = useState(true); const swipeRef = useRef(null); const {replyPosted} = useSelector((state: RootState) => state.user); + const state: RootState = useStore().getState(); + const navigation = useNavigation(); + const dispatch = useDispatch(); useEffect(() => { if (shouldUpdateParent) { @@ -135,12 +149,12 @@ const CommentTile: React.FC = ({ screenType={screenType} /> - - {renderTextWithMentions({ - value: commentObject.comment, - partTypes: mentionPartTypes, - })} - + {renderTextWithMentions({ + value: commentObject.comment, + styles: styles.comment, + onPress: (user: UserType) => + navigateToProfile(state, dispatch, navigation, screenType, user), + })} {' ' + timePosted} diff --git a/src/components/moments/MomentPostContent.tsx b/src/components/moments/MomentPostContent.tsx index d68ceaa3..03034925 100644 --- a/src/components/moments/MomentPostContent.tsx +++ b/src/components/moments/MomentPostContent.tsx @@ -1,8 +1,17 @@ +import {useNavigation} from '@react-navigation/native'; import React, {useEffect} from 'react'; import {Image, StyleSheet, Text, View, ViewProps} from 'react-native'; +import {useDispatch, useStore} from 'react-redux'; import {getCommentsCount} from '../../services'; -import {ScreenType} from '../../types'; -import {getTimePosted, SCREEN_HEIGHT, SCREEN_WIDTH} from '../../utils'; +import {RootState} from '../../store/rootReducer'; +import {ScreenType, UserType} from '../../types'; +import { + getTimePosted, + navigateToProfile, + SCREEN_HEIGHT, + SCREEN_WIDTH, +} from '../../utils'; +import {renderTextWithMentions} from '../../utils/comments'; import {CommentsCount} from '../comments'; interface MomentPostContentProps extends ViewProps { @@ -22,6 +31,9 @@ const MomentPostContent: React.FC = ({ }) => { const [elapsedTime, setElapsedTime] = React.useState(); const [comments_count, setCommentsCount] = React.useState(''); + const state: RootState = useStore().getState(); + const navigation = useNavigation(); + const dispatch = useDispatch(); useEffect(() => { const fetchCommentsCount = async () => { @@ -47,7 +59,12 @@ const MomentPostContent: React.FC = ({ /> {elapsedTime} - {caption} + {renderTextWithMentions({ + value: caption, + styles: styles.captionText, + onPress: (user: UserType) => + navigateToProfile(state, dispatch, navigation, screenType, user), + })} ); }; diff --git a/src/screens/profile/CaptionScreen.tsx b/src/screens/profile/CaptionScreen.tsx index 156ee41c..041f0da2 100644 --- a/src/screens/profile/CaptionScreen.tsx +++ b/src/screens/profile/CaptionScreen.tsx @@ -11,9 +11,10 @@ import { TouchableWithoutFeedback, View, } from 'react-native'; +import {MentionInput} from 'react-native-controlled-mentions'; import {Button} from 'react-native-elements'; import {useDispatch, useSelector} from 'react-redux'; -import {SearchBackground, TaggBigInput} from '../../components'; +import {SearchBackground} from '../../components'; import {CaptionScreenHeader} from '../../components/'; import TaggLoadingIndicator from '../../components/common/TaggLoadingIndicator'; import {TAGG_LIGHT_BLUE_2} from '../../constants'; @@ -26,6 +27,7 @@ import { } from '../../store/actions'; import {RootState} from '../../store/rootReducer'; import {SCREEN_WIDTH, StatusBarHeight} from '../../utils'; +import {mentionPartTypes} from '../../utils/comments'; /** * Upload Screen to allow users to upload posts to Tagg @@ -49,10 +51,6 @@ const CaptionScreen: React.FC = ({route, navigation}) => { const [caption, setCaption] = useState(''); const [loading, setLoading] = useState(false); - const handleCaptionUpdate = (newCaption: string) => { - setCaption(newCaption); - }; - const navigateToProfile = () => { //Since the logged In User is navigating to own profile, useXId is not required navigation.navigate('Profile', { @@ -112,12 +110,13 @@ const CaptionScreen: React.FC = ({route, navigation}) => { source={{uri: image.path}} resizeMode={'cover'} /> - diff --git a/src/utils/comments.tsx b/src/utils/comments.tsx index c0b522f2..47d26bb5 100644 --- a/src/utils/comments.tsx +++ b/src/utils/comments.tsx @@ -1,23 +1,26 @@ import React from 'react'; -import {Text} from 'react-native'; +import {StyleProp, Text, TextStyle} from 'react-native'; import { isMentionPartType, parseValue, Part, PartType, } from 'react-native-controlled-mentions'; +import {TouchableOpacity} from 'react-native-gesture-handler'; import TaggTypeahead from '../components/common/TaggTypeahead'; import {TAGG_LIGHT_BLUE} from '../constants'; +import {UserType} from '../types'; /** * Part renderer * * https://github.com/dabakovich/react-native-controlled-mentions#rendering-mentioninputs-value - * - * @param part - * @param index */ -const renderPart = (part: Part, index: number) => { +const renderPart = ( + part: Part, + index: number, + handlePress: (user: UserType) => void, +) => { // Just plain text if (!part.partType) { return {part.text}; @@ -26,12 +29,18 @@ const renderPart = (part: Part, index: number) => { // Mention type part if (isMentionPartType(part.partType)) { return ( - console.log('Pressed', part.data)}> - {part.text} - + onPress={() => { + if (part.data) { + handlePress({ + userId: part.data.id, + username: part.data.name, + }); + } + }}> + {part.text} + ); } @@ -45,23 +54,26 @@ const renderPart = (part: Part, index: number) => { interface RenderProps { value: string; - partTypes: PartType[]; + styles: StyleProp; + onPress: (user: UserType) => void; } /** * Value renderer. Parsing value to parts array and then mapping the array using 'renderPart' * * https://github.com/dabakovich/react-native-controlled-mentions#rendering-mentioninputs-value - * - * @param value - value from MentionInput - * @param partTypes - the part types array that you providing to MentionInput */ export const renderTextWithMentions: React.FC = ({ value, - partTypes, + styles, + onPress, }) => { - const {parts} = parseValue(value, partTypes); - return {parts.map(renderPart)}; + const {parts} = parseValue(value, mentionPartTypes); + return ( + + {parts.map((part, index) => renderPart(part, index, onPress))} + + ); }; export const mentionPartTypes: PartType[] = [ diff --git a/src/utils/users.ts b/src/utils/users.ts index abadaf6e..c167ac2f 100644 --- a/src/utils/users.ts +++ b/src/utils/users.ts @@ -1,4 +1,6 @@ import AsyncStorage from '@react-native-community/async-storage'; +import {NavigationProp} from '@react-navigation/core'; +import {Dispatch} from 'react'; import {INTEGRATED_SOCIAL_LIST} from '../constants'; import {isUserBlocked, loadSocialPosts} from '../services'; import { @@ -199,3 +201,25 @@ export const canViewProfile = ( } return false; }; + +export const navigateToProfile = async ( + state: RootState, + dispatch: any, + navigation: any, + screenType: ScreenType, + user: UserType, +) => { + const loggedInUserId = state.user.user.userId; + const {userId, username} = user; + if (!userXInStore(state, screenType, userId)) { + await fetchUserX( + dispatch, + {userId: userId, username: username}, + screenType, + ); + } + navigation.push('Profile', { + userXId: userId === loggedInUserId ? undefined : userId, + screenType, + }); +}; -- cgit v1.2.3-70-g09d2 From 05bcb134a026ee98919438044a63a656f60e74f2 Mon Sep 17 00:00:00 2001 From: Ivan Chen Date: Tue, 4 May 2021 21:06:48 -0400 Subject: fixed layout issue --- src/utils/comments.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/utils/comments.tsx') diff --git a/src/utils/comments.tsx b/src/utils/comments.tsx index 47d26bb5..a71e3857 100644 --- a/src/utils/comments.tsx +++ b/src/utils/comments.tsx @@ -6,7 +6,6 @@ import { Part, PartType, } from 'react-native-controlled-mentions'; -import {TouchableOpacity} from 'react-native-gesture-handler'; import TaggTypeahead from '../components/common/TaggTypeahead'; import {TAGG_LIGHT_BLUE} from '../constants'; import {UserType} from '../types'; @@ -29,8 +28,9 @@ const renderPart = ( // Mention type part if (isMentionPartType(part.partType)) { return ( - { if (part.data) { handlePress({ @@ -39,8 +39,8 @@ const renderPart = ( }); } }}> - {part.text} - + {part.text} + ); } -- cgit v1.2.3-70-g09d2