Commit 6ac01896 authored by Terrillo Walls's avatar Terrillo Walls Committed by GitHub

Merge pull request #38 from terrillo/master

Takeover Underway!
parents 06fc2efe 1000a017
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
3774C8D71D20C65F0000B3F3 /* RCTAppleHealthKit+Methods_Fitness.m in Sources */ = {isa = PBXBuildFile; fileRef = 3774C8D61D20C65F0000B3F3 /* RCTAppleHealthKit+Methods_Fitness.m */; }; 3774C8D71D20C65F0000B3F3 /* RCTAppleHealthKit+Methods_Fitness.m in Sources */ = {isa = PBXBuildFile; fileRef = 3774C8D61D20C65F0000B3F3 /* RCTAppleHealthKit+Methods_Fitness.m */; };
377D44F31D247D0A004E35CB /* RCTAppleHealthKit+Methods_Characteristic.m in Sources */ = {isa = PBXBuildFile; fileRef = 377D44F21D247D0A004E35CB /* RCTAppleHealthKit+Methods_Characteristic.m */; }; 377D44F31D247D0A004E35CB /* RCTAppleHealthKit+Methods_Characteristic.m in Sources */ = {isa = PBXBuildFile; fileRef = 377D44F21D247D0A004E35CB /* RCTAppleHealthKit+Methods_Characteristic.m */; };
37837E7D1DCFE270000201A0 /* RCTAppleHealthKit+Methods_Sleep.m in Sources */ = {isa = PBXBuildFile; fileRef = 37837E7C1DCFE270000201A0 /* RCTAppleHealthKit+Methods_Sleep.m */; }; 37837E7D1DCFE270000201A0 /* RCTAppleHealthKit+Methods_Sleep.m in Sources */ = {isa = PBXBuildFile; fileRef = 37837E7C1DCFE270000201A0 /* RCTAppleHealthKit+Methods_Sleep.m */; };
61232F931E303758000A5026 /* RCTAppleHealthKit+Methods_Mindfulness.m in Sources */ = {isa = PBXBuildFile; fileRef = 61232F921E303758000A5026 /* RCTAppleHealthKit+Methods_Mindfulness.m */; };
64C42D4A1D351A8800A0A8F7 /* RCTAppleHealthKit+Methods_Vitals.m in Sources */ = {isa = PBXBuildFile; fileRef = 64C42D491D351A8800A0A8F7 /* RCTAppleHealthKit+Methods_Vitals.m */; }; 64C42D4A1D351A8800A0A8F7 /* RCTAppleHealthKit+Methods_Vitals.m in Sources */ = {isa = PBXBuildFile; fileRef = 64C42D491D351A8800A0A8F7 /* RCTAppleHealthKit+Methods_Vitals.m */; };
64E0E73F1D37947B00EAB905 /* RCTAppleHealthKit+Methods_Results.m in Sources */ = {isa = PBXBuildFile; fileRef = 64E0E73E1D37947B00EAB905 /* RCTAppleHealthKit+Methods_Results.m */; }; 64E0E73F1D37947B00EAB905 /* RCTAppleHealthKit+Methods_Results.m in Sources */ = {isa = PBXBuildFile; fileRef = 64E0E73E1D37947B00EAB905 /* RCTAppleHealthKit+Methods_Results.m */; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
...@@ -51,6 +52,8 @@ ...@@ -51,6 +52,8 @@
377D44F21D247D0A004E35CB /* RCTAppleHealthKit+Methods_Characteristic.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "RCTAppleHealthKit+Methods_Characteristic.m"; sourceTree = "<group>"; }; 377D44F21D247D0A004E35CB /* RCTAppleHealthKit+Methods_Characteristic.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "RCTAppleHealthKit+Methods_Characteristic.m"; sourceTree = "<group>"; };
37837E7B1DCFE270000201A0 /* RCTAppleHealthKit+Methods_Sleep.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "RCTAppleHealthKit+Methods_Sleep.h"; sourceTree = "<group>"; }; 37837E7B1DCFE270000201A0 /* RCTAppleHealthKit+Methods_Sleep.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "RCTAppleHealthKit+Methods_Sleep.h"; sourceTree = "<group>"; };
37837E7C1DCFE270000201A0 /* RCTAppleHealthKit+Methods_Sleep.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "RCTAppleHealthKit+Methods_Sleep.m"; sourceTree = "<group>"; }; 37837E7C1DCFE270000201A0 /* RCTAppleHealthKit+Methods_Sleep.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "RCTAppleHealthKit+Methods_Sleep.m"; sourceTree = "<group>"; };
61232F911E303758000A5026 /* RCTAppleHealthKit+Methods_Mindfulness.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "RCTAppleHealthKit+Methods_Mindfulness.h"; sourceTree = "<group>"; };
61232F921E303758000A5026 /* RCTAppleHealthKit+Methods_Mindfulness.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "RCTAppleHealthKit+Methods_Mindfulness.m"; sourceTree = "<group>"; };
64C42D481D351A8800A0A8F7 /* RCTAppleHealthKit+Methods_Vitals.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "RCTAppleHealthKit+Methods_Vitals.h"; sourceTree = "<group>"; }; 64C42D481D351A8800A0A8F7 /* RCTAppleHealthKit+Methods_Vitals.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "RCTAppleHealthKit+Methods_Vitals.h"; sourceTree = "<group>"; };
64C42D491D351A8800A0A8F7 /* RCTAppleHealthKit+Methods_Vitals.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "RCTAppleHealthKit+Methods_Vitals.m"; sourceTree = "<group>"; }; 64C42D491D351A8800A0A8F7 /* RCTAppleHealthKit+Methods_Vitals.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "RCTAppleHealthKit+Methods_Vitals.m"; sourceTree = "<group>"; };
64E0E73D1D37947B00EAB905 /* RCTAppleHealthKit+Methods_Results.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "RCTAppleHealthKit+Methods_Results.h"; sourceTree = "<group>"; }; 64E0E73D1D37947B00EAB905 /* RCTAppleHealthKit+Methods_Results.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "RCTAppleHealthKit+Methods_Results.h"; sourceTree = "<group>"; };
...@@ -87,6 +90,8 @@ ...@@ -87,6 +90,8 @@
3774C88F1D2092F20000B3F3 /* RCTAppleHealthKit */ = { 3774C88F1D2092F20000B3F3 /* RCTAppleHealthKit */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
61232F911E303758000A5026 /* RCTAppleHealthKit+Methods_Mindfulness.h */,
61232F921E303758000A5026 /* RCTAppleHealthKit+Methods_Mindfulness.m */,
64E0E73D1D37947B00EAB905 /* RCTAppleHealthKit+Methods_Results.h */, 64E0E73D1D37947B00EAB905 /* RCTAppleHealthKit+Methods_Results.h */,
64E0E73E1D37947B00EAB905 /* RCTAppleHealthKit+Methods_Results.m */, 64E0E73E1D37947B00EAB905 /* RCTAppleHealthKit+Methods_Results.m */,
64C42D481D351A8800A0A8F7 /* RCTAppleHealthKit+Methods_Vitals.h */, 64C42D481D351A8800A0A8F7 /* RCTAppleHealthKit+Methods_Vitals.h */,
...@@ -171,6 +176,7 @@ ...@@ -171,6 +176,7 @@
3774C8A11D20A6B90000B3F3 /* RCTAppleHealthKit+Utils.m in Sources */, 3774C8A11D20A6B90000B3F3 /* RCTAppleHealthKit+Utils.m in Sources */,
37837E7D1DCFE270000201A0 /* RCTAppleHealthKit+Methods_Sleep.m in Sources */, 37837E7D1DCFE270000201A0 /* RCTAppleHealthKit+Methods_Sleep.m in Sources */,
3774C8D41D20C6390000B3F3 /* RCTAppleHealthKit+Methods_Body.m in Sources */, 3774C8D41D20C6390000B3F3 /* RCTAppleHealthKit+Methods_Body.m in Sources */,
61232F931E303758000A5026 /* RCTAppleHealthKit+Methods_Mindfulness.m in Sources */,
64E0E73F1D37947B00EAB905 /* RCTAppleHealthKit+Methods_Results.m in Sources */, 64E0E73F1D37947B00EAB905 /* RCTAppleHealthKit+Methods_Results.m in Sources */,
64C42D4A1D351A8800A0A8F7 /* RCTAppleHealthKit+Methods_Vitals.m in Sources */, 64C42D4A1D351A8800A0A8F7 /* RCTAppleHealthKit+Methods_Vitals.m in Sources */,
3774C8931D2092F20000B3F3 /* RCTAppleHealthKit.m in Sources */, 3774C8931D2092F20000B3F3 /* RCTAppleHealthKit.m in Sources */,
......
//
// RCTAppleHealthKit+Methods_Mindfulness.h
// RCTAppleHealthKit
//
//
#import "RCTAppleHealthKit.h"
@interface RCTAppleHealthKit (Methods_Mindfulness)
- (void)mindfulness_saveMindfulSession:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback;
@end
//
// RCTAppleHealthKit+Methods_Mindfulness.m
// RCTAppleHealthKit
//
//
#import "RCTAppleHealthKit+Methods_Mindfulness.h"
#import "RCTAppleHealthKit+Queries.h"
#import "RCTAppleHealthKit+Utils.h"
@implementation RCTAppleHealthKit (Methods_Sleep)
- (void)mindfulness_saveMindfulSession:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback
{
double value = [RCTAppleHealthKit doubleFromOptions:input key:@"value" withDefault:(double)0];
NSDate *startDate = [RCTAppleHealthKit dateFromOptions:input key:@"startDate" withDefault:nil];
NSDate *endDate = [RCTAppleHealthKit dateFromOptions:input key:@"endDate" withDefault:[NSDate date]];
if(startDate == nil || endDate == nil){
callback(@[RCTMakeError(@"startDate and endDate are required in options", nil, nil)]);
return;
}
HKCategoryType *type = [HKCategoryType categoryTypeForIdentifier: HKCategoryTypeIdentifierMindfulSession];
HKCategorySample *sample = [HKCategorySample categorySampleWithType:type value:value startDate:startDate endDate:endDate];
[self.healthStore saveObject:sample withCompletion:^(BOOL success, NSError *error) {
if (!success) {
NSLog(@"An error occured saving the mindful session sample %@. The error was: %@.", sample, error);
callback(@[RCTMakeError(@"An error occured saving the mindful session sample", error, nil)]);
return;
}
callback(@[[NSNull null], @(value)]);
}];
}
@end
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
@"ActiveEnergyBurned" : [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierActiveEnergyBurned], @"ActiveEnergyBurned" : [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierActiveEnergyBurned],
@"FlightsClimbed" : [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierFlightsClimbed], @"FlightsClimbed" : [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierFlightsClimbed],
@"NikeFuel" : [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierNikeFuel], @"NikeFuel" : [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierNikeFuel],
@"AppleExerciseTime" : [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierAppleExerciseTime], // @"AppleExerciseTime" : [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierAppleExerciseTime],
// Nutrition Identifiers // Nutrition Identifiers
@"DietaryEnergy" : [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierDietaryEnergyConsumed], @"DietaryEnergy" : [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierDietaryEnergyConsumed],
// Vital Signs Identifiers // Vital Signs Identifiers
...@@ -47,6 +47,8 @@ ...@@ -47,6 +47,8 @@
@"BloodGlucose" : [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierBloodGlucose], @"BloodGlucose" : [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierBloodGlucose],
// Sleep // Sleep
@"SleepAnalysis" : [HKObjectType categoryTypeForIdentifier:HKCategoryTypeIdentifierSleepAnalysis], @"SleepAnalysis" : [HKObjectType categoryTypeForIdentifier:HKCategoryTypeIdentifierSleepAnalysis],
// Mindfulness
@"MindfulSession" : [HKObjectType categoryTypeForIdentifier:HKCategoryTypeIdentifierMindfulSession],
}; };
return readPerms; return readPerms;
} }
...@@ -73,6 +75,8 @@ ...@@ -73,6 +75,8 @@
@"DietaryEnergy" : [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierDietaryEnergyConsumed], @"DietaryEnergy" : [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierDietaryEnergyConsumed],
// Sleep // Sleep
@"SleepAnalysis" : [HKObjectType categoryTypeForIdentifier:HKCategoryTypeIdentifierSleepAnalysis], @"SleepAnalysis" : [HKObjectType categoryTypeForIdentifier:HKCategoryTypeIdentifierSleepAnalysis],
// Mindfulness
@"MindfulSession" : [HKObjectType categoryTypeForIdentifier:HKCategoryTypeIdentifierMindfulSession],
}; };
return writePerms; return writePerms;
} }
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#import "RCTAppleHealthKit+Methods_Vitals.h" #import "RCTAppleHealthKit+Methods_Vitals.h"
#import "RCTAppleHealthKit+Methods_Results.h" #import "RCTAppleHealthKit+Methods_Results.h"
#import "RCTAppleHealthKit+Methods_Sleep.h" #import "RCTAppleHealthKit+Methods_Sleep.h"
#import "RCTAppleHealthKit+Methods_Mindfulness.h"
#import <React/RCTBridgeModule.h> #import <React/RCTBridgeModule.h>
#import <React/RCTEventDispatcher.h> #import <React/RCTEventDispatcher.h>
...@@ -164,6 +165,11 @@ RCT_EXPORT_METHOD(getInfo:(NSDictionary *)input callback:(RCTResponseSenderBlock ...@@ -164,6 +165,11 @@ RCT_EXPORT_METHOD(getInfo:(NSDictionary *)input callback:(RCTResponseSenderBlock
[self getModuleInfo:input callback:callback]; [self getModuleInfo:input callback:callback];
} }
RCT_EXPORT_METHOD(saveMindfulSession:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback)
{
[self mindfulness_saveMindfulSession:input callback:callback];
}
- (void)isHealthKitAvailable:(RCTResponseSenderBlock)callback - (void)isHealthKitAvailable:(RCTResponseSenderBlock)callback
{ {
......
This diff is collapsed.
'use strict' 'use strict'
/**
* Apple Health Permissions
* @type {Object}
*/
const PERMISSIONS = { const PERMISSIONS = {
DateOfBirth: 'DateOfBirth', DateOfBirth: 'DateOfBirth',
BiologicalSex: 'BiologicalSex', BiologicalSex: 'BiologicalSex',
...@@ -26,9 +30,12 @@ const PERMISSIONS = { ...@@ -26,9 +30,12 @@ const PERMISSIONS = {
RespiratoryRate: 'RespiratoryRate', RespiratoryRate: 'RespiratoryRate',
BloodGlucose: 'BloodGlucose', BloodGlucose: 'BloodGlucose',
SleepAnalysis: 'SleepAnalysis', SleepAnalysis: 'SleepAnalysis',
MindfulSession: 'MindfulSession',
}; };
/**
* Unit Request Types
*/
const UNITS = { const UNITS = {
gram: 'gram', gram: 'gram',
pound: 'pound', pound: 'pound',
...@@ -52,8 +59,6 @@ const UNITS = { ...@@ -52,8 +59,6 @@ const UNITS = {
mgPerdL: 'mgPerdL', mgPerdL: 'mgPerdL',
}; };
const CONSTANTS = { const CONSTANTS = {
Permissions: PERMISSIONS, Permissions: PERMISSIONS,
Units: UNITS, Units: UNITS,
......
[android]
target = Google Inc.:Google APIs:23
[maven_repositories]
central = https://repo1.maven.org/maven2
[ignore]
# We fork some components by platform.
.*/*.web.js
.*/*.android.js
# Some modules have their own node_modules with overlap
.*/node_modules/node-haste/.*
# Ugh
.*/node_modules/babel.*
.*/node_modules/babylon.*
.*/node_modules/invariant.*
# Ignore react and fbjs where there are overlaps, but don't ignore
# anything that react-native relies on
.*/node_modules/fbjs/lib/Map.js
.*/node_modules/fbjs/lib/ErrorUtils.js
# Flow has a built-in definition for the 'react' module which we prefer to use
# over the currently-untyped source
.*/node_modules/react/react.js
.*/node_modules/react/lib/React.js
.*/node_modules/react/lib/ReactDOM.js
.*/__mocks__/.*
.*/__tests__/.*
.*/commoner/test/source/widget/share.js
# Ignore commoner tests
.*/node_modules/commoner/test/.*
# See https://github.com/facebook/flow/issues/442
.*/react-tools/node_modules/commoner/lib/reader.js
# Ignore jest
.*/node_modules/jest-cli/.*
# Ignore Website
.*/website/.*
# Ignore generators
.*/local-cli/generator.*
# Ignore BUCK generated folders
.*\.buckd/
# Ignore RNPM
.*/local-cli/rnpm/.*
.*/node_modules/is-my-json-valid/test/.*\.json
.*/node_modules/iconv-lite/encodings/tables/.*\.json
.*/node_modules/y18n/test/.*\.json
.*/node_modules/spdx-license-ids/spdx-license-ids.json
.*/node_modules/spdx-exceptions/index.json
.*/node_modules/resolve/test/subdirs/node_modules/a/b/c/x.json
.*/node_modules/resolve/lib/core.json
.*/node_modules/jsonparse/samplejson/.*\.json
.*/node_modules/json5/test/.*\.json
.*/node_modules/ua-parser-js/test/.*\.json
.*/node_modules/builtin-modules/builtin-modules.json
.*/node_modules/binary-extensions/binary-extensions.json
.*/node_modules/url-regex/tlds.json
.*/node_modules/joi/.*\.json
.*/node_modules/isemail/.*\.json
.*/node_modules/tr46/.*\.json
[include]
[libs]
node_modules/react-native/Libraries/react-native/react-native-interface.js
node_modules/react-native/flow
flow/
[options]
module.system=haste
esproposal.class_static_fields=enable
esproposal.class_instance_fields=enable
experimental.strict_type_args=true
munge_underscores=true
module.name_mapper='^image![a-zA-Z0-9$_-]+$' -> 'GlobalImageStub'
module.name_mapper='^[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\)$' -> 'RelativeImageStub'
suppress_type=$FlowIssue
suppress_type=$FlowFixMe
suppress_type=$FixMe
suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(2[0-6]\\|1[0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)
suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(2[0-6]\\|1[0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)?:? #[0-9]+
suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy
[version]
^0.26.0
# OSX
#
.DS_Store
# Xcode
#
build/
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
xcuserdata
*.xccheckout
*.moved-aside
DerivedData
*.hmap
*.ipa
*.xcuserstate
project.xcworkspace
# Android/IJ
#
*.iml
.idea
.gradle
local.properties
# node.js
#
node_modules/
npm-debug.log
# BUCK
buck-out/
\.buckd/
android/app/libs
android/keystores/debug.keystore
# Body Measurements Demo
![alt text](https://raw.githubusercontent.com/GregWilson/react-native-apple-healthkit/master/examples/images/body_measurements_demo_screen.png "Body Measurements Demo App Screenshot")
/**
* Created by greg on 2016-06-28.
*/
var airflux = require('airflux');
let actions = {
saveWeight: new airflux.Action().asFunction,
saveHeight: new airflux.Action().asFunction,
};
module.exports = actions;
export default actions;
/**
* Created by greg on 2016-06-27.
*/
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Navigator,
Text,
View
} from 'react-native';
let Dashboard = require('./components/dashboard/dashboard');
let Weight = require('./components/weight/weight');
let Height = require('./components/height/height');
let BodyMassIndex = require('./components/bodyMassIndex/bodyMassIndex');
let BodyFatPercentage = require('./components/bodyFatPercentage/bodyFatPercentage');
let LeanBodyMass = require('./components/leanBodyMass/leanBodyMass');
class BodyMeasurementsApp extends Component {
render() {
return (
<Navigator
style={{ flex:1 }}
initialRoute={{ name: 'Dashboard' }}
renderScene={ this.renderScene } />
);
}
renderScene(route, navigator) {
if(route.name == 'Dashboard') {
return <Dashboard navigator={navigator} />
}
if(route.name == 'Weight') {
return <Weight navigator={navigator} />
}
if(route.name == 'Height') {
return <Height navigator={navigator} />
}
if(route.name == 'BodyMassIndex') {
return <BodyMassIndex navigator={navigator} />
}
if(route.name == 'BodyFatPercentage') {
return <BodyFatPercentage navigator={navigator} />
}
if(route.name == 'LeanBodyMass') {
return <LeanBodyMass navigator={navigator} />
}
}
}
module.exports = BodyMeasurementsApp;
export default BodyMeasurementsApp;
/**
* Created by greg on 2016-06-27.
*/
import React, { Component } from 'react';
import {
Navigator,
TouchableOpacity,
Text,
View
} from 'react-native';
import styles from '../../styles/styles';
import BodyStore from '../../stores/body';
class BodyFatPercentage extends Component {
constructor(props) {
super(props);
this.state = this._getStateObject();
}
componentDidMount() {
this.unsub = BodyStore.listen(this._onBodyStoreEvent.bind(this));
}
componentWillUnmount() {
this.unsub();
}
_onBodyStoreEvent(evt) {
this.setState(this._getStateObject())
}
_getStateObject() {
return {
bodyFatFormatted: BodyStore.GetBodyFatPercentageFormatted(),
};
}
render() {
return (
<Navigator
renderScene={this.renderScene.bind(this)}
navigator={this.props.navigator}
navigationBar={
<Navigator.NavigationBar style={styles.navigationBar}
routeMapper={NavigationBarRouteMapper} />
}/>
);
}
renderScene(route, navigator) {
return (
<View style={styles.sceneContainerNavbar}>
<View style={styles.row_1_3}>
<Text style={styles.largeCenteredText}>
{this.state.bodyFatFormatted}
</Text>
</View>
<View style={[styles.row_2_3, styles.borderTopLightGrey]}>
<Text></Text>
</View>
</View>
);
}
}
var NavigationBarRouteMapper = {
LeftButton(route, navigator, index, nextState) {
return (
<TouchableOpacity style={styles.navbarTitleTouchable} onPress={() => {navigator.parentNavigator.pop()}}>
<Text style={styles.navbarTitle}>
Back
</Text>
</TouchableOpacity>
);
},
RightButton(route, navigator, index, nextState) {
return null;
},
Title(route, navigator, index, nextState) {
return (
<TouchableOpacity style={styles.navbarTitleTouchable}>
<Text style={styles.navbarTitle}>
Body Fat Percentage
</Text>
</TouchableOpacity>
);
}
};
module.exports = BodyFatPercentage;
export default BodyFatPercentage;
/**
* Created by greg on 2016-06-27.
*/
import React, { Component } from 'react';
import {
Navigator,
TouchableOpacity,
Text,
View
} from 'react-native';
import styles from '../../styles/styles';
import BodyStore from '../../stores/body';
class BodyMassIndex extends Component {
constructor(props) {
super(props);
this.state = this._getStateObject();
}
componentDidMount() {
this.unsub = BodyStore.listen(this._onBodyStoreEvent.bind(this));
}
componentWillUnmount() {
this.unsub();
}
_onBodyStoreEvent(evt) {
this.setState(this._getStateObject())
}
_getStateObject() {
return {
bmiFormatted: BodyStore.GetBMIFormatted(),
};
}
render() {
return (
<Navigator
renderScene={this.renderScene.bind(this)}
navigator={this.props.navigator}
navigationBar={
<Navigator.NavigationBar style={styles.navigationBar}
routeMapper={NavigationBarRouteMapper} />
}/>
);
}
renderScene(route, navigator) {
return (
<View style={styles.sceneContainerNavbar}>
<View style={styles.row_1_3}>
<Text style={styles.largeCenteredText}>
{this.state.bmiFormatted}
</Text>
</View>
<View style={[styles.row_2_3, styles.borderTopLightGrey]}>
<Text></Text>
</View>
</View>
);
}
}
var NavigationBarRouteMapper = {
LeftButton(route, navigator, index, nextState) {
return (
<TouchableOpacity style={styles.navbarTitleTouchable} onPress={() => {navigator.parentNavigator.pop()}}>
<Text style={styles.navbarTitle}>
Back
</Text>
</TouchableOpacity>
);
},
RightButton(route, navigator, index, nextState) {
return null;
},
Title(route, navigator, index, nextState) {
return (
<TouchableOpacity style={styles.navbarTitleTouchable}>
<Text style={styles.navbarTitle}>
Body Mass Index
</Text>
</TouchableOpacity>
);
}
};
module.exports = BodyMassIndex;
export default BodyMassIndex;
/**
* Created by greg on 2016-06-27.
*/
import React, { Component } from 'react';
import {
Navigator,
TouchableOpacity,
ScrollView,
Text,
View
} from 'react-native';
import TimerMixin from 'react-timer-mixin';
var reactMixin = require('react-mixin');
import styles from '../../styles/styles';
import BodyStore from '../../stores/body';
import DashboardItem from './item';
class Dashboard extends Component {
constructor(props) {
super(props);
this.state = this._getStateObject();
}
componentDidMount() {
this.unsub = BodyStore.listen(this._onBodyStoreEvent.bind(this));
}
componentWillUnmount() {
this.unsub();
}
_onBodyStoreEvent(evt) {
this.setState(this._getStateObject())
}
_getStateObject() {
return {
weightFormatted: BodyStore.GetWeightFormatted(),
heightFormatted: BodyStore.GetHeightFormatted(),
bmiFormatted: BodyStore.GetBMIFormatted(),
bodyFatFormatted: BodyStore.GetBodyFatPercentageFormatted(),
leanBodyMassFormatted: BodyStore.GetLeanBodyMassFormatted(),
};
}
_onPressItem(key) {
console.log('_onPressItem() ==> ', key);
let self = this;
this.requestAnimationFrame(() => {
this.props.navigator.push({
name: key
});
})
}
render() {
return (
<Navigator
renderScene={this.renderScene.bind(this)}
navigator={this.props.navigator}
navigationBar={
<Navigator.NavigationBar style={styles.navigationBar}
routeMapper={NavigationBarRouteMapper} />
}/>
);
}
renderScene(route, navigator) {
return (
<View style={styles.sceneContainerNavbar}>
<ScrollView automaticallyAdjustContentInsets={false} style={{flex:1,}}>
<DashboardItem icon="scale"
label="Weight"
value={this.state.weightFormatted}
onPress={this._onPressItem.bind(this, 'Weight')} />
<DashboardItem icon="ruler"
label="Height"
value={this.state.heightFormatted}
onPress={this._onPressItem.bind(this, 'Height')} />
<DashboardItem icon="bmi"
label="BMI"
value={this.state.bmiFormatted}
onPress={this._onPressItem.bind(this, 'BodyMassIndex')} />
<DashboardItem icon="bodyfat"
label="Body Fat Percentage"
value={this.state.bodyFatFormatted}
onPress={this._onPressItem.bind(this, 'BodyFatPercentage')} />
<DashboardItem icon="musclemass"
label="Lean Body Mass"
value={this.state.leanBodyMassFormatted}
onPress={this._onPressItem.bind(this, 'LeanBodyMass')} />
</ScrollView>
</View>
);
}
}
reactMixin(Dashboard.prototype, TimerMixin);
var NavigationBarRouteMapper = {
LeftButton(route, navigator, index, nextState) {
return null;
},
RightButton(route, navigator, index, nextState) {
return null;
},
Title(route, navigator, index, nextState) {
return (
<TouchableOpacity style={styles.navbarTitleTouchable}>
<Text style={styles.navbarTitle}>
HealthKit Body Measurements
</Text>
</TouchableOpacity>
);
}
};
module.exports = Dashboard;
export default Dashboard;
/**
* Created by greg on 2016-06-27.
*/
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Navigator,
TouchableOpacity,
TouchableHighlight,
ScrollView,
Image,
Text,
View
} from 'react-native';
import styles from '../../styles/styles';
const ICONS = {
"scale": require("../../assets/images/scale.png"),
"ruler": require("../../assets/images/ruler.png"),
"bmi": require("../../assets/images/bmi.png"),
"bodyfat": require("../../assets/images/bodyfat.png"),
"musclemass": require("../../assets/images/muscle-mass.png"),
"arrowright": require('../../assets/images/arrow-right.png'),
"heartbeat": require('../../assets/images/heartbeat.png')
};
class DashboardItem extends Component {
constructor(props) {
super(props);
this.state = this._getStateObject(this.props);
}
componentWillReceiveProps(newProps) {
this.setState(this._getStateObject(newProps));
}
_getStateObject(props) {
let label = props.label ? props.label : 'Label';
let value = props.value ? props.value : 'Value';
let iconSource = (props.icon && ICONS.hasOwnProperty(props.icon)) ? ICONS[props.icon] : ICONS.heartbeat;
return {label,value,iconSource};
}
render() {
return (
<TouchableHighlight onPress={this.props.onPress} style={ styles.dashboardListItemHighlight } underlayColor="#0088cc">
<View style={ styles.dashboardListItemView }>
<View style={ styles.dashboardListItem }>
<Image source={this.state.iconSource}
style={styles.dashboardListItemIcon}/>
<Text style={styles.dashboardListItemLabel}>
{this.state.label}
</Text>
<Text style={styles.dashboardListItemValue}>
{this.state.value}
</Text>
<Image source={ICONS.arrowright}
style={styles.dashboardListItemIcon}/>
</View>
</View>
</TouchableHighlight>
)
}
}
DashboardItem.propTypes = {
icon: React.PropTypes.string,
label: React.PropTypes.string,
value: React.PropTypes.string,
onPress: React.PropTypes.func
};
DashboardItem.defaultProps = {
onPress: function(){
console.log('default onPress()');
}
};
module.exports = DashboardItem;
export default DashboardItem;
/**
* Created by greg on 2016-06-27.
*/
import React, { Component } from 'react';
import {
Navigator,
TouchableOpacity,
Text,
View
} from 'react-native';
import styles from '../../styles/styles';
import BodyStore from '../../stores/body';
class Height extends Component {
constructor(props) {
super(props);
this.state = this._getStateObject();
}
componentDidMount() {
this.unsub = BodyStore.listen(this._onBodyStoreEvent.bind(this));
}
componentWillUnmount() {
this.unsub();
}
_onBodyStoreEvent(evt) {
this.setState(this._getStateObject())
}
_getStateObject() {
return {
heightFormatted: BodyStore.GetHeightFormatted(),
};
}
render() {
return (
<Navigator
renderScene={this.renderScene.bind(this)}
navigator={this.props.navigator}
navigationBar={
<Navigator.NavigationBar style={styles.navigationBar}
routeMapper={NavigationBarRouteMapper} />
}/>
);
}
renderScene(route, navigator) {
return (
<View style={styles.sceneContainerNavbar}>
<View style={styles.row_1_3}>
<Text style={styles.largeCenteredText}>
{this.state.heightFormatted}
</Text>
</View>
<View style={[styles.row_2_3, styles.borderTopLightGrey]}>
<Text></Text>
</View>
</View>
);
}
}
var NavigationBarRouteMapper = {
LeftButton(route, navigator, index, nextState) {
return (
<TouchableOpacity style={styles.navbarTitleTouchable} onPress={() => {navigator.parentNavigator.pop()}}>
<Text style={styles.navbarTitle}>
Back
</Text>
</TouchableOpacity>
);
},
RightButton(route, navigator, index, nextState) {
return null;
},
Title(route, navigator, index, nextState) {
return (
<TouchableOpacity style={styles.navbarTitleTouchable}>
<Text style={styles.navbarTitle}>
Height
</Text>
</TouchableOpacity>
);
}
};
module.exports = Height;
export default Height;
/**
* Created by greg on 2016-06-27.
*/
import React, { Component } from 'react';
import {
Navigator,
TouchableOpacity,
Text,
View
} from 'react-native';
import styles from '../../styles/styles';
import BodyStore from '../../stores/body';
class LeanBodyMass extends Component {
constructor(props) {
super(props);
this.state = this._getStateObject();
}
componentDidMount() {
this.unsub = BodyStore.listen(this._onBodyStoreEvent.bind(this));
}
componentWillUnmount() {
this.unsub();
}
_onBodyStoreEvent(evt) {
this.setState(this._getStateObject())
}
_getStateObject() {
return {
leanBodyMassFormatted: BodyStore.GetLeanBodyMassFormatted(),
};
}
render() {
return (
<Navigator
renderScene={this.renderScene.bind(this)}
navigator={this.props.navigator}
navigationBar={
<Navigator.NavigationBar style={styles.navigationBar}
routeMapper={NavigationBarRouteMapper} />
}/>
);
}
renderScene(route, navigator) {
return (
<View style={styles.sceneContainerNavbar}>
<View style={styles.row_1_3}>
<Text style={styles.largeCenteredText}>
{this.state.leanBodyMassFormatted}
</Text>
</View>
<View style={[styles.row_2_3, styles.borderTopLightGrey]}>
<Text></Text>
</View>
</View>
);
}
}
var NavigationBarRouteMapper = {
LeftButton(route, navigator, index, nextState) {
return (
<TouchableOpacity style={styles.navbarTitleTouchable} onPress={() => {navigator.parentNavigator.pop()}}>
<Text style={styles.navbarTitle}>
Back
</Text>
</TouchableOpacity>
);
},
RightButton(route, navigator, index, nextState) {
return null;
},
Title(route, navigator, index, nextState) {
return (
<TouchableOpacity style={styles.navbarTitleTouchable}>
<Text style={styles.navbarTitle}>
Lean Body Mass
</Text>
</TouchableOpacity>
);
}
};
module.exports = LeanBodyMass;
export default LeanBodyMass;
/**
* Created by greg on 2016-06-27.
*/
import React, { Component } from 'react';
import {
Navigator,
TouchableOpacity,
Text,
View
} from 'react-native';
import styles from '../../styles/styles';
import BodyStore from '../../stores/body';
class Weight extends Component {
constructor(props) {
super(props);
this.state = this._getStateObject();
}
componentDidMount() {
this.unsub = BodyStore.listen(this._onBodyStoreEvent.bind(this));
}
componentWillUnmount() {
this.unsub();
}
_onBodyStoreEvent(evt) {
this.setState(this._getStateObject())
}
_getStateObject() {
return {
weightFormatted: BodyStore.GetWeightFormatted(),
};
}
render() {
return (
<Navigator
renderScene={this.renderScene.bind(this)}
navigator={this.props.navigator}
navigationBar={
<Navigator.NavigationBar style={styles.navigationBar}
routeMapper={NavigationBarRouteMapper} />
}/>
);
}
renderScene(route, navigator) {
return (
<View style={styles.sceneContainerNavbar}>
<View style={styles.row_1_3}>
<Text style={styles.largeCenteredText}>
{this.state.weightFormatted}
</Text>
</View>
<View style={[styles.row_2_3, styles.borderTopLightGrey]}>
<Text></Text>
</View>
</View>
);
}
}
var NavigationBarRouteMapper = {
LeftButton(route, navigator, index, nextState) {
return (
<TouchableOpacity style={styles.navbarTitleTouchable} onPress={() => {navigator.parentNavigator.pop()}}>
<Text style={styles.navbarTitle}>
Back
</Text>
</TouchableOpacity>
);
},
RightButton(route, navigator, index, nextState) {
return null;
},
Title(route, navigator, index, nextState) {
return (
<TouchableOpacity style={styles.navbarTitleTouchable}>
<Text style={styles.navbarTitle}>
Weight
</Text>
</TouchableOpacity>
);
}
};
module.exports = Weight;
export default Weight;
This diff is collapsed.
/**
* Created by greg on 2016-06-27.
*/
import {
Platform,
StyleSheet
} from 'react-native';
const styles = StyleSheet.create({
sceneContainerNavbar: {
flex: 1,
flexDirection: 'column',
//justifyContent: 'flex-start',
//alignItems: 'flex-start',
marginTop: (Platform.OS === 'ios') ? 64 : 54,
backgroundColor: '#FFFFFF'
},
navigationBar: {
borderBottomWidth: 1,
borderBottomColor: '#cccccc',
backgroundColor: '#f5f5f5'
},
navbarTitleTouchable: {
flex: 1,
justifyContent: 'center'
},
navbarTitle: {
color: '#FD2D55',
margin: 10,
fontSize: 18
},
row_1_3: {
flex: 0.33,
flexDirection:'column',
padding:10,
//backgroundColor: '#FF8000'
},
row_2_3: {
flex: 0.66,
flexDirection:'column',
padding:10,
//backgroundColor: '#0088cc'
},
borderTopLightGrey: {
borderTopColor: '#CCCCCC',
borderTopWidth: 1,
},
largeCenteredText: {
textAlign: 'center',
flexDirection:'row',
fontSize:34,
marginTop:60,
},
dashboardListItemLabel: {
fontSize:12,
color: '#FD2D55',
position:'absolute',
left: 70,
top:0,
},
dashboardListItemValue: {
fontSize:22,
color: '#47a292',
position:'absolute',
left: 70,
top:15,
},
sceneContainerFull: {
flex: 1,
flexDirection: 'column',
//justifyContent: 'flex-start',
//alignItems: 'flex-start',
marginTop: 0,
backgroundColor: '#FFFFFF'
},
dashboardToday: {
height: 30,
alignItems: 'stretch',
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'rgba(162, 162, 162, 0.2)',
},
dashboardTodayText: {
color: '#a2a2a2',
},
dashboardListItemHighlight: {
flexDirection: 'row',
alignSelf: 'stretch',
justifyContent: 'center',
//flex:1,
//alignSelf: 'stretch',
//overflow: 'hidden',
},
dashboardListItemView: {
flex: 1,
//backgroundColor: '#FDFDFD',
backgroundColor: '#FDFDFD',
//paddingTop:74,
//flexDirection: 'row',
flexDirection: 'column',
alignSelf: 'stretch',
justifyContent: 'flex-start',
alignItems: 'flex-start',
paddingTop:15,
paddingBottom: 15,
//flexWrap: 'wrap',
borderBottomColor: '#AAAAAA',
borderBottomWidth: 1,
},
dashboardListItemViewTransparent: {
flex: 1,
//backgroundColor: '#FDFDFD',
backgroundColor: 'transparent',
//paddingTop:74,
//flexDirection: 'row',
flexDirection: 'column',
alignSelf: 'stretch',
justifyContent: 'flex-start',
alignItems: 'flex-start',
paddingTop:15,
paddingBottom: 15,
//flexWrap: 'wrap',
borderBottomColor: '#AAAAAA',
borderBottomWidth: 1,
},
dashboardListItem: {
flexDirection: 'row',
alignSelf: 'stretch',
justifyContent: 'space-between',
flex:1,
backgroundColor: 'transparent',
},
dashboardListItemIcon: {
width: 40,
height: 40,
marginLeft: 10,
opacity:0.7,
//marginTop: 50,
//backgroundColor: 'transparent',
alignSelf: 'flex-start',
},
dashboardListItemText: {
flex: 1,
flexDirection: 'column',
alignSelf: 'flex-start',
marginLeft: 20,
fontSize: 29,
color: '#47a292',
//color: '#98CA3F',
//color: '#644496',
flexWrap: 'wrap',
backgroundColor:'transparent',
},
});
module.exports = styles;
export default styles;
/**
* Sample React Native App
* https://github.com/facebook/react-native
* @flow
*/
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Navigator,
Text,
View
} from 'react-native';
let App = require('./app/app');
class BodyMeasurements extends Component {
render() {
return (
<App />
)
}
}
AppRegistry.registerComponent('BodyMeasurements', () => BodyMeasurements);
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0620"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
BuildableName = "BodyMeasurements.app"
BlueprintName = "BodyMeasurements"
ReferencedContainer = "container:BodyMeasurements.xcodeproj">
</BuildableReference>
</BuildActionEntry>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "NO"
buildForArchiving = "NO"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "00E356ED1AD99517003FC87E"
BuildableName = "BodyMeasurementsTests.xctest"
BlueprintName = "BodyMeasurementsTests"
ReferencedContainer = "container:BodyMeasurements.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
buildConfiguration = "Debug">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "00E356ED1AD99517003FC87E"
BuildableName = "BodyMeasurementsTests.xctest"
BlueprintName = "BodyMeasurementsTests"
ReferencedContainer = "container:BodyMeasurements.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
BuildableName = "BodyMeasurements.app"
BlueprintName = "BodyMeasurements"
ReferencedContainer = "container:BodyMeasurements.xcodeproj">
</BuildableReference>
</MacroExpansion>
</TestAction>
<LaunchAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
buildConfiguration = "Debug"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
BuildableName = "BodyMeasurements.app"
BlueprintName = "BodyMeasurements"
ReferencedContainer = "container:BodyMeasurements.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
buildConfiguration = "Release"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
BuildableName = "BodyMeasurements.app"
BlueprintName = "BodyMeasurements"
ReferencedContainer = "container:BodyMeasurements.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#import <UIKit/UIKit.h>
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (nonatomic, strong) UIWindow *window;
@end
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#import "AppDelegate.h"
#import "RCTRootView.h"
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSURL *jsCodeLocation;
/**
* Loading JavaScript code - uncomment the one you want.
*
* OPTION 1
* Load from development server. Start the server from the repository root:
*
* $ npm start
*
* To run on device, change `localhost` to the IP address of your computer
* (you can get this by typing `ifconfig` into the terminal and selecting the
* `inet` value under `en0:`) and make sure your computer and iOS device are
* on the same Wi-Fi network.
*/
jsCodeLocation = [NSURL URLWithString:@"http://192.168.0.14:8081/index.ios.bundle?platform=ios&dev=true"];
// jsCodeLocation = [NSURL URLWithString:@"http://10.1.14.163:8081/index.ios.bundle?platform=ios&dev=true"];
/**
* OPTION 2
* Load from pre-bundled file on disk. The static bundle is automatically
* generated by the "Bundle React Native code and images" build step when
* running the project on an actual device or running the project on the
* simulator in the "Release" build configuration.
*/
// jsCodeLocation = [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
moduleName:@"BodyMeasurements"
initialProperties:nil
launchOptions:launchOptions];
rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1];
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
UIViewController *rootViewController = [UIViewController new];
rootViewController.view = rootView;
self.window.rootViewController = rootViewController;
[self.window makeKeyAndVisible];
return YES;
}
@end
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="10117" systemVersion="15F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
<capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="iN0-l3-epB">
<rect key="frame" x="0.0" y="0.0" width="480" height="480"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Powered by React Native" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="9" translatesAutoresizingMaskIntoConstraints="NO" id="8ie-xW-0ye">
<rect key="frame" x="20" y="439" width="441" height="21"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="BodyMeasurements" textAlignment="center" lineBreakMode="middleTruncation" baselineAdjustment="alignBaselines" minimumFontSize="18" translatesAutoresizingMaskIntoConstraints="NO" id="kId-c2-rCX">
<rect key="frame" x="20" y="140" width="441" height="43"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="36"/>
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
<constraints>
<constraint firstItem="kId-c2-rCX" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="bottom" multiplier="1/3" constant="1" id="5cJ-9S-tgC"/>
<constraint firstAttribute="centerX" secondItem="kId-c2-rCX" secondAttribute="centerX" id="Koa-jz-hwk"/>
<constraint firstAttribute="bottom" secondItem="8ie-xW-0ye" secondAttribute="bottom" constant="20" id="Kzo-t9-V3l"/>
<constraint firstItem="8ie-xW-0ye" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="20" symbolic="YES" id="MfP-vx-nX0"/>
<constraint firstAttribute="centerX" secondItem="8ie-xW-0ye" secondAttribute="centerX" id="ZEH-qu-HZ9"/>
<constraint firstItem="kId-c2-rCX" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="20" symbolic="YES" id="fvb-Df-36g"/>
</constraints>
<nil key="simulatedStatusBarMetrics"/>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
<point key="canvasLocation" x="548" y="455"/>
</view>
</objects>
</document>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.developer.healthkit</key>
<true/>
</dict>
</plist>
{
"images" : [
{
"idiom" : "iphone",
"size" : "29x29",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "29x29",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "40x40",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "40x40",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "60x60",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "60x60",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
<key>NSLocationWhenInUseUsageDescription</key>
<string></string>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>
<string>healthkit</string>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
</dict>
</plist>
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
int main(int argc, char * argv[]) {
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#import <UIKit/UIKit.h>
#import <XCTest/XCTest.h>
#import "RCTLog.h"
#import "RCTRootView.h"
#define TIMEOUT_SECONDS 600
#define TEXT_TO_LOOK_FOR @"Welcome to React Native!"
@interface BodyMeasurementsTests : XCTestCase
@end
@implementation BodyMeasurementsTests
- (BOOL)findSubviewInView:(UIView *)view matching:(BOOL(^)(UIView *view))test
{
if (test(view)) {
return YES;
}
for (UIView *subview in [view subviews]) {
if ([self findSubviewInView:subview matching:test]) {
return YES;
}
}
return NO;
}
- (void)testRendersWelcomeScreen
{
UIViewController *vc = [[[[UIApplication sharedApplication] delegate] window] rootViewController];
NSDate *date = [NSDate dateWithTimeIntervalSinceNow:TIMEOUT_SECONDS];
BOOL foundElement = NO;
__block NSString *redboxError = nil;
RCTSetLogFunction(^(RCTLogLevel level, RCTLogSource source, NSString *fileName, NSNumber *lineNumber, NSString *message) {
if (level >= RCTLogLevelError) {
redboxError = message;
}
});
while ([date timeIntervalSinceNow] > 0 && !foundElement && !redboxError) {
[[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
[[NSRunLoop mainRunLoop] runMode:NSRunLoopCommonModes beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
foundElement = [self findSubviewInView:vc.view matching:^BOOL(UIView *view) {
if ([view.accessibilityLabel isEqualToString:TEXT_TO_LOOK_FOR]) {
return YES;
}
return NO;
}];
}
RCTSetLogFunction(RCTDefaultLogFunction);
XCTAssertNil(redboxError, @"RedBox error: %@", redboxError);
XCTAssertTrue(foundElement, @"Couldn't find element with text '%@' in %d seconds", TEXT_TO_LOOK_FOR, TIMEOUT_SECONDS);
}
@end
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1</string>
</dict>
</plist>
{
"name": "BodyMeasurements",
"version": "0.0.1",
"private": true,
"scripts": {
"start": "node node_modules/react-native/local-cli/cli.js start"
},
"dependencies": {
"airflux": "^0.5.1",
"react": "15.1.0",
"react-mixin": "^2.0.2",
"react-native": "^0.28.0",
"react-native-apple-healthkit": "file:///Users/greg/Dev/experimental/RCTAppleHealthKit"
}
}
/**
* Created by greg on 2016-06-27.
*/
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Navigator,
Text,
View
} from 'react-native';
class Index extends Component {
render() {
return (
<View style={styles.container}>
<Text style={styles.welcome}>
Index
</Text>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
instructions: {
textAlign: 'center',
color: '#333333',
marginBottom: 5,
},
});
module.exports = Index;
export default Index;
[ignore]
# We fork some components by platform.
.*/*.web.js
.*/*.android.js
# Some modules have their own node_modules with overlap
.*/node_modules/node-haste/.*
# Ugh
.*/node_modules/babel.*
.*/node_modules/babylon.*
.*/node_modules/invariant.*
# Ignore react and fbjs where there are overlaps, but don't ignore
# anything that react-native relies on
.*/node_modules/fbjs/lib/Map.js
.*/node_modules/fbjs/lib/ErrorUtils.js
# Flow has a built-in definition for the 'react' module which we prefer to use
# over the currently-untyped source
.*/node_modules/react/react.js
.*/node_modules/react/lib/React.js
.*/node_modules/react/lib/ReactDOM.js
.*/__mocks__/.*
.*/__tests__/.*
.*/commoner/test/source/widget/share.js
# Ignore commoner tests
.*/node_modules/commoner/test/.*
# See https://github.com/facebook/flow/issues/442
.*/react-tools/node_modules/commoner/lib/reader.js
# Ignore jest
.*/node_modules/jest-cli/.*
# Ignore Website
.*/website/.*
# Ignore generators
.*/local-cli/generator.*
# Ignore BUCK generated folders
.*\.buckd/
# Ignore RNPM
.*/local-cli/rnpm/.*
.*/node_modules/is-my-json-valid/test/.*\.json
.*/node_modules/iconv-lite/encodings/tables/.*\.json
.*/node_modules/y18n/test/.*\.json
.*/node_modules/spdx-license-ids/spdx-license-ids.json
.*/node_modules/spdx-exceptions/index.json
.*/node_modules/resolve/test/subdirs/node_modules/a/b/c/x.json
.*/node_modules/resolve/lib/core.json
.*/node_modules/jsonparse/samplejson/.*\.json
.*/node_modules/json5/test/.*\.json
.*/node_modules/ua-parser-js/test/.*\.json
.*/node_modules/builtin-modules/builtin-modules.json
.*/node_modules/binary-extensions/binary-extensions.json
.*/node_modules/url-regex/tlds.json
.*/node_modules/joi/.*\.json
.*/node_modules/isemail/.*\.json
.*/node_modules/tr46/.*\.json
[include]
[libs]
node_modules/react-native/Libraries/react-native/react-native-interface.js
node_modules/react-native/flow
flow/
[options]
module.system=haste
esproposal.class_static_fields=enable
esproposal.class_instance_fields=enable
experimental.strict_type_args=true
munge_underscores=true
module.name_mapper='^image![a-zA-Z0-9$_-]+$' -> 'GlobalImageStub'
module.name_mapper='^[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\)$' -> 'RelativeImageStub'
suppress_type=$FlowIssue
suppress_type=$FlowFixMe
suppress_type=$FixMe
suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(2[0-6]\\|1[0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)
suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(2[0-6]\\|1[0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)?:? #[0-9]+
suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy
[version]
^0.26.0
# OSX
#
.DS_Store
# Xcode
#
build/
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
xcuserdata
*.xccheckout
*.moved-aside
DerivedData
*.hmap
*.ipa
*.xcuserstate
project.xcworkspace
# Android/IJ
#
*.iml
.idea
.gradle
local.properties
# node.js
#
node_modules/
npm-debug.log
# BUCK
buck-out/
\.buckd/
android/app/libs
android/keystores/debug.keystore
{}
\ No newline at end of file
# Steps Demo
![alt text](https://raw.githubusercontent.com/GregWilson/react-native-apple-healthkit/master/examples/images/steps_demo_screen.png "Steps Demo App Screenshot")
/**
* Created by greg on 2016-06-30.
*/
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Navigator,
Text,
View
} from 'react-native';
let Home = require('./components/home/index');
let Add = require('./components/add/index');
class StepsDemoApp extends Component {
render() {
return (
<Navigator
style={{ flex:1 }}
initialRoute={{ name: 'Home' }}
renderScene={ this.renderScene } />
);
}
renderScene(route, navigator) {
if(route.name == 'Home') {
return <Home navigator={navigator} />
}
if(route.name == 'Add') {
return <Add navigator={navigator} />
}
}
}
module.exports = StepsDemoApp;
export default StepsDemoApp;
/**
* Created by greg on 2016-06-30.
*/
import React, { Component } from 'react';
import {
Navigator,
TouchableOpacity,
ScrollView,
Text,
View
} from 'react-native';
import TimerMixin from 'react-timer-mixin';
var reactMixin = require('react-mixin');
import styles from '../../styles/styles';
class Add extends Component {
constructor(props) {
super(props);
this.state = {};
}
componentDidMount() {
}
componentWillUnmount() {
}
_onPressItem(key) {
console.log('_onPressItem() ==> ', key);
let self = this;
this.requestAnimationFrame(() => {
this.props.navigator.push({
name: key
});
})
}
render() {
return (
<Navigator
renderScene={this.renderScene.bind(this)}
navigator={this.props.navigator}
navigationBar={
<Navigator.NavigationBar style={styles.navigationBar}
routeMapper={NavigationBarRouteMapper} />
}/>
);
}
renderScene(route, navigator) {
return (
<View style={styles.sceneContainerWithNavbar}>
<Text>Add Steps</Text>
</View>
);
}
}
reactMixin(Add.prototype, TimerMixin);
var NavigationBarRouteMapper = {
LeftButton(route, navigator, index, nextState) {
return (
<TouchableOpacity style={styles.navbarTitleTouchable} onPress={() => {navigator.parentNavigator.pop()}}>
<Text style={styles.navbarTitle}>
Back
</Text>
</TouchableOpacity>
);
},
RightButton(route, navigator, index, nextState) {
return null;
},
Title(route, navigator, index, nextState) {
return (
<TouchableOpacity style={styles.navbarTitleTouchable}>
<Text style={styles.navbarTitle}>
Add Steps
</Text>
</TouchableOpacity>
);
}
};
module.exports = Add;
export default Add;
\ No newline at end of file
/**
* Created by greg on 2016-06-30.
*/
import React, { Component } from 'react';
import {
Navigator,
TouchableOpacity,
TouchableHighlight,
ScrollView,
ListView,
RecyclerViewBackedScrollView,
Text,
View
} from 'react-native';
import _ from 'lodash';
import moment from 'moment';
//import TimerMixin from 'react-timer-mixin';
//var reactMixin = require('react-mixin');
import styles from '../../styles/styles';
class History extends Component {
constructor(props) {
super(props);
let ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
if(_.isArray(this.props.data)){
ds = ds.cloneWithRows(this.props.data);
}
this.state = {
dataSource: ds,
};
}
componentDidMount() {}
componentWillUnmount() {}
componentWillReceiveProps(newProps) {
if(newProps && newProps.data && _.isArray(newProps.data)){
this.setState({
dataSource: this.state.dataSource.cloneWithRows(newProps.data),
});
}
}
render() {
return (
<ListView
dataSource={this.state.dataSource}
enableEmptySections={true}
renderRow={this._renderRow}
renderScrollComponent={props => <RecyclerViewBackedScrollView {...props} />}
/>
);
}
_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 (
<TouchableHighlight onPress={() => {
//this._pressRow(rowID);
highlightRow(sectionID, rowID);
}}>
<View>
<View style={styles.listViewRow}>
<View style={styles.col_1_3}>
<Text style={{flex:1, fontWeight: '600'}}>
{rowData.value}
</Text>
</View>
<View style={styles.col_2_3}>
<Text style={{flex:1, textAlign: 'right',}}>
{formattedDate}
</Text>
</View>
</View>
</View>
</TouchableHighlight>
);
}
}
//reactMixin(History.prototype, TimerMixin);
module.exports = History;
export default History;
/**
* Created by greg on 2016-06-30.
*/
import React, { Component } from 'react';
import {
Navigator,
TouchableOpacity,
ScrollView,
Image,
Text,
View,
NativeAppEventEmitter,
} from 'react-native';
import AppleHealthKit from 'react-native-apple-healthkit';
import styles from '../../styles/styles';
import History from './history';
// setup the HealthKit initialization options
const HKPERMS = AppleHealthKit.Constants.Permissions;
const HKOPTIONS = {
permissions: {
read: [
HKPERMS.StepCount,
HKPERMS.DistanceWalkingRunning,
HKPERMS.FlightsClimbed,
HKPERMS.Height,
HKPERMS.DateOfBirth,
HKPERMS.BiologicalSex,
HKPERMS.SleepAnalysis,
],
write: [
HKPERMS.StepCount
],
}
};
/**
* React Component
*/
class Home extends Component {
constructor(props) {
super(props);
this.state = {
stepsToday: 0,
stepHistory: [],
};
}
/**
* 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() {
AppleHealthKit.isAvailable((err,available) => {
if(available){
AppleHealthKit.initHealthKit(HKOPTIONS, (err, res) => {
if(this._handleHKError(err, 'initHealthKit')){
return;
}
AppleHealthKit.initStepCountObserver({}, () => {});
var subscription = NativeAppEventEmitter.addListener(
'change:steps',
(evt) => {
console.log('change:steps EVENT!! : ', evt);
this._fetchStepsToday();
}
);
this.sub = subscription;
this._fetchStepsToday();
this._fetchStepsHistory();
this._fetchSleepAnalysis();
});
}
});
}
componentWillUnmount() {
this.sub.remove();
}
/**
* get today's step count from HealthKit. on success update
* the component state
* @private
*/
_fetchStepsToday() {
AppleHealthKit.getStepCount(null, (err, res) => {
if(this._handleHKError(err, 'getStepCount')){
return;
}
this.setState({stepsToday: res.value});
});
}
/**
* get the step history from options.startDate through the
* current time. on success update the component state
* @private
*/
_fetchStepsHistory() {
let options = {
startDate: (new Date(2016,4,1)).toISOString(),
};
AppleHealthKit.getDailyStepCountSamples(options, (err, res) => {
if(this._handleHKError(err, 'getDailyStepCountSamples')){
return;
}
this.setState({stepHistory: res});
});
}
_fetchSleepAnalysis() {
let options = {
startDate: (new Date(2016,10,1)).toISOString(),
};
AppleHealthKit.getSleepSamples(options, (err, res) => {
if(this._handleHKError(err, 'getSleepSamples')){
return;
}
//this.setState({stepHistory: res});
console.log('######################################')
console.log('### SLEEP SAMPLES ###')
console.log('######################################')
console.log(res)
});
}
/**
* render the Navigator which will render the navigation
* bar and the scene
* @returns {XML}
*/
render() {
return (
<Navigator
renderScene={this.renderScene.bind(this)}
navigator={this.props.navigator}
navigationBar={
<Navigator.NavigationBar style={styles.navigationBar}
routeMapper={NavigationBarRouteMapper} />
}/>
);
}
/**
* render the scene
* @param route
* @param navigator
* @returns {XML}
*/
renderScene(route, navigator) {
return (
<View style={styles.sceneContainerWithNavbar}>
<View style={styles.stepsContainer}>
<Image style={styles.stepsIcon}
source={require('../../assets/images/steps.png')}>
</Image>
<Text style={styles.stepsLabel}>
Today's Steps
</Text>
<Text style={styles.stepsValue}>
{this.state.stepsToday}
</Text>
</View>
<View style={styles.historyContainer}>
<View style={styles.titleRow}>
<Text>
History
</Text>
</View>
<History data={this.state.stepHistory} />
</View>
</View>
);
}
/**
* 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 {
if(err){
let errStr = 'HealthKit_ERROR['+method+'] : ';
errStr += (err && err.message) ? err.message : err;
console.log(errStr);
return true;
}
return false;
}
}
var NavigationBarRouteMapper = {
LeftButton(route, navigator, index, nextState) {
return null;
},
RightButton(route, navigator, index, nextState) {
return (
<TouchableOpacity style={styles.navbarTitleTouchable}
onPress={() => { navigator.parentNavigator.push({name: 'Add'})}}>
<Text style={styles.navbarPlusButton}>
+
</Text>
</TouchableOpacity>
);
},
Title(route, navigator, index, nextState) {
return (
<TouchableOpacity style={styles.navbarTitleTouchable}>
<Text style={styles.navbarTitle}>
HealthKit Steps
</Text>
</TouchableOpacity>
);
}
};
module.exports = Home;
export default Home;
/**
* Created by greg on 2016-06-30.
*/
import {
Platform,
StyleSheet
} from 'react-native';
const styles = StyleSheet.create({
sceneContainerWithNavbar: {
flex: 1,
flexDirection: 'column',
//justifyContent: 'flex-start',
//alignItems: 'flex-start',
marginTop: (Platform.OS === 'ios') ? 64 : 54,
backgroundColor: '#FFFFFF'
},
navigationBar: {
borderBottomWidth: 1,
borderBottomColor: '#cccccc',
backgroundColor: '#f5f5f5'
},
navbarTitleTouchable: {
flex: 1,
justifyContent: 'center'
},
navbarTitle: {
color: '#FD2D55',
margin: 10,
fontSize: 18
},
navbarPlusButton: {
fontSize:33,
marginRight:13,
color: '#FD2D55',
top: -3
},
stepsContainer: {
height:100,
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: {
flex: 1,
//backgroundColor: '#0088cc',
},
titleRow: {
height:40,
alignItems: 'center',
//backgroundColor: '#FF00FF'
borderTopColor: '#DDDDDD',
borderBottomColor: '#DDDDDD',
borderTopWidth: 1,
borderBottomWidth: 1,
paddingTop:10,
backgroundColor: '#EFEFEF',
},
listViewRow: {
flexDirection: 'row',
justifyContent: 'center',
padding: 10,
backgroundColor: '#F6F6F6',
borderBottomColor: '#DADADA',
borderBottomWidth: 1,
},
row_1_3: {
flex: 0.33,
flexDirection:'column',
padding:10,
//backgroundColor: '#FF8000'
},
row_2_3: {
flex: 0.66,
flexDirection:'column',
padding:10,
//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: {
borderTopColor: '#CCCCCC',
borderTopWidth: 1,
},
largeCenteredText: {
textAlign: 'center',
flexDirection:'row',
fontSize:34,
marginTop:60,
},
dashboardListItemLabel: {
fontSize:12,
color: '#FD2D55',
position:'absolute',
left: 70,
top:0,
},
dashboardListItemValue: {
fontSize:22,
color: '#47a292',
position:'absolute',
left: 70,
top:15,
},
sceneContainerFull: {
flex: 1,
flexDirection: 'column',
//justifyContent: 'flex-start',
//alignItems: 'flex-start',
marginTop: 0,
backgroundColor: '#FFFFFF'
},
dashboardToday: {
height: 30,
alignItems: 'stretch',
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'rgba(162, 162, 162, 0.2)',
},
dashboardTodayText: {
color: '#a2a2a2',
},
dashboardListItemHighlight: {
flexDirection: 'row',
alignSelf: 'stretch',
justifyContent: 'center',
//flex:1,
//alignSelf: 'stretch',
//overflow: 'hidden',
},
dashboardListItemView: {
flex: 1,
//backgroundColor: '#FDFDFD',
backgroundColor: '#FDFDFD',
//paddingTop:74,
//flexDirection: 'row',
flexDirection: 'column',
alignSelf: 'stretch',
justifyContent: 'flex-start',
alignItems: 'flex-start',
paddingTop:15,
paddingBottom: 15,
//flexWrap: 'wrap',
borderBottomColor: '#AAAAAA',
borderBottomWidth: 1,
},
dashboardListItemViewTransparent: {
flex: 1,
//backgroundColor: '#FDFDFD',
backgroundColor: 'transparent',
//paddingTop:74,
//flexDirection: 'row',
flexDirection: 'column',
alignSelf: 'stretch',
justifyContent: 'flex-start',
alignItems: 'flex-start',
paddingTop:15,
paddingBottom: 15,
//flexWrap: 'wrap',
borderBottomColor: '#AAAAAA',
borderBottomWidth: 1,
},
dashboardListItem: {
flexDirection: 'row',
alignSelf: 'stretch',
justifyContent: 'space-between',
flex:1,
backgroundColor: 'transparent',
},
dashboardListItemIcon: {
width: 40,
height: 40,
marginLeft: 10,
opacity:0.7,
//marginTop: 50,
//backgroundColor: 'transparent',
alignSelf: 'flex-start',
},
dashboardListItemText: {
flex: 1,
flexDirection: 'column',
alignSelf: 'flex-start',
marginLeft: 20,
fontSize: 29,
color: '#47a292',
//color: '#98CA3F',
//color: '#644496',
flexWrap: 'wrap',
backgroundColor:'transparent',
},
});
module.exports = styles;
export default styles;
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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