"use strict";

require("core-js/modules/web.dom.iterable");

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = exports.routes = void 0;

var _auth0React = require("@auth0/auth0-react");

var _connectedReactRouter = require("connected-react-router");

var _history = require("history");

var _lodash = _interopRequireDefault(require("lodash.isequal"));

var _coreUtils = _interopRequireDefault(require("@opentripplanner/core-utils"));

var _propTypes = _interopRequireDefault(require("prop-types"));

var _qs = _interopRequireDefault(require("qs"));

var _react = _interopRequireWildcard(require("react"));

var _reactBootstrap = require("react-bootstrap");

var _reactIntl = require("react-intl");

var _reactRedux = require("react-redux");

var _reactRouter = require("react-router");

var authActions = _interopRequireWildcard(require("../../actions/auth"));

var callTakerActions = _interopRequireWildcard(require("../../actions/call-taker"));

var configActions = _interopRequireWildcard(require("../../actions/config"));

var formActions = _interopRequireWildcard(require("../../actions/form"));

var locationActions = _interopRequireWildcard(require("../../actions/location"));

var mapActions = _interopRequireWildcard(require("../../actions/map"));

var uiActions = _interopRequireWildcard(require("../../actions/ui"));

var _printFieldTripLayout = _interopRequireDefault(require("../admin/print-field-trip-layout"));

var _appFrame = require("../app/app-frame");

var _connectedLinks = require("../form/connected-links");

var _map2 = _interopRequireDefault(require("../map/map"));

var _main = _interopRequireDefault(require("../mobile/main"));

var _auth2 = require("../../util/auth");

var _constants = require("../../util/constants");

var _contexts = require("../../util/contexts");

var _i18n = require("../../util/i18n");

var _state = require("../../util/state");

var _afterSigninScreen = _interopRequireDefault(require("../user/after-signin-screen"));

var _beforeSigninScreen = _interopRequireDefault(require("../user/before-signin-screen"));

var _favoritePlaceScreen = _interopRequireDefault(require("../user/places/favorite-place-screen"));

var _savedTripList = _interopRequireDefault(require("../user/monitored-trip/saved-trip-list"));

var _savedTripScreen = _interopRequireDefault(require("../user/monitored-trip/saved-trip-screen"));

var _userAccountScreen = _interopRequireDefault(require("../user/user-account-screen"));

var _withLoggedInUserSupport = _interopRequireDefault(require("../user/with-logged-in-user-support"));

var _printLayout = _interopRequireDefault(require("./print-layout"));

var _desktopNav = _interopRequireDefault(require("./desktop-nav"));

function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _extends() { _extends = Object.assign || 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); }

function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }

const {
  isMobile
} = _coreUtils.default.ui;

class ResponsiveWebapp extends _react.Component {
  constructor(...args) {
    super(...args);

    _defineProperty(this, "renderDesktopView", () => {
      const {
        MainControls,
        MainPanel,
        MapWindows
      } = this.context;
      return /*#__PURE__*/_react.default.createElement("div", {
        className: "otp"
      }, /*#__PURE__*/_react.default.createElement(_desktopNav.default, null), /*#__PURE__*/_react.default.createElement(_reactBootstrap.Grid, null, /*#__PURE__*/_react.default.createElement(_reactBootstrap.Row, {
        className: "main-row"
      }, /*#__PURE__*/_react.default.createElement(_reactBootstrap.Col, {
        className: "sidebar",
        md: 4,
        sm: 6
      }, /*#__PURE__*/_react.default.createElement("main", null, /*#__PURE__*/_react.default.createElement(MainPanel, null))), MainControls && /*#__PURE__*/_react.default.createElement(MainControls, null), /*#__PURE__*/_react.default.createElement(_reactBootstrap.Col, {
        className: "map-container",
        md: 8,
        sm: 6
      }, MapWindows && /*#__PURE__*/_react.default.createElement(MapWindows, null), /*#__PURE__*/_react.default.createElement(_map2.default, null)))));
    });

    _defineProperty(this, "renderMobileView", () => {
      return (
        /*#__PURE__*/
        // <main> Needed for accessibility checks. TODO: Find a better place.
        _react.default.createElement("main", null, /*#__PURE__*/_react.default.createElement(_main.default, null))
      );
    });
  }

  /** Lifecycle methods **/

