Add GPS related disable for buttons

This commit is contained in:
John Lyon-Smith
2018-04-14 14:05:21 -07:00
parent 7e366062b1
commit 84e43b0573
5 changed files with 206 additions and 122 deletions

View File

@@ -7,54 +7,66 @@ import {
Image,
View,
TouchableOpacity,
TouchableHighlight,
} from "react-native"
import MapView, { Marker } from "react-native-maps"
import { Icon, Header } from "../ui"
import { api } from "../API"
import autobind from "autobind-decorator"
import { ifIphoneX } from "react-native-iphone-x-helper"
import { workItemTypeText, pad } from "../util"
import { workItemTypeText, pad, regionContainingPoints } from "../util"
import pinImage from "./images/pin.png"
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#FFFFFF",
alignItems: "flex-start",
justifyContent: "flex-start",
},
})
const minGPSAccuracy = 20
export class Home extends React.Component {
constructor(props) {
super(props)
this.state = {
sections: [],
showWorkItems: true,
region: {
latitude: 43.653908,
longitude: -79.384293,
latitudeDelta: 0.0922,
longitudeDelta: 0.0922,
},
positionInfo: null,
}
this.watchId = navigator.geolocation.watchPosition(
this.handlePositionChange,
null,
{ distanceFilter: 10 }
)
api
.listWorkItemActivities()
.then((list) => {
this.setState({ sections: list.items })
this.setState({
sections: list.items,
region: regionContainingPoints(
list.items.map((item) => item.coordinate),
0.02
),
})
})
.catch((err) => {
console.error(err)
})
}
@autobind
_handleNavigatorEvent(event) {
switch (event.id) {
case "logout":
api.logout().then(() => {
this.props.history.replace("/login")
})
break
case "viewer":
this.props.push("/viewer")
break
componentWillUnmount() {
if (this.watchId) {
navigator.geolocation.clearWatch(this.watchId)
}
}
@autobind
handlePositionChange(positionInfo) {
this.setState({ positionInfo })
}
@autobind
handleMarkerPress(e, sectionIndex) {
if (this.sectionList) {
@@ -88,45 +100,56 @@ export class Home extends React.Component {
@autobind
handleMyLocationPress() {
navigator.geolocation.getCurrentPosition((info) => {
if (this.map) {
this.map.animateToCoordinate({
latitude: info.coords.latitude,
longitude: info.coords.longitude,
})
}
})
if (this.state.positionInfo) {
const coords = this.state.positionInfo.coords
this.map.animateToCoordinate({
latitude: coords.latitude,
longitude: coords.longitude,
})
}
}
@autobind
handleToggleWorkItemsList() {
this.setState({ showWorkItems: !this.state.showWorkItems })
}
render() {
const { sections } = this.state
const { sections, showWorkItems, region, positionInfo } = this.state
return (
<View style={styles.container}>
<View
style={{
flexDirection: "column",
height: "100%",
backgroundColor: "#FFFFFF",
}}>
<Header
title="Work Item Map"
leftButton={{ icon: "logout", onPress: this.handleLogoutPress }}
rightButton={{ icon: "glasses", onPress: this.handleGlassesPress }}
disabled={
!(positionInfo && positionInfo.coords.accuracy <= minGPSAccuracy)
}
/>
<MapView
ref={(ref) => {
this.map = ref
}}
style={{
width: "100%",
height: "50%",
}}
style={[
{
width: "100%",
},
showWorkItems && { height: "40%" },
!showWorkItems && { flexGrow: 1 },
]}
showsUserLocation
showsBuildings={false}
showsTraffic={false}
showsIndoors={false}
zoomControlEnabled
initialRegion={{
latitude: 43.653908,
longitude: -79.384293,
latitudeDelta: 0.0922,
longitudeDelta: 0.0922,
}}>
region={region}>
{sections.map((workItem, index) => (
<Marker
key={index}
@@ -145,103 +168,131 @@ export class Home extends React.Component {
</MapView>
<View
style={{
flexDirection: "row",
alignItems: "center",
display: showWorkItems ? "flex" : "none",
flexDirection: "column",
flexGrow: 1,
flexBasis: 0,
width: "100%",
height: 40,
backgroundColor: "white",
}}>
<Icon
name="search"
size={16}
style={{ marginLeft: 10, marginRight: 5, tintColor: "gray" }}
/>
<TextInput
style={{ flexGrow: 1, flexBasis: 0, height: "100%" }}
underlineColorAndroid="white"
placeholder="Search"
/>
<Icon
name="cancel"
size={16}
style={{ marginLeft: 5, marginRight: 10, tintColor: "gray" }}
<View
style={{
flexDirection: "row",
alignItems: "center",
width: "100%",
height: 40,
backgroundColor: "white",
}}>
<Icon
name="search"
size={16}
style={{ marginLeft: 10, marginRight: 5, tintColor: "gray" }}
/>
<TextInput
style={{ flexGrow: 1, flexBasis: 0, height: "100%" }}
underlineColorAndroid="white"
placeholder="Search"
/>
<Icon
style={{ marginLeft: 5, marginRight: 10 }}
name="cancel"
size={16}
/>
</View>
<SectionList
ref={(ref) => (this.sectionList = ref)}
style={{ width: "100%", flexGrow: 1 }}
sections={sections}
stickySectionHeadersEnabled={true}
renderSectionHeader={({ section: workItem }) => (
<View
key={workItem._id}
style={{
flexDirection: "column",
justifyContent: "center",
backgroundColor: "#F4F4F4",
paddingLeft: 8,
height: 45,
}}>
<Text style={{ fontSize: 16 }}>
{workItemTypeText[workItem.workItemType].toUpperCase()}{" "}
{pad(workItem.ticketNumber, 4)}
</Text>
</View>
)}
keyExtractor={(item) => item._id}
renderItem={({ item: activity, section }) => {
return (
<TouchableHighlight
style={{
height: 50,
paddingLeft: 20,
paddingRight: 20,
backgroundColor: "white",
}}
underlayColor="#EEEEEE"
onPress={() => this.handleItemSelect(activity, index)}>
<View
style={{
height: "100%",
width: "100%",
flexDirection: "row",
}}>
<Text
style={{
fontSize: 8,
width: 45,
alignSelf: "center",
}}>
{activity.status.toUpperCase()}
</Text>
<View
style={{
flexGrow: 1,
flexBasis: 0,
flexDirection: "column",
}}>
<Text style={{ fontSize: 20, fontWeight: "bold" }}>
{activity.resolution}
</Text>
<Text style={{ fontSize: 14, color: "gray" }}>
{activity.address || "..."}
</Text>
</View>
<Icon
name="rightArrow"
size={16}
style={{ alignSelf: "center" }}
/>
</View>
</TouchableHighlight>
)
}}
/>
</View>
<SectionList
ref={(ref) => (this.sectionList = ref)}
style={{ width: "100%", flexGrow: 1 }}
sections={sections}
stickySectionHeadersEnabled={true}
renderSectionHeader={({ section: workItem }) => (
<View
key={workItem._id}
style={{
flexDirection: "column",
justifyContent: "center",
backgroundColor: "#F4F4F4",
paddingLeft: 8,
height: 45,
}}>
<Text style={{ fontSize: 16 }}>
{workItemTypeText[workItem.workItemType].toUpperCase()}{" "}
{pad(workItem.ticketNumber, 4)}
</Text>
</View>
)}
keyExtractor={(item) => item._id}
renderItem={({ item: activity, section }) => {
return (
<View
style={{
flexDirection: "row",
height: 50,
marginTop: 3,
marginBottom: 3,
}}>
<Text
style={{
fontSize: 8,
width: 45,
marginLeft: 5,
alignSelf: "center",
}}>
{activity.status.toUpperCase()}
</Text>
<View style={{ width: "75%", flexDirection: "column" }}>
<Text style={{ fontSize: 20, fontWeight: "bold" }}>
{activity.resolution}
</Text>
<Text style={{ fontSize: 14, color: "gray" }}>
{activity.address || "..."}
</Text>
</View>
<TouchableOpacity
style={{ alignSelf: "center" }}
onPress={() => this.handleItemSelect(activity, index)}>
<Icon name="rightArrow" size={16} />
</TouchableOpacity>
</View>
)
}}
/>
<View
style={{
flexDirection: "row",
justifyContent: "space-between",
alignItems: "center",
width: "100%",
height: 45,
height: 55,
backgroundColor: "#F4F4F4",
...ifIphoneX({ marginBottom: 22 }, {}),
}}>
<TouchableOpacity onPress={this.handleMyLocationPress}>
<TouchableOpacity
disabled={!positionInfo}
onPress={this.handleMyLocationPress}>
<Icon
name="center"
size={24}
style={{ marginLeft: 15, tintColor: "gray" }}
/>
</TouchableOpacity>
<Text style={{ color: "gray", fontSize: 20 }}>Hide List</Text>
<TouchableOpacity onPress={this.handleToggleWorkItemsList}>
<Text style={{ color: "gray", fontSize: 20 }}>
{showWorkItems ? "Hide List" : "Show List"}
</Text>
</TouchableOpacity>
<TouchableOpacity onPress={this.handleWorkItemsListPress}>
<Icon
name="settings"

View File

@@ -145,7 +145,6 @@ export class WorkItemList extends React.Component {
style={{
fontSize: 10,
width: 45,
marginLeft: 5,
alignSelf: "center",
}}>
{pad(item.ticketNumber, 4)}

View File

@@ -1,3 +1,3 @@
export const localIPAddr = "192.168.1.175"
// export const defaultUser = "john@lyon-smith.org"
export const defaultUser = ""
export const defaultUser = "john@lyon-smith.org"
// export const defaultUser = ""

View File

@@ -8,6 +8,7 @@ const images = {
back: require("./images/back.png"),
hand: require("./images/hand.png"),
center: require("./images/center.png"),
cancel: require("./images/cancel.png"),
rightArrow: require("./images/right-arrow.png"),
search: require("./images/search.png"),
settings: require("./images/settings.png"),

View File

@@ -55,3 +55,36 @@ export const pad = (num, size) => {
while (s.length < size) s = "0" + s
return s
}
export const regionContainingPoints = (points, inset) => {
let minX, maxX, minY, maxY
// init first point
;((point) => {
minX = point.latitude
maxX = point.latitude
minY = point.longitude
maxY = point.longitude
})(points[0])
// calculate rect
points.map((point) => {
minX = Math.min(minX, point.latitude)
maxX = Math.max(maxX, point.latitude)
minY = Math.min(minY, point.longitude)
maxY = Math.max(maxY, point.longitude)
})
const midX = (minX + maxX) / 2
const midY = (minY + maxY) / 2
const midPoint = [midX, midY]
const deltaX = maxX - minX + inset
const deltaY = maxY - minY + inset
return {
latitude: midX,
longitude: midY,
latitudeDelta: deltaX,
longitudeDelta: deltaY,
}
}