media_attachments.js 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. import React from 'react';
  2. import PropTypes from 'prop-types';
  3. import ImmutablePropTypes from 'react-immutable-proptypes';
  4. import ImmutablePureComponent from 'react-immutable-pure-component';
  5. import { MediaGallery, Video, Audio } from 'mastodon/features/ui/util/async-components';
  6. import Bundle from 'mastodon/features/ui/components/bundle';
  7. import noop from 'lodash/noop';
  8. export default class MediaAttachments extends ImmutablePureComponent {
  9. static propTypes = {
  10. status: ImmutablePropTypes.map.isRequired,
  11. height: PropTypes.number,
  12. width: PropTypes.number,
  13. };
  14. static defaultProps = {
  15. height: 110,
  16. width: 239,
  17. };
  18. updateOnProps = [
  19. 'status',
  20. ];
  21. renderLoadingMediaGallery = () => {
  22. const { height, width } = this.props;
  23. return (
  24. <div className='media-gallery' style={{ height, width }} />
  25. );
  26. }
  27. renderLoadingVideoPlayer = () => {
  28. const { height, width } = this.props;
  29. return (
  30. <div className='video-player' style={{ height, width }} />
  31. );
  32. }
  33. renderLoadingAudioPlayer = () => {
  34. const { height, width } = this.props;
  35. return (
  36. <div className='audio-player' style={{ height, width }} />
  37. );
  38. }
  39. render () {
  40. const { status, width, height } = this.props;
  41. const mediaAttachments = status.get('media_attachments');
  42. if (mediaAttachments.size === 0) {
  43. return null;
  44. }
  45. if (mediaAttachments.getIn([0, 'type']) === 'audio') {
  46. const audio = mediaAttachments.get(0);
  47. return (
  48. <Bundle fetchComponent={Audio} loading={this.renderLoadingAudioPlayer} >
  49. {Component => (
  50. <Component
  51. src={audio.get('url')}
  52. alt={audio.get('description')}
  53. width={width}
  54. height={height}
  55. poster={audio.get('preview_url') || status.getIn(['account', 'avatar_static'])}
  56. backgroundColor={audio.getIn(['meta', 'colors', 'background'])}
  57. foregroundColor={audio.getIn(['meta', 'colors', 'foreground'])}
  58. accentColor={audio.getIn(['meta', 'colors', 'accent'])}
  59. duration={audio.getIn(['meta', 'original', 'duration'], 0)}
  60. />
  61. )}
  62. </Bundle>
  63. );
  64. } else if (mediaAttachments.getIn([0, 'type']) === 'video') {
  65. const video = mediaAttachments.get(0);
  66. return (
  67. <Bundle fetchComponent={Video} loading={this.renderLoadingVideoPlayer} >
  68. {Component => (
  69. <Component
  70. preview={video.get('preview_url')}
  71. frameRate={video.getIn(['meta', 'original', 'frame_rate'])}
  72. blurhash={video.get('blurhash')}
  73. src={video.get('url')}
  74. alt={video.get('description')}
  75. width={width}
  76. height={height}
  77. inline
  78. sensitive={status.get('sensitive')}
  79. onOpenVideo={noop}
  80. />
  81. )}
  82. </Bundle>
  83. );
  84. } else {
  85. return (
  86. <Bundle fetchComponent={MediaGallery} loading={this.renderLoadingMediaGallery} >
  87. {Component => (
  88. <Component
  89. media={mediaAttachments}
  90. sensitive={status.get('sensitive')}
  91. defaultWidth={width}
  92. height={height}
  93. onOpenMedia={noop}
  94. />
  95. )}
  96. </Bundle>
  97. );
  98. }
  99. }
  100. }