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 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<Props, State> {
|
|||
|
||||
navigatorRef: Object;
|
||||
|
||||
defaultRoute: Array<string>;
|
||||
defaultRoute: string | null;
|
||||
defaultData: Object;
|
||||
|
||||
createDrawerNavigator: Function;
|
||||
|
||||
urlHandler: URLHandler;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
LocaleManager.initTranslations();
|
||||
|
@ -55,61 +58,25 @@ export default class App extends React.Component<Props, State> {
|
|||
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<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
|
||||
*/
|
||||
|
@ -156,7 +123,8 @@ export default class App extends React.Component<Props, State> {
|
|||
} catch (e) {
|
||||
}
|
||||
|
||||
this.createDrawerNavigator = () => <DrawerNavigator defaultPath={this.defaultRoute} defaultData={this.defaultData}/>;
|
||||
this.createDrawerNavigator = () => <DrawerNavigator defaultRoute={this.defaultRoute}
|
||||
defaultData={this.defaultData}/>;
|
||||
this.onLoadFinished();
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -317,35 +317,25 @@ function getDrawerContent(props) {
|
|||
}
|
||||
|
||||
type Props = {
|
||||
defaultPath: Array<string>,
|
||||
defaultRoute: string | null,
|
||||
defaultData: Object
|
||||
}
|
||||
|
||||
|
||||
export default class DrawerNavigator extends React.Component<Props> {
|
||||
|
||||
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 = () => <TabNavigator defaultPath={props.defaultPath} defaultData={props.defaultData}/>
|
||||
this.createTabNavigator = () => <TabNavigator defaultRoute={props.defaultRoute} defaultData={props.defaultData}/>
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Drawer.Navigator
|
||||
initialRouteName={this.defaultRoute}
|
||||
initialRouteName={'Main'}
|
||||
headerMode={'float'}
|
||||
backBehavior={'initialRoute'}
|
||||
drawerType={'front'}
|
||||
|
|
|
@ -145,6 +145,10 @@ function PlanningStackComponent() {
|
|||
const HomeStack = createStackNavigator();
|
||||
|
||||
function HomeStackComponent(initialRoute: string | null, defaultData: Object) {
|
||||
let data;
|
||||
if (initialRoute !== null)
|
||||
data = {data: defaultData, nextScreen: initialRoute, shouldOpen: true};
|
||||
|
||||
return (
|
||||
<HomeStack.Navigator
|
||||
initialRouteName={"index"}
|
||||
|
@ -161,7 +165,7 @@ function HomeStackComponent(initialRoute: string | null, defaultData: Object) {
|
|||
headerLeft: openDrawer
|
||||
};
|
||||
}}
|
||||
initialParams={{data: defaultData, nextScreen: initialRoute}}
|
||||
initialParams={data}
|
||||
/>
|
||||
<HomeStack.Screen
|
||||
name="planning-information"
|
||||
|
@ -212,7 +216,7 @@ function PlanexStackComponent() {
|
|||
const Tab = createMaterialBottomTabNavigator();
|
||||
|
||||
type Props = {
|
||||
defaultPath: Array<string>,
|
||||
defaultRoute: string | null,
|
||||
defaultData: Object
|
||||
}
|
||||
|
||||
|
@ -221,19 +225,17 @@ class TabNavigator extends React.Component<Props>{
|
|||
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() {
|
||||
|
|
|
@ -61,6 +61,7 @@ class ClubDisplayScreen extends React.Component<Props, State> {
|
|||
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;
|
||||
|
|
|
@ -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<Props> {
|
|||
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<Props> {
|
|||
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 = () => {
|
||||
|
|
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