  /* eslint-disable-next-line complexity */
  componentDidUpdate(prevProps) {
    const {
      activeSearchId,
      currentPosition,
      formChanged,
      initZoomOnLocate,
      location,
      matchContentToUrl,
      query,
      setLocale,
      setLocationToCurrent,
      setMapCenter,
      setMapZoom,
      title
    } = this.props;
    document.title = title;

    const urlParams = _coreUtils.default.query.getUrlParams();

    const newSearchId = urlParams.ui_activeSearch; // Determine if trip is being replanned by checking the active search ID
    // against the ID found in the URL params. If they are different, a new one
    // has been routed to (see handleBackButtonPress) and there is no need to
    // trigger a form change because necessarily the query will be different
    // from the previous query.

    const replanningTrip = newSearchId && activeSearchId && newSearchId !== activeSearchId;

    if (!(0, _lodash.default)(prevProps.query, query) && !replanningTrip) {
      // Trigger on form change action if previous query is different from
      // current one AND trip is not being replanned already. This will
      // determine whether a search needs to be made, the mobile view needs
      // updating, etc.
      formChanged(prevProps.query, query);
    } // check if device position changed (typically only set once, on initial page load)


    if (currentPosition !== prevProps.currentPosition) {
      if (currentPosition.error || !currentPosition.coords) return;
      const pt = {
        lat: currentPosition.coords.latitude,
        lon: currentPosition.coords.longitude
      }; // if in mobile mode and from field is not set, use current location as from and recenter map

      if (isMobile() && query.from === null) {
        setLocationToCurrent({
          locationType: 'from'
        });
        setMapCenter(pt);

        if (initZoomOnLocate) {
          setMapZoom({
            zoom: initZoomOnLocate
          });
        }
      }
    } // If the path changes (e.g., via a back button press) check whether the
    // main content needs to switch between, for example, a viewer and a search.


    if (!(0, _lodash.default)(location.pathname, prevProps.location.pathname)) {
      // console.log('url changed to', location.pathname)
      matchContentToUrl(location);
    } // If the URL locale parameter changes or is initially blank, (e.g., user modifies anything after ?, e.g. locale)
    // update the corresponding redux state.


    if (!urlParams.locale && !prevProps.locale || urlParams.locale && urlParams.locale !== prevProps.locale) {
      setLocale(urlParams.locale);
    } // Check for change between ITINERARY and PROFILE routingTypes
    // TODO: restore this for profile mode

    /* if (query.routingType !== nextProps.query.routingType) {
      let queryModes = nextProps.query.mode.split(',')
      // If we are entering 'ITINERARY' mode, ensure that one and only one access mode is selected
      if (nextProps.query.routingType === 'ITINERARY') {
        queryModes = ensureSingleAccessMode(queryModes)
        this.props.setQueryParam({ mode: queryModes.join(',') })
      }
      // If we are entering 'PROFILE' mode, ensure that CAR_HAIL is not selected
      // TODO: make this more generic, i.e. introduce concept of mode->routingType permissions
      if (nextProps.query.routingType === 'ITINERARY') {
        queryModes = queryModes.filter(mode => mode !== 'CAR_HAIL')
        this.props.setQueryParam({ mode: queryModes.join(',') })
      }
    } */

  }

  componentDidMount() {
    const {
      getCurrentPosition,
      handleBackButtonPress,
      initializeModules,
      location,
      matchContentToUrl,
      parseUrlQueryString,
      receivedPositionResponse,
      title
    } = this.props; // Add on back button press behavior.

    window.addEventListener('popstate', handleBackButtonPress);
    document.title = title; // If a URL is detected without hash routing (e.g., http://localhost:9966?sessionId=test),
    // window.location.search will have a value. In this case, we need to redirect to the URL root with the
    // search reconstructed for use with the hash router.
    // Exception: Do not redirect after auth0 login, which sets the URL in the form
    // http://localhost:9966/?code=xxxxxxx&state=yyyyyyyyy that we want to preserve.

    const search = window.location.search;

    if (search) {
      const searchParams = _qs.default.parse(search, {
        ignoreQueryPrefix: true
      });

      if (!(searchParams.code && searchParams.state)) {
        window.location.href = `${_constants.URL_ROOT}/#/${search}`;
        return;
      }
    }

    if (isMobile()) {
      // If on mobile browser, check position on load
      getCurrentPosition(); // Also, watch for changes in position on mobile

      navigator.geolocation.watchPosition( // On success
      position => {
        receivedPositionResponse({
          position
        });
      }, // On error
      error => {
        console.log('error in watchPosition', error);
      }, // Options
      {
        enableHighAccuracy: true
      });
    } // Handle routing to a specific part of the app (e.g. stop viewer) on page
    // load. (This happens prior to routing request in case special routerId is
    // set from URL.)


    matchContentToUrl(location);

    if (location && location.search) {
      // Set search params and plan trip if routing enabled and a query exists
      // in the URL.
      parseUrlQueryString();
    } // Initialize call taker/field trip modules (check for valid auth session).


    initializeModules();
  }

  componentWillUnmount() {
    // Remove on back button press listener.
    window.removeEventListener('popstate', this.props.handleBackButtonPress);
  }

  render() {
    return isMobile() ? this.renderMobileView() : this.renderDesktopView();
  }

} // connect to the redux store


_defineProperty(ResponsiveWebapp, "propTypes", {
  initZoomOnLocate: _propTypes.default.number,
  query: _propTypes.default.object
});

_defineProperty(ResponsiveWebapp, "contextType", _contexts.ComponentContext);

const mapStateToProps = (state, ownProps) => {
  const title = (0, _state.getTitle)(state);
  return {
    activeItinerary: (0, _state.getActiveItinerary)(state),
    activeSearchId: state.otp.activeSearchId,
    currentPosition: state.otp.location.currentPosition,
    initZoomOnLocate: state.otp.config.map && state.otp.config.map.initZoomOnLocate,
    locale: state.otp.ui.locale,
    mobileScreen: state.otp.ui.mobileScreen,
    modeGroups: state.otp.config.modeGroups,
    query: state.otp.currentQuery,
    searches: state.otp.searches,
    title
  };
};

const mapDispatchToProps = {
  formChanged: formActions.formChanged,
  getCurrentPosition: locationActions.getCurrentPosition,
  handleBackButtonPress: uiActions.handleBackButtonPress,
  initializeModules: callTakerActions.initializeModules,
  matchContentToUrl: uiActions.matchContentToUrl,
  parseUrlQueryString: formActions.parseUrlQueryString,
  receivedPositionResponse: locationActions.receivedPositionResponse,
  setLocale: uiActions.setLocale,
  setLocationToCurrent: mapActions.setLocationToCurrent,
  setMapCenter: configActions.setMapCenter,
  setMapZoom: configActions.setMapZoom
};
const history = (0, _history.createHashHistory)();
const WebappWithRouter = (0, _reactRouter.withRouter)((0, _withLoggedInUserSupport.default)((0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps)(ResponsiveWebapp))); // TODO: A number of these routes are ignored during a11y testing as no server mocks are available

const routes = [{
  exact: true,
  path: [// App root
  '/', // Load app with preset lat/lon/zoom and optional router
  // NOTE: All params will be cast to :id in matchContentToUrl due
  // to a quirk with react-router.
  // https://github.com/ReactTraining/react-router/issues/5870#issuecomment-394194338
  '/@/:latLonZoomRouter', '/start/:latLonZoomRouter', // Route viewer (and route ID).
  '/route', '/route/:id', // Stop viewer (and stop ID).
  '/stop', '/stop/:id'],
  shouldRenderWebApp: true
}, {
  a11yIgnore: true,
  component: _favoritePlaceScreen.default,
  path: [`${_constants.CREATE_ACCOUNT_PLACES_PATH}/:id`, `${_constants.PLACES_PATH}/:id`]
}, {
  a11yIgnore: true,
  component: _savedTripScreen.default,
  path: `${_constants.TRIPS_PATH}/:id`
}, {
  a11yIgnore: true,
  children: /*#__PURE__*/_react.default.createElement(_connectedLinks.RedirectWithQuery, {
    to: _constants.TRIPS_PATH
  }),
  exact: true,
  path: _constants.ACCOUNT_PATH
}, {
  a11yIgnore: true,
  children: /*#__PURE__*/_react.default.createElement(_connectedLinks.RedirectWithQuery, {
    to: _constants.CREATE_ACCOUNT_VERIFY_PATH
  }),
  exact: true,
  path: _constants.CREATE_ACCOUNT_PATH
}, {
  a11yIgnore: true,
  // This route lets new or existing users edit or set up their account.
  component: _userAccountScreen.default,
  path: [`${_constants.CREATE_ACCOUNT_PATH}/:step`, _constants.ACCOUNT_SETTINGS_PATH]
}, {
  getContextComponent: components => (0, _appFrame.frame)(components.TermsOfService),
  path: _constants.TERMS_OF_SERVICE_PATH
}, {
  getContextComponent: components => (0, _appFrame.frame)(components.TermsOfStorage),
  path: _constants.TERMS_OF_STORAGE_PATH
}, {
  a11yIgnore: true,
  component: _savedTripList.default,
  path: _constants.TRIPS_PATH
}, {
  a11yIgnore: true,
  // This route is called immediately after login by Auth0
  // and by the onRedirectCallback function from /lib/util/auth.js.
  // For new users, it displays the account setup form.
  // For existing users, it takes the browser back to the itinerary search prior to login.
  component: _afterSigninScreen.default,
  path: '/signedin'
}, {
  a11yIgnore: true,
  component: _printLayout.default,
  path: '/print'
}, {
  a11yIgnore: true,
  component: _printFieldTripLayout.default,
  path: '/printFieldTrip'
}];
/**
 * The routing component for the application.
 * This is the top-most "standard" component,
 * and we initialize the Auth0Provider here
 * so that Auth0 services are available everywhere.
 */

exports.routes = routes;

class RouterWrapperWithAuth0 extends _react.Component {
  render() {
    const {
      auth0Config,
      components,
      defaultLocale,
      locale,
      localizedMessages,
      processSignIn,
      routerConfig,
      showAccessTokenError,
      showLoginError
    } = this.props;

    const router = localizedMessages && /*#__PURE__*/_react.default.createElement(_contexts.ComponentContext.Provider, {
      value: components
    }, /*#__PURE__*/_react.default.createElement(_reactIntl.IntlProvider, {
      defaultLocale: defaultLocale,
      locale: locale || defaultLocale,
      messages: localizedMessages
    }, /*#__PURE__*/_react.default.createElement(_connectedReactRouter.ConnectedRouter, {
      basename: routerConfig && routerConfig.basename,
      history: history
    }, /*#__PURE__*/_react.default.createElement(_reactRouter.Switch, null, routes.map((props, index) => {
      const {
        getContextComponent,
        shouldRenderWebApp,
        ...routerProps
      } = props;
      return /*#__PURE__*/_react.default.createElement(_reactRouter.Route, _extends({
        component: getContextComponent ? getContextComponent(components) : undefined,
        render: shouldRenderWebApp ? () => /*#__PURE__*/_react.default.createElement(WebappWithRouter, this.props) : undefined
      }, routerProps));
    }), /*#__PURE__*/_react.default.createElement(_reactRouter.Route, {
      render: () => /*#__PURE__*/_react.default.createElement(WebappWithRouter, this.props)
    })))));

    return auth0Config ? /*#__PURE__*/_react.default.createElement(_auth0React.Auth0Provider, {
      audience: _constants.AUTH0_AUDIENCE,
      clientId: auth0Config.clientId,
      domain: auth0Config.domain,
      onAccessTokenError: showAccessTokenError,
      onLoginError: showLoginError,
      onRedirectCallback: processSignIn,
      onRedirecting: _beforeSigninScreen.default,
      redirectUri: _constants.URL_ROOT,
      scope: _constants.AUTH0_SCOPE
    }, router) : router;
  }

}

const mapStateToWrapperProps = (state, ownProps) => {
  const {
    persistence,
    reactRouter
  } = state.otp.config;
  return {
    auth0Config: (0, _auth2.getAuth0Config)(persistence),
    defaultLocale: (0, _i18n.getDefaultLocale)(state.otp.config),
    locale: state.otp.ui.locale,
    localizedMessages: state.otp.ui.localizedMessages,
    routerConfig: reactRouter
  };
};

const mapWrapperDispatchToProps = {
  processSignIn: authActions.processSignIn,
  showAccessTokenError: authActions.showAccessTokenError,
  showLoginError: authActions.showLoginError
};

var _default = (0, _reactRedux.connect)(mapStateToWrapperProps, mapWrapperDispatchToProps)(RouterWrapperWithAuth0);

exports.default = _default;

//# sourceMappingURL=responsive-webapp.js