From 6a6049220dc76e74dc4e68915b68724cb61404d8 Mon Sep 17 00:00:00 2001 From: Arnaud Vergnet Date: Wed, 8 Apr 2020 12:10:06 +0200 Subject: [PATCH] Improved url handling --- App.js | 70 +++++------------ src/managers/ConnectionManager.js | 4 +- src/navigation/DrawerNavigator.js | 16 +--- src/navigation/MainTabNavigator.js | 20 ++--- .../Amicale/Clubs/ClubDisplayScreen.js | 1 + src/screens/HomeScreen.js | 13 +++- src/utils/URLHandler.js | 76 +++++++++++++++++++ 7 files changed, 121 insertions(+), 79 deletions(-) create mode 100644 src/utils/URLHandler.js diff --git a/App.js b/App.js index b3b9ffd..62a3058 100644 --- a/App.js +++ b/App.js @@ -5,7 +5,7 @@ import {Platform, StatusBar} from 'react-native'; import LocaleManager from './src/managers/LocaleManager'; import AsyncStorageManager from "./src/managers/AsyncStorageManager"; import CustomIntroSlider from "./src/components/Custom/CustomIntroSlider"; -import {Linking, SplashScreen} from 'expo'; +import {SplashScreen} from 'expo'; import ThemeManager from './src/managers/ThemeManager'; import {NavigationContainer} from '@react-navigation/native'; import {createStackNavigator} from '@react-navigation/stack'; @@ -15,6 +15,7 @@ import {Provider as PaperProvider} from 'react-native-paper'; import AprilFoolsManager from "./src/managers/AprilFoolsManager"; import Update from "./src/constants/Update"; import ConnectionManager from "./src/managers/ConnectionManager"; +import URLHandler from "./src/utils/URLHandler"; type Props = {}; @@ -43,11 +44,13 @@ export default class App extends React.Component { navigatorRef: Object; - defaultRoute: Array; + defaultRoute: string | null; defaultData: Object; createDrawerNavigator: Function; + urlHandler: URLHandler; + constructor() { super(); LocaleManager.initTranslations(); @@ -55,61 +58,25 @@ export default class App extends React.Component { this.onUpdateTheme = this.onUpdateTheme.bind(this); SplashScreen.preventAutoHide(); this.navigatorRef = React.createRef(); - this.defaultRoute = []; + this.defaultRoute = null; this.defaultData = {}; - // this.defaultRoute = ["main", "home", "club-information"]; - // this.defaultData = {clubId: 0}; - this.handleUrls(); + this.urlHandler = new URLHandler(this.onInitialURLParsed, this.onDetectURL); + this.urlHandler.listen(); } - handleUrls() { - console.log(Linking.makeUrl('main/home/club-information', {clubId: 1})); - Linking.addEventListener('url', this.onUrl); - Linking.parseInitialURLAsync().then(this.onParsedUrl); - } - - onUrl = (url: string) => { - this.onParsedUrl(Linking.parse(url)); + onInitialURLParsed = ({route, data}: Object) => { + this.defaultRoute = route; + this.defaultData = data; }; - onParsedUrl = ({path, queryParams}: Object) => { - if (path !== null) { - let pathArray = path.split('/'); - if (this.isClubInformationLink(pathArray)) - this.handleClubInformationUrl(queryParams); - else if (this.isPlanningInformationLink(pathArray)) - this.handlePlanningInformationUrl(queryParams); - } + onDetectURL = ({route, data}: Object) => { + // Navigate to nested navigator and pass data to the index screen + this.navigatorRef.current.navigate('home', { + screen: 'index', + params: {nextScreen: route, data: data, shouldOpen: true} + }); }; - isClubInformationLink(pathArray: Array) { - return pathArray[0] === "main" && pathArray[1] === "home" && pathArray[2] === "club-information"; - } - - isPlanningInformationLink(pathArray: Array) { - return pathArray[0] === "main" && pathArray[1] === "home" && pathArray[2] === "planning-information"; - } - - handleClubInformationUrl(params: Object) { - if (params !== undefined && params.clubId !== undefined) { - let id = parseInt(params.clubId); - if (!isNaN(id)) { - this.defaultRoute = ["main", "home", "club-information"]; - this.defaultData = {clubId: id}; - } - } - } - - handlePlanningInformationUrl(params: Object) { - if (params !== undefined && params.eventId !== undefined) { - let id = parseInt(params.eventId); - if (!isNaN(id)) { - this.defaultRoute = ["main", "home", "planning-information"]; - this.defaultData = {eventId: id}; - } - } - } - /** * Updates the theme */ @@ -156,7 +123,8 @@ export default class App extends React.Component { } catch (e) { } - this.createDrawerNavigator = () => ; + this.createDrawerNavigator = () => ; this.onLoadFinished(); } diff --git a/src/managers/ConnectionManager.js b/src/managers/ConnectionManager.js index f36183e..5bd7cb2 100644 --- a/src/managers/ConnectionManager.js +++ b/src/managers/ConnectionManager.js @@ -196,7 +196,7 @@ export default class ConnectionManager { let data = {}; if (keys !== null && values !== null && keys.length === values.length) data = this.generatePostArguments(keys, values); - console.log(data); + // console.log(data); fetch(API_ENDPOINT + path, { method: 'POST', headers: new Headers({ @@ -209,7 +209,7 @@ export default class ConnectionManager { }) }).then(async (response) => response.json()) .then((response: response_format) => { - console.log(response); + // console.log(response); if (this.isResponseValid(response)) { if (response.error === ERROR_TYPE.SUCCESS) resolve(response.data); diff --git a/src/navigation/DrawerNavigator.js b/src/navigation/DrawerNavigator.js index 8b66c04..26cdc2f 100644 --- a/src/navigation/DrawerNavigator.js +++ b/src/navigation/DrawerNavigator.js @@ -317,35 +317,25 @@ function getDrawerContent(props) { } type Props = { - defaultPath: Array, + defaultRoute: string | null, defaultData: Object } export default class DrawerNavigator extends React.Component { - defaultRoute: string; - defaultSubRoute: string | null; - createTabNavigator: Object; constructor(props: Object) { super(props); - this.defaultRoute = 'Main'; - this.defaultSubRoute = null; - if (props.defaultPath.length > 0) - this.defaultRoute = props.defaultPath[0]; - if (props.defaultPath.length > 1) - this.defaultSubRoute = props.defaultPath[1]; - - this.createTabNavigator = () => + this.createTabNavigator = () => } render() { return ( , + defaultRoute: string | null, defaultData: Object } @@ -221,19 +225,17 @@ class TabNavigator extends React.Component{ createHomeStackComponent: Object; colors: Object; + defaultRoute: string; + constructor(props) { super(props); this.colors = props.theme.colors; this.defaultRoute = AsyncStorageManager.getInstance().preferences.defaultStartScreen.current.toLowerCase(); - this.defaultSubRoute = null; - if (props.defaultPath.length > 1) - this.defaultRoute = props.defaultPath[1]; - if (props.defaultPath.length > 2) - this.defaultSubRoute = props.defaultPath[2]; + if (props.defaultRoute !== null) + this.defaultRoute = 'home'; - - this.createHomeStackComponent = () => HomeStackComponent(this.defaultSubRoute, props.defaultData); + this.createHomeStackComponent = () => HomeStackComponent(props.defaultRoute, props.defaultData); } render() { diff --git a/src/screens/Amicale/Clubs/ClubDisplayScreen.js b/src/screens/Amicale/Clubs/ClubDisplayScreen.js index 607fb19..092c0ab 100644 --- a/src/screens/Amicale/Clubs/ClubDisplayScreen.js +++ b/src/screens/Amicale/Clubs/ClubDisplayScreen.js @@ -61,6 +61,7 @@ class ClubDisplayScreen extends React.Component { super(props); this.colors = props.theme.colors; + console.log(this.props.route.params); if (this.props.route.params.data !== undefined && this.props.route.params.categories !== undefined) { this.displayData = this.props.route.params.data; this.categories = this.props.route.params.categories; diff --git a/src/screens/HomeScreen.js b/src/screens/HomeScreen.js index e2dd830..13e3013 100644 --- a/src/screens/HomeScreen.js +++ b/src/screens/HomeScreen.js @@ -14,6 +14,7 @@ import {openBrowser} from "../utils/WebBrowser"; import ActionsDashBoardItem from "../components/Home/ActionsDashboardItem"; import HeaderButton from "../components/Custom/HeaderButton"; import ConnectionManager from "../managers/ConnectionManager"; +import {CommonActions} from '@react-navigation/native'; // import DATA from "../dashboard_data.json"; @@ -52,9 +53,6 @@ class HomeScreen extends React.Component { this.colors = props.theme.colors; this.isLoggedIn = null; - if (this.props.route.params.nextScreen !== undefined && this.props.route.params.nextScreen !== null) { - this.props.navigation.navigate(this.props.route.params.nextScreen, this.props.route.params.data); - } } /** @@ -79,7 +77,14 @@ class HomeScreen extends React.Component { headerRight: this.getHeaderButton, }); } - + // TODO if already on home screen + if (this.props.route.params !== undefined) { + if (this.props.route.params.shouldOpen !== undefined && this.props.route.params.shouldOpen) { + this.props.navigation.navigate(this.props.route.params.nextScreen, this.props.route.params.data); + // reset params to prevent infinite loop + this.props.navigation.dispatch(CommonActions.setParams({ shouldOpen: false })); + } + } }; getHeaderButton = () => { diff --git a/src/utils/URLHandler.js b/src/utils/URLHandler.js new file mode 100644 index 0000000..ae9f41b --- /dev/null +++ b/src/utils/URLHandler.js @@ -0,0 +1,76 @@ +// @flow + +import {Linking} from 'expo'; + +export default class URLHandler { + + static CLUB_INFO_ROUTE = "club-information"; + static EVENT_INFO_ROUTE = "planning-information"; + + onInitialURLParsed: Function; + onDetectURL: Function; + + constructor(onInitialURLParsed: Function, onDetectURL: Function) { + this.onInitialURLParsed = onInitialURLParsed; + this.onDetectURL = onDetectURL; + } + + listen() { + console.log(Linking.makeUrl('main/home/club-information', {clubId: 1})); + Linking.addEventListener('url', this.onUrl); + Linking.parseInitialURLAsync().then(this.onInitialUrl); + } + + onUrl = ({url}: Object) => { + let data = this.getUrlData(Linking.parse(url)); + if (data !== null) + this.onDetectURL(data); + }; + + onInitialUrl = ({path, queryParams}: Object) => { + let data = this.getUrlData({path, queryParams}); + if (data !== null) + this.onInitialURLParsed(data); + }; + + getUrlData({path, queryParams}: Object) { + let data = null; + if (path !== null) { + let pathArray = path.split('/'); + if (this.isClubInformationLink(pathArray)) + data = this.generateClubInformationData(queryParams); + else if (this.isPlanningInformationLink(pathArray)) + data = this.generatePlanningInformationData(queryParams); + } + return data; + } + + isClubInformationLink(pathArray: Array) { + return pathArray[0] === "main" && pathArray[1] === "home" && pathArray[2] === "club-information"; + } + + isPlanningInformationLink(pathArray: Array) { + return pathArray[0] === "main" && pathArray[1] === "home" && pathArray[2] === "planning-information"; + } + + generateClubInformationData(params: Object): Object | null { + if (params !== undefined && params.clubId !== undefined) { + let id = parseInt(params.clubId); + if (!isNaN(id)) { + return {route: URLHandler.CLUB_INFO_ROUTE, data: {clubId: id}}; + } + } + return null; + } + + generatePlanningInformationData(params: Object): Object | null { + if (params !== undefined && params.eventId !== undefined) { + let id = parseInt(params.eventId); + if (!isNaN(id)) { + return {route: URLHandler.EVENT_INFO_ROUTE, data: {eventId: id}}; + } + } + return null; + } + +}