diff options
Diffstat (limited to 'src/components')
| -rw-r--r-- | src/components/common/Avatar.tsx | 1 | ||||
| -rw-r--r-- | src/components/common/TaggRadioButton.tsx | 48 | ||||
| -rw-r--r-- | src/components/common/TaggUserSelectionCell.tsx | 73 | ||||
| -rw-r--r-- | src/components/common/index.ts | 1 | ||||
| -rw-r--r-- | src/components/profile/ProfilePreview.tsx | 44 | ||||
| -rw-r--r-- | src/components/search/SearchBar.tsx | 24 |
6 files changed, 176 insertions, 15 deletions
diff --git a/src/components/common/Avatar.tsx b/src/components/common/Avatar.tsx index fa80f121..29197d6e 100644 --- a/src/components/common/Avatar.tsx +++ b/src/components/common/Avatar.tsx @@ -16,6 +16,7 @@ const Avatar: FC<AvatarProps> = ({ return loading ? ( <ImageBackground style={style} + imageStyle={style} defaultSource={require('../../assets/images/avatar-placeholder.png')} source={{uri, cache: 'reload'}}> {loading && ( diff --git a/src/components/common/TaggRadioButton.tsx b/src/components/common/TaggRadioButton.tsx new file mode 100644 index 00000000..fc4008e5 --- /dev/null +++ b/src/components/common/TaggRadioButton.tsx @@ -0,0 +1,48 @@ +import React from 'react'; +import {StyleSheet, TouchableOpacity, View} from 'react-native'; + +interface TaggRadioButtonProps { + pressed: boolean; + onPress: Function; +} +const TaggRadioButton: React.FC<TaggRadioButtonProps> = ({ + pressed, + onPress, +}) => { + const activeOuterStyle = { + borderColor: pressed ? '#6EE7E7' : '#BEBEBE', + }; + + const activeInnerStyle = { + backgroundColor: pressed ? '#6EE7E7' : 'white', + }; + return ( + <TouchableOpacity + style={[styles.outer, activeOuterStyle]} + onPress={() => { + onPress(); + }}> + {pressed && <View style={[styles.inner, activeInnerStyle]} />} + </TouchableOpacity> + ); +}; + +export default TaggRadioButton; +const styles = StyleSheet.create({ + outer: { + width: 20, + height: 20, + borderWidth: 1.5, + borderRadius: 20, + + backgroundColor: 'white', + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'center', + }, + inner: { + width: 14, + height: 14, + borderRadius: 8, + }, +}); diff --git a/src/components/common/TaggUserSelectionCell.tsx b/src/components/common/TaggUserSelectionCell.tsx new file mode 100644 index 00000000..01d965cf --- /dev/null +++ b/src/components/common/TaggUserSelectionCell.tsx @@ -0,0 +1,73 @@ +import React, {useEffect, useState} from 'react'; +import {StyleSheet, View} from 'react-native'; +import {ProfilePreview} from '..'; +import {ProfilePreviewType, ScreenType} from '../../types'; +import {SCREEN_WIDTH} from '../../utils'; +import TaggRadioButton from './TaggRadioButton'; + +interface TaggUserSelectionCellProps { + item: ProfilePreviewType; + selectedUsers: ProfilePreviewType[]; + setSelectedUsers: Function; +} +const TaggUserSelectionCell: React.FC<TaggUserSelectionCellProps> = ({ + item, + selectedUsers, + setSelectedUsers, +}) => { + const [pressed, setPressed] = useState<boolean>(false); + + /* + * To update state of radio button on initial render and subsequent re-renders + */ + useEffect(() => { + const updatePressed = () => { + const userSelected = selectedUsers.findIndex( + (selectedUser) => item.id === selectedUser.id, + ); + setPressed(userSelected !== -1); + }; + updatePressed(); + }); + + /* + * Handles on press on radio button + * Adds/removes user from selected list of users + */ + const handlePress = () => { + // Add to selected list of users + if (pressed === false) { + setSelectedUsers([...selectedUsers, item]); + } + // Remove item from selected list of users + else { + const filteredSelection = selectedUsers.filter( + (user) => user.id !== item.id, + ); + setSelectedUsers(filteredSelection); + } + }; + return ( + <View style={styles.container}> + <View style={{width: SCREEN_WIDTH * 0.8}}> + <ProfilePreview + profilePreview={item} + previewType={'Search'} + screenType={ScreenType.Profile} + /> + </View> + <TaggRadioButton pressed={pressed} onPress={handlePress} /> + </View> + ); +}; + +export default TaggUserSelectionCell; + +const styles = StyleSheet.create({ + container: { + marginHorizontal: '3%', + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'center', + }, +}); diff --git a/src/components/common/index.ts b/src/components/common/index.ts index 48abb8b8..44edbe5f 100644 --- a/src/components/common/index.ts +++ b/src/components/common/index.ts @@ -27,3 +27,4 @@ export {default as Avatar} from './Avatar'; export {default as TaggTypeahead} from './TaggTypeahead'; export {default as TaggUserRowCell} from './TaggUserRowCell'; export {default as LikeButton} from './LikeButton'; +export {default as TaggUserSelectionCell} from './TaggUserSelectionCell'; diff --git a/src/components/profile/ProfilePreview.tsx b/src/components/profile/ProfilePreview.tsx index 66d68d8f..af49c6a2 100644 --- a/src/components/profile/ProfilePreview.tsx +++ b/src/components/profile/ProfilePreview.tsx @@ -148,6 +148,14 @@ const ProfilePreview: React.FC<ProfilePreviewProps> = ({ usernameStyle = styles.discoverUsersUsername; nameStyle = styles.discoverUsersName; break; + case 'Tag Selection': + containerStyle = styles.tagSelectionContainer; + avatarStyle = styles.tagSelectionAvatar; + nameContainerStyle = styles.tagSelectionNameContainer; + usernameToDisplay = '@' + username; + usernameStyle = styles.tagSelectionUsername; + nameStyle = styles.tagSelectionName; + break; case 'Comment': containerStyle = styles.commentContainer; avatarStyle = styles.commentAvatar; @@ -195,10 +203,9 @@ const ProfilePreview: React.FC<ProfilePreviewProps> = ({ <Text style={nameStyle}>{first_name.concat(' ', last_name)}</Text> </> )} - {previewType === 'Comment' && ( - <Text style={usernameStyle}>{usernameToDisplay}</Text> - )} - {previewType === 'Discover Users' && ( + {(previewType === 'Discover Users' || + previewType === 'Tag Selection' || + previewType === 'Comment') && ( <> <Text style={usernameStyle}>{usernameToDisplay}</Text> </> @@ -368,6 +375,35 @@ const styles = StyleSheet.create({ marginRight: 15, borderRadius: 50, }, + tagSelectionContainer: { + width: 60, + flexDirection: 'column', + alignItems: 'center', + justifyContent: 'flex-start', + margin: '1%', + }, + tagSelectionAvatar: { + width: 34, + height: 34, + borderRadius: 20, + }, + tagSelectionNameContainer: { + width: '100%', + paddingVertical: '5%', + }, + tagSelectionUsername: { + fontWeight: '500', + fontSize: normalize(9), + lineHeight: normalize(10), + letterSpacing: normalize(0.2), + color: 'white', + textAlign: 'center', + }, + tagSelectionName: { + fontWeight: '500', + fontSize: 8, + color: 'white', + }, }); export default ProfilePreview; diff --git a/src/components/search/SearchBar.tsx b/src/components/search/SearchBar.tsx index 25ea3b59..a17d0695 100644 --- a/src/components/search/SearchBar.tsx +++ b/src/components/search/SearchBar.tsx @@ -21,10 +21,10 @@ import {getSearchSuggestions, normalize} from '../../utils'; const AnimatedIcon = Animated.createAnimatedComponent(Icon); interface SearchBarProps extends TextInputProps { - onCancel: () => void; - animationProgress: Animated.SharedValue<number>; - searching: boolean; - onLayout: (e: LayoutChangeEvent) => void; + onCancel?: () => void; + animationProgress?: Animated.SharedValue<number>; + searching?: boolean; + onLayout?: (e: LayoutChangeEvent) => void; } const SearchBar: React.FC<SearchBarProps> = ({ onFocus, @@ -113,8 +113,8 @@ const SearchBar: React.FC<SearchBarProps> = ({ * On-search marginRight style ("cancel" button slides and fades in). */ const animatedStyles = useAnimatedStyle<ViewStyle>(() => ({ - marginRight: animationProgress.value * 58, - opacity: animationProgress.value, + marginRight: (animationProgress ? animationProgress.value : 0) * 58, + opacity: animationProgress ? animationProgress.value : 0, })); return ( @@ -136,11 +136,13 @@ const SearchBar: React.FC<SearchBarProps> = ({ {...{placeholder, value, onChangeText, onFocus, onBlur}} /> </Animated.View> - <Animated.View style={animatedStyles}> - <TouchableOpacity style={styles.cancelButton} onPress={onCancel}> - <Text style={styles.cancelText}>Cancel</Text> - </TouchableOpacity> - </Animated.View> + {onCancel && ( + <Animated.View style={animatedStyles}> + <TouchableOpacity style={styles.cancelButton} onPress={onCancel}> + <Text style={styles.cancelText}>Cancel</Text> + </TouchableOpacity> + </Animated.View> + )} </View> ); }; |
