Related
I am coding a project using expo react native and I made a horizontal scrollview for images. The images are styled correctly when pixels are used: <Image code... style={{width: 350}}/> However if I try to change the 350 to 35% the image disappears from the screen. I have tried several different ways to fix this problem, like adding a 100% width viewport for the parent class (like seen below), however it still is not working.
Here is the file of code:
import { StatusBar } from 'expo-status-bar';
import { StyleSheet, Text, View, Image, ScrollView, Modal, Pressable } from 'react-native';
import tw from 'tailwind-react-native-classnames';
import { useState } from 'react';
export default function ImpEvents() {
const slides = ['https://patch.com/img/cdn20/users/22844250/20200421/014148/styles/patch_image/public/livingston-highschool-schoolpr___21133742706.jpg', 'https://patch.com/img/cdn/users/22844250/2015/05/raw/20150555523bf088bd6.jpg', 'https://patch.com/img/cdn/users/22821264/2014/08/raw/5400e8ea02f3c.png']
const [modalVisible1, setModalVisible1] = useState(false);
const [modalVisible2, setModalVisible2] = useState(false);
const [modalVisible3, setModalVisible3] = useState(false);
return (
<View style={{width: '100%'}}>
<Modal
animationType="slide"
presentationStyle='pageSheet'
visible={modalVisible1}
onRequestClose={() => {
setModalVisible1(!modalVisible1);
}}>
<View style={{ position: 'absolute', backgroundColor: 'grey', top: 10, alignContent: 'center', height: 5, width: '10%', alignSelf: 'center', borderRadius: 10 }}>
</View>
<Text style={{ fontSize: 80, alignSelf: 'center' }}>1</Text>
</Modal>
<Modal
animationType="slide"
presentationStyle='pageSheet'
visible={modalVisible2}
onRequestClose={() => {
setModalVisible2(!modalVisible2);
}}>
<View style={{ position: 'absolute', backgroundColor: 'grey', top: 10, alignContent: 'center', height: 5, width: '10%', alignSelf: 'center', borderRadius: 10 }}>
</View>
<Text style={{ fontSize: 80, alignSelf: 'center' }}>2</Text>
</Modal>
<Modal
animationType="slide"
presentationStyle='pageSheet'
visible={modalVisible3}
onRequestClose={() => {
setModalVisible3(!modalVisible3);
}}>
<View style={{ position: 'absolute', backgroundColor: 'grey', top: 10, alignContent: 'center', height: 5, width: '10%', alignSelf: 'center', borderRadius: 10 }}>
</View>
<Text style={{ fontSize: 80, alignSelf: 'center' }}>3</Text>
</Modal>
<Text style={{ left: 40, fontFamily: 'OpenSans_700Bold', marginTop: '70%', fontSize: 25, color: "#3D3D3D" }}>Important Information</Text>
<View style={{ flexDirection: 'row', justifyContent: 'space-between', marginTop: 10 }}>
<ScrollView horizontal={true} showsHorizontalScrollIndicator={false} style={{ paddingTop: 7, paddingLeft: 40 }} snapToInterval={370} decelerationRate={0}>
<Pressable onPress={() => setModalVisible1(true)} style={({ pressed }) => [
{
opacity: pressed
? '0.5'
: '1'
},
]}>
<Image
source={{
uri: slides[0]
}}
style={{ width: "35%", height: 175, borderRadius: 10 }}
/>
</Pressable>
<Pressable onPress={() => setModalVisible2(true)} style={({ pressed }) => [
{
opacity: pressed
? '0.5'
: '1'
},
]}>
<Image
source={{
uri: slides[1]
}}
style={{ width: 350, height: 175, borderRadius: 10, marginLeft: 20 }}
/>
</Pressable>
<Pressable onPress={() => setModalVisible3(true)} style={({ pressed }) => [
{
opacity: pressed
? '0.5'
: '1'
},
]}>
<Image
source={{
uri: slides[2]
}}
style={{ width: 350, height: 175, borderRadius: 10, marginLeft: 20 }}
/>
</Pressable>
<View
style={{ width: 50, height: 175, borderRadius: 10, marginLeft: 20 }}
/>
</ScrollView >
</View>
<View/>
)
}
So the image at index 0 is not being displayed but the images at indices 1 and 2 are being displayed when I don't use percentages.
Thanks for the help.
If you would like to use % you need to give a parent component width. Or there is another solution which you can get the width of the device in react native. You can achieve it using Dimension as below:
import { Dimensions } from 'react-native';
const ScreenWidth = Dimensions.get('window').width;
So in order to give 90% width of device you can use it like this width: ScreenWidth * 0.9.
It's Happening because Its parent component <Pressable> does not have the width style mentioned if you want to provide dynamic height or width in percentage then you must provide height and width to its parent component.
just give width: "100%" to its parent component and then check and if that does not work check the parent component of the parent component and backtrace it.
I have an app that I am working on and am having trouble with the android styling. Everything looked fine on iOS but then when I used it on an android emulator the inputs were squished towards the top and all of the text was overlapping. So I'm trying to figure out how to use the KeyboardAwareScrollView or the KeyboardAvoidingView to either move absolutely everything on the page up or at least move the content under the header up and under the header so that you can still see the input. Here are some screen shots to show what is currently happening.
The screen when inputs are not focused on:
The Screen when an input is focused on:
Here is my screen's code. You can see by the commented out sections that I also tried placing these keyboard aware views on almost the very outside of my screen in an attempt to move the entire screen's content. Instead, it continued to behave in the same way.
return (
<SafeAreaView edges={['top']} style={{ flex: 1, backgroundColor: theme.colors.primary }}>
<SafeAreaView edges={['left', 'right', 'bottom']} style={{ flex: 1, backgroundColor: theme.colors['Surface'] }}>
<StatusBar barStyle="light-content" backgroundColor={theme.colors.primary} />
{/* <KeyboardAvoidingView
style={{ width: '100%', height: Dimensions.get('window').height, backgroundColor: theme.colors.Background, justifyContent: 'flex-end' }}
behavior={Platform.OS === "ios" ? "padding" : "padding"}
contentContainerStyle={{ width: '100%', height: '100%'}}
enabled={true}
keyboardVerticalOffset={-120}
> */}
{/* <KeyboardAwareScrollView
extraHeight={0}
enableOnAndroid={true}
automaticallyAdjustContentInsets={true}
scrollEnabled={false}
contentContainerStyle={{ height: Dimensions.get('window').height }}
> */}
<ScreenContainer hasSafeArea={false} scrollable={false}>
<View style={[styles.topBlueContainer, { backgroundColor: theme.colors.primary, position: 'absolute', zIndex: 99 }]}>
{/* Logo */}
<View style={styles.logoContainer}>
<View style={styles.Viewfe3a5f26}>
<Text
style={[styles.ConnectLogo, { color: theme.colors['Background'] }]}
>
{'company'}
</Text>
<Text
style={[styles.WalletLogo, { color: theme.colors['Background'] }]}
>
{'name'}
</Text>
<View style={styles.View63f8fbfb}>
<Icon
name={'AntDesign/trademark'}
size={8}
color={theme.colors['Background']}
/>
</View>
</View>
</View>
{/* header row */}
<View style={[styles.headerRow, {}]}>
<Touchable
onPress={() => {
navigation.navigate('PortfolioDetailsScreen');
}}
style={[styles.backArrowBtnContainer, {}]}
>
<Icon
name={'AntDesign/left'}
size={36}
color={theme.colors['Background']}
/>
</Touchable>
<View style={[styles.currencyTitleContainer, {}]}>
<Text style={[styles.currencyTitleText, { color: theme.colors['Background'] }]}> SEND {selectedToken.symbol}</Text>
</View>
<View style={styles.backArrowBtnContainer} />
</View>
</View>
{/* Page Content */}
<KeyboardAwareScrollView
extraScrollHeight={-220}
style={[
styles.contentContainer,
{
height: '100%',
paddingTop: 120,
}
]}
contentContainerStyle={
{
alignItems: 'center',
flex: 1
}
}
resetScrollToCoords={{ x: 0, y: 0 }}
enableOnAndroid={true}
viewIsInsideTabBar={true}
>
{/* Total Amnt Container */}
<View style={{ width: '100%', height: '25%', justifyContent: 'center', alignItems: 'center' }}>
<Text style={{ fontSize: 56, fontFamily: 'TitilliumWeb_600SemiBold', textAlign: 'center', marginBottom: -10 }}>{selectedToken.balance.toString().slice(0, 10)}</Text>
<Text style={{ fontSize: 16, fontFamily: 'TitilliumWeb_400Regular', textAlign: 'center', color: '#979797' }}>Current Balance</Text>
</View>
{/* Amnt To Send Container */}
<View style={{ width: '100%', height: '25%' }}>
<View style={{ width: '100%', height: '50%', justifyContent: 'flex-end', alignItems: 'center' }}>
<TextInput
onChangeText={newTextInputValue => {
try {
if (newTextInputValue) {
if (newTextInputValue === '.') {
setAmountToSend('0.');
} else if (parseFloat(newTextInputValue) <= parseFloat(selectedToken.balance)) {
setAmountToSend(newTextInputValue);
} else {
Alert.alert('Not Enough Funds', reachedMaxButtons);
}
} else {
setAmountToSend(newTextInputValue);
}
} catch (err) {
console.error(err);
}
}}
style={[
styles.amountInput,
{ borderColor: theme.colors.divider },
]}
placeholder={'0.00'}
value={amountToSend}
editable={true}
placeholderTextColor={theme.colors['Medium']}
keyboardType={'decimal-pad'}
/>
</View>
<View style={{ width: '100%', flexDirection: 'row', justifyContent: 'space-between', marginTop: 10 }}>
<View style={{ width: 100 }}/>
<View>
<Text style={{ fontSize: 16, fontFamily: 'TitilliumWeb_400Regular', textAlign: 'center', color: '#979797' }}>Amount</Text>
</View>
<Touchable
style={{
width: 100,
height: 30,
backgroundColor: theme.colors['Background'],
borderWidth: 1,
borderRadius: 23,
borderColor: '#347AF0',
alignItems: 'center',
justifyContent: 'center'
}}
onPress={() => {
setAmountToSend(selectedToken.balance.toString());
}}
>
<Text style={{ fontSize: 16, fontFamily: 'TitilliumWeb_600SemiBold', color: '#347AF0' }}>Max</Text>
</Touchable>
</View>
</View>
{/* Address Container */}
<View style={{ width: '100%', height: '25%' }}>
<View style={{ width: '100%', height: '50%', justifyContent: 'flex-end', alignItems: 'flex-start', alignItems: 'center' }}>
<TextInput
style={styles.addressInput}
placeholder={'0x43452...'}
placeholderTextColor={theme.colors['Medium']}
editable={true}
value={addressToSendTo}
onChangeText={newAddressValue => {
try {
setAddressToSendTo(newAddressValue);
} catch (err) {
console.error(err);
}
}}
/>
</View>
<View style={{ width: '100%', flexDirection: 'row', justifyContent: 'space-between', alignItems: 'flex-start', marginTop: 10 }}>
<View style={{ width: 100 }}/>
<View>
<Text style={{ fontSize: 16, fontFamily: 'TitilliumWeb_400Regular', textAlign: 'center', color: '#979797' }}>Recipient</Text>
</View>
<Touchable
style={{
width: 100,
height: 30,
backgroundColor: theme.colors['Background'],
borderWidth: 1,
borderRadius: 23,
borderColor: '#347AF0',
alignItems: 'center',
justifyContent: 'center'
}}
onPress={() => {
navigation.navigate('CodeScannerScreen', { 'screen': 'SendTokenUpdatedScreen' });
}}
>
<Text style={{ fontSize: 16, fontFamily: 'TitilliumWeb_600SemiBold', color: '#347AF0' }}>Scan QR</Text>
</Touchable>
</View>
</View>
{/* Next Btn Container */}
<View style={{ width: '100%', height: '25%', alignItems: 'center', justifyContent: 'flex-start' }}>
<Button
title={'Next'}
style={{
width: '100%',
maxWidth: 300,
height: 46,
fontFamily: 'TitilliumWeb_600SemiBold',
fontSize: 19,
color: theme.colors['Background'],
borderRadius: 23,
}}
onPress={() => {
console.log('amount', amountToSend)
console.log('amount there: ', amountToSend === '')
navigation.navigate('ConfirmSendTokenScreen', {
'amountToSend': amountToSend,
'addressToSendTo': addressToSendTo,
'selectedToken': selectedToken,
});
}}
disabled={addressToSendTo === '' || amountToSend === ''}
/>
</View>
</KeyboardAwareScrollView>
</ScreenContainer>
{/* </KeyboardAvoidingView> */}
{/* </KeyboardAwareScrollView> */}
</SafeAreaView>
</SafeAreaView>
);
};
const styles = StyleSheet.create({
logoContainer: {
paddingLeft: 15,
},
Viewfe3a5f26: {
alignItems: 'flex-start',
flexDirection: 'row',
},
WalletLogo: {
alignSelf: 'flex-start',
fontSize: 28,
fontFamily: 'ProximaNova-Bold'
},
ConnectLogo: {
alignSelf: 'flex-end',
fontSize: 28,
paddingRight: 5,
fontFamily: 'ProximaNova-Regular'
},
View63f8fbfb: {
paddingTop: 5,
},
topBlueContainer: {
height: 120,
width: '100%'
},
headerRow: {
width: '100%',
flexDirection: 'row',
marginTop: 20,
},
backArrowBtnContainer: {
paddingLeft: 12,
justifyContent: 'center',
width: '15%',
},
currencyTitleContainer: {
width: 200,
alignItems: 'center',
width: '70%'
},
currencyTitleText: {
fontFamily: 'TitilliumWeb_700Bold',
fontSize: 36
},
contentContainer: {
width: '100%',
paddingLeft: 20,
paddingRight: 20,
},
amountInput: {
fontSize: 56,
width: '100%',
height: 56,
textAlign: 'center',
borderBottomWidth: 1,
fontFamily: 'TitilliumWeb_600SemiBold',
},
amountLabel: {
fontFamily: 'TitilliumWeb_400Regular',
color: '#979797',
fontSize: 16,
},
scanQRBtn: {
width: 100,
height: 30,
borderRadius: 23,
borderWidth: 1,
},
addressInput: {
fontSize: 56,
width: '100%',
height: 56,
marginTop: 10,
textAlign: 'center',
borderBottomWidth: 1,
fontFamily: 'TitilliumWeb_600SemiBold',
borderColor: '#CFD2D8'
},
sendData: {
fontFamily: 'TitilliumWeb_400Regular',
fontSize: 20,
},
splitContainer: {
width: '100%',
height: '50%',
justifyContent: 'space-around',
alignItems: 'center',
},
sendCurrencyBtn: {
width: 300,
fontFamily: 'TitilliumWeb_600SemiBold',
fontSize: 19,
height: 46,
borderRadius: 25,
marginBottom: 20
},
});
Can anyone help me either move the current balance section and the appropriate input up and out of the way or move the entire screen's content up and out of the way just up to where the focused input is just above the keyboard?
When applying Grid to my post layout on my social media website, for some reason I am left with extra white space above the Grid element or GIF in this case. How do I remove this extra white space? Here is an image of the whitespace:
Here is an image of what logged for the whitespace via inspect:
Here is the code in question:
import { useEffect, useState, useMemo, useRef } from "react";
import userInformation from "../../services/userInformation";
import { Link, useNavigate } from "react-router-dom";
import ReactPlayer from 'react-player'
import VectorIllustration from "./VectorIllustration";
import AvatarPicture from '../../images/AvatarPicture.png'
import HomeTwoToneIcon from '#mui/icons-material/HomeTwoTone';
import { Avatar } from "#nextui-org/react";
import PageviewTwoToneIcon from '#mui/icons-material/PageviewTwoTone';
import GroupsTwoToneIcon from '#mui/icons-material/GroupsTwoTone';
import EmailTwoToneIcon from '#mui/icons-material/EmailTwoTone';
import SettingsApplicationsTwoToneIcon from '#mui/icons-material/SettingsApplicationsTwoTone';
import { Dialog, Button, IconButton, ImageList, ImageListItem, InputAdornment, DialogTitle } from "#mui/material";
import { TextField, Grid } from "#mui/material";
import { useDispatch, useSelector } from "react-redux";
import { storeUserInformation } from "../../reducers/storeInformationReducer";
import { Loading } from '#nextui-org/react'
import '../../style-sheets/Home.css'
import FavoriteBorderTwoToneIcon from '#mui/icons-material/FavoriteBorderTwoTone';
import FavoriteIcon from '#mui/icons-material/Favorite';
import HeartBrokenIcon from '#mui/icons-material/HeartBroken';
import MessageIcon from '#mui/icons-material/Message';
import IosShareOutlinedIcon from '#mui/icons-material/IosShareOutlined';
import MessageOutlinedIcon from '#mui/icons-material/MessageOutlined';
import InfiniteScroll from 'react-infinite-scroll-component'
import ViewProfileBox from "./ViewProfileBox";
const Home = () => {
const state = useSelector(state => state)
const [savedUser, setSavedUser] = useState()
const [like, setLike] = useState([])
const [mouseOver, setMouseOver] = useState(false)
const [replies, setReplies] = useState([])
const [numberOfPosts, setNumberOfPosts] = useState(Array.from({ length: 5}))
const [hasMore, setHasMore] = useState(true)
const [open, setOpen] = useState(false)
const [imageToView, setImageToView] = useState('')
const dispatch = useDispatch();
const navigate = useNavigate();
useEffect(() => {
const initializer = async () => {
const user = await JSON.parse(window.localStorage.getItem('loggedAppUser'))
setSavedUser(user)
userInformation.setToken(user.token)
const response = await userInformation.findUser(user.user.email)
const arrayOfKeys = Object.keys(response.data.user)
const arrayOfValues = Object.values(response.data.user)
let i = 0
arrayOfKeys.forEach(element => {
dispatch(storeUserInformation(arrayOfValues[i], element))
i++
});
}
initializer()
}, [])
useEffect(() => {
setLike(numberOfPosts.map((post, i) => (like[i] === undefined ? false : like[i])))
setReplies(numberOfPosts.map((post, i) => (replies[i] === undefined ? false : replies[i])))
}, [numberOfPosts])
const handleLike = (index) => {
setLike(like.map((val, i) => index === i ? !val : val));
}
const handleReplies = (index) => {
setReplies(replies.map((val, i) => index === i ? !val : val));
}
const handleOpen = (e) => {
setOpen(true)
setImageToView(e)
}
const handleClose = () => setOpen(false)
const style = {
position: 'absolute',
top: '50%',
left: '50%',
transform: 'translate(-50%, -50%)',
width: 400,
bgcolor: 'background.paper',
border: '2px solid #000',
boxShadow: 24,
p: 4,
};
const fetchMoreData = () => {
console.log(state.posts)
console.log(numberOfPosts.length)
if ((Object.entries(state.posts)).length - numberOfPosts.length < 5) {
setTimeout(() => {
setNumberOfPosts(numberOfPosts.concat(Array.from({length: ((Object.entries(state.posts)).length - numberOfPosts)})))
}, 1500)
setHasMore(false)
return;
} else {
setTimeout(() => {
setNumberOfPosts(numberOfPosts.concat(Array.from({length: 5})))
}, 1500)
}
}
return (
<>
<div style={{
position: 'relative',
width: '1920px',
height: '1080px',
background: '#F7F9FE'}}>
<VectorIllustration />
<h1 style={{position: 'absolute', width: '30%', height: '5%', left: '20%', top: '4%', fontFamily: 'Outfit', fontStyle: 'normal', fontWeight: '400', fontSize: '32px', lineHeight: '40px', color: '#000000'}}>Welcome {state.storage.name}!</h1>
<Link to='/home' style={{position: 'absolute', width: '10%', height: '6.5%', left: '2%', top: '20%', background: 'linear-gradient(90deg, rgba(255, 255, 255, 0.47) 0%, rgba(255, 255, 255, 0) 93.56%)', textDecoration: 'none', color: '#FFFFFF', display: 'flex', textAlign: 'center', justifyContent: 'center', flexDirection: 'column'}}>Home</Link>
<HomeTwoToneIcon style={{position: 'absolute', left: "3%", top: '21.5%', fontSize: '225%'}} color='primary' />
<Avatar src={state.storage.profileImageURL ? state.storage.profileImageURL : AvatarPicture} style={{position: 'absolute', left: '83.5%', top: '11%', height: '132px', width: '132px'}}></Avatar>
<Link to='/findasponsor' style={{position: 'absolute', width: '10%', height: '6.5%', left: '3.5%', top: '29%', textDecoration: 'none', color: '#FFFFFF', display: 'flex', textAlign: 'center', justifyContent: 'center', flexDirection: 'column'}}>Find A Sponsor</Link>
<PageviewTwoToneIcon style={{position: 'absolute', left: "3%", top: '30.5%', fontSize: '225%', opacity: '0.7'}} />
<Link to='/Groups' style={{position: 'absolute', width: '10%', height: '6.5%', left: '3.5%', top: '37%', textDecoration: 'none', color: '#FFFFFF', display: 'flex', textAlign: 'center', justifyContent: 'center', flexDirection: 'column'}}>Groups</Link>
<GroupsTwoToneIcon style={{position: 'absolute', left: "3%", top: '38.6%', fontSize: '225%', opacity: '0.75'}} />
<Link to='/Messsages' style={{position: 'absolute', width: '10%', height: '6.5%', left: '3.5%', top: '45%', textDecoration: 'none', color: '#FFFFFF', display: 'flex', textAlign: 'center', justifyContent: 'center', flexDirection: 'column'}}>Messages</Link>
<EmailTwoToneIcon style={{position: 'absolute', left: "3%", top: '46.5%', fontSize: '225%', opacity: '0.75'}} />
<Link to='/Settings' style={{position: 'absolute', width: '10%', height: '6.5%', left: '3.5%', top: '54%', textDecoration: 'none', color: '#FFFFFF', display: 'flex', textAlign: 'center', justifyContent: 'center', flexDirection: 'column'}}>Settings</Link>
<SettingsApplicationsTwoToneIcon style={{position: 'absolute', left: "3%", top: '55.5%', fontSize: '225%', opacity: '0.75'}} />
<h1 style={{position: 'absolute', width: '201px', height: '76px', left: '4%', top: '68%', fontFamily: 'Outfit', fontStyle: 'normal', fontWeight: '500', fontSize: '26px', lineHeight: '38px', textAlign: 'center', color: '#1B1C1F', textDecoration: 'underline'}}>Go Local</h1>
<p style={{position: 'absolute', width: '201px', height: '76px', left: '4%', top: '73%', fontFamily: 'Outfit', fontStyle: 'normal', fontWeight: '500', fontSize: '15px', textAlign: 'center', color: 'black'}}>Currently, you are viewing sponsors/ sponsees globally. Would you like to view only sponsors/sponsees in your country?</p>
<Button style={{position: 'absolute', left: '4.5%', top: '85%', background: '#FFFFFF', borderRadius: '16px'}}>No</Button>
<Button style={{position: 'absolute', left: '10.5%', top: '85%', background: '#FFFFFF', borderRadius: '16px'}} onClick={(e) => navigate('./Settings')}>Yes</Button>
<h1 style={{position: 'absolute', top: '70%', left: '78%'}}>Trending Users</h1>
<Link to='/home/:id' style={{position: 'absolute', top: '73.25%', left: '94%'}}>View all</Link>
<p style={{position: 'absolute', top: '20%', left: '79%', fontFamily: 'Outfit', fontStyle: 'normal', fontWeight: '600', fontSize: '20px', lineHeight: '25px', textAlign: 'center'}}>{state.storage.followers}</p>
<p style={{position: 'absolute', top: '23%', left: '77.5%', fontFamily: 'Outfit', fontStyle: 'normal', fontWeight: '300', fontSize: '16px', lineHeight: '20px', textAlign: 'center', color: '#A2ADBC'}}>Followers</p>
<p style={{position: 'absolute', top: '20%', left: '94.5%', fontFamily: 'Outfit', fontStyle: 'normal', fontWeight: '600', fontSize: '20px', lineHeight: '25px', textAlign: 'center'}}>{state.storage.following}</p>
<p style={{position: 'absolute', top: '23%', left: '93%', fontFamily: 'Outfit', fontStyle: 'normal', fontWeight: '300', fontSize: '16px', lineHeight: '20px', textAlign: 'center', color: '#A2ADBC'}}>Following</p>
<h1 style={{position: 'absolute', top: '28%', left: '83.6%', fontFamily: 'Outfit', fontStyle: 'normal', fontWeight: '500', fontSize: '20px', lineHeight: '25px', textAlign: 'center'}}>{state.storage.name}</h1>
<p style={{position: 'absolute', width: '360px', height: '54px', left: '77.6%', top: '33%', fontFamily: 'Outfit', fontStyle: 'normal', fontWeight: '300', fontSize: '14px', lineHeight: '18px', textAlign: 'center', color: '#6D7683'}}>{state.storage.biography}</p>
<ViewProfileBox savedUser={savedUser}/>
{(Object.values(state.posts)).length !== 0 ?
<InfiniteScroll height='100%' dataLength={numberOfPosts.length} next={fetchMoreData} hasMore={hasMore} loader={<Loading style={{position: 'absolute', left: '50%'}}/>}
id='all-post-container' scrollThreshold={0.5} endMessage={<p style={{ textAlign: "center" }}>
<b>That's all folks!</b>
</p>}
style={{position: 'absolute', top: '25%', left: '20%', backgroundColor: '#F7F9FE', height: '72%', width: "54%", borderRadius: '30px'}}>
<Grid
container
direction="column"
justifyContent="center"
alignItems="center"
spacing={15}
>
{numberOfPosts.map((key, i) => {
return (
<Grid container item>
<Grid item xs={12} container style={{backgroundColor: 'white', paddingTop: '20px'}}>
{/* avatar, username, etc */}
<Grid item xs={1} container style={{ justifyContent: "center" }}>
<Avatar src={AvatarPicture} />
</Grid>
<Grid item container xs={11} style={{ gap: "10px" }}>
<Grid item xs={11}>
#{state.posts[i]?.username}
</Grid>
<Grid item xs={11}>
{state.posts[i]?.location} {state.posts[i]?.date}
</Grid>
</Grid>
</Grid>
<Grid item xs={12} className="indent2" style={{backgroundColor: 'white'}}>
{/* post text */}
<p
className="Post"
style={{
padding: "1em",
backgroundColor: "#FFFBEE",
borderRadius: "20px",
margin: '1%'
}}
>
{state.posts[i]?.text}
</p>
</Grid>
{state.posts[i]?.video && (
<Grid item xs={12} className="indent2" style={{backgroundColor: 'white'}}>
{/* post video */}
<ReactPlayer url={state.posts[i].video} controls width='100%'/>
</Grid>
)}
<Grid container wrap="nowrap">
{state.posts[i]?.images && (
<Grid item xs={12} className="indent2" style={{backgroundColor: 'white'}}>
{/* post image */}
<ImageList sx={{overflowX: 'auto' }} rowHeight={200}>
<ImageListItem sx={{display: 'flex', flexDirection: 'row'}}>
{state.posts[i].images.map(image => {
return (
<img
src={image}
alt='title'
loading='lazy'
style={{paddingRight: '1em', objectFit: 'contain'}}
onClick={(e) => handleOpen(e.target.src)}
/>
)
})}
<Dialog
open={open}
onClose={handleClose}
style={{ maxWidth: "100%", maxHeight: "100%" }}
BackdropProps={{invisible: true}}
>
<img
style={{ width: 'auto', height: '100%' }}
src={imageToView}
alt="image"
/>
</Dialog>
</ImageListItem>
</ImageList>
</Grid>
)}
</Grid>
<Grid container wrap="nowrap">
{state.posts[i]?.gif && (
<Grid item xs={12} className="indent2" style={{backgroundColor: 'white'}}>
{/* post gif */}
<img src={state.posts[i].gif} style={{objectFit: 'contain'}} />
</Grid>
)}
</Grid>
<Grid item xs={12} className="indent2" style={{backgroundColor: 'white'}}>
{/* icon bar */}
<Grid container style={{ padding: 12, gap: 20 }}>
<Grid item>
<IconButton
onClick={() => handleLike(i)}
onMouseLeave={() => setMouseOver(false)}
onMouseOver={() => setMouseOver(true)}
>
{like[i]&& mouseOver ? (
<HeartBrokenIcon style={{ color: "red" }} />
) : like[i] ? (
<FavoriteIcon style={{ color: "red" }} />
) : (
<FavoriteBorderTwoToneIcon />
)}
</IconButton>{" "}
{state.posts[i]?.likes}
</Grid>
<Grid item>
<IconButton onClick={() => handleReplies(i)}>
{replies[i] ? (
<MessageIcon color="primary" />
) : (
<MessageOutlinedIcon />
)}
</IconButton>{" "}
{state.posts[i]?.comments}
</Grid>
<Grid item>
<IconButton>
<IosShareOutlinedIcon />
</IconButton>{" "}
{state.posts[i]?.shares}
</Grid>
</Grid>
</Grid>
<Grid item xs={12} className="indent2" style={{backgroundColor: 'white', borderRadius: '16px'}}>
{/* comment */}
<TextField
InputProps={{
startAdornment: (
<InputAdornment>
<Avatar src={state.storage.profileImageURL} style={{ marginRight: 12 }} />
</InputAdornment>
),
classes: {
notchedOutline: "notched-outline-border-radius"
},
maxLength: 500
}}
maxRows={10}
multiline
placeholder="Write your comment"
style={{ width: "100%" }}
/>
</Grid>
</Grid>
)})}
</Grid>
</InfiniteScroll> : <div id='content-loader' style={{position: 'absolute', top: '25%', left: '20%', backgroundColor: '#F7F9FE', height: '72%', width: "54%", borderRadius: '30px'}}><Loading size='lg' style={{position: 'absolute', left: '50%', top: '50%'}}/></div>}
</div>
</>
)
}
export default Home;
Here is the code that deals specifically with the posting of a gif:
<Grid container wrap="nowrap">
{state.posts[i]?.gif && (
<Grid item xs={12} className="indent2" style={{backgroundColor: 'white'}}>
{/* post gif */}
<img src={state.posts[i].gif} style={{objectFit: 'contain'}} />
</Grid>
)}
</Grid>
I found the solution. The whitespace had the same measurements for the Grid of the post for images. For some reason, even though a post only had a GIF, it was acting as if it also had an image because images is set with an empty array, so to avoid the Grid for images to be rendered i placed a state.posts[i].images.length > 0 ultimatum so there has to be at least 1 image for the image Grid to execute...
I change the post button from an icon to text, when message is written. But my input keeps losing focus and I have to click it to type each letter. I have commented the code which is causing the problem (in my oppinion). I have been trying to solve it. I moved the textarea out of the component, I gave it a unique key, I moved the Post button out to a new component but none of it worked. Please help!
My Code:
import { useState, useRef, useEffect } from "react"
import {
Box,
Typography,
Button
} from "#mui/material"
import { styled } from "#mui/system"
import {
InfoOutlined as InfoIcon,
InsertPhotoOutlined as PhotoIcon
} from "#mui/icons-material"
import Message from "./Message"
import EmojiPicker from "../EmojiPicker/EmojiPicker"
const Chat = () => {
const Container = styled(Box)({
width: '100%',
display: 'flex',
flexDirection: 'column',
flex: 1
})
const HeaderContainer = styled(Box)({
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
padding: '1.2rem 2rem',
borderBottom: '1px solid #e8e8e8',
borderLeft: '1px solid #e8e8e8'
})
const NameContainer = styled(Box)({
display: 'flex',
alignItems: 'center',
cursor: 'pointer'
})
const ImageContainer = styled(Box)({
width: '30px',
height: '30px',
borderRadius: '50%',
overflow: 'hidden'
})
const ProfileName = styled(Typography)({
fontSize: '1.7rem',
fontWeight: '600',
marginLeft: '1.5rem'
})
const imageStyles = {
width: '100%',
height: '100%',
objectFit: 'cover',
objectPosition: 'center'
}
const ChatContainer = styled(Box)({
flex: 1,
display: 'flex',
flexDirection: 'column',
overflowY: 'scroll',
padding: '1.5rem'
})
const MessageFieldContainer = styled(Box)({
display: 'flex',
alignItems: 'center',
padding: '.5rem 1rem',
border: '1px solid #8e8e8e',
borderRadius: '25px'
})
const SendButton = styled(Button)({
fontWeight: '600',
fontSize: '1.3rem',
textTransform: 'none',
padding: '0'
})
const messageFieldStyles = {
border: 'none',
outline: 'none',
fontSize: '1.4rem',
fontFamily: 'inherit',
resize: 'none',
flex: 1
}
const [message, setMessage] = useState('')
return (
<Container>
<HeaderContainer>
<NameContainer>
<ImageContainer>
<img style={imageStyles} component="image" src="images/person.jpg"/>
</ImageContainer>
<ProfileName>Asfand Yar</ProfileName>
</NameContainer>
<InfoIcon sx={{
fontSize: '2.5rem',
cursor: 'pointer'
}}/>
</HeaderContainer>
<ChatContainer>
<Message type="reciever">Hello</Message>
</ChatContainer>
<Box sx={{ padding: '2rem' }}>
<MessageFieldContainer>
<EmojiPicker />
// Error Code ***********
<textarea
placeholder="Message..."
name="message"
rows="1"
style={messageFieldStyles}
value={message}
onChange={(e) => setMessage(e.target.value)}/>
{
message == "" ? <PhotoIcon sx={{ fontSize: '2.5rem'}}/> : <SendButton>Send</SendButton>
}
// ***************
</MessageFieldContainer>
</Box>
</Container>
)
}
export default Chat
I am using an image as the background for one of my pages. I'd like to add a backgroundColor with an opacity over the image. I'm not sure how I can achieve this with React Native.
render() {
return (
<Image source={require('./assets/climbing_mountain.jpeg')} style={styles.container}>
<Text>Hello</Text>
</Image>
)
}
const styles = StyleSheet.create({
container: {
flex: 1,
width: null,
height: null,
}
Here is how I'd achieve this on a web page: How to make in CSS an overlay over an image?
A cool thing you can do is drop an absolutely positioned view over it.
<View>
<Image source={require('./assets/climbing_mountain.jpeg')} style= {StyleSheet.absoluteFillObject}} resizeMode='cover'>
<Text>Hello</Text>
</Image>
<View style={styles.overlay} />
</View>
...
const styles = StyleSheet.create({
overlay: {
...StyleSheet.absoluteFillObject,
backgroundColor: 'rgba(0,0,0,0.5)'
}
})
absoluteFillObject is the same as
{
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0
}
If you want to be able to tap through your overlay, just set the pointerEvents prop on the view to none
docs: https://facebook.github.io/react-native/docs/stylesheet.html#absolutefillobject
I was able to get this working thanks to #Kevin Velasco.
render() {
return (
<View style={styles.container}>
<Image source={require('./assets/climbing_mountain.jpeg')} style={styles.imageContainer}>
</Image>
<View style={styles.overlay} />
</View>
)
}
const styles = StyleSheet.create({
container: {
flex: 1,
width: null,
height: null,
},
imageContainer: {
flex: 1,
width: null,
height: null,
},
overlay: {
...StyleSheet.absoluteFillObject,
backgroundColor: 'rgba(69,85,117,0.7)',
}
})
Here I use to solve my project, thansk to all:
<View>
<View
style = {{
//make overlay
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
//change this color to the other one which you want
backgroundColor: 'green',
}}
/>
<Image
source = {{ uri: Your-Image-Here }}
style = {{ height: 150, width: 200, resizeMode: 'cover', borderBottomLeftRadius: 20, borderTopLeftRadius: 20 }}
/>
</View>
Make an overlay on react native image background: If you want to make an overlay on the background image ONLY in react native and not affect other elements that are inside the < ImageBackground> tag, do this:
//Fetching the background image from online, you can use any image source of your choice.
const GoProImageBackGd = { uri: "https://images.pexels.com/photos/2462402/pexels-photo-2462402.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940" };
// Setting the background image for the view:
<View style={styles.GoProBox}>
<ImageBackground source={GoProImageBackGd} resizeMode='cover' style={styles.goProBgImage}>
<View style={styles.overlayView}/>
<Text style={styles.goProText}> Want to join the hot section? Go hot with Pro!</Text>
<GoProButton />
</ImageBackground>
//Stylesheet
const styles = StyleSheet.create({
GoProBox: {
width: '95%',
height: 200,
margin: 5,
backgroundColor: '#00cc00',
borderRadius: 10,
alignSelf: 'center',
overflow: 'hidden'
},
goProBgImage: {
width: '100%', height: '100%',
},
goProText: {
textAlign: 'center',
fontSize: 20,
marginTop: 10,
fontWeight: 'bold',
padding: 10,
color: 'white'
},
GoProButton: {
height: 60,
width: 200,
backgroundColor: 'red',
borderRadius: 15,
alignSelf: 'center',
justifyContent: 'center',
top: 50
},
overlayView: {
height: "100%",
width: "100%",
position: 'absolute',
backgroundColor: 'rgba(0, 204, 0, 0.5)',
}
})
this is how i dit it to get it work for me
const visaCard = require('../Images/card_visa.png');
const [iscardBloqued, setIsCardBolqued] = useState(false);
const [hideInfos, setHideInfos] = useState(true);
Here is How the component looks like
<View style={styles.imageContainer}>
<ImageBackground
source={visaCard}
imageStyle={{ borderRadius: wp(3) }}
style={styles.imageStyle}
resizeMode="cover"
>
{hideInfos && (
<TouchableOpacity activeOpacity={0.8} style={styles.cardWhiteButton}>
<FText style={styles.whiteButtonText}>Afficher les infos</FText>
</TouchableOpacity>
)}
{iscardBloqued && (
<View style={styles.overlay}>
<TouchableOpacity
activeOpacity={0.7}
style={{ alignItems: 'center' }}
>
<Lock />
<FText style={styles.overlayText}>Carte bloqueé</FText>
</TouchableOpacity>
</View>
)}
</ImageBackground>
</View>
And her is my Style page: "i prefered to separate it from my component"
export default StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
},
imageContainer: {
alignSelf: 'center',
marginTop: hp(3),
},
imageStyle: {
height: hp(25),
width: wp(85),
},
cardWhiteButton: {
marginHorizontal: wp(8),
backgroundColor: 'white',
marginTop: hp(17),
height: hp(5),
width: wp(32),
alignItems: 'center',
justifyContent: 'center',
borderRadius: wp(5),
},
whiteButtonText: {
fontSize: hp(1.4),
color: 'white',
fontFamily: 'Roboto',
},
overlay: {
...StyleSheet.absoluteFillObject,
backgroundColor: 'rgba(0,0,0,0.89)',
justifyContent: 'center',
alignItems: 'center',
borderRadius: wp(3),
},
overlayText: {
color: 'white',
fontSize: hp(1.6),
fontFamily: 'Roboto',
marginTop: hp(2),
},
});