about summary refs log tree commit diff
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/javascript/mastodon/components/status.js4
-rw-r--r--app/javascript/mastodon/containers/media_container.js25
-rw-r--r--app/javascript/mastodon/features/status/components/detailed_status.js4
-rw-r--r--app/javascript/mastodon/features/ui/components/media_modal.js17
-rw-r--r--app/javascript/mastodon/features/video/index.js25
-rw-r--r--app/javascript/styles/mastodon/components.scss4
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;