· 7 years ago · May 16, 2018, 01:30 PM
1/**
2 * Sample React Native App
3 * https://github.com/facebook/react-native
4 * @flow
5 */
6
7import keys from './assets/keys'
8import Map from './components/Map/Map'
9import Loader from './components/Loader/Loader'
10import User from './components/User/User'
11// import UserExpress from './components/User/UserExpress'
12import Menu from './components/Menu/Menu'
13import SideMenu from 'react-native-side-menu';
14import ModalConfirm from './components/ModalConfirm/ModalConfirm'
15
16
17
18import React, { Component } from 'react';
19import {
20 AppRegistry,
21 Dimensions,
22 StyleSheet,
23 Text,
24 TouchableHighlight,
25 View,
26 Image,
27 ActivityIndicator,
28 TouchableOpacity,
29 AsyncStorage,
30 TextInput,
31 Alert,
32 Button,
33} from 'react-native';
34import Camera from 'react-native-camera';
35import SplashScreen from 'react-native-splash-screen'
36import store from 'react-native-simple-store'
37import {
38 createStackNavigator,
39 withNavigation
40} from 'react-navigation';
41
42import axios from 'axios';
43import fs from 'react-native-fs'
44import RNFetchBlob from 'react-native-fetch-blob'
45
46
47const styles = StyleSheet.create({
48 container: {
49 position: 'absolute',
50 top: 0,
51 left: 0,
52 right: 0,
53 bottom: 0,
54 justifyContent: 'flex-end',
55 alignItems: 'center',
56
57 },
58 preview: {
59 flex: 1,
60 justifyContent: 'flex-end',
61 alignItems: 'center',
62 height: Dimensions.get('window').height,
63 width: Dimensions.get('window').width
64 },
65 capture: {
66 width: 70,
67 height: 70,
68 borderRadius: 35,
69 borderWidth: 5,
70 borderColor: '#FFF',
71 marginBottom: 15,
72 },
73 cancel: {
74 position: 'absolute',
75 right: 20,
76 top: 20,
77 backgroundColor: 'transparent',
78 color: '#FFF',
79 fontWeight: '600',
80 fontSize: 17,
81 },
82 map: {
83 position: 'absolute',
84 top: 0,
85 left: 0,
86 right: 0,
87 bottom: 0,
88 },
89 welcome: {
90 fontSize: 20,
91 textAlign: 'center',
92 margin: 10,
93 },
94 instructions: {
95 textAlign: 'center',
96 color: '#333333',
97 marginBottom: 5,
98 },
99 column: {
100 top: 0,
101 left: 0,
102 right: 0,
103 bottom: 0,
104 margin: 10
105 },
106 title: {
107 fontSize: 30,
108 alignSelf: 'center',
109 marginBottom: 30
110 },
111 buttonText: {
112 fontSize: 18,
113 color: 'white',
114 alignSelf: 'center'
115 },
116 button: {
117 height: 30,
118 backgroundColor: '#938CB3',
119 borderColor: '#938CB3',
120 borderWidth: 1,
121 borderRadius: 50,
122 marginBottom: 20,
123 justifyContent: 'center',
124 alignItems: 'center',
125 width: 200,
126 left: 0,
127 right: 0
128 },
129 buttonLogin: {
130 height: 30,
131 backgroundColor: '#938CB3',
132 borderColor: '#938CB3',
133 borderWidth: 1,
134 borderRadius: 50,
135 marginBottom: 280,
136 justifyContent: 'center',
137 alignItems: 'center',
138 width: 200,
139 left: 0,
140 right: 0
141 },
142 input: {
143 textAlign: 'center',
144 width: '90%',
145 marginBottom: 20,
146 height: 40,
147 borderRadius: 5 ,
148 fontSize: 20,
149 },
150 image: {
151 width: 83.33,
152 height:145.33,
153 marginTop: 15
154 },
155 user: {
156 flex: 1,
157 backgroundColor: 'black'
158 }
159});
160
161
162
163export default class App extends Component {
164
165 constructor(props) {
166 super(props);
167 this.state = {
168 latitude: null,
169 longitude: null,
170 city: null,
171 street: null,
172 car: {
173 plate: null,
174 model: null,
175 color: null,
176 make: null,
177 recognize_vehicle: 0
178 },
179 auth_token: '',
180 auth: false,
181 error: null,
182 path: null,
183 pathPlaceHolder: null, // placeholder to path so it will update the 'path' only after plate recognized
184 updatePath: this.updatePath,
185 loading: false,
186 isOpen: false,
187 modalVisible: false,
188 user: this.props.user
189 };
190 }
191
192
193
194 // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% TESTING ERA FOR LOGIN %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
195
196
197
198 checkToken = () => {
199 AsyncStorage.getItem('user')
200 .then((res) => {
201 res = JSON.parse(res)
202 console.log('this is checkToken()',res.token)
203 // this.renderUserSection(res.token);
204 return (
205 <View style={styles.container}>
206 {!res.token ? this.renderUser() : this.renderApp()}
207 </View>
208 )
209 })
210 .catch((err) => {
211 console.log(err)
212 })
213 }
214
215 setToken = (token, auth) => {
216 AsyncStorage.getItem('user')
217 .then((res) => {
218 res = JSON.parse(res)
219 res.token = token
220 AsyncStorage.setItem('user', JSON.stringify(res))
221 this.setState({ auth_token: token });
222 this.setState({ auth: auth });
223 })
224 .then(() => this.checkToken())
225 .done();
226 }
227
228 createDataBase = () => {
229 AsyncStorage.setItem('user', JSON.stringify({
230 token: undefined,
231 credit: 1,
232 points: 0,
233 lvl: 1
234 }))
235 }
236
237 removeToken = () => {
238 // this.setState({auth_token: this.state.auth_token})
239 console.log('this is this.state.auth_token', this.state.auth_token)
240 this.setToken(undefined, false);
241 }
242
243
244 Signup = async () => {
245 fetch(url , {
246 method: 'post',
247 headers: {
248 'Content-Type': 'application/json'
249 },
250 body: JSON.stringify({
251 "provider": "username",
252 "data": {
253 "username": this.state.username,
254 "email": this.state.email,
255 "password": this.state.password
256 }
257 })
258 })
259 .then((response) => response.json())
260 .then((res) => {
261 if(typeof(res.message) != "undefined"){
262 Alert.alert("Error signing up", "Error: "+ res.message);
263 }
264 else{
265 // if there is no db create one
266 // this.createDataBase();
267 // this.setToken(res.auth_token);
268 // this.setState({ auth_token: res.auth_token });
269 Alert.alert("Success", "You have succesfully signed up");
270 }
271 })
272 .catch((error) => {
273 console.error(error);
274 });
275 }
276
277
278
279
280
281 Login = async () => {
282 fetch(url , {
283 method: 'post',
284 headers: {
285 'Content-Type': 'application/json'
286 },
287 body: JSON.stringify({
288 "provider": "username",
289 "data": {
290 "username": this.state.username,
291 "email": this.state.email,
292 "password": this.state.password
293 }
294 })
295 })
296 .then((response) => response.json())
297 .then((res) => {
298 if (typeof(res.message) != "undefined") {
299 Alert.alert("Error", "Error: "+ res.message);
300 } else {
301 this.setToken(res.auth_token, true);
302 // this.checkToken();
303
304 Alert.alert("Welcome", " You have succesfully logged in");
305 }
306 })
307 .catch((error) => {
308 console.error(error);
309 });
310 }
311
312
313renderUser = () => {
314 console.log('render UserSection')
315 return (
316 <View style={styles.container}>
317
318 <Image
319 source={require('./components/User/FirstTry4.png')}
320 style={styles.image}
321 />
322
323 <TextInput
324 placeholder="Enter User name"
325 onChangeText={ TextInputValue =>
326 this.setState({username : TextInputValue }) }
327 style={styles.input}
328 />
329 <TextInput
330 placeholder="Enter email"
331 onChangeText={ TextInputValue =>
332 this.setState({email : TextInputValue }) }
333 style={styles.input}
334 />
335 <TextInput
336 placeholder="Enter password"
337 onChangeText={ TextInputValue =>
338 this.setState({password: TextInputValue }) }
339 secureTextEntry={true}
340 style={styles.input}
341 />
342 <TouchableHighlight onPress={this.Signup.bind(this)} style={styles.button}>
343 <Text style={styles.buttonText}>SignUp</Text>
344 </TouchableHighlight>
345
346 <TouchableHighlight onPress={this.Login.bind(this)} style={styles.buttonLogin}>
347 <Text style={styles.buttonText}>Login</Text>
348 </TouchableHighlight>
349
350 </View>
351 )
352}
353
354renderApp = () => {
355 console.log('render App')
356 !this.state.loading ?
357 <View style={styles.container}>
358 {this.state.path ? this.renderMap() : this.renderCamera()}
359 </View> :
360 <View style={styles.container}>
361 <Loader loading={this.state.loading}/>
362 </View>
363 }
364
365
366
367 // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% TESTING ERA FOR LOGIN %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
368
369
370
371
372
373// remove car data so it could refresh and take another photo
374removeAllCarStateData = () => {
375 this.setState({
376 car: {
377 plate: null,
378 model: null,
379 color: null,
380 make: null,
381 recognize_vehicle: 0
382 }
383 })
384}
385
386 fillCarDetailsInState = (res) => { // taking the promise from the response as argument
387 if (this.state.car.recognize_vehicle === 0) { // if there is no need for car recognition update only the plate
388 this.setState({
389 car: {
390 plate: res.data.results[0].plate
391 },
392 path: this.state.pathPlaceHolder
393 })
394 } else {
395 this.setState({ // update the state with thw API data
396 car: {
397 plate: res.data.results[0].plate,
398 model: res.data.results[0].vehicle.make_model[0].name,
399 color: res.data.results[0].vehicle.color[0].name,
400 make: res.data.results[0].vehicle.make[0].name
401 },
402 path: this.state.pathPlaceHolder // update path so it can render the map
403 })
404 }
405 }
406
407
408
409 recognizeCar = (image) => {
410 this.startLoader(true) // cousing for the worning *cant call setState on onmounted component it indicate a memory leak in your application*
411 axios({
412 method: 'post',
413 url: `https://api.openalpr.com/v2/recognize_bytes`,
414 data: image,
415 params: {
416 secret_key: 'sk_356549c5e643663684f6f9f2',
417 country: 'eu',
418 recognize_vehicle: this.state.car.recognize_vehicle
419 }
420 })
421 .then((res) => {
422 this.setModalVisible(); // open modal to ask if the details are good
423 this.fillCarDetailsInState(res);
424 this.startLoader(false); // remove loader
425 this.msgWithCarDetails();
426 })
427 .catch((errInFetch) => { // catch any error in the API
428 console.log('i am error:', errInFetch)
429 })
430 }
431
432
433
434 setModalVisible = () => {
435 this.setState({modalVisible: !this.state.modalVisible});
436 }
437
438
439 // toggle sidebar
440 toggle = () => {
441 this.setState({
442 isOpen: !this.state.isOpen,
443 });
444 }
445
446 // update sidebar state
447 updateMenuState = (isOpen) => {
448 this.setState({ isOpen });
449 }
450
451 //when item selected
452 onMenuItemSelected = item =>
453 this.setState({
454 isOpen: false,
455 selectedItem: item,
456 });
457
458 // start loader
459 startLoader = (value) => {
460 this.setState({
461 loading: value
462 });
463 }
464
465
466 // update image path to null when you want to back from map to camera
467 updatePath = () => {
468 this.setState({
469 path: null,
470 pathPlaceHolder: null
471 })
472 }
473
474
475 // geting user location
476 componentDidMount() {
477 console.log('render componentDidMount')
478 navigator.geolocation.getCurrentPosition(
479 (position) => {
480 this.setState({
481 latitude: position.coords.latitude,
482 longitude: position.coords.longitude,
483 error: null,
484 });
485 },
486 (error) => this.setState({ error: error.message }),
487 { enableHighAccuracy: true, timeout: 20000, maximumAge: 1000 },
488 );
489 SplashScreen.hide();
490 }
491
492 // rendering the camera
493 renderCamera = () => {
494 console.log('render camera')
495 console.log(this.state.auth)
496 // console.log(this.checkToken());
497 const menu = <Menu rmToken={this.removeToken}/>;
498 return (
499 <SideMenu // BUG: makes the camera to be at the left side when the device on its side
500 menu={menu}
501 isOpen={this.state.isOpen}
502 onChange={isOpen => this.updateMenuState(isOpen)}
503 >
504 <Camera
505 ref={(cam) => {
506 this.camera = cam;
507 }}
508 style={styles.preview}
509 aspect={Camera.constants.Aspect.fill}
510 captureTarget={Camera.constants.CaptureTarget.disk}
511 >
512 <TouchableHighlight
513 style={styles.capture}
514 onPress={() => this.getAddress(this.takePicture)}
515 underlayColor="rgba(255, 255, 255, 0.5)"
516 >
517 <View />
518 </TouchableHighlight>
519 </Camera>
520 </SideMenu >
521 );
522 }
523
524 // get address based on user location
525 getAddress = (takePhotoCb) => {
526 axios.get('https://maps.googleapis.com/maps/api/geocode/json', {
527 params: {
528 key: keys.googkey,
529 latlng: `${this.state.latitude},${this.state.longitude}`
530 }
531 })
532 .then((response) => {
533 // this.getLocation();
534 const address = response.data.results[0].formatted_address.split(',');
535 console.log(`i am address: ${address}`);
536 const street = address[0];
537 const city = address[1].replace(' ', '');
538 this.setState({
539 city: city,
540 street: street,
541 number: null
542 });
543 console.log(`city is: ${this.state.city} & street is: ${this.state.street}`)
544 })
545 .catch((error) => {
546 console.log(error);
547 });
548 takePhotoCb();
549 }
550
551 // taking photo
552 takePicture = () => {
553 this.camera.capture()
554 .then((data) => { // promise returned with the image path
555 console.log(`\n lat: ${this.state.latitude} \n lon: ${this.state.longitude}`);
556 this.setState({
557 pathPlaceHolder: data.path, // update path to image
558 });
559 return data.path; // returning proimse with the image path
560 })
561 .then((image) => { // using the image path we returned
562 this.recognise(image); // passing the image path to the recognize() function
563 console.log(`this is image ${image}`)
564 })
565 .catch(err => console.error(err));
566 }
567
568 recognise = (imageToRead) => {
569 this.startLoader(true) // cousing for the worning *cant call setState on onmounted component it indicate a memory leak in your application*
570 RNFetchBlob.fs.readFile(imageToRead , 'base64')
571 .then((data) => {
572 this.recognizeCar(data);
573 })
574 .catch((err) => {
575 console.log(err);
576 })
577
578 }
579
580 getMap = () => { // not working
581 return (
582 <View style={styles.container}>
583 <Map
584 lat={this.state.latitude}
585 lon={this.state.longitude}
586 updatePath={this.updatePath}
587 city={this.state.city}
588 street={this.state.street}
589 removeCarData={this.removeAllCarStateData}
590 />
591 </View>
592 )
593 }
594
595
596 renderMap() {
597
598 return (
599
600 <View style={styles.container}>
601 <ModalConfirm
602 modalVisible={this.state.modalVisible}
603 setModalVisible={this.setModalVisible}
604 carPlate={this.state.car.plate}
605 city={this.state.city}
606 street={this.state.street}
607 getMap={this.getMap}
608 renderCamera={this.renderCamera}
609 updateImage={this.updatePath}
610 removeCarData={this.removeAllCarStateData}
611
612 />
613 <Map
614 lat={this.state.latitude}
615 lon={this.state.longitude}
616 updatePath={this.updatePath}
617 city={this.state.city}
618 street={this.state.street}
619 removeCarData={this.removeAllCarStateData}
620 />
621 </View>
622 )
623
624
625 }
626
627
628 render() {
629 <View>
630 {this.checkToken()}
631 </View>
632 )
633 }
634}
635
636AppRegistry.registerComponent('App', () => App);