You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

122 lines
4.2 KiB

7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
  1. import React from 'react';
  2. import PropTypes from 'prop-types';
  3. import ImmutablePropTypes from 'react-immutable-proptypes';
  4. import { FormattedMessage, FormattedNumber } from 'react-intl';
  5. import AccountContainer from '../../../containers/account_container';
  6. import StatusContainer from '../../../containers/status_container';
  7. import { Link } from 'react-router-dom';
  8. import ImmutablePureComponent from 'react-immutable-pure-component';
  9. import { Sparklines, SparklinesCurve } from 'react-sparklines';
  10. const shortNumberFormat = number => {
  11. if (number < 1000) {
  12. return <FormattedNumber value={number} />;
  13. } else {
  14. return <React.Fragment><FormattedNumber value={number / 1000} maximumFractionDigits={1} />K</React.Fragment>;
  15. }
  16. };
  17. const renderHashtag = hashtag => (
  18. <div className='trends__item' key={hashtag.get('name')}>
  19. <div className='trends__item__name'>
  20. <Link to={`/timelines/tag/${hashtag.get('name')}`}>
  21. #<span>{hashtag.get('name')}</span>
  22. </Link>
  23. <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> }} />
  24. </div>
  25. <div className='trends__item__current'>
  26. {shortNumberFormat(hashtag.getIn(['history', 0, 'uses']))}
  27. </div>
  28. <div className='trends__item__sparkline'>
  29. <Sparklines width={50} height={28} data={hashtag.get('history').reverse().map(day => day.get('uses')).toArray()}>
  30. <SparklinesCurve style={{ fill: 'none' }} />
  31. </Sparklines>
  32. </div>
  33. </div>
  34. );
  35. export default class SearchResults extends ImmutablePureComponent {
  36. static propTypes = {
  37. results: ImmutablePropTypes.map.isRequired,
  38. trends: ImmutablePropTypes.list,
  39. fetchTrends: PropTypes.func.isRequired,
  40. };
  41. componentDidMount () {
  42. const { fetchTrends } = this.props;
  43. fetchTrends();
  44. }
  45. render () {
  46. const { results, trends } = this.props;
  47. let accounts, statuses, hashtags;
  48. let count = 0;
  49. if (results.isEmpty()) {
  50. return (
  51. <div className='search-results'>
  52. <div className='trends'>
  53. <div className='trends__header'>
  54. <i className='fa fa-fire fa-fw' />
  55. <FormattedMessage id='trends.header' defaultMessage='Trending now' />
  56. </div>
  57. {trends && trends.map(hashtag => renderHashtag(hashtag))}
  58. </div>
  59. </div>
  60. );
  61. }
  62. if (results.get('accounts') && results.get('accounts').size > 0) {
  63. count += results.get('accounts').size;
  64. accounts = (
  65. <div className='search-results__section'>
  66. <h5><i className='fa fa-fw fa-users' /><FormattedMessage id='search_results.accounts' defaultMessage='People' /></h5>
  67. {results.get('accounts').map(accountId => <AccountContainer key={accountId} id={accountId} />)}
  68. </div>
  69. );
  70. }
  71. if (results.get('statuses') && results.get('statuses').size > 0) {
  72. count += results.get('statuses').size;
  73. statuses = (
  74. <div className='search-results__section'>
  75. <h5><i className='fa fa-fw fa-quote-right' /><FormattedMessage id='search_results.statuses' defaultMessage='Toots' /></h5>
  76. {results.get('statuses').map(statusId => <StatusContainer key={statusId} id={statusId} />)}
  77. </div>
  78. );
  79. }
  80. if (results.get('hashtags') && results.get('hashtags').size > 0) {
  81. count += results.get('hashtags').size;
  82. hashtags = (
  83. <div className='search-results__section'>
  84. <h5><i className='fa fa-fw fa-hashtag' /><FormattedMessage id='search_results.hashtags' defaultMessage='Hashtags' /></h5>
  85. {results.get('hashtags').map(hashtag => renderHashtag(hashtag))}
  86. </div>
  87. );
  88. }
  89. return (
  90. <div className='search-results'>
  91. <div className='search-results__header'>
  92. <i className='fa fa-search fa-fw' />
  93. <FormattedMessage id='search_results.total' defaultMessage='{count, number} {count, plural, one {result} other {results}}' values={{ count }} />
  94. </div>
  95. {accounts}
  96. {statuses}
  97. {hashtags}
  98. </div>
  99. );
  100. }
  101. }