/**
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */
import React from 'react';
import { Route } from 'react-router-dom';
import ClientLifecyclesDispatcher, { dispatchLifecycleAction, } from './ClientLifecyclesDispatcher';
import ExecutionEnvironment from './exports/ExecutionEnvironment';
import preload from './preload';
class PendingNavigation extends React.Component {
    previousLocation;
    routeUpdateCleanupCb;
    constructor(props) {
        super(props);
        // previousLocation doesn't affect rendering, hence not stored in state.
        this.previousLocation = null;
        this.routeUpdateCleanupCb = ExecutionEnvironment.canUseDOM
            ? dispatchLifecycleAction('onRouteUpdate', {
                previousLocation: null,
                location: this.props.location,
            })
            : () => { };
        this.state = {
            nextRouteHasLoaded: true,
        };
    }
    // Intercept location update and still show current route until next route
    // is done loading.
    shouldComponentUpdate(nextProps, nextState) {
        if (nextProps.location === this.props.location) {
            // `nextRouteHasLoaded` is false means there's a pending route transition.
            // Don't update until it's done.
            return nextState.nextRouteHasLoaded;
        }
        // props.location being different means the router is trying to navigate to
        // a new route. We will preload the new route.
        const nextLocation = nextProps.location;
        // Save the location first.
        this.previousLocation = this.props.location;
        this.setState({ nextRouteHasLoaded: false });
        this.routeUpdateCleanupCb = dispatchLifecycleAction('onRouteUpdate', {
            previousLocation: this.previousLocation,
            location: nextLocation,
        });
        // Load data while the old screen remains. Force preload instead of using
        // `window.docusaurus`, because we want to avoid loading screen even when
        // user is on saveData
        preload(nextLocation.pathname)
            .then(() => {
            this.routeUpdateCleanupCb();
            this.setState({ nextRouteHasLoaded: true });
        })
            .catch((e) => {
            console.warn(e);
            // If chunk loading failed, it could be because the path to a chunk
            // no longer exists due to a new deployment. Force refresh the page
            // instead of just not navigating.
            window.location.reload();
        });
        return false;
    }
    render() {
        const { children, location } = this.props;
        // Use a controlled <Route> to trick all descendants into rendering the old
        // location.
        return (<ClientLifecyclesDispatcher previousLocation={this.previousLocation} location={location}>
        <Route location={location} render={() => children}/>
      </ClientLifecyclesDispatcher>);
    }
}
export default PendingNavigation;
