React native create rectangle bottom, plus half rectangle is cut by circle - reactjs

Hello I am having task to create custom shape figure. On the bottom the shape of figure is rectangle and on half top of rectangle is cut by circle shape. Can anyone give me direction where to go from now?

import React, { Component } from 'react';
import { View } from 'react-native';
import { Icon} from 'react-native-elements'
class BottomNavigator extends Component {
render() {
return (
<View style={{
flex: 1,
flexDirection: 'column',
backgroundColor: '#f8f4f4'
}}>
<View style={{ position: 'absolute', alignSelf: 'center', backgroundColor: '#f8f4f4', width: 70, height: 70, borderRadius: 35, bottom: 25, zIndex: 10 }}>
<Icon
name='add'
type='material'
color='#f00'
containerStyle={{ alignSelf: 'center' }}
reverse
size={28}
onPress={() => {}}
/>
</View>
<View style={{ position: 'absolute', backgroundColor: '#2196F3', bottom: 0, zIndex: 1, width: '100%', height: 60, flexDirection: 'row', justifyContent: 'space-between', paddingHorizontal: 15, paddingVertical: 10 }}>
<Icon
name='menu'
type='material'
color='#fff'
onPress={() => {}}
/>
<View style={{ flexDirection: 'row', justifyContent: 'center' }}>
<Icon
name='favorite'
type='material'
color='#fff'
onPress={() => {}}
containerStyle={{ marginHorizontal: 16 }}
/>
<Icon
name='search'
type='material'
color='#fff'
/>
</View>
</View>
</View>
);
}
}
export default BottomNavigator;

Related

How to append new images to the array using react native image crop picker?

