From d7aba191cdfbf6f2f5e35bcaa94e011fafcde3dc Mon Sep 17 00:00:00 2001 From: eug-vs Date: Thu, 13 Aug 2020 23:55:35 +0300 Subject: feat: scroll to top on redirects --- src/containers/Page/Page.tsx | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/containers/Page/Page.tsx b/src/containers/Page/Page.tsx index 848ca1d..c876dae 100644 --- a/src/containers/Page/Page.tsx +++ b/src/containers/Page/Page.tsx @@ -1,8 +1,8 @@ -import React, { Suspense } from 'react'; +import React, { Suspense, useEffect } from 'react'; import { makeStyles, useTheme } from '@material-ui/core/styles'; import { useMediaQuery } from '@material-ui/core'; import { SnackbarProvider } from 'notistack'; -import { Switch, Route } from 'react-router-dom'; +import { Switch, Route, useHistory } from 'react-router-dom'; import Loading from '../../components/Loading/Loading'; const Profile = React.lazy(() => import('../Profile/Profile')); @@ -29,8 +29,15 @@ const useStyles = makeStyles(theme => ({ const Page: React.FC = () => { const classes = useStyles(); const theme = useTheme(); + const history = useHistory(); const isMobile = useMediaQuery(theme.breakpoints.down('sm')); + useEffect(() => { + return history.listen(() => { + window.scrollTo(0, 0); + }); + }, [history]) + return ( Date: Fri, 14 Aug 2020 01:25:56 +0300 Subject: refactor: add useS3Preupload hook --- src/containers/PollCreation/PollCreation.tsx | 46 ++++++++++++-------------- src/hooks/useS3Preupload.tsx | 48 ++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+), 26 deletions(-) create mode 100644 src/hooks/useS3Preupload.tsx diff --git a/src/containers/PollCreation/PollCreation.tsx b/src/containers/PollCreation/PollCreation.tsx index 64ab7fd..e613afd 100644 --- a/src/containers/PollCreation/PollCreation.tsx +++ b/src/containers/PollCreation/PollCreation.tsx @@ -1,4 +1,4 @@ -import React, { useState } from 'react'; +import React from 'react'; import { useHistory } from 'react-router-dom'; import { makeStyles } from '@material-ui/core/styles'; import { @@ -8,13 +8,14 @@ import { Container } from '@material-ui/core'; import { useSnackbar } from 'notistack'; -import axios from 'axios'; import PollCreationImage from './PollCreationImage'; import UserStrip from '../../components/UserStrip/UserStrip'; -import { get, post } from '../../requests'; +import { post } from '../../requests'; import { useAuth } from '../../hooks/useAuth'; import { useFeed } from '../../hooks/APIClient'; +import useS3Preupload from '../../hooks/useS3Preupload'; + const useStyles = makeStyles(theme => ({ root: { @@ -26,36 +27,29 @@ const useStyles = makeStyles(theme => ({ } })); + const PollCreation: React.FC = () => { const classes = useStyles(); const history = useHistory(); - const [left, setLeft] = useState(); - const [right, setRight] = useState(); const { enqueueSnackbar } = useSnackbar(); const { user } = useAuth(); const { mutate: updateFeed } = useFeed(); - - const readyToSubmit = left && right; - - const uploadFile = (file: File): Promise => { - const headers = { 'Content-Type': 'image/png' }; - return get('/files') - .then(response => response.data) - .then(uploadUrl => axios.put(uploadUrl, file, { headers })) - .then(response => { - const { config: { url } } = response; - return url?.slice(0, url?.indexOf('?')) || ''; - }); - }; - - const resolveFile = async (file?: File | string): Promise => { - if (file instanceof File) return uploadFile(file); - return file || ''; - }; + const { + setValue: setLeft, + progress: progressLeft, + resolve: resolveLeft, + isReady: isLeftReady + } = useS3Preupload(); + const { + setValue: setRight, + progress: progressRight, + resolve: resolveRight, + isReady: isRightReady + } = useS3Preupload(); const handleClick = async () => { - if (readyToSubmit) { - const [leftUrl, rightUrl] = await Promise.all([resolveFile(left), resolveFile(right)]); + if (isLeftReady && isRightReady) { + const [leftUrl, rightUrl] = await Promise.all([resolveLeft(), resolveRight()]); const contents = { left: { url: leftUrl }, @@ -84,7 +78,7 @@ const PollCreation: React.FC = () => { diff --git a/src/containers/PollCreation/PollCreationImage.tsx b/src/containers/PollCreation/PollCreationImage.tsx index 1200b11..d619a8e 100644 --- a/src/containers/PollCreation/PollCreationImage.tsx +++ b/src/containers/PollCreation/PollCreationImage.tsx @@ -3,15 +3,17 @@ import { makeStyles } from '@material-ui/core/styles'; import { CardActionArea, CardMedia, - Typography + Typography, + CircularProgress } from '@material-ui/core'; -import ClearIcon from '@material-ui/icons/CancelOutlined'; +import { Check, CancelOutlined } from '@material-ui/icons'; import AttachLink from '../../components/AttachLink/AttachLink'; import FileUpload from '../../components/FileUpload/FileUpload'; interface PropTypes { callback: (file?: File | string) => void; + progress?: number; } const useStyles = makeStyles({ @@ -32,11 +34,25 @@ const useStyles = makeStyles({ display: 'flex', justifyContent: 'center', alignItems: 'center' + }, + darkOverlay: { + backgroundColor: 'rgba(0, 0, 0, 0.45)', + color: 'white', + position: 'absolute', + top: 0, + left: 0, + transitionDuration: '0.5s' + }, + invisible: { + backgroundColor: 'rgba(0, 0, 0, 0)', + }, + icon: { + color: 'white' } }); -const PollCreationImage: React.FC = ({ callback }) => { +const PollCreationImage: React.FC = ({ callback, progress }) => { const classes = useStyles(); const [url, setUrl] = useState(); @@ -59,9 +75,17 @@ const PollCreationImage: React.FC = ({ callback }) => { ); const Media = ( - + - +
+ { + progress + ? progress < 100 + ? + : + : + } +
); diff --git a/src/hooks/useS3Preupload.tsx b/src/hooks/useS3Preupload.tsx index aeb1d65..64db942 100644 --- a/src/hooks/useS3Preupload.tsx +++ b/src/hooks/useS3Preupload.tsx @@ -41,7 +41,10 @@ export default () => { const { config: { url } } = response; return url ? url.slice(0, url.indexOf('?')) : ''; }); - } else return url || ''; + } else { + setProgress(100); + return url || ''; + } }, [file, handleUploadProgress, url]); return { setValue, isReady, resolve, progress }; -- cgit v1.2.3 From fca54f49bb3541f726da1becffaa60197835ca68 Mon Sep 17 00:00:00 2001 From: eug-vs Date: Fri, 14 Aug 2020 02:45:20 +0300 Subject: refactor: resolve eslint errors --- package-lock.json | 2 +- package.json | 2 +- src/containers/Page/Page.tsx | 6 +- src/containers/PollCreation/ImageInput.tsx | 96 +++++++++++++++++++++++ src/containers/PollCreation/PollCreation.tsx | 33 +++++--- src/containers/PollCreation/PollCreationImage.tsx | 96 ----------------------- src/containers/PollCreation/types.ts | 7 -- src/hooks/useS3Preupload.tsx | 39 ++++++--- 8 files changed, 147 insertions(+), 134 deletions(-) create mode 100644 src/containers/PollCreation/ImageInput.tsx delete mode 100644 src/containers/PollCreation/PollCreationImage.tsx delete mode 100644 src/containers/PollCreation/types.ts diff --git a/package-lock.json b/package-lock.json index c01707b..d0b962b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "which", - "version": "1.1.0", + "version": "1.2.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index a18e64d..c2d414f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "which", - "version": "1.1.0", + "version": "1.2.0", "homepage": "https://which-ecosystem.github.io/", "dependencies": { "@material-ui/core": "^4.10.1", diff --git a/src/containers/Page/Page.tsx b/src/containers/Page/Page.tsx index c876dae..023d86e 100644 --- a/src/containers/Page/Page.tsx +++ b/src/containers/Page/Page.tsx @@ -1,4 +1,4 @@ -import React, { Suspense, useEffect } from 'react'; +import React, { Suspense, useEffect } from 'react'; import { makeStyles, useTheme } from '@material-ui/core/styles'; import { useMediaQuery } from '@material-ui/core'; import { SnackbarProvider } from 'notistack'; @@ -17,7 +17,7 @@ const PollCreation = React.lazy(() => import('../PollCreation/PollCreation')); const useStyles = makeStyles(theme => ({ root: { [theme.breakpoints.down('sm')]: { - margin: theme.spacing(12, 0, 12, 0) + margin: theme.spacing(10, 0, 12, 0) }, [theme.breakpoints.up('md')]: { margin: theme.spacing(15, 5, 8, 5) @@ -36,7 +36,7 @@ const Page: React.FC = () => { return history.listen(() => { window.scrollTo(0, 0); }); - }, [history]) + }, [history]); return ( void; + progress?: number; +} + +const useStyles = makeStyles({ + root: { + display: 'flex', + justifyContent: 'center', + flexDirection: 'column', + alignItems: 'center', + width: '50%' + }, + clearIcon: { + opacity: '.5', + fontSize: 50 + }, + media: { + height: '100%', + width: '100%', + display: 'flex', + justifyContent: 'center', + alignItems: 'center' + }, + darkOverlay: { + backgroundColor: 'rgba(0, 0, 0, 0.45)', + color: 'white', + position: 'absolute', + top: 0, + left: 0, + transitionDuration: '0.5s' + }, + invisible: { + backgroundColor: 'rgba(0, 0, 0, 0)' + }, + icon: { + color: 'white' + } +}); + + +const ImageInput: React.FC = ({ callback, progress }) => { + const classes = useStyles(); + const [url, setUrl] = useState(); + + const handleClear = (): void => { + setUrl(undefined); + callback(undefined); + }; + + const childrenCallback = (fileUrl: string, file?: File) => { + setUrl(fileUrl); + callback(file || fileUrl); + }; + + const Upload = ( +
+ + or + +
+ ); + + const Media = ( + + +
+ { + progress + ? progress < 100 + ? + : + : + } +
+
+
+ ); + + return url ? Media : Upload; +}; + +export default ImageInput; diff --git a/src/containers/PollCreation/PollCreation.tsx b/src/containers/PollCreation/PollCreation.tsx index e350179..107314a 100644 --- a/src/containers/PollCreation/PollCreation.tsx +++ b/src/containers/PollCreation/PollCreation.tsx @@ -5,11 +5,12 @@ import { Button, Card, Divider, - Container + Container, + LinearProgress } from '@material-ui/core'; import { useSnackbar } from 'notistack'; -import PollCreationImage from './PollCreationImage'; +import ImageInput from './ImageInput'; import UserStrip from '../../components/UserStrip/UserStrip'; import { post } from '../../requests'; import { useAuth } from '../../hooks/useAuth'; @@ -73,18 +74,24 @@ const PollCreation: React.FC = () => { {user && }
- - + +
- + { + progressLeft || progressRight + ? + : ( + + ) + } ); diff --git a/src/containers/PollCreation/PollCreationImage.tsx b/src/containers/PollCreation/PollCreationImage.tsx deleted file mode 100644 index d619a8e..0000000 --- a/src/containers/PollCreation/PollCreationImage.tsx +++ /dev/null @@ -1,96 +0,0 @@ -import React, { useState } from 'react'; -import { makeStyles } from '@material-ui/core/styles'; -import { - CardActionArea, - CardMedia, - Typography, - CircularProgress -} from '@material-ui/core'; -import { Check, CancelOutlined } from '@material-ui/icons'; - -import AttachLink from '../../components/AttachLink/AttachLink'; -import FileUpload from '../../components/FileUpload/FileUpload'; - -interface PropTypes { - callback: (file?: File | string) => void; - progress?: number; -} - -const useStyles = makeStyles({ - root: { - display: 'flex', - justifyContent: 'center', - flexDirection: 'column', - alignItems: 'center', - width: '50%' - }, - clearIcon: { - opacity: '.5', - fontSize: 50 - }, - media: { - height: '100%', - width: '100%', - display: 'flex', - justifyContent: 'center', - alignItems: 'center' - }, - darkOverlay: { - backgroundColor: 'rgba(0, 0, 0, 0.45)', - color: 'white', - position: 'absolute', - top: 0, - left: 0, - transitionDuration: '0.5s' - }, - invisible: { - backgroundColor: 'rgba(0, 0, 0, 0)', - }, - icon: { - color: 'white' - } -}); - - -const PollCreationImage: React.FC = ({ callback, progress }) => { - const classes = useStyles(); - const [url, setUrl] = useState(); - - const handleClear = (): void => { - setUrl(undefined); - callback(undefined); - }; - - const childrenCallback = (fileUrl: string, file?: File) => { - setUrl(fileUrl); - callback(file || fileUrl); - }; - - const Upload = ( -
- - or - -
- ); - - const Media = ( - - -
- { - progress - ? progress < 100 - ? - : - : - } -
-
-
- ); - - return url ? Media : Upload; -}; - -export default PollCreationImage; diff --git a/src/containers/PollCreation/types.ts b/src/containers/PollCreation/types.ts deleted file mode 100644 index 24ace4e..0000000 --- a/src/containers/PollCreation/types.ts +++ /dev/null @@ -1,7 +0,0 @@ -export interface ImageData { - url: string; -} -export interface Contents { - left: ImageData; - right: ImageData; -} diff --git a/src/hooks/useS3Preupload.tsx b/src/hooks/useS3Preupload.tsx index 64db942..3c98e9a 100644 --- a/src/hooks/useS3Preupload.tsx +++ b/src/hooks/useS3Preupload.tsx @@ -1,19 +1,28 @@ import { useState, useCallback, useMemo } from 'react'; -import { get } from '../requests'; import axios from 'axios'; +import { get } from '../requests'; + + +interface ProgressEvent { + loaded: number; + total: number; +} +interface Hook { + setValue: (value: File | string | undefined) => void; + isReady: boolean; + resolve: () => Promise; + progress: number; +} -export default () => { +export default (): Hook => { const [url, setUrl] = useState(); const [file, setFile] = useState(); const [progress, setProgress] = useState(0); const isReady = useMemo(() => Boolean(file || url), [file, url]); - - console.log({ file, url }) - - const setValue = useCallback((value: File | string | undefined): void => { + const setValue: Hook['setValue'] = useCallback(value => { if (value instanceof File) { setFile(value); setUrl(undefined); @@ -23,7 +32,7 @@ export default () => { } }, [setUrl, setFile]); - const handleUploadProgress = useCallback((progressEvent: any) => { + const handleUploadProgress = useCallback((progressEvent: ProgressEvent): void => { setProgress(Math.round((progressEvent.loaded * 100) / progressEvent.total)); }, [setProgress]); @@ -38,14 +47,18 @@ export default () => { .then(response => response.data) .then(uploadUrl => axios.put(uploadUrl, file, config)) .then(response => { - const { config: { url } } = response; - return url ? url.slice(0, url.indexOf('?')) : ''; + const uri = response.config.url; + return uri ? uri.slice(0, uri.indexOf('?')) : ''; }); - } else { - setProgress(100); - return url || ''; } + setProgress(100); + return url || ''; }, [file, handleUploadProgress, url]); - return { setValue, isReady, resolve, progress }; + return { + setValue, + isReady, + resolve, + progress + }; }; -- cgit v1.2.3