From 237d16c273a47e68254f9fa76d3190d28a257ca6 Mon Sep 17 00:00:00 2001 From: eug-vs Date: Fri, 14 Aug 2020 23:04:33 +0300 Subject: feat: use BackgroundImage in PollCreation --- src/containers/PollCreation/ImageInput.tsx | 37 ++++++++++++++---------------- 1 file changed, 17 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/containers/PollCreation/ImageInput.tsx b/src/containers/PollCreation/ImageInput.tsx index cc60478..475d527 100644 --- a/src/containers/PollCreation/ImageInput.tsx +++ b/src/containers/PollCreation/ImageInput.tsx @@ -2,7 +2,6 @@ import React, { useState } from 'react'; import { makeStyles } from '@material-ui/core/styles'; import { CardActionArea, - CardMedia, Typography, CircularProgress } from '@material-ui/core'; @@ -10,6 +9,7 @@ import { Check, CancelOutlined } from '@material-ui/icons'; import AttachLink from '../../components/AttachLink/AttachLink'; import FileUpload from '../../components/FileUpload/FileUpload'; +import BackgroundImage from '../../components/Image/BackgroundImage'; interface PropTypes { callback: (file?: File | string) => void; @@ -28,19 +28,17 @@ const useStyles = makeStyles({ opacity: '.5', fontSize: 50 }, - media: { - height: '100%', - width: '100%', - display: 'flex', - justifyContent: 'center', - alignItems: 'center' - }, - darkOverlay: { + overlay: { backgroundColor: 'rgba(0, 0, 0, 0.45)', color: 'white', position: 'absolute', top: 0, left: 0, + height: '100%', + width: '100%', + display: 'flex', + justifyContent: 'center', + alignItems: 'center', transitionDuration: '0.5s' }, invisible: { @@ -76,17 +74,16 @@ const ImageInput: React.FC = ({ callback, progress }) => { const Media = ( - -
- { - progress - ? progress < 100 - ? - : - : - } -
-
+ +
+ { + progress + ? progress < 100 + ? + : + : + } +
); -- cgit v1.2.3 From bf47681e325e18edb3b5bfa4c655095189697e8b Mon Sep 17 00:00:00 2001 From: eug-vs Date: Sat, 15 Aug 2020 03:48:53 +0300 Subject: refactor: separate Message component --- src/components/EmptyState/EmptyState.tsx | 24 +++------------ src/components/Loading/Loading.tsx | 23 ++++++-------- src/components/Message/Message.tsx | 42 ++++++++++++++++++++++++++ src/containers/Notifications/Notifications.tsx | 2 +- 4 files changed, 56 insertions(+), 35 deletions(-) create mode 100644 src/components/Message/Message.tsx (limited to 'src') diff --git a/src/components/EmptyState/EmptyState.tsx b/src/components/EmptyState/EmptyState.tsx index 214bb56..f79a391 100644 --- a/src/components/EmptyState/EmptyState.tsx +++ b/src/components/EmptyState/EmptyState.tsx @@ -1,6 +1,7 @@ import React from 'react'; -import Typography from '@material-ui/core/Typography'; import { makeStyles } from '@material-ui/core/styles'; + +import Message from '../Message/Message'; import noContentIcon from '../../assets/noContent.svg'; import constructionIcon from '../../assets/construction.svg'; @@ -11,17 +12,9 @@ interface PropTypes { } const useStyles = makeStyles(theme => ({ - root: { - display: 'flex', - flexDirection: 'column', - justifyContent: 'center', - alignItems: 'center' - }, img: { - margin: theme.spacing(2), width: theme.spacing(24) } - })); const CONTEXT = { @@ -37,21 +30,12 @@ const CONTEXT = { const EmptyState: React.FC = ({ variant = 'default', message }) => { const classes = useStyles(); - const { icon, tagline } = CONTEXT[variant]; return ( -
+ No content - - {tagline} - - -

- {message} -

-
-
+ ); }; diff --git a/src/components/Loading/Loading.tsx b/src/components/Loading/Loading.tsx index 34d436b..fac0049 100644 --- a/src/components/Loading/Loading.tsx +++ b/src/components/Loading/Loading.tsx @@ -1,22 +1,17 @@ import React from 'react'; import CircularProgress from '@material-ui/core/CircularProgress'; -import { makeStyles } from '@material-ui/core'; +import Message from '../Message/Message'; -const useStyles = makeStyles(theme => ({ - loader: { - width: '100%', - textAlign: 'center', - marginTop: theme.spacing(10) - } -})); - -const Loading: React.FC = React.memo(() => { - const classes = useStyles(); +interface PropTypes { + tagline?: string; + message?: string; +} +const Loading: React.FC = React.memo(({ tagline, message }) => { return ( -
- -
+ + + ); }); diff --git a/src/components/Message/Message.tsx b/src/components/Message/Message.tsx new file mode 100644 index 0000000..f568552 --- /dev/null +++ b/src/components/Message/Message.tsx @@ -0,0 +1,42 @@ +import React from 'react'; +import Typography from '@material-ui/core/Typography'; +import { makeStyles } from '@material-ui/core/styles'; + + +interface PropTypes { + tagline?: string; + message?: string; +} + +const useStyles = makeStyles(theme => ({ + root: { + display: 'flex', + flexDirection: 'column', + justifyContent: 'center', + alignItems: 'center', + marginTop: theme.spacing(6) + }, + content: { + margin: theme.spacing(2) + } +})); + +const Message: React.FC = React.memo(({ tagline, message, children }) => { + const classes = useStyles(); + + return ( +
+
+ {children} +
+ + {tagline} + + + {message} + +
+ ); +}); + +export default Message; diff --git a/src/containers/Notifications/Notifications.tsx b/src/containers/Notifications/Notifications.tsx index 2a9ea13..655e7be 100644 --- a/src/containers/Notifications/Notifications.tsx +++ b/src/containers/Notifications/Notifications.tsx @@ -4,7 +4,7 @@ import EmptyState from '../../components/EmptyState/EmptyState'; const useStyles = makeStyles(theme => ({ root: { - marginTop: theme.spacing(25) + marginTop: theme.spacing(16) } })); -- cgit v1.2.3 From 5ca84ded5a1500ad3ea8d029b71488e8b3b74181 Mon Sep 17 00:00:00 2001 From: eug-vs Date: Sat, 15 Aug 2020 03:55:27 +0300 Subject: feat: ping server before showing content --- src/containers/Page/DynoWaiter.tsx | 64 ++++++++++++++++++++++++++++++++++++++ src/containers/Page/Page.tsx | 30 ++++++------------ src/containers/Page/Router.tsx | 27 ++++++++++++++++ 3 files changed, 100 insertions(+), 21 deletions(-) create mode 100644 src/containers/Page/DynoWaiter.tsx create mode 100644 src/containers/Page/Router.tsx (limited to 'src') diff --git a/src/containers/Page/DynoWaiter.tsx b/src/containers/Page/DynoWaiter.tsx new file mode 100644 index 0000000..d8460bf --- /dev/null +++ b/src/containers/Page/DynoWaiter.tsx @@ -0,0 +1,64 @@ +import React, { useEffect, useState, useCallback, useMemo } from 'react'; +import { makeStyles } from '@material-ui/core/styles'; +import { get } from '../../requests'; +import Loading from '../../components/Loading/Loading'; + +const DYNO_WAKEUP_TIME = 30; + +const messages = [ + '', + 'It looks like our server is sleeping.', + `We need about ${DYNO_WAKEUP_TIME} seconds to wake it up.`, + 'Please, stay with us.', + 'You are doing good.', + 'Almost done.' +]; + +const useStyles = makeStyles(theme => ({ + root: { + textAlign: 'center' + }, + hidden: { + visibility: 'hidden', + position: 'absolute' + } +})); + +const DynoWaiter: React.FC = ({ children }) => { + const classes = useStyles(); + const [isReady, setIsReady] = useState(false); + const [time, setTime] = useState(0); + + const tick = useCallback((): void => setTime(value => value + 1), [setTime]); + + useEffect(() => { + const interval = setInterval(tick, 1000); + get('/ping').then(() => { + setIsReady(true); + clearInterval(interval); + }); + return () => clearInterval(interval); + }, [setIsReady, tick]); + + const message = useMemo(() => { + const interval = DYNO_WAKEUP_TIME / messages.length; + const index = Math.floor(time / interval); + const lastIndex = messages.length - 1; + return messages[index > lastIndex ? lastIndex : index]; + }, [time]); + + const tagline = useMemo(() => time > 3 ? 'Waiting for the server' : '', [time]); + + return ( + <> + {!isReady && } +
+ {children} +
+ + ); +}; + + +export default DynoWaiter; + diff --git a/src/containers/Page/Page.tsx b/src/containers/Page/Page.tsx index 023d86e..475f76d 100644 --- a/src/containers/Page/Page.tsx +++ b/src/containers/Page/Page.tsx @@ -2,30 +2,24 @@ 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, useHistory } from 'react-router-dom'; -import Loading from '../../components/Loading/Loading'; +import { useHistory } from 'react-router-dom'; -const Profile = React.lazy(() => import('../Profile/Profile')); -const Feed = React.lazy(() => import('../Feed/Feed')); -const Login = React.lazy(() => import('../Login/Login')); -const Registration = React.lazy(() => import('../Registration/Registration')); -const Home = React.lazy(() => import('../Home/Home')); -const Notifications = React.lazy(() => import('../Notifications/Notifications')); -const PollCreation = React.lazy(() => import('../PollCreation/PollCreation')); +import Router from './Router'; +import DynoWaiter from './DynoWaiter'; +import Loading from '../../components/Loading/Loading'; const useStyles = makeStyles(theme => ({ root: { [theme.breakpoints.down('sm')]: { - margin: theme.spacing(10, 0, 12, 0) + padding: theme.spacing(10, 0, 12, 0) }, [theme.breakpoints.up('md')]: { - margin: theme.spacing(15, 5, 8, 5) + padding: theme.spacing(15, 5, 8, 5) } } })); - const Page: React.FC = () => { const classes = useStyles(); const theme = useTheme(); @@ -49,15 +43,9 @@ const Page: React.FC = () => { >
}> - - - - - - - - - + + +
diff --git a/src/containers/Page/Router.tsx b/src/containers/Page/Router.tsx new file mode 100644 index 0000000..7067eea --- /dev/null +++ b/src/containers/Page/Router.tsx @@ -0,0 +1,27 @@ +import React from 'react'; +import { Switch, Route } from 'react-router-dom'; + +const Profile = React.lazy(() => import('../Profile/Profile')); +const Feed = React.lazy(() => import('../Feed/Feed')); +const Login = React.lazy(() => import('../Login/Login')); +const Registration = React.lazy(() => import('../Registration/Registration')); +const Home = React.lazy(() => import('../Home/Home')); +const Notifications = React.lazy(() => import('../Notifications/Notifications')); +const PollCreation = React.lazy(() => import('../PollCreation/PollCreation')); + + +const Router: React.FC = React.memo(() => ( + + + + + + + + + +)); + + +export default Router; + -- cgit v1.2.3 From 3605a00b1399c4305ed54b65e500d8cfad35f5a7 Mon Sep 17 00:00:00 2001 From: eug-vs Date: Sat, 15 Aug 2020 05:03:51 +0300 Subject: feat: add illustration to DynoWaiter --- src/assets/coffeeBreak.svg | 1 + src/containers/Page/DynoWaiter.tsx | 31 +++++++++++++++++++++++++------ 2 files changed, 26 insertions(+), 6 deletions(-) create mode 100644 src/assets/coffeeBreak.svg (limited to 'src') diff --git a/src/assets/coffeeBreak.svg b/src/assets/coffeeBreak.svg new file mode 100644 index 0000000..9cb0aed --- /dev/null +++ b/src/assets/coffeeBreak.svg @@ -0,0 +1 @@ +coffee break \ No newline at end of file diff --git a/src/containers/Page/DynoWaiter.tsx b/src/containers/Page/DynoWaiter.tsx index d8460bf..05d269f 100644 --- a/src/containers/Page/DynoWaiter.tsx +++ b/src/containers/Page/DynoWaiter.tsx @@ -1,7 +1,15 @@ -import React, { useEffect, useState, useCallback, useMemo } from 'react'; +import React, { + useEffect, + useState, + useCallback, + useMemo +} from 'react'; import { makeStyles } from '@material-ui/core/styles'; import { get } from '../../requests'; import Loading from '../../components/Loading/Loading'; +import Image from '../../components/Image/Image'; +import Message from '../../components/Message/Message'; +import coffeIcon from '../../assets/coffeeBreak.svg'; const DYNO_WAKEUP_TIME = 30; @@ -10,7 +18,7 @@ const messages = [ 'It looks like our server is sleeping.', `We need about ${DYNO_WAKEUP_TIME} seconds to wake it up.`, 'Please, stay with us.', - 'You are doing good.', + 'We love you <3', 'Almost done.' ]; @@ -20,10 +28,18 @@ const useStyles = makeStyles(theme => ({ }, hidden: { visibility: 'hidden', - position: 'absolute' + position: 'absolute', + width: 0, + height: 0, + overflow: 'hidden' + }, + img: { + width: theme.spacing(24) } })); +// TODO: if Dyno is sleeping, use this time to pre-load pages + const DynoWaiter: React.FC = ({ children }) => { const classes = useStyles(); const [isReady, setIsReady] = useState(false); @@ -47,11 +63,14 @@ const DynoWaiter: React.FC = ({ children }) => { return messages[index > lastIndex ? lastIndex : index]; }, [time]); - const tagline = useMemo(() => time > 3 ? 'Waiting for the server' : '', [time]); - return ( <> - {!isReady && } + {!isReady && ( + <> + + {message && } + + )}
{children}
-- cgit v1.2.3 From f2ad02d1f2aa5acaac430148dadfd2abc9e671e0 Mon Sep 17 00:00:00 2001 From: eug-vs Date: Sat, 15 Aug 2020 05:04:26 +0300 Subject: refactor: get rid of unnecessary types --- src/hooks/APIClient.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/hooks/APIClient.ts b/src/hooks/APIClient.ts index f66ef2e..cf5d247 100644 --- a/src/hooks/APIClient.ts +++ b/src/hooks/APIClient.ts @@ -10,17 +10,17 @@ export const useUser = (username: string | null): Response => { return useSWR( username && `/users?username=${username}`, (url: string) => get(url).then(response => response.data[0]) - ) as Response; + ); }; export const useProfile = (id: string): Response => { - return useSWR(id && `/profiles/${id}`, fetcher) as Response; + return useSWR(id && `/profiles/${id}`, fetcher); }; export const useFeed = (): Response => { - return useSWR('/feed', fetcher, { revalidateOnFocus: false }) as Response; + return useSWR('/feed', fetcher, { revalidateOnFocus: false }); }; export const useFeedback = (): Response => { - return useSWR('/feedback', fetcher) as Response; + return useSWR('/feedback', fetcher); }; -- cgit v1.2.3