{"size": 1896, "ext": "js", "max_stars_repo_path": "src/components/MessageList.js", "max_stars_repo_name": "indutny/vowlink-electron", "max_stars_repo_stars_event_min_datetime": "2019-09-17T12:21:29.000Z", "max_stars_repo_stars_event_max_datetime": "2021-04-07T08:39:33.000Z", "max_issues_repo_path": "src/components/MessageList.js", "max_issues_repo_name": "indutny/vowlink-electron", "max_issues_repo_issues_event_min_datetime": "2019-09-17T18:00:21.000Z", "max_issues_repo_issues_event_max_datetime": "2022-02-18T09:13:26.000Z", "max_forks_repo_path": "src/components/MessageList.js", "max_forks_repo_name": "indutny/vowlink-electron", "max_forks_repo_forks_event_min_datetime": "2019-09-17T18:53:13.000Z", "max_forks_repo_forks_event_max_datetime": "2021-12-30T18:32:59.000Z"}
{"max_stars_count": 26, "max_issues_count": 29, "max_forks_count": 8, "avg_line_length": 25.28, "max_line_length": 77, "alphanum_fraction": 0.6703586498}
import React, { useState, useRef, useEffect } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';

import Message from './Message';

import './MessageList.css';

const MessageList = React.memo(function MessageList(props) {
  const { channelName, readHeight, messages, isSticky, setIsSticky } = props;

  const [ expandAuthorFor, setExpandAuthorFor ] = useState(null);
  const view = useRef();

  useEffect(() => {
    if (isSticky && view.current) {
      const elem = view.current;
      elem.scrollTo({
        top: elem.scrollHeight - elem.clientHeight,
        left: 0,
      });
    }
  });

  const rows = messages.map((message) => {
    const isExpanded = expandAuthorFor === message.hash;

    return <Message
      channelName={channelName}
      message={message}
      key={message.hash}
      isExpanded={isExpanded}
      setExpandAuthorFor={setExpandAuthorFor}/>;
  });

  const marker = messages.findIndex((message) => {
    return message.height > readHeight;
  });

  if (marker > 0) {
    rows.splice(marker, 0, <hr key='unread-marker'/>);
  }

  const onScroll = ({ target }) => {
    const scrollTop = target.scrollTop;
    const maxScrollTop = target.scrollHeight - target.clientHeight;

    // Scroll to the bottom
    setIsSticky(scrollTop === maxScrollTop);
  };

  return <div className='message-list' onScroll={onScroll} ref={view}>
    {rows}
  </div>;
});

MessageList.propTypes = {
  channelName: PropTypes.string.isRequired,
  readHeight: PropTypes.number.isRequired,
  messages: PropTypes.arrayOf(PropTypes.shape({
    hash: PropTypes.string.isRequired,
    height: PropTypes.number.isRequired,
  })),
  isSticky: PropTypes.bool.isRequired,
  setIsSticky: PropTypes.func.isRequired,
};

const mapStateToProps = (state) => {
  return {
    channels: state.channels,
  };
};

export default connect(mapStateToProps)(MessageList);
