diff --git a/src/screens/searchResult/screen/CommunitiesListItem.js b/src/screens/searchResult/screen/CommunitiesListItem.js new file mode 100644 index 000000000..0a70871c3 --- /dev/null +++ b/src/screens/searchResult/screen/CommunitiesListItem.js @@ -0,0 +1,80 @@ +import React, { useState } from 'react'; +import { View, Text, TouchableOpacity } from 'react-native'; +import { useIntl } from 'react-intl'; + +import styles from './communitiesListItemStyles'; + +import { Tag } from '../../../components/basicUIElements'; + +const UserListItem = ({ + index, + handleOnPress, + handleOnLongPress, + title, + about, + admins, + id, + authors, + posts, + subscribers, + isNsfw, + name, + handleSubscribeButtonPress, + isSubscribed, + isLoggedIn, +}) => { + const [subscribed, setSubscribed] = useState(isSubscribed); + const intl = useIntl(); + + const _handleSubscribeButtonPress = () => { + handleSubscribeButtonPress({ subscribed: !subscribed, communityId: name }).then(() => { + setSubscribed(!subscribed); + }); + }; + + return ( + handleOnLongPress && handleOnLongPress()} + onPress={() => handleOnPress && handleOnPress(name)} + > + + + + {title} + {isLoggedIn && ( + + )} + + {!!about && {about}} + + + {`${subscribers.toString()} ${intl.formatMessage({ + id: 'search_result.communities.subscribers', + })} • ${authors.toString()} ${intl.formatMessage({ + id: 'search_result.communities.posters', + })} • ${posts} ${intl.formatMessage({ + id: 'search_result.communities.posts', + })}`} + + + + + ); +}; + +export default UserListItem; diff --git a/src/screens/searchResult/screen/communities.js b/src/screens/searchResult/screen/communities.js new file mode 100644 index 000000000..b3a615e29 --- /dev/null +++ b/src/screens/searchResult/screen/communities.js @@ -0,0 +1,108 @@ +import React from 'react'; +import { useIntl } from 'react-intl'; +import { FlatList, View, Text, TouchableOpacity } from 'react-native'; +import get from 'lodash/get'; + +// Components +import { FilterBar, UserAvatar } from '../../../components'; +import CommunitiesList from './communitiesList'; +import { CommunitiesPlaceHolder } from '../../../components/basicUIElements'; + +import CommunitiesContainer from '../container/communitiesContainer'; +import styles from './otherResultsStyles'; +import DEFAULT_IMAGE from '../../../assets/no_image.png'; +import Tag from '../../../components/basicUIElements/view/tag/tagView'; + +const filterOptions = ['my', 'rank', 'subs', 'new']; + +const CommunitiesScreen = ({ navigation, searchValue }) => { + const intl = useIntl(); + + const activeVotes = get(navigation, 'state.params.activeVotes'); + + const _renderEmptyContent = () => { + return ( + <> + + + + + ); + }; + + return ( + + {({ + data, + filterIndex, + allSubscriptions, + handleOnVotersDropdownSelect, + handleOnPress, + handleSubscribeButtonPress, + isLoggedIn, + noResult, + }) => ( + <> + + intl.formatMessage({ + id: `search_result.communities_filter.${item}`, + }), + )} + defaultText={intl.formatMessage({ + id: `search_result.communities_filter.${filterOptions[filterIndex]}`, + })} + selectedOptionIndex={filterIndex} + onDropdownSelect={(index) => handleOnVotersDropdownSelect(index, filterOptions[index])} + /> + {filterIndex !== 0 && ( + + )} + {filterIndex === 0 && allSubscriptions && allSubscriptions.length > 0 && ( + `${item}-${ind}`} + renderItem={({ item, index }) => ( + + + handleOnPress(item[0])}> + + + handleOnPress(item[0])}> + {item[1]} + + + + + handleSubscribeButtonPress({ isSubscribed: true, communityId: item[0] }) + } + /> + + + )} + ListEmptyComponent={_renderEmptyContent} + /> + )} + + )} + + ); +}; + +export default CommunitiesScreen; diff --git a/src/screens/searchResult/screen/communitiesList.js b/src/screens/searchResult/screen/communitiesList.js new file mode 100644 index 000000000..a581b768e --- /dev/null +++ b/src/screens/searchResult/screen/communitiesList.js @@ -0,0 +1,70 @@ +import React from 'react'; +import { SafeAreaView, FlatList } from 'react-native'; + +// Components +import CommunitiesListItem from './CommunitiesListItem'; +import { CommunitiesPlaceHolder } from '../../../components/basicUIElements'; + +// Styles +import styles from './communitiesListStyles'; + +const CommunitiesList = ({ + votes, + handleOnPress, + handleSubscribeButtonPress, + allSubscriptions, + isLoggedIn, + noResult, +}) => { + const _renderItem = ({ item, index }) => { + const isSubscribed = allSubscriptions.some((sub) => sub[0] === item.name); + + return ( + + ); + }; + + const _renderEmptyContent = () => { + return ( + <> + + + + + + + + + ); + }; + + return ( + + {!noResult && ( + item.id && item.id.toString()} + renderItem={_renderItem} + ListEmptyComponent={_renderEmptyContent} + /> + )} + + ); +}; + +export default CommunitiesList; diff --git a/src/screens/searchResult/screen/communitiesListItemStyles.js b/src/screens/searchResult/screen/communitiesListItemStyles.js new file mode 100644 index 000000000..19880705c --- /dev/null +++ b/src/screens/searchResult/screen/communitiesListItemStyles.js @@ -0,0 +1,62 @@ +import EStyleSheet from 'react-native-extended-stylesheet'; + +export default EStyleSheet.create({ + container: { + padding: 8, + flexDirection: 'row', + }, + content: { + flexDirection: 'column', + marginLeft: 8, + width: '100%', + }, + itemWrapper: { + alignItems: 'center', + padding: 16, + borderRadius: 8, + flexDirection: 'row', + backgroundColor: '$primaryBackgroundColor', + }, + itemWrapperGray: { + backgroundColor: '$primaryLightBackground', + }, + title: { + color: '$primaryBlue', + fontSize: 17, + fontWeight: 'bold', + fontFamily: '$primaryFont', + }, + about: { + fontSize: 14, + fontFamily: '$primaryFont', + marginTop: 5, + paddingTop: 10, + color: '$primaryBlack', + }, + separator: { + width: 100, + alignSelf: 'center', + backgroundColor: '$primaryDarkGray', + height: 1, + marginVertical: 10, + }, + stats: { + fontSize: 14, + fontFamily: '$primaryFont', + color: '$primaryDarkGray', + paddingBottom: 10, + }, + subscribeButton: { + borderWidth: 1, + maxWidth: 75, + borderColor: '$primaryBlue', + }, + subscribeButtonText: { + textAlign: 'center', + color: '$primaryBlue', + }, + header: { + flexDirection: 'row', + justifyContent: 'space-between', + }, +}); diff --git a/src/screens/searchResult/screen/communitiesListStyles.js b/src/screens/searchResult/screen/communitiesListStyles.js new file mode 100644 index 000000000..8423a2e5e --- /dev/null +++ b/src/screens/searchResult/screen/communitiesListStyles.js @@ -0,0 +1,16 @@ +import EStyleSheet from 'react-native-extended-stylesheet'; + +export default EStyleSheet.create({ + container: { + flex: 1, + padding: 8, + marginBottom: 40, + flexDirection: 'row', + backgroundColor: '$primaryBackgroundColor', + }, + text: { + color: '$iconColor', + fontSize: 12, + fontFamily: '$primaryFont', + }, +}); diff --git a/src/screens/searchResult/screen/otherResults.js b/src/screens/searchResult/screen/otherResults.js new file mode 100644 index 000000000..213b0410a --- /dev/null +++ b/src/screens/searchResult/screen/otherResults.js @@ -0,0 +1,107 @@ +import React from 'react'; +import { SafeAreaView, FlatList, View, Text, TouchableOpacity } from 'react-native'; +import { useIntl } from 'react-intl'; + +// Components +import { FilterBar, UserAvatar } from '../../../components'; +import { CommunitiesPlaceHolder } from '../../../components/basicUIElements'; +import OtherResultContainer from '../container/otherResultContainer'; + +import styles from './otherResultsStyles'; + +import DEFAULT_IMAGE from '../../../assets/no_image.png'; + +const filterOptions = ['user', 'tag']; + +const OtherResult = ({ navigation, searchValue }) => { + const intl = useIntl(); + + const _renderUserItem = (item, index) => ( + + + {item} + + ); + + const _renderTagItem = (item, index) => ( + + {`#${item.name}`} + + ); + + const _renderEmptyContent = () => { + return ( + <> + + + + + + + + + ); + }; + + const _renderList = (users, tags, filterIndex, handleOnPress) => { + switch (filterIndex) { + case 0: + if (users && users.length > 0) { + return ( + `${item}-${ind}`} + renderItem={({ item, index }) => ( + handleOnPress(item)}> + {_renderUserItem(item, index)} + + )} + ListEmptyComponent={_renderEmptyContent} + /> + ); + } + case 1: + if (tags && tags.length > 0) { + return ( + `${item.name}+${item.id}+${item.comments}`} + renderItem={({ item, index }) => ( + handleOnPress(item)}> + {_renderTagItem(item, index)} + + )} + ListEmptyComponent={_renderEmptyContent} + /> + ); + } + default: + break; + } + }; + + return ( + + {({ users, tags, filterIndex, handleFilterChanged, handleOnPress, loadMore }) => ( + + + intl.formatMessage({ + id: `search_result.other_result_filter.${item}`, + }), + )} + defaultText={intl.formatMessage({ + id: `search_result.other_result_filter.${filterOptions[filterIndex]}`, + })} + selectedOptionIndex={filterIndex} + onDropdownSelect={(index) => handleFilterChanged(index, filterOptions[index])} + /> + {_renderList(users, tags, filterIndex, handleOnPress)} + + )} + + ); +}; + +export default OtherResult; diff --git a/src/screens/searchResult/screen/otherResultsStyles.js b/src/screens/searchResult/screen/otherResultsStyles.js new file mode 100644 index 000000000..6fe3db675 --- /dev/null +++ b/src/screens/searchResult/screen/otherResultsStyles.js @@ -0,0 +1,48 @@ +import EStyleSheet from 'react-native-extended-stylesheet'; + +export default EStyleSheet.create({ + container: { + flex: 1, + backgroundColor: '$primaryBackgroundColor', + }, + itemWrapper: { + paddingHorizontal: 16, + paddingTop: 16, + paddingBottom: 8, + borderRadius: 8, + backgroundColor: '$primaryBackgroundColor', + flexDirection: 'row', + alignItems: 'center', + }, + itemWrapperGray: { + backgroundColor: '$primaryLightBackground', + }, + username: { + marginLeft: 10, + color: '$primaryBlack', + }, + communityWrapper: { + paddingHorizontal: 16, + paddingTop: 10, + paddingBottom: 10, + borderRadius: 8, + backgroundColor: '$primaryBackgroundColor', + flexDirection: 'row', + alignItems: 'center', + flex: 1, + }, + subscribeButton: { + maxWidth: 75, + borderWidth: 1, + borderColor: '$primaryBlue', + }, + subscribeButtonText: { + textAlign: 'center', + color: '$primaryBlue', + }, + community: { + justifyContent: 'center', + marginLeft: 15, + color: '$primaryBlack', + }, +}); diff --git a/src/screens/searchResult/screen/postResult.js b/src/screens/searchResult/screen/postResult.js new file mode 100644 index 000000000..83c5f67cd --- /dev/null +++ b/src/screens/searchResult/screen/postResult.js @@ -0,0 +1,115 @@ +import React from 'react'; +import { SafeAreaView, FlatList, View, Text, TouchableOpacity } from 'react-native'; +import get from 'lodash/get'; +import isUndefined from 'lodash/isUndefined'; +import FastImage from 'react-native-fast-image'; +import { useIntl } from 'react-intl'; + +// Components +import { PostHeaderDescription, FilterBar } from '../../../components'; +import { TextWithIcon, CommunitiesPlaceHolder } from '../../../components/basicUIElements'; +import PostResultContainer from '../container/postResultContainer'; + +import { getTimeFromNow } from '../../../utils/time'; + +import styles from './postResultStyles'; + +import DEFAULT_IMAGE from '../../../assets/no_image.png'; + +const filterOptions = ['relevance', 'popularity', 'newest']; + +const PostResult = ({ navigation, searchValue }) => { + const intl = useIntl(); + + const _renderItem = (item, index) => { + return ( + + + + + {item.title} + {!!item.body && ( + + {item.body} + + )} + + + {!isUndefined(item.payout) && ( + {`$ ${item.payout}`} + )} + + + + + ); + }; + + const _renderEmptyContent = () => { + return ( + <> + + + + + + + + + ); + }; + + return ( + + {({ data, filterIndex, handleFilterChanged, handleOnPress, loadMore }) => ( + + + intl.formatMessage({ + id: `search_result.post_result_filter.${item}`, + }), + )} + defaultText={intl.formatMessage({ + id: `search_result.post_result_filter.${filterOptions[filterIndex]}`, + })} + selectedOptionIndex={filterIndex} + onDropdownSelect={(index) => handleFilterChanged(index, filterOptions[index])} + /> + item.id && item.id.toString()} + renderItem={({ item, index }) => ( + handleOnPress(item)}> + {_renderItem(item, index)} + + )} + onEndReached={loadMore} + ListEmptyComponent={_renderEmptyContent} + ListFooterComponent={} + /> + + )} + + ); +}; + +export default PostResult; diff --git a/src/screens/searchResult/screen/postResultStyles.js b/src/screens/searchResult/screen/postResultStyles.js new file mode 100644 index 000000000..db40ab8fe --- /dev/null +++ b/src/screens/searchResult/screen/postResultStyles.js @@ -0,0 +1,44 @@ +import EStyleSheet from 'react-native-extended-stylesheet'; + +export default EStyleSheet.create({ + container: { + flex: 1, + backgroundColor: '$primaryBackgroundColor', + }, + title: { + fontSize: 16, + fontWeight: 'bold', + marginVertical: 5, + color: '$primaryBlack', + }, + summary: { + fontSize: 13, + color: '$primaryDarkGray', + }, + itemWrapper: { + paddingHorizontal: 16, + paddingTop: 16, + paddingBottom: 8, + borderRadius: 8, + backgroundColor: '$primaryBackgroundColor', + }, + itemWrapperGray: { + backgroundColor: '$primaryLightBackground', + }, + stats: { + flexDirection: 'row', + }, + postIcon: { + alignSelf: 'flex-start', + fontSize: 20, + color: '$iconColor', + margin: 0, + width: 20, + marginLeft: 25, + }, + postIconText: { + color: '$primaryDarkGray', + fontSize: 13, + alignSelf: 'center', + }, +});