From a13dcb5110245bb554d79e779c4942e6f5aaf18a Mon Sep 17 00:00:00 2001 From: Ivan Chen Date: Tue, 27 Apr 2021 10:46:17 -0400 Subject: refactored avatar --- src/components/common/Avatar.tsx | 18 ++++++++++++++++++ src/components/common/AvatarTitle.tsx | 14 ++++---------- src/components/common/index.ts | 1 + 3 files changed, 23 insertions(+), 10 deletions(-) create mode 100644 src/components/common/Avatar.tsx (limited to 'src/components/common') diff --git a/src/components/common/Avatar.tsx b/src/components/common/Avatar.tsx new file mode 100644 index 00000000..831cf906 --- /dev/null +++ b/src/components/common/Avatar.tsx @@ -0,0 +1,18 @@ +import React, {FC} from 'react'; +import {Image, ImageStyle, StyleProp} from 'react-native'; + +type AvatarProps = { + style: StyleProp; + uri: string | undefined; +}; +const Avatar: FC = ({style, uri}) => { + return ( + + ); +}; + +export default Avatar; diff --git a/src/components/common/AvatarTitle.tsx b/src/components/common/AvatarTitle.tsx index 81351327..a2a7c0aa 100644 --- a/src/components/common/AvatarTitle.tsx +++ b/src/components/common/AvatarTitle.tsx @@ -1,10 +1,11 @@ import React from 'react'; -import {Image, StyleSheet, View} from 'react-native'; +import {StyleSheet, View} from 'react-native'; import LinearGradient from 'react-native-linear-gradient'; import {TAGGS_GRADIENT} from '../../constants'; +import Avatar from './Avatar'; type AvatarTitleProps = { - avatar: string | null; + avatar: string | undefined; }; const AvatarTitle: React.FC = ({avatar}) => { return ( @@ -16,14 +17,7 @@ const AvatarTitle: React.FC = ({avatar}) => { angleCenter={{x: 0.5, y: 0.5}} style={styles.gradient} /> - + ); }; diff --git a/src/components/common/index.ts b/src/components/common/index.ts index 5a601f1d..802cf505 100644 --- a/src/components/common/index.ts +++ b/src/components/common/index.ts @@ -23,3 +23,4 @@ export {default as FriendsButton} from './FriendsButton'; export {default as TaggSquareButton} from './TaggSquareButton'; export {default as GradientBorderButton} from './GradientBorderButton'; export {default as BasicButton} from './BasicButton'; +export {default as Avatar} from './Avatar'; -- cgit v1.2.3-70-g09d2 From ef2c8f57971b6ca55a6a3ef58609b0c80fe55869 Mon Sep 17 00:00:00 2001 From: ankit-thanekar007 Date: Mon, 3 May 2021 10:23:01 -0700 Subject: tma-822-base UI changes --- src/components/common/EmptyContentView.tsx | 129 +++++++++++++++++++++ src/screens/chat/ChatListScreen.tsx | 4 +- src/screens/main/NotificationsScreen.tsx | 4 +- .../main/notification/EmptyNotificationView.tsx | 129 --------------------- 4 files changed, 133 insertions(+), 133 deletions(-) create mode 100644 src/components/common/EmptyContentView.tsx delete mode 100644 src/screens/main/notification/EmptyNotificationView.tsx (limited to 'src/components/common') diff --git a/src/components/common/EmptyContentView.tsx b/src/components/common/EmptyContentView.tsx new file mode 100644 index 00000000..1416c556 --- /dev/null +++ b/src/components/common/EmptyContentView.tsx @@ -0,0 +1,129 @@ +import React from 'react'; +import {Image, Text, StyleSheet, View} from 'react-native'; +import LinearGradient from 'react-native-linear-gradient'; +import { + UP_TO_DATE, + NO_NEW_NOTIFICATIONS, + FIRST_MESSAGE, + START_CHATTING, +} from '../../constants/strings'; +import {NOTIFICATION_GRADIENT} from '../../constants/constants'; +import {SCREEN_HEIGHT, normalize, SCREEN_WIDTH} from '../../utils'; +import {EmptyViewProps} from '../../types/index'; + +const EmptyNotificationView: React.FC = ({viewType}) => { + const _getNotificationImage = () => { + return ( + + + + ); + }; + + const _getChatImage = () => { + return ( + + + + ); + }; + + const _getImageForType = () => { + switch (viewType) { + case 'Notification': + return _getNotificationImage(); + case 'ChatList': + return _getChatImage(); + } + }; + + const _getTextForNotification = () => { + return ( + <> + + {UP_TO_DATE} + + + {NO_NEW_NOTIFICATIONS} + + + ); + }; + + const _getTextForChat = () => { + return ( + + + {START_CHATTING} + + + {FIRST_MESSAGE} + + + ); + }; + + const _getTextForType = () => { + switch (viewType) { + case 'Notification': + return _getTextForNotification(); + case 'ChatList': + return _getTextForChat(); + } + }; + + return ( + + {_getImageForType()} + {_getTextForType()} + + ); +}; + +const styles = StyleSheet.create({ + container: { + flex: 1, + flexDirection: 'column', + justifyContent: 'center', + alignItems: 'center', + }, + topMargin: {marginTop: SCREEN_HEIGHT * 0.025}, + upperTextStyle: { + textAlign: 'center', + fontWeight: '700', + fontSize: normalize(23), + lineHeight: normalize(40), + }, + chatTextStyles: { + width: '85%', + }, + bottomTextStyle: { + textAlign: 'center', + color: '#2D3B45', + fontWeight: '600', + fontSize: normalize(20), + lineHeight: normalize(40), + }, + imageStyles: { + width: SCREEN_WIDTH * 0.72, + height: SCREEN_WIDTH * 0.72, + }, + backgroundLinearView: { + borderRadius: (SCREEN_WIDTH * 0.72) / 2, + }, +}); + +export default EmptyNotificationView; diff --git a/src/screens/chat/ChatListScreen.tsx b/src/screens/chat/ChatListScreen.tsx index 810ebdb2..1df5c2da 100644 --- a/src/screens/chat/ChatListScreen.tsx +++ b/src/screens/chat/ChatListScreen.tsx @@ -9,7 +9,7 @@ import {TabsGradient} from '../../components'; import {ChannelPreview, MessagesHeader} from '../../components/messages'; import {MainStackParams} from '../../routes'; import {RootState} from '../../store/rootReducer'; -import EmptyNotificationView from '../../screens/main/notification/EmptyNotificationView'; +import EmptyContentView from '../../components/common/EmptyContentView'; import { LocalAttachmentType, LocalChannelType, @@ -101,7 +101,7 @@ const ChatListScreen: React.FC = () => { maxUnreadCount={99} Preview={ChannelPreview} EmptyStateIndicator={() => { - return ; + return ; }} /> diff --git a/src/screens/main/NotificationsScreen.tsx b/src/screens/main/NotificationsScreen.tsx index 06a61f04..9fbc4cfe 100644 --- a/src/screens/main/NotificationsScreen.tsx +++ b/src/screens/main/NotificationsScreen.tsx @@ -28,7 +28,7 @@ import { import {RootState} from '../../store/rootReducer'; import {NotificationType, ScreenType} from '../../types'; import {getDateAge, normalize, SCREEN_HEIGHT, SCREEN_WIDTH} from '../../utils'; -import EmptyNotificationView from './notification/EmptyNotificationView'; +import EmptyContentView from '../../components/common/EmptyContentView'; const NotificationsScreen: React.FC = () => { const {newNotificationReceived} = useSelector( @@ -304,7 +304,7 @@ const NotificationsScreen: React.FC = () => { extraData={requestLimit} ListEmptyComponent={ - + } /> diff --git a/src/screens/main/notification/EmptyNotificationView.tsx b/src/screens/main/notification/EmptyNotificationView.tsx deleted file mode 100644 index b80bb203..00000000 --- a/src/screens/main/notification/EmptyNotificationView.tsx +++ /dev/null @@ -1,129 +0,0 @@ -import React from 'react'; -import {Image, Text, StyleSheet, View} from 'react-native'; -import LinearGradient from 'react-native-linear-gradient'; -import { - UP_TO_DATE, - NO_NEW_NOTIFICATIONS, - FIRST_MESSAGE, - START_CHATTING, -} from '../../../constants/strings'; -import {NOTIFICATION_GRADIENT} from '../../../constants/constants'; -import {SCREEN_HEIGHT, normalize, SCREEN_WIDTH} from '../../../utils'; -import {EmptyViewProps} from '../../../types/index'; - -const EmptyNotificationView: React.FC = ({viewType}) => { - const _getNotificationImage = () => { - return ( - - - - ); - }; - - const _getChatImage = () => { - return ( - - - - ); - }; - - const _getImageForType = () => { - switch (viewType) { - case 'Notification': - return _getNotificationImage(); - case 'ChatList': - return _getChatImage(); - } - }; - - const _getTextForNotification = () => { - return ( - <> - - {UP_TO_DATE} - - - {NO_NEW_NOTIFICATIONS} - - - ); - }; - - const _getTextForChat = () => { - return ( - - - {START_CHATTING} - - - {FIRST_MESSAGE} - - - ); - }; - - const _getTextForType = () => { - switch (viewType) { - case 'Notification': - return _getTextForNotification(); - case 'ChatList': - return _getTextForChat(); - } - }; - - return ( - - {_getImageForType()} - {_getTextForType()} - - ); -}; - -const styles = StyleSheet.create({ - container: { - flex: 1, - flexDirection: 'column', - justifyContent: 'center', - alignItems: 'center', - }, - topMargin: {marginTop: SCREEN_HEIGHT * 0.025}, - upperTextStyle: { - textAlign: 'center', - fontWeight: '700', - fontSize: normalize(23), - lineHeight: normalize(40), - }, - chatTextStyles: { - width: '85%', - }, - bottomTextStyle: { - textAlign: 'center', - color: '#2D3B45', - fontWeight: '600', - fontSize: normalize(20), - lineHeight: normalize(40), - }, - imageStyles: { - width: SCREEN_WIDTH * 0.72, - height: SCREEN_WIDTH * 0.72, - }, - backgroundLinearView: { - borderRadius: (SCREEN_WIDTH * 0.72) / 2, - }, -}); - -export default EmptyNotificationView; -- cgit v1.2.3-70-g09d2 From 2abe11e6b231410c7bd531adabfe9158109411cb Mon Sep 17 00:00:00 2001 From: ankit-thanekar007 Date: Mon, 3 May 2021 12:16:35 -0700 Subject: File name changes --- src/components/common/EmptyContentView.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/components/common') diff --git a/src/components/common/EmptyContentView.tsx b/src/components/common/EmptyContentView.tsx index 1416c556..e3aaf621 100644 --- a/src/components/common/EmptyContentView.tsx +++ b/src/components/common/EmptyContentView.tsx @@ -11,7 +11,7 @@ import {NOTIFICATION_GRADIENT} from '../../constants/constants'; import {SCREEN_HEIGHT, normalize, SCREEN_WIDTH} from '../../utils'; import {EmptyViewProps} from '../../types/index'; -const EmptyNotificationView: React.FC = ({viewType}) => { +const EmptyContentView: React.FC = ({viewType}) => { const _getNotificationImage = () => { return ( Date: Tue, 4 May 2021 07:45:08 -0700 Subject: style to look more like figma --- src/components/common/EmptyContentView.tsx | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'src/components/common') diff --git a/src/components/common/EmptyContentView.tsx b/src/components/common/EmptyContentView.tsx index e3aaf621..14ad4af1 100644 --- a/src/components/common/EmptyContentView.tsx +++ b/src/components/common/EmptyContentView.tsx @@ -100,7 +100,10 @@ const styles = StyleSheet.create({ justifyContent: 'center', alignItems: 'center', }, - topMargin: {marginTop: SCREEN_HEIGHT * 0.025}, + topMargin: { + marginTop: SCREEN_HEIGHT * 0.025, + paddingBottom: '5%', + }, upperTextStyle: { textAlign: 'center', fontWeight: '700', @@ -112,10 +115,10 @@ const styles = StyleSheet.create({ }, bottomTextStyle: { textAlign: 'center', - color: '#2D3B45', + color: '#808080', fontWeight: '600', fontSize: normalize(20), - lineHeight: normalize(40), + lineHeight: normalize(30), }, imageStyles: { width: SCREEN_WIDTH * 0.72, -- cgit v1.2.3-70-g09d2 From f0c5a226d4ae02cd92d92372708056f63d3cd976 Mon Sep 17 00:00:00 2001 From: Ivan Chen Date: Thu, 29 Apr 2021 16:32:30 -0400 Subject: added ParsedText, initial work for typeahead --- package.json | 1 + src/components/comments/AddComment.tsx | 48 +++++++++++++++++++++++----- src/components/common/TaggTypeahead.tsx | 25 +++++++++++++++ src/components/common/index.ts | 1 + src/screens/profile/MomentCommentsScreen.tsx | 34 +------------------- yarn.lock | 9 +++++- 6 files changed, 76 insertions(+), 42 deletions(-) create mode 100644 src/components/common/TaggTypeahead.tsx (limited to 'src/components/common') diff --git a/package.json b/package.json index 2612e67f..b3d69c76 100644 --- a/package.json +++ b/package.json @@ -44,6 +44,7 @@ "react-native-image-resizer": "^1.4.4", "react-native-inappbrowser-reborn": "^3.4.0", "react-native-linear-gradient": "^2.5.6", + "react-native-parsed-text": "^0.0.22", "react-native-picker-select": "^7.0.0", "react-native-push-notifications": "^3.0.10", "react-native-reanimated": "2.0.0-rc.0", diff --git a/src/components/comments/AddComment.tsx b/src/components/comments/AddComment.tsx index 2a8c773e..79d4d970 100644 --- a/src/components/comments/AddComment.tsx +++ b/src/components/comments/AddComment.tsx @@ -1,12 +1,14 @@ -import React, {useEffect, useRef} from 'react'; +import React, {useEffect, useRef, useState} from 'react'; import { Keyboard, KeyboardAvoidingView, Platform, StyleSheet, + TextInput, View, } from 'react-native'; -import {TextInput, TouchableOpacity} from 'react-native-gesture-handler'; +import {TouchableOpacity} from 'react-native-gesture-handler'; +import ParsedText 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'; @@ -14,7 +16,7 @@ import {postComment} from '../../services'; import {updateReplyPosted} from '../../store/actions'; import {RootState} from '../../store/rootreducer'; import {SCREEN_HEIGHT, SCREEN_WIDTH} from '../../utils'; -import {Avatar} from '../common'; +import {Avatar, TaggTypeahead} from '../common'; /** * This file provides the add comment view for a user. @@ -36,7 +38,9 @@ const AddComment: React.FC = ({ isCommentInFocus, }) => { const [comment, setComment] = React.useState(''); - const [keyboardVisible, setKeyboardVisible] = React.useState(false); + const [keyboardVisible, setKeyboardVisible] = useState(false); + const [isMentioning, setIsMentioning] = useState(false); + const [mentionSearch, setMentionSearch] = useState(''); const {avatar} = useSelector((state: RootState) => state.user); const dispatch = useDispatch(); @@ -95,6 +99,7 @@ const AddComment: React.FC = ({ + {isMentioning && } = ({ style={styles.text} placeholder={placeholderText} placeholderTextColor="grey" - onChangeText={setComment} - value={comment} + onChangeText={(newText: string) => { + const newestChar = newText[newText.length - 1]; + if (newestChar === ' ') { + setIsMentioning(false); + setMentionSearch(''); + } + if (newestChar === '@') { + setIsMentioning(true); + } + if (isMentioning) { + const match = newText.match(/@(.*)$/); + if (match) { + setMentionSearch(match[1]); + } + } + setComment(newText); + }} multiline={true} - ref={ref} - /> + ref={ref}> + '@fooo', + }, + ]}> + {comment} + + @@ -141,6 +172,7 @@ const styles = StyleSheet.create({ flex: 1, padding: '1%', marginHorizontal: '1%', + maxHeight: 100, }, avatar: { height: 35, diff --git a/src/components/common/TaggTypeahead.tsx b/src/components/common/TaggTypeahead.tsx new file mode 100644 index 00000000..8a68c9a5 --- /dev/null +++ b/src/components/common/TaggTypeahead.tsx @@ -0,0 +1,25 @@ +import React from 'react'; +import {StyleSheet, Text, View} from 'react-native'; +import {SCREEN_WIDTH} from '../../utils'; + +type TaggTypeaheadProps = { + search: string; +}; + +const TaggTypeahead: React.FC = ({search}) => { + return ( + + searching for {search} + + ); +}; + +const styles = StyleSheet.create({ + container: { + width: SCREEN_WIDTH * 0.9, + height: 100, + borderWidth: 1, + }, +}); + +export default TaggTypeahead; diff --git a/src/components/common/index.ts b/src/components/common/index.ts index 802cf505..4a49339b 100644 --- a/src/components/common/index.ts +++ b/src/components/common/index.ts @@ -24,3 +24,4 @@ export {default as TaggSquareButton} from './TaggSquareButton'; export {default as GradientBorderButton} from './GradientBorderButton'; export {default as BasicButton} from './BasicButton'; export {default as Avatar} from './Avatar'; +export {default as TaggTypeahead} from './TaggTypeahead'; diff --git a/src/screens/profile/MomentCommentsScreen.tsx b/src/screens/profile/MomentCommentsScreen.tsx index b0208f6f..effbbb63 100644 --- a/src/screens/profile/MomentCommentsScreen.tsx +++ b/src/screens/profile/MomentCommentsScreen.tsx @@ -8,12 +8,7 @@ import CommentsContainer from '../../components/comments/CommentsContainer'; import {ADD_COMMENT_TEXT} from '../../constants/strings'; import {headerBarOptions, MainStackParams} from '../../routes/main'; import {CommentType} from '../../types'; -import { - HeaderHeight, - normalize, - SCREEN_HEIGHT, - SCREEN_WIDTH, -} from '../../utils'; +import {HeaderHeight, SCREEN_HEIGHT, SCREEN_WIDTH} from '../../utils'; /** * Comments Screen for an image uploaded @@ -88,39 +83,12 @@ const styles = StyleSheet.create({ backgroundColor: 'white', height: '100%', }, - header: {justifyContent: 'center', padding: '3%'}, - headerText: { - position: 'absolute', - alignSelf: 'center', - fontSize: normalize(18), - fontWeight: '700', - lineHeight: normalize(21.48), - letterSpacing: normalize(1.3), - }, - headerButton: { - width: '5%', - aspectRatio: 1, - padding: 0, - marginLeft: '5%', - alignSelf: 'flex-start', - }, - headerButtonText: { - color: 'black', - fontSize: 18, - fontWeight: '400', - }, body: { marginTop: HeaderHeight, width: SCREEN_WIDTH * 0.9, height: SCREEN_HEIGHT * 0.8, paddingTop: '3%', }, - scrollView: { - paddingHorizontal: 20, - }, - scrollViewContent: { - justifyContent: 'center', - }, }); export default MomentCommentsScreen; diff --git a/yarn.lock b/yarn.lock index d9aab38e..ef159ae5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6148,7 +6148,7 @@ prompts@^2.0.1: kleur "^3.0.3" sisteransi "^1.0.5" -prop-types@^15.5.10, prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2: +prop-types@^15.5.10, prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2, prop-types@^15.7.x: version "15.7.2" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ== @@ -6367,6 +6367,13 @@ react-native-markdown-package@1.8.1: react-native-lightbox "^0.7.0" simple-markdown "^0.7.1" +react-native-parsed-text@^0.0.22: + version "0.0.22" + resolved "https://registry.yarnpkg.com/react-native-parsed-text/-/react-native-parsed-text-0.0.22.tgz#a23c756eaa5d6724296814755085127f9072e5f5" + integrity sha512-hfD83RDXZf9Fvth3DowR7j65fMnlqM9PpxZBGWkzVcUTFtqe6/yPcIoIAgrJbKn6YmtzkivmhWE2MCE4JKBXrQ== + dependencies: + prop-types "^15.7.x" + react-native-picker-select@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/react-native-picker-select/-/react-native-picker-select-7.0.0.tgz#4808a1177f997e234bb8505849dfffe1a01fedac" -- cgit v1.2.3-70-g09d2 From bdc7186d869ff969c3e19cb9a4a8839df51a7f32 Mon Sep 17 00:00:00 2001 From: Ivan Chen Date: Thu, 29 Apr 2021 19:34:10 -0400 Subject: completed typeahead missed import --- src/components/common/TaggTypeahead.tsx | 57 ++++++++++++++++++++++++++----- src/components/common/TaggUserRowCell.tsx | 55 +++++++++++++++++++++++++++++ src/components/common/index.ts | 1 + 3 files changed, 105 insertions(+), 8 deletions(-) create mode 100644 src/components/common/TaggUserRowCell.tsx (limited to 'src/components/common') diff --git a/src/components/common/TaggTypeahead.tsx b/src/components/common/TaggTypeahead.tsx index 8a68c9a5..6239971e 100644 --- a/src/components/common/TaggTypeahead.tsx +++ b/src/components/common/TaggTypeahead.tsx @@ -1,23 +1,64 @@ -import React from 'react'; -import {StyleSheet, Text, View} from 'react-native'; +import React, {Fragment, useEffect, useState} from 'react'; +import {ScrollView, StyleSheet} from 'react-native'; +import {SEARCH_ENDPOINT_MESSAGES} from '../../constants'; +import {loadSearchResults} from '../../services'; +import {ProfilePreviewType} from '../../types'; import {SCREEN_WIDTH} from '../../utils'; +import TaggUserRowCell from './TaggUserRowCell'; type TaggTypeaheadProps = { - search: string; + query: string; + setSelectedMention: (user: ProfilePreviewType) => void; }; -const TaggTypeahead: React.FC = ({search}) => { +const TaggTypeahead: React.FC = ({ + query, + setSelectedMention, +}) => { + const [results, setResults] = useState([]); + + useEffect(() => { + getQuerySuggested(); + }, [query]); + + const getQuerySuggested = async () => { + if (query.length < 3) { + setResults([]); + return; + } + const searchResults = await loadSearchResults( + `${SEARCH_ENDPOINT_MESSAGES}?query=${query}`, + ); + if (searchResults && searchResults.users) { + setResults(searchResults.users); + } + }; + + if (results.length === 0) { + return ; + } + return ( - - searching for {search} - + + {results.map((user) => ( + { + setSelectedMention(user); + setResults([]); + }} + user={user} + /> + ))} + ); }; const styles = StyleSheet.create({ container: { + marginLeft: SCREEN_WIDTH * 0.05, width: SCREEN_WIDTH * 0.9, - height: 100, + maxHeight: 300, + borderRadius: 10, borderWidth: 1, }, }); diff --git a/src/components/common/TaggUserRowCell.tsx b/src/components/common/TaggUserRowCell.tsx new file mode 100644 index 00000000..446f5e87 --- /dev/null +++ b/src/components/common/TaggUserRowCell.tsx @@ -0,0 +1,55 @@ +import React from 'react'; +import {Image, StyleSheet, Text, TouchableOpacity, View} from 'react-native'; +import {ProfilePreviewType} from '../../types'; +import {defaultUserProfile, normalize} from '../../utils'; + +type TaggUserRowCellProps = { + onPress: () => void; + user: ProfilePreviewType; +}; +const TaggUserRowCell: React.FC = ({onPress, user}) => { + return ( + + + + {`@${user.username}`} + + {user.first_name} {user.last_name} + + + + ); +}; + +const styles = StyleSheet.create({ + container: { + flexDirection: 'row', + paddingHorizontal: 25, + paddingVertical: 15, + width: '100%', + }, + image: { + width: normalize(30), + height: normalize(30), + borderRadius: 30, + }, + textContent: { + flexDirection: 'column', + justifyContent: 'space-between', + marginLeft: 20, + }, + username: { + fontWeight: '500', + fontSize: normalize(14), + }, + name: { + fontWeight: '500', + fontSize: normalize(12), + color: '#828282', + }, +}); +export default TaggUserRowCell; diff --git a/src/components/common/index.ts b/src/components/common/index.ts index 4a49339b..b38056c6 100644 --- a/src/components/common/index.ts +++ b/src/components/common/index.ts @@ -25,3 +25,4 @@ export {default as GradientBorderButton} from './GradientBorderButton'; export {default as BasicButton} from './BasicButton'; export {default as Avatar} from './Avatar'; export {default as TaggTypeahead} from './TaggTypeahead'; +export {default as TaggUserRowCell} from './TaggUserRowCell'; -- cgit v1.2.3-70-g09d2 From a665c527cf0ab24b1a19b2ed35f38b9acb79cdeb Mon Sep 17 00:00:00 2001 From: Ivan Chen Date: Fri, 30 Apr 2021 15:16:32 -0400 Subject: removed old code, added controlled-mention --- package.json | 3 +- src/components/comments/AddComment.tsx | 83 +++++++-------------------------- src/components/common/TaggTypeahead.tsx | 37 +++++++++------ 3 files changed, 41 insertions(+), 82 deletions(-) (limited to 'src/components/common') diff --git a/package.json b/package.json index b3d69c76..d3c02059 100644 --- a/package.json +++ b/package.json @@ -32,6 +32,7 @@ "react-native-animatable": "^1.3.3", "react-native-confirmation-code-field": "^6.5.0", "react-native-contacts": "^6.0.4", + "react-native-controlled-mentions": "^2.2.5", "react-native-date-picker": "^3.2.5", "react-native-device-info": "^7.3.1", "react-native-document-picker": "^5.0.3", @@ -102,4 +103,4 @@ "./node_modules/react-native-gesture-handler/jestSetup.js" ] } -} +} \ No newline at end of file diff --git a/src/components/comments/AddComment.tsx b/src/components/comments/AddComment.tsx index 97c87299..7576675e 100644 --- a/src/components/comments/AddComment.tsx +++ b/src/components/comments/AddComment.tsx @@ -7,15 +7,14 @@ import { TextInput, View, } from 'react-native'; +import {MentionInput} from 'react-native-controlled-mentions'; import {TouchableOpacity} from 'react-native-gesture-handler'; -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'; @@ -40,14 +39,9 @@ const AddComment: React.FC = ({ }) => { const [comment, setComment] = useState(''); const [keyboardVisible, setKeyboardVisible] = useState(false); - const [isMentioning, setIsMentioning] = useState(false); - const [mentionQuery, setMentionQuery] = useState(''); - const [selectedMention, setSelectedMention] = useState(); - const [mentions, setMentions] = useState([]); const {avatar} = useSelector((state: RootState) => state.user); const dispatch = useDispatch(); const ref = useRef(null); - const [parsePatterns, setParsePatterns] = useState([]); const addComment = async () => { const trimmed = comment.trim(); @@ -78,30 +72,6 @@ const AddComment: React.FC = ({ } }; - 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); @@ -125,12 +95,6 @@ const AddComment: React.FC = ({ - {isMentioning && ( - - )} = ({ ]}> - { - const newestChar = newText[newText.length - 1]; - const deletedChar = - newText.length === comment.length - 1 - ? comment[comment.length - 1] - : undefined; - if (newestChar === ' ' || deletedChar === '@') { - setIsMentioning(false); - setMentionQuery(''); - } - if (newestChar === '@') { - setIsMentioning(true); - } - if (isMentioning) { - const match = newText.match(/.*@(.*)$/); - if (match) { - setMentionQuery(match[1]); - } - } - setComment(newText); - }} - multiline={true} - ref={ref}> - - {comment} - - + value={comment} + onChange={setComment} + inputRef={ref} + partTypes={[ + { + trigger: '@', + renderSuggestions: (props) => , + allowedSpacesCount: 0, + isInsertSpaceAfterMention: true, + textStyle: {color: TAGG_LIGHT_BLUE}, + }, + ]} + /> diff --git a/src/components/common/TaggTypeahead.tsx b/src/components/common/TaggTypeahead.tsx index 6239971e..7cd99278 100644 --- a/src/components/common/TaggTypeahead.tsx +++ b/src/components/common/TaggTypeahead.tsx @@ -1,33 +1,30 @@ import React, {Fragment, useEffect, useState} from 'react'; import {ScrollView, StyleSheet} from 'react-native'; +import {MentionSuggestionsProps} from 'react-native-controlled-mentions'; import {SEARCH_ENDPOINT_MESSAGES} from '../../constants'; import {loadSearchResults} from '../../services'; import {ProfilePreviewType} from '../../types'; import {SCREEN_WIDTH} from '../../utils'; import TaggUserRowCell from './TaggUserRowCell'; -type TaggTypeaheadProps = { - query: string; - setSelectedMention: (user: ProfilePreviewType) => void; -}; - -const TaggTypeahead: React.FC = ({ - query, - setSelectedMention, +const TaggTypeahead: React.FC = ({ + keyword, + onSuggestionPress, }) => { const [results, setResults] = useState([]); + const [height, setHeight] = useState(0); useEffect(() => { getQuerySuggested(); - }, [query]); + }, [keyword]); const getQuerySuggested = async () => { - if (query.length < 3) { + if (!keyword || keyword.length < 3) { setResults([]); return; } const searchResults = await loadSearchResults( - `${SEARCH_ENDPOINT_MESSAGES}?query=${query}`, + `${SEARCH_ENDPOINT_MESSAGES}?query=${keyword}`, ); if (searchResults && searchResults.users) { setResults(searchResults.users); @@ -39,11 +36,19 @@ const TaggTypeahead: React.FC = ({ } return ( - + { + setHeight(event.nativeEvent.layout.height); + }}> {results.map((user) => ( { - setSelectedMention(user); + onSuggestionPress({ + id: user.id, + name: user.username, + }); setResults([]); }} user={user} @@ -57,8 +62,12 @@ const styles = StyleSheet.create({ container: { marginLeft: SCREEN_WIDTH * 0.05, width: SCREEN_WIDTH * 0.9, - maxHeight: 300, + maxHeight: 264, borderRadius: 10, + backgroundColor: 'white', + position: 'absolute', + alignSelf: 'center', + zIndex: 1, borderWidth: 1, }, }); -- cgit v1.2.3-70-g09d2 From 9795083f41e6417c32d9c070ab0b2bf4aca67012 Mon Sep 17 00:00:00 2001 From: Ivan Chen Date: Tue, 4 May 2021 17:12:22 -0400 Subject: fixed merge issues --- src/components/common/TaggUserRowCell.tsx | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'src/components/common') diff --git a/src/components/common/TaggUserRowCell.tsx b/src/components/common/TaggUserRowCell.tsx index 446f5e87..446dedc9 100644 --- a/src/components/common/TaggUserRowCell.tsx +++ b/src/components/common/TaggUserRowCell.tsx @@ -1,7 +1,8 @@ import React from 'react'; -import {Image, StyleSheet, Text, TouchableOpacity, View} from 'react-native'; +import {StyleSheet, Text, TouchableOpacity, View} from 'react-native'; import {ProfilePreviewType} from '../../types'; -import {defaultUserProfile, normalize} from '../../utils'; +import {normalize} from '../../utils'; +import Avatar from './Avatar'; type TaggUserRowCellProps = { onPress: () => void; @@ -10,11 +11,7 @@ type TaggUserRowCellProps = { const TaggUserRowCell: React.FC = ({onPress, user}) => { return ( - + {`@${user.username}`} -- cgit v1.2.3-70-g09d2