import React from 'react'; import { createStackNavigator, createAppContainer, createSwitchNavigator, createDrawerNavigator } from 'react-navigation'; import { Provider } from 'react-redux'; import { useScreens } from 'react-native-screens'; // eslint-disable-line import/no-unresolved import { Linking } from 'react-native'; import firebase from 'react-native-firebase'; import PropTypes from 'prop-types'; import { appInit } from './actions'; import { deepLinkingOpen } from './actions/deepLinking'; import Navigation from './lib/Navigation'; import Sidebar from './views/SidebarView'; import { HEADER_BACKGROUND, HEADER_TITLE, HEADER_BACK } from './constants/colors'; import parseQuery from './lib/methods/helpers/parseQuery'; import { initializePushNotifications, onNotification } from './notifications/push'; import store from './lib/createStore'; import NotificationBadge from './notifications/inApp'; useScreens(); const parseDeepLinking = (url) => { if (url) { url = url.replace(/rocketchat:\/\/|https:\/\/go.rocket.chat\//, ''); const regex = /^(room|auth)\?/; if (url.match(regex)) { url = url.replace(regex, '').trim(); if (url) { return parseQuery(url); } } } return null; }; const defaultHeader = { headerStyle: { backgroundColor: HEADER_BACKGROUND }, headerTitleStyle: { color: HEADER_TITLE }, headerBackTitle: null, headerTintColor: HEADER_BACK }; // Outside const OutsideStack = createStackNavigator({ OnboardingView: { getScreen: () => require('./views/OnboardingView').default, header: null }, NewServerView: { getScreen: () => require('./views/NewServerView').default }, LoginSignupView: { getScreen: () => require('./views/LoginSignupView').default }, LoginView: { getScreen: () => require('./views/LoginView').default }, ForgotPasswordView: { getScreen: () => require('./views/ForgotPasswordView').default }, RegisterView: { getScreen: () => require('./views/RegisterView').default }, LegalView: { getScreen: () => require('./views/LegalView').default } }, { defaultNavigationOptions: defaultHeader }); const OAuthStack = createStackNavigator({ OAuthView: { getScreen: () => require('./views/OAuthView').default } }, { defaultNavigationOptions: defaultHeader }); const OutsideStackModal = createStackNavigator({ OutsideStack, OAuthStack }, { mode: 'modal', headerMode: 'none' }); // Inside const ChatsStack = createStackNavigator({ RoomsListView: { getScreen: () => require('./views/RoomsListView').default }, RoomView: { getScreen: () => require('./views/RoomView').default }, RoomActionsView: { getScreen: () => require('./views/RoomActionsView').default }, RoomInfoView: { getScreen: () => require('./views/RoomInfoView').default }, RoomInfoEditView: { getScreen: () => require('./views/RoomInfoEditView').default }, RoomMembersView: { getScreen: () => require('./views/RoomMembersView').default }, SearchMessagesView: { getScreen: () => require('./views/SearchMessagesView').default }, SelectedUsersView: { getScreen: () => require('./views/SelectedUsersView').default }, ThreadMessagesView: { getScreen: () => require('./views/ThreadMessagesView').default }, MessagesView: { getScreen: () => require('./views/MessagesView').default }, AutoTranslateView: { getScreen: () => require('./views/AutoTranslateView').default }, ReadReceiptsView: { getScreen: () => require('./views/ReadReceiptView').default }, DirectoryView: { getScreen: () => require('./views/DirectoryView').default } }, { defaultNavigationOptions: defaultHeader }); ChatsStack.navigationOptions = ({ navigation }) => { let drawerLockMode = 'unlocked'; if (navigation.state.index > 0) { drawerLockMode = 'locked-closed'; } return { drawerLockMode }; }; const ProfileStack = createStackNavigator({ ProfileView: { getScreen: () => require('./views/ProfileView').default } }, { defaultNavigationOptions: defaultHeader }); ProfileStack.navigationOptions = ({ navigation }) => { let drawerLockMode = 'unlocked'; if (navigation.state.index > 0) { drawerLockMode = 'locked-closed'; } return { drawerLockMode }; }; const SettingsStack = createStackNavigator({ SettingsView: { getScreen: () => require('./views/SettingsView').default }, LanguageView: { getScreen: () => require('./views/LanguageView').default } }, { defaultNavigationOptions: defaultHeader }); const AdminPanelStack = createStackNavigator({ AdminPanelView: { getScreen: () => require('./views/AdminPanelView').default } }, { defaultNavigationOptions: defaultHeader }); SettingsStack.navigationOptions = ({ navigation }) => { let drawerLockMode = 'unlocked'; if (navigation.state.index > 0) { drawerLockMode = 'locked-closed'; } return { drawerLockMode }; }; const ChatsDrawer = createDrawerNavigator({ ChatsStack, ProfileStack, SettingsStack, AdminPanelStack }, { contentComponent: Sidebar }); const NewMessageStack = createStackNavigator({ NewMessageView: { getScreen: () => require('./views/NewMessageView').default }, SelectedUsersViewCreateChannel: { getScreen: () => require('./views/SelectedUsersView').default }, CreateChannelView: { getScreen: () => require('./views/CreateChannelView').default } }, { defaultNavigationOptions: defaultHeader }); const InsideStackModal = createStackNavigator({ Main: ChatsDrawer, NewMessageStack }, { mode: 'modal', headerMode: 'none' }); const SetUsernameStack = createStackNavigator({ SetUsernameView: { getScreen: () => require('./views/SetUsernameView').default } }); class CustomInsideStack extends React.Component { static router = InsideStackModal.router; static propTypes = { navigation: PropTypes.object } render() { const { navigation } = this.props; return ( ); } } const App = createAppContainer(createSwitchNavigator( { OutsideStack: OutsideStackModal, InsideStack: CustomInsideStack, AuthLoading: { getScreen: () => require('./views/AuthLoadingView').default }, SetUsernameStack }, { initialRouteName: 'AuthLoading' } )); // gets the current screen from navigation state const getActiveRouteName = (navigationState) => { if (!navigationState) { return null; } const route = navigationState.routes[navigationState.index]; // dive into nested navigators if (route.routes) { return getActiveRouteName(route); } return route.routeName; }; const onNavigationStateChange = (prevState, currentState) => { const currentScreen = getActiveRouteName(currentState); const prevScreen = getActiveRouteName(prevState); if (prevScreen !== currentScreen) { firebase.analytics().setCurrentScreen(currentScreen); } }; export default class Root extends React.Component { constructor(props) { super(props); this.init(); } componentDidMount() { this.listenerTimeout = setTimeout(() => { Linking.addEventListener('url', ({ url }) => { const parsedDeepLinkingURL = parseDeepLinking(url); if (parsedDeepLinkingURL) { store.dispatch(deepLinkingOpen(parsedDeepLinkingURL)); } }); }, 5000); } componentWillUnmount() { clearTimeout(this.listenerTimeout); } init = async() => { const [notification, deepLinking] = await Promise.all([initializePushNotifications(), Linking.getInitialURL()]); const parsedDeepLinkingURL = parseDeepLinking(deepLinking); if (notification) { onNotification(notification); } else if (parsedDeepLinkingURL) { store.dispatch(deepLinkingOpen(parsedDeepLinkingURL)); } else { store.dispatch(appInit()); } } render() { return ( { Navigation.setTopLevelNavigator(navigatorRef); }} onNavigationStateChange={onNavigationStateChange} /> ); } }