Hi, I am using react-native-image-crop-picker to overcome the above-shown module to select images from the gallery and display it in react native app, but I also want to click on add photo and again select images from the gallery and append them to the previous array of photos, am unable to figure that out.
This is the exact code that I have written to achieve the above-shown behavior, what should I change or add to perform the append feature?
import React, {useEffect, useState} from 'react';
import {
View,
Text,
StyleSheet,
ScrollView,
Image,
TouchableOpacity,
Dimensions,
FlatList,
} from 'react-native';
import Icon from 'react-native-vector-icons/FontAwesome';
import ImagePicker from 'react-native-image-crop-picker';
const deviceWidth = Dimensions.get('window').width;
const deviceHeight = Dimensions.get('window').height;
const App = () => {
const [photos, setAddPhotos] = useState(null);
const [photo, setAddphoto] = useState(null);
const handleChoosePhoto = () => {
ImagePicker.openPicker({
multiple: true,
waitAnimationEnd: false,
includeExif: true,
forceJpg: true,
})
.then((images) => {
setAddphoto(null);
setAddPhotos(
images.map((i) => {
console.log('recieved image', i);
return {
uri: i.path,
// width: i.width,
// height: i.height,
width: 185,
height: 128,
mime: i.mime,
};
}),
);
})
.catch((e) => alert(e));
};
const renderImage = (image) => {
return (
<Image
style={{
width: 185,
height: 128,
resizeMode: 'contain',
marginTop: 1,
}}
source={image}
/>
);
};
const renderAsset = (image) => {
return renderImage(image);
};
return (
<View style={{flex: 1}}>
{console.log('PHOTOS', photos)}
{photos === null ? (
<View style={{flex: 1}}>
<View style={Styles.headerWrapper}>
<View
style={{flexDirection: 'row', justifyContent: 'space-between'}}>
<Icon name="angle-left" size={30} />
<TouchableOpacity style={{right: '10%', top: '2%'}}>
<Text style={{fontSize: 15, fontWeight: 'bold'}}>
SAVE AND EXIT
</Text>
</TouchableOpacity>
</View>
</View>
<ScrollView>
<Text style={Styles.headerText}>Add photos to your listing</Text>
<Text style={Styles.subHeader}>
Photos help guests imagine staying in your place. You can start
with one and add more after you publish.
</Text>
<View style={Styles.container}>
<TouchableOpacity onPress={() => handleChoosePhoto()}>
<View
style={{
backgroundColor: '#20B2AA',
width: 150,
height: 40,
borderRadius: 5,
justifyContent: 'center',
}}>
<Text
style={{
color: '#fff',
textAlign: 'center',
fontSize: 15,
fontWeight: 'bold',
}}>
Add photos
</Text>
</View>
</TouchableOpacity>
</View>
</ScrollView>
<TouchableOpacity
style={{
alignSelf: 'flex-end',
right: '5%',
position: 'absolute',
bottom: 10,
}}>
<View
style={{
borderColor: '#20B2AA',
borderWidth: 1,
alignSelf: 'flex-end',
padding: 10,
}}>
<Text
style={{fontSize: 15, fontWeight: 'bold', color: '#20B2AA'}}>
Skip For Now
</Text>
</View>
</TouchableOpacity>
</View>
) : (
<>
<View style={{flex: 1}}>
<View style={Styles.headerWrapper}>
<View
style={{flexDirection: 'row', justifyContent: 'space-between'}}>
<Icon name="angle-left" size={30} />
<TouchableOpacity style={{right: '10%', top: '2%'}}>
<Text style={{fontSize: 15, fontWeight: 'bold'}}>
SAVE AND EXIT
</Text>
</TouchableOpacity>
</View>
</View>
<ScrollView>
<View style={{flex: 1, flexWrap: 'wrap', flexDirection: 'row'}}>
{photos
? photos.map((i) => (
<View
style={{
// width: 185, height: 128,
// width:'50%',
flexBasis: '33.33%',
}}
key={i.uri}>
{renderAsset(i)}
</View>
))
: null}
</View>
</ScrollView>
<TouchableOpacity
style={{
alignSelf: 'flex-end',
right: '5%',
position: 'absolute',
bottom: 10,
}}>
<View
style={{
backgroundColor: '#20B2AA',
alignSelf: 'flex-end',
padding: 10,
}}>
<Text style={{fontSize: 15, fontWeight: 'bold', color: '#FFF'}}>
NEXT
</Text>
</View>
</TouchableOpacity>
</View>
</>
)}
</View>
);
};
export default App;
const Styles = StyleSheet.create({
headerWrapper: {
width: deviceWidth,
paddingLeft: 24,
paddingTop: 10,
paddingBottom: 10,
},
headerText: {
fontWeight: 'bold',
fontSize: 28,
paddingLeft: 24,
},
container: {
padding: 24,
},
subHeader: {
paddingLeft: 24,
fontSize: 17,
paddingTop: 24,
paddingRight: 24,
},
});
Please let me know if anything else is required for better understanding, thank you.
You only need to take the prevState in setAddPhotos
setAddPhotos((lastPhotos) => {
const imagesMap = images.map((i) => {
return {
uri: i.path,
width: i.width,
height: i.height,
mime: i.mime,
};
});
return [...lastPhotos, ...imagesMap];
});

(React Native) update the 'fileduration' state for 'React-native-slider' upon fetching the audio file from firebase

