From 41b01382ac4a3267f2abc037bed4f9104b0e5d17 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Sat, 14 May 2022 12:35:12 -0500 Subject: [PATCH] SearchResults: convert to TSX --- .../compose/components/search_results.js | 174 ---------------- .../compose/components/search_results.tsx | 187 ++++++++++++++++++ 2 files changed, 187 insertions(+), 174 deletions(-) delete mode 100644 app/soapbox/features/compose/components/search_results.js create mode 100644 app/soapbox/features/compose/components/search_results.tsx diff --git a/app/soapbox/features/compose/components/search_results.js b/app/soapbox/features/compose/components/search_results.js deleted file mode 100644 index 05cbe2663..000000000 --- a/app/soapbox/features/compose/components/search_results.js +++ /dev/null @@ -1,174 +0,0 @@ -import classNames from 'classnames'; -import PropTypes from 'prop-types'; -import React from 'react'; -import ImmutablePropTypes from 'react-immutable-proptypes'; -import ImmutablePureComponent from 'react-immutable-pure-component'; -import { FormattedMessage } from 'react-intl'; -import { defineMessages, injectIntl } from 'react-intl'; - -import ScrollableList from 'soapbox/components/scrollable_list'; -import PlaceholderAccount from 'soapbox/features/placeholder/components/placeholder_account'; -import PlaceholderHashtag from 'soapbox/features/placeholder/components/placeholder_hashtag'; -import PlaceholderStatus from 'soapbox/features/placeholder/components/placeholder_status'; - -import Hashtag from '../../../components/hashtag'; -import { Tabs } from '../../../components/ui'; -import AccountContainer from '../../../containers/account_container'; -import StatusContainer from '../../../containers/status_container'; - -const messages = defineMessages({ - accounts: { id: 'search_results.accounts', defaultMessage: 'People' }, - statuses: { id: 'search_results.statuses', defaultMessage: 'Posts' }, - hashtags: { id: 'search_results.hashtags', defaultMessage: 'Hashtags' }, -}); - -export default @injectIntl -class SearchResults extends ImmutablePureComponent { - - static propTypes = { - value: PropTypes.string, - results: ImmutablePropTypes.map.isRequired, - submitted: PropTypes.bool, - expandSearch: PropTypes.func.isRequired, - selectedFilter: PropTypes.string.isRequired, - selectFilter: PropTypes.func.isRequired, - features: PropTypes.object.isRequired, - suggestions: ImmutablePropTypes.list, - trendingStatuses: ImmutablePropTypes.list, - trends: ImmutablePropTypes.list, - intl: PropTypes.object.isRequired, - }; - - handleLoadMore = () => this.props.expandSearch(this.props.selectedFilter); - - handleSelectFilter = newActiveFilter => this.props.selectFilter(newActiveFilter); - - componentDidMount() { - this.props.fetchTrendingStatuses(); - } - - renderFilterBar() { - const { intl, selectedFilter } = this.props; - - const items = [ - { - text: intl.formatMessage(messages.accounts), - action: () => this.handleSelectFilter('accounts'), - name: 'accounts', - }, - { - text: intl.formatMessage(messages.statuses), - action: () => this.handleSelectFilter('statuses'), - name: 'statuses', - }, - { - text: intl.formatMessage(messages.hashtags), - action: () => this.handleSelectFilter('hashtags'), - name: 'hashtags', - }, - ]; - - return ; - } - - render() { - const { value, results, submitted, selectedFilter, suggestions, trendingStatuses, trends } = this.props; - - let searchResults; - let hasMore = false; - let loaded; - let noResultsMessage; - let placeholderComponent = PlaceholderStatus; - - if (selectedFilter === 'accounts') { - hasMore = results.get('accountsHasMore'); - loaded = results.get('accountsLoaded'); - placeholderComponent = PlaceholderAccount; - - if (results.get('accounts') && results.get('accounts').size > 0) { - searchResults = results.get('accounts').map(accountId => ); - } else if (!submitted && suggestions && !suggestions.isEmpty()) { - searchResults = suggestions.map(suggestion => ); - } else if (loaded) { - noResultsMessage = ( -
- -
- ); - } - } - - if (selectedFilter === 'statuses') { - hasMore = results.get('statusesHasMore'); - loaded = results.get('statusesLoaded'); - - if (results.get('statuses') && results.get('statuses').size > 0) { - searchResults = results.get('statuses').map(statusId => ); - } else if (!submitted && trendingStatuses && !trendingStatuses.isEmpty()) { - searchResults = trendingStatuses.map(statusId => ); - } else if (loaded) { - noResultsMessage = ( -
- -
- ); - } - } - - if (selectedFilter === 'hashtags') { - hasMore = results.get('hashtagsHasMore'); - loaded = results.get('hashtagsLoaded'); - placeholderComponent = PlaceholderHashtag; - - if (results.get('hashtags') && results.get('hashtags').size > 0) { - searchResults = results.get('hashtags').map(hashtag => ); - } else if (!submitted && suggestions && !suggestions.isEmpty()) { - searchResults = trends.map(hashtag => ); - } else if (loaded) { - noResultsMessage = ( -
- -
- ); - } - } - - return ( - <> - {this.renderFilterBar()} - - {noResultsMessage || ( - - {searchResults} - - )} - - ); - } - -} diff --git a/app/soapbox/features/compose/components/search_results.tsx b/app/soapbox/features/compose/components/search_results.tsx new file mode 100644 index 000000000..1dc244920 --- /dev/null +++ b/app/soapbox/features/compose/components/search_results.tsx @@ -0,0 +1,187 @@ +import classNames from 'classnames'; +import React, { useEffect } from 'react'; +import { FormattedMessage } from 'react-intl'; +import { defineMessages, useIntl } from 'react-intl'; + +import { fetchTrendingStatuses } from 'soapbox/actions/trending_statuses'; +import ScrollableList from 'soapbox/components/scrollable_list'; +import PlaceholderAccount from 'soapbox/features/placeholder/components/placeholder_account'; +import PlaceholderHashtag from 'soapbox/features/placeholder/components/placeholder_hashtag'; +import PlaceholderStatus from 'soapbox/features/placeholder/components/placeholder_status'; +import { useAppDispatch } from 'soapbox/hooks'; + +import Hashtag from '../../../components/hashtag'; +import { Tabs } from '../../../components/ui'; +import AccountContainer from '../../../containers/account_container'; +import StatusContainer from '../../../containers/status_container'; + +import type { Map as ImmutableMap, List as ImmutableList } from 'immutable'; + +const messages = defineMessages({ + accounts: { id: 'search_results.accounts', defaultMessage: 'People' }, + statuses: { id: 'search_results.statuses', defaultMessage: 'Posts' }, + hashtags: { id: 'search_results.hashtags', defaultMessage: 'Hashtags' }, +}); + +type SearchFilter = 'accounts' | 'statuses' | 'hashtags'; + +interface ISearchResults { + value: string, + results: ImmutableMap, + submitted: boolean, + expandSearch: (filter: SearchFilter) => void, + selectedFilter: SearchFilter, + selectFilter: (filter: SearchFilter) => void, + suggestions: ImmutableList, + trendingStatuses: ImmutableList, + trends: ImmutableList, +} + +/** Displays search results depending on the active tab. */ +const SearchResults: React.FC = ({ + value, + results, + submitted, + expandSearch, + selectedFilter, + selectFilter, + suggestions, + trendingStatuses, + trends, +}) => { + const intl = useIntl(); + const dispatch = useAppDispatch(); + + const handleLoadMore = () => expandSearch(selectedFilter); + const handleSelectFilter = (newActiveFilter: SearchFilter) => selectFilter(newActiveFilter); + + useEffect(() => { + dispatch(fetchTrendingStatuses()); + }, []); + + const renderFilterBar = () => { + const items = [ + { + text: intl.formatMessage(messages.accounts), + action: () => handleSelectFilter('accounts'), + name: 'accounts', + }, + { + text: intl.formatMessage(messages.statuses), + action: () => handleSelectFilter('statuses'), + name: 'statuses', + }, + { + text: intl.formatMessage(messages.hashtags), + action: () => handleSelectFilter('hashtags'), + name: 'hashtags', + }, + ]; + + return ; + }; + + let searchResults; + let hasMore = false; + let loaded; + let noResultsMessage; + let placeholderComponent: React.ComponentType = PlaceholderStatus; + + if (selectedFilter === 'accounts') { + hasMore = results.get('accountsHasMore'); + loaded = results.get('accountsLoaded'); + placeholderComponent = PlaceholderAccount; + + if (results.get('accounts') && results.get('accounts').size > 0) { + searchResults = results.get('accounts').map((accountId: string) => ); + } else if (!submitted && suggestions && !suggestions.isEmpty()) { + searchResults = suggestions.map(suggestion => ); + } else if (loaded) { + noResultsMessage = ( +
+ +
+ ); + } + } + + if (selectedFilter === 'statuses') { + hasMore = results.get('statusesHasMore'); + loaded = results.get('statusesLoaded'); + + if (results.get('statuses') && results.get('statuses').size > 0) { + searchResults = results.get('statuses').map((statusId: string) => ( + // @ts-ignore + + )); + } else if (!submitted && trendingStatuses && !trendingStatuses.isEmpty()) { + searchResults = trendingStatuses.map(statusId => ( + // @ts-ignore + + )); + } else if (loaded) { + noResultsMessage = ( +
+ +
+ ); + } + } + + if (selectedFilter === 'hashtags') { + hasMore = results.get('hashtagsHasMore'); + loaded = results.get('hashtagsLoaded'); + placeholderComponent = PlaceholderHashtag; + + if (results.get('hashtags') && results.get('hashtags').size > 0) { + searchResults = results.get('hashtags').map((hashtag: ImmutableMap) => ); + } else if (!submitted && suggestions && !suggestions.isEmpty()) { + searchResults = trends.map(hashtag => ); + } else if (loaded) { + noResultsMessage = ( +
+ +
+ ); + } + } + + return ( + <> + {renderFilterBar()} + + {noResultsMessage || ( + + {searchResults} + + )} + + ); +}; + +export default SearchResults;