Merge branch 'fix-trends' into 'develop'

Trends: fix Hashtag component and TrendsPanel, display trends in Search

See merge request soapbox-pub/soapbox-fe!839
This commit is contained in:
Alex Gleason 2021-11-02 01:44:15 +00:00
commit 1fe077ea19
7 changed files with 48 additions and 29 deletions

View file

@ -1,30 +1,44 @@
import React from 'react'; import React from 'react';
// import { Sparklines, SparklinesCurve } from 'react-sparklines'; import { Sparklines, SparklinesCurve } from 'react-sparklines';
import { FormattedMessage } from 'react-intl'; import { FormattedMessage } from 'react-intl';
import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePropTypes from 'react-immutable-proptypes';
import Permalink from './permalink'; import Permalink from './permalink';
import { shortNumberFormat } from '../utils/numbers'; import { shortNumberFormat } from '../utils/numbers';
const Hashtag = ({ hashtag }) => ( const Hashtag = ({ hashtag }) => {
<div className='trends__item'> const count = Number(hashtag.getIn(['history', 0, 'accounts']));
<div className='trends__item__name'>
<Permalink href={hashtag.get('url')} to={`/tags/${hashtag.get('name')}`}>
#<span>{hashtag.get('name')}</span>
</Permalink>
{hashtag.get('history') && <div className='trends__item__count'> return (
<FormattedMessage id='trends.count_by_accounts' defaultMessage='{count} {rawCount, plural, one {person} other {people}} talking' values={{ rawCount: hashtag.getIn(['history', 0, 'accounts']), count: <strong>{shortNumberFormat(hashtag.getIn(['history', 0, 'accounts']))}</strong> }} /> <div className='trends__item'>
</div>} <div className='trends__item__name'>
<Permalink href={hashtag.get('url')} to={`/tags/${hashtag.get('name')}`}>
#<span>{hashtag.get('name')}</span>
</Permalink>
{hashtag.get('history') && (
<div className='trends__item__count'>
<FormattedMessage
id='trends.count_by_accounts'
defaultMessage='{count} {rawCount, plural, one {person} other {people}} talking'
values={{
rawCount: count,
count: <strong>{shortNumberFormat(count)}</strong>,
}}
/>
</div>
)}
</div>
{hashtag.get('history') && (
<div className='trends__item__sparkline'>
<Sparklines width={50} height={28} data={hashtag.get('history').reverse().map(day => day.get('uses')).toArray()}>
<SparklinesCurve style={{ fill: 'none' }} />
</Sparklines>
</div>
)}
</div> </div>
);
{/* Pleroma doesn't support tag history yet */} };
{/* hashtag.get('history') && <div className='trends__item__sparkline'>
<Sparklines width={50} height={28} data={hashtag.get('history').reverse().map(day => day.get('uses')).toArray()}>
<SparklinesCurve style={{ fill: 'none' }} />
</Sparklines>
</div> */}
</div>
);
Hashtag.propTypes = { Hashtag.propTypes = {
hashtag: ImmutablePropTypes.map.isRequired, hashtag: ImmutablePropTypes.map.isRequired,

View file

@ -23,6 +23,7 @@ export default class SearchResults extends ImmutablePureComponent {
selectFilter: PropTypes.func.isRequired, selectFilter: PropTypes.func.isRequired,
features: PropTypes.object.isRequired, features: PropTypes.object.isRequired,
suggestions: ImmutablePropTypes.list, suggestions: ImmutablePropTypes.list,
trends: ImmutablePropTypes.list,
}; };
handleLoadMore = () => this.props.expandSearch(this.props.selectedFilter); handleLoadMore = () => this.props.expandSearch(this.props.selectedFilter);
@ -30,7 +31,7 @@ export default class SearchResults extends ImmutablePureComponent {
handleSelectFilter = newActiveFilter => this.props.selectFilter(newActiveFilter); handleSelectFilter = newActiveFilter => this.props.selectFilter(newActiveFilter);
render() { render() {
const { value, results, submitted, selectedFilter, suggestions } = this.props; const { value, results, submitted, selectedFilter, suggestions, trends } = this.props;
let searchResults; let searchResults;
let hasMore = false; let hasMore = false;
@ -79,14 +80,16 @@ export default class SearchResults extends ImmutablePureComponent {
} }
} }
if (selectedFilter === 'hashtags' && results.get('hashtags')) { if (selectedFilter === 'hashtags') {
hasMore = results.get('hashtagsHasMore'); hasMore = results.get('hashtagsHasMore');
loaded = results.get('hashtagsLoaded'); loaded = results.get('hashtagsLoaded');
placeholderComponent = PlaceholderHashtag; placeholderComponent = PlaceholderHashtag;
if (results.get('hashtags').size > 0) { if (results.get('hashtags') && results.get('hashtags').size > 0) {
searchResults = results.get('hashtags').map(hashtag => <Hashtag key={hashtag.get('name')} hashtag={hashtag} />); searchResults = results.get('hashtags').map(hashtag => <Hashtag key={hashtag.get('name')} hashtag={hashtag} />);
} else { } else if (!submitted && suggestions && !suggestions.isEmpty()) {
searchResults = trends.map(hashtag => <Hashtag key={hashtag.get('name')} hashtag={hashtag} />);
} else if (loaded) {
noResultsMessage = ( noResultsMessage = (
<div className='empty-column-indicator'> <div className='empty-column-indicator'>
<FormattedMessage <FormattedMessage

View file

@ -11,6 +11,7 @@ const mapStateToProps = state => {
value: state.getIn(['search', 'submittedValue']), value: state.getIn(['search', 'submittedValue']),
results: state.getIn(['search', 'results']), results: state.getIn(['search', 'results']),
suggestions: state.getIn(['suggestions', 'items']), suggestions: state.getIn(['suggestions', 'items']),
trends: state.getIn(['trends', 'items']),
submitted: state.getIn(['search', 'submitted']), submitted: state.getIn(['search', 'submitted']),
selectedFilter: state.getIn(['search', 'filter']), selectedFilter: state.getIn(['search', 'filter']),
features: getFeatures(instance), features: getFeatures(instance),

View file

@ -11,9 +11,10 @@ import Hashtag from '../../../components/hashtag';
class TrendsPanel extends ImmutablePureComponent { class TrendsPanel extends ImmutablePureComponent {
static propTypes = { static propTypes = {
intl: PropTypes.object.isRequired,
trends: ImmutablePropTypes.list.isRequired, trends: ImmutablePropTypes.list.isRequired,
fetchTrends: PropTypes.func.isRequired, fetchTrends: PropTypes.func.isRequired,
intl: PropTypes.object.isRequired, limit: PropTypes.number,
}; };
componentDidMount() { componentDidMount() {
@ -22,8 +23,8 @@ class TrendsPanel extends ImmutablePureComponent {
render() { render() {
const trends = this.props.trends.sort((a, b) => { const trends = this.props.trends.sort((a, b) => {
const num_a = parseInt(a.getIn(['history', 0, 'accounts'])); const num_a = Number(a.getIn(['history', 0, 'accounts']));
const num_b = parseInt(b.getIn(['history', 0, 'accounts'])); const num_b = Number(b.getIn(['history', 0, 'accounts']));
return num_b - num_a; return num_b - num_a;
}).slice(0, this.props.limit); }).slice(0, this.props.limit);

View file

@ -64,7 +64,7 @@ class DefaultPage extends ImmutablePureComponent {
)} )}
{showTrendsPanel && ( {showTrendsPanel && (
<BundleContainer fetchComponent={TrendsPanel}> <BundleContainer fetchComponent={TrendsPanel}>
{Component => <Component key='trends-panel' />} {Component => <Component limit={3} key='trends-panel' />}
</BundleContainer> </BundleContainer>
)} )}
{showWhoToFollowPanel && ( {showWhoToFollowPanel && (

View file

@ -98,7 +98,7 @@ class HomePage extends ImmutablePureComponent {
)} )}
{showTrendsPanel && ( {showTrendsPanel && (
<BundleContainer fetchComponent={TrendsPanel}> <BundleContainer fetchComponent={TrendsPanel}>
{Component => <Component key='trends-panel' />} {Component => <Component limit={3} key='trends-panel' />}
</BundleContainer> </BundleContainer>
)} )}
{showWhoToFollowPanel && ( {showWhoToFollowPanel && (

View file

@ -65,7 +65,7 @@ class StatusPage extends ImmutablePureComponent {
)} )}
{showTrendsPanel && ( {showTrendsPanel && (
<BundleContainer fetchComponent={TrendsPanel}> <BundleContainer fetchComponent={TrendsPanel}>
{Component => <Component key='trends-panel' />} {Component => <Component limit={3} key='trends-panel' />}
</BundleContainer> </BundleContainer>
)} )}
{showWhoToFollowPanel && ( {showWhoToFollowPanel && (