TL;DR
It is uncertain that when will the audio file be fetched and given to the trackplayer. So i need a way that will detect the change that the file has been fetched and duration value is now available. I tried playing around with Async/await but it still fails to deliver the duration value on time to the slider.
I am developing an RN app that can stream the audio files that are currently stored in my firebase storage. I am facing difficulty in updating the slider's maximumValue. Since the song takes a couple of seconds to get fetched from firebase, the (total) duration value of the song file given by the react-native-track-player is undefiend and consequently the play button's onPress function setState(duration) sets the new tracklength state as undefined. And this is set as the maximumValue for the slider, which in turn gives the error as shown in the screenshot.
What can i do such that, when the TrackPlayer.getState() (a method from the ProgressComponent) changes its value to 'playing' or 'Ready', the application automatically rerenders with the correct duration value without giving the error.
I have used React-native-slider and React-native-Track-player
/* eslint-disable react-native/no-inline-styles */
import React from 'react';
import { Text, View, Image, SafeAreaView, TouchableOpacity, Platform, StatusBar, Dimensions, Modal, Button } from 'react-native';
import Slider from 'react-native-slider';
import Moment from 'moment';
import DeviceInfo from 'react-native-device-info';
import { FontAwesome5, Feather, Entypo } from '#expo/vector-icons';
import { Surface, Card, Badge } from 'react-native-paper';
import TrackPlayer, { ProgressComponent, getPosition } from 'react-native-track-player';
import storage from '#react-native-firebase/storage';
export default class MusicPlayer extends ProgressComponent {
componentWillMount() {
TrackPlayer.setupPlayer().then(async () => {
await TrackPlayer.add({
// url: 'https://sampleswap.org/mp3/artist/5101/Peppy--The-Firing-Squad_YMXB-160.mp3',
url: (await storage().ref('Songs/01 - Luck Aazma - www.downloadming.com.mp3').getDownloadURL()).toString(),
});
}
).then(console.log('aaaaaaaaaaaaaaaaaaaaaaa ' + this.getS().then(res => console.log(res))));
// .then(async () => {
// var dur = (await TrackPlayer.getDuration()).toString();
// this.setState({ trackLength: dur });
// });
// const temp = await TrackPlayer.getState();
// if (temp === TrackPlayer.STATE_READY) { console.log('its ready here') }
}
// componentDidMount() {
// this.interval = setInterval(
// () => {
// this.forceUpdate;
// }, 3500
// );
// }
// componentWillUnmount() {
// clearInterval(this.interval);
// }
constructor(props) {
super(props);
this.state = {
trackLength: 300,
timeElapsed: '0:00',
timeRemaining: '5:00',
optionsVisible: false,
curr_time: 0,
isPlaying: false,
t_state: this.getS(),
};
}
seekTime = seconds => {
this.setState({ timeElapsed: Moment.utc(seconds * 1000).format('m:ss') });
TrackPlayer.seekTo(seconds);
this.setState({ timeRemaining: Moment.utc((this.state.trackLength - seconds) * 1000).format('m:ss') });
};
setCurr = seconds => {
return Moment.utc(seconds * 1000).format('m:ss');
};
getS = async () => {
return await TrackPlayer.getState();
}
render() {
return (
<SafeAreaView style={{ backgroundColor: '#2d545e', flex: 1, paddingTop: (DeviceInfo.hasNotch && Platform.OS === 'android') ? StatusBar.currentHeight : 0 }}>
<View style={{ margin: 3, flex: 1 }}>
<TouchableOpacity
style={{ alignSelf: 'flex-end', marginRight: 10 }}
onPress={this.toggleOverlay} >
<Entypo name="dots-three-vertical" size={24} color="white" />
</TouchableOpacity>
{/* playlist name and album name */}
<View style={{ alignItems: 'center', marginTop: -25 }}>
<Text style={{ color: '#FFFFFF', fontSize: 10 }}>PLAYLIST</Text>
<Text style={{ color: '#FFFFFF', fontFamily: 'sans-serif', fontWeight: '500' }}>Album_name_here</Text>
</View>
{/* song image/ thumbnail zone */}
<Surface raised style={{ marginTop: 30, height: 200, width: 200, alignSelf: 'center', elevation: 50, borderRadius: 30 }}>
<Image source={{ uri: 'https://a10.gaanacdn.com/images/albums/61/161/crop_480x480_161.jpg' } || require('../../assets/images/temp.jpeg')} style={{ height: 200, width: 200, borderRadius: 30, alignSelf: 'center' }} />
</Surface>
{/* song name and artist name */}
<View style={{ marginTop: 25, flexDirection: 'column', alignItems: 'center' }}>
<Text style={{ color: '#FFFFFF', fontFamily: 'sans-serif', fontWeight: 'bold', fontSize: 20 }}>Song_Name_here</Text>
<Text style={{ color: '#FFFFFF', fontFamily: 'sans-serif', fontWeight: '500', marginTop: 3 }}>artist_name_here</Text>
</View>
{/* slider component only */}
<View style={{ flexDirection: 'column', alignItems: 'center', marginTop: 8 }}>
<Slider
minimumValue={0}
value={this.state.position}
animationType="timing"
maximumValue={this.state.trackLength}
trackStyle={{ width: Dimensions.get('screen').width - 50, height: 4 }}
thumbStyle={{ height: 20, width: 20, backgroundColor: '#fff' }}
thumbTouchSize={{ width: 100, height: 40 }}
minimumTrackTintColor="#000000"
onSlidingComplete={seconds => { console.log(seconds); this.seekTime(seconds); }}
/>
<View style={{ width: Dimensions.get('screen').width - 35, backgroundColor: '#', flexDirection: 'row', justifyContent: 'space-between' }}>
<Text style={{ flex: 1 }}>{this.setCurr(this.state.position)}</Text>
<Text style={{ alignSelf: 'flex-end' }}>{this.setCurr(this.state.trackLength)}</Text>
</View>
</View>
{/* repeat, back, play, forward and shuffle button */}
<View style={{ width: '95%', height: 70, backgroundColor: '#', alignSelf: 'center', margin: 15, flexDirection: 'row' }}>
<TouchableOpacity style={{ flex: 1, height: 30, width: 10, alignSelf: 'center', justifyContent: 'space-between', alignItems: 'center' }}>
<Feather
name="repeat"
size={30}
color="#000000"
style={{ alignItems: 'center' }}
/>
</TouchableOpacity>
<TouchableOpacity style={{ flex: 1, height: 30, width: 10, alignSelf: 'center', justifyContent: 'space-between' }} onPress={() => TrackPlayer.skipToPrevious()}>
<FontAwesome5 name="backward" size={32} color="#242320" style={{ alignSelf: 'center' }} />
</TouchableOpacity>
{
// this.state.t_state === TrackPlayer.STATE_READY &&
!this.state.isPlaying && <TouchableOpacity
style={{ flex: 1, height: 50, alignSelf: 'center', justifyContent: 'space-between', alignItems: 'center' }}
onPress={async () => {
TrackPlayer.play().then(this.setState({ isPlaying: true })).then(async () => {
var dur = (await TrackPlayer.getDuration()).toString();
this.setState({ trackLength: dur });
});
}}
>
<FontAwesome5
name="play"
size={38}
color="#000000"
style={{ marginTop: 5 }}
/>
</TouchableOpacity>}
{this.state.isPlaying && <TouchableOpacity style={{ flex: 1, height: 50, alignSelf: 'center', justifyContent: 'space-between', alignItems: 'center' }} onPress={() => TrackPlayer.pause().then(this.setState({ isPlaying: false }))}>
<FontAwesome5
name="pause"
size={38}
color="#000000"
style={{ marginTop: 5 }}
/>
</TouchableOpacity>}
<TouchableOpacity style={{ flex: 1, height: 30, width: 10, alignSelf: 'center', justifyContent: 'space-between' }} onPress={() => TrackPlayer.skipToNext()}>
<FontAwesome5 name="forward" size={32} color="#242320" style={{ alignSelf: 'center' }} />
</TouchableOpacity>
<TouchableOpacity style={{ flex: 1, height: 30, width: 10, alignSelf: 'center', justifyContent: 'space-between', alignItems: 'center' }}>
<Entypo
name="shuffle"
size={30}
color="#000000"
style={{ alignItems: 'center' }}
/>
</TouchableOpacity>
</View>
{/* up next section */}
<Surface raised style={{ width: '95%', backgroundColor: 'black', alignSelf: 'center', height: 70, borderRadius: 10, marginTop: 5 }}>
<Card.Title
style={{ backgroundColor: 'white', flex: 1, borderRadius: 10 }}
title={'Song Name here'}
titleStyle={{ margin: 25, padding: 0 }}
left={() =>
<Image
style={{ width: 50, height: 50, borderRadius: 10, alignSelf: 'flex-start', alignItems: 'flex-start' }}
source={require('../../assets/images/temp.jpeg')}
/>
}
leftStyle={{ alignItems: 'flex-start', margin: -10, padding: 0 }}
right={() => <Badge children={'Next'} size={30} style={{ width: 70, backgroundColor: 'black', borderRadius: 5, marginRight: 10 }} />}
/>
</Surface>
</View>
</SafeAreaView>
);
}
}
Sorry for the messy code but the comments would help a bit in navigating to the main parts like Slider and Play Button
Error:
My Error from the slider
For those who might require an answer to this, I solved the problem using React Hooks. React Native Track Player has a v2 update, in which the converting the above class component to functional component did the trick. It gives a rather accurate results then before. Refer to the docs here.

