|
|
@ -6,6 +6,8 @@ import { FormattedMessage } from 'react-intl'; |
|
|
|
import Permalink from './permalink'; |
|
|
|
import Permalink from './permalink'; |
|
|
|
import classnames from 'classnames'; |
|
|
|
import classnames from 'classnames'; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const MAX_HEIGHT = 322; // 20px * 16 (+ 2px padding at the top)
|
|
|
|
|
|
|
|
|
|
|
|
export default class StatusContent extends React.PureComponent { |
|
|
|
export default class StatusContent extends React.PureComponent { |
|
|
|
|
|
|
|
|
|
|
|
static contextTypes = { |
|
|
|
static contextTypes = { |
|
|
@ -17,10 +19,12 @@ export default class StatusContent extends React.PureComponent { |
|
|
|
expanded: PropTypes.bool, |
|
|
|
expanded: PropTypes.bool, |
|
|
|
onExpandedToggle: PropTypes.func, |
|
|
|
onExpandedToggle: PropTypes.func, |
|
|
|
onClick: PropTypes.func, |
|
|
|
onClick: PropTypes.func, |
|
|
|
|
|
|
|
collapsable: PropTypes.bool, |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
state = { |
|
|
|
state = { |
|
|
|
hidden: true, |
|
|
|
hidden: true, |
|
|
|
|
|
|
|
collapsed: null, // `collapsed: null` indicates that an element doesn't need collapsing, while `true` or `false` indicates that it does (and is/isn't).
|
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
_updateStatusLinks () { |
|
|
|
_updateStatusLinks () { |
|
|
@ -53,6 +57,16 @@ export default class StatusContent extends React.PureComponent { |
|
|
|
link.setAttribute('target', '_blank'); |
|
|
|
link.setAttribute('target', '_blank'); |
|
|
|
link.setAttribute('rel', 'noopener'); |
|
|
|
link.setAttribute('rel', 'noopener'); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ( |
|
|
|
|
|
|
|
this.props.collapsable |
|
|
|
|
|
|
|
&& this.props.onClick |
|
|
|
|
|
|
|
&& this.state.collapsed === null |
|
|
|
|
|
|
|
&& node.clientHeight > MAX_HEIGHT |
|
|
|
|
|
|
|
&& this.props.status.get('spoiler_text').length === 0 |
|
|
|
|
|
|
|
) { |
|
|
|
|
|
|
|
this.setState({ collapsed: true }); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
componentDidMount () { |
|
|
|
componentDidMount () { |
|
|
@ -113,6 +127,11 @@ export default class StatusContent extends React.PureComponent { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
handleCollapsedClick = (e) => { |
|
|
|
|
|
|
|
e.preventDefault(); |
|
|
|
|
|
|
|
this.setState({ collapsed: !this.state.collapsed }); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
setRef = (c) => { |
|
|
|
setRef = (c) => { |
|
|
|
this.node = c; |
|
|
|
this.node = c; |
|
|
|
} |
|
|
|
} |
|
|
@ -132,12 +151,19 @@ export default class StatusContent extends React.PureComponent { |
|
|
|
const classNames = classnames('status__content', { |
|
|
|
const classNames = classnames('status__content', { |
|
|
|
'status__content--with-action': this.props.onClick && this.context.router, |
|
|
|
'status__content--with-action': this.props.onClick && this.context.router, |
|
|
|
'status__content--with-spoiler': status.get('spoiler_text').length > 0, |
|
|
|
'status__content--with-spoiler': status.get('spoiler_text').length > 0, |
|
|
|
|
|
|
|
'status__content--collapsed': this.state.collapsed === true, |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
if (isRtl(status.get('search_index'))) { |
|
|
|
if (isRtl(status.get('search_index'))) { |
|
|
|
directionStyle.direction = 'rtl'; |
|
|
|
directionStyle.direction = 'rtl'; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const readMoreButton = ( |
|
|
|
|
|
|
|
<button className='status__content__read-more-button' onClick={this.props.onClick}> |
|
|
|
|
|
|
|
<FormattedMessage id='status.read_more' defaultMessage='Read more' /><i className='fa fa-fw fa-angle-right' /> |
|
|
|
|
|
|
|
</button> |
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
if (status.get('spoiler_text').length > 0) { |
|
|
|
if (status.get('spoiler_text').length > 0) { |
|
|
|
let mentionsPlaceholder = ''; |
|
|
|
let mentionsPlaceholder = ''; |
|
|
|
|
|
|
|
|
|
|
@ -167,17 +193,23 @@ export default class StatusContent extends React.PureComponent { |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
); |
|
|
|
); |
|
|
|
} else if (this.props.onClick) { |
|
|
|
} else if (this.props.onClick) { |
|
|
|
return ( |
|
|
|
const output = [ |
|
|
|
<div |
|
|
|
<div |
|
|
|
ref={this.setRef} |
|
|
|
ref={this.setRef} |
|
|
|
tabIndex='0' |
|
|
|
tabIndex='0' |
|
|
|
className={classNames} |
|
|
|
className={classNames} |
|
|
|
style={directionStyle} |
|
|
|
style={directionStyle} |
|
|
|
|
|
|
|
dangerouslySetInnerHTML={content} |
|
|
|
onMouseDown={this.handleMouseDown} |
|
|
|
onMouseDown={this.handleMouseDown} |
|
|
|
onMouseUp={this.handleMouseUp} |
|
|
|
onMouseUp={this.handleMouseUp} |
|
|
|
dangerouslySetInnerHTML={content} |
|
|
|
/>, |
|
|
|
/> |
|
|
|
]; |
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
if (this.state.collapsed) { |
|
|
|
|
|
|
|
output.push(readMoreButton); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return output; |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
return ( |
|
|
|
return ( |
|
|
|
<div |
|
|
|
<div |
|
|
|