<commit_before>/**
 * @file PageLoading component
 * @author chao(<EMAIL>)
 */

import React, {Component} from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import CSSTransition from 'react-transition-group/CSSTransition';

class PageLoading extends Component {

    constructor(props, ...restArgs) {

        super(props, ...restArgs);

        this.progressTimeout = null;

        this.finishDuration = 100;

        this.defaultHighlightStyle = {
            width: 0,
            transition: 'width 0s'
        };

        this.state = {
            highlightStyle: this.defaultHighlightStyle
        };

        this.setLoading = ::this.setLoading;
        this.clearProgress = ::this.clearProgress;
        this.enterHandler = ::this.enterHandler;
        this.exitHandler = ::this.exitHandler;

    }

    setLoading(progress = this.props.loadingProgress, index = 0) {

        const {width, timeout} = progress[index],
            highlightStyle = {};

        highlightStyle.width = width + '%';
        highlightStyle.transition = 'width ' + timeout + 'ms linear 0ms';

        this.setState({
            highlightStyle
        }, () => {
            if (index < progress.length - 1) {
                this.clearProgress();
                this.progressTimeout = setTimeout(() => {
                    this.setLoading(progress, index + 1);
                }, width === 100 ? 0 : timeout);
            }
        });

    }

    clearProgress() {
        this.progressTimeout && clearTimeout(this.progressTimeout);
    }

    enterHandler() {
        this.clearProgress();
        this.setState({
            highlightStyle: this.defaultHighlightStyle
        }, () => {
            this.setLoading();
        });
    }

    exitHandler() {
        this.clearProgress();
        this.setLoading([{
            width: 100,
            timeout: this.finishDuration
        }]);
    }

    componentWillUnmonut() {
        this.clearProgress();
    }

    render() {

        const {className, style, visible, duration, showStripes} = this.props,
            {highlightStyle} = this.state,

            loadingClassName = classNames('page-loading', {
                striped: showStripes,
                [className]: className
            });

        return (
            <CSSTransition in={visible}
                           timeout={{exit: duration + this.finishDuration}}
                           classNames="page-loading"
                           onEnter={this.enterHandler}
                           onExit={this.exitHandler}>

                <div className={loadingClassName}
                     style={style}>
                    <div className="page-loading-bar"
                         style={highlightStyle}></div>
                </div>

            </CSSTransition>
        );

    }
};

PageLoading.propTypes = {

    className: PropTypes.string,
    style: PropTypes.object,

    visible: PropTypes.bool,
    duration: PropTypes.number,
    showStripes: PropTypes.bool,

    loadingProgress: PropTypes.arrayOf(PropTypes.shape({
        width: PropTypes.number,
        timeout: PropTypes.number
    }))

};

PageLoading.defaultProps = {

    className: null,
    style: null,

    visible: false,
    duration: 250,
    showStripes: true,

    loadingProgress: [{
        width: 0,
        timeout: 0
    }, {
        width: 50,
        timeout: 200
    }, {
        width: 80,
        timeout: 2000
    }, {
        width: 90,
        timeout: 2500
    }, {
        width: 95,
        timeout: 25000
    }]

};<commit_msg>update PageLoading<commit_after>/**
 * @file PageLoading component
 * @author chao(<EMAIL>)
 */

import React, {Component} from 'react';
import classNames from 'classnames';
import CSSTransition from 'react-transition-group/CSSTransition';

import PureRender from '../_vendors/PureRender';

@PureRender
class PageLoading extends Component {

    constructor(props, ...restArgs) {

        super(props, ...restArgs);

        this.progressTimeout = null;

        this.finishDuration = 100;

        this.defaultHighlightStyle = {
            width: 0,
            transition: 'width 0s'
        };

        this.state = {
            highlightStyle: this.defaultHighlightStyle
        };

        this.setLoading = ::this.setLoading;
        this.clearProgress = ::this.clearProgress;
        this.enterHandler = ::this.enterHandler;
        this.exitHandler = ::this.exitHandler;

    }

    setLoading(progress = this.props.loadingProgress, index = 0) {

        const {width, timeout} = progress[index],
            highlightStyle = {};

        highlightStyle.width = width + '%';
        highlightStyle.transition = 'width ' + timeout + 'ms linear 0ms';

        this.setState({
            highlightStyle
        }, () => {
            if (index < progress.length - 1) {
                this.clearProgress();
                this.progressTimeout = setTimeout(() => {
                    this.setLoading(progress, index + 1);
                }, width === 100 ? 0 : timeout);
            }
        });

    }

    clearProgress() {
        this.progressTimeout && clearTimeout(this.progressTimeout);
    }

    enterHandler() {
        this.clearProgress();
        this.setState({
            highlightStyle: this.defaultHighlightStyle
        }, () => {
            this.setLoading();
        });
    }

    exitHandler() {
        this.clearProgress();
        this.setLoading([{
            width: 100,
            timeout: this.finishDuration
        }]);
    }

    componentWillUnmonut() {
        this.clearProgress();
    }

    render() {

        const {className, style, visible, duration, showStripes} = this.props,
            {highlightStyle} = this.state,

            loadingClassName = classNames('page-loading', {
                striped: showStripes,
                [className]: className
            });

        return (
            <CSSTransition in={visible}
                           timeout={{exit: duration + this.finishDuration}}
                           classNames="page-loading"
                           onEnter={this.enterHandler}
                           onExit={this.exitHandler}>

                <div className={loadingClassName}
                     style={style}>
                    <div className="page-loading-bar"
                         style={highlightStyle}></div>
                </div>

            </CSSTransition>
        );

    }
};

if (process.env.NODE_ENV === 'development') {

    const PropTypes = require('prop-types');

    PageLoading.propTypes = {

        className: PropTypes.string,
        style: PropTypes.object,

        visible: PropTypes.bool,
        duration: PropTypes.number,
        showStripes: PropTypes.bool,

        loadingProgress: PropTypes.arrayOf(PropTypes.shape({
            width: PropTypes.number,
            timeout: PropTypes.number
        }))

    };

}

PageLoading.defaultProps = {

    visible: false,
    duration: 250,
    showStripes: true,

    loadingProgress: [{
        width: 0,
        timeout: 0
    }, {
        width: 50,
        timeout: 200
    }, {
        width: 80,
        timeout: 2000
    }, {
        width: 90,
        timeout: 2500
    }, {
        width: 95,
        timeout: 25000
    }]

};
{'fraction_non_alphanumeric': 0.11676237353021603, 'fraction_numerical': 0.012305168170631665, 'mean_word_length': 1.6775256222547583, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6062361', 'n_tokens_mistral': 2051, 'n_tokens_neox': 1878, 'n_words': 374}