diff options
Diffstat (limited to 'app')
6 files changed, 68 insertions, 11 deletions
diff --git a/app/javascript/mastodon/components/status.js b/app/javascript/mastodon/components/status.js index 953d98c20..fd08ff3b7 100644 --- a/app/javascript/mastodon/components/status.js +++ b/app/javascript/mastodon/components/status.js @@ -84,8 +84,8 @@ export default class Status extends ImmutablePureComponent { return <div className='media-spoiler-video' style={{ height: '110px' }} />; } - handleOpenVideo = startTime => { - this.props.onOpenVideo(this._properStatus().getIn(['media_attachments', 0]), startTime); + handleOpenVideo = (media, startTime) => { + this.props.onOpenVideo(media, startTime); } handleHotkeyReply = e => { diff --git a/app/javascript/mastodon/containers/media_container.js b/app/javascript/mastodon/containers/media_container.js index eb2d540cb..1700fba05 100644 --- a/app/javascript/mastodon/containers/media_container.js +++ b/app/javascript/mastodon/containers/media_container.js @@ -8,7 +8,7 @@ import Video from '../features/video'; import Card from '../features/status/components/card'; import ModalRoot from '../components/modal_root'; import MediaModal from '../features/ui/components/media_modal'; -import { fromJS } from 'immutable'; +import { List as ImmutableList, fromJS } from 'immutable'; const { localeData, messages } = getLocale(); addLocaleData(localeData); @@ -25,6 +25,7 @@ export default class MediaContainer extends PureComponent { state = { media: null, index: null, + time: null, }; handleOpenMedia = (media, index) => { @@ -32,9 +33,16 @@ export default class MediaContainer extends PureComponent { this.setState({ media, index }); } + handleOpenVideo = (video, time) => { + const media = ImmutableList([video]); + + document.body.classList.add('media-standalone__body'); + this.setState({ media, time }); + } + handleCloseMedia = () => { document.body.classList.remove('media-standalone__body'); - this.setState({ media: null, index: null }); + this.setState({ media: null, index: null, time: null }); } render () { @@ -51,18 +59,25 @@ export default class MediaContainer extends PureComponent { Object.assign(props, { ...(media ? { media: fromJS(media) } : {}), ...(card ? { card: fromJS(card) } : {}), + + ...(componentName === 'Video' ? { + onOpenVideo: this.handleOpenVideo, + } : { + onOpenMedia: this.handleOpenMedia, + }), }); return ReactDOM.createPortal( - <Component onOpenMedia={this.handleOpenMedia} {...props} key={`media-${i}`} />, + <Component {...props} key={`media-${i}`} />, component, ); })} <ModalRoot onClose={this.handleCloseMedia}> - {this.state.media === null || this.state.index === null ? null : ( + {this.state.media && ( <MediaModal media={this.state.media} - index={this.state.index} + index={this.state.index || 0} + time={this.state.time} onClose={this.handleCloseMedia} /> )} diff --git a/app/javascript/mastodon/features/status/components/detailed_status.js b/app/javascript/mastodon/features/status/components/detailed_status.js index b5f516032..417719004 100644 --- a/app/javascript/mastodon/features/status/components/detailed_status.js +++ b/app/javascript/mastodon/features/status/components/detailed_status.js @@ -34,8 +34,8 @@ export default class DetailedStatus extends ImmutablePureComponent { e.stopPropagation(); } - handleOpenVideo = startTime => { - this.props.onOpenVideo(this.props.status.getIn(['media_attachments', 0]), startTime); + handleOpenVideo = (media, startTime) => { + this.props.onOpenVideo(media, startTime); } handleExpandedToggle = () => { diff --git a/app/javascript/mastodon/features/ui/components/media_modal.js b/app/javascript/mastodon/features/ui/components/media_modal.js index fb76270fa..f4d6b5c4e 100644 --- a/app/javascript/mastodon/features/ui/components/media_modal.js +++ b/app/javascript/mastodon/features/ui/components/media_modal.js @@ -2,6 +2,7 @@ import React from 'react'; import ReactSwipeableViews from 'react-swipeable-views'; import ImmutablePropTypes from 'react-immutable-proptypes'; import PropTypes from 'prop-types'; +import Video from '../../video'; import ExtendedVideoPlayer from '../../../components/extended_video_player'; import classNames from 'classnames'; import { defineMessages, injectIntl } from 'react-intl'; @@ -112,6 +113,22 @@ export default class MediaModal extends ImmutablePureComponent { onClick={this.toggleNavigation} /> ); + } else if (image.get('type') === 'video') { + const { time } = this.props; + + return ( + <Video + preview={image.get('preview_url')} + src={image.get('url')} + width={image.get('width')} + height={image.get('height')} + startTime={time || 0} + onCloseVideo={onClose} + detailed + description={image.get('description')} + key={image.get('url')} + /> + ); } else if (image.get('type') === 'gifv') { return ( <ExtendedVideoPlayer diff --git a/app/javascript/mastodon/features/video/index.js b/app/javascript/mastodon/features/video/index.js index 98ebcb6f9..47a165e16 100644 --- a/app/javascript/mastodon/features/video/index.js +++ b/app/javascript/mastodon/features/video/index.js @@ -1,6 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; +import { fromJS } from 'immutable'; import { throttle } from 'lodash'; import classNames from 'classnames'; import { isFullscreen, requestFullscreen, exitFullscreen } from '../ui/util/fullscreen'; @@ -131,6 +132,8 @@ export default class Video extends React.PureComponent { this.seek = c; } + handleClickRoot = e => e.stopPropagation(); + handlePlay = () => { this.setState({ paused: false }); } @@ -244,8 +247,17 @@ export default class Video extends React.PureComponent { } handleOpenVideo = () => { + const { src, preview, width, height } = this.props; + const media = fromJS({ + type: 'video', + url: src, + preview_url: preview, + width, + height, + }); + this.video.pause(); - this.props.onOpenVideo(this.video.currentTime); + this.props.onOpenVideo(media, this.video.currentTime); } handleCloseVideo = () => { @@ -270,7 +282,16 @@ export default class Video extends React.PureComponent { } return ( - <div className={classNames('video-player', { inactive: !revealed, detailed, inline: inline && !fullscreen, fullscreen })} style={playerStyle} ref={this.setPlayerRef} onMouseEnter={this.handleMouseEnter} onMouseLeave={this.handleMouseLeave}> + <div + role='menuitem' + className={classNames('video-player', { inactive: !revealed, detailed, inline: inline && !fullscreen, fullscreen })} + style={playerStyle} + ref={this.setPlayerRef} + onMouseEnter={this.handleMouseEnter} + onMouseLeave={this.handleMouseLeave} + onClick={this.handleClickRoot} + tabIndex={0} + > <video ref={this.setVideoRef} src={src} diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss index 158bf6851..61c38ce80 100644 --- a/app/javascript/styles/mastodon/components.scss +++ b/app/javascript/styles/mastodon/components.scss @@ -4432,6 +4432,10 @@ a.status-card { max-width: 100%; border-radius: 4px; + &:focus { + outline: 0; + } + video { max-width: 100vw; max-height: 80vh; |