Advertisement
Guest User

Untitled

a guest
Apr 22nd, 2019
133
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.69 KB | None | 0 0
  1. import React from 'react';
  2. import { StyleSheet,
  3. Text,
  4. View,
  5. Button,
  6. TextInput,
  7. Keyboard,
  8. TouchableWithoutFeedback,
  9. FlatList,
  10. TouchableOpacity,
  11. Dimensions,
  12. Modal,
  13. Platform } from 'react-native';
  14. // import { List, ListItem } from 'react-native-elements'
  15. import { ActionSheet } from 'native-base';
  16. import { Actions } from 'react-native-router-flux';
  17. import {connect} from 'react-redux';
  18. import cloneDeep from 'lodash/cloneDeep';
  19.  
  20. import { RNCamera } from 'react-native-camera';
  21.  
  22. // For future use, this is the link to app settings if user does not allow camera access
  23. // Linking.openURL('app-settings:')
  24.  
  25. const Width = Dimensions.get('window').width;
  26. const Height = Dimensions.get('window').height;
  27. const API_KEY = 'LzeIbgSBnewzVpdbt0GGDAOBmQNZDcvklWy2fERw';
  28. const NUM_RESULTS = '25';
  29.  
  30.  
  31. const DESIRED_RATIO = "16:9";
  32.  
  33. class Nutrition extends React.Component {
  34. constructor(props){
  35. super(props);
  36. this.state = {
  37. text : '',
  38. foodData : {},
  39. loading : false,
  40.  
  41. cameraOpen : false,
  42. cameraType: RNCamera.Constants.Type.back,
  43. flashMode: RNCamera.Constants.FlashMode.auto,
  44. barcodeFinderVisible: true,
  45. cameraRatio: DESIRED_RATIO
  46. }
  47. }
  48.  
  49. toggleCamera(){
  50. this.setState({ cameraOpen : !cameraOpen });
  51. }
  52.  
  53. renderItem({item}){
  54. // console.log(item);
  55. if( item.phosphorus ){
  56. return (
  57. // <ListItem
  58. // title={item.item.name}
  59. // titleStyle={{ color: 'black' }}
  60. // badge={{ value : item.item.phosphorus.value, textStyle: { color: 'blue' } }}
  61. // />
  62. <Text>{item.name} : {item.phosphorus.value}mg</Text>
  63.  
  64. )
  65.  
  66. }
  67. // else {
  68. // return <Text>{item.item.nbdno} : Not listed</Text>
  69. // }
  70. }
  71.  
  72. _listEmptyComponent = () => {
  73. return (
  74. <View>
  75. <Text>No results.</Text>
  76. </View>
  77. )
  78. }
  79.  
  80. prepareRatio = async () => {
  81. console.log('Preparing ratio...');
  82. console.log(this.cam);
  83. if (Platform.OS === 'android' && this.cam) {
  84. const ratios = await this.cam.getSupportedRatiosAsync();
  85.  
  86. // See if the current device has your desired ratio, otherwise get the maximum supported one
  87. // Usually the last element of "ratios" is the maximum supported ratio
  88. const ratio = ratios.find((ratio) => ratio === DESIRED_RATIO) || ratios[ratios.length - 1];
  89. this.setState({ cameraRatio : ratio }, () => {console.log(JSON.stringify(this.state, null, 2))});
  90. }
  91. }
  92.  
  93. render() {
  94. return (
  95. <View style={[styles.mainContainer, {backgroundColor : this.props.themeProp.backgroundColor}]}>
  96. {this.state.cameraOpen &&
  97. <Modal>
  98. <View style={{ flex: 1, backgroundColor: "black", opacity: 0.9999 }}>
  99. <RNCamera
  100. ref={cam => {
  101. this.cam = cam;
  102. }}
  103. // onCameraReady={this.prepareRatio}
  104. ratio={this.state.cameraRatio}
  105. style={styles.preview}
  106. type={this.state.cameraType}
  107. flashMode={this.state.flashMode}
  108. permissionDialogTitle={'Permission to use camera'}
  109. permissionDialogMessage={'We need your permission to use your camera'}
  110. captureAudio={false}
  111. onBarCodeRead={this.onBarCodeRead}
  112. barcodeFinderVisible={this.state.barcodeFinderVisible}
  113. barcodeFinderWidth={280}
  114. barcodeFinderHeight={220}
  115. barcodeFinderBorderColor="white"
  116. barcodeFinderBorderWidth={2}
  117. defaultTouchToFocus
  118. >
  119. <View style={styles.cameraView}>
  120. <Button onPress={ () => this.setState({ cameraOpen : false })} title="Cancel"></Button>
  121. </View>
  122. </RNCamera>
  123. </View>
  124. </Modal>
  125. }
  126. <View style={styles.textInputContainer}>
  127. <TextInput style={styles.textInput}
  128. onChangeText={(text) => this.setState({text})}
  129. value={this.state.text}
  130. clearTextOnFocus
  131. placeholder={'Search for a food item...'}
  132. placeholderColor={'gray'}
  133.  
  134. onSubmitEditing={this.submitText}
  135. />
  136. <View style={styles.textButtonsView}>
  137. <TouchableOpacity style={styles.textButton} onPress={() => this.setState({text: ""})}>
  138. <Text style={styles.buttonText}>Clear</Text>
  139. </TouchableOpacity>
  140. <TouchableOpacity style={styles.textButton} onPress={() => { Keyboard.dismiss(); this.submitText(); }}>
  141. <Text style={styles.buttonText}>Submit</Text>
  142. </TouchableOpacity>
  143. </View>
  144. <View style={styles.scanButtonView}>
  145. <TouchableOpacity style={styles.scanButton} onPress={() => this.setState( { cameraOpen : true })}>
  146. <Text style={styles.buttonText}>Scan Barcode</Text>
  147. </TouchableOpacity>
  148. </View>
  149. {/* <Button onPress={() => {console.log(JSON.stringify(this.state, null, 2))} } title="Log State"/> */}
  150. </View>
  151. <TouchableWithoutFeedback onPress={ () => Keyboard.dismiss() }>
  152. <View style={{flex : 1}}>
  153. {/* <List> */}
  154. <FlatList
  155. keyExtractor={ (item) => item.ndbno }
  156. data={ this.state.foodData.list ? this.state.foodData.list.item : [] }
  157. renderItem={this.renderItem}
  158. ListEmptyComponent={this._listEmptyComponent}
  159. contentContainerStyle={styles.list}
  160. ListFooterComponent={USDACredit()}
  161. />
  162. {/* </List> */}
  163. </View>
  164. </TouchableWithoutFeedback>
  165. </View>
  166. );
  167. }
  168.  
  169. onBarCodeRead = (scanResult) => {
  170. console.warn(scanResult.type);
  171. console.warn(scanResult.data);
  172. console.warn(scanResult.data.slice(1));
  173. const UPC = scanResult.data.slice(1);
  174. this.setState({ cameraOpen : false, text : UPC }, this.submitText());
  175. // this.getUSDAProductInfo(UPC);
  176.  
  177. // if (scanResult.data != null) {
  178. // if (!this.barcodeCodes.includes(scanResult.data)) {
  179. // this.barcodeCodes.push(scanResult.data);
  180. // console.warn('onBarCodeRead call');
  181. // }
  182. // }
  183. return;
  184. }
  185.  
  186. submitText = () => {
  187.  
  188. this.getUSDAProductInfo(this.state.text);
  189.  
  190. }
  191.  
  192. getUSDAProductInfo(submittedText){
  193. let url = 'https://api.nal.usda.gov/ndb/search/?format=json&q=';
  194. url += encodeURIComponent(submittedText);
  195. url += '&max=';
  196. url += NUM_RESULTS;
  197. url += '&offset=0&api_key=';
  198. url += API_KEY;
  199.  
  200. console.log('URL produced: ' + url);
  201. return fetch(url)
  202. .then((response) => {
  203. if(response.ok){
  204. console.log('USDA Response1: ' + JSON.stringify(response, null, 2));
  205. return response;
  206. }
  207. else{
  208. console.log(`Request rejected with status ${response.status}`);
  209. throw Error(`Search Request rejected with status ${response.status}`);
  210. }
  211. })
  212. .then(response => response.json())
  213. // .then(responseJson => { console.dir(responseJson); return responseJson })
  214. .then( responseJson => this.getNutrients(responseJson))
  215. // .then(responseJson => { this.setState({ foodData : responseJson }, function() {this.getNutrients()})})
  216. .catch((error) => {
  217. console.log(error);
  218. });
  219. }
  220.  
  221. getNutrients(foodDataCopy){
  222. console.log("Getting Nutrients...");
  223. // console.log('Current state in getNutrients : ');
  224. // console.log(JSON.stringify(this.state.foodData, null, 2));
  225.  
  226. if(foodDataCopy){
  227.  
  228. // if(this.state.foodData){
  229. // let foodDataCopy = cloneDeep(this.state.foodData);
  230. // console.log(' COPY : ');
  231. // console.log(JSON.stringify(foodDataCopy, null, 2));
  232.  
  233. const reqNDOs = foodDataCopy.list.item.map( (item) => item.ndbno );
  234. console.log("NDBnos : " + reqNDOs);
  235.  
  236. let url = 'https://api.nal.usda.gov/ndb/V2/reports?';
  237.  
  238. for(let i = 0; i < reqNDOs.length; i++){
  239. url += 'ndbno=';
  240. url += reqNDOs[i];
  241. if(i < reqNDOs.length){
  242. url += '&'
  243. }
  244. }
  245. url += 'type=b&format=json&api_key=';
  246. url += API_KEY;
  247.  
  248. console.log('url created : ' + url);
  249. return fetch(url)
  250. .then((response) => {
  251. if(response.ok){
  252. console.log('USDA Response2: ' + JSON.stringify(response, null, 2));
  253. return response;
  254. }
  255. else{
  256. console.log(`Nutrition Request rejected with status ${response.status}`);
  257. // throw Error(`Request rejected with status ${response.status}`);
  258. }
  259. })
  260. .then(response => response.json())
  261. .then(responseJson => {
  262. foodDataCopy.list.item.forEach( food => {
  263. let match = responseJson.foods.find( res => res.food.desc.ndbno === food.ndbno );
  264. food.phosphorus = match.food.nutrients.find( o => { return o.nutrient_id === '305' })
  265. })
  266. })
  267. .then( () => { this.setState({ foodData : foodDataCopy }, () => {
  268. console.log('Updating state...');
  269. console.log(JSON.stringify(this.state.foodData, null, 2)) } )})
  270. .catch((error) => {
  271. console.log(error);
  272. });
  273.  
  274. } else {
  275. // this.setState({ displayData : {} });
  276. }
  277. }
  278.  
  279. }
  280.  
  281. const USDACredit = () => {
  282. return (
  283. <View style={{flex:1,justifyContent: "center",alignItems: "center"}}>
  284. <Text style={{textAlignVertical: "center",textAlign: "center",}}>U.S. Department of Agriculture, Agricultural Research Service. 20xx. USDA National Nutrient Database for Standard Reference, Release . Nutrient Data Laboratory Home Page, http://www.ars.usda.gov/nutrientdata</Text>
  285. </View>
  286. )
  287. }
  288.  
  289. const styles = StyleSheet.create({
  290. mainContainer: {
  291. flex: 1,
  292. },
  293.  
  294. textInputContainer: {
  295. margin : 15
  296. },
  297.  
  298. textInput: {
  299. height: 40,
  300. borderColor: 'gray',
  301. borderWidth: 1,
  302. backgroundColor : 'white'
  303.  
  304. },
  305.  
  306. textButtonsView: {
  307. flexDirection : 'row',
  308. justifyContent : 'space-around',
  309. alignItems : 'center',
  310. margin : 10,
  311. },
  312.  
  313. textButton:{
  314. backgroundColor : 'lightgray',
  315. height : 40,
  316. width : 120,
  317. justifyContent : 'center',
  318. alignItems : 'center'
  319. },
  320.  
  321. buttonText:{
  322. fontSize : 24
  323. },
  324.  
  325. scanButtonView: {
  326. justifyContent : 'space-around',
  327. alignItems: 'center',
  328. justifyContent: 'center',
  329. margin : 10
  330. },
  331.  
  332. scanButton:{
  333. backgroundColor : 'lightgray',
  334. height : 45,
  335. width : 300,
  336. justifyContent : 'center',
  337. alignItems : 'center'
  338. },
  339.  
  340. list: {
  341.  
  342. },
  343. preview: {
  344. flex: 1,
  345. justifyContent: 'flex-end',
  346. alignItems: 'center',
  347. width: Width,
  348. height: Height,
  349. },
  350. capture: {
  351. flex: 0,
  352. backgroundColor: '#fff',
  353. borderRadius: 5,
  354. padding: 15,
  355. paddingHorizontal: 20,
  356. alignSelf: 'center',
  357. margin: 20,
  358. },
  359. cameraView : {
  360. marginBottom : 80,
  361. }
  362.  
  363. });
  364.  
  365. function mapStateToProps(state) {
  366. return {
  367. themeProp: state.themeProps,
  368. fontProp: state.fontProps
  369. };
  370. }
  371.  
  372.  
  373. export default connect(mapStateToProps)(Nutrition);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement