import { RouterDirection } from '@ionic/core'; import { NavContext, NavContextState } from '@ionic/react'; import { Location as HistoryLocation, UnregisterCallback } from 'history'; import React from 'react'; import { RouteComponentProps } from 'react-router-dom'; import { generateId } from '../utils'; import { LocationHistory } from '../utils/LocationHistory'; import { StackManager } from './StackManager'; import { ViewItem } from './ViewItem'; import { ViewStack } from './ViewStacks'; interface NavManagerProps extends RouteComponentProps { findViewInfoByLocation: (location: HistoryLocation) => { view?: ViewItem, viewStack?: ViewStack }; findViewInfoById: (id: string) => { view?: ViewItem, viewStack?: ViewStack }; getActiveIonPage: () => { view?: ViewItem, viewStack?: ViewStack }; } export class NavManager extends React.Component { listenUnregisterCallback: UnregisterCallback | undefined; locationHistory: LocationHistory = new LocationHistory(); constructor(props: NavManagerProps) { super(props); this.state = { goBack: this.goBack.bind(this), hasIonicRouter: () => true, getHistory: this.getHistory.bind(this), getLocation: this.getLocation.bind(this), navigate: this.navigate.bind(this), getStackManager: this.getStackManager.bind(this), getPageManager: this.getPageManager.bind(this), currentPath: this.props.location.pathname, registerIonPage: () => { return; }, // overridden in View for each IonPage tabNavigate: this.tabNavigate.bind(this) }; this.listenUnregisterCallback = this.props.history.listen((location: HistoryLocation) => { this.setState({ currentPath: location.pathname }); this.locationHistory.add(location); }); this.locationHistory.add({ hash: window.location.hash, key: generateId(), pathname: window.location.pathname, search: window.location.search, state: {} }); } componentWillUnmount() { if (this.listenUnregisterCallback) { this.listenUnregisterCallback(); } } goBack(defaultHref?: string) { const { view: activeIonPage } = this.props.getActiveIonPage(); if (activeIonPage) { const { view: enteringView } = this.props.findViewInfoById(activeIonPage.prevId!); if (enteringView) { const lastLocation = this.locationHistory.findLastLocation(enteringView.routeData.match.url); if (lastLocation) { this.props.history.replace(lastLocation.pathname + lastLocation.search, { direction: 'back' }); } else { this.props.history.replace(enteringView.routeData.match.url, { direction: 'back' }); } } else { if (defaultHref) { this.props.history.replace(defaultHref, { direction: 'back' }); } } } else { if (defaultHref) { this.props.history.replace(defaultHref, { direction: 'back' }); } } } getHistory() { return this.props.history as any; } getLocation() { return this.props.location as any; } navigate(path: string, direction?: RouterDirection | 'none') { this.props.history.push(path, { direction }); } tabNavigate(url: string) { this.props.history.replace(url, { direction: 'back' }); } getPageManager() { return (children: any) => children; } getStackManager() { return StackManager; } render() { return ( {this.props.children} ); } }