diff options
Diffstat (limited to 'src/components')
-rw-r--r-- | src/components/Header/Header.tsx | 4 | ||||
-rw-r--r-- | src/components/Header/SearchBar.tsx | 4 | ||||
-rw-r--r-- | src/components/Loading/Loading.tsx | 24 | ||||
-rw-r--r-- | src/components/PollCard/PollCard.tsx | 20 | ||||
-rw-r--r-- | src/components/PollsList/PollsList.tsx (renamed from src/components/Feed/Feed.tsx) | 43 | ||||
-rw-r--r-- | src/components/ScrollTopArrow/ScrollTopArrow.tsx | 4 |
6 files changed, 59 insertions, 40 deletions
diff --git a/src/components/Header/Header.tsx b/src/components/Header/Header.tsx index 5aa66ba..c3a678c 100644 --- a/src/components/Header/Header.tsx +++ b/src/components/Header/Header.tsx @@ -42,7 +42,7 @@ const useStyles = makeStyles(theme => ({ })); -const Header: React.FC = () => { +const Header: React.FC = React.memo(() => { const classes = useStyles(); const { user } = useAuth(); const theme = useTheme(); @@ -118,7 +118,7 @@ const Header: React.FC = () => { ); return isMobile ? MobileVersion : BrowserVersion; -}; +}); export default Header; diff --git a/src/components/Header/SearchBar.tsx b/src/components/Header/SearchBar.tsx index f541589..8bfe0fb 100644 --- a/src/components/Header/SearchBar.tsx +++ b/src/components/Header/SearchBar.tsx @@ -37,7 +37,7 @@ const useStyles = makeStyles(theme => ({ } })); -const SearchBar: React.FC = () => { +const SearchBar: React.FC = React.memo(() => { const [results, setResults] = useState<User[]>([]); const [query, setQuery] = useState<string>(''); const [debouncedQuery, setDebouncedQuery] = useState<string>(query); @@ -104,7 +104,7 @@ const SearchBar: React.FC = () => { {results.length > 0 && SearchResults} </div> ); -}; +}); export default SearchBar; diff --git a/src/components/Loading/Loading.tsx b/src/components/Loading/Loading.tsx new file mode 100644 index 0000000..34d436b --- /dev/null +++ b/src/components/Loading/Loading.tsx @@ -0,0 +1,24 @@ +import React from 'react'; +import CircularProgress from '@material-ui/core/CircularProgress'; +import { makeStyles } from '@material-ui/core'; + +const useStyles = makeStyles(theme => ({ + loader: { + width: '100%', + textAlign: 'center', + marginTop: theme.spacing(10) + } +})); + +const Loading: React.FC = React.memo(() => { + const classes = useStyles(); + + return ( + <div className={classes.loader}> + <CircularProgress color="primary" style={{ margin: '0 auto' }} /> + </div> + ); +}); + +export default Loading; + diff --git a/src/components/PollCard/PollCard.tsx b/src/components/PollCard/PollCard.tsx index 98ae001..689e872 100644 --- a/src/components/PollCard/PollCard.tsx +++ b/src/components/PollCard/PollCard.tsx @@ -1,4 +1,4 @@ -import React, { useState } from 'react'; +import React from 'react'; import { makeStyles } from '@material-ui/core/styles'; import { Card, @@ -14,7 +14,8 @@ import { post } from '../../requests'; import { useAuth } from '../../hooks/useAuth'; interface PropTypes { - initialPoll: Poll; + poll: Poll; + setPoll: (poll: Poll) => void; } const DATE_FORMAT = { @@ -49,8 +50,7 @@ const useStyles = makeStyles(theme => ({ } })); -const PollCard: React.FC<PropTypes> = ({ initialPoll }) => { - const [poll, setPoll] = useState<Poll>(initialPoll); +const PollCard: React.FC<PropTypes> = ({ poll, setPoll }) => { const classes = useStyles(); const { author, contents: { left, right }, vote } = poll; const { enqueueSnackbar } = useSnackbar(); @@ -58,7 +58,7 @@ const PollCard: React.FC<PropTypes> = ({ initialPoll }) => { const date: string = new Date(poll.createdAt).toLocaleString('default', DATE_FORMAT); const handleVote = (which: Which) => { - if (!isAuthenticated()) { + if (!isAuthenticated) { enqueueSnackbar('Unauthorized users can not vote in polls', { variant: 'error' }); @@ -68,15 +68,17 @@ const PollCard: React.FC<PropTypes> = ({ initialPoll }) => { }); } else { const newVote = ({ which, pollId: poll._id }); - post('votes/', newVote); - poll.contents[which].votes += 1; - poll.vote = { + const newPoll = { ...poll }; + newPoll.contents[which].votes += 1; + newPoll.vote = { _id: '', authorId: '', createdAt: new Date(), ...newVote }; - setPoll({ ...poll }); + setPoll(newPoll); + + post('votes/', newVote); } }; diff --git a/src/components/Feed/Feed.tsx b/src/components/PollsList/PollsList.tsx index 03358da..c95bfde 100644 --- a/src/components/Feed/Feed.tsx +++ b/src/components/PollsList/PollsList.tsx @@ -1,12 +1,12 @@ import React from 'react'; import { Poll } from 'which-types'; import { WindowScroller, AutoSizer, List } from 'react-virtualized'; -import CircularProgress from '@material-ui/core/CircularProgress'; -import { makeStyles } from '@material-ui/core'; import PollCard from '../PollCard/PollCard'; + interface PropTypes { polls: Poll[]; + mutate: (polls: Poll[], refetch: boolean) => void; } interface RenderPropTypes { @@ -15,34 +15,29 @@ interface RenderPropTypes { style: React.CSSProperties; } -const useStyles = makeStyles(theme => ({ - loader: { - width: '100%', - textAlign: 'center', - marginTop: theme.spacing(10) - } -})); - -const Feed: React.FC<PropTypes> = ({ polls }) => { - const classes = useStyles(); - +const PollsList: React.FC<PropTypes> = ({ polls, mutate }) => { const RenderItem: React.FC<RenderPropTypes> = ({ index, style, key }) => { const poll = polls[index]; + + const setPoll = (newPoll: Poll) => { + const newPolls = [...polls]; + newPolls[index] = newPoll; + + // Force-update list-size so everything re-renders + mutate([], false); + mutate(newPolls, false); + }; + return ( - <div key={key} style={style}> - <PollCard initialPoll={poll} /> + // To re-render on list resize, add this info to key + <div key={`${key}-${poll._id}-${polls.length}`} style={style}> + <PollCard poll={poll} setPoll={setPoll} /> </div> ); }; - const loader = ( - <div className={classes.loader}> - <CircularProgress color="primary" style={{ margin: '0 auto' }} /> - </div> - ); - - const list = ( + return ( <WindowScroller> {({ height, @@ -73,9 +68,7 @@ const Feed: React.FC<PropTypes> = ({ polls }) => { )} </WindowScroller> ); - - return polls.length ? list : loader; }; -export default Feed; +export default PollsList; diff --git a/src/components/ScrollTopArrow/ScrollTopArrow.tsx b/src/components/ScrollTopArrow/ScrollTopArrow.tsx index 08b8591..8a5bb8f 100644 --- a/src/components/ScrollTopArrow/ScrollTopArrow.tsx +++ b/src/components/ScrollTopArrow/ScrollTopArrow.tsx @@ -23,7 +23,7 @@ const useStyles = makeStyles(theme => ({ } })); -const ScrollTopArrow: React.FC = () => { +const ScrollTopArrow: React.FC = React.memo(() => { const [showScroll, setShowScroll] = useState(false); const theme = useTheme(); const classes = useStyles(); @@ -52,6 +52,6 @@ const ScrollTopArrow: React.FC = () => { } </div> ); -}; +}); export default ScrollTopArrow; |