You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

81 lines
2.8 KiB

  1. import { connect } from 'react-redux';
  2. import PureRenderMixin from 'react-addons-pure-render-mixin';
  3. import ImmutablePropTypes from 'react-immutable-proptypes';
  4. import { fetchStatus } from '../../actions/statuses';
  5. import Immutable from 'immutable';
  6. import EmbeddedStatus from '../../components/status';
  7. import { favourite, reblog } from '../../actions/interactions';
  8. import { replyCompose } from '../../actions/compose';
  9. import { selectStatus } from '../../reducers/timelines';
  10. function selectStatuses(state, ids) {
  11. return ids.map(id => selectStatus(state, id)).filterNot(status => status === null);
  12. };
  13. const mapStateToProps = (state, props) => ({
  14. status: selectStatus(state, Number(props.params.statusId)),
  15. ancestors: selectStatuses(state, state.getIn(['timelines', 'ancestors', Number(props.params.statusId)], Immutable.OrderedSet())),
  16. descendants: selectStatuses(state, state.getIn(['timelines', 'descendants', Number(props.params.statusId)], Immutable.OrderedSet()))
  17. });
  18. const Status = React.createClass({
  19. propTypes: {
  20. params: React.PropTypes.object.isRequired,
  21. dispatch: React.PropTypes.func.isRequired,
  22. status: ImmutablePropTypes.map,
  23. ancestors: ImmutablePropTypes.orderedSet.isRequired,
  24. descendants: ImmutablePropTypes.orderedSet.isRequired
  25. },
  26. mixins: [PureRenderMixin],
  27. componentWillMount () {
  28. this.props.dispatch(fetchStatus(Number(this.props.params.statusId)));
  29. },
  30. componentWillReceiveProps (nextProps) {
  31. if (nextProps.params.statusId !== this.props.params.statusId && nextProps.params.statusId) {
  32. this.props.dispatch(fetchStatus(Number(nextProps.params.statusId)));
  33. }
  34. },
  35. handleFavouriteClick (status) {
  36. this.props.dispatch(favourite(status));
  37. },
  38. handleReplyClick (status) {
  39. this.props.dispatch(replyCompose(status));
  40. },
  41. handleReblogClick (status) {
  42. this.props.dispatch(reblog(status));
  43. },
  44. renderChildren (list) {
  45. return list.map(s => <EmbeddedStatus status={s} key={s.get('id')} onReply={this.handleReplyClick} onFavourite={this.handleFavouriteClick} onReblog={this.handleReblogClick} />);
  46. },
  47. render () {
  48. const { status, ancestors, descendants } = this.props;
  49. if (status === null) {
  50. return <div>Loading {this.props.params.statusId}...</div>;
  51. }
  52. const account = status.get('account');
  53. return (
  54. <div style={{ overflowY: 'scroll', flex: '1 1 auto' }} className='scrollable'>
  55. <div>{this.renderChildren(ancestors)}</div>
  56. <EmbeddedStatus status={status} onReply={this.handleReplyClick} onFavourite={this.handleFavouriteClick} onReblog={this.handleReblogClick} />
  57. <div>{this.renderChildren(descendants)}</div>
  58. </div>
  59. );
  60. }
  61. });
  62. export default connect(mapStateToProps)(Status);