diff --git a/app/javascript/mastodon/components/status.js b/app/javascript/mastodon/components/status.js index a13493b7ccf..7ca898c3958 100644 --- a/app/javascript/mastodon/components/status.js +++ b/app/javascript/mastodon/components/status.js @@ -41,6 +41,7 @@ class Status extends ImmutablePureComponent { }; state = { + isExpanded: false, isIntersecting: true, // assume intersecting until told otherwise isHidden: false, // set to true in requestIdleCallback to trigger un-render } @@ -57,7 +58,7 @@ class Status extends ImmutablePureComponent { 'muted', ] - updateOnStates = [] + updateOnStates = ['isExpanded'] shouldComponentUpdate (nextProps, nextState) { if (!nextState.isIntersecting && nextState.isHidden) { @@ -112,12 +113,15 @@ class Status extends ImmutablePureComponent { this.setState((prevState) => ({ isHidden: !prevState.isIntersecting })); } + saveHeight = () => { + if (this.node && this.node.children.length !== 0) { + this.height = this.node.clientHeight; + } + } handleRef = (node) => { this.node = node; - if (node && node.children.length !== 0) { - this.height = node.clientHeight; - } + this.saveHeight(); } handleClick = () => { @@ -133,11 +137,15 @@ class Status extends ImmutablePureComponent { } } + handleExpandedToggle = () => { + this.setState({ isExpanded: !this.state.isExpanded }); + }; + render () { let media = null; let statusAvatar; const { status, account, ...other } = this.props; - const { isIntersecting, isHidden } = this.state; + const { isExpanded, isIntersecting, isHidden } = this.state; if (status === null) { return null; @@ -203,7 +211,7 @@ class Status extends ImmutablePureComponent { - + {media} diff --git a/app/javascript/mastodon/components/status_content.js b/app/javascript/mastodon/components/status_content.js index d2285428841..89031b3dcb1 100644 --- a/app/javascript/mastodon/components/status_content.js +++ b/app/javascript/mastodon/components/status_content.js @@ -15,6 +15,9 @@ class StatusContent extends React.PureComponent { static propTypes = { status: ImmutablePropTypes.map.isRequired, + expanded: PropTypes.bool, + onExpandedToggle: PropTypes.func, + onHeightUpdate: PropTypes.func, onClick: PropTypes.func, }; @@ -44,6 +47,12 @@ class StatusContent extends React.PureComponent { } } + componentDidUpdate () { + if (this.props.onHeightUpdate) { + this.props.onHeightUpdate(); + } + } + onMentionClick = (mention, e) => { if (e.button === 0) { e.preventDefault(); @@ -85,7 +94,13 @@ class StatusContent extends React.PureComponent { handleSpoilerClick = (e) => { e.preventDefault(); - this.setState({ hidden: !this.state.hidden }); + + if (this.props.onExpandedToggle) { + // The parent manages the state + this.props.onExpandedToggle(); + } else { + this.setState({ hidden: !this.state.hidden }); + } } setRef = (c) => { @@ -94,7 +109,8 @@ class StatusContent extends React.PureComponent { render () { const { status } = this.props; - const { hidden } = this.state; + + const hidden = this.props.onExpandedToggle ? !this.props.expanded : this.state.hidden; const content = { __html: emojify(status.get('content')) }; const spoilerContent = { __html: emojify(escapeTextContentForBrowser(status.get('spoiler_text', ''))) };