function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }

function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }

import React, { useRef, forwardRef, useImperativeHandle, isValidElement, useContext } from 'react';
import clsx from 'clsx';
import Loading from '../loading';
import { getRect } from '../hooks/use-rect';
import useScrollParent from '../hooks/use-scroll-parent';
import useEventListener from '../hooks/use-event-listener';
import { isHidden } from '../utils';
import { useSetState, useUpdateEffect } from '../hooks';
import ConfigProviderContext from '../config-provider/ConfigProviderContext';
var List = /*#__PURE__*/forwardRef(function (props, ref) {
  var _useContext = useContext(ConfigProviderContext),
      prefixCls = _useContext.prefixCls,
      createNamespace = _useContext.createNamespace,
      locale = _useContext.locale;

  var _createNamespace = createNamespace('list', prefixCls),
      bem = _createNamespace[0];

  var _useSetState = useSetState({
    loading: props.loading,
    error: props.error
  }),
      state = _useSetState[0],
      updateState = _useSetState[1];

  var root = useRef();
  var scrollParent = useRef(null);
  var placeholder = useRef();
  scrollParent.current = useScrollParent(root); // 判断是否需要加载

  var check = /*#__PURE__*/function () {
    var _ref = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee() {
      var offset, direction, scrollParentRect, isReachEdge, placeholderRect;
      return regeneratorRuntime.wrap(function _callee$(_context) {
        while (1) {
          switch (_context.prev = _context.next) {
            case 0:
              if (props.onLoad) {
                _context.next = 2;
                break;
              }

              return _context.abrupt("return");

            case 2:
              if (!(state.loading || props.finished || state.error)) {
                _context.next = 4;
                break;
              }

              return _context.abrupt("return");

            case 4:
              offset = props.offset, direction = props.direction;
              scrollParentRect = getRect(scrollParent.current);

              if (!(!scrollParentRect.height || isHidden(root.current))) {
                _context.next = 8;
                break;
              }

              return _context.abrupt("return");

            case 8:
              isReachEdge = false;
              placeholderRect = getRect(placeholder.current);

              if (direction === 'up') {
                isReachEdge = scrollParentRect.top - placeholderRect.top <= offset;
              } else {
                isReachEdge = placeholderRect.bottom - scrollParentRect.bottom <= offset;
              }

              if (!isReachEdge) {
                _context.next = 24;
                break;
              }

              _context.prev = 12;
              updateState({
                loading: true
              });

              if (!props.onLoad) {
                _context.next = 17;
                break;
              }

              _context.next = 17;
              return props.onLoad();

            case 17:
              updateState({
                loading: false
              });
              _context.next = 24;
              break;

            case 20:
              _context.prev = 20;
              _context.t0 = _context["catch"](12);
              // eslint-disable-next-line no-console
              console.warn('onLoad error:', _context.t0);
              updateState({
                loading: false,
                error: true
              });

            case 24:
            case "end":
              return _context.stop();
          }
        }
      }, _callee, null, [[12, 20]]);
    }));

    return function check() {
      return _ref.apply(this, arguments);
    };
  }();

  var renderFinishedText = function renderFinishedText() {
    if (props.finished && props.finishedText) {
      return /*#__PURE__*/React.createElement("div", {
        className: clsx(bem('finished-text'))
      }, props.finishedText);
    }

    return null;
  };

  var clickErrorText = function clickErrorText() {
    updateState({
      error: false
    });
    check();
  };

  var renderErrorText = function renderErrorText() {
    if (state.error && props.errorText) {
      return /*#__PURE__*/React.createElement("div", {
        className: clsx(bem('error-text')),
        onClick: clickErrorText
      }, props.errorText);
    }

    return null;
  };

  var renderLoading = function renderLoading() {
    if (state.loading && !props.finished) {
      return /*#__PURE__*/React.createElement("div", {
        className: clsx(bem('loading'))
      }, /*#__PURE__*/isValidElement(props.loadingText) ? props.loadingText : /*#__PURE__*/React.createElement(Loading, {
        className: clsx(bem('loading-icon')),
        size: 16
      }, props.loadingText || locale.loading));
    }

    return null;
  };

  useUpdateEffect(function () {
    if (props.autoCheck) {
      check();
    }
  }, [state.loading, props.finished, props.error]);
  useUpdateEffect(function () {
    updateState({
      loading: props.loading,
      error: props.error
    });
  }, [props.loading, props.error]);
  useUpdateEffect(function () {
    if (scrollParent.current && props.immediateCheck) {
      check();
    }
  }, [scrollParent.current]);
  useEventListener('scroll', check, {
    target: scrollParent.current,
    depends: [state.loading, props.finished, state.error]
  });
  useImperativeHandle(ref, function () {
    return {
      check: check,
      state: state
    };
  });
  var Placeholder = /*#__PURE__*/React.createElement("div", {
    ref: placeholder,
    className: clsx(bem('placeholder'))
  });
  return /*#__PURE__*/React.createElement("div", {
    ref: root,
    role: "feed",
    className: clsx(bem(), props.className),
    style: props.style,
    "aria-busy": state.loading
  }, props.direction === 'down' ? props.children : Placeholder, renderLoading(), renderFinishedText(), renderErrorText(), props.direction === 'up' ? props.children : Placeholder);
});
List.defaultProps = {
  offset: 300,
  direction: 'down',
  immediateCheck: true,
  autoCheck: true
};
export default List;