"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.InfiniteScroll = void 0;
var _tslib = require("tslib");
var _withDefaultProps = require("../../utils/with-default-props");
var _react = _interopRequireWildcard(require("react"));
var _ahooks = require("ahooks");
var _nativeProps = require("../../utils/native-props");
var _getScrollParent = require("../../utils/get-scroll-parent");
var _configProvider = require("../config-provider");
var _dotLoading = _interopRequireDefault(require("../dot-loading"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
function isWindow(element) {
  return element === window;
}
const classPrefix = `adm-infinite-scroll`;
const defaultProps = {
  threshold: 250,
  children: (hasMore, failed, retry) => _react.default.createElement(InfiniteScrollContent, {
    hasMore: hasMore,
    failed: failed,
    retry: retry
  })
};
const InfiniteScroll = p => {
  const props = (0, _withDefaultProps.mergeProps)(defaultProps, p);
  const [failed, setFailed] = (0, _react.useState)(false);
  const doLoadMore = (0, _ahooks.useLockFn)(isRetry => (0, _tslib.__awaiter)(void 0, void 0, void 0, function* () {
    try {
      yield props.loadMore(isRetry);
    } catch (e) {
      setFailed(true);
      throw e;
    }
  }));
  const elementRef = (0, _react.useRef)(null);
  // Prevent duplicated trigger of `check` function
  const [flag, setFlag] = (0, _react.useState)({});
  const nextFlagRef = (0, _react.useRef)(flag);
  const [scrollParent, setScrollParent] = (0, _react.useState)();
  const {
    run: check
  } = (0, _ahooks.useThrottleFn)(() => (0, _tslib.__awaiter)(void 0, void 0, void 0, function* () {
    if (nextFlagRef.current !== flag) return;
    if (!props.hasMore) return;
    const element = elementRef.current;
    if (!element) return;
    if (!element.offsetParent) return;
    const parent = (0, _getScrollParent.getScrollParent)(element);
    setScrollParent(parent);
    if (!parent) return;
    const rect = element.getBoundingClientRect();
    const elementTop = rect.top;
    const current = isWindow(parent) ? window.innerHeight : parent.getBoundingClientRect().bottom;
    if (current >= elementTop - props.threshold) {
      const nextFlag = {};
      nextFlagRef.current = nextFlag;
      try {
        yield doLoadMore(false);
        setFlag(nextFlag);
      } catch (e) {}
    }
  }), {
    wait: 100,
    leading: true,
    trailing: true
  });
  // Make sure to trigger `loadMore` when content changes
  (0, _react.useEffect)(() => {
    check();
  });
  (0, _react.useEffect)(() => {
    const element = elementRef.current;
    if (!element) return;
    if (!scrollParent) return;
    function onScroll() {
      check();
    }
    scrollParent.addEventListener('scroll', onScroll);
    return () => {
      scrollParent.removeEventListener('scroll', onScroll);
    };
  }, [scrollParent]);
  function retry() {
    return (0, _tslib.__awaiter)(this, void 0, void 0, function* () {
      setFailed(false);
      try {
        yield doLoadMore(true);
        setFlag(nextFlagRef.current);
      } catch (e) {}
    });
  }
  return (0, _nativeProps.withNativeProps)(props, _react.default.createElement("div", {
    className: classPrefix,
    ref: elementRef
  }, typeof props.children === 'function' ? props.children(props.hasMore, failed, retry) : props.children));
};
exports.InfiniteScroll = InfiniteScroll;
const InfiniteScrollContent = props => {
  const {
    locale
  } = (0, _configProvider.useConfig)();
  if (!props.hasMore) {
    return _react.default.createElement("span", null, locale.InfiniteScroll.noMore);
  }
  if (props.failed) {
    return _react.default.createElement("span", null, _react.default.createElement("span", {
      className: `${classPrefix}-failed-text`
    }, locale.InfiniteScroll.failedToLoad), _react.default.createElement("a", {
      onClick: () => {
        props.retry();
      }
    }, locale.InfiniteScroll.retry));
  }
  return _react.default.createElement(_react.default.Fragment, null, _react.default.createElement("span", null, locale.common.loading), _react.default.createElement(_dotLoading.default, null));
};