Upload an image to Firebase with React Native - react-native

i am trying to make a photo uploader to firebase in react native. I followed a tutorial and adopted the code 1-on-1. However, after I want to execute the code everything appears to work until the code has to be uploaded then I get the following error:
Possible Unhandled Promise Rejection (id: 0): Error: An unknown error
has occurred.
fn#http://localhost:8081/index.bundle?platform=android&dev=true&minify=false:2132:45
http://localhost:8081/index.bundle?platform=android&dev=true&minify=false:127402:44
putFile#http://localhost:8081/index.bundle?platform=android&dev=true&minify=false:137147:104
uploadImage#http://localhost:8081/index.bundle?platform=android&dev=true&minify=false:210966:91
touchableHandlePress#http://localhost:8081/index.bundle?platform=android&dev=true&minify=false:54240:47
touchableHandlePress#[native code]
_performSideEffectsForTransition#http://localhost:8081/index.bundle?platform=android&dev=true&minify=false:52872:36
_performSideEffectsForTransition#[native code]
_receiveSignal#http://localhost:8081/index.bundle?platform=android&dev=true&minify=false:52798:46
_receiveSignal#[native code] touchableHandleResponderRelease#http://localhost:8081/index.bundle?platform=android&dev=true&minify=false:52677:26
touchableHandleResponderRelease#[native code]
invokeGuardedCallbackImpl#http://localhost:8081/index.bundle?platform=android&dev=true&minify=false:8997:21
invokeGuardedCallback#http://localhost:8081/index.bundle?platform=android&dev=true&minify=false:9093:42
invokeGuardedCallbackAndCatchFirstError#http://localhost:8081/index.bundle?platform=android&dev=true&minify=false:9097:36
executeDispatch#http://localhost:8081/index.bundle?platform=android&dev=true&minify=false:9204:48
executeDispatchesInOrder#http://localhost:8081/index.bundle?platform=android&dev=true&minify=false:9224:26
executeDispatchesAndRelease#http://localhost:8081/index.bundle?platform=android&dev=true&minify=false:9329:35
forEach#[native code]
forEachAccumulated#http://localhost:8081/index.bundle?platform=android&dev=true&minify=false:9319:22
runEventsInBatch#http://localhost:8081/index.bundle?platform=android&dev=true&minify=false:9353:27
runExtractedPluginEventsInBatch#http://localhost:8081/index.bundle?platform=android&dev=true&minify=false:9441:25
http://localhost:8081/index.bundle?platform=android&dev=true&minify=false:10467:42
batchedUpdates$1#http://localhost:8081/index.bundle?platform=android&dev=true&minify=false:21921:20
batchedUpdates#http://localhost:8081/index.bundle?platform=android&dev=true&minify=false:10415:36
_receiveRootNodeIDEvent#http://localhost:8081/index.bundle?platform=android&dev=true&minify=false:10466:23
receiveTouches#http://localhost:8081/index.bundle?platform=android&dev=true&minify=false:10496:34
__callFunction#http://localhost:8081/index.bundle?platform=android&dev=true&minify=false:2650:49
http://localhost:8081/index.bundle?platform=android&dev=true&minify=false:2363:31
__guard#http://localhost:8081/index.bundle?platform=android&dev=true&minify=false:2604:15
callFunctionReturnFlushedQueue#http://localhost:8081/index.bundle?platform=android&dev=true&minify=false:2362:21
callFunctionReturnFlushedQueue#[native code]
Is anyone familiar with uploading images to firebase? in the tutorial they use uuid but for some reason the app breaks when I try to use this, so I left it out. this is the corresponding code:
import React, {Component} from 'react';
import {Platform, StyleSheet, Text, View, Image, Button, ScrollView, ImageBackground, Dimensions,TouchableOpacity, FlatList,
AsyncStorage} from 'react-native';
import { Avatar, ListItem } from 'react-native-elements';
import Icon from 'react-native-vector-icons/FontAwesome';
import ImagePicker from 'react-native-image-picker';
import firebase from 'react-native-firebase';
const SCREEN_WIDTH = Dimensions.get("window").width;
const list = [
{
title: '',
icon: 'cake',
url: 'ProfileSettings',
},
]
const options = {
title: 'Select Image',
storageOptions: {
skipBackup: true,
path: 'images'
}
};
const ImageRow = ({ image, windowWidth, popImage }) => (
<View>
<Image
source={{ uri: image }}
style={[styles.img, { width: windowWidth / 2 - 15 }]}
onError={popImage}
/>
</View>
);
class profileScreen extends Component {
constructor(props){
super(props);
this.state = {
first: '',
place: '',
province: '',
uid: '',
profileImg: '',
email: '',
imgSource: '',
uploading: false,
progress: 0,
images: []
}
}
getUserData = (user) => {
console.log(user);
let ref = firebase.database().ref('Users/' + user);
ref.on('value' , snapshot =>{
var state = snapshot.val();
this.setState({
first: state.firstname,
place: state.place,
province: state.province,
uid: user,
profileImg: state.profileImg,
birthday: state.birthday,
email: state.email,
year: state.registered.split("-",1)
})
})
}
componentDidMount(){
let user = firebase.auth().currentUser;
console.log(user);
console.log('test');
this.getUserData(user.uid);
let images;
AsyncStorage.getItem('images')
.then(data => {
images = JSON.parse(data) || [];
this.setState({
images: images
});
})
.catch(error => {
console.log(error);
});
}
/**
* Select image method
*/
pickImage = () => {
ImagePicker.showImagePicker(options, response => {
if (response.didCancel) {
console.log('You cancelled image picker 😟');
} else if (response.error) {
alert('And error occured: ', response.error);
} else {
const source = { uri: response.uri };
this.setState({
imgSource: source,
imageUri: response.uri
});
console.log(source);
}
});
};
/**
* Upload image method
*/
uploadImage = () => {
const ext = this.state.imageUri.split('.').pop(); // Extract image extension
const filename = `unique image' + ${ext}`; // Generate unique name
const imageRef = firebase.storage().ref('tutorials/images').child(filename +ext);
let mime = 'image/jpg';
imageRef.put(this.state.imageUri, { contentType: mime }).then((snapshot)=>{
console.log('Image uploaded successfully.')
}).catch((error)=>{
console.log('Image uploading failed:' + error);
});
};
/**
* Remove image from the state and persistance storage
*/
removeImage = imageIndex => {
let images = this.state.images;
images.pop(imageIndex);
this.setState({ images });
AsyncStorage.setItem('images', JSON.stringify(images));
};
render() {
const { uploading, imgSource, progress, images } = this.state;
const windowWidth = Dimensions.get('window').width;
const disabledStyle = uploading ? styles.disabledBtn : {};
const actionBtnStyles = [styles.btn, disabledStyle];
return (
<ScrollView style={styles.scorllVert}>
<View style={{ alignItems: 'flex-start', justifyContent: 'center', marginBottom: 40 }}>
<View style={styles.intro}>
<Text style={styles.introText}>Hoi, ik ben {this.state.first}{"\n"}<Text style={styles.introTextSpan}>Lid geworden in {this.state.year}</Text></Text>
{ this.state.profileImg ?
<Avatar size="large" rounded source={{uri: this.state.profileImg,}} onPress={() => console.log("Works!")} activeOpacity={0.7} />
:
<Avatar size="large" rounded title="GLR" onPress={() => console.log("Works!")} activeOpacity={0.7} />
}
</View>
<View style={styles.divider}>
</View>
<View style={styles.about}>
<Text style={styles.profileName}>Over</Text>
<View style={styles.aboutLiving}>
<Icon name='home' style={styles.icon}/>
<Text style={styles.aboutText}>Woont in {this.state.place}, {this.state.province}</Text>
</View>
</View>
<View style={styles.divider}>
</View>
<View style={styles.about}>
<Text style={styles.profileName}>Door {this.state.first} versterkt</Text>
<View style={styles.aboutLiving}>
<Icon name='check-circle' style={[styles.icon, styles.iconGreen]}/>
<Text style={styles.aboutText}>E-mail adres</Text>
</View>
</View>
<View style={styles.divider}>
</View>
<View style={styles.about}>
<Text style={styles.profileName}>Recente activiteiten</Text>
<Text >N.v.t.</Text>
<TouchableOpacity
style={actionBtnStyles}
onPress={this.pickImage}
disabled={uploading}
>
<View>
<Text style={styles.btnTxt}>Pick image</Text>
</View>
</TouchableOpacity>
{imgSource !== '' && (
<View>
<Image source={imgSource} style={styles.image} />
{uploading && (
<View
style={[styles.progressBar, { width: `${progress}%` }]}
/>
)}
<TouchableOpacity
style={actionBtnStyles}
onPress={this.uploadImage}
disabled={uploading}
>
<View>
{uploading ? (
<Text style={styles.btnTxt}>Uploading ...</Text>
) : (
<Text style={styles.btnTxt}>Upload image</Text>
)}
</View>
</TouchableOpacity>
</View>
)}
<View>
<Text
style={{
fontWeight: '600',
paddingTop: 20,
alignSelf: 'center'
}}
>
{images.length > 0
? 'Your uploaded images'
: 'There is no image you uploaded'}
</Text>
</View>
<FlatList
numColumns={2}
style={{ marginTop: 20 }}
data={images}
renderItem={({ item: image, index }) => (
<ImageRow
windowWidth={windowWidth}
image={image}
popImage={() => this.removeImage(index)}
/>
)}
keyExtractor={index => index}
/>
</View>
</View>
</ScrollView>
);
}
}
const styles = StyleSheet.create({
profileName:{
fontWeight: 'bold',
fontSize: 22,
marginTop: 20,
},
list:{
marginTop: 40,
width: '100%'
},intro:{
flex: 1,
flexDirection: 'row',
flexWrap: 'wrap',
alignItems: 'flex-start',
padding: 25,
marginBottom: 30,
paddingTop: 80,
},
introText:{
marginLeft: 0,
marginRight: 50,
fontSize: 22,
fontWeight: "700",
marginTop:15,
},
introTextSpan:{
marginLeft: 0,
marginRight: 40,
fontSize: 15,
fontWeight: "200",
marginTop:50,
},
divider:{
width: SCREEN_WIDTH-50,
padding: 10,
borderBottomColor: 'grey',
borderBottomWidth: 0.5,
marginTop: 10,
marginLeft: 25
},
about:{
paddingLeft: 25,
},
aboutLiving:{
flexDirection: 'row',
flexWrap: 'wrap',
alignItems: 'flex-start',
paddingTop: 10
},
icon:{
fontSize: 18
},
aboutText:{
marginLeft: 30
},
iconGreen:{
color: 'green'
}
,
button: {
marginTop: 30,
marginBottom: 20,
paddingVertical: 10,
alignItems: 'center',
backgroundColor: '#019BB4',
width: 300
},
buttonText: {
fontSize: 20,
fontWeight: 'bold',
color: '#fff'
},
scorllVert:{
marginBottom: 40
},
btn: {
paddingLeft: 20,
paddingRight: 20,
paddingTop: 10,
paddingBottom: 10,
borderRadius: 20,
backgroundColor: 'rgb(3, 154, 229)',
marginTop: 20,
alignItems: 'center'
},
disabledBtn: {
backgroundColor: 'rgba(3,155,229,0.5)'
},
btnTxt: {
color: '#fff'
},
image: {
marginTop: 20,
minWidth: 200,
height: 200,
resizeMode: 'contain',
backgroundColor: '#ccc',
},
img: {
flex: 1,
height: 100,
margin: 5,
resizeMode: 'contain',
borderWidth: 1,
borderColor: '#eee',
backgroundColor: '#ccc'
},
progressBar: {
backgroundColor: 'rgb(3, 154, 229)',
height: 3,
shadowColor: '#000',
}
})
export default profileScreen;
I am fairly new to react native and would like to upload images, is there anyone who can help me get this done? Even if there are other methods, I am open to that!

Try wrapping your uploadImage function in a try..catch and see if you can get a clearer error message in catch

Try this code for uploading the image,
const ext = this.state.imageUri.split('.').pop(); // Extract image extension
const filename = `unique image' + ${ext}`; // Generate unique name
const imageRef = firebase.storage().ref('tutorials/images).child(filename +ext);
let mime = 'image/jpg';
imageRef.put(this.state.imageUri, { contentType: mime }).then((snapshot)=>{
console.log('Image uploaded successfully.')
}).catch((error)=>{
console.log('Image uploading failed');
});

Related

how to validate DateTimePickerModal with yup and formik in React native?

Here is my screen component with two textinputs from the link. I have removed some other code that isn't necessary to this issue.
When i choose the date from the popup it appears in the text input but doesnt get validated.
I cannot use the result of DatePicker component as it is , so i am doing some formating and saved to a function getDate.
How would you go about implemnting this ? is there any better way
enter image description here
import React, { useState, useContext, useEffect } from 'react';
import {
StyleSheet,
View,
Text,
TextInput,
TouchableOpacity,
ScrollView,
KeyboardAvoidingView,
Platform,
Image,
} from 'react-native';
import { icons, COLORS, } from '../constants';
import { Formik } from 'formik';
import * as yup from "yup";
import client from '../api/client';
import DateTimePickerModal from "react-native-modal-datetime-picker";
const addfarm = ({ navigation, Arrival_Date }) => {
const addFarmValidationSchema = yup.object().shape({
Farm_Code: yup.string().required('Please Enter the chick price'),
Arrival_Date: yup.string().required('Please Choose a date'),
});
const [isDatePickerVisible, setDatePickerVisibility] = useState(false);
const [date, setDate] = useState('');
const showDatePicker = () => {
setDatePickerVisibility(true);
};
const hideDatePicker = () => {
setDatePickerVisibility(false);
};
const handleConfirm = (date) => {
hideDatePicker();
setDate(date);
};
const getDate = () => {
let tempDate = JSON.stringify(date).split(/[ ",T,]/);
return date !== ''
? `${tempDate[1]}`
: '';
};
const newDate = getDate();
const addFarmInfo = {
Farm_Code: '',
Arrival_Date: '',
};
const add = async (values) => {
const res = await client({
method: 'POST',
url: '/Farm/SaveFarm',
data: JSON.stringify({ ...values, id })
})
.then(res => console.log(res.data))
.catch(err => console.log(err))
}
return (
<KeyboardAvoidingView
behavior={Platform.OS === 'ios' ? 'padding' : null}
style={{ flex: 1 }}>
<ScrollView style={styles.container}>
<Formik
initialValues={addFarmInfo}
validateOnMount={true}
onSubmit={add}
validationSchema={addFarmValidationSchema}>
{({
handleChange,
handleBlur,
handleSubmit,
values,
touched,
errors,
isValid,
setFieldValue,
}) => {
const {
Farm_Code,
Arrival_Date,
} = values
return (
<View
style={{
paddingHorizontal: '10%',
paddingTop: 50,
marginTop: 50,
backgroundColor: COLORS.main_background,
}}>
<Text style={styles.auth_text}>Add Farm</Text>
<Text style={styles.tag}>
Farm Code:
</Text>
<View
style={[styles.textInputView, { marginBottom: 10 }]}>
<TextInput
onChangeText={handleChange('Farm_Code')}
onBlur={handleBlur('Farm_Code')}
value={Farm_Code}
placeholder="Farm Code"
placeholderTextColor={COLORS.placeholder_fonts}
selectionColor={COLORS.drawer_button}
style={styles.textInput}
/>
<Image
source={!errors.Farm_Code ? icons.tick : icons.close}
resizeMode="stretch"
style={{
width: 18,
height: 18,
tintColor: !errors.Farm_Code ? COLORS.drawer_button : 'red',
alignItems: 'center',
marginRight: 10,
}}
/>
</View>
{(errors.Farm_Code && touched.Farm_Code) &&
<Text style={styles.errors}>{errors.Farm_Code}</Text>
}
<Text style={styles.tag}>
Arrival Date:
</Text>
<View
style={[styles.textInputView, { marginBottom: 10 }]}>
<TextInput
onChangeText={handleChange('Arrival_Date')}
onBlur={handleBlur('Arrival_Date')}
value={newDate}
onFocus={showDatePicker}
placeholder="yyyy/mm/dd"
placeholderTextColor={COLORS.placeholder_fonts}
selectionColor={COLORS.drawer_button}
style={styles.textInput}
/>
<TouchableOpacity style={{ marginRight: 10, }}
onPress={showDatePicker}
>
<DateTimePickerModal
isVisible={isDatePickerVisible}
mode="date"
onConfirm={handleConfirm}
onCancel={hideDatePicker}
/>
<Image
source={icons.calendar}
resizeMode="stretch"
style={{
width: 18,
height: 18,
tintColor: COLORS.secondary_fonts,
alignItems: 'center'
}}
/>
</TouchableOpacity>
<Image
source={!errors.Arrival_Date ? icons.tick : icons.close}
resizeMode="stretch"
style={{
width: 18,
height: 18,
tintColor: !errors.Arrival_Date ? COLORS.drawer_button : 'red',
alignItems: 'center',
marginRight: 10,
}}
/>
</View>
{(errors.Arrival_Date && touched.Arrival_Date) &&
<Text style={styles.errors}>{errors.Arrival_Date}</Text>
}
{(errors.Arrival_Date && touched.Arrival_Date) &&
<Text style={styles.errors}>{errors.Arrival_Date}</Text>
}
{/* Save */}
<TouchableOpacity
disabled={!isValid}
onPress={handleSubmit}
style={[styles.button, { backgroundColor: isValid ? COLORS.authButtons : COLORS.placeholder_fonts, marginTop: 10 }]}>
<Text style={styles.button_Text}>Save</Text>
</TouchableOpacity>
</View>
)
}
}
</Formik >
</ScrollView>
</KeyboardAvoidingView>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: COLORS.main_background,
},
textInput: {
flex: 1,
paddingLeft: 10,
color: 'black',
},
auth_text: {
fontSize: 20,
fontWeight: 'bold',
textAlign: 'center',
marginBottom: 5,
},
button: {
height: 50,
width: '100%',
marginVertical: 20,
borderRadius: 10,
alignItems: 'center',
justifyContent: 'center',
},
button_Text: {
fontSize: 18,
color: COLORS.white,
},
login_nav: {
fontSize: 12,
textAlign: 'center',
fontWeight: '400',
marginTop: 10,
},
errors: {
fontSize: 14,
color: 'red',
fontWeight: '400',
marginTop: 5,
},
textInputView: {
flex: 1,
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
borderWidth: 1,
borderRadius: 10,
height: 50,
width: '100%',
borderColor: COLORS.secondary_fonts,
},
tag: {
color: 'black',
fontSize: 15,
marginBottom: 4,
marginLeft: 4
},
});
export default addfarm;
If you want formik to handle the validation, you should call the setFieldValue method and it will trigger the validation as the documentation says

How to get the value from Async Storage getData function?

I want to store username to local storage using #react-native-async-storage/async-storage in React Native. When I checked through console.log, username was saved successfully but while retrieving the data back to different screen using getData function, It says null. Help me to figure out the issue.
this is my storage.js file where I've kept all the Async Storage functions.
import AsyncStorage from '#react-native-async-storage/async-storage';
const storeData = async (key, value) => {
try {
await AsyncStorage.setItem(key, value)
} catch (e) {
console.log('Error on saving')
}
}
const getData = async (key) => {
try {
const value = await AsyncStorage.getItem(key)
if (value !== null) {
console.log('Promise', value)
return value
}
} catch (e) {
// error reading value
}
}
export { storeData, getData };
this is my Log In Screen file
import React, { Component, useState } from 'react';
import { View, Text, Button, ScrollView, TextInput, TouchableHighlight, StyleSheet } from 'react-native';
import * as yup from 'yup'
import { Formik } from 'formik'
import { storeData } from '../utils/storage';
const Login = (props) => {
const handleLogin = (name) => {
storeData('username',name)
props.navigation.navigate('Home')
}
return (
<Formik
initialValues={{
name: '',
password: ''
}}
onSubmit={values => Alert.alert(JSON.stringify(values))}
validationSchema={yup.object().shape({
name: yup
.string()
.required('Please, provide your name!'),
password: yup
.string()
.min(4)
.max(10, 'Password should not excced 10 chars.')
.required(),
})}
>
{({ values, handleChange, errors, setFieldTouched, touched, isValid, handleSubmit }) => (
<ScrollView style={styles.scrollb}>
<View style={styles.container}>
<Text style={styles.title}>LOGIN PAGE</Text>
<Text style={styles.subtitle}>Welcome Back.</Text>
</View>
<View style={styles.container2}>
<TextInput
style={styles.tinput}
placeholder="Username"
value={values.name}
onChangeText={handleChange('name')}
onBlur={() => setFieldTouched('name')}
/>
{touched.name && errors.name &&
<Text style={{ fontSize: 12, color: '#FF0D10' }}>{errors.name}</Text>
}
</View>
<View style={styles.container2}>
<TextInput
style={styles.tinput}
placeholder="Password"
value={values.password}
onChangeText={handleChange('password')}
placeholder="Password"
onBlur={() => setFieldTouched('password')}
secureTextEntry={true}
/>
{touched.password && errors.password &&
<Text style={{ fontSize: 12, color: '#FF0D10' }}>{errors.password}</Text>
}
</View>
<View style={styles.container3}>
<TouchableHighlight
style={{
borderRadius: 10,
}}>
<Button
title="Login"
borderRadius={25}
containerViewStyle={{ borderRadius: 25 }}
buttonStyle={{ width: 145, height: 45, borderRadius: 25 }}
accessibilityLabel="Learn more about this button"
onPress={() => handleLogin(values.name)}
disabled={!isValid}
/>
</TouchableHighlight>
</View>
</ScrollView>
)}
</Formik>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
padding: 24,
backgroundColor: "#61dafb",
},
container2: {
flex: 1,
paddingTop: 14,
paddingHorizontal: 24,
backgroundColor: "#61dafb",
},
container3: {
flex: 1,
paddingTop: 284,
paddingHorizontal: 34,
backgroundColor: "#61dafb",
borderRadius: 40,
},
title: {
marginTop: 16,
borderRadius: 6,
backgroundColor: "#61dafb",
color: "white",
textAlign: "center",
fontSize: 50,
fontWeight: "bold",
},
subtitle: {
borderRadius: 6,
paddingLeft: 33,
backgroundColor: "#61dafb",
color: "white",
textAlign: "left",
fontSize: 30,
fontWeight: '400',
},
tinput: {
height: 50,
textAlign: "center",
paddingVertical: 8,
backgroundColor: "white",
borderRadius: 27,
},
scrollb: {
backgroundColor: "#61dafb",
},
});
export default Login;
This is my Home screen file. Where I want to retrieve that username from Login Page via async storage.
import React, { Component, useEffect, useState } from 'react';
import { View, Text, ScrollView, TouchableHighlight, Image, StyleSheet } from 'react-native';
import { getData } from '../utils/storage';
const Home = (props) => {
const [username, setUsername] = useState('');
useEffect(() => {
getData('username')
console.log('useEffect',getData('username'))
}, [])
const CategoriesAr = [
{
name: "Business",
path: "Business",
imgURL: "https://img.icons8.com/clouds/100/000000/analytics.png",
},
{
name: "Technology",
path: "Technology",
imgURL: "https://img.icons8.com/clouds/100/000000/transaction-list.png",
},
{
name: "Science",
path: "Science",
imgURL: "https://img.icons8.com/clouds/100/000000/innovation.png",
},
{
name: "Health",
path: "Health",
imgURL: "https://img.icons8.com/clouds/100/000000/client-company.png",
}
]
const GridItem = (gridProps) => {
const { data } = gridProps;
return (
<>
<TouchableHighlight onPress={() => props.navigation.navigate(data.path)}>
<View style={styles.card}>
<View style={styles.header}>
<Text style={{ fontWeight: "bold", fontSize: 18 }}>{data.name}</Text>
</View>
<View style={styles.imgbody}>
<Image
style={styles.tinyLogo}
source={{
uri: data.imgURL,
}}
/>
</View>
</View>
</TouchableHighlight>
</>
)
}
return (
<ScrollView style={styles.sclb}>
<Text style={styles.title}>Hi {username}</Text>
<View style={styles.containerX}>
{CategoriesAr.map((item) => <GridItem data={item} />)}
</View>
</ScrollView>
);
}
const styles = StyleSheet.create({
title: {
marginTop: 16,
borderRadius: 6,
backgroundColor: "#61dafb",
color: "white",
textAlign: "center",
fontSize: 50,
fontWeight: "bold",
},
containerX: {
flex: 1,
flexWrap: "wrap",
marginTop: 8,
maxHeight: 400,
backgroundColor: "#61dafb",
},
card: {
height: 150,
width: 150,
backgroundColor: "white",
alignItems: "center",
borderRadius: 15,
elevation: 10,
padding: 10,
margin: 22,
},
imgbody: {
paddingTop: 20,
},
tinyLogo: {
height: 90,
width: 90,
},
header: {
flexDirection: "row",
},
sclb: {
backgroundColor: "#61dafb",
}
});
export default Home;
You need to put await before getData like this.
useEffect(() => {
(async()=>{
await getData('username')
console.log('useEffect',await getData('username'))
})();
}, [])
useEffect(() => {
CallMethod()
}, [])
const CallMethod = async() =>{
await getData('username')
}

add current time with text input

enter image description here Iam new with react native,so maybe my question seems silly to all excepts.I want to add current time in text input.(i designd todo app,that show the todo list,now i want to show time in todo list,for eg i enter todo(complete frontend)and add,that contain complete and delete button,now i want to add time in that(task adding time).my code are following below,
import React from 'react';
import {
StyleSheet,
SafeAreaView,
View,
TextInput,
Text,
FlatList,
TouchableOpacity,
Alert,
} from 'react-native';
import Icon from 'react-native-vector-icons/MaterialIcons';
import AsyncStorage from '#react-native-async-storage/async-storage';
const COLORS = {primary: '#1f145c', white: '#fff'};
const App = () => {
const \[todos, setTodos\] = React.useState(\[\]);
const \[textInput, setTextInput\] = React.useState('');
React.useEffect(() => {
getTodosFromUserDevice();
}, \[\]);
React.useEffect(() => {
saveTodoToUserDevice(todos);
}, \[todos\]);
const addTodo = () => {
if (textInput == '') {
Alert.alert('Error', 'Please input todo');
} else {
const newTodo = {
id: Math.random(),
task: textInput,
completed: false,
};
setTodos(\[...todos, newTodo\]);
setTextInput('');
}
};
const saveTodoToUserDevice = async todos => {
try {
const stringifyTodos = JSON.stringify(todos);
await AsyncStorage.setItem('todos', stringifyTodos);
} catch (error) {
console.log(error);
}
};
const getTodosFromUserDevice = async () => {
try {
const todos = await AsyncStorage.getItem('todos');
if (todos != null) {
setTodos(JSON.parse(todos));
}
} catch (error) {
console.log(error);
}
};
const markTodoComplete = todoId => {
const newTodosItem = todos.map(item => {
if (item.id == todoId) {
return {...item, completed: true};
}
return item;
});
setTodos(newTodosItem);
};
const deleteTodo = todoId => {
const newTodosItem = todos.filter(item => item.id != todoId);
setTodos(newTodosItem);
};
const clearAllTodos = () => {
Alert.alert('Confirm', 'Clear todos?', \[
{
text: 'Yes',
onPress: () => setTodos(\[\]),
},
{
text: 'No',
},
\]);
};
const ListItem = ({todo}) => {
return (
<View style={styles.listItem}>
<View style={{flex: 1}}>
<Text
style={{
fontWeight: 'bold',
fontSize: 20,
color: COLORS.primary,
textDecorationLine: todo?.completed ? 'line-through' : 'none',
}}>
{todo?.task}
</Text>
</View>
{!todo?.completed && (
<TouchableOpacity onPress={() => markTodoComplete(todo.id)}>
<View style={\[styles.actionIcon, {backgroundColor: 'green'}\]}>
<Icon name="done" size={20} color="white" />
</View>
</TouchableOpacity>
)}
<TouchableOpacity onPress={() => deleteTodo(todo.id)}>
<View style={styles.actionIcon}>
<Icon name="delete" size={20} color="white" />
</View>
</TouchableOpacity>
</View>
);
};
return (
<SafeAreaView
style={{
flex: 1,
backgroundColor: 'white',
}}>
<View style={styles.header}>
<Text
style={{
fontWeight: 'bold',
fontSize: 20,
color: COLORS.primary,
}}>
TODO APP
</Text>
<Icon name="delete" size={25} color="red" onPress={clearAllTodos} />
</View>
<FlatList
showsVerticalScrollIndicator={false}
contentContainerStyle={{padding: 20, paddingBottom: 100}}
data={todos}
renderItem={({item}) => <ListItem todo={item} />}
/>
<View style={styles.footer}>
<View style={styles.inputContainer}>
<TextInput
value={textInput}
placeholder="Add Todo"
onChangeText={text => setTextInput(text)}
/>
</View>
<TouchableOpacity onPress={addTodo}>
<View style={styles.iconContainer}>
<Icon name="add" color="white" size={30} />
</View>
</TouchableOpacity>
</View>
</SafeAreaView>
);
};
const styles = StyleSheet.create({
footer: {
position: 'absolute',
bottom: 0,
width: '100%',
flexDirection: 'row',
alignItems: 'center',
paddingHorizontal: 20,
backgroundColor: COLORS.white,
},
inputContainer: {
height: 50,
paddingHorizontal: 20,
elevation: 40,
backgroundColor: COLORS.white,
flex: 1,
marginVertical: 20,
marginRight: 20,
borderRadius: 30,
},
iconContainer: {
height: 50,
width: 50,
backgroundColor: COLORS.primary,
elevation: 40,
borderRadius: 25,
justifyContent: 'center',
alignItems: 'center',
},
listItem: {
padding: 20,
backgroundColor: COLORS.white,
flexDirection: 'row',
elevation: 12,
borderRadius: 7,
marginVertical: 10,
},
actionIcon: {
height: 25,
width: 25,
backgroundColor: COLORS.white,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'red',
marginLeft: 5,
borderRadius: 3,
},
header: {
padding: 20,
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
},
});
export default App;][1]
i got the answer ,answer is following below,
import React from 'react';
import {
StyleSheet,
SafeAreaView,
View,
TextInput,
Text,
FlatList,
TouchableOpacity,
Alert,
} from 'react-native';
import Icon from 'react-native-vector-icons/MaterialIcons';
import AsyncStorage from '#react-native-async-storage/async-storage';
const COLORS = {primary: '#1f145c', white: '#fff'};
const App = () => {
const [todos, setTodos] = React.useState([]);
const [textInput, setTextInput] = React.useState('');
React.useEffect(() => {
getTodosFromUserDevice();
}, []);
React.useEffect(() => {
saveTodoToUserDevice(todos);
}, [todos]);
const addTodo = () => {
if (textInput == '') {
Alert.alert('Error', 'Please input todo');
} else {
const newTodo = {
id: Math.random(),
task: textInput,
completed: false,
time: getCurrentTime()
};
setTodos([...todos, newTodo]);
setTextInput('');
}
};
const saveTodoToUserDevice = async todos => {
try {
const stringifyTodos = JSON.stringify(todos);
await AsyncStorage.setItem('todos', stringifyTodos);
} catch (error) {
console.log(error);
}
};
const getTodosFromUserDevice = async () => {
try {
const todos = await AsyncStorage.getItem('todos');
if (todos != null) {
setTodos(JSON.parse(todos));
}
} catch (error) {
console.log(error);
}
};
***const getCurrentTime = () => {
let today = new Date();
let date = today.getFullYear()+'-'+(today.getMonth()+1)+'-'+today.getDate();
let time = today.getHours() + ":" + today.getMinutes() + ":" + today.getSeconds();
let dateTime = date + '/' + time;
return dateTime;
}***
const markTodoComplete = todoId => {
const newTodosItem = todos.map(item => {
if (item.id == todoId) {
return {...item, completed: true};
}
return item;
});
setTodos(newTodosItem);
};
const deleteTodo = todoId => {
const newTodosItem = todos.filter(item => item.id != todoId);
setTodos(newTodosItem);
};
const clearAllTodos = () => {
Alert.alert('Confirm', 'Clear todos?', [
{
text: 'Yes',
onPress: () => setTodos([]),
},
{
text: 'No',
},
]);
};
const comdel = () => {
Alert.alert('select status', 'Complete or Delete', [
{
text: 'Delete',
onPress: () => setTodos([]),
},
{
text: 'Complete',
onPress: () => {markTodoComplete(todo.id)}
},
]);
};
const ListItem = ({todo}) => {
return (
<View style={styles.listItem}>
<View style={{flex: 1}}>
<Text
style={{
fontWeight: 'bold',
fontSize: 20,
color: COLORS.primary,
textDecorationLine: todo?.completed ? 'line-through' : 'none',
}}>
{todo?.task}
</Text>
</View>
{/* {!todo?.completed && (
<TouchableOpacity onPress={() => markTodoComplete(todo.id)}>
<View style={[styles.actionIcon, {backgroundColor: 'green'}]}>
<Icon name="done" size={20} color="white" />
</View>
</TouchableOpacity>
)} */}
{/* <TouchableOpacity onPress={() => deleteTodo(todo.id)}>
<View style={styles.actionIcon}>
<Icon name="delete" size={20} color="white" />
</View>
</TouchableOpacity> */}
<View>
<Text>
{todo?.time}
</Text>
</View>
<Icon name="menu" size={40} color="#a9a9a9" onPress={comdel} />
</View>
);
};
return (
<SafeAreaView
style={{
flex: 1,
backgroundColor: 'white',
}}>
<View style={styles.header}>
<Text
style={{
fontWeight: 'bold',
fontSize: 20,
color: COLORS.primary,
}}>
TODO APP
</Text>
<Icon name="delete" size={25} color="red" onPress={comdel} />
</View>
<FlatList
showsVerticalScrollIndicator={false}
contentContainerStyle={{padding: 20, paddingBottom: 100}}
data={todos}
renderItem={({item}) => <ListItem todo={item} />}
/>
<View style={styles.footer}>
<View style={styles.inputContainer}>
<TextInput
value={textInput}
placeholder="Add Todo"
onChangeText={text => setTextInput(text)}
/>
</View>
<TouchableOpacity onPress={addTodo}>
<View style={styles.iconContainer}>
<Icon name="add" color="white" size={30} />
</View>
</TouchableOpacity>
</View>
</SafeAreaView>
);
};
const styles = StyleSheet.create({
footer: {
position: 'absolute',
bottom: 0,
width: '100%',
flexDirection: 'row',
alignItems: 'center',
paddingHorizontal: 20,
backgroundColor: COLORS.white,
},
inputContainer: {
height: 50,
paddingHorizontal: 20,
elevation: 40,
backgroundColor: COLORS.white,
flex: 1,
marginVertical: 20,
marginRight: 20,
borderRadius: 30,
},
iconContainer: {
height: 50,
width: 50,
backgroundColor: COLORS.primary,
elevation: 40,
borderRadius: 25,
justifyContent: 'center',
alignItems: 'center',
},
listItem: {
padding: 40,
backgroundColor: "#d3d3d3",
flexDirection: 'column',
elevation: 12,
borderRadius: 7,
marginVertical: 10,
},
actionIcon: {
height: 25,
width: 25,
backgroundColor: COLORS.white,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'red',
marginLeft: 5,
borderRadius: 3,
},
header: {
padding: 20,
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
},
});
export default App;

How to make background black of react native camera?

Problem:
I have created react native camera but it is looked like this.
But the problem is the background color of camera action icons are transparent.
This is my code.
import React, {useState, useEffect} from 'react';
import {
AppRegistry,
StyleSheet,
TouchableOpacity,
View,
Image,
CameraRoll,
Platform,
} from 'react-native';
import IoniconsIcon from 'react-native-vector-icons/Ionicons';
import EntypoIcon from 'react-native-vector-icons/Entypo';
import AppText from '_components/appText';
import {RNCamera} from 'react-native-camera';
import normalize from '_utils/fontsize';
let countRecordTime;
const PendingView = () => (
<View
style={{
flex: 1,
backgroundColor: 'lightgreen',
justifyContent: 'center',
alignItems: 'center',
}}>
<AppText>Waiting</AppText>
</View>
);
const takePicture = async (camera) => {
const options = {quality: 1};
const data = await camera.takePictureAsync(options);
console.log(data.uri);
};
const recordVideo = async (
camera,
recording,
seconds,
setRecording,
setSeconds,
) => {
if (camera) {
if (!recording) {
startRecording(recording, setRecording, seconds, setSeconds, camera);
} else {
stopRecording(camera, setSeconds);
}
}
};
const startRecording = async (
recording,
setRecording,
seconds,
setSeconds,
camera,
) => {
setRecording(true);
console.log('>>>>>> start recording seconds', seconds);
const cameraConfig = {maxDuration: 20};
const data = await camera.recordAsync(cameraConfig);
console.log('>>>>>> data', data);
setRecording(false);
};
const stopRecording = (camera, setSeconds) => {
camera.stopRecording();
setSeconds(0);
};
const secondsToMMSS = (seconds) => {
console.log('>>>>>> seconds', seconds);
let m = Math.floor(seconds / 60);
let s = Math.floor(seconds % 60);
let mDisplay = m < 10 ? `0${m}` : `${m}`;
let sDisplay = s < 10 ? `0${s}` : `${s}`;
return `${mDisplay}:${sDisplay}`;
};
const VideoRecording = (props) => {
const [type, setType] = useState(RNCamera.Constants.Type.back);
const [flashMode, setFlashMode] = useState(RNCamera.Constants.FlashMode.off);
const [recording, setRecording] = useState(false);
const [seconds, setSeconds] = useState(0);
useEffect(() => {
if (recording) {
countRecordTime = setInterval(() => setSeconds(seconds + 1), 1000);
}
if (!recording && countRecordTime) {
clearInterval(countRecordTime);
}
if (seconds === 20 && countRecordTime) {
clearInterval(countRecordTime);
setRecording(false);
}
return () => {
if (countRecordTime) {
clearInterval(countRecordTime);
}
};
}, [recording, seconds]);
return (
<View style={styles.container}>
<RNCamera
style={styles.preview}
autoFocus={RNCamera.Constants.AutoFocus.on}
type={type}
flashMode={flashMode}
faceDetectionMode={RNCamera.Constants.FaceDetection.Mode.fast}
ratio="4:3"
whiteBalance={RNCamera.Constants.WhiteBalance.auto}
captureAudio={true}
androidCameraPermissionOptions={{
title: 'Permission to use camera',
message: 'We need your permission to use your camera',
buttonPositive: 'Ok',
buttonNegative: 'Cancel',
}}
androidRecordAudioPermissionOptions={{
title: 'Permission to use audio recording',
message: 'We need your permission to use your audio',
buttonPositive: 'Ok',
buttonNegative: 'Cancel',
}}>
{({camera, status, recordAudioPermissionStatus}) => {
if (status !== 'READY') {
return <PendingView />;
}
return (
<>
<View
style={{
flex: 0,
flexDirection: 'row',
justifyContent: 'center',
}}>
<TouchableOpacity
style={styles.capture}
onPress={(_) => {
switch (flashMode) {
case RNCamera.Constants.FlashMode.off:
setFlashMode(RNCamera.Constants.FlashMode.auto);
break;
case RNCamera.Constants.FlashMode.auto:
setFlashMode(RNCamera.Constants.FlashMode.on);
break;
case RNCamera.Constants.FlashMode.on:
setFlashMode(RNCamera.Constants.FlashMode.off);
break;
}
}}>
<Image
source={
flashMode === RNCamera.Constants.FlashMode.auto
? require('../../assets/img/flashAuto.png')
: flashMode === RNCamera.Constants.FlashMode.on
? require('../../assets/img/flashOn.png')
: require('../../assets/img/flashOff.png')
}
style={{width: 30, height: 30}}
resizeMode={'contain'}
/>
</TouchableOpacity>
{/* <TouchableOpacity
onPress={() => takePicture(camera)}
style={styles.capture}>
<Image
source={require('../../assets/img/cameraButton.png')}
style={{width: 50, height: 50}}
resizeMode={'contain'}
/>
</TouchableOpacity> */}
<TouchableOpacity
style={styles.iconContainer}
onPress={() =>
recordVideo(
camera,
recording,
seconds,
setRecording,
setSeconds,
)
}>
<EntypoIcon
style={styles.icon}
size={40}
color={recording ? 'red' : 'white'}
name="video-camera"
/>
{recording ? (
<AppText styles={styles.recordingTime}>
{secondsToMMSS(seconds)}
</AppText>
) : null}
</TouchableOpacity>
<TouchableOpacity
style={styles.capture}
onPress={(_) => {
if (type === RNCamera.Constants.Type.back) {
setType(RNCamera.Constants.Type.front);
} else {
setType(RNCamera.Constants.Type.back);
}
}}>
<Image
source={require('../../assets/img/cameraFlipIcon.png')}
style={{width: 40, height: 40}}
resizeMode={'contain'}
/>
</TouchableOpacity>
</View>
<TouchableOpacity style={styles.closeButton} onPress={() => {}}>
<IoniconsIcon
name={'ios-close'}
style={styles.closeButtonIcon}
/>
</TouchableOpacity>
</>
);
}}
</RNCamera>
</View>
);
};
export default VideoRecording;
const styles = StyleSheet.create({
container: {
position: 'absolute',
left: 0,
right: 0,
top: 0,
bottom: 0,
},
preview: {
flex: 1,
justifyContent: 'flex-end',
alignItems: 'center',
backgroundColor: 'black',
},
capture: {
flex: 0,
borderRadius: 5,
padding: 15,
paddingHorizontal: 20,
alignSelf: 'center',
margin: 20,
},
cptureView: {
backgroundColor: '#ffffff',
width: 100,
height: 100,
borderRadius: 100,
alignItems: 'center',
justifyContent: 'center',
marginBottom: '20%',
marginTop: '5%',
},
camIcon: {
color: '#858181',
},
iconContainer: {
justifyContent: 'center',
alignItems: 'center',
},
icon: {
marginHorizontal: 15,
// paddingVertical: 10,
},
recordingTime: {
color: 'red',
},
closeButton: {
position: 'absolute',
backgroundColor: '#aaaaaab0',
width: 50,
height: 50,
borderRadius: 25,
justifyContent: 'center',
top: Platform.OS === 'ios' ? 45 : 10,
left: 10,
},
closeButtonIcon: {
fontSize: Platform.OS === 'ios' ? 40 : 40,
fontWeight: 'bold',
alignSelf: 'center',
lineHeight: Platform.OS === 'ios' ? 58 : 40,
},
});
Can someone help me to make it black? I tried a lot to find out way to do so that. But I could not so if someone can help me it would be grateful. Thank you very much.
Have you try this?
...
<View
style={{
flex: 0,
flexDirection: 'row',
justifyContent: 'center',
backgroundColor: "#000000", //-----------------Here?
}}>
<TouchableOpacity
style={styles.capture}
onPress={(_) => {
switch (flashMode) {
case RNCamera.Constants.FlashMode.off:
setFlashMode(RNCamera.Constants.FlashMode.auto);
...

How to draw an arrow on every polyline segment on react-native-maps

hi i want to draw an arrow every polyline
like this image :
read this post :
How to draw an arrow on every polyline segment on Google Maps V3
this is answer my question but this post for javascript
but i use it and this is my code:
<View style={{ height: hp('50%'), width: wp('100%') }}>
<MapView
provider={PROVIDER_GOOGLE}
onLayout={this.onMapLayout}
style={styles.containerMap}
initialRegion={{
latitude: this.props.data ? this.props.data[0].YPOINT : '',
longitude: this.props.data ? this.props.data[0].XPOINT : '',
latitudeDelta: 0.0922,
longitudeDelta: 0.0421,
}} >
{this.state.isMapReady && <Polyline
strokeWidth={2}
strokeColor="red"
geodesic={true}
icons={
icon = { path: google.maps.SymbolPath.FORWARD_CLOSED_ARROW },
offset = '100%'
}
coordinates={[...this.props.data.map((value, index) => {
return { latitude: value.YPOINT, longitude: value.XPOINT }
})]}
/>
}
</MapView>
</View>
but when run i get error 'google is not defined'.
UPDATE
this is function :
import React, { Component } from 'react'
import { Text, View, StyleSheet, ScrollView, AsyncStorage, ActivityIndicator, Alert, FlatList } from 'react-native'
import { widthPercentageToDP as wp, heightPercentageToDP as hp } from 'react-native-responsive-screen';
//import arrowIcon from '../../../assets/images/icon/Arrow/090.ico'
import SegmentedControlTab from "react-native-segmented-control-tab";
import { Dropdown } from 'react-native-material-dropdown';
import { getTraceOfHardware } from '../../../Store/actions';
import { connect } from 'react-redux';
import MapView, { Marker, PROVIDER_GOOGLE, Polyline } from 'react-native-maps';
import Icon from 'react-native-vector-icons/Entypo';
var moment = require('jalali-moment');
let dataDay = [{
value: 'امروز',
}, {
value: 'یک روز پیش',
}, {
value: 'دو روز پیش',
}, {
value: 'سه روز پیش',
}, {
value: 'چهار روز پیش',
}, {
value: 'پنج روز پیش',
}, {
value: 'شش روز پیش',
}, {
value: 'هفت روز پیش',
},];
const airplin = <Icon name="aircraft" size={30}/>
class mainRoutsReport extends Component {
constructor () {
super()
this.state = {
selectedIndex: 0,
selectedIndices: [0],
customStyleIndex: 0,
daySelected: '',
isMapReady: false,
tableHead: ['Head', 'Head2', 'Head3', 'Head4', 'Head5', 'Head6', 'Head7', 'Head8', 'Head9'],
widthArr: [40, 60, 80, 100, 120, 140, 160, 180, 200],
data: [],
latlon: []
// tableData: [
// ['1', '2', '3', '4', '5', '6'],
// ['1', '2', '3', '4', '5', '6']
// ]
}
}
//GET UDID
_retrieveUDID = async () => {
try {
return await AsyncStorage.getItem('#IranTracking:UDID', (error, result) => { return result })
} catch (error) {
// Error retrieving data
console.log(error)
}
};
//GET TOKEN
_retrieveToken = async () => {
try {
return await AsyncStorage.getItem('#IranTracking:Token', (error, result) => { return result })
} catch (error) {
// Error retrieving data
console.log(error)
}
};
//This method creat XML to send action.js to get List of Hardware from SOAP
async _makXML(value, index) {
udid = await this._retrieveUDID()
token = await this._retrieveToken()
var yesterday = moment().locale('fa').subtract(index + 0, 'day').format('YYYY-MM-DD')
// console.log(yesterday)
let xml = `<?xml version="1.0" encoding="utf-8"?>\
<x:Envelope xmlns:x="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tra="http://Trackinguri.org/">\
<x:Header>\
<tra:SOAPHeaderContent>\
<tra:UserName></tra:UserName>\
<tra:Password></tra:Password>\
<tra:Token>${token}</tra:Token>\
<tra:UID>${udid}</tra:UID>\
</tra:SOAPHeaderContent>\
</x:Header>\
<x:Body>\
<tra:GetTraceByHardwareID>\
<tra:HardwareID>${this.props.navigation.state.params.HID}</tra:HardwareID>\
<tra:FromDate>${yesterday} 00:00:00</tra:FromDate>\
<tra:ToDate>${yesterday} 23:59:59</tra:ToDate>\
<tra:HijriDates>true</tra:HijriDates>\
<tra:Time_Zone>Tehran</tra:Time_Zone>\
<tra:Lang>fa</tra:Lang>\
</tra:GetTraceByHardwareID>\
</x:Body>\
</x:Envelope>`;
console.log(" xml to get Tarce reports " + xml)
this.props.getTraceOfHardware(xml)
}
componentWillMount() {
this._makXML()
this.props.getTraceOfHardware()
}
componentDidMount() {
}
//this function use for day
_HandelDay(value, index) {
// var yesterday = moment().locale('fa').subtract(index,'day').format('YYYY-MM-DD')
//console.log('index of drop down is : ' + value + ' \nindex is : '+ index + '\n and date is : ' + yesterday)
//Alert.alert(yesterday)
}
handleMultipleIndexSelect = (index: number) => {
const { selectedIndices } = this.state
if (selectedIndices.includes(index)) {
this.setState(prevState => ({
...prevState,
selectedIndices: selectedIndices.filter((i) => i !== index),
}))
} else {
this.setState(prevState => ({
...prevState,
selectedIndices: [
...selectedIndices,
index,
],
}))
}
}
handleCustomIndexSelect = (index: number) => {
this.setState(prevState => ({ ...prevState, customStyleIndex: index }))
}
onMapLayout = () => {
this.setState({ isMapReady: true });
}
_renderItem = ({ item, index }) => (
// console.log(item)
<View style={{ flex: 1, height: hp('15%'), flexDirection: 'row', backgroundColor: index % 2 ? '#f3f3f3' : '#dedede', marginHorizontal: 5, alignItems: 'center' }} >
<View style={{ width: wp('15%'), alignItems: 'center', }}>
<Text style={{ marginLeft: 4, fontFamily: 'IRANSansMobile', }}>{item.TRUCKSTATE}</Text>
</View>
<View style={{ width: wp('12%'), alignItems: 'center' }}>
<Text style={{ marginLeft: 4, fontFamily: 'IRANSansMobile', }}>{item.SPEED}</Text>
</View>
<View style={{ width: wp('50%'), alignItems: 'center' }}>
<Text style={{ marginLeft: 4, fontFamily: 'IRANSansMobile', }}>{item.POSDESCRIPTION}</Text>
</View>
<View style={{ width: wp('10%'), alignItems: 'center' }}>
<Text style={{ marginLeft: 4, fontFamily: 'IRANSansMobile', }}>{item.SENTDATE}</Text>
</View>
<View style={{ width: wp('10%'), alignItems: 'center' }}>
<Text style={{ marginLeft: 4, fontFamily: 'IRANSansMobile', }}>{index + 1}</Text>
</View>
</View>
);
_renderHeadr = () => (
<View style={{ flexDirection: 'row', alignContent: 'space-between', alignItems: 'center', backgroundColor: '#5e9dcb' }}>
<View style={{ borderWidth: 0.5, width: wp('15%'), alignItems: 'center', borderTopLeftRadius: 5 }}>
<Text style={{ fontSize: 15, fontFamily: 'IRANSansMobile', }}>وضعیت</Text>
</View>
<View style={{ borderWidth: 0.5, width: wp('12%'), alignItems: 'center' }}>
<Text style={{ fontSize: 15, fontFamily: 'IRANSansMobile', }}>سرعت</Text>
</View>
<View style={{ borderWidth: 0.5, width: wp('50%'), alignItems: 'center' }}>
<Text style={{ fontSize: 15, fontFamily: 'IRANSansMobile', }}>موقعیت</Text>
</View>
<View style={{ borderWidth: 0.5, width: wp('10%'), alignItems: 'center' }}>
<Text style={{ fontSize: 15, fontFamily: 'IRANSansMobile', }}>زمان</Text>
</View>
<View style={{ borderWidth: 0.5, width: wp('10%'), alignItems: 'center', borderTopRightRadius: 5 }}>
<Text style={{ fontSize: 15, fontFamily: 'IRANSansMobile', }}>ردیف</Text>
</View>
</View>
);
render() {
const { customStyleIndex } = this.state
//console.log(this.props.navigation.state.params.HID)
//console.log(this.props.data)
return (
<View style={{ width: wp('100%'), height: hp('100%') }}>
<Dropdown animationDuration={100}
dropdownMargins={{ min: 0, max: 0 }}
dropdownOffset={{ top: 0, left: 0 }}
style={{ textAlign: 'center' }}
containerStyle={{ textAlign: 'right', backgroundColor: '#fcee97', borderWidth: 0.5, borderRadius: 13, margin: 8 }}
absoluteRTLLayout={true}
data={dataDay}
dropdownPosition={-5}
onChangeText={(value, index) => this._makXML(value, index)}
value={dataDay[0].value} />
<SegmentedControlTab
values={['نمایش متنی', 'نمایش نقشه']}
selectedIndex={customStyleIndex}
onTabPress={this.handleCustomIndexSelect}
borderRadius={0}
tabsContainerStyle={{ height: 50, backgroundColor: '#F2F2F2' }}
tabStyle={{ backgroundColor: '#ffffff', borderWidth: 0, borderColor: 'transparent' }}
activeTabStyle={{ backgroundColor: '#5e9dcb', marginTop: 2 }}
tabTextStyle={{ color: '#000000', fontWeight: 'bold', fontFamily: 'IRANSansMobile' }}
activeTabTextStyle={{ color: '#ffffff', fontFamily: 'IRANSansMobile' }}
/>
{//table
customStyleIndex === 0
&&
<View style={{ paddingBottom: wp('20%') }}>
{this.props.isLoading ? <ActivityIndicator /> : <FlatList
ListHeaderComponent={this._renderHeadr}
stickyHeaderIndices={[0]}
data={this.props.data}
renderItem={this._renderItem}//({item})=>(this._renderItem)
keyExtractor={(item, index) => index.toString()}
/>}
</View>
}
{//Map
customStyleIndex === 1
&&
<View style={{ height: hp('50%'), width: wp('100%') }}>
<MapView
provider={PROVIDER_GOOGLE}
onLayout={this.onMapLayout}
style={styles.containerMap}
initialRegion={{
latitude: this.props.data ? this.props.data[0].YPOINT : '',
longitude: this.props.data ? this.props.data[0].XPOINT : '',
latitudeDelta: 0.0922,
longitudeDelta: 0.0421,
}} >
{this.state.isMapReady &&
<Polyline
strokeWidth={2}
strokeColor="red"
geodesic={true}
icons={
icon = {airplin },
offset = '100%'
}
coordinates={[...this.props.data.map((value, index) => {
return { latitude: value.YPOINT, longitude: value.XPOINT }
})]}
/>
}
</MapView>
</View>
}
</View>
)
}
}
function mapStateToProps(state) {
console.log(state)
return {
data: state.GetTraceHardware.data,
isLoading: state.GetTraceHardware.isLoading,
error: state.GetTraceHardware.error
}
}
function mapDispatchToProps(dispatch) {
return {
getTraceOfHardware: (data) => dispatch(getTraceOfHardware(data))
}
}
export default connect(mapStateToProps, mapDispatchToProps)(mainRoutsReport);