闭社主体 forked from https://github.com/tootsuite/mastodon
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.

90 lines
2.6 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 Column from '../ui/components/column';
  5. import {
  6. refreshNotifications,
  7. expandNotifications
  8. } from '../../actions/notifications';
  9. import NotificationContainer from './containers/notification_container';
  10. import { ScrollContainer } from 'react-router-scroll';
  11. import { defineMessages, injectIntl } from 'react-intl';
  12. import ColumnSettingsContainer from './containers/column_settings_container';
  13. import { createSelector } from 'reselect';
  14. import Immutable from 'immutable';
  15. const messages = defineMessages({
  16. title: { id: 'column.notifications', defaultMessage: 'Notifications' }
  17. });
  18. const getNotifications = createSelector([
  19. state => Immutable.List(state.getIn(['notifications', 'settings', 'shows']).filter(item => !item).keys()),
  20. state => state.getIn(['notifications', 'items'])
  21. ], (excludedTypes, notifications) => notifications.filterNot(item => excludedTypes.includes(item.get('type'))));
  22. const mapStateToProps = state => ({
  23. notifications: getNotifications(state)
  24. });
  25. const Notifications = React.createClass({
  26. propTypes: {
  27. notifications: ImmutablePropTypes.list.isRequired,
  28. dispatch: React.PropTypes.func.isRequired,
  29. trackScroll: React.PropTypes.bool,
  30. intl: React.PropTypes.object.isRequired
  31. },
  32. getDefaultProps () {
  33. return {
  34. trackScroll: true
  35. };
  36. },
  37. mixins: [PureRenderMixin],
  38. componentWillMount () {
  39. const { dispatch } = this.props;
  40. dispatch(refreshNotifications());
  41. },
  42. handleScroll (e) {
  43. const { scrollTop, scrollHeight, clientHeight } = e.target;
  44. if (scrollTop === scrollHeight - clientHeight) {
  45. this.props.dispatch(expandNotifications());
  46. }
  47. },
  48. render () {
  49. const { intl, notifications, trackScroll } = this.props;
  50. const scrollableArea = (
  51. <div className='scrollable' onScroll={this.handleScroll}>
  52. <div>
  53. {notifications.map(item => <NotificationContainer key={item.get('id')} notification={item} accountId={item.get('account')} />)}
  54. </div>
  55. </div>
  56. );
  57. if (trackScroll) {
  58. return (
  59. <Column icon='bell' heading={intl.formatMessage(messages.title)}>
  60. <ScrollContainer scrollKey='notifications'>
  61. {scrollableArea}
  62. </ScrollContainer>
  63. </Column>
  64. );
  65. } else {
  66. return (
  67. <Column icon='bell' heading={intl.formatMessage(messages.title)}>
  68. <ColumnSettingsContainer />
  69. {scrollableArea}
  70. </Column>
  71. );
  72. }
  73. }
  74. });
  75. export default connect(mapStateToProps)(injectIntl(Notifications));