Target tracking location, BoundHeader, WorkItem page done.
This commit is contained in:
Binary file not shown.
@@ -6,6 +6,7 @@
|
|||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
|
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
|
||||||
<uses-permission android:name="android.permission.CAMERA" />
|
<uses-permission android:name="android.permission.CAMERA" />
|
||||||
|
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||||
|
|
||||||
<uses-sdk
|
<uses-sdk
|
||||||
android:minSdkVersion="24"
|
android:minSdkVersion="24"
|
||||||
|
|||||||
@@ -37,8 +37,6 @@
|
|||||||
</dict>
|
</dict>
|
||||||
<key>NSCameraUsageDescription</key>
|
<key>NSCameraUsageDescription</key>
|
||||||
<string>$(PRODUCT_NAME) camera use</string>
|
<string>$(PRODUCT_NAME) camera use</string>
|
||||||
<key>NSLocationWhenInUseUsageDescription</key>
|
|
||||||
<string></string>
|
|
||||||
<key>NSPhotoLibraryUsageDescription</key>
|
<key>NSPhotoLibraryUsageDescription</key>
|
||||||
<string>$(PRODUCT_NAME) photo use</string>
|
<string>$(PRODUCT_NAME) photo use</string>
|
||||||
<key>UILaunchStoryboardName</key>
|
<key>UILaunchStoryboardName</key>
|
||||||
@@ -52,6 +50,8 @@
|
|||||||
<string>UIInterfaceOrientationPortrait</string>
|
<string>UIInterfaceOrientationPortrait</string>
|
||||||
<string>UIInterfaceOrientationPortraitUpsideDown</string>
|
<string>UIInterfaceOrientationPortraitUpsideDown</string>
|
||||||
</array>
|
</array>
|
||||||
|
<key>NSLocationWhenInUseUsageDescription</key>
|
||||||
|
<string>$(PRODUCT_NAME) location use</string>
|
||||||
<key>UIViewControllerBasedStatusBarAppearance</key>
|
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||||
<false/>
|
<false/>
|
||||||
</dict>
|
</dict>
|
||||||
|
|||||||
5
mobile/package-lock.json
generated
5
mobile/package-lock.json
generated
@@ -5451,6 +5451,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/react-native-iphone-x-helper/-/react-native-iphone-x-helper-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/react-native-iphone-x-helper/-/react-native-iphone-x-helper-1.0.2.tgz",
|
||||||
"integrity": "sha512-5FYNC4kTi/YK86l+r8GQ0xgsSL2tleCQ5Yppu1+ARbnm2qGRmDoJTGSNsWBAWa8FP1ORyhMjxi18IlvSRKaI2g=="
|
"integrity": "sha512-5FYNC4kTi/YK86l+r8GQ0xgsSL2tleCQ5Yppu1+ARbnm2qGRmDoJTGSNsWBAWa8FP1ORyhMjxi18IlvSRKaI2g=="
|
||||||
},
|
},
|
||||||
|
"react-native-keyboard-spacer": {
|
||||||
|
"version": "0.4.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-native-keyboard-spacer/-/react-native-keyboard-spacer-0.4.1.tgz",
|
||||||
|
"integrity": "sha1-RvGKMgQyCYol6p+on1FD3SVNMy0="
|
||||||
|
},
|
||||||
"react-native-maps": {
|
"react-native-maps": {
|
||||||
"version": "0.20.1",
|
"version": "0.20.1",
|
||||||
"resolved": "https://registry.npmjs.org/react-native-maps/-/react-native-maps-0.20.1.tgz",
|
"resolved": "https://registry.npmjs.org/react-native-maps/-/react-native-maps-0.20.1.tgz",
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
"react-form-binder": "^1.2.0",
|
"react-form-binder": "^1.2.0",
|
||||||
"react-native": "^0.51.1",
|
"react-native": "^0.51.1",
|
||||||
"react-native-iphone-x-helper": "^1.0.2",
|
"react-native-iphone-x-helper": "^1.0.2",
|
||||||
|
"react-native-keyboard-spacer": "^0.4.1",
|
||||||
"react-native-maps": "^0.20.1",
|
"react-native-maps": "^0.20.1",
|
||||||
"react-native-modal": "^5.4.0",
|
"react-native-modal": "^5.4.0",
|
||||||
"react-router-native": "^4.2.0",
|
"react-router-native": "^4.2.0",
|
||||||
|
|||||||
@@ -44,7 +44,6 @@ class APIError extends Error {
|
|||||||
class API extends EventEmitter {
|
class API extends EventEmitter {
|
||||||
constructor() {
|
constructor() {
|
||||||
super()
|
super()
|
||||||
// We don't know if the user has a valid token yet so assume they do and clean-up if they don't
|
|
||||||
this.user = { pending: true }
|
this.user = { pending: true }
|
||||||
|
|
||||||
AsyncStorage.getItem(authTokenName).then((token) => {
|
AsyncStorage.getItem(authTokenName).then((token) => {
|
||||||
|
|||||||
@@ -2,5 +2,6 @@ import React, { Fragment, Component } from 'react'
|
|||||||
import { Route, Redirect } from 'react-router-native'
|
import { Route, Redirect } from 'react-router-native'
|
||||||
|
|
||||||
export const DefaultRoute = () => {
|
export const DefaultRoute = () => {
|
||||||
return <Route render={() => (<Redirect to={'/home'} />)} />
|
// NOTE: When working on the app, change this to the page you are working on
|
||||||
|
return <Route render={() => (<Redirect to={'/workitem'} />)} />
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,13 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import { StyleSheet, Text, TextInput, FlatList, Image, View, TouchableOpacity } from 'react-native'
|
import {
|
||||||
|
StyleSheet,
|
||||||
|
Text,
|
||||||
|
TextInput,
|
||||||
|
FlatList,
|
||||||
|
Image,
|
||||||
|
View,
|
||||||
|
TouchableOpacity,
|
||||||
|
} from 'react-native'
|
||||||
import MapView, { Marker } from 'react-native-maps'
|
import MapView, { Marker } from 'react-native-maps'
|
||||||
import { Icon, Header } from '../ui'
|
import { Icon, Header } from '../ui'
|
||||||
import { api } from '../API'
|
import { api } from '../API'
|
||||||
@@ -66,20 +74,34 @@ export class Home extends React.Component {
|
|||||||
this.props.history.push('/arviewer')
|
this.props.history.push('/arviewer')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@autobind
|
||||||
|
handleMyLocationPress() {
|
||||||
|
navigator.geolocation.getCurrentPosition((info) => {
|
||||||
|
if (this.map) {
|
||||||
|
this.map.animateToCoordinate({latitude: info.coords.latitude, longitude: info.coords.longitude})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<View style={styles.container}>
|
<View style={styles.container}>
|
||||||
<Header title='Work Item Map' leftButton={{ icon: 'logout', onPress: this.handleLogoutPress }} rightButton={{ icon: 'glasses', onPress: this.handleGlassesPress }} />
|
<Header title='Work Item Map' leftButton={{ icon: 'logout', onPress: this.handleLogoutPress }} rightButton={{ icon: 'glasses', onPress: this.handleGlassesPress }} />
|
||||||
<MapView
|
<MapView
|
||||||
|
ref={ref => { this.map = ref }}
|
||||||
style={{
|
style={{
|
||||||
width: '100%', height: '50%',
|
width: '100%', height: '50%',
|
||||||
}}
|
}}
|
||||||
|
showsUserLocation
|
||||||
|
showsBuildings={false}
|
||||||
|
showsTraffic={false}
|
||||||
|
showsIndoors={false}
|
||||||
zoomControlEnabled
|
zoomControlEnabled
|
||||||
initialRegion={{
|
initialRegion={{
|
||||||
latitude: 43.653908,
|
latitude: 43.653908,
|
||||||
longitude: -79.384293,
|
longitude: -79.384293,
|
||||||
latitudeDelta: 0.0922,
|
latitudeDelta: 0.0922,
|
||||||
longitudeDelta: 0.0421,
|
longitudeDelta: 0.0922,
|
||||||
}}>
|
}}>
|
||||||
{
|
{
|
||||||
data.map(marker => (
|
data.map(marker => (
|
||||||
|
|||||||
@@ -10,10 +10,17 @@ import {
|
|||||||
Platform,
|
Platform,
|
||||||
TouchableOpacity
|
TouchableOpacity
|
||||||
} from 'react-native'
|
} from 'react-native'
|
||||||
import { Icon, Header, PhotoButton } from '../ui'
|
|
||||||
import MapView, { Marker } from 'react-native-maps'
|
import MapView, { Marker } from 'react-native-maps'
|
||||||
import { FormBinder } from 'react-form-binder'
|
import { FormBinder } from 'react-form-binder'
|
||||||
import { BoundInput, BoundButton } from '../ui'
|
import {
|
||||||
|
BoundInput,
|
||||||
|
BoundButton,
|
||||||
|
BoundHeader,
|
||||||
|
Icon,
|
||||||
|
Header,
|
||||||
|
PhotoButton,
|
||||||
|
BoundOptionStrip,
|
||||||
|
} from '../ui'
|
||||||
import autobind from 'autobind-decorator'
|
import autobind from 'autobind-decorator'
|
||||||
import { ifIphoneX, isIphoneX } from 'react-native-iphone-x-helper'
|
import { ifIphoneX, isIphoneX } from 'react-native-iphone-x-helper'
|
||||||
|
|
||||||
@@ -39,12 +46,26 @@ const styles = StyleSheet.create({
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const workItemOptions = [
|
||||||
|
{ value: 'workOrder', text: 'Work Order' },
|
||||||
|
{ value: 'inspection', text: 'Inspection' },
|
||||||
|
{ value: 'complaint', text: 'Complaint' }
|
||||||
|
]
|
||||||
|
|
||||||
export class WorkItem extends React.Component {
|
export class WorkItem extends React.Component {
|
||||||
static bindings = {
|
static bindings = {
|
||||||
|
header: {
|
||||||
|
noValue: true,
|
||||||
|
isDisabled: (r) => (!(r.anyModified && r.allValid)),
|
||||||
|
},
|
||||||
location: {
|
location: {
|
||||||
isValid: true,
|
isValid: true,
|
||||||
|
isDisabled: true,
|
||||||
},
|
},
|
||||||
details: {
|
details: {
|
||||||
|
isValid: (r, v) => (v !== ''),
|
||||||
|
},
|
||||||
|
workItemType: {
|
||||||
isValid: true,
|
isValid: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -68,6 +89,22 @@ export class WorkItem extends React.Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@autobind
|
||||||
|
handleDonePress() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@autobind
|
||||||
|
handleRegionChange(region) {
|
||||||
|
const { binder } = this.state
|
||||||
|
// NOTE: For some reason, object destructuring does not work here :(
|
||||||
|
const lon = region.longitude
|
||||||
|
const lat = region.latitude
|
||||||
|
|
||||||
|
this.setState(binder.updateFieldValue('location',
|
||||||
|
`${Math.abs(lon).toFixed(4)}°${lon > 0 ? 'S' : 'N'}, ${Math.abs(lat).toFixed(4)}°${lat > 0 ? 'W' : 'E'}`))
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { binder } = this.state
|
const { binder } = this.state
|
||||||
|
|
||||||
@@ -76,11 +113,21 @@ export class WorkItem extends React.Component {
|
|||||||
style={{ width: '100%', height: '100%' }}
|
style={{ width: '100%', height: '100%' }}
|
||||||
behavior='padding'
|
behavior='padding'
|
||||||
keyboardVerticalOffset={Platform.select({ios: 0, android: -220})}>
|
keyboardVerticalOffset={Platform.select({ios: 0, android: -220})}>
|
||||||
<Header title='Work Item' leftButton={{ icon: 'back', onPress: this.handleBackPress }} rightButton={{ icon: 'done' }} />
|
<BoundHeader
|
||||||
|
binder={binder}
|
||||||
|
name='header'
|
||||||
|
title='Work Item'
|
||||||
|
leftButton={{ icon: 'back', onPress: this.handleBackPress }}
|
||||||
|
rightButton={{ icon: 'done', onPress: this.handleDonePress }} />
|
||||||
<ScrollView style={styles.container}>
|
<ScrollView style={styles.container}>
|
||||||
|
<View style={styles.panel}>
|
||||||
|
<BoundOptionStrip binder={binder} name='workItemType' label='Work Item Type:' options={workItemOptions} />
|
||||||
|
</View>
|
||||||
<View style={styles.panel}>
|
<View style={styles.panel}>
|
||||||
<MapView
|
<MapView
|
||||||
style={{
|
style={{
|
||||||
|
flexDirection: 'column',
|
||||||
|
justifyContent: 'center',
|
||||||
width: '100%',
|
width: '100%',
|
||||||
height: 400,
|
height: 400,
|
||||||
marginBottom: 10,
|
marginBottom: 10,
|
||||||
@@ -91,7 +138,10 @@ export class WorkItem extends React.Component {
|
|||||||
longitude: -79.384293,
|
longitude: -79.384293,
|
||||||
latitudeDelta: 0.0922,
|
latitudeDelta: 0.0922,
|
||||||
longitudeDelta: 0.0421,
|
longitudeDelta: 0.0421,
|
||||||
}} />
|
}}
|
||||||
|
onRegionChange={this.handleRegionChange}>
|
||||||
|
<Icon name='target' size={24} style={{ alignSelf: 'center' }} pointerEvents={false} />
|
||||||
|
</MapView>
|
||||||
<BoundInput binder={binder} name='location' label='Location:' />
|
<BoundInput binder={binder} name='location' label='Location:' />
|
||||||
</View>
|
</View>
|
||||||
<View style={styles.panel}>
|
<View style={styles.panel}>
|
||||||
@@ -103,7 +153,7 @@ export class WorkItem extends React.Component {
|
|||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
<View style={styles.panel}>
|
<View style={styles.panel}>
|
||||||
<BoundInput binder={binder} name='details' label='Details:' message='You must supply details for the work item' />
|
<BoundInput binder={binder} name='details' lines={4} label='Details:' message='You must supply details for the work item' />
|
||||||
</View>
|
</View>
|
||||||
{ isIphoneX ? <View style={{ height: 30, width: '100%' }} /> : null }
|
{ isIphoneX ? <View style={{ height: 30, width: '100%' }} /> : null }
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ export class BoundButton extends React.Component {
|
|||||||
name: PropTypes.string.isRequired,
|
name: PropTypes.string.isRequired,
|
||||||
title: PropTypes.string,
|
title: PropTypes.string,
|
||||||
binder: PropTypes.object.isRequired,
|
binder: PropTypes.object.isRequired,
|
||||||
submit: PropTypes.string,
|
|
||||||
onPress: PropTypes.func,
|
onPress: PropTypes.func,
|
||||||
width: PropTypes.oneOfType([ PropTypes.string, PropTypes.number ]),
|
width: PropTypes.oneOfType([ PropTypes.string, PropTypes.number ]),
|
||||||
}
|
}
|
||||||
@@ -16,7 +15,7 @@ export class BoundButton extends React.Component {
|
|||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props)
|
super(props)
|
||||||
|
|
||||||
let { name, binder } = this.props
|
const { name, binder } = this.props
|
||||||
|
|
||||||
binder.addListener(name, this.updateValue)
|
binder.addListener(name, this.updateValue)
|
||||||
this.state = binder.getFieldState(name)
|
this.state = binder.getFieldState(name)
|
||||||
@@ -40,7 +39,7 @@ export class BoundButton extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { name, title, submit, width, onPress } = this.props
|
const { name, title, width, onPress } = this.props
|
||||||
const { visible, disabled } = this.state
|
const { visible, disabled } = this.state
|
||||||
|
|
||||||
if (!visible) {
|
if (!visible) {
|
||||||
|
|||||||
60
mobile/src/ui/BoundHeader.js
Normal file
60
mobile/src/ui/BoundHeader.js
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import PropTypes from 'prop-types'
|
||||||
|
import { Header } from '.'
|
||||||
|
import autobind from 'autobind-decorator'
|
||||||
|
|
||||||
|
const headerButtonShape = { icon: PropTypes.string.isRequired, onPress: PropTypes.func }
|
||||||
|
|
||||||
|
export class BoundHeader extends React.Component {
|
||||||
|
static propTypes = {
|
||||||
|
name: PropTypes.string.isRequired,
|
||||||
|
title: PropTypes.string,
|
||||||
|
leftButton: PropTypes.shape(headerButtonShape).isRequired,
|
||||||
|
rightButton: PropTypes.shape(headerButtonShape),
|
||||||
|
binder: PropTypes.object.isRequired,
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(props) {
|
||||||
|
super(props)
|
||||||
|
|
||||||
|
const { name, binder } = this.props
|
||||||
|
|
||||||
|
binder.addListener(name, this.updateValue)
|
||||||
|
this.state = binder.getFieldState(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
@autobind
|
||||||
|
updateValue(e) {
|
||||||
|
this.setState(e.state)
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillUnmount() {
|
||||||
|
this.props.binder.removeListener(this.props.name, this.updateValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillReceiveProps(nextProps) {
|
||||||
|
if (nextProps.binder !== this.props.binder) {
|
||||||
|
this.props.binder.removeListener(this.props.name, this.updateValue)
|
||||||
|
nextProps.binder.addListener(nextProps.name, this.updateValue)
|
||||||
|
this.setState(nextProps.binder.getFieldState(nextProps.name))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { title, leftButton } = this.props
|
||||||
|
let { rightButton } = this.props
|
||||||
|
const { visible, disabled } = this.state
|
||||||
|
|
||||||
|
if (!visible) {
|
||||||
|
rightButton = null
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Header
|
||||||
|
title={title}
|
||||||
|
disabled={disabled}
|
||||||
|
leftButton={leftButton}
|
||||||
|
rightButton={rightButton} />
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,7 +10,12 @@ export class BoundInput extends React.Component {
|
|||||||
label: PropTypes.string,
|
label: PropTypes.string,
|
||||||
binder: PropTypes.object.isRequired,
|
binder: PropTypes.object.isRequired,
|
||||||
password: PropTypes.bool,
|
password: PropTypes.bool,
|
||||||
placeholder: PropTypes.string
|
placeholder: PropTypes.string,
|
||||||
|
lines: PropTypes.number,
|
||||||
|
}
|
||||||
|
|
||||||
|
static defaultProps = {
|
||||||
|
lines: 1,
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
@@ -29,19 +34,30 @@ export class BoundInput extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { label, password, name, placeholder, message } = this.props
|
const { label, password, name, placeholder, message, lines } = this.props
|
||||||
const { visible, disabled, value, valid } = this.state
|
const { visible, disabled, value, valid } = this.state
|
||||||
|
|
||||||
if (!visible) {
|
if (!visible) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Disabled
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={{ width: '100%' }}>
|
<View style={{ width: '100%' }}>
|
||||||
<Text style={{ color: 'black', fontSize: 14, marginBottom: 5 }}>{label}</Text>
|
<Text style={{ color: 'black', fontSize: 14, marginBottom: 5 }}>{label}</Text>
|
||||||
<TextInput style={{ width: '100%', paddingLeft: 5, paddingRight: 5, height: 40, borderColor: 'gray', borderWidth: 1, fontSize: 16 }}
|
<TextInput
|
||||||
|
style={{
|
||||||
|
width: '100%',
|
||||||
|
paddingLeft: 5,
|
||||||
|
paddingRight: 5,
|
||||||
|
borderColor: 'gray',
|
||||||
|
borderWidth: 1,
|
||||||
|
fontSize: 16,
|
||||||
|
paddingTop: 7,
|
||||||
|
paddingBottom: 7,
|
||||||
|
}}
|
||||||
|
multiline={lines > 1}
|
||||||
|
numberOfLines={lines}
|
||||||
|
editable={!disabled}
|
||||||
autoCapitalize='none'
|
autoCapitalize='none'
|
||||||
underlineColorAndroid='white'
|
underlineColorAndroid='white'
|
||||||
value={value}
|
value={value}
|
||||||
|
|||||||
@@ -9,17 +9,36 @@ const headerButtonShape = { icon: PropTypes.string.isRequired, onPress: PropType
|
|||||||
export class Header extends Component {
|
export class Header extends Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
title: PropTypes.string.isRequired,
|
title: PropTypes.string.isRequired,
|
||||||
leftButton: PropTypes.shape(headerButtonShape),
|
leftButton: PropTypes.shape(headerButtonShape).isRequired,
|
||||||
rightButton: PropTypes.shape(headerButtonShape),
|
rightButton: PropTypes.shape(headerButtonShape),
|
||||||
|
disabled: PropTypes.bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
rightButton: { icon: 'none' },
|
rightButton: { icon: 'none' },
|
||||||
leftButton: { icon: 'none' },
|
leftButton: { icon: 'none' },
|
||||||
|
visible: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { title, leftButton, rightButton } = this.props
|
const { title, leftButton, rightButton, disabled, visible } = this.props
|
||||||
|
let right = null
|
||||||
|
|
||||||
|
if (!rightButton) {
|
||||||
|
right = (
|
||||||
|
<Icon name='' size={24} style={{ marginRight: 15 }} />
|
||||||
|
)
|
||||||
|
} else if (disabled) {
|
||||||
|
right = (
|
||||||
|
<Icon name={rightButton.icon} size={24} style={{ marginRight: 15, tintColor: 'lightgrey' }} />
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
right = (
|
||||||
|
<TouchableOpacity onPress={rightButton.onPress}>
|
||||||
|
<Icon name={rightButton.icon} size={24} style={{ marginRight: 15, tintColor: 'grey' }} />
|
||||||
|
</TouchableOpacity>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={{
|
<View style={{
|
||||||
@@ -35,9 +54,7 @@ export class Header extends Component {
|
|||||||
<Icon name={leftButton.icon} size={24} style={{ marginLeft: 15, tintColor: 'gray' }} />
|
<Icon name={leftButton.icon} size={24} style={{ marginLeft: 15, tintColor: 'gray' }} />
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
<Text style={{ color: 'gray', fontSize: 18, }}>{title}</Text>
|
<Text style={{ color: 'gray', fontSize: 18, }}>{title}</Text>
|
||||||
<TouchableOpacity onPress={rightButton.onPress}>
|
{right}
|
||||||
<Icon name={rightButton.icon} size={24} style={{ marginRight: 15, tintColor: 'gray' }} />
|
|
||||||
</TouchableOpacity>
|
|
||||||
</View>
|
</View>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ const images = {
|
|||||||
settings: require('./images/settings.png'),
|
settings: require('./images/settings.png'),
|
||||||
add: require('./images/add.png'),
|
add: require('./images/add.png'),
|
||||||
done: require('./images/done.png'),
|
done: require('./images/done.png'),
|
||||||
|
target: require('./images/target.png'),
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Icon extends Component {
|
export class Icon extends Component {
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ export class OptionStrip extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
componentWillReceiveProps(newProps) {
|
componentWillReceiveProps(newProps) {
|
||||||
if (newProps.options !== props.options || newProps.value !== props.value) {
|
if (newProps.options !== this.props.options || newProps.value !== this.props.value) {
|
||||||
this.setState({ selectedIndex: this.getSelectedIndex(newProps.options, newProps.value)})
|
this.setState({ selectedIndex: this.getSelectedIndex(newProps.options, newProps.value)})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 685 B After Width: | Height: | Size: 725 B |
BIN
mobile/src/ui/images/target.png
Normal file
BIN
mobile/src/ui/images/target.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.2 KiB |
@@ -1,8 +1,9 @@
|
|||||||
export { BoundSwitch } from './BoundSwitch'
|
|
||||||
export { BoundInput } from './BoundInput'
|
|
||||||
export { BoundButton } from './BoundButton'
|
|
||||||
export { BoundOptionStrip } from './BoundOptionStrip'
|
|
||||||
export { Icon } from './Icon'
|
export { Icon } from './Icon'
|
||||||
export { Header } from './Header'
|
export { Header } from './Header'
|
||||||
export { PhotoButton } from './PhotoButton'
|
export { PhotoButton } from './PhotoButton'
|
||||||
export { OptionStrip } from './OptionStrip'
|
export { OptionStrip } from './OptionStrip'
|
||||||
|
export { BoundSwitch } from './BoundSwitch'
|
||||||
|
export { BoundInput } from './BoundInput'
|
||||||
|
export { BoundButton } from './BoundButton'
|
||||||
|
export { BoundOptionStrip } from './BoundOptionStrip'
|
||||||
|
export { BoundHeader } from './BoundHeader'
|
||||||
|
|||||||
Reference in New Issue
Block a user