Open video modal on public UI (#7469)

main
Yamagishi Kazutoshi 2018-05-13 20:48:14 +09:00 committed by Eugen Rochko
parent f77b11cd10
commit d9b2f84c92
6 changed files with 68 additions and 11 deletions

View File

@ -84,8 +84,8 @@ export default class Status extends ImmutablePureComponent {
return <div className='media-spoiler-video' style={{ height: '110px' }} />; return <div className='media-spoiler-video' style={{ height: '110px' }} />;
} }
handleOpenVideo = startTime => { handleOpenVideo = (media, startTime) => {
this.props.onOpenVideo(this._properStatus().getIn(['media_attachments', 0]), startTime); this.props.onOpenVideo(media, startTime);
} }
handleHotkeyReply = e => { handleHotkeyReply = e => {

View File

@ -8,7 +8,7 @@ import Video from '../features/video';
import Card from '../features/status/components/card'; import Card from '../features/status/components/card';
import ModalRoot from '../components/modal_root'; import ModalRoot from '../components/modal_root';
import MediaModal from '../features/ui/components/media_modal'; import MediaModal from '../features/ui/components/media_modal';
import { fromJS } from 'immutable'; import { List as ImmutableList, fromJS } from 'immutable';
const { localeData, messages } = getLocale(); const { localeData, messages } = getLocale();
addLocaleData(localeData); addLocaleData(localeData);
@ -25,6 +25,7 @@ export default class MediaContainer extends PureComponent {
state = { state = {
media: null, media: null,
index: null, index: null,
time: null,
}; };
handleOpenMedia = (media, index) => { handleOpenMedia = (media, index) => {
@ -32,9 +33,16 @@ export default class MediaContainer extends PureComponent {
this.setState({ media, index }); this.setState({ media, index });
} }
handleOpenVideo = (video, time) => {
const media = ImmutableList([video]);
document.body.classList.add('media-standalone__body');
this.setState({ media, time });
}
handleCloseMedia = () => { handleCloseMedia = () => {
document.body.classList.remove('media-standalone__body'); document.body.classList.remove('media-standalone__body');
this.setState({ media: null, index: null }); this.setState({ media: null, index: null, time: null });
} }
render () { render () {
@ -51,18 +59,25 @@ export default class MediaContainer extends PureComponent {
Object.assign(props, { Object.assign(props, {
...(media ? { media: fromJS(media) } : {}), ...(media ? { media: fromJS(media) } : {}),
...(card ? { card: fromJS(card) } : {}), ...(card ? { card: fromJS(card) } : {}),
...(componentName === 'Video' ? {
onOpenVideo: this.handleOpenVideo,
} : {
onOpenMedia: this.handleOpenMedia,
}),
}); });
return ReactDOM.createPortal( return ReactDOM.createPortal(
<Component onOpenMedia={this.handleOpenMedia} {...props} key={`media-${i}`} />, <Component {...props} key={`media-${i}`} />,
component, component,
); );
})} })}
<ModalRoot onClose={this.handleCloseMedia}> <ModalRoot onClose={this.handleCloseMedia}>
{this.state.media === null || this.state.index === null ? null : ( {this.state.media && (
<MediaModal <MediaModal
media={this.state.media} media={this.state.media}
index={this.state.index} index={this.state.index || 0}
time={this.state.time}
onClose={this.handleCloseMedia} onClose={this.handleCloseMedia}
/> />
)} )}

View File

@ -34,8 +34,8 @@ export default class DetailedStatus extends ImmutablePureComponent {
e.stopPropagation(); e.stopPropagation();
} }
handleOpenVideo = startTime => { handleOpenVideo = (media, startTime) => {
this.props.onOpenVideo(this.props.status.getIn(['media_attachments', 0]), startTime); this.props.onOpenVideo(media, startTime);
} }
handleExpandedToggle = () => { handleExpandedToggle = () => {

View File

@ -2,6 +2,7 @@ import React from 'react';
import ReactSwipeableViews from 'react-swipeable-views'; import ReactSwipeableViews from 'react-swipeable-views';
import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePropTypes from 'react-immutable-proptypes';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import Video from '../../video';
import ExtendedVideoPlayer from '../../../components/extended_video_player'; import ExtendedVideoPlayer from '../../../components/extended_video_player';
import classNames from 'classnames'; import classNames from 'classnames';
import { defineMessages, injectIntl } from 'react-intl'; import { defineMessages, injectIntl } from 'react-intl';
@ -112,6 +113,22 @@ export default class MediaModal extends ImmutablePureComponent {
onClick={this.toggleNavigation} 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') { } else if (image.get('type') === 'gifv') {
return ( return (
<ExtendedVideoPlayer <ExtendedVideoPlayer

View File

@ -1,6 +1,7 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
import { fromJS } from 'immutable';
import { throttle } from 'lodash'; import { throttle } from 'lodash';
import classNames from 'classnames'; import classNames from 'classnames';
import { isFullscreen, requestFullscreen, exitFullscreen } from '../ui/util/fullscreen'; import { isFullscreen, requestFullscreen, exitFullscreen } from '../ui/util/fullscreen';
@ -131,6 +132,8 @@ export default class Video extends React.PureComponent {
this.seek = c; this.seek = c;
} }
handleClickRoot = e => e.stopPropagation();
handlePlay = () => { handlePlay = () => {
this.setState({ paused: false }); this.setState({ paused: false });
} }
@ -244,8 +247,17 @@ export default class Video extends React.PureComponent {
} }
handleOpenVideo = () => { handleOpenVideo = () => {
const { src, preview, width, height } = this.props;
const media = fromJS({
type: 'video',
url: src,
preview_url: preview,
width,
height,
});
this.video.pause(); this.video.pause();
this.props.onOpenVideo(this.video.currentTime); this.props.onOpenVideo(media, this.video.currentTime);
} }
handleCloseVideo = () => { handleCloseVideo = () => {
@ -270,7 +282,16 @@ export default class Video extends React.PureComponent {
} }
return ( 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 <video
ref={this.setVideoRef} ref={this.setVideoRef}
src={src} src={src}

View File

@ -4432,6 +4432,10 @@ a.status-card {
max-width: 100%; max-width: 100%;
border-radius: 4px; border-radius: 4px;
&:focus {
outline: 0;
}
video { video {
max-width: 100vw; max-width: 100vw;
max-height: 80vh; max-height: 80vh;