forked from vergnet/application-amicale
Improved url handling
This commit is contained in:
parent
41b9194d98
commit
6a6049220d
7 changed files with 121 additions and 79 deletions
70
App.js
70
App.js
|
@ -5,7 +5,7 @@ import {Platform, StatusBar} from 'react-native';
|
||||||
import LocaleManager from './src/managers/LocaleManager';
|
import LocaleManager from './src/managers/LocaleManager';
|
||||||
import AsyncStorageManager from "./src/managers/AsyncStorageManager";
|
import AsyncStorageManager from "./src/managers/AsyncStorageManager";
|
||||||
import CustomIntroSlider from "./src/components/Custom/CustomIntroSlider";
|
import CustomIntroSlider from "./src/components/Custom/CustomIntroSlider";
|
||||||
import {Linking, SplashScreen} from 'expo';
|
import {SplashScreen} from 'expo';
|
||||||
import ThemeManager from './src/managers/ThemeManager';
|
import ThemeManager from './src/managers/ThemeManager';
|
||||||
import {NavigationContainer} from '@react-navigation/native';
|
import {NavigationContainer} from '@react-navigation/native';
|
||||||
import {createStackNavigator} from '@react-navigation/stack';
|
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 AprilFoolsManager from "./src/managers/AprilFoolsManager";
|
||||||
import Update from "./src/constants/Update";
|
import Update from "./src/constants/Update";
|
||||||
import ConnectionManager from "./src/managers/ConnectionManager";
|
import ConnectionManager from "./src/managers/ConnectionManager";
|
||||||
|
import URLHandler from "./src/utils/URLHandler";
|
||||||
|
|
||||||
type Props = {};
|
type Props = {};
|
||||||
|
|
||||||
|
@ -43,11 +44,13 @@ export default class App extends React.Component<Props, State> {
|
||||||
|
|
||||||
navigatorRef: Object;
|
navigatorRef: Object;
|
||||||
|
|
||||||
defaultRoute: Array<string>;
|
defaultRoute: string | null;
|
||||||
defaultData: Object;
|
defaultData: Object;
|
||||||
|
|
||||||
createDrawerNavigator: Function;
|
createDrawerNavigator: Function;
|
||||||
|
|
||||||
|
urlHandler: URLHandler;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
LocaleManager.initTranslations();
|
LocaleManager.initTranslations();
|
||||||
|
@ -55,61 +58,25 @@ export default class App extends React.Component<Props, State> {
|
||||||
this.onUpdateTheme = this.onUpdateTheme.bind(this);
|
this.onUpdateTheme = this.onUpdateTheme.bind(this);
|
||||||
SplashScreen.preventAutoHide();
|
SplashScreen.preventAutoHide();
|
||||||
this.navigatorRef = React.createRef();
|
this.navigatorRef = React.createRef();
|
||||||
this.defaultRoute = [];
|
this.defaultRoute = null;
|
||||||
this.defaultData = {};
|
this.defaultData = {};
|
||||||
// this.defaultRoute = ["main", "home", "club-information"];
|
this.urlHandler = new URLHandler(this.onInitialURLParsed, this.onDetectURL);
|
||||||
// this.defaultData = {clubId: 0};
|
this.urlHandler.listen();
|
||||||
this.handleUrls();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
handleUrls() {
|
onInitialURLParsed = ({route, data}: Object) => {
|
||||||
console.log(Linking.makeUrl('main/home/club-information', {clubId: 1}));
|
this.defaultRoute = route;
|
||||||
Linking.addEventListener('url', this.onUrl);
|
this.defaultData = data;
|
||||||
Linking.parseInitialURLAsync().then(this.onParsedUrl);
|
|
||||||
}
|
|
||||||
|
|
||||||
onUrl = (url: string) => {
|
|
||||||
this.onParsedUrl(Linking.parse(url));
|
|
||||||
};
|
};
|
||||||
|
|
||||||
onParsedUrl = ({path, queryParams}: Object) => {
|
onDetectURL = ({route, data}: Object) => {
|
||||||
if (path !== null) {
|
// Navigate to nested navigator and pass data to the index screen
|
||||||
let pathArray = path.split('/');
|
this.navigatorRef.current.navigate('home', {
|
||||||
if (this.isClubInformationLink(pathArray))
|
screen: 'index',
|
||||||
this.handleClubInformationUrl(queryParams);
|
params: {nextScreen: route, data: data, shouldOpen: true}
|
||||||
else if (this.isPlanningInformationLink(pathArray))
|
});
|
||||||
this.handlePlanningInformationUrl(queryParams);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
isClubInformationLink(pathArray: Array<string>) {
|
|
||||||
return pathArray[0] === "main" && pathArray[1] === "home" && pathArray[2] === "club-information";
|
|
||||||
}
|
|
||||||
|
|
||||||
isPlanningInformationLink(pathArray: Array<string>) {
|
|
||||||
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
|
* Updates the theme
|
||||||
*/
|
*/
|
||||||
|
@ -156,7 +123,8 @@ export default class App extends React.Component<Props, State> {
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.createDrawerNavigator = () => <DrawerNavigator defaultPath={this.defaultRoute} defaultData={this.defaultData}/>;
|
this.createDrawerNavigator = () => <DrawerNavigator defaultRoute={this.defaultRoute}
|
||||||
|
defaultData={this.defaultData}/>;
|
||||||
this.onLoadFinished();
|
this.onLoadFinished();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -196,7 +196,7 @@ export default class ConnectionManager {
|
||||||
let data = {};
|
let data = {};
|
||||||
if (keys !== null && values !== null && keys.length === values.length)
|
if (keys !== null && values !== null && keys.length === values.length)
|
||||||
data = this.generatePostArguments(keys, values);
|
data = this.generatePostArguments(keys, values);
|
||||||
console.log(data);
|
// console.log(data);
|
||||||
fetch(API_ENDPOINT + path, {
|
fetch(API_ENDPOINT + path, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: new Headers({
|
headers: new Headers({
|
||||||
|
@ -209,7 +209,7 @@ export default class ConnectionManager {
|
||||||
})
|
})
|
||||||
}).then(async (response) => response.json())
|
}).then(async (response) => response.json())
|
||||||
.then((response: response_format) => {
|
.then((response: response_format) => {
|
||||||
console.log(response);
|
// console.log(response);
|
||||||
if (this.isResponseValid(response)) {
|
if (this.isResponseValid(response)) {
|
||||||
if (response.error === ERROR_TYPE.SUCCESS)
|
if (response.error === ERROR_TYPE.SUCCESS)
|
||||||
resolve(response.data);
|
resolve(response.data);
|
||||||
|
|
|
@ -317,35 +317,25 @@ function getDrawerContent(props) {
|
||||||
}
|
}
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
defaultPath: Array<string>,
|
defaultRoute: string | null,
|
||||||
defaultData: Object
|
defaultData: Object
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export default class DrawerNavigator extends React.Component<Props> {
|
export default class DrawerNavigator extends React.Component<Props> {
|
||||||
|
|
||||||
defaultRoute: string;
|
|
||||||
defaultSubRoute: string | null;
|
|
||||||
|
|
||||||
createTabNavigator: Object;
|
createTabNavigator: Object;
|
||||||
|
|
||||||
constructor(props: Object) {
|
constructor(props: Object) {
|
||||||
super(props);
|
super(props);
|
||||||
this.defaultRoute = 'Main';
|
|
||||||
this.defaultSubRoute = null;
|
|
||||||
|
|
||||||
if (props.defaultPath.length > 0)
|
this.createTabNavigator = () => <TabNavigator defaultRoute={props.defaultRoute} defaultData={props.defaultData}/>
|
||||||
this.defaultRoute = props.defaultPath[0];
|
|
||||||
if (props.defaultPath.length > 1)
|
|
||||||
this.defaultSubRoute = props.defaultPath[1];
|
|
||||||
|
|
||||||
this.createTabNavigator = () => <TabNavigator defaultPath={props.defaultPath} defaultData={props.defaultData}/>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<Drawer.Navigator
|
<Drawer.Navigator
|
||||||
initialRouteName={this.defaultRoute}
|
initialRouteName={'Main'}
|
||||||
headerMode={'float'}
|
headerMode={'float'}
|
||||||
backBehavior={'initialRoute'}
|
backBehavior={'initialRoute'}
|
||||||
drawerType={'front'}
|
drawerType={'front'}
|
||||||
|
|
|
@ -145,6 +145,10 @@ function PlanningStackComponent() {
|
||||||
const HomeStack = createStackNavigator();
|
const HomeStack = createStackNavigator();
|
||||||
|
|
||||||
function HomeStackComponent(initialRoute: string | null, defaultData: Object) {
|
function HomeStackComponent(initialRoute: string | null, defaultData: Object) {
|
||||||
|
let data;
|
||||||
|
if (initialRoute !== null)
|
||||||
|
data = {data: defaultData, nextScreen: initialRoute, shouldOpen: true};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<HomeStack.Navigator
|
<HomeStack.Navigator
|
||||||
initialRouteName={"index"}
|
initialRouteName={"index"}
|
||||||
|
@ -161,7 +165,7 @@ function HomeStackComponent(initialRoute: string | null, defaultData: Object) {
|
||||||
headerLeft: openDrawer
|
headerLeft: openDrawer
|
||||||
};
|
};
|
||||||
}}
|
}}
|
||||||
initialParams={{data: defaultData, nextScreen: initialRoute}}
|
initialParams={data}
|
||||||
/>
|
/>
|
||||||
<HomeStack.Screen
|
<HomeStack.Screen
|
||||||
name="planning-information"
|
name="planning-information"
|
||||||
|
@ -212,7 +216,7 @@ function PlanexStackComponent() {
|
||||||
const Tab = createMaterialBottomTabNavigator();
|
const Tab = createMaterialBottomTabNavigator();
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
defaultPath: Array<string>,
|
defaultRoute: string | null,
|
||||||
defaultData: Object
|
defaultData: Object
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -221,19 +225,17 @@ class TabNavigator extends React.Component<Props>{
|
||||||
createHomeStackComponent: Object;
|
createHomeStackComponent: Object;
|
||||||
colors: Object;
|
colors: Object;
|
||||||
|
|
||||||
|
defaultRoute: string;
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.colors = props.theme.colors;
|
this.colors = props.theme.colors;
|
||||||
this.defaultRoute = AsyncStorageManager.getInstance().preferences.defaultStartScreen.current.toLowerCase();
|
this.defaultRoute = AsyncStorageManager.getInstance().preferences.defaultStartScreen.current.toLowerCase();
|
||||||
this.defaultSubRoute = null;
|
|
||||||
|
|
||||||
if (props.defaultPath.length > 1)
|
if (props.defaultRoute !== null)
|
||||||
this.defaultRoute = props.defaultPath[1];
|
this.defaultRoute = 'home';
|
||||||
if (props.defaultPath.length > 2)
|
|
||||||
this.defaultSubRoute = props.defaultPath[2];
|
|
||||||
|
|
||||||
|
this.createHomeStackComponent = () => HomeStackComponent(props.defaultRoute, props.defaultData);
|
||||||
this.createHomeStackComponent = () => HomeStackComponent(this.defaultSubRoute, props.defaultData);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
|
|
@ -61,6 +61,7 @@ class ClubDisplayScreen extends React.Component<Props, State> {
|
||||||
super(props);
|
super(props);
|
||||||
this.colors = props.theme.colors;
|
this.colors = props.theme.colors;
|
||||||
|
|
||||||
|
console.log(this.props.route.params);
|
||||||
if (this.props.route.params.data !== undefined && this.props.route.params.categories !== undefined) {
|
if (this.props.route.params.data !== undefined && this.props.route.params.categories !== undefined) {
|
||||||
this.displayData = this.props.route.params.data;
|
this.displayData = this.props.route.params.data;
|
||||||
this.categories = this.props.route.params.categories;
|
this.categories = this.props.route.params.categories;
|
||||||
|
|
|
@ -14,6 +14,7 @@ import {openBrowser} from "../utils/WebBrowser";
|
||||||
import ActionsDashBoardItem from "../components/Home/ActionsDashboardItem";
|
import ActionsDashBoardItem from "../components/Home/ActionsDashboardItem";
|
||||||
import HeaderButton from "../components/Custom/HeaderButton";
|
import HeaderButton from "../components/Custom/HeaderButton";
|
||||||
import ConnectionManager from "../managers/ConnectionManager";
|
import ConnectionManager from "../managers/ConnectionManager";
|
||||||
|
import {CommonActions} from '@react-navigation/native';
|
||||||
// import DATA from "../dashboard_data.json";
|
// import DATA from "../dashboard_data.json";
|
||||||
|
|
||||||
|
|
||||||
|
@ -52,9 +53,6 @@ class HomeScreen extends React.Component<Props> {
|
||||||
this.colors = props.theme.colors;
|
this.colors = props.theme.colors;
|
||||||
|
|
||||||
this.isLoggedIn = null;
|
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<Props> {
|
||||||
headerRight: this.getHeaderButton,
|
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 = () => {
|
getHeaderButton = () => {
|
||||||
|
|
76
src/utils/URLHandler.js
Normal file
76
src/utils/URLHandler.js
Normal file
|
@ -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<string>) {
|
||||||
|
return pathArray[0] === "main" && pathArray[1] === "home" && pathArray[2] === "club-information";
|
||||||
|
}
|
||||||
|
|
||||||
|
isPlanningInformationLink(pathArray: Array<string>) {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in a new issue