aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugene Sokolov <eug-vs@keemail.me>2020-10-09 00:30:59 +0300
committerGitHub <noreply@github.com>2020-10-09 00:30:59 +0300
commita5d0f3edcd5478c81262524cbfef8273a065df36 (patch)
tree48725733e1650fb11f59e4e8dd4f752950a26f72
parentbdb4d194307c9755c2083c1a11bb876abebcb6de (diff)
parent8e9245d18ba591e93dd7dd1de9a271d0b51941a7 (diff)
downloadwhich-ui-a5d0f3edcd5478c81262524cbfef8273a065df36.tar.gz
Merge pull request #103 from which-ecosystem/feat/description
Add description to Poll Model
-rw-r--r--package-lock.json8
-rw-r--r--package.json4
-rw-r--r--src/components/ModalScreen/ModalScreen.tsx4
-rw-r--r--src/components/PollCard/PollCard.tsx12
-rw-r--r--src/components/PollsList/PollsList.tsx20
-rw-r--r--src/components/PollsList/RenderItem.tsx31
-rw-r--r--src/containers/Page/Page.tsx3
-rw-r--r--src/containers/PollCreation/PollCreation.tsx39
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