Moved reblog wrapper outside of <Status>

master
kibigo! 8 years ago
parent ab4632a41e
commit 36805a39db
  1. 104
      app/javascript/mastodon/components/status.js

@ -9,7 +9,7 @@ import VideoPlayer from './video_player';
import StatusContent from './status_content'; import StatusContent from './status_content';
import StatusActionBar from './status_action_bar'; import StatusActionBar from './status_action_bar';
import IconButton from './icon_button'; import IconButton from './icon_button';
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; import { defineMessages, FormattedMessage } from 'react-intl';
import emojify from '../emoji'; import emojify from '../emoji';
import escapeTextContentForBrowser from 'escape-html'; import escapeTextContentForBrowser from 'escape-html';
import ImmutablePureComponent from 'react-immutable-pure-component'; import ImmutablePureComponent from 'react-immutable-pure-component';
@ -20,7 +20,75 @@ const messages = defineMessages({
uncollapse: { id: 'status.uncollapse', defaultMessage: 'Uncollapse' }, uncollapse: { id: 'status.uncollapse', defaultMessage: 'Uncollapse' },
}); });
class StatusUnextended extends ImmutablePureComponent { export default class StatusOrReblog 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,
onOpenMedia: PropTypes.func,
onOpenVideo: PropTypes.func,
onBlock: PropTypes.func,
me: PropTypes.number,
boostModal: PropTypes.bool,
autoPlayGif: PropTypes.bool,
muted: PropTypes.bool,
collapse: PropTypes.bool,
intersectionObserverWrapper: PropTypes.object,
intl: PropTypes.object.isRequired,
};
// Avoid checking props that are functions (and whose equality will always
// evaluate to false. See react-immutable-pure-component for usage.
updateOnProps = [
'status',
'account',
'wrapped',
'me',
'boostModal',
'autoPlayGif',
'muted',
'collapse',
]
render () {
// Exclude intersectionObserverWrapper from `other` variable
// because intersection is managed in here.
const { status, account, ...other } = this.props;
if (status === null) {
return null;
}
if (status.get('reblog', null) !== null && typeof status.get('reblog') === 'object') {
let displayName = status.getIn(['account', 'display_name']);
if (displayName.length === 0) {
displayName = status.getIn(['account', 'username']);
}
const displayNameHTML = { __html: emojify(escapeTextContentForBrowser(displayName)) };
return (
<div className='status__wrapper' ref={this.handleRef} 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={displayNameHTML} /></a> }} />
</div>
<Status {...other} status={status.get('reblog')} account={status.get('account')} wrapped />
</div>
);
} else return <Status {...this.props} />;
}
}
class Status extends ImmutablePureComponent {
static contextTypes = { static contextTypes = {
router: PropTypes.object, router: PropTypes.object,
@ -90,15 +158,15 @@ class StatusUnextended extends ImmutablePureComponent {
return super.shouldComponentUpdate(nextProps, nextState); return super.shouldComponentUpdate(nextProps, nextState);
} }
componentDidUpdate (prevProps, prevState) { componentDidUpdate () {
if (prevState.isCollapsed !== this.state.isCollapsed) this.saveHeight(); if (this.state.isIntersecting || !this.state.isHidden) this.saveHeight();
} }
componentDidMount () { componentDidMount () {
const node = this.node; const node = this.node;
if (this.props.collapse !== undefined) this.setState({ isCollapsed: !!this.props.collapse }); if (this.props.collapse !== undefined) this.setState({ isCollapsed: !!this.props.collapse });
else if (node.clientHeight > 400 && !(this.props.status.get('reblog', null) !== null && typeof this.props.status.get('reblog') === 'object')) this.setState({ isCollapsed: true }); else if (node.clientHeight > 400) this.setState({ isCollapsed: true });
if (!this.props.intersectionObserverWrapper) { if (!this.props.intersectionObserverWrapper) {
// TODO: enable IntersectionObserver optimization for notification statuses. // TODO: enable IntersectionObserver optimization for notification statuses.
@ -123,7 +191,7 @@ class StatusUnextended extends ImmutablePureComponent {
// https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/12156111/ // https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/12156111/
// https://github.com/WICG/IntersectionObserver/issues/211 // https://github.com/WICG/IntersectionObserver/issues/211
const isIntersecting = (typeof entry.isIntersecting === 'boolean') ? const isIntersecting = (typeof entry.isIntersecting === 'boolean') ?
entry.isIntersecting : entry.intersectionRect.height > 0; entry.isIntersecting : entry.intersectionRect.height > 0;
this.setState((prevState) => { this.setState((prevState) => {
if (prevState.isIntersecting && !isIntersecting) { if (prevState.isIntersecting && !isIntersecting) {
scheduleIdleTask(this.hideIfNotIntersecting); scheduleIdleTask(this.hideIfNotIntersecting);
@ -206,27 +274,6 @@ class StatusUnextended extends ImmutablePureComponent {
); );
} }
if (status.get('reblog', null) !== null && typeof status.get('reblog') === 'object') {
let displayName = status.getIn(['account', 'display_name']);
if (displayName.length === 0) {
displayName = status.getIn(['account', 'username']);
}
const displayNameHTML = { __html: emojify(escapeTextContentForBrowser(displayName)) };
return (
<div className='status__wrapper' ref={this.handleRef} 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={displayNameHTML} /></a> }} />
</div>
<Status {...other} wrapped status={status.get('reblog')} account={status.get('account')} />
</div>
);
}
if (status.get('media_attachments').size > 0 && !this.props.muted) { if (status.get('media_attachments').size > 0 && !this.props.muted) {
if (status.get('media_attachments').some(item => item.get('type') === 'unknown')) { if (status.get('media_attachments').some(item => item.get('type') === 'unknown')) {
@ -285,6 +332,3 @@ class StatusUnextended extends ImmutablePureComponent {
} }
} }
const Status = injectIntl(StatusUnextended);
export default Status;

Loading…
Cancel
Save