| @@ -2,7 +2,7 @@ import React, { PureComponent, Fragment } from 'react'; | |||
| import ReactDOM from 'react-dom'; | |||
| import PropTypes from 'prop-types'; | |||
| import { IntlProvider, addLocaleData } from 'react-intl'; | |||
| import { List as ImmutableList, fromJS } from 'immutable'; | |||
| import { fromJS } from 'immutable'; | |||
| import { getLocale } from 'mastodon/locales'; | |||
| import { getScrollbarWidth } from 'mastodon/utils/scrollbar'; | |||
| import MediaGallery from 'mastodon/components/media_gallery'; | |||
| @@ -31,6 +31,7 @@ export default class MediaContainer extends PureComponent { | |||
| index: null, | |||
| time: null, | |||
| backgroundColor: null, | |||
| options: null, | |||
| }; | |||
| handleOpenMedia = (media, index) => { | |||
| @@ -40,13 +41,15 @@ export default class MediaContainer extends PureComponent { | |||
| this.setState({ media, index }); | |||
| } | |||
| handleOpenVideo = (video, time) => { | |||
| const media = ImmutableList([video]); | |||
| handleOpenVideo = (options) => { | |||
| const { components } = this.props; | |||
| const { media } = JSON.parse(components[options.componetIndex].getAttribute('data-props')); | |||
| const mediaList = fromJS(media); | |||
| document.body.classList.add('with-modals--active'); | |||
| document.documentElement.style.marginRight = `${getScrollbarWidth()}px`; | |||
| this.setState({ media, time }); | |||
| this.setState({ media: mediaList, options }); | |||
| } | |||
| handleCloseMedia = () => { | |||
| @@ -58,6 +61,7 @@ export default class MediaContainer extends PureComponent { | |||
| index: null, | |||
| time: null, | |||
| backgroundColor: null, | |||
| options: null, | |||
| }); | |||
| } | |||
| @@ -83,6 +87,7 @@ export default class MediaContainer extends PureComponent { | |||
| ...(hashtag ? { hashtag: fromJS(hashtag) } : {}), | |||
| ...(componentName === 'Video' ? { | |||
| componetIndex: i, | |||
| onOpenVideo: this.handleOpenVideo, | |||
| } : { | |||
| onOpenMedia: this.handleOpenMedia, | |||
| @@ -100,7 +105,9 @@ export default class MediaContainer extends PureComponent { | |||
| <MediaModal | |||
| media={this.state.media} | |||
| index={this.state.index || 0} | |||
| time={this.state.time} | |||
| currentTime={this.state.options?.startTime} | |||
| autoPlay={this.state.options?.autoPlay} | |||
| volume={this.state.options?.defaultVolume} | |||
| onClose={this.handleCloseMedia} | |||
| onChangeBackgroundColor={this.setBackgroundColor} | |||
| /> | |||
| @@ -32,6 +32,9 @@ class MediaModal extends ImmutablePureComponent { | |||
| onClose: PropTypes.func.isRequired, | |||
| intl: PropTypes.object.isRequired, | |||
| onChangeBackgroundColor: PropTypes.func.isRequired, | |||
| currentTime: PropTypes.number, | |||
| autoPlay: PropTypes.bool, | |||
| volume: PropTypes.number, | |||
| }; | |||
| static contextTypes = { | |||
| @@ -183,7 +186,7 @@ class MediaModal extends ImmutablePureComponent { | |||
| /> | |||
| ); | |||
| } else if (image.get('type') === 'video') { | |||
| const { time } = this.props; | |||
| const { currentTime, autoPlay, volume } = this.props; | |||
| return ( | |||
| <Video | |||
| @@ -192,7 +195,10 @@ class MediaModal extends ImmutablePureComponent { | |||
| src={image.get('url')} | |||
| width={image.get('width')} | |||
| height={image.get('height')} | |||
| currentTime={time || 0} | |||
| frameRate={image.getIn(['meta', 'original', 'frame_rate'])} | |||
| currentTime={currentTime || 0} | |||
| autoPlay={autoPlay || false} | |||
| volume={volume || 1} | |||
| onCloseVideo={onClose} | |||
| detailed | |||
| alt={image.get('description')} | |||
| @@ -121,6 +121,7 @@ class Video extends React.PureComponent { | |||
| autoPlay: PropTypes.bool, | |||
| volume: PropTypes.number, | |||
| muted: PropTypes.bool, | |||
| componetIndex: PropTypes.number, | |||
| }; | |||
| static defaultProps = { | |||
| @@ -501,6 +502,7 @@ class Video extends React.PureComponent { | |||
| startTime: this.video.currentTime, | |||
| autoPlay: !this.state.paused, | |||
| defaultVolume: this.state.volume, | |||
| componetIndex: this.props.componetIndex, | |||
| }); | |||
| } | |||
| @@ -14,7 +14,7 @@ | |||
| - unless status.proper.media_attachments.empty? | |||
| - if status.proper.media_attachments.first.video? | |||
| - video = status.proper.media_attachments.first | |||
| = react_component :video, src: video.file.url(:original), preview: video.file.url(:small), blurhash: video.blurhash, sensitive: status.proper.sensitive?, visible: false, width: 610, height: 343, inline: true, alt: video.description | |||
| = react_component :video, src: video.file.url(:original), preview: video.file.url(:small), frameRate: video.file.meta.dig('original', 'frame_rate'), blurhash: video.blurhash, sensitive: status.proper.sensitive?, visible: false, width: 610, height: 343, inline: true, alt: video.description, media: [ActiveModelSerializers::SerializableResource.new(video, serializer: REST::MediaAttachmentSerializer)].as_json | |||
| - elsif status.proper.media_attachments.first.audio? | |||
| - audio = status.proper.media_attachments.first | |||
| = react_component :audio, src: audio.file.url(:original), height: 110, alt: audio.description, duration: audio.file.meta.dig(:original, :duration) | |||
| @@ -3,7 +3,7 @@ | |||
| = javascript_pack_tag 'public', crossorigin: 'anonymous' | |||
| - if @media_attachment.video? | |||
| = react_component :video, src: @media_attachment.file.url(:original), preview: @media_attachment.thumbnail.present? ? @media_attachment.thumbnail.url : @media_attachment.file.url(:small), blurhash: @media_attachment.blurhash, width: 670, height: 380, editable: true, detailed: true, inline: true, alt: @media_attachment.description do | |||
| = react_component :video, src: @media_attachment.file.url(:original), preview: @media_attachment.thumbnail.present? ? @media_attachment.thumbnail.url : @media_attachment.file.url(:small), frameRate: @media_attachment.file.meta.dig('original', 'frame_rate'), blurhash: @media_attachment.blurhash, width: 670, height: 380, editable: true, detailed: true, inline: true, alt: @media_attachment.description, media: [ActiveModelSerializers::SerializableResource.new(@media_attachment, serializer: REST::MediaAttachmentSerializer)].as_json do | |||
| %video{ controls: 'controls' } | |||
| %source{ src: @media_attachment.file.url(:original) } | |||
| - elsif @media_attachment.gifv? | |||
| @@ -29,7 +29,7 @@ | |||
| - if !status.media_attachments.empty? | |||
| - if status.media_attachments.first.video? | |||
| - video = status.media_attachments.first | |||
| = react_component :video, src: full_asset_url(video.file.url(:original)), preview: full_asset_url(video.thumbnail.present? ? video.thumbnail.url : video.file.url(:small)), blurhash: video.blurhash, sensitive: sensitized?(status, current_account), width: 670, height: 380, detailed: true, inline: true, alt: video.description do | |||
| = react_component :video, src: full_asset_url(video.file.url(:original)), preview: full_asset_url(video.thumbnail.present? ? video.thumbnail.url : video.file.url(:small)), frameRate: video.file.meta.dig('original', 'frame_rate'), blurhash: video.blurhash, sensitive: sensitized?(status, current_account), width: 670, height: 380, detailed: true, inline: true, alt: video.description, media: [ActiveModelSerializers::SerializableResource.new(video, serializer: REST::MediaAttachmentSerializer)].as_json do | |||
| = render partial: 'statuses/attachment_list', locals: { attachments: status.media_attachments } | |||
| - elsif status.media_attachments.first.audio? | |||
| - audio = status.media_attachments.first | |||
| @@ -38,7 +38,7 @@ | |||
| - if !status.media_attachments.empty? | |||
| - if status.media_attachments.first.video? | |||
| - video = status.media_attachments.first | |||
| = react_component :video, src: full_asset_url(video.file.url(:original)), preview: full_asset_url(video.thumbnail.present? ? video.thumbnail.url : video.file.url(:small)), blurhash: video.blurhash, sensitive: sensitized?(status, current_account), width: 610, height: 343, inline: true, alt: video.description do | |||
| = react_component :video, src: full_asset_url(video.file.url(:original)), preview: full_asset_url(video.thumbnail.present? ? video.thumbnail.url : video.file.url(:small)), frameRate: video.file.meta.dig('original', 'frame_rate'), blurhash: video.blurhash, sensitive: sensitized?(status, current_account), width: 610, height: 343, inline: true, alt: video.description, media: [ActiveModelSerializers::SerializableResource.new(video, serializer: REST::MediaAttachmentSerializer)].as_json do | |||
| = render partial: 'statuses/attachment_list', locals: { attachments: status.media_attachments } | |||
| - elsif status.media_attachments.first.audio? | |||
| - audio = status.media_attachments.first | |||