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.

102 lines
2.8 KiB

  1. import React from 'react';
  2. import ImmutablePropTypes from 'react-immutable-proptypes';
  3. import PropTypes from 'prop-types';
  4. import StatusContainer from 'flavours/glitch/containers/status_container';
  5. import ImmutablePureComponent from 'react-immutable-pure-component';
  6. import ScrollableList from './scrollable_list';
  7. import { FormattedMessage } from 'react-intl';
  8. export default class StatusList extends ImmutablePureComponent {
  9. static propTypes = {
  10. scrollKey: PropTypes.string.isRequired,
  11. statusIds: ImmutablePropTypes.list.isRequired,
  12. featuredStatusIds: ImmutablePropTypes.list,
  13. onScrollToBottom: PropTypes.func,
  14. onScrollToTop: PropTypes.func,
  15. onScroll: PropTypes.func,
  16. trackScroll: PropTypes.bool,
  17. shouldUpdateScroll: PropTypes.func,
  18. isLoading: PropTypes.bool,
  19. isPartial: PropTypes.bool,
  20. hasMore: PropTypes.bool,
  21. prepend: PropTypes.node,
  22. emptyMessage: PropTypes.node,
  23. };
  24. static defaultProps = {
  25. trackScroll: true,
  26. };
  27. handleMoveUp = id => {
  28. const elementIndex = this.props.statusIds.indexOf(id) - 1;
  29. this._selectChild(elementIndex);
  30. }
  31. handleMoveDown = id => {
  32. const elementIndex = this.props.statusIds.indexOf(id) + 1;
  33. this._selectChild(elementIndex);
  34. }
  35. _selectChild (index) {
  36. const element = this.node.node.querySelector(`article:nth-of-type(${index + 1}) .focusable`);
  37. if (element) {
  38. element.focus();
  39. }
  40. }
  41. setRef = c => {
  42. this.node = c;
  43. }
  44. render () {
  45. const { statusIds, featuredStatusIds, ...other } = this.props;
  46. const { isLoading, isPartial } = other;
  47. if (isPartial) {
  48. return (
  49. <div className='regeneration-indicator'>
  50. <div>
  51. <div className='regeneration-indicator__figure' />
  52. <div className='regeneration-indicator__label'>
  53. <FormattedMessage id='regeneration_indicator.label' tagName='strong' defaultMessage='Loading&hellip;' />
  54. <FormattedMessage id='regeneration_indicator.sublabel' defaultMessage='Your home feed is being prepared!' />
  55. </div>
  56. </div>
  57. </div>
  58. );
  59. }
  60. let scrollableContent = (isLoading || statusIds.size > 0) ? (
  61. statusIds.map(statusId => (
  62. <StatusContainer
  63. key={statusId}
  64. id={statusId}
  65. onMoveUp={this.handleMoveUp}
  66. onMoveDown={this.handleMoveDown}
  67. />
  68. ))
  69. ) : null;
  70. if (scrollableContent && featuredStatusIds) {
  71. scrollableContent = featuredStatusIds.map(statusId => (
  72. <StatusContainer
  73. key={`f-${statusId}`}
  74. id={statusId}
  75. featured
  76. onMoveUp={this.handleMoveUp}
  77. onMoveDown={this.handleMoveDown}
  78. />
  79. )).concat(scrollableContent);
  80. }
  81. return (
  82. <ScrollableList {...other} ref={this.setRef}>
  83. {scrollableContent}
  84. </ScrollableList>
  85. );
  86. }
  87. }