I'm trying to create a responsive page where the element stack upon each other when viewed on a mobile device however instead of stacking they keep aligning side by side. How could I stack them?
I've tried messing with the spacing and padding but that didn't seem to help. I also looked into adjusting the flexgrow values but that didn't work either.
Here's my code:
<Grid container justifyContent="center" alignItems="center" flexGrow={1}>
<Box sx={homeStyle.main}>
<Box sx={homeStyle.blueBox}>
<Box sx={homeStyle.noBeneAvailText}>
Register
</Box>
<Box sx={homeStyle.noBeneAvailDetailText}>
Information About you
</Box>
<Grid container spacing={2}>
<Grid item xs={6}>
<TextField
variant="outlined"
id="first-name-input"
label="First Name"
defaultValue=""
fullWidth
/>
</Grid>
<Grid item xs={6}>
<TextField
variant="outlined"
id="last-name-input"
label="Last Name"
fullWidth
/>
</Grid>
</Grid>
<Grid container spacing={2}>
<Grid item xs={6}>
<TextField
variant="outlined"
id="phone-number-input"
label="Phone Number"
defaultValue=""
fullWidth
/>
</Grid>
<Grid item xs={6}>
<TextField
variant="outlined"
id="email-input"
label="Email Address"
fullWidth
/>
</Grid>
</Grid>
</Box>
</Box>
</Grid>
const homeStyle = {
updateInfoText: {
//color: "#FFFFFF",
fontFamily: "Roboto",
fontStyle: "bold",
fontWeight: 800,
fontSize: "14px",
lineHeight: "20px",
textAlign: "center",
letterSpacing: "0.1px",
},
updateInfoButton: {
display: "flex",
flexDirection: "column",
justifyContent: "center",
alignItems: "center",
alignSelf: "center",
py: "10px",
px: "24px",
// gap: "10px",
width: { lg: "540px", md: "666px", xs: '311px' },
height: "40px",
mt: "15px",
backgroundColor: "#3C4FB9",
color: 'white',
borderRadius: "100px",
flex: "none",
order: 2,
flexGrow: 0,
'&:hover': {
backgroundColor: '#9BA5DF',
color: '#36414E',
}
},
noBeneAvailDetailText: {
width: { lg: "740px", md: "666px", xs: '311px' },
fontFamily: "Roboto",
fontStyle: "normal",
fontWeight: 400,
fontSize: "16px",
lineHeight: "24px",
textAlign: "left",
alignItems: "center",
color: "#56677B",
flex: "none",
alignSelf: "stretch",
flexGrow: 0
},
noBeneAvailText: {
width: { lg: "740px", md: "666px", xs: '311px' },
height: "32px",
fontFamily: "Roboto Slab",
fontStyle: "normal",
fontWeight: 500,
fontSize: "24px",
lineHeight: "32px",
textAlign: "left",
alignSelf: "stretch",
color: "#252D36",
flex: "none",
flexGrow: 0
},
benefitsAvaillibilityTextFrame: {
display: "flex",
flexDirection: "column",
alignItems: "center",
textAlign: "center",
padding: "0px",
gap: "12px",
width: { lg: "740px", md: "666px", xs: '311px' },
height: { lg: "92px", md: "92px", xs: '140px' },
flex: "none",
order: 2,
alignSelf: "center",
flexGrow: 0,
},
blueBox: {
display: "flex",
flexDirection: "column",
alignItems: "center",
//alignSelf: "center",
// justifyContent: "center",
pt: { lg: "52px", md: "52px", sm: "39px", xs: '24px' },
pr: { lg: "52px", md: "52px", sm: "39px", xs: '16px' },
pb: { lg: "52px", md: "52px", sm: "39px", xs: '24px' },
pl: { lg: "52px", md: "52px", sm: "39px", xs: '16px' },
gap: { lg: "32px", md: '32px', sm: "32px", xs: '20px' },
width: { lg: "544px", md: '770px', sm: "500px", xs: '343px' },
height: { lg: "750px", md: '750px', sm: "700px", xs: '783px' },
background: "#F5F7FF",
borderRadius: "8px",
flex: "none",
order: 1,
alignSelf: "center",
flexGrow: 0,
},
welcomeText: {
width: { lg: "626px", md: '770px', xs: '343px' },
height: { lg: "44px", md: '38px', xs: '32px' },
fontFamily: 'Roboto Slab',
fontStyle: "normal",
fontWeight: 500,
fontSize: { lg: "36px", md: '30px', xs: '24px' },
lineHeight: { lg: "44px", md: '38px', xs: '32px' },
textAlign: "center",
letterSpacing: "-0.02em",
color: "#252D36",
flex: "none",
order: 0,
alignSelf: "center",
flexGrow: 0,
},
main: {
display: "flex",
flexDirection: "column",
alignSelf: "center",
alignItems: "center",
pt: { lg: "90px", md: '40px', sm: "32px", xs: '32px' },
pr: { lg: "407px", md: '32px', sm: "16px", xs: '16px' },
pb: { lg: "80px", md: '40px', sm: "32px", xs: '32px' },
pl: { lg: "407px", md: '32px', sm: "px", xs: '16px' },
gap: { lg: "40px", md: '32px', sm: "32px", xs: '20px' },
width: { lg: "1000", md: '834', xs: '375' },
height: { lg: "888", md: '1100', xs: '942' },
background: "#FFFFFF",
flex: "none",
order: 1,
flexGrow: { lg: 1, md: 0, xs: 0 },
},
container: (theme) => ({
display: "flex"
}),
item: (theme) => ({
border: "1px solid blue"
}),
itemFlexGrow: (theme) => ({
flexGrow: 1,
border: "1px solid red"
})
Currently, it looks like this:
I think you need to set the xs which preset the width of the grid in the x-small screen like mobile to 12 to take the full width.
<Grid container spacing={2}>
<Grid item xs={12}>
<TextField
variant="outlined"
id="first-name-input"
label="First Name"
defaultValue=""
fullWidth
/>
</Grid>
<Grid item xs={12}>
<TextField
variant="outlined"
id="last-name-input"
label="Last Name"
fullWidth
/>
</Grid>
</Grid>
<Grid container spacing={2}>
<Grid item xs={12}>
<TextField
variant="outlined"
id="phone-number-input"
label="Phone Number"
defaultValue=""
fullWidth
/>
</Grid>
<Grid item xs={12}>
<TextField
variant="outlined"
id="email-input"
label="Email Address"
fullWidth
/>
</Grid>
</Grid>
Related
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?
I'm trying to split the date on both release_date and first_air_date however the split() method isn't working for me. What am I doing wrong - please explain! I'm a beginner. Many thanks in advance!
Below is my code:
import { Typography } from "#mui/material";
import { Box } from "#mui/system";
import React from "react";
function Card({ daily }) {
let text = daily.release_date;
let airDate = daily.first_air_date;
const myArray = text.split("-");
const splitDate = airDate.split("-");
const word = myArray[0];
const date = splitDate[0];
console.log(word);
console.log(date);
return (
<Box
sx={{
width: "25%",
height: "550px",
backgroundColor: "#144272",
alignSelf: "flex-start",
borderRadius: "10px",
}}
>
<Box
sx={{
width: "100%",
height: "85%",
backgroundColor: "red",
borderRadius: "20px",
}}
>
<img
className="img-src"
src={`https://image.tmdb.org/t/p/w500/${daily.poster_path}`}
alt=""
style={{
width: "100%",
height: "100%",
objectFit: "cover",
borderRadius: "20px",
}}
/>
</Box>
<Box
sx={{
display: "flex",
align: "center",
fontFamily: "Open Sans, sans-serif",
fontWeight: "normal",
fontSize: "20px",
color: "#fff",
margin: "5px 10px",
flexDirection: "column",
}}
>
{daily.original_title ? (
<Typography sx={{}}>{daily.original_title}</Typography>
) : (
<Typography sx={{}}>{daily.name}</Typography>
)}
<Typography
sx={{
fontFamily: "Open Sans, sans-serif",
fontWeight: "lighter",
fontSize: "15px",
color: "#fff",
margin: "5px 10px",
}}
>
{/*word*/}
</Typography>
{daily.release_date ? (
<Typography sx={{}}>{text}</Typography>
) : (
<Typography sx={{}}>{/*airDate*/}</Typography>
)}
</Box>
</Box>
);
}
export default Card;
I used the split() method in another component, here is the code for that one and it worked fine:
import React from "react";
function Card({ recomendations }) {
let text = recomendations.release_date;
const myArray = text.split("-");
let word = myArray[0];
console.log(word);
return (
<Box
sx={{
width: "25%",
height: "550px",
backgroundColor: "#144272",
alignSelf: "flex-start",
borderRadius: "10px",
}}
>
<Box
sx={{
width: "100%",
height: "85%",
backgroundColor: "red",
borderRadius: "20px",
}}
>
<img
className="img-src"
src={`https://image.tmdb.org/t/p/w500/${recomendations.poster_path}`}
alt=""
style={{
width: "100%",
height: "100%",
objectFit: "cover",
borderRadius: "20px",
}}
/>
</Box>
<Box
sx={{
display: "flex",
align: "center",
fontFamily: "Open Sans, sans-serif",
fontWeight: "normal",
fontSize: "20px",
color: "#fff",
margin: "5px 10px",
flexDirection: "column",
}}
>
<Typography sx={{}}>{recomendations.original_title}</Typography>
<Typography
sx={{
fontFamily: "Open Sans, sans-serif",
fontWeight: "lighter",
fontSize: "15px",
color: "#fff",
margin: "5px 10px",
}}
>
{word}
</Typography>
</Box>
</Box>
);
}
export default Card;
I have a Material UI grid component. I need the child grid items to increase in size with the viewport, but to also maintain the square dimensions.
Reproducible example: https://codesandbox.io/s/material-ui-grid-demo-forked-6ws4yj?file=/src/index.js
Grid component:
<Box sx={{ width: { xs: "100%", lg: "80%", xl: "100%" } }}>
<Grid
container
columns={{ xs: 2, lg: 2, xl: 4 }}
rowSpacing={{ xs: 1, xl: 2 }}
columnSpacing={{ xs: 1, xl: 2 }}
>
{tiles.map((tile) => (
<Grid item key={tile} xs={1} lg={1} xl={1}>
<Box
sx={{
width: {
xs: "calc(100% - 4px)",
lg: "calc(100% - 4px)",
xl: "100%"
},
height: { xs: "139.5px", lg: "164px", xl: "198px" },
border: "1px solid black",
borderRadius: 2,
display: "flex",
justifyContent: "center",
alignItems: "center",
cursor: "pointer"
}}
>
test
</Box>
</Grid>
))}
</Grid>
</Box>
How can I have the height change dynamically with the width to keep the square ratio?
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 am attempting to replicate the following layout from instagram using react native in my own app:
Here is my code:
render() {
if (this.state.isLoading) {
return (
<View styles ={styles.container}>
<ActivityIndicator size="large" color="#9E9E9E" />
</View>
);
}
return (
<TouchableWithoutFeedback onPress={Keyboard.dismiss}>
<View style={styles.container}>
<Image
source={{ uri: this.state.oldProfilePic }}
style={styles.thumbnail}
/>
<TouchableOpacity
onPress={this.openImagePickerAsync}
style={styles.button}
>
<Text style={{ color: '#FFFFFF', fontWeight: 'bold', fontSize: 18 }}>change profile picture</Text>
</TouchableOpacity>
<View style= {{ flexDirection: 'row', justifyContent: 'space-between', padding: 20 }}>
<Text style={{ color: '#FFFFFF', fontWeight: 'bold', fontSize: 18, paddingTop: 5 }}>bio </Text>
<TextInput
style={styles.inputBox}
value={this.state.newBio}
onChangeText={newBio => this.setState({ newBio })}
placeholder={this.state.oldBio}
multiline
autoCapitalize="none"
placeholderTextColor="#696969"
/>
</View>
<View style ={{ flexDirection: 'row', justifyContent: 'space-between', padding: 20 }}>
<Text style={{ color: '#FFFFFF', fontWeight: 'bold', fontSize: 18, paddingTop: 7 }}>twitter </Text>
<TextInput
style={styles.socialInputBox}
value={this.state.twitter}
onChangeText={twitter => this.setState({ twitter })}
placeholder={this.state.twitter === null ? 'Enter Twitter username' : this.state.twitter}
autoCapitalize="none"
placeholderTextColor="#696969"
/>
</View>
<View style= {{ flexDirection: 'row', justifyContent: 'space-between', padding: 20 }}>
<Text style={{ color: '#FFFFFF', fontWeight: 'bold', fontSize: 18, paddingTop: 7 }}>instagram </Text>
<TextInput
style={styles.socialInputBox}
value={this.state.instagram}
onChangeText={instagram => this.setState({ instagram })}
placeholder={this.state.instagram === null ? 'Enter Instagram username' : this.state.instagram}
autoCapitalize="none"
placeholderTextColor="#696969"
/>
</View>
<TouchableOpacity
onPress={() => { this.saveChanges(); }}
style={styles.button}
>
<Text style={{ color: '#FFFFFF', fontWeight: 'bold', fontSize: 18 }}>save changes</Text>
</TouchableOpacity>
<KeyboardSpacer />
</View>
</TouchableWithoutFeedback>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
// justifyContent: 'space-between',
backgroundColor: '#121212',
},
inputBox: {
width: '85%',
// margin: 10,
padding: 15,
fontSize: 16,
borderColor: '#d3d3d3',
borderWidth: 1,
color: '#FFFFFF',
// textAlign: 'center'
},
thumbnail: {
width: 150,
height: 150,
borderRadius: 75,
marginTop: 40,
marginBottom: 30,
},
button: {
// marginTop: 10,
paddingVertical: 5,
alignItems: 'center',
backgroundColor: 'transparent',
borderColor: '#FFFFFF',
borderWidth: 1,
borderRadius: 5,
width: 200,
marginRight: 10,
marginLeft: 10,
marginBottom: 30,
},
socialInputBoxText: {
fontSize: 16,
fontWeight: 'bold',
marginTop: 10,
paddingTop: 15,
color: '#FFFFFF',
},
socialInputBox: {
width: '35%',
// marginTop: 10,
padding: 10,
fontSize: 14,
borderColor: '#d3d3d3',
borderWidth: 1,
textAlign: 'center',
color: '#FFFFFF',
},
});
And here is the result of my code:
As you can see, the instagram one is much neater. I am wondering how I can come closer to replicating the instagram layout in my own app. Thank you in advance!