326 lines
9.9 KiB
JavaScript
326 lines
9.9 KiB
JavaScript
import React, {Component} from 'react';
|
|
import {
|
|
TouchableOpacity,
|
|
Linking,
|
|
Platform,
|
|
Image,
|
|
View,
|
|
Modal,
|
|
StyleSheet,
|
|
Text,
|
|
} from 'react-native';
|
|
import PropTypes from 'prop-types';
|
|
import { ViewPropTypes } from 'deprecated-react-native-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} |