about summary refs log tree commit diff
path: root/app/javascript
diff options
context:
space:
mode:
Diffstat (limited to 'app/javascript')
-rw-r--r--app/javascript/flavours/glitch/actions/notifications.js2
-rw-r--r--app/javascript/flavours/glitch/components/modal_root.js18
-rw-r--r--app/javascript/flavours/glitch/components/status.js1
-rw-r--r--app/javascript/flavours/glitch/features/status/components/detailed_status.js1
-rw-r--r--app/javascript/flavours/glitch/features/ui/components/focal_point_modal.js3
-rw-r--r--app/javascript/flavours/glitch/features/ui/components/video_modal.js1
-rw-r--r--app/javascript/flavours/glitch/features/video/index.js18
-rw-r--r--app/javascript/flavours/glitch/styles/components/modal.scss2
-rw-r--r--app/javascript/flavours/glitch/util/notifications.js3
-rw-r--r--app/javascript/flavours/glitch/util/stream.js2
-rw-r--r--app/javascript/mastodon/actions/notifications.js2
-rw-r--r--app/javascript/mastodon/components/modal_root.js16
-rw-r--r--app/javascript/mastodon/components/status.js1
-rw-r--r--app/javascript/mastodon/features/status/components/detailed_status.js1
-rw-r--r--app/javascript/mastodon/features/ui/components/focal_point_modal.js3
-rw-r--r--app/javascript/mastodon/features/ui/components/video_modal.js1
-rw-r--r--app/javascript/mastodon/features/video/index.js18
-rw-r--r--app/javascript/mastodon/stream.js2
-rw-r--r--app/javascript/mastodon/utils/notifications.js3
-rw-r--r--app/javascript/styles/mastodon/components.scss2
20 files changed, 60 insertions, 40 deletions
diff --git a/app/javascript/flavours/glitch/actions/notifications.js b/app/javascript/flavours/glitch/actions/notifications.js
index 7273191b2..9f12df773 100644
--- a/app/javascript/flavours/glitch/actions/notifications.js
+++ b/app/javascript/flavours/glitch/actions/notifications.js
@@ -345,7 +345,7 @@ export function setupBrowserNotifications() {
     if ('Notification' in window && 'permissions' in navigator) {
       navigator.permissions.query({ name: 'notifications' }).then((status) => {
         status.onchange = () => dispatch(setBrowserPermission(Notification.permission));
-      });
+      }).catch(console.warn);
     }
   };
 }
diff --git a/app/javascript/flavours/glitch/components/modal_root.js b/app/javascript/flavours/glitch/components/modal_root.js
index 8d73a1e40..13a8e8702 100644
--- a/app/javascript/flavours/glitch/components/modal_root.js
+++ b/app/javascript/flavours/glitch/components/modal_root.js
@@ -14,11 +14,7 @@ export default class ModalRoot extends React.PureComponent {
     noEsc: PropTypes.bool,
   };
 
-  state = {
-    revealed: !!this.props.children,
-  };
-
-  activeElement = this.state.revealed ? document.activeElement : null;
+  activeElement = this.props.children ? document.activeElement : null;
 
   handleKeyUp = (e) => {
     if ((e.key === 'Escape' || e.key === 'Esc' || e.keyCode === 27)
@@ -59,8 +55,6 @@ export default class ModalRoot extends React.PureComponent {
       this.activeElement = document.activeElement;
 
       this.getSiblings().forEach(sibling => sibling.setAttribute('inert', true));
-    } else if (!nextProps.children) {
-      this.setState({ revealed: false });
     }
   }
 
@@ -80,11 +74,8 @@ export default class ModalRoot extends React.PureComponent {
 
       this.handleModalClose();
     }
-    if (this.props.children) {
-      requestAnimationFrame(() => {
-        this.setState({ revealed: true });
-      });
-      if (!prevProps.children) this.handleModalOpen();
+    if (this.props.children && !prevProps.children) {
+      this.handleModalOpen();
     }
   }
 
@@ -121,7 +112,6 @@ export default class ModalRoot extends React.PureComponent {
 
   render () {
     const { children, onClose } = this.props;
-    const { revealed } = this.state;
     const visible = !!children;
 
     if (!visible) {
@@ -131,7 +121,7 @@ export default class ModalRoot extends React.PureComponent {
     }
 
     return (
-      <div className='modal-root' ref={this.setRef} style={{ opacity: revealed ? 1 : 0 }}>
+      <div className='modal-root' ref={this.setRef}>
         <div style={{ pointerEvents: visible ? 'auto' : 'none' }}>
           <div role='presentation' className='modal-root__overlay' onClick={onClose} />
           <div role='dialog' className='modal-root__container'>{children}</div>
diff --git a/app/javascript/flavours/glitch/components/status.js b/app/javascript/flavours/glitch/components/status.js
index 1b7dce4c4..fcbf4be8c 100644
--- a/app/javascript/flavours/glitch/components/status.js
+++ b/app/javascript/flavours/glitch/components/status.js
@@ -628,6 +628,7 @@ class Status extends ImmutablePureComponent {
           <Bundle fetchComponent={Video} loading={this.renderLoadingVideoPlayer} >
             {Component => (<Component
               preview={attachment.get('preview_url')}
+              frameRate={attachment.getIn(['meta', 'original', 'frame_rate'])}
               blurhash={attachment.get('blurhash')}
               src={attachment.get('url')}
               alt={attachment.get('description')}
diff --git a/app/javascript/flavours/glitch/features/status/components/detailed_status.js b/app/javascript/flavours/glitch/features/status/components/detailed_status.js
index 04d350bcb..40bf370f3 100644
--- a/app/javascript/flavours/glitch/features/status/components/detailed_status.js
+++ b/app/javascript/flavours/glitch/features/status/components/detailed_status.js
@@ -160,6 +160,7 @@ export default class DetailedStatus extends ImmutablePureComponent {
         media = (
           <Video
             preview={attachment.get('preview_url')}
+            frameRate={attachment.getIn(['meta', 'original', 'frame_rate'])}
             blurhash={attachment.get('blurhash')}
             src={attachment.get('url')}
             alt={attachment.get('description')}
diff --git a/app/javascript/flavours/glitch/features/ui/components/focal_point_modal.js b/app/javascript/flavours/glitch/features/ui/components/focal_point_modal.js
index 5de3e26d5..87a7de851 100644
--- a/app/javascript/flavours/glitch/features/ui/components/focal_point_modal.js
+++ b/app/javascript/flavours/glitch/features/ui/components/focal_point_modal.js
@@ -18,7 +18,9 @@ import { length } from 'stringz';
 import { Tesseract as fetchTesseract } from 'flavours/glitch/util/async-components';
 import GIFV from 'flavours/glitch/components/gifv';
 import { me } from 'flavours/glitch/util/initial_state';
+// eslint-disable-next-line import/no-extraneous-dependencies
 import tesseractCorePath from 'tesseract.js-core/tesseract-core.wasm.js';
+// eslint-disable-next-line import/extensions
 import tesseractWorkerPath from 'tesseract.js/dist/worker.min.js';
 import { assetHost } from 'flavours/glitch/util/config';
 
@@ -386,6 +388,7 @@ class FocalPointModal extends ImmutablePureComponent {
             {media.get('type') === 'video' && (
               <Video
                 preview={media.get('preview_url')}
+                frameRate={media.getIn(['meta', 'original', 'frame_rate'])}
                 blurhash={media.get('blurhash')}
                 src={media.get('url')}
                 detailed
diff --git a/app/javascript/flavours/glitch/features/ui/components/video_modal.js b/app/javascript/flavours/glitch/features/ui/components/video_modal.js
index c8d2a81b0..b0a4f3f03 100644
--- a/app/javascript/flavours/glitch/features/ui/components/video_modal.js
+++ b/app/javascript/flavours/glitch/features/ui/components/video_modal.js
@@ -40,6 +40,7 @@ export default class VideoModal extends ImmutablePureComponent {
         <div className='video-modal__container'>
           <Video
             preview={media.get('preview_url')}
+            frameRate={media.getIn(['meta', 'original', 'frame_rate'])}
             blurhash={media.get('blurhash')}
             src={media.get('url')}
             currentTime={options.startTime}
diff --git a/app/javascript/flavours/glitch/features/video/index.js b/app/javascript/flavours/glitch/features/video/index.js
index ea40b6073..92dcaf473 100644
--- a/app/javascript/flavours/glitch/features/video/index.js
+++ b/app/javascript/flavours/glitch/features/video/index.js
@@ -98,6 +98,7 @@ class Video extends React.PureComponent {
 
   static propTypes = {
     preview: PropTypes.string,
+    frameRate: PropTypes.string,
     src: PropTypes.string.isRequired,
     alt: PropTypes.string,
     width: PropTypes.number,
@@ -125,6 +126,10 @@ class Video extends React.PureComponent {
     muted: PropTypes.bool,
   };
 
+  static defaultProps = {
+    frameRate: 25,
+  };
+
   state = {
     currentTime: 0,
     duration: 0,
@@ -298,7 +303,7 @@ class Video extends React.PureComponent {
   }
 
   handleKeyDown = e => {
-    const frameTime = 1 / 25;
+    const frameTime = 1 / this.getFrameRate();
 
     switch(e.key) {
     case 'k':
@@ -531,6 +536,17 @@ class Video extends React.PureComponent {
     this.props.onCloseVideo();
   }
 
+  getFrameRate () {
+    if (this.props.frameRate && isNaN(this.props.frameRate)) {
+      // The frame rate is returned as a fraction string so we
+      // need to convert it to a number
+
+      return this.props.frameRate.split('/').reduce((p, c) => p / c);
+    }
+
+    return this.props.frameRate || 25;
+  }
+
   render () {
     const { preview, src, inline, onOpenVideo, onCloseVideo, intl, alt, letterbox, fullwidth, detailed, sensitive, link, editable, blurhash } = this.props;
     const { containerWidth, currentTime, duration, volume, buffer, dragging, paused, fullscreen, hovered, muted, revealed } = this.state;
diff --git a/app/javascript/flavours/glitch/styles/components/modal.scss b/app/javascript/flavours/glitch/styles/components/modal.scss
index bc0965864..421cbec00 100644
--- a/app/javascript/flavours/glitch/styles/components/modal.scss
+++ b/app/javascript/flavours/glitch/styles/components/modal.scss
@@ -4,8 +4,6 @@
 
 .modal-root {
   position: relative;
-  transition: opacity 0.3s linear;
-  will-change: opacity;
   z-index: 9999;
 }
 
diff --git a/app/javascript/flavours/glitch/util/notifications.js b/app/javascript/flavours/glitch/util/notifications.js
index ab119c2e3..7634cac21 100644
--- a/app/javascript/flavours/glitch/util/notifications.js
+++ b/app/javascript/flavours/glitch/util/notifications.js
@@ -3,6 +3,7 @@
 
 const checkNotificationPromise = () => {
   try {
+    // eslint-disable-next-line promise/catch-or-return
     Notification.requestPermission().then();
   } catch(e) {
     return false;
@@ -22,7 +23,7 @@ const handlePermission = (permission, callback) => {
 
 export const requestNotificationPermission = (callback) => {
   if (checkNotificationPromise()) {
-    Notification.requestPermission().then((permission) => handlePermission(permission, callback));
+    Notification.requestPermission().then((permission) => handlePermission(permission, callback)).catch(console.warn);
   } else {
     Notification.requestPermission((permission) => handlePermission(permission, callback));
   }
diff --git a/app/javascript/flavours/glitch/util/stream.js b/app/javascript/flavours/glitch/util/stream.js
index cf1388aed..c6d12cd6f 100644
--- a/app/javascript/flavours/glitch/util/stream.js
+++ b/app/javascript/flavours/glitch/util/stream.js
@@ -16,7 +16,7 @@ let sharedConnection;
  * @property {function(): void} onDisconnect
  */
 
- /**
+/**
   * @typedef StreamEvent
   * @property {string} event
   * @property {object} payload
diff --git a/app/javascript/mastodon/actions/notifications.js b/app/javascript/mastodon/actions/notifications.js
index d40b65745..93e18fba9 100644
--- a/app/javascript/mastodon/actions/notifications.js
+++ b/app/javascript/mastodon/actions/notifications.js
@@ -257,7 +257,7 @@ export function setupBrowserNotifications() {
     if ('Notification' in window && 'permissions' in navigator) {
       navigator.permissions.query({ name: 'notifications' }).then((status) => {
         status.onchange = () => dispatch(setBrowserPermission(Notification.permission));
-      });
+      }).catch(console.warn);
     }
   };
 }
diff --git a/app/javascript/mastodon/components/modal_root.js b/app/javascript/mastodon/components/modal_root.js
index 6297b5e29..fe573ffda 100644
--- a/app/javascript/mastodon/components/modal_root.js
+++ b/app/javascript/mastodon/components/modal_root.js
@@ -9,11 +9,7 @@ export default class ModalRoot extends React.PureComponent {
     onClose: PropTypes.func.isRequired,
   };
 
-  state = {
-    revealed: !!this.props.children,
-  };
-
-  activeElement = this.state.revealed ? document.activeElement : null;
+  activeElement = this.props.children ? document.activeElement : null;
 
   handleKeyUp = (e) => {
     if ((e.key === 'Escape' || e.key === 'Esc' || e.keyCode === 27)
@@ -53,8 +49,6 @@ export default class ModalRoot extends React.PureComponent {
       this.activeElement = document.activeElement;
 
       this.getSiblings().forEach(sibling => sibling.setAttribute('inert', true));
-    } else if (!nextProps.children) {
-      this.setState({ revealed: false });
     }
   }
 
@@ -72,11 +66,6 @@ export default class ModalRoot extends React.PureComponent {
         console.error(error);
       });
     }
-    if (this.props.children) {
-      requestAnimationFrame(() => {
-        this.setState({ revealed: true });
-      });
-    }
   }
 
   componentWillUnmount () {
@@ -94,7 +83,6 @@ export default class ModalRoot extends React.PureComponent {
 
   render () {
     const { children, onClose } = this.props;
-    const { revealed } = this.state;
     const visible = !!children;
 
     if (!visible) {
@@ -104,7 +92,7 @@ export default class ModalRoot extends React.PureComponent {
     }
 
     return (
-      <div className='modal-root' ref={this.setRef} style={{ opacity: revealed ? 1 : 0 }}>
+      <div className='modal-root' ref={this.setRef}>
         <div style={{ pointerEvents: visible ? 'auto' : 'none' }}>
           <div role='presentation' className='modal-root__overlay' onClick={onClose} />
           <div role='dialog' className='modal-root__container'>{children}</div>
diff --git a/app/javascript/mastodon/components/status.js b/app/javascript/mastodon/components/status.js
index f4ed25f1e..8f288bdf9 100644
--- a/app/javascript/mastodon/components/status.js
+++ b/app/javascript/mastodon/components/status.js
@@ -391,6 +391,7 @@ class Status extends ImmutablePureComponent {
             {Component => (
               <Component
                 preview={attachment.get('preview_url')}
+                frameRate={attachment.getIn(['meta', 'original', 'frame_rate'])}
                 blurhash={attachment.get('blurhash')}
                 src={attachment.get('url')}
                 alt={attachment.get('description')}
diff --git a/app/javascript/mastodon/features/status/components/detailed_status.js b/app/javascript/mastodon/features/status/components/detailed_status.js
index c2b883f7f..cd29b5489 100644
--- a/app/javascript/mastodon/features/status/components/detailed_status.js
+++ b/app/javascript/mastodon/features/status/components/detailed_status.js
@@ -142,6 +142,7 @@ class DetailedStatus extends ImmutablePureComponent {
         media = (
           <Video
             preview={attachment.get('preview_url')}
+            frameRate={attachment.getIn(['meta', 'original', 'frame_rate'])}
             blurhash={attachment.get('blurhash')}
             src={attachment.get('url')}
             alt={attachment.get('description')}
diff --git a/app/javascript/mastodon/features/ui/components/focal_point_modal.js b/app/javascript/mastodon/features/ui/components/focal_point_modal.js
index e19f277d8..578375a7f 100644
--- a/app/javascript/mastodon/features/ui/components/focal_point_modal.js
+++ b/app/javascript/mastodon/features/ui/components/focal_point_modal.js
@@ -18,7 +18,9 @@ import { length } from 'stringz';
 import { Tesseract as fetchTesseract } from 'mastodon/features/ui/util/async-components';
 import GIFV from 'mastodon/components/gifv';
 import { me } from 'mastodon/initial_state';
+// eslint-disable-next-line import/no-extraneous-dependencies
 import tesseractCorePath from 'tesseract.js-core/tesseract-core.wasm.js';
+// eslint-disable-next-line import/extensions
 import tesseractWorkerPath from 'tesseract.js/dist/worker.min.js';
 import { assetHost } from 'mastodon/utils/config';
 
@@ -386,6 +388,7 @@ class FocalPointModal extends ImmutablePureComponent {
             {media.get('type') === 'video' && (
               <Video
                 preview={media.get('preview_url')}
+                frameRate={media.getIn(['meta', 'original', 'frame_rate'])}
                 blurhash={media.get('blurhash')}
                 src={media.get('url')}
                 detailed
diff --git a/app/javascript/mastodon/features/ui/components/video_modal.js b/app/javascript/mastodon/features/ui/components/video_modal.js
index 9a07e7c4d..cce6756c3 100644
--- a/app/javascript/mastodon/features/ui/components/video_modal.js
+++ b/app/javascript/mastodon/features/ui/components/video_modal.js
@@ -64,6 +64,7 @@ export default class VideoModal extends ImmutablePureComponent {
         <div className='video-modal__container'>
           <Video
             preview={media.get('preview_url')}
+            frameRate={media.getIn(['meta', 'original', 'frame_rate'])}
             blurhash={media.get('blurhash')}
             src={media.get('url')}
             currentTime={options.startTime}
diff --git a/app/javascript/mastodon/features/video/index.js b/app/javascript/mastodon/features/video/index.js
index e6c6f4b67..83e638ff6 100644
--- a/app/javascript/mastodon/features/video/index.js
+++ b/app/javascript/mastodon/features/video/index.js
@@ -99,6 +99,7 @@ class Video extends React.PureComponent {
 
   static propTypes = {
     preview: PropTypes.string,
+    frameRate: PropTypes.string,
     src: PropTypes.string.isRequired,
     alt: PropTypes.string,
     width: PropTypes.number,
@@ -123,6 +124,10 @@ class Video extends React.PureComponent {
     muted: PropTypes.bool,
   };
 
+  static defaultProps = {
+    frameRate: 25,
+  };
+
   state = {
     currentTime: 0,
     duration: 0,
@@ -288,7 +293,7 @@ class Video extends React.PureComponent {
   }
 
   handleKeyDown = e => {
-    const frameTime = 1 / 25;
+    const frameTime = 1 / this.getFrameRate();
 
     switch(e.key) {
     case 'k':
@@ -517,6 +522,17 @@ class Video extends React.PureComponent {
     this.props.onCloseVideo();
   }
 
+  getFrameRate () {
+    if (this.props.frameRate && isNaN(this.props.frameRate)) {
+      // The frame rate is returned as a fraction string so we
+      // need to convert it to a number
+
+      return this.props.frameRate.split('/').reduce((p, c) => p / c);
+    }
+
+    return this.props.frameRate;
+  }
+
   render () {
     const { preview, src, inline, onOpenVideo, onCloseVideo, intl, alt, detailed, sensitive, link, editable, blurhash } = this.props;
     const { containerWidth, currentTime, duration, volume, buffer, dragging, paused, fullscreen, hovered, muted, revealed } = this.state;
diff --git a/app/javascript/mastodon/stream.js b/app/javascript/mastodon/stream.js
index cf1388aed..c6d12cd6f 100644
--- a/app/javascript/mastodon/stream.js
+++ b/app/javascript/mastodon/stream.js
@@ -16,7 +16,7 @@ let sharedConnection;
  * @property {function(): void} onDisconnect
  */
 
- /**
+/**
   * @typedef StreamEvent
   * @property {string} event
   * @property {object} payload
diff --git a/app/javascript/mastodon/utils/notifications.js b/app/javascript/mastodon/utils/notifications.js
index ab119c2e3..7634cac21 100644
--- a/app/javascript/mastodon/utils/notifications.js
+++ b/app/javascript/mastodon/utils/notifications.js
@@ -3,6 +3,7 @@
 
 const checkNotificationPromise = () => {
   try {
+    // eslint-disable-next-line promise/catch-or-return
     Notification.requestPermission().then();
   } catch(e) {
     return false;
@@ -22,7 +23,7 @@ const handlePermission = (permission, callback) => {
 
 export const requestNotificationPermission = (callback) => {
   if (checkNotificationPromise()) {
-    Notification.requestPermission().then((permission) => handlePermission(permission, callback));
+    Notification.requestPermission().then((permission) => handlePermission(permission, callback)).catch(console.warn);
   } else {
     Notification.requestPermission((permission) => handlePermission(permission, callback));
   }
diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss
index 9c4e6d08f..efdc6fa39 100644
--- a/app/javascript/styles/mastodon/components.scss
+++ b/app/javascript/styles/mastodon/components.scss
@@ -4439,8 +4439,6 @@ a.status-card.compact:hover {
 
 .modal-root {
   position: relative;
-  transition: opacity 0.3s linear;
-  will-change: opacity;
   z-index: 9999;
 }