Commit 61fdf8a2 authored by Greg Wilson's avatar Greg Wilson

StepsDemo app mostly functional

parent 419c257e
...@@ -14,6 +14,8 @@ import { ...@@ -14,6 +14,8 @@ import {
View View
} from 'react-native'; } from 'react-native';
import _ from 'lodash'; import _ from 'lodash';
import moment from 'moment';
//import TimerMixin from 'react-timer-mixin'; //import TimerMixin from 'react-timer-mixin';
//var reactMixin = require('react-mixin'); //var reactMixin = require('react-mixin');
import styles from '../../styles/styles'; import styles from '../../styles/styles';
...@@ -50,6 +52,7 @@ class History extends Component { ...@@ -50,6 +52,7 @@ class History extends Component {
return ( return (
<ListView <ListView
dataSource={this.state.dataSource} dataSource={this.state.dataSource}
enableEmptySections={true}
renderRow={this._renderRow} renderRow={this._renderRow}
renderScrollComponent={props => <RecyclerViewBackedScrollView {...props} />} renderScrollComponent={props => <RecyclerViewBackedScrollView {...props} />}
/> />
...@@ -57,6 +60,10 @@ class History extends Component { ...@@ -57,6 +60,10 @@ class History extends Component {
} }
_renderRow(rowData: Object, sectionID: number, rowID: number, highlightRow: (sectionID: number, rowID: number) => void) { _renderRow(rowData: Object, sectionID: number, rowID: number, highlightRow: (sectionID: number, rowID: number) => void) {
let m = moment(rowData.startDate);
let formattedDate = m.format('MMM Do YYYY');
return ( return (
<TouchableHighlight onPress={() => { <TouchableHighlight onPress={() => {
//this._pressRow(rowID); //this._pressRow(rowID);
...@@ -64,10 +71,17 @@ class History extends Component { ...@@ -64,10 +71,17 @@ class History extends Component {
}}> }}>
<View> <View>
<View style={styles.listViewRow}> <View style={styles.listViewRow}>
<Text style={{flex:1,}}> <View style={styles.col_1_3}>
{rowData.value + ' - ' + rowData.startDate} <Text style={{flex:1, fontWeight: '600'}}>
{rowData.value}
</Text> </Text>
</View> </View>
<View style={styles.col_2_3}>
<Text style={{flex:1, textAlign: 'right',}}>
{formattedDate}
</Text>
</View>
</View>
</View> </View>
</TouchableHighlight> </TouchableHighlight>
); );
......
...@@ -7,22 +7,17 @@ import { ...@@ -7,22 +7,17 @@ import {
Navigator, Navigator,
TouchableOpacity, TouchableOpacity,
ScrollView, ScrollView,
Image,
Text, Text,
View View
} from 'react-native'; } from 'react-native';
import TimerMixin from 'react-timer-mixin';
var reactMixin = require('react-mixin');
import styles from '../../styles/styles';
//var AppleHealthKit = require('react-native-apple-healthkit');
import AppleHealthKit from 'react-native-apple-healthkit'; import AppleHealthKit from 'react-native-apple-healthkit';
import styles from '../../styles/styles';
import History from './history'; import History from './history';
// setup the HealthKit initialization options
const WPERMS = AppleHealthKit.Constants.Permissions.WRITE; const WPERMS = AppleHealthKit.Constants.Permissions.WRITE;
const RPERMS = AppleHealthKit.Constants.Permissions.READ; const RPERMS = AppleHealthKit.Constants.Permissions.READ;
const HKOPTIONS = { const HKOPTIONS = {
permissions: { permissions: {
read: [ read: [
...@@ -31,11 +26,15 @@ const HKOPTIONS = { ...@@ -31,11 +26,15 @@ const HKOPTIONS = {
RPERMS.FlightsClimbed, RPERMS.FlightsClimbed,
RPERMS.Height, RPERMS.Height,
], ],
write: [WPERMS.StepCount], write: [
WPERMS.StepCount
],
} }
}; };
/**
* React Component
*/
class Home extends Component { class Home extends Component {
constructor(props) { constructor(props) {
...@@ -46,11 +45,12 @@ class Home extends Component { ...@@ -46,11 +45,12 @@ class Home extends Component {
}; };
} }
/**
* if HealthKit is available on the device then initialize it
* with the permissions set above in HKOPTIONS. on successful
* initialization fetch today's steps and the step history
*/
componentDidMount() { componentDidMount() {
console.log('CONSTANTS: ', AppleHealthKit.Constants);
//console.log('balls: ', ahk);
AppleHealthKit.isAvailable((err,available) => { AppleHealthKit.isAvailable((err,available) => {
if(available){ if(available){
AppleHealthKit.initHealthKit(HKOPTIONS, (err, res) => { AppleHealthKit.initHealthKit(HKOPTIONS, (err, res) => {
...@@ -64,10 +64,11 @@ class Home extends Component { ...@@ -64,10 +64,11 @@ class Home extends Component {
}); });
} }
componentWillUnmount() { /**
* get today's step count from HealthKit. on success update
} * the component state
* @private
*/
_fetchStepsToday() { _fetchStepsToday() {
AppleHealthKit.getStepCountForToday(null, (err, steps) => { AppleHealthKit.getStepCountForToday(null, (err, steps) => {
if(this._handleHKError(err, 'getStepCountForToday')){ if(this._handleHKError(err, 'getStepCountForToday')){
...@@ -77,6 +78,11 @@ class Home extends Component { ...@@ -77,6 +78,11 @@ class Home extends Component {
}); });
} }
/**
* get the step history from options.startDate through the
* current time. on success update the component state
* @private
*/
_fetchStepsHistory() { _fetchStepsHistory() {
let options = { let options = {
startDate: (new Date(2016,4,1)).toISOString(), startDate: (new Date(2016,4,1)).toISOString(),
...@@ -87,48 +93,13 @@ class Home extends Component { ...@@ -87,48 +93,13 @@ class Home extends Component {
} }
this.setState({stepHistory: res}); this.setState({stepHistory: res});
}); });
AppleHealthKit.getDistanceWalkingRunning(null, (err, res) => {
if(this._handleHKError(err, 'getDistanceWalkingRunning')){
return;
}
console.log('getDistanceWalkingRunning -res-> ', res);
});
AppleHealthKit.getFlightsClimbed(null, (err, res) => {
if(this._handleHKError(err, 'getFlightsClimbed')){
return;
}
console.log('getFlightsClimbed -res-> ', res);
});
let sampleOptions = {
startDate: (new Date(2016,4,1)).toISOString(),
};
AppleHealthKit.getHeightSamples(sampleOptions, (err, samples) => {
if(this._handleHKError(err, 'getHeightSamples')){
return;
}
console.log('getHeightSamples: ', samples);
});
}
_onPressItem(key) {
console.log('_onPressItem() ==> ', key);
let self = this;
this.requestAnimationFrame(() => {
this.props.navigator.push({
name: key
});
})
} }
/**
* render the Navigator which will render the navigation
* bar and the scene
* @returns {XML}
*/
render() { render() {
return ( return (
<Navigator <Navigator
...@@ -141,17 +112,35 @@ class Home extends Component { ...@@ -141,17 +112,35 @@ class Home extends Component {
); );
} }
/**
* render the scene
* @param route
* @param navigator
* @returns {XML}
*/
renderScene(route, navigator) { renderScene(route, navigator) {
return ( return (
<View style={styles.sceneContainerWithNavbar}> <View style={styles.sceneContainerWithNavbar}>
<View style={styles.stepsContainer}> <View style={styles.stepsContainer}>
<Text> <Image style={styles.stepsIcon}
STEPS: {this.state.stepsToday} source={require('../../assets/images/steps.png')}>
</Image>
<Text style={styles.stepsLabel}>
Today's Steps
</Text>
<Text style={styles.stepsValue}>
{this.state.stepsToday}
</Text> </Text>
</View> </View>
<View style={styles.historyContainer}> <View style={styles.historyContainer}>
<View style={styles.titleRow}>
<Text>
History
</Text>
</View>
<History data={this.state.stepHistory} /> <History data={this.state.stepHistory} />
</View> </View>
...@@ -159,30 +148,39 @@ class Home extends Component { ...@@ -159,30 +148,39 @@ class Home extends Component {
); );
} }
/**
* if 'err' is truthy then log the error message and
* return true indicating an error has occurred
* @param err
* @param method
* @returns {boolean}
* @private
*/
_handleHKError(err, method) : boolean { _handleHKError(err, method) : boolean {
if(err){ if(err){
let errStr = 'HealthKit_ERROR['+method+'] : '; let errStr = 'HealthKit_ERROR['+method+'] : ';
if(typeof err === 'string'){ errStr += (err && err.message) ? err.message : err;
errStr += err;
} else if (typeof err === 'object' && err.message){
errStr += err.message;
}
console.log(errStr); console.log(errStr);
return true; return true;
} }
return false; return false;
} }
} }
reactMixin(Home.prototype, TimerMixin);
var NavigationBarRouteMapper = { var NavigationBarRouteMapper = {
LeftButton(route, navigator, index, nextState) { LeftButton(route, navigator, index, nextState) {
return null; return null;
}, },
RightButton(route, navigator, index, nextState) { RightButton(route, navigator, index, nextState) {
return null; return (
<TouchableOpacity style={styles.navbarTitleTouchable}
onPress={() => { navigator.parentNavigator.push({name: 'Add'})}}>
<Text style={styles.navbarPlusButton}>
+
</Text>
</TouchableOpacity>
);
}, },
Title(route, navigator, index, nextState) { Title(route, navigator, index, nextState) {
return ( return (
...@@ -195,6 +193,5 @@ var NavigationBarRouteMapper = { ...@@ -195,6 +193,5 @@ var NavigationBarRouteMapper = {
} }
}; };
module.exports = Home; module.exports = Home;
export default Home; export default Home;
...@@ -36,30 +36,81 @@ const styles = StyleSheet.create({ ...@@ -36,30 +36,81 @@ const styles = StyleSheet.create({
margin: 10, margin: 10,
fontSize: 18 fontSize: 18
}, },
navbarPlusButton: {
fontSize:33,
marginRight:13,
color: '#FD2D55',
top: -3
},
stepsContainer: { stepsContainer: {
height:100, height:100,
backgroundColor: '#FF8000', backgroundColor: '#FAFAFA',
//backgroundColor: '#FF8000',
},
stepsIcon: {
width: 60,
height: 60,
marginLeft: 20,
marginTop: 20,
//marginTop: 50,
//backgroundColor: 'transparent',
alignSelf: 'flex-start',
},
stepsLabel: {
fontSize:12,
color: '#FD2D55',
position:'absolute',
left: 105,
top:11,
}, },
stepsValue: {
fontSize:50,
color: '#47a292',
position:'absolute',
left: 105,
top:25,
},
historyContainer: { historyContainer: {
flex: 1, flex: 1,
backgroundColor: '#0088cc', //backgroundColor: '#0088cc',
}, },
titleRow: {
height:40,
alignItems: 'center',
//backgroundColor: '#FF00FF'
borderTopColor: '#DDDDDD',
borderBottomColor: '#DDDDDD',
borderTopWidth: 1,
borderBottomWidth: 1,
paddingTop:10,
backgroundColor: '#EFEFEF',
},
listViewRow: { listViewRow: {
flexDirection: 'row', flexDirection: 'row',
justifyContent: 'center', justifyContent: 'center',
padding: 10, padding: 10,
backgroundColor: '#F6F6F6', backgroundColor: '#F6F6F6',
borderBottomColor: '#DADADA',
borderBottomWidth: 1,
}, },
row_1_3: { row_1_3: {
flex: 0.33, flex: 0.33,
flexDirection:'column', flexDirection:'column',
...@@ -74,6 +125,22 @@ const styles = StyleSheet.create({ ...@@ -74,6 +125,22 @@ const styles = StyleSheet.create({
//backgroundColor: '#0088cc' //backgroundColor: '#0088cc'
}, },
col_1_3: {
flex: 0.33,
flexDirection:'row',
padding:10,
//backgroundColor: '#FF8000'
},
col_2_3: {
flex: 0.66,
flexDirection:'row',
padding:10,
//backgroundColor: '#0088cc'
},
borderTopLightGrey: { borderTopLightGrey: {
borderTopColor: '#CCCCCC', borderTopColor: '#CCCCCC',
borderTopWidth: 1, borderTopWidth: 1,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment