diff options
author | Eugene Sokolov <eug-vs@keemail.me> | 2020-10-09 00:30:59 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-10-09 00:30:59 +0300 |
commit | a5d0f3edcd5478c81262524cbfef8273a065df36 (patch) | |
tree | 48725733e1650fb11f59e4e8dd4f752950a26f72 | |
parent | bdb4d194307c9755c2083c1a11bb876abebcb6de (diff) | |
parent | 8e9245d18ba591e93dd7dd1de9a271d0b51941a7 (diff) | |
download | which-ui-a5d0f3edcd5478c81262524cbfef8273a065df36.tar.gz |
Merge pull request #103 from which-ecosystem/feat/description
Add description to Poll Model
-rw-r--r-- | package-lock.json | 8 | ||||
-rw-r--r-- | package.json | 4 | ||||
-rw-r--r-- | src/components/ModalScreen/ModalScreen.tsx | 4 | ||||
-rw-r--r-- | src/components/PollCard/PollCard.tsx | 12 | ||||
-rw-r--r-- | src/components/PollsList/PollsList.tsx | 20 | ||||
-rw-r--r-- | src/components/PollsList/RenderItem.tsx | 31 | ||||
-rw-r--r-- | src/containers/Page/Page.tsx | 3 | ||||
-rw-r--r-- | src/containers/PollCreation/PollCreation.tsx | 39 |
8 files changed, 93 insertions, 28 deletions
diff --git a/package-lock.json b/package-lock.json index e25fb85..86992bb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "which", - "version": "1.2.5", + "version": "1.2.6", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -14429,9 +14429,9 @@ "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" }, "which-types": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/which-types/-/which-types-1.6.1.tgz", - "integrity": "sha512-uTCrp6+rbU48kyT9Z6upVo9CgGmiR50zFSwzDik8slE8oZ+0FC9SBEfJlfgADX/rFJVbIe8Vxsw4BsSxlL5Lsw==" + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/which-types/-/which-types-1.6.2.tgz", + "integrity": "sha512-+OAaJtZsqJab9YohByErzVqxWTsl/JvZ6AVpz7a0WrPEQHapv0aoA0RZIu1zrfSBFhAQLSJmw4fyvfqUvViO5g==" }, "word-wrap": { "version": "1.2.3", diff --git a/package.json b/package.json index 2bb2500..6f0bc12 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "which", - "version": "1.2.5", + "version": "1.2.6", "homepage": "https://which-ecosystem.github.io/", "dependencies": { "@material-ui/core": "^4.10.1", @@ -21,7 +21,7 @@ "react-virtualized": "^9.21.2", "swr": "^0.3.0", "typeface-roboto": "0.0.75", - "which-types": "^1.6.1", + "which-types": "^1.6.2", "yup": "^0.29.3" }, "scripts": { diff --git a/src/components/ModalScreen/ModalScreen.tsx b/src/components/ModalScreen/ModalScreen.tsx index c6f0565..cf76272 100644 --- a/src/components/ModalScreen/ModalScreen.tsx +++ b/src/components/ModalScreen/ModalScreen.tsx @@ -27,7 +27,9 @@ const useStyles = makeStyles(theme => ({ backgroundColor: theme.palette.background.default }, content: { - padding: theme.spacing(6, 0) + [theme.breakpoints.up('md')]: { + padding: theme.spacing(4) + } }, toolbar: { display: 'flex', diff --git a/src/components/PollCard/PollCard.tsx b/src/components/PollCard/PollCard.tsx index 540679f..a06bad8 100644 --- a/src/components/PollCard/PollCard.tsx +++ b/src/components/PollCard/PollCard.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { makeStyles } from '@material-ui/core/styles'; -import { Card, CardActionArea } from '@material-ui/core/'; +import { Card, CardActionArea, Typography } from '@material-ui/core/'; import { Which, Poll } from 'which-types'; import { useSnackbar } from 'notistack'; @@ -42,6 +42,11 @@ const useStyles = makeStyles(theme => ({ height: theme.spacing(2), backgroundColor: theme.palette.primary.light, transitionDuration: '0.5s' + }, + description: { + padding: theme.spacing(1, 2), + wordWrap: 'break-word', + whiteSpace: 'pre-wrap' } })); @@ -93,6 +98,11 @@ const PollCard: React.FC<PropTypes> = React.memo(({ poll, setPoll }) => { return ( <Card elevation={3}> <UserStrip user={author} info={date} /> + {poll.description && ( + <Typography className={classes.description}> + {poll.description} + </Typography> + )} <div className={classes.media}> <CardActionArea onDoubleClick={handleVote('left')} className={classes.media}> <BackgroundImage src={left.url} /> diff --git a/src/components/PollsList/PollsList.tsx b/src/components/PollsList/PollsList.tsx index 039639d..1ad7763 100644 --- a/src/components/PollsList/PollsList.tsx +++ b/src/components/PollsList/PollsList.tsx @@ -1,9 +1,10 @@ -import React, { useCallback, useState, useMemo } from 'react'; +import React, { useCallback, useState, useMemo, useEffect } from 'react'; import { WindowScroller, AutoSizer, List, - InfiniteLoader + InfiniteLoader, + CellMeasurerCache } from 'react-virtualized'; import _ from 'lodash'; import { Poll } from 'which-types'; @@ -15,17 +16,27 @@ interface PropTypes { mutate: (polls: Poll[], refetch: boolean) => void; } +const cache = new CellMeasurerCache({ + fixedWidth: true +}); + const PAGE_SIZE = 10; const PollsList: React.FC<PropTypes> = ({ polls, mutate }) => { const [displayCount, setDisplayCount] = useState<number>(PAGE_SIZE); - const rowRenderer = useCallback(({ index, style, key }) => ( + useEffect(() => { + cache.clearAll(); + }, [polls]); + + const rowRenderer = useCallback(({ index, style, key, parent }) => ( <RenderItem polls={polls} mutate={mutate} index={index} style={style} + cache={cache} + parent={parent} key={key} _key={key} /> @@ -68,7 +79,7 @@ const PollsList: React.FC<PropTypes> = ({ polls, mutate }) => { isScrolling={isScrolling} onScroll={onChildScroll} rowCount={rowCount} - rowHeight={550} + rowHeight={cache.rowHeight} rowRenderer={rowRenderer} scrollTop={scrollTop} width={width} @@ -76,6 +87,7 @@ const PollsList: React.FC<PropTypes> = ({ polls, mutate }) => { overscanRowCount={2} onRowsRendered={onRowsRendered} ref={ref} + deferredMeasurementCache={cache} /> )} </InfiniteLoader> diff --git a/src/components/PollsList/RenderItem.tsx b/src/components/PollsList/RenderItem.tsx index beed259..28411ec 100644 --- a/src/components/PollsList/RenderItem.tsx +++ b/src/components/PollsList/RenderItem.tsx @@ -1,5 +1,7 @@ import React, { useCallback } from 'react'; +import { makeStyles } from '@material-ui/core/styles'; import { Poll } from 'which-types'; +import { CellMeasurer, CellMeasurerCache, List } from 'react-virtualized'; import PollCard from '../PollCard/PollCard'; @@ -8,23 +10,31 @@ interface PropTypes { mutate: (polls: Poll[], refetch: boolean) => void; index: number; style: React.CSSProperties; + cache: CellMeasurerCache; + parent: List; _key: string; // https://reactjs.org/warnings/special-props.html } +const useStyles = makeStyles(theme => ({ + root: { + paddingBottom: theme.spacing(8) + } +})); + const compareProps = (oldProps: PropTypes, newProps: PropTypes) => { if (oldProps._key !== newProps._key) return false; if (oldProps.index !== newProps.index) return false; if (oldProps.polls !== newProps.polls) return false; - // TODO: uncomment line below to listen to style updates - // if (JSON.stringify(oldProps.style)!== JSON.stringify(newProps.style)) return false; + // Only listen for height changes in style + if (oldProps.style.height !== newProps.style.height) return false; return true; }; const RenderItem: React.FC<PropTypes> = React.memo(({ - polls, mutate, index, style, _key + polls, mutate, index, style, cache, parent, _key }) => { + const classes = useStyles(); const poll = polls[index]; - const setPoll = useCallback((newPoll: Poll) => { const newPolls = [...polls]; newPolls[index] = newPoll; @@ -35,9 +45,16 @@ const RenderItem: React.FC<PropTypes> = React.memo(({ }, [mutate, index, polls]); return ( - <div key={`${_key}-${poll._id}`} style={style}> - <PollCard poll={poll} setPoll={setPoll} /> - </div> + <CellMeasurer + cache={cache} + columnIndex={0} + rowIndex={index} + parent={parent} + > + <div key={`${_key}-${poll._id}`} className={classes.root} style={style}> + <PollCard poll={poll} setPoll={setPoll} /> + </div> + </CellMeasurer> ); }, compareProps); diff --git a/src/containers/Page/Page.tsx b/src/containers/Page/Page.tsx index e60f7da..9a904a4 100644 --- a/src/containers/Page/Page.tsx +++ b/src/containers/Page/Page.tsx @@ -17,7 +17,8 @@ const useStyles = makeStyles(theme => ({ }, [theme.breakpoints.up('md')]: { padding: theme.spacing(15, 5, 8, 5) - } + }, + backgroundColor: 'whitesmoke' } })); diff --git a/src/containers/PollCreation/PollCreation.tsx b/src/containers/PollCreation/PollCreation.tsx index 68f41d2..2e2bd06 100644 --- a/src/containers/PollCreation/PollCreation.tsx +++ b/src/containers/PollCreation/PollCreation.tsx @@ -1,7 +1,7 @@ -import React from 'react'; +import React, { ChangeEvent, useState, useMemo } from 'react'; import Bluebird from 'bluebird'; import { makeStyles } from '@material-ui/core/styles'; -import { Card, Container, LinearProgress } from '@material-ui/core'; +import { Card, Container, LinearProgress, InputBase, Typography } from '@material-ui/core'; import SendIcon from '@material-ui/icons/Send'; import { useSnackbar } from 'notistack'; @@ -19,14 +19,22 @@ const useStyles = makeStyles(theme => ({ images: { height: theme.spacing(50), display: 'flex' + }, + textarea: { + width: '100%', + height: 100 + }, + description: { + padding: theme.spacing(1, 2) } })); const PollCreation: React.FC = () => { + const [description, setDescription] = useState<string>(''); const classes = useStyles(); - const { user } = useAuth(); const { enqueueSnackbar } = useSnackbar(); + const { user } = useAuth(); const { mutate: updateFeed } = useFeed(); const { mutate: updateProfile } = useProfile(user?.username || ''); const { @@ -42,16 +50,19 @@ const PollCreation: React.FC = () => { progress: rightProgress } = useS3Preupload(); + const handleDescriptionChange = (e: ChangeEvent<HTMLTextAreaElement|HTMLInputElement>) => { + setDescription(e.target.value); + }; + const handleSubmit = async () => { try { const [leftUrl, rightUrl] = await Bluebird.all([resolveLeft(), resolveRight()]); - const contents = { left: { url: leftUrl }, right: { url: rightUrl } }; - post('/polls/', { contents }).then(() => { + post('/polls/', { contents, description }).then(() => { updateFeed(); updateProfile(); enqueueSnackbar('Your poll has been successfully created!', { variant: 'success' }); @@ -61,22 +72,34 @@ const PollCreation: React.FC = () => { } }; + const isSubmitting = useMemo(() => leftProgress + rightProgress > 0, [leftProgress, rightProgress]); + return ( <ModalScreen title="Create a poll" actionIcon={<SendIcon />} handleAction={handleSubmit} - isActionDisabled={!(left && right) || leftProgress > 0 || rightProgress > 0} + isActionDisabled={!(left && right) || isSubmitting} > <Container maxWidth="sm" disableGutters> <Card elevation={3}> - {user && <UserStrip user={user} info="" />} + {user && <UserStrip user={user} />} + <Typography> + <InputBase + multiline + fullWidth + placeholder="Add description" + onChange={handleDescriptionChange} + className={classes.description} + readOnly={isSubmitting} + /> + </Typography> <div className={classes.images}> <ImageInput callback={setLeft} progress={leftProgress} /> <ImageInput callback={setRight} progress={rightProgress} /> </div> </Card> - {(leftProgress > 0 || rightProgress > 0) && ( + {isSubmitting && ( <> <LinearProgress color="primary" /> <Message |