links.jsx 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. import PropTypes from 'prop-types';
  2. import { PureComponent } from 'react';
  3. import { FormattedMessage } from 'react-intl';
  4. import { withRouter } from 'react-router-dom';
  5. import ImmutablePropTypes from 'react-immutable-proptypes';
  6. import { connect } from 'react-redux';
  7. import { fetchTrendingLinks } from 'mastodon/actions/trends';
  8. import { DismissableBanner } from 'mastodon/components/dismissable_banner';
  9. import { LoadingIndicator } from 'mastodon/components/loading_indicator';
  10. import { WithRouterPropTypes } from 'mastodon/utils/react_router';
  11. import Story from './components/story';
  12. const mapStateToProps = state => ({
  13. links: state.getIn(['trends', 'links', 'items']),
  14. isLoading: state.getIn(['trends', 'links', 'isLoading']),
  15. });
  16. class Links extends PureComponent {
  17. static propTypes = {
  18. links: ImmutablePropTypes.list,
  19. isLoading: PropTypes.bool,
  20. dispatch: PropTypes.func.isRequired,
  21. ...WithRouterPropTypes,
  22. };
  23. componentDidMount () {
  24. const { dispatch, links, history } = this.props;
  25. // If we're navigating back to the screen, do not trigger a reload
  26. if (history.action === 'POP' && links.size > 0) {
  27. return;
  28. }
  29. dispatch(fetchTrendingLinks());
  30. }
  31. render () {
  32. const { isLoading, links } = this.props;
  33. const banner = (
  34. <DismissableBanner id='explore/links'>
  35. <FormattedMessage id='dismissable_banner.explore_links' defaultMessage='These are news stories being shared the most on the social web today. Newer news stories posted by more different people are ranked higher.' />
  36. </DismissableBanner>
  37. );
  38. if (!isLoading && links.isEmpty()) {
  39. return (
  40. <div className='explore__links scrollable scrollable--flex'>
  41. {banner}
  42. <div className='empty-column-indicator'>
  43. <FormattedMessage id='empty_column.explore_statuses' defaultMessage='Nothing is trending right now. Check back later!' />
  44. </div>
  45. </div>
  46. );
  47. }
  48. return (
  49. <div className='explore__links scrollable' data-nosnippet>
  50. {banner}
  51. {isLoading ? (<LoadingIndicator />) : links.map((link, i) => (
  52. <Story
  53. key={link.get('id')}
  54. expanded={i === 0}
  55. lang={link.get('language')}
  56. url={link.get('url')}
  57. title={link.get('title')}
  58. publisher={link.get('provider_name')}
  59. publishedAt={link.get('published_at')}
  60. author={link.get('author_name')}
  61. sharedTimes={link.getIn(['history', 0, 'accounts']) * 1 + link.getIn(['history', 1, 'accounts']) * 1}
  62. thumbnail={link.get('image')}
  63. thumbnailDescription={link.get('image_description')}
  64. blurhash={link.get('blurhash')}
  65. />
  66. ))}
  67. </div>
  68. );
  69. }
  70. }
  71. export default connect(mapStateToProps)(withRouter(Links));