story.js 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. import React from 'react';
  2. import PropTypes from 'prop-types';
  3. import Blurhash from 'mastodon/components/blurhash';
  4. import { accountsCountRenderer } from 'mastodon/components/hashtag';
  5. import ShortNumber from 'mastodon/components/short_number';
  6. import Skeleton from 'mastodon/components/skeleton';
  7. import classNames from 'classnames';
  8. export default class Story extends React.PureComponent {
  9. static propTypes = {
  10. url: PropTypes.string,
  11. title: PropTypes.string,
  12. publisher: PropTypes.string,
  13. sharedTimes: PropTypes.number,
  14. thumbnail: PropTypes.string,
  15. blurhash: PropTypes.string,
  16. };
  17. state = {
  18. thumbnailLoaded: false,
  19. };
  20. handleImageLoad = () => this.setState({ thumbnailLoaded: true });
  21. render () {
  22. const { url, title, publisher, sharedTimes, thumbnail, blurhash } = this.props;
  23. const { thumbnailLoaded } = this.state;
  24. return (
  25. <a className='story' href={url} target='blank' rel='noopener'>
  26. <div className='story__details'>
  27. <div className='story__details__publisher'>{publisher ? publisher : <Skeleton width={50} />}</div>
  28. <div className='story__details__title'>{title ? title : <Skeleton />}</div>
  29. <div className='story__details__shared'>{typeof sharedTimes === 'number' ? <ShortNumber value={sharedTimes} renderer={accountsCountRenderer} /> : <Skeleton width={100} />}</div>
  30. </div>
  31. <div className='story__thumbnail'>
  32. {thumbnail ? (
  33. <React.Fragment>
  34. <div className={classNames('story__thumbnail__preview', { 'story__thumbnail__preview--hidden': thumbnailLoaded })}><Blurhash hash={blurhash} /></div>
  35. <img src={thumbnail} onLoad={this.handleImageLoad} alt='' role='presentation' />
  36. </React.Fragment>
  37. ) : <Skeleton />}
  38. </div>
  39. </a>
  40. );
  41. }
  42. }