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.

103 lines
2.7 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 StatusList from '../../components/status_list';
  5. import Column from '../ui/components/column';
  6. import Immutable from 'immutable';
  7. import { selectStatus } from '../../reducers/timelines';
  8. import {
  9. updateTimeline,
  10. refreshTimeline,
  11. expandTimeline
  12. } from '../../actions/timelines';
  13. import { deleteStatus } from '../../actions/statuses';
  14. import { replyCompose } from '../../actions/compose';
  15. import {
  16. favourite,
  17. reblog,
  18. unreblog,
  19. unfavourite
  20. } from '../../actions/interactions';
  21. function selectStatuses(state) {
  22. return state.getIn(['timelines', 'public'], Immutable.List()).map(id => selectStatus(state, id)).filterNot(status => status === null);
  23. };
  24. const mapStateToProps = (state) => ({
  25. statuses: selectStatuses(state),
  26. me: state.getIn(['timelines', 'me'])
  27. });
  28. const PublicTimeline = React.createClass({
  29. propTypes: {
  30. statuses: ImmutablePropTypes.list.isRequired,
  31. me: React.PropTypes.number.isRequired,
  32. dispatch: React.PropTypes.func.isRequired
  33. },
  34. mixins: [PureRenderMixin],
  35. componentWillMount () {
  36. const { dispatch } = this.props;
  37. dispatch(refreshTimeline('public'));
  38. if (typeof App !== 'undefined') {
  39. this.subscription = App.cable.subscriptions.create('PublicChannel', {
  40. received (data) {
  41. dispatch(updateTimeline('public', JSON.parse(data.message)));
  42. }
  43. });
  44. }
  45. },
  46. componentWillUnmount () {
  47. if (typeof this.subscription !== 'undefined') {
  48. this.subscription.unsubscribe();
  49. }
  50. },
  51. handleReply (status) {
  52. this.props.dispatch(replyCompose(status));
  53. },
  54. handleReblog (status) {
  55. if (status.get('reblogged')) {
  56. this.props.dispatch(unreblog(status));
  57. } else {
  58. this.props.dispatch(reblog(status));
  59. }
  60. },
  61. handleFavourite (status) {
  62. if (status.get('favourited')) {
  63. this.props.dispatch(unfavourite(status));
  64. } else {
  65. this.props.dispatch(favourite(status));
  66. }
  67. },
  68. handleDelete (status) {
  69. this.props.dispatch(deleteStatus(status.get('id')));
  70. },
  71. handleScrollToBottom () {
  72. this.props.dispatch(expandTimeline('public'));
  73. },
  74. render () {
  75. const { statuses, me } = this.props;
  76. return (
  77. <Column icon='globe' heading='Public'>
  78. <StatusList statuses={statuses} me={me} onScrollToBottom={this.handleScrollToBottom} onReply={this.handleReply} onReblog={this.handleReblog} onFavourite={this.handleFavourite} onDelete={this.handleDelete} />
  79. </Column>
  80. );
  81. },
  82. });
  83. export default connect(mapStateToProps)(PublicTimeline);