cannot place an image to right side react native

I have an image and it should be placed at right side of the header. I have tried and it is working perfectly in android devices. But in IOS the image is showing at left side. Please check my code,
export default class Header extends Component {
constructor(props) {
super(props);
}
render() {
return (
<View style={styles.header}>
<View style={styles.logoContainer}>
<Text style={{textAlign: 'right'}}>
<Image
style={styles.logo}
resizeMode={'contain'}
source={require('../../../../assets/logo.png')}
/>
</Text>
<TouchableOpacity
onPress={() =>
this.props.navigation.navigate('AffiliateInfo')
}
>
<Text style={{textAlign: 'right'}}>
<Image
style={styles.agile}
source={require('../../../../assets/agile.png')}
/>
</Text>
</TouchableOpacity>
</View>
<Image
style={styles.navImage}
source={require('../../../../assets/nav.png')}
/>
</View>
);
}
}
const styles = StyleSheet.create({
header: {
backgroundColor: '#0d2c4f',
paddingLeft: 10,
paddingRight: 10,
paddingTop: 30,
paddingBottom: 30,
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'flex-end'
},
logoContainer: {
flex: 1
},
logo: {
width: 200,
height: 50,
resizeMode: 'contain'
},
agile: {
width: 100,
height: 30,
resizeMode: 'contain'
},
navImage: {
width: 40,
height: 15,
resizeMode: 'contain',
marginLeft: 20
}
});
The logo.png and agile.png image should be placed at right side. Is there anything to be done in IOS. Any solution will be appreciated. I am really stuck in here.
You can use alignItems
< View style={{ alignItems: 'flex-end', width: 100, height: 30 }} >
<Image
style={styles.agile}
source={require('../../../../assets/agile.png')}
/>
< View />

Building Image Card in React Native

I'm trying to build a simple image card component in React Native and got some problems. This is my component now (It's available for you on snack):
I can't find a way to set border only on the top of the image on the card, keeping the bottom border flat.
Desired form:
The Image component doesn't seen to be rendered from the top showing the model's face, instead it's getting centered showing her body.
Here it's the original image for comparison:
Use this code. Added overflow: "hidden" to the View and removed borderRadius for Image. Tested in IOS.
import * as React from 'react';
import { Text, View, Image } from "react-native";
export default class RootComponent extends React.Component {
render() {
return (
<View style={{ flex: 1, alignItems: "center", justifyContent: "center" }}>
<View style={{ backgroundColor: "#eee", borderRadius: 10, overflow: "hidden" }}>
<View>
<Image
source={require("./assets/h4.jpg")}
style={{
height: 135,
width: 155
}}
/>
</View>
<View style={{ padding: 10, width: 155 }}>
<Text>Title</Text>
<Text style={{ color: "#777", paddingTop: 5 }}>
Description of the image
</Text>
</View>
</View>
</View>
);
}
}
By removing the height from the <Image> and setting it in its parent view, the image will be shown from the top.
<View style={{ flex: 1, alignItems: "center", justifyContent: "center" }}>
<View style={{ backgroundColor: "#eee", borderRadius: 10, overflow: 'hidden' }}>
<View style={{ height: 135, width: 155, overflow: 'hidden' }}>
<Image
source={require("./assets/h4.jpg")}
style={{
width: 155
}}
/>
</View>
<View style={{ padding: 10, width: 155 }}>
<Text>Title</Text>
<Text style={{ color: "#777", paddingTop: 5 }}>
Description of the image
</Text>
</View>
</View>
</View>
You can directly do it with borderTopLeftRadius and borderTopRightRadius in a Card.
<Card
containerStyle={styles.boxCon}
featuredTitle={title}
image={{
uri: urlToImage
}}
imageStyle={{ borderTopLeftRadius: 10, borderTopRightRadius: 10 }}
>
const styles = {
boxCon: {
margin: 15,
marginHorizontal: 10,
marginBottom: 17.5,
borderColor: '#FFFFFF',
shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.3,
shadowRadius: 5,
elevation: 5,
borderRadius: 10
}
};

React Native: Component not rendering

I am importing a custom component (RecipeCard) and it isn't appearing on the screen.
I'm fairly certain it is to do with the styling that I am currently using.
The fastimage component works exactly as the RN component does and can be seen here.
Any help is appreciated!
File1
<View style={styles.container}>
<Head
headerText={this.props.type}
navigation={this.props.navigation}
backButton
/>
<FlatList
data={this.state.data}
renderItem={({ item }) => <RecipeCard {...item} />}
/>
</View>
const styles = {
container: {
flex: 1
}};
RecipeCard
<FastImage
style={styles.imageStyle}
source={{ uri: this.props.image }}
>
<View style={styles.titleContainer}>
<Text style={styles.titleText}>
{this.props.title}
</Text>
<Text style={styles.subtitleText}>
{this.props.subtitle}
</Text>
</View>
</FastImage>
const styles = StyleSheet.create({
imageStyle: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
alignSelf: 'stretch',
backgroundColor: 'transparent',
},
titleContainer: {
position: 'absolute',
marginTop: 15,
zIndex: 2,
bottom: 13,
flex: 1,
width: '100%',
height: 70,
flexDirection: 'column',
alignItems: 'flex-start',
},
titleText: {
color: 'white',
fontWeight: '800',
paddingLeft: 5,
paddingTop: 10
},
subtitleText: {
color: '#adadad',
fontWeight: '500',
paddingLeft: 5,
paddingTop: 5,
}
});
Try to add the resizeMode to the FastImage:
resizeMode={FastImage.resizeMode.contain}
It's also described in the docs of FastImage:
import FastImage from 'react-native-fast-image'
const YourImage = () =>
<FastImage
style={styles.image}
source={{
uri: 'https://unsplash.it/400/400?image=1',
headers:{ Authorization: 'someAuthToken' },
priority: FastImage.priority.normal,
}}
resizeMode={FastImage.resizeMode.contain}
/>
I tried the example you have given above, I was able to see the image with a little change in imageStyle, just added height and it was showing the images.
RecipeCard component
const RecipeCard = (props) => {
return (
<FastImage
style={styles.imageStyle}
source={{ uri: 'https://unsplash.it/400/400?image=1' }}
>
<View style={styles.titleContainer}>
<Text style={styles.titleText}>
{props.title}
</Text>
<Text style={styles.subtitleText}>
{props.subtitle}
</Text>
</View>
</FastImage>
);
}
In imageStyle I have added height
imageStyle: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
alignSelf: 'stretch',
backgroundColor: 'transparent',
height: 200
},
Hope this helps!

Resources