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