renamed Spinner.tsx to Loading.tsx, changed loading screen design, chagned emphasis on IE not supported message, and added loading page
This commit is contained in:
parent
bc10d33cb2
commit
9f6ee2d95c
4 changed files with 205 additions and 179 deletions
|
@ -14,7 +14,7 @@ import "katex/dist/katex.min.css" // latex mathematical expression
|
||||||
|
|
||||||
import theming from "./theming"
|
import theming from "./theming"
|
||||||
|
|
||||||
import Spinner from "./components/Spinner"
|
import Loading from "./components/Loading"
|
||||||
import Navbar from "./components/Navbar"
|
import Navbar from "./components/Navbar"
|
||||||
import Footer from "./components/Footer"
|
import Footer from "./components/Footer"
|
||||||
|
|
||||||
|
@ -245,10 +245,9 @@ const IENotSupported = styled.p`
|
||||||
`
|
`
|
||||||
|
|
||||||
const StyledContentContainer = styled.div`
|
const StyledContentContainer = styled.div`
|
||||||
display: inline-block;
|
|
||||||
flex: 1 1 auto;
|
flex: 1 1 auto;
|
||||||
margin-bottom: 3rem;
|
margin-bottom: 3rem;
|
||||||
margin-top: 3rem;
|
margin-top: 5rem;
|
||||||
`
|
`
|
||||||
|
|
||||||
interface AppProps {}
|
interface AppProps {}
|
||||||
|
@ -299,13 +298,11 @@ export default class App extends React.Component<AppProps, AppState> {
|
||||||
render() {
|
render() {
|
||||||
if (isIE)
|
if (isIE)
|
||||||
return (
|
return (
|
||||||
<>
|
|
||||||
<IENotSupported>
|
<IENotSupported>
|
||||||
<b>Internet Explorer</b> is not supported.
|
Internet Explorer is <b>not supported.</b>
|
||||||
</IENotSupported>
|
</IENotSupported>
|
||||||
</>
|
|
||||||
)
|
)
|
||||||
else
|
|
||||||
return (
|
return (
|
||||||
<HelmetProvider>
|
<HelmetProvider>
|
||||||
<ThemeProvider
|
<ThemeProvider
|
||||||
|
@ -316,10 +313,7 @@ export default class App extends React.Component<AppProps, AppState> {
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Helmet>
|
<Helmet>
|
||||||
<meta
|
<meta property="og:site_name" content="developomp" />
|
||||||
property="og:site_name"
|
|
||||||
content="developomp"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<meta property="og:title" content="Home" />
|
<meta property="og:title" content="Home" />
|
||||||
|
|
||||||
|
@ -338,13 +332,17 @@ export default class App extends React.Component<AppProps, AppState> {
|
||||||
<Navbar />
|
<Navbar />
|
||||||
<StyledContentContainer>
|
<StyledContentContainer>
|
||||||
{this.state.isLoading ? (
|
{this.state.isLoading ? (
|
||||||
<Spinner size={200} />
|
<Loading />
|
||||||
) : (
|
) : (
|
||||||
<Switch>
|
<Switch>
|
||||||
<Route exact path="/">
|
<Route exact path="/">
|
||||||
<PostList howMany={4} title="Home" />
|
<PostList howMany={4} title="Home" />
|
||||||
</Route>
|
</Route>
|
||||||
|
|
||||||
|
<Route exact path="/loading">
|
||||||
|
<Loading />
|
||||||
|
</Route>
|
||||||
|
|
||||||
<Route exact path="/search">
|
<Route exact path="/search">
|
||||||
<Search />
|
<Search />
|
||||||
</Route>
|
</Route>
|
||||||
|
|
144
source/src/components/Loading.tsx
Normal file
144
source/src/components/Loading.tsx
Normal file
|
@ -0,0 +1,144 @@
|
||||||
|
/**
|
||||||
|
* inspired by https://codepen.io/avstorm/pen/RwNzPNN
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React from "react"
|
||||||
|
import styled, { keyframes } from "styled-components"
|
||||||
|
import theming from "../theming"
|
||||||
|
|
||||||
|
const swing = keyframes`
|
||||||
|
50% {
|
||||||
|
transform: rotate(-3deg);
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
const steamLarge = keyframes`
|
||||||
|
0% {
|
||||||
|
stroke-dashoffset: 13;
|
||||||
|
opacity: .6;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
stroke-dashoffset: 39;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
const steamSmall = keyframes`
|
||||||
|
10% {
|
||||||
|
stroke-dashoffset: 9;
|
||||||
|
opacity: .6;
|
||||||
|
}
|
||||||
|
80% {
|
||||||
|
stroke-dashoffset: 27;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
stroke-dashoffset: 27;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
const StyledContainer = styled.div`
|
||||||
|
text-align: center;
|
||||||
|
animation: fadein 2s;
|
||||||
|
|
||||||
|
@keyframes fadein {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
const StyledBox = styled.div`
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
`
|
||||||
|
|
||||||
|
const StyledSVG = styled.svg`
|
||||||
|
--secondary: ${(props) =>
|
||||||
|
theming.theme(props.theme.currentTheme, {
|
||||||
|
light: theming.light.color1,
|
||||||
|
dark: theming.dark.color1,
|
||||||
|
})};
|
||||||
|
|
||||||
|
transform: scale(1.5);
|
||||||
|
|
||||||
|
#teabag {
|
||||||
|
transform-origin: top center;
|
||||||
|
transform: rotate(3deg);
|
||||||
|
animation: ${swing} 2s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
#steamL {
|
||||||
|
stroke-dasharray: 13;
|
||||||
|
stroke-dashoffset: 13;
|
||||||
|
animation: ${steamLarge} 2s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
#steamR {
|
||||||
|
stroke-dasharray: 9;
|
||||||
|
stroke-dashoffset: 9;
|
||||||
|
animation: ${steamSmall} 2s infinite;
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
const Spinner: React.FC = () => {
|
||||||
|
return (
|
||||||
|
<StyledContainer className="card main-content">
|
||||||
|
<StyledBox>
|
||||||
|
<StyledSVG
|
||||||
|
width="37"
|
||||||
|
height="48"
|
||||||
|
viewBox="0 0 37 48"
|
||||||
|
fill="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M27.0819 17H3.02508C1.91076 17 1.01376 17.9059 1.0485 19.0197C1.15761 22.5177 1.49703 29.7374 2.5 34C4.07125 40.6778 7.18553 44.8868 8.44856 46.3845C8.79051 46.79 9.29799 47 9.82843 47H20.0218C20.639 47 21.2193 46.7159 21.5659 46.2052C22.6765 44.5687 25.2312 40.4282 27.5 34C28.9757 29.8188 29.084 22.4043 29.0441 18.9156C29.0319 17.8436 28.1539 17 27.0819 17Z"
|
||||||
|
stroke="var(--secondary)"
|
||||||
|
strokeWidth="2"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
d="M29 23.5C29 23.5 34.5 20.5 35.5 25.4999C36.0986 28.4926 34.2033 31.5383 32 32.8713C29.4555 34.4108 28 34 28 34"
|
||||||
|
stroke="var(--secondary)"
|
||||||
|
strokeWidth="2"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
id="teabag"
|
||||||
|
fill="var(--secondary)"
|
||||||
|
fillRule="evenodd"
|
||||||
|
clipRule="evenodd"
|
||||||
|
d="M16 25V17H14V25H12C10.3431 25 9 26.3431 9 28V34C9 35.6569 10.3431 37 12 37H18C19.6569 37 21 35.6569 21 34V28C21 26.3431 19.6569 25 18 25H16ZM11 28C11 27.4477 11.4477 27 12 27H18C18.5523 27 19 27.4477 19 28V34C19 34.5523 18.5523 35 18 35H12C11.4477 35 11 34.5523 11 34V28Z"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
id="steamL"
|
||||||
|
d="M17 1C17 1 17 4.5 14 6.5C11 8.5 11 12 11 12"
|
||||||
|
strokeWidth="2"
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
stroke="var(--secondary)"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
id="steamR"
|
||||||
|
d="M21 6C21 6 21 8.22727 19 9.5C17 10.7727 17 13 17 13"
|
||||||
|
stroke="var(--secondary)"
|
||||||
|
strokeWidth="2"
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
/>
|
||||||
|
</StyledSVG>
|
||||||
|
</StyledBox>
|
||||||
|
<br />
|
||||||
|
<h2>Loading...</h2>
|
||||||
|
</StyledContainer>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Spinner
|
|
@ -1,116 +0,0 @@
|
||||||
/**
|
|
||||||
* inspired by https://github.com/dmitrymorozoff/react-spinners-kit/tree/master/src/components/whisper
|
|
||||||
*/
|
|
||||||
|
|
||||||
import React from "react"
|
|
||||||
import styled, { keyframes } from "styled-components"
|
|
||||||
|
|
||||||
const motion = keyframes`
|
|
||||||
from {
|
|
||||||
transform: scale(1, 1);
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
to {
|
|
||||||
transform: scale(0, 0);
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
`
|
|
||||||
|
|
||||||
const spin = keyframes`
|
|
||||||
from {
|
|
||||||
transform: rotate(0deg);
|
|
||||||
}
|
|
||||||
to {
|
|
||||||
transform: rotate(360deg);
|
|
||||||
}
|
|
||||||
`
|
|
||||||
|
|
||||||
const Ball = styled.div<BallInterface>`
|
|
||||||
float: left;
|
|
||||||
clear: right;
|
|
||||||
margin: ${(props) => props.size / 15}px;
|
|
||||||
width: ${(props) => props.size / 5}px;
|
|
||||||
height: ${(props) => props.size / 5}px;
|
|
||||||
border-radius: 2px;
|
|
||||||
background-color: lightgrey;
|
|
||||||
animation-name: ${motion};
|
|
||||||
animation-direction: alternate;
|
|
||||||
animation-duration: 800ms;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
|
|
||||||
/* use a for loop here? */
|
|
||||||
&:nth-child(1) {
|
|
||||||
animation-delay: 200ms;
|
|
||||||
}
|
|
||||||
&:nth-child(2) {
|
|
||||||
animation-delay: 400ms;
|
|
||||||
}
|
|
||||||
&:nth-child(3) {
|
|
||||||
animation-delay: 600ms;
|
|
||||||
}
|
|
||||||
&:nth-child(4) {
|
|
||||||
animation-delay: 400ms;
|
|
||||||
}
|
|
||||||
&:nth-child(5) {
|
|
||||||
animation-delay: 600ms;
|
|
||||||
}
|
|
||||||
&:nth-child(6) {
|
|
||||||
animation-delay: 800ms;
|
|
||||||
}
|
|
||||||
&:nth-child(7) {
|
|
||||||
animation-delay: 600ms;
|
|
||||||
}
|
|
||||||
&:nth-child(8) {
|
|
||||||
animation-delay: 800ms;
|
|
||||||
}
|
|
||||||
&:nth-child(9) {
|
|
||||||
animation-delay: 1000ms;
|
|
||||||
}
|
|
||||||
`
|
|
||||||
|
|
||||||
const Wrapper = styled.div`
|
|
||||||
margin: 5rem auto 0 auto;
|
|
||||||
width: 200px;
|
|
||||||
height: 200px;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
animation: ${spin} 10s infinite;
|
|
||||||
`
|
|
||||||
|
|
||||||
interface BallInterface {
|
|
||||||
size: number
|
|
||||||
key: string
|
|
||||||
index: number
|
|
||||||
}
|
|
||||||
|
|
||||||
interface SpinnerProps {
|
|
||||||
size: number
|
|
||||||
}
|
|
||||||
|
|
||||||
export default class Spinner extends React.Component<SpinnerProps> {
|
|
||||||
balls: unknown[] = []
|
|
||||||
|
|
||||||
constructor(props: SpinnerProps) {
|
|
||||||
super(props)
|
|
||||||
|
|
||||||
let keyValue = 0
|
|
||||||
const countBallsInLine = 3
|
|
||||||
|
|
||||||
for (let i = 0; i < countBallsInLine; i++) {
|
|
||||||
for (let j = 0; j < countBallsInLine; j++) {
|
|
||||||
this.balls.push(
|
|
||||||
<Ball
|
|
||||||
size={this.props.size}
|
|
||||||
key={keyValue.toString()}
|
|
||||||
index={keyValue}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
keyValue++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return <Wrapper>{this.balls}</Wrapper>
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -11,7 +11,7 @@ import theming from "../theming"
|
||||||
import Tag from "../components/Tag"
|
import Tag from "../components/Tag"
|
||||||
import TagList from "../components/TagList"
|
import TagList from "../components/TagList"
|
||||||
import NotFound from "./NotFound"
|
import NotFound from "./NotFound"
|
||||||
import Spinner from "../components/Spinner"
|
import Loading from "../components/Loading"
|
||||||
|
|
||||||
import _map from "../data/map.json"
|
import _map from "../data/map.json"
|
||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
|
||||||
|
@ -260,7 +260,7 @@ export default class Page extends React.Component<PageProps, PageState> {
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
if (this.state.loading) return <Spinner size={200} />
|
if (this.state.loading) return <Loading />
|
||||||
if (!this.state.fetchedPage) return <NotFound />
|
if (!this.state.fetchedPage) return <NotFound />
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue