about summary refs log tree commit diff
path: root/app/javascript/mastodon/components/status.js
diff options
context:
space:
mode:
Diffstat (limited to 'app/javascript/mastodon/components/status.js')
-rw-r--r--app/javascript/mastodon/components/status.js114
1 files changed, 14 insertions, 100 deletions
diff --git a/app/javascript/mastodon/components/status.js b/app/javascript/mastodon/components/status.js
index 7468957d3..b8617018d 100644
--- a/app/javascript/mastodon/components/status.js
+++ b/app/javascript/mastodon/components/status.js
@@ -12,13 +12,11 @@ import StatusContent from './status_content';
 import StatusActionBar from './status_action_bar';
 import { FormattedMessage } from 'react-intl';
 import ImmutablePureComponent from 'react-immutable-pure-component';
-import scheduleIdleTask from '../features/ui/util/schedule_idle_task';
 import { MediaGallery, VideoPlayer } from '../features/ui/util/async-components';
 
 // We use the component (and not the container) since we do not want
 // to use the progress bar to show download progress
 import Bundle from '../features/ui/components/bundle';
-import getRectFromEntry from '../features/ui/util/get_rect_from_entry';
 
 export default class Status extends ImmutablePureComponent {
 
@@ -29,27 +27,25 @@ export default class Status extends ImmutablePureComponent {
   static propTypes = {
     status: ImmutablePropTypes.map,
     account: ImmutablePropTypes.map,
-    wrapped: PropTypes.bool,
     onReply: PropTypes.func,
     onFavourite: PropTypes.func,
     onReblog: PropTypes.func,
     onDelete: PropTypes.func,
+    onPin: PropTypes.func,
     onOpenMedia: PropTypes.func,
     onOpenVideo: PropTypes.func,
     onBlock: PropTypes.func,
+    onEmbed: PropTypes.func,
     onHeightChange: PropTypes.func,
     me: PropTypes.number,
     boostModal: PropTypes.bool,
     autoPlayGif: PropTypes.bool,
     muted: PropTypes.bool,
-    intersectionObserverWrapper: PropTypes.object,
-    index: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
-    listLength: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
+    hidden: PropTypes.bool,
   };
 
   state = {
     isExpanded: false,
-    isHidden: false, // set to true in requestIdleCallback to trigger un-render
   }
 
   // Avoid checking props that are functions (and whose equality will always
@@ -57,91 +53,15 @@ export default class Status extends ImmutablePureComponent {
   updateOnProps = [
     'status',
     'account',
-    'wrapped',
     'me',
     'boostModal',
     'autoPlayGif',
     'muted',
-    'listLength',
+    'hidden',
   ]
 
   updateOnStates = ['isExpanded']
 
-  shouldComponentUpdate (nextProps, nextState) {
-    if (!nextState.isIntersecting && nextState.isHidden) {
-      // It's only if we're not intersecting (i.e. offscreen) and isHidden is true
-      // that either "isIntersecting" or "isHidden" matter, and then they're
-      // the only things that matter (and updated ARIA attributes).
-      return this.state.isIntersecting || !this.state.isHidden || nextProps.listLength !== this.props.listLength;
-    } else if (nextState.isIntersecting && !this.state.isIntersecting) {
-      // If we're going from a non-intersecting state to an intersecting state,
-      // (i.e. offscreen to onscreen), then we definitely need to re-render
-      return true;
-    }
-    // Otherwise, diff based on "updateOnProps" and "updateOnStates"
-    return super.shouldComponentUpdate(nextProps, nextState);
-  }
-
-  componentDidMount () {
-    if (!this.props.intersectionObserverWrapper) {
-      // TODO: enable IntersectionObserver optimization for notification statuses.
-      // These are managed in notifications/index.js rather than status_list.js
-      return;
-    }
-    this.props.intersectionObserverWrapper.observe(
-      this.props.id,
-      this.node,
-      this.handleIntersection
-    );
-
-    this.componentMounted = true;
-  }
-
-  componentWillUnmount () {
-    if (this.props.intersectionObserverWrapper) {
-      this.props.intersectionObserverWrapper.unobserve(this.props.id, this.node);
-    }
-
-    this.componentMounted = false;
-  }
-
-  handleIntersection = (entry) => {
-    if (this.node && this.node.children.length !== 0) {
-      // save the height of the fully-rendered element
-      this.height = getRectFromEntry(entry).height;
-
-      if (this.props.onHeightChange) {
-        this.props.onHeightChange(this.props.status, this.height);
-      }
-    }
-
-    this.setState((prevState) => {
-      if (prevState.isIntersecting && !entry.isIntersecting) {
-        scheduleIdleTask(this.hideIfNotIntersecting);
-      }
-      return {
-        isIntersecting: entry.isIntersecting,
-        isHidden: false,
-      };
-    });
-  }
-
-  hideIfNotIntersecting = () => {
-    if (!this.componentMounted) {
-      return;
-    }
-
-    // When the browser gets a chance, test if we're still not intersecting,
-    // and if so, set our isHidden to true to trigger an unrender. The point of
-    // this is to save DOM nodes and avoid using up too much memory.
-    // See: https://github.com/tootsuite/mastodon/issues/2900
-    this.setState((prevState) => ({ isHidden: !prevState.isIntersecting }));
-  }
-
-  handleRef = (node) => {
-    this.node = node;
-  }
-
   handleClick = () => {
     if (!this.context.router) {
       return;
@@ -175,25 +95,19 @@ export default class Status extends ImmutablePureComponent {
     let media = null;
     let statusAvatar;
 
-    // Exclude intersectionObserverWrapper from `other` variable
-    // because intersection is managed in here.
-    const { status, account, intersectionObserverWrapper, index, listLength, wrapped, ...other } = this.props;
-    const { isExpanded, isIntersecting, isHidden } = this.state;
+    const { status, account, hidden, ...other } = this.props;
+    const { isExpanded } = this.state;
 
     if (status === null) {
       return null;
     }
 
-    const hasIntersectionObserverWrapper = !!this.props.intersectionObserverWrapper;
-    const isHiddenForSure = isIntersecting === false && isHidden;
-    const visibilityUnknownButHeightIsCached = isIntersecting === undefined && status.has('height');
-
-    if (hasIntersectionObserverWrapper && (isHiddenForSure || visibilityUnknownButHeightIsCached)) {
+    if (hidden) {
       return (
-        <article ref={this.handleRef} data-id={status.get('id')} aria-posinset={index} aria-setsize={listLength} tabIndex='0' style={{ height: `${this.height || status.get('height')}px`, opacity: 0, overflow: 'hidden' }}>
+        <div>
           {status.getIn(['account', 'display_name']) || status.getIn(['account', 'username'])}
           {status.get('content')}
-        </article>
+        </div>
       );
     }
 
@@ -201,14 +115,14 @@ export default class Status extends ImmutablePureComponent {
       const display_name_html = { __html: status.getIn(['account', 'display_name_html']) };
 
       return (
-        <article className='status__wrapper' ref={this.handleRef} data-id={status.get('id')} aria-posinset={index} aria-setsize={listLength} tabIndex='0'>
+        <div className='status__wrapper' data-id={status.get('id')} >
           <div className='status__prepend'>
             <div className='status__prepend-icon-wrapper'><i className='fa fa-fw fa-retweet status__prepend-icon' /></div>
             <FormattedMessage id='status.reblogged_by' defaultMessage='{name} boosted' values={{ name: <a onClick={this.handleAccountClick} data-id={status.getIn(['account', 'id'])} href={status.getIn(['account', 'url'])} className='status__display-name muted'><strong dangerouslySetInnerHTML={display_name_html} /></a> }} />
           </div>
 
-          <Status {...other} wrapped status={status.get('reblog')} account={status.get('account')} />
-        </article>
+          <Status {...other} status={status.get('reblog')} account={status.get('account')} />
+        </div>
       );
     }
 
@@ -237,7 +151,7 @@ export default class Status extends ImmutablePureComponent {
     }
 
     return (
-      <article aria-posinset={index} aria-setsize={listLength} className={`status ${this.props.muted ? 'muted' : ''} status-${status.get('visibility')}`} data-id={status.get('id')} tabIndex={wrapped ? null : '0'}  ref={this.handleRef}>
+      <div className={`status ${this.props.muted ? 'muted' : ''} status-${status.get('visibility')}`} data-id={status.get('id')}>
         <div className='status__info'>
           <a href={status.get('url')} className='status__relative-time' target='_blank' rel='noopener'><RelativeTimestamp timestamp={status.get('created_at')} /></a>
 
@@ -255,7 +169,7 @@ export default class Status extends ImmutablePureComponent {
         {media}
 
         <StatusActionBar {...this.props} />
-      </article>
+      </div>
     );
   }