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.

75 lines
2.2 KiB

  1. import React from 'react';
  2. import PropTypes from 'prop-types';
  3. import ImmutablePropTypes from 'react-immutable-proptypes';
  4. import ImmutablePureComponent from 'react-immutable-pure-component';
  5. import ConversationContainer from '../containers/conversation_container';
  6. import ScrollableList from '../../../components/scrollable_list';
  7. import { debounce } from 'lodash';
  8. export default class ConversationsList extends ImmutablePureComponent {
  9. static propTypes = {
  10. conversations: ImmutablePropTypes.list.isRequired,
  11. scrollKey: PropTypes.string.isRequired,
  12. hasMore: PropTypes.bool,
  13. isLoading: PropTypes.bool,
  14. onLoadMore: PropTypes.func,
  15. };
  16. getCurrentIndex = id => this.props.conversations.findIndex(x => x.get('id') === id)
  17. handleMoveUp = id => {
  18. const elementIndex = this.getCurrentIndex(id) - 1;
  19. this._selectChild(elementIndex, true);
  20. }
  21. handleMoveDown = id => {
  22. const elementIndex = this.getCurrentIndex(id) + 1;
  23. this._selectChild(elementIndex, false);
  24. }
  25. _selectChild (index, align_top) {
  26. const container = this.node.node;
  27. const element = container.querySelector(`article:nth-of-type(${index + 1}) .focusable`);
  28. if (element) {
  29. if (align_top && container.scrollTop > element.offsetTop) {
  30. element.scrollIntoView(true);
  31. } else if (!align_top && container.scrollTop + container.clientHeight < element.offsetTop + element.offsetHeight) {
  32. element.scrollIntoView(false);
  33. }
  34. element.focus();
  35. }
  36. }
  37. setRef = c => {
  38. this.node = c;
  39. }
  40. handleLoadOlder = debounce(() => {
  41. const last = this.props.conversations.last();
  42. if (last && last.get('last_status')) {
  43. this.props.onLoadMore(last.get('last_status'));
  44. }
  45. }, 300, { leading: true })
  46. render () {
  47. const { conversations, onLoadMore, ...other } = this.props;
  48. return (
  49. <ScrollableList {...other} onLoadMore={onLoadMore && this.handleLoadOlder} ref={this.setRef}>
  50. {conversations.map(item => (
  51. <ConversationContainer
  52. key={item.get('id')}
  53. conversationId={item.get('id')}
  54. onMoveUp={this.handleMoveUp}
  55. onMoveDown={this.handleMoveDown}
  56. scrollKey={this.props.scrollKey}
  57. />
  58. ))}
  59. </ScrollableList>
  60. );
  61. }
  62. }