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.

114 lines
3.2 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. getFeaturedStatusCount = () => {
  28. return this.props.featuredStatusIds ? this.props.featuredStatusIds.size : 0;
  29. }
  30. getCurrentStatusIndex = (id, featured) => {
  31. if (featured) {
  32. return this.props.featuredStatusIds.indexOf(id);
  33. } else {
  34. return this.props.statusIds.indexOf(id) + this.getFeaturedStatusCount();
  35. }
  36. }
  37. handleMoveUp = (id, featured) => {
  38. const elementIndex = this.getCurrentStatusIndex(id, featured) - 1;
  39. this._selectChild(elementIndex);
  40. }
  41. handleMoveDown = (id, featured) => {
  42. const elementIndex = this.getCurrentStatusIndex(id, featured) + 1;
  43. this._selectChild(elementIndex);
  44. }
  45. _selectChild (index) {
  46. const element = this.node.node.querySelector(`article:nth-of-type(${index + 1}) .focusable`);
  47. if (element) {
  48. element.focus();
  49. }
  50. }
  51. setRef = c => {
  52. this.node = c;
  53. }
  54. render () {
  55. const { statusIds, featuredStatusIds, ...other } = this.props;
  56. const { isLoading, isPartial } = other;
  57. if (isPartial) {
  58. return (
  59. <div className='regeneration-indicator'>
  60. <div>
  61. <div className='regeneration-indicator__figure' />
  62. <div className='regeneration-indicator__label'>
  63. <FormattedMessage id='regeneration_indicator.label' tagName='strong' defaultMessage='Loading&hellip;' />
  64. <FormattedMessage id='regeneration_indicator.sublabel' defaultMessage='Your home feed is being prepared!' />
  65. </div>
  66. </div>
  67. </div>
  68. );
  69. }
  70. let scrollableContent = (isLoading || statusIds.size > 0) ? (
  71. statusIds.map(statusId => (
  72. <StatusContainer
  73. key={statusId}
  74. id={statusId}
  75. onMoveUp={this.handleMoveUp}
  76. onMoveDown={this.handleMoveDown}
  77. />
  78. ))
  79. ) : null;
  80. if (scrollableContent && featuredStatusIds) {
  81. scrollableContent = featuredStatusIds.map(statusId => (
  82. <StatusContainer
  83. key={`f-${statusId}`}
  84. id={statusId}
  85. featured
  86. onMoveUp={this.handleMoveUp}
  87. onMoveDown={this.handleMoveDown}
  88. />
  89. )).concat(scrollableContent);
  90. }
  91. return (
  92. <ScrollableList {...other} ref={this.setRef}>
  93. {scrollableContent}
  94. </ScrollableList>
  95. );
  96. }
  97. }