function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
import * as React from 'react';
import { Animated, Easing, Platform, StyleSheet, View } from 'react-native';
import { withTheme } from '../../core/theming';
import color from 'color';
const DURATION = 2400;
const ActivityIndicator = _ref => {
  var _theme$colors;
  let {
    animating = true,
    color: indicatorColor,
    hidesWhenStopped = true,
    size: indicatorSize = 'small',
    style,
    theme,
    ...rest
  } = _ref;
  const {
    current: timer
  } = React.useRef(new Animated.Value(0));
  const {
    current: fade
  } = React.useRef(new Animated.Value(!animating && hidesWhenStopped ? 0 : 1));
  const rotation = React.useRef(undefined);
  const {
    animation: {
      scale
    }
  } = theme;
  const startRotation = React.useCallback(() => {
    // Show indicator
    Animated.timing(fade, {
      duration: 200 * scale,
      toValue: 1,
      isInteraction: false,
      useNativeDriver: true
    }).start();

    // Circular animation in loop
    if (rotation.current) {
      timer.setValue(0);
      // $FlowFixMe
      Animated.loop(rotation.current).start();
    }
  }, [scale, fade, timer]);
  const stopRotation = () => {
    if (rotation.current) {
      rotation.current.stop();
    }
  };
  React.useEffect(() => {
    if (rotation.current === undefined) {
      // Circular animation in loop
      rotation.current = Animated.timing(timer, {
        duration: DURATION,
        easing: Easing.linear,
        // Animated.loop does not work if useNativeDriver is true on web
        useNativeDriver: Platform.OS !== 'web',
        toValue: 1,
        isInteraction: false
      });
    }
    if (animating) {
      startRotation();
    } else if (hidesWhenStopped) {
      // Hide indicator first and then stop rotation
      Animated.timing(fade, {
        duration: 200 * scale,
        toValue: 0,
        useNativeDriver: true,
        isInteraction: false
      }).start(stopRotation);
    } else {
      stopRotation();
    }
  }, [animating, fade, hidesWhenStopped, startRotation, scale, timer]);
  const spinnerColor = indicatorColor || ((_theme$colors = theme.colors) === null || _theme$colors === void 0 ? void 0 : _theme$colors.primary.default);
  const size = typeof indicatorSize === 'string' ? indicatorSize === 'small' ? 24 : 48 : indicatorSize ? indicatorSize : 24;
  const frames = 60 * DURATION / 1000;
  const easing = Easing.bezier(0.4, 0.0, 0.7, 1.0);
  const containerStyle = {
    width: size,
    height: size / 2,
    overflow: 'hidden'
  };
  return /*#__PURE__*/React.createElement(View, _extends({
    style: [styles.container, style]
  }, rest, {
    accessible: true,
    accessibilityRole: "progressbar",
    accessibilityState: {
      busy: animating
    }
  }), /*#__PURE__*/React.createElement(Animated.View, {
    style: [{
      width: size,
      height: size,
      opacity: fade
    }],
    collapsable: false
  }, [0, 1].map(index => {
    var _theme$colors2;
    // Thanks to https://github.com/n4kz/react-native-indicators for the great work
    const inputRange = Array.from(new Array(frames), (_, frameIndex) => frameIndex / (frames - 1));
    const outputRange = Array.from(new Array(frames), (_, frameIndex) => {
      let progress = 2 * frameIndex / (frames - 1);
      const rotation = index ? +(360 - 15) : -(180 - 15);
      if (progress > 1.0) {
        progress = 2.0 - progress;
      }
      const direction = index ? -1 : +1;
      return `${direction * (150 - 30) + rotation}deg`;
    });
    const layerStyle = {
      width: size,
      height: size,
      transform: [{
        rotate: timer.interpolate({
          inputRange: [0, 1],
          outputRange: [`${0 + 30 + 15}deg`, `${2 * 360 + 30 + 15}deg`]
        })
      }]
    };
    const viewportStyle = {
      width: size,
      height: size,
      transform: [{
        translateY: index ? -size / 2 : 0
      }, {
        rotate: timer.interpolate({
          inputRange,
          outputRange
        })
      }]
    };
    const offsetStyle = index ? {
      top: size / 2
    } : null;
    const lineStyle = {
      width: size,
      height: size,
      borderColor: spinnerColor,
      borderWidth: 2,
      borderRadius: size / 2
    };
    const lineStyle2 = {
      width: size,
      height: size,
      borderColor: color(indicatorColor).alpha(0.24).rgb().string() || ((_theme$colors2 = theme.colors) === null || _theme$colors2 === void 0 ? void 0 : _theme$colors2.primary.subtle),
      borderWidth: 2,
      borderRadius: size / 2,
      position: 'absolute',
      zIndex: -1
    };
    return /*#__PURE__*/React.createElement(Animated.View, {
      key: index,
      style: [styles.layer]
    }, /*#__PURE__*/React.createElement(Animated.View, {
      style: layerStyle
    }, /*#__PURE__*/React.createElement(Animated.View, {
      style: [containerStyle, offsetStyle],
      collapsable: false
    }, /*#__PURE__*/React.createElement(Animated.View, {
      style: viewportStyle
    }, /*#__PURE__*/React.createElement(Animated.View, {
      style: containerStyle,
      collapsable: false
    }, /*#__PURE__*/React.createElement(Animated.View, {
      style: lineStyle
    })), /*#__PURE__*/React.createElement(Animated.View, {
      style: lineStyle2
    })))));
  })));
};
const styles = StyleSheet.create({
  container: {
    justifyContent: 'center',
    alignItems: 'center'
  },
  layer: {
    ...StyleSheet.absoluteFillObject,
    justifyContent: 'center',
    alignItems: 'center'
  }
});
export default withTheme(ActivityIndicator);
//# sourceMappingURL=Spinner.js.map