|
/* eslint react/forbid-prop-types: "off"*/ |
|
import React, { PureComponent } from "react"; |
|
import { AppState } from "react-native"; |
|
import DrawerStack from "./DrawerStack"; |
|
import AuthStack from "./auth/stack"; |
|
import PropTypes from "prop-types"; |
|
import { connect } from "react-redux"; |
|
import { NavigationActions } from "react-navigation"; |
|
import * as cache from "utils/cache"; |
|
import { AUTH_STATUS } from "../enums/authStatus"; |
|
import { resetState } from "navigation/actions"; |
|
import { setSelectedEvent } from "events/actions"; |
|
import { setSelectedSurvey } from "surveys-ballots/actions"; |
|
import { setSelectedArticle } from "articles/actions"; |
|
import { setSelectedAlert } from "action-alerts/actions"; |
|
import * as articleHelpers from "articles/helpers/actions-helpers"; |
|
import * as eventHelpers from "events/helpers/actions-helper"; |
|
import * as alertHelpers from "action-alerts/helpers/actions-helpers"; |
|
import * as appcenter from "utils/appcenterLogger"; |
|
import * as surveysHelpers from "surveys-ballots/helpers/data-helpers"; |
|
|
|
class RootNavigation extends PureComponent { |
|
static propTypes = { |
|
deepLinkElementRoute: PropTypes.string, |
|
deepLinkElementType: PropTypes.string, |
|
notification: PropTypes.string, |
|
resetPasswordDeepLinkKey: PropTypes.string, |
|
resetState: PropTypes.func, |
|
setSelectedAlert: PropTypes.func, |
|
setSelectedArticle: PropTypes.func, |
|
setSelectedEvent: PropTypes.func, |
|
setSelectedSurvey: PropTypes.func.isRequired, |
|
user: PropTypes.object |
|
}; |
|
|
|
static defaultProps = { |
|
resetPasswordDeepLinkKey: "", |
|
user: null |
|
}; |
|
|
|
constructor(props) { |
|
super(props); |
|
this.transitioned = false; |
|
|
|
this.state = { |
|
appState: AppState.currentState |
|
}; |
|
} |
|
|
|
componentDidMount() { |
|
AppState.addEventListener("change", this._handleAppStateChange); |
|
|
|
const resetPasswordDeepLinked = this.props.resetPasswordDeepLinkKey !== ""; |
|
if (resetPasswordDeepLinked) { |
|
return this._pushNavigation("SetNewPassword"); |
|
} |
|
|
|
const eventsDeepLinked = this.props.deepLinkElementType === "event"; |
|
if (eventsDeepLinked) { |
|
return this._pushNavigation(this.props.deepLinkElementRoute); |
|
} |
|
const surveyDeepLinked = this.props.deepLinkElementType === "survey_ballot"; |
|
if (surveyDeepLinked) { |
|
return this._pushNavigation(this.props.deepLinkElementRoute); |
|
} |
|
} |
|
// should be changed to `static getDerivedStateFromProps` but said lifecycle |
|
// method cannot do props comparisons |
|
componentWillReceiveProps(nextProps) { |
|
//deep link set/reset password |
|
const resetPasswordDeepLinked = |
|
this.props.resetPasswordDeepLinkKey === "" && |
|
nextProps.resetPasswordDeepLinkKey !== ""; |
|
if (resetPasswordDeepLinked) { |
|
return this._pushNavigation("SetNewPassword"); |
|
} |
|
|
|
//prettier-ignore |
|
const notifiationReceived = !this.props.notification && nextProps.notification; |
|
if (notifiationReceived) { |
|
this._handleNotification(nextProps); |
|
} |
|
|
|
if (this._deepLinkChanged(nextProps)) { |
|
const eventsDeepLinked = nextProps.deepLinkElementType === "event"; |
|
if (eventsDeepLinked) { |
|
return this._pushNavigation(nextProps.deepLinkElementRoute); |
|
} |
|
const surveyDeepLinked = |
|
nextProps.deepLinkElementType === "survey_ballot"; |
|
if (surveyDeepLinked) { |
|
return this._pushNavigation(nextProps.deepLinkElementRoute); |
|
} |
|
} |
|
} |
|
|
|
componentWillUnmount() { |
|
AppState.removeEventListener("change", this._handleAppStateChange); |
|
} |
|
|
|
_deepLinkChanged = nextProps => { |
|
return nextProps.deepLinkElementRoute !== ""; |
|
}; |
|
|
|
_handleAppStateChange = async nextAppState => { |
|
if ( |
|
this.state.appState.match(/inactive|background/) && |
|
nextAppState === "active" |
|
) { |
|
const redirect = await cache.shouldInactivityRedirect(); |
|
if (redirect && this.navigator) { |
|
this.setState({ appState: nextAppState }, () => { |
|
const resetAction = NavigationActions.reset({ |
|
index: 0, |
|
key: null, |
|
actions: [NavigationActions.navigate({ routeName: "MainDrawer" })] |
|
}); |
|
this.navigator.dispatch(resetAction); |
|
}); |
|
} |
|
} else { |
|
this.setState({ appState: nextAppState }); |
|
cache.setBackgroundTime(); |
|
appcenter.trackAppBackgrounding(); |
|
} |
|
}; |
|
|
|
_handleNotification = async ({ notification }) => { |
|
const { Type } = notification; |
|
const objectKey = notification.Key || notification.Id; |
|
|
|
if (Type.toLowerCase() === "event") { |
|
const event = await eventHelpers.fetchEventDetails({ |
|
Key: objectKey |
|
}); |
|
this.props.setSelectedEvent(event); |
|
this._pushNavigation("EventDetails"); |
|
} |
|
|
|
if (["SURVEY_SURVEY", "SURVEY_BALLOT"].includes(Type)) { |
|
const routeName = surveysHelpers.ballotOrSurvey(Type); |
|
this.props.setSelectedSurvey({ Key: objectKey }); |
|
this._pushNavigation(routeName); |
|
} |
|
|
|
if (Type === "ALERT") { |
|
const alert = await alertHelpers.fetchCampaign(objectKey, "DETAIL_FULL"); |
|
this.props.setSelectedAlert(alert); |
|
this._pushNavigation("ActionAlertDetails", { |
|
content: alert.Alert, |
|
id: alert.CampaignId, |
|
title: alert.Headline |
|
}); |
|
} |
|
|
|
if (Type === "ARTICLE") { |
|
const article = await articleHelpers.fetchArticleDetails({ |
|
Id: objectKey |
|
}); |
|
this.props.setSelectedArticle(article); |
|
this._pushNavigation("ArticleDetails"); |
|
} |
|
}; |
|
|
|
_pushNavigation = (routeName, params = {}) => { |
|
if (this.navigator && !this.transitioned) { |
|
this.navigator.dispatch( |
|
NavigationActions.navigate({ |
|
routeName, |
|
params |
|
}) |
|
); |
|
this.props.resetState(); |
|
this.transitioned = true; |
|
setTimeout(() => { |
|
this.transitioned = false; |
|
}, 2000); |
|
} |
|
}; |
|
|
|
_getCurrentRouteName = navigationState => { |
|
if (!navigationState) { |
|
return null; |
|
} |
|
const route = navigationState.routes[navigationState.index]; |
|
if (route.routes) { |
|
return this._getCurrentRouteName(route); |
|
} |
|
return route.routeName; |
|
}; |
|
|
|
_screenTracking = (prevState, currentState) => { |
|
const currentScreen = this._getCurrentRouteName(currentState); |
|
const prevScreen = this._getCurrentRouteName(prevState); |
|
// comment out if removing appcenter |
|
if (prevScreen !== currentScreen) { |
|
appcenter.trackNavigation(prevScreen, currentScreen); |
|
} |
|
}; |
|
|
|
render() { |
|
if ( |
|
this.props.user && |
|
this.props.user.authStatus === AUTH_STATUS.LOGGED_IN |
|
) { |
|
return ( |
|
<DrawerStack |
|
ref={nav => { |
|
this.navigator = nav; |
|
}} |
|
onNavigationStateChange={this._screenTracking} |
|
/> |
|
); |
|
} |
|
return ( |
|
<AuthStack |
|
authStatus={this.props.user.authStatus} |
|
// onNavigationStateChange={this._screenTracking} |
|
ref={nav => { |
|
this.navigator = nav; |
|
}} |
|
/> |
|
); |
|
} |
|
} |
|
|
|
const mapStateToProps = ({ auth, registrations, navigation }) => { |
|
const { user } = auth; |
|
return { |
|
user, |
|
resetPasswordDeepLinkKey: registrations.resetPasswordData.resetKey, |
|
...navigation |
|
}; |
|
}; |
|
|
|
export default connect( |
|
mapStateToProps, |
|
{ |
|
resetState, |
|
setSelectedEvent, |
|
setSelectedSurvey, |
|
setSelectedArticle, |
|
setSelectedAlert |
|
} |
|
)(RootNavigation); |