about summary refs log tree commit diff
path: root/app/javascript/mastodon/components/gifv.jsx
diff options
context:
space:
mode:
Diffstat (limited to 'app/javascript/mastodon/components/gifv.jsx')
-rw-r--r--app/javascript/mastodon/components/gifv.jsx76
1 files changed, 76 insertions, 0 deletions
diff --git a/app/javascript/mastodon/components/gifv.jsx b/app/javascript/mastodon/components/gifv.jsx
new file mode 100644
index 000000000..1ce7e7c29
--- /dev/null
+++ b/app/javascript/mastodon/components/gifv.jsx
@@ -0,0 +1,76 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+
+export default class GIFV extends React.PureComponent {
+
+  static propTypes = {
+    src: PropTypes.string.isRequired,
+    alt: PropTypes.string,
+    lang: PropTypes.string,
+    width: PropTypes.number,
+    height: PropTypes.number,
+    onClick: PropTypes.func,
+  };
+
+  state = {
+    loading: true,
+  };
+
+  handleLoadedData = () => {
+    this.setState({ loading: false });
+  };
+
+  componentWillReceiveProps (nextProps) {
+    if (nextProps.src !== this.props.src) {
+      this.setState({ loading: true });
+    }
+  }
+
+  handleClick = e => {
+    const { onClick } = this.props;
+
+    if (onClick) {
+      e.stopPropagation();
+      onClick();
+    }
+  };
+
+  render () {
+    const { src, width, height, alt, lang } = this.props;
+    const { loading } = this.state;
+
+    return (
+      <div className='gifv' style={{ position: 'relative' }}>
+        {loading && (
+          <canvas
+            width={width}
+            height={height}
+            role='button'
+            tabIndex={0}
+            aria-label={alt}
+            title={alt}
+            lang={lang}
+            onClick={this.handleClick}
+          />
+        )}
+
+        <video
+          src={src}
+          role='button'
+          tabIndex={0}
+          aria-label={alt}
+          title={alt}
+          lang={lang}
+          muted
+          loop
+          autoPlay
+          playsInline
+          onClick={this.handleClick}
+          onLoadedData={this.handleLoadedData}
+          style={{ position: loading ? 'absolute' : 'static', top: 0, left: 0 }}
+        />
+      </div>
+    );
+  }
+
+}