import Permalink from './permalink';
import classnames from 'classnames';
+const MAX_HEIGHT = 322; // 20px * 16 (+ 2px padding at the top)
+
export default class StatusContent extends React.PureComponent {
static contextTypes = {
expanded: PropTypes.bool,
onExpandedToggle: PropTypes.func,
onClick: PropTypes.func,
+ collapsable: PropTypes.bool,
};
state = {
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 () {
link.setAttribute('target', '_blank');
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 () {
}
}
+ handleCollapsedClick = (e) => {
+ e.preventDefault();
+ this.setState({ collapsed: !this.state.collapsed });
+ }
+
setRef = (c) => {
this.node = c;
}
const classNames = classnames('status__content', {
'status__content--with-action': this.props.onClick && this.context.router,
'status__content--with-spoiler': status.get('spoiler_text').length > 0,
+ 'status__content--collapsed': this.state.collapsed === true,
});
if (isRtl(status.get('search_index'))) {
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) {
let mentionsPlaceholder = '';
</div>
);
} else if (this.props.onClick) {
- return (
+ const output = [
<div
ref={this.setRef}
tabIndex='0'
className={classNames}
style={directionStyle}
+ dangerouslySetInnerHTML={content}
onMouseDown={this.handleMouseDown}
onMouseUp={this.handleMouseUp}
- dangerouslySetInnerHTML={content}
- />
- );
+ />,
+ ];
+
+ if (this.state.collapsed) {
+ output.push(readMoreButton);
+ }
+
+ return output;
} else {
return (
<div
.status__content,
.reply-indicator__content {
+ position: relative;
font-size: 15px;
line-height: 20px;
word-wrap: break-word;
font-weight: 400;
overflow: hidden;
+ text-overflow: ellipsis;
white-space: pre-wrap;
padding-top: 2px;
color: $primary-text-color;
}
}
+.status__content.status__content--collapsed {
+ max-height: 20px * 15; // 15 lines is roughly above 500 characters
+}
+
+.status__content__read-more-button {
+ display: block;
+ font-size: 15px;
+ line-height: 20px;
+ color: lighten($ui-highlight-color, 8%);
+ border: 0;
+ background: transparent;
+ padding: 0;
+ padding-top: 8px;
+
+ &:hover,
+ &:active {
+ text-decoration: underline;
+ }
+}
+
.status__content__spoiler-link {
display: inline-block;
border-radius: 2px;