unioil-loyalty-rn-app/app/components/navigationapps/NavigationApps.js

326 lines
9.8 KiB
JavaScript

import React, {Component} from 'react';
import {
TouchableOpacity,
Linking,
Platform,
Image,
View,
Modal,
StyleSheet,
Text,
ViewPropTypes,
} from 'react-native';
import PropTypes from 'prop-types';
import ActionSheet from 'react-native-actionsheet';
import {actions, googleMapsTravelModes, mapsTravelModes} from "./NavigationAppsTools";
import Assets from '../../components/assets.manager.js';
import { AdjustableText } from '../text';
const waze = {
title: 'waze',
icon: Assets.directionIcon.wazeIcon,
address: '',
action: actions.navigateByAddress,
lat: '',
lon: '',
travelModes: {},
};
const googleMaps = {
title: 'google maps',
icon: Assets.directionIcon.googleMapsIcon,
address: '',
lat: '',
lon: '',
travelMode: googleMapsTravelModes.driving,
action: actions.navigateByAddress
};
const maps = {
title: 'maps',
icon: Assets.directionIcon.mapsIcon,
address: '',
lat: '',
lon: '',
travelMode: mapsTravelModes.driving,
action: actions.navigateByAddress,
};
class NavigationApps extends Component {
constructor(props) {
super(props);
this.state = {
navApps: {
'waze': {
appDeepLinkUri: (destination) => `https://waze.com/ul?ll=${destination}&navigate=yes`,
...waze,
...props.waze,
},
'googlemaps': {
appDeepLinkUri: `http://maps.google.com/maps?daddr=`,
...googleMaps,
...props.googleMaps
},
...Platform.select({
ios: {
'maps': {
...maps,
...props.maps,
appDeepLinkUri: 'maps://app',
appDeepLinkUriToUse: 'maps://app?',
},
}
})
},
modalVisible: false,
};
this.actionSheetRef = null;
}
handleNavApp = async (navApp) => {
navApp = (typeof navApp === 'string') ? this.capitalizeWord(navApp, false) : navApp;
navApp = (typeof navApp === 'string') ? navApp.replace(' ', '') : navApp;
let navAppItem = this.state.navApps[navApp];
let {address} = this.props;
let {appDeepLinkUri} = navAppItem;
let lat = navAppItem.lat ? navAppItem.lat : '';
let lon = navAppItem.lon ? navAppItem.lon : '';
let latLng = `${lat},${lon}`;
let url;
if(navApp === "googlemaps") {
let label = address;
url = `${appDeepLinkUri}${latLng}(${label})`
} else {
url = `${appDeepLinkUri(latLng)}${latLng}&navigate=yes`;
}
Linking.openURL(url);
};
renderNavigationApps = () => {
const {iconSize} = this.props;
const {navApps} = this.state;
return (
Object.keys(navApps).map((navApp, key) => {
const navAppItem = navApps[navApp];
return (
<TouchableOpacity onPress={() => this.handleNavApp(navApp)} key={key}>
<Image style={{width: iconSize, height: iconSize}} source={navAppItem.icon}/>
</TouchableOpacity>
)
})
)
};
renderNavigationAppsAsModal = () => {
const setModalVisible = (visible) => {
this.setState({modalVisible: visible});
};
const renderModalBtnOpen = () => {
const {modalBtnOpenStyle, modalBtnOpenTitle, modalBtnOpenTextStyle, disable} = this.props;
return (
<TouchableOpacity style={modalBtnOpenStyle} onPress={() => disable ? null : setModalVisible(true)}>
<AdjustableText style={modalBtnOpenTextStyle}>{modalBtnOpenTitle}</AdjustableText>
</TouchableOpacity>
)
};
const renderModalBtnClose = () => {
const {modalBtnCloseStyle, modalBtnCloseTitle, modalBtnCloseTextStyle} = this.props;
return (
<TouchableOpacity style={modalBtnCloseStyle} onPress={() => {
setModalVisible(false)
}}>
<AdjustableText style={modalBtnCloseTextStyle}>{modalBtnCloseTitle}</AdjustableText>
</TouchableOpacity>
)
};
const {modalProps, modalContainerStyle, modalCloseBtnContainerStyle} = this.props;
const {modalVisible} = this.state;
return (
<React.Fragment>
{renderModalBtnOpen()}
<Modal {...modalProps} visible={modalVisible}>
<View style={styles.modalStyle}>
<View style={modalContainerStyle}>
{this.renderNavigationAppsView()}
<View style={modalCloseBtnContainerStyle}>
{renderModalBtnClose()}
</View>
</View>
</View>
</Modal>
</React.Fragment>
)
};
capitalizeWord = (word, isCapitalize) => {
return word.replace(/\b(\w)/g, s => isCapitalize ? s.toUpperCase() : s.toLowerCase());
}
renderNavigationAppsAsActionSheet = () => {
const renderActionSheetOpenBtn = () => {
const {actionSheetBtnOpenStyle, actionSheetBtnOpenTitle, actionSheetBtnOpenTextStyle, disable} = this.props;
return (
<TouchableOpacity style={actionSheetBtnOpenStyle}
onPress={() => disable ? null : this.actionSheetRef.show()}>
<AdjustableText style={actionSheetBtnOpenTextStyle}>{actionSheetBtnOpenTitle}</AdjustableText>
</TouchableOpacity>
)
};
const actionSheetOptions = () => {
const {actionSheetBtnCloseTitle} = this.props;
const {navApps} = this.state;
const actionSheetArray = Object.keys(navApps).map((navApp, key) => {
const navAppItem = navApps[navApp];
return this.capitalizeWord(navAppItem.title, true)
});
actionSheetArray.push(actionSheetBtnCloseTitle);
return actionSheetArray
};
const {actionSheetTitle} = this.props;
return (
<React.Fragment>
{renderActionSheetOpenBtn()}
<ActionSheet
ref={ref => this.actionSheetRef = ref}
title={actionSheetTitle}
options={actionSheetOptions()}
cancelButtonIndex={actionSheetOptions().length - 1}
destructiveButtonIndex={actionSheetOptions().length - 1}
onPress={async (index) => {
if (index !== actionSheetOptions().length - 1) {
await this.handleNavApp(actionSheetOptions()[index])
}
}}
/>
</React.Fragment>
)
};
renderNavigationAppsView = () => {
const {row, viewContainerStyle} = this.props;
return (
<View style={[{flexDirection: row ? 'row' : 'column'}, viewContainerStyle]}>
{this.renderNavigationApps()}
</View>
)
};
renderMainView = () => {
const {viewMode} = this.props;
switch (viewMode) {
case "view":
return (
this.renderNavigationAppsView()
);
case "modal" :
return (
this.renderNavigationAppsAsModal()
);
case "sheet":
return (
this.renderNavigationAppsAsActionSheet()
);
default:
return (
this.renderNavigationAppsView()
);
}
};
render() {
return (
this.renderMainView()
)
}
}
const styles = StyleSheet.create({
modalStyle: {
flex: 1,
flexDirection: 'column',
justifyContent: 'center',
alignItems: 'center'
}
});
NavigationApps.defaultProps = {
iconSize: 100,
viewMode: 'view',
row: false,
viewContainerStyle: {},
modalProps: {},
modalContainerStyle: {},
modalBtnOpenTitle: 'open modal',
modalBtnCloseTitle: 'close modal',
modalBtnCloseContainerStyle: {},
modalBtnCloseStyle: {},
modalBtnCloseTextStyle: {},
modalBtnOpenTextStyle: {},
modalBtnOpenStyle: {},
actionSheetBtnOpenTitle: 'open action sheet',
actionSheetBtnCloseTitle: 'close action sheet',
actionSheetTitle: 'choose navigation app',
actionSheetBtnOpenStyle: {},
actionSheetBtnOpenTextStyle: {},
address: '',
disable: false,
};
NavigationApps.propTypes = {
disable: PropTypes.bool,
iconSize: PropTypes.number,
viewMode: PropTypes.oneOf(['view', 'modal', 'sheet']),
row: PropTypes.bool,
address: PropTypes.string,
containerStyle: ViewPropTypes.style,
modalBtnOpenTitle: PropTypes.string,
modalBtnCloseTitle: PropTypes.string,
modalBtnCloseContainerStyle: ViewPropTypes.style,
modalBtnCloseStyle: ViewPropTypes.style,
modalBtnCloseTextStyle: Text.propTypes.style,
modalBtnOpenTextStyle: Text.propTypes.style,
modalBtnOpenStyle: ViewPropTypes.style,
modalProps: PropTypes.object,
modalContainerStyle: PropTypes.object,
actionSheetBtnOpenTitle: PropTypes.string,
actionSheetBtnCloseTitle: PropTypes.string,
actionSheetTitle: PropTypes.string,
actionSheetBtnOpenStyle: ViewPropTypes.style,
actionSheetBtnOpenTextStyle: Text.propTypes.style,
waze:PropTypes.object,
googleMaps:PropTypes.object,
maps:PropTypes.object
};
export {NavigationApps}