Last active
January 24, 2018 18:57
-
-
Save parappathekappa/000cb565c7bfc57fb3821a07ec7405c6 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { Component } from "react"; | |
import { | |
ActivityIndicator, | |
FlatList, | |
StatusBar, | |
Text, | |
TouchableHighlight, | |
View | |
} from "react-native"; | |
import EStyleSheet from "react-native-extended-stylesheet"; | |
import PropTypes from "prop-types"; | |
import { Location, Permissions } from "expo"; | |
import { ListItem, Separator } from "../components/List"; | |
import { connect } from "react-redux"; | |
import { selectAddress } from "../actions/postcard"; | |
import { compareString } from "../utils/compareString"; | |
import { setLocation } from "../actions/postcard"; | |
import { setAddresses } from "../actions/postcard"; | |
import { clearLocation } from "../actions/postcard"; | |
import { clearAddresses } from "../actions/postcard"; | |
import { setExpoAddresses } from "../actions/postcard"; | |
class AddressList extends Component { | |
static PropTypes = { | |
navigation: PropTypes.object, | |
addresses: PropTypes.array | |
}; | |
state = { | |
loading: true, | |
location: null, | |
addresses: [] | |
}; | |
componentWillMount() { | |
this.masterFunction(); | |
} | |
handlePress = address => { | |
if (!this.props.options.house) { | |
this.props.dispatch(selectAddress(address)); | |
} | |
this.props.navigation.navigate("Preview", { title: "Preview" }); | |
}; | |
// filters out duplicate addresses | |
filterAddresses(addresses) { | |
return this.unique(addresses); | |
} | |
unique(array) { | |
return array.reduce(function(result, object) { | |
if ( | |
!result.find(function(item) { | |
return item.number === object.number; | |
}) | |
) { | |
result.push(object); | |
} | |
return result; | |
}, []); | |
} | |
masterFunction = async () => { | |
let { status } = await Permissions.askAsync(Permissions.LOCATION); | |
if (status !== "granted") { | |
this.setState({ | |
errorMessage: "Permission to access location was denied" | |
}); | |
} | |
let location = await Location.getCurrentPositionAsync({ | |
enableHighAccuracy: true | |
}); | |
if (location.coords.accuracy <= 10) { | |
this.props.dispatch(clearLocation()); | |
this.props.dispatch(clearAddresses()); | |
this.props.dispatch(setLocation(location)); | |
this.getAddresses(location); | |
} else { | |
this.masterFunction(); | |
} | |
}; | |
getAddresses = location => { | |
Location.reverseGeocodeAsync({ | |
latitude: location.coords.latitude, | |
longitude: location.coords.longitude | |
}).then(response => { | |
console.log("RESPONSE:", response); | |
this.props.dispatch(setExpoAddresses(response)); | |
}).then(response => { | |
this.getAddressesFromApi( | |
location.coords.latitude, | |
location.coords.longitude | |
); | |
}).then(response => { | |
this.getMultipleAddressesFromApi(location); | |
}).then(response => { | |
this.pickAddy(); | |
}); | |
}; | |
getAddressesFromApi = (latitude, longitude) => { | |
return fetch("https://miserywhip.com/v1/locate", { | |
method: "POST", | |
headers: { | |
Accept: "application/json", | |
"Content-Type": "application/json" | |
}, | |
body: JSON.stringify({ | |
lat: latitude, | |
lng: longitude | |
}) | |
}) | |
.then(response => response.json()) | |
.then(responseJson => { | |
console.log(responseJson); | |
this.props.dispatch(setAddresses(responseJson.addresses)); | |
}) | |
.catch(error => { | |
console.error(error); | |
}); | |
}; | |
// Hack attack. Move the point around and hit api several times | |
// Remove duplicate addresses from the array | |
// Hold list of lat lng points | |
getMultipleAddressesFromApi = location => { | |
pointsHolder = []; | |
// Earth's radius | |
R = 6371000; | |
// Array of radians | |
radiansArray = [0, 1.57, 3.14, 4.71]; | |
// Distance between points | |
d = 15; | |
// add original lat lng values from location | |
mylat = location.coords.latitude; | |
mylon = location.coords.longitude; | |
pointsHolder.push([mylat, mylon]); | |
// cycle through radiansArray to generate new points | |
for (i = 0; i < radiansArray.length; i++) { | |
brng = radiansArray[i]; | |
mylatrad = mylat * Math.PI / 180; | |
mylonrad = mylon * Math.PI / 180; | |
var newlatrad = Math.asin( | |
Math.sin(mylatrad) * Math.cos(d / R) + | |
Math.cos(mylatrad) * Math.sin(d / R) * Math.cos(brng) | |
); | |
var newlonrad = | |
mylonrad + | |
Math.atan2( | |
Math.sin(brng) * Math.sin(d / R) * Math.cos(mylatrad), | |
Math.cos(d / R) - Math.sin(mylatrad) * Math.sin(newlatrad) | |
); | |
newlat = newlatrad / Math.PI * 180; | |
newlon = newlonrad / Math.PI * 180; | |
pointsHolder.push([newlat, newlon]); | |
} | |
for (i = 0; i < 5; i++) { | |
this.getAddressesFromApi(pointsHolder[i][0], pointsHolder[i][1]); | |
} | |
this.pickAddy(); | |
}; | |
theone = new String(); | |
pickAddy() { | |
// only do this if the user has entered a house number | |
// in the options form | |
if (this.props.options.house) { | |
var myNewAddy = {}; | |
var hnum = Number(this.props.options.house); | |
// Cycle through each address in the list | |
// Find the one that is correct, update selectedAddress | |
for (i = 0; i < this.props.addresses.length; i++) { | |
var addy = String(this.props.addresses[i].number); | |
if (compareString(addy, hnum)) { | |
this.theone = this.props.addresses[i].number; | |
myNewAddy = Object.assign({}, this.props.addresses[i]); | |
myNewAddy.number = this.props.options.house; | |
this.props.dispatch(selectAddress(myNewAddy)); | |
console.log("Selected this address from the list."); | |
console.log(myNewAddy); | |
return; | |
} | |
} | |
// If none of the address list options were correc | |
// Check the expo returned address | |
for (i = 0; i < this.props.expoAddresses.length; i++) { | |
var bigaddy = String(this.props.expoAddresses[i].name); | |
var newind = bigaddy.indexOf(' '); | |
var expoaddy = bigaddy.slice(0, newind); | |
if (compareString(expoaddy, hnum)) { | |
this.theone = this.props.expoAddresses[i].name; | |
myNewAddy = Object.assign({}, this.props.expoAddresses[i]); | |
this.props.dispatch(selectAddress(myNewAddy)); | |
console.log("Selected this address from expo."); | |
console.log(myNewAddy); | |
return; | |
} | |
} | |
// If no hits, just return nothing | |
return; | |
} | |
} | |
render() { | |
if (this.props.addresses.length < 1) { | |
return ( | |
<ActivityIndicator animating size="large" style={{ padding: 20 }} /> | |
); | |
} | |
return ( | |
<View style={styles.container}> | |
<StatusBar barStyle="default" translucent={false} /> | |
<FlatList | |
data={this.props.expoAddresses} | |
renderItem={({ item }) => ( | |
<ListItem | |
text={item.name} | |
selected={item.name === this.theone} | |
onPress={() => this.handlePress(item)} | |
/> | |
)} | |
keyExtractor={(item, index) => index} | |
ItemSeparatorComponent={Separator} | |
/> | |
<FlatList | |
data={this.filterAddresses(this.props.addresses)} | |
renderItem={({ item }) => ( | |
<ListItem | |
text={item.number + " " + item.street} | |
selected={item.number === this.theone} | |
onPress={() => this.handlePress(item)} | |
/> | |
)} | |
keyExtractor={(item, index) => index} | |
ItemSeparatorComponent={Separator} | |
/> | |
<TouchableHighlight | |
style={styles.debugging} | |
onPress={() => this.masterFunction()} | |
> | |
<Text>REFRESH</Text> | |
</TouchableHighlight> | |
<TouchableHighlight | |
style={styles.debugging} | |
onPress={() => alert(JSON.stringify(this.props.addresses))} | |
> | |
<Text>View All Addresses Returned</Text> | |
</TouchableHighlight> | |
</View> | |
); | |
} | |
} | |
const mapStateToProps = state => { | |
const addresses = state.postcard.addresses; | |
const expoAddresses = state.postcard.expoAddresses; | |
const options = state.postcard.options; | |
const selectedAddress = state.postcard.selectedAddress; | |
return { | |
addresses, | |
expoAddresses, | |
options, | |
selectedAddress | |
}; | |
}; | |
const styles = EStyleSheet.create({ | |
container: { | |
flex: 1, | |
paddingTop: 30, | |
justifyContent: "flex-start" | |
}, | |
debugging: { | |
padding: 5, | |
paddingBottom: 20, | |
alignItems: "center" | |
} | |
}); | |
export default connect(mapStateToProps)(AddressList); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { Component } from "react"; | |
import { | |
ActivityIndicator, | |
FlatList, | |
StatusBar, | |
Text, | |
TouchableHighlight, | |
View | |
} from "react-native"; | |
import EStyleSheet from "react-native-extended-stylesheet"; | |
import PropTypes from "prop-types"; | |
import { Location, Permissions } from "expo"; | |
import { ListItem, Separator } from "../components/List"; | |
import { connect } from "react-redux"; | |
import { selectAddress } from "../actions/postcard"; | |
import { pickAddy } from "../utils/pickAddy"; | |
import { getLocationAsync } from "../utils/getLocationAsync"; | |
import { getMultipleAddressesFromApi } from "../utils/getMultipleAddressesFromApi"; | |
import { | |
setLocation, | |
setAddresses, | |
clearLocation, | |
clearAddresses, | |
setExpoAddresses, | |
setAddressStatus | |
} from "../actions/postcard"; | |
class AddressList extends Component { | |
static PropTypes = { | |
navigation: PropTypes.object, | |
addresses: PropTypes.array | |
}; | |
state = { | |
loading: true, | |
location: null, | |
addresses: [] | |
}; | |
componentWillMount() { | |
// Clear cache and get users location | |
this.masterFunction(); | |
} | |
handlePress = address => { | |
if (!this.props.options.house) { | |
this.props.dispatch(selectAddress(address)); | |
} | |
this.props.navigation.navigate("Preview", { title: "Preview" }); | |
}; | |
// filters out duplicate addresses | |
filterAddresses(addresses) { | |
return this.unique(addresses); | |
} | |
unique(array) { | |
return array.reduce(function(result, object) { | |
if ( | |
!result.find(function(item) { | |
return item.number === object.number; | |
}) | |
) { | |
result.push(object); | |
} | |
return result; | |
}, []); | |
} | |
masterFunction = () => { | |
// Clear Cache | |
this.props.dispatch(clearLocation()); | |
this.props.dispatch(clearAddresses()); | |
this.props.dispatch(setAddressStatus("Finding your location...")); | |
// Get the users location | |
this.getAddresses(); | |
} | |
getAddresses = () => { | |
// Get the users location | |
let myLocation = getLocationAsync() | |
.then(location => { | |
if (location.coords.accuracy <= 1000) { | |
console.log("Accuracy Reached!"); | |
this.props.dispatch(setLocation(location)); | |
this.props.dispatch(setAddressStatus("Loading Address List...")); | |
// Get the expo address | |
Location.reverseGeocodeAsync({ | |
latitude: location.coords.latitude, | |
longitude: location.coords.longitude | |
}).then(response => { | |
// Update the state with Expo Address | |
console.log("Expo Address Returned"); | |
this.props.dispatch(setExpoAddresses(response)); | |
}).catch(error => { | |
console.error(error); | |
}); | |
// Get multiple addresses from the api using a hack method | |
// of moving a point around a bunch of times | |
getMultipleAddressesFromApi( | |
location | |
).then(masterlist => { | |
// Update the state with list from API | |
console.log("API Addresses Returned"); | |
this.props.dispatch(setAddresses(masterlist)); | |
}).then(() => { | |
// Select the correct addy from the list | |
var selectedAddy = pickAddy( | |
this.props.options.house, | |
this.props.expoAddresses, | |
this.props.addresses | |
); | |
this.props.dispatch(selectAddress(selectedAddy.myNewAddy)); | |
this.theone = selectedAddy.theone; | |
this.props.dispatch(setAddressStatus("All loaded!")); | |
}).catch(error => { | |
console.error(error); | |
}); | |
} else { | |
console.log("Accuracy: " + location.coords.accuracy); | |
// Repeat every second until the accuracy threshold is reached | |
setTimeout(() => { | |
this.getAddresses(); | |
}, 1000); | |
} | |
}) | |
}; | |
theone = new String(); | |
render() { | |
// Spinning icon for waiting for the list | |
// if (this.props.addresses.length < 1 || this.props.expoAddresses.length < 1) { | |
// return ( | |
// <ActivityIndicator animating size="large" style={{ padding: 20 }} /> | |
// ); | |
// } | |
return ( | |
<View style={styles.container}> | |
<StatusBar barStyle="default" translucent={false} /> | |
{/* Status message */} | |
<Text> | |
{this.props.addressStatus} | |
</Text> | |
<FlatList | |
data={this.filterAddresses(this.props.expoAddresses)} | |
renderItem={({ item }) => ( | |
<ListItem | |
text={item.name} | |
selected={item.name === this.theone} | |
onPress={() => this.handlePress(item)} | |
/> | |
)} | |
keyExtractor={(item, index) => index} | |
ItemSeparatorComponent={Separator} | |
/> | |
<FlatList | |
data={this.filterAddresses(this.props.addresses)} | |
// data={this.props.addresses} | |
renderItem={({ item }) => ( | |
<ListItem | |
text={item.number + " " + item.street} | |
selected={item.number === this.theone} | |
onPress={() => this.handlePress(item)} | |
/> | |
)} | |
keyExtractor={(item, index) => index} | |
ItemSeparatorComponent={Separator} | |
/> | |
<TouchableHighlight | |
style={styles.debugging} | |
// onPress={() => this.getLocationAsync()} | |
onPress={() => this.masterFunction()} | |
> | |
<Text>REFRESH</Text> | |
</TouchableHighlight> | |
<TouchableHighlight | |
style={styles.debugging} | |
onPress={() => alert(JSON.stringify(this.props.addresses))} | |
> | |
<Text>View All Addresses Returned</Text> | |
</TouchableHighlight> | |
</View> | |
); | |
} | |
} | |
const mapStateToProps = state => { | |
const addresses = state.postcard.addresses; | |
const expoAddresses = state.postcard.expoAddresses; | |
const options = state.postcard.options; | |
const selectedAddress = state.postcard.selectedAddress; | |
const addressStatus = state.postcard.addressStatus; | |
return { | |
addresses, | |
expoAddresses, | |
options, | |
selectedAddress, | |
addressStatus | |
}; | |
}; | |
const styles = EStyleSheet.create({ | |
container: { | |
flex: 1, | |
paddingTop: 30, | |
justifyContent: "flex-start" | |
}, | |
debugging: { | |
padding: 5, | |
paddingBottom: 20, | |
alignItems: "center" | |
} | |
}); | |
export default connect(mapStateToProps)(AddressList); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment