add loading state
This commit is contained in:
parent
e274f32486
commit
498c7d3e32
2
dist/app.css
vendored
2
dist/app.css
vendored
@ -4,6 +4,8 @@
|
||||
|
||||
.PokemonApp__wrapper__3ZEoC{display:flex;flex-flow:column nowrap;align-items:stretch}.PokemonApp__wrapper__3ZEoC .PokemonApp__body__23cv_{background-color:#fff;display:flex;flex-flow:row nowrap;align-items:stretch;position:relative;padding-bottom:60px}.PokemonApp__wrapper__3ZEoC.PokemonApp__overlaid__3B_Ol{background-color:rgba(0,0,0,0.7)}.PokemonApp__wrapper__3ZEoC.PokemonApp__overlaid__3B_Ol .PokemonApp__highlight__1zywH{z-index:1}.PokemonApp__header__2s_s2{display:flex;flex:0 0 auto;justify-content:space-between;align-items:center;padding:0.5rem 1rem;position:sticky;top:0}.PokemonApp__header__2s_s2 a{display:inline-block;display:flex}.PokemonApp__footer__3q19Q{height:60px;position:fixed;right:0;bottom:0;left:0}.PokemonApp__header__2s_s2,.PokemonApp__footer__3q19Q{margin:0.1em;z-index:10}.PokemonApp__navigationButton__2BuiE{}.PokemonApp__navigationButton__2BuiE.PokemonApp__hamburgerIcon__1ujIT{font-size:2rem;margin-top:-6px}.PokemonApp__overlay__2vc-r{position:absolute;top:0;right:0;bottom:0;left:0;background-color:#000;opacity:.7}.PokemonApp__overlay__2vc-r.PokemonApp__complete__h3L_s{z-index:1}.PokemonApp__navigationWrapper__3oyCI{display:flex;margin:0 auto}.PokemonApp__displayWrapper__2PiN5{margin:0 auto}.PokemonApp__displayWrapper__2PiN5>*{width:450px;margin:0 1em}@media only screen and (max-width: 767px){.PokemonApp__displayWrapper__2PiN5>*{width:auto;margin:0 0.1em}}.PokemonApp__container__MsUHy{display:flex;justify-content:space-evenly}.PokemonApp__container__MsUHy .PokemonApp__leftColumn__3Lv_L,.PokemonApp__container__MsUHy .PokemonApp__rightColumn__1xE25{display:flex;flex-flow:column nowrap;align-items:center}.PokemonApp__container__MsUHy .PokemonApp__leftColumn__3Lv_L{width:45%;text-align:center}.PokemonApp__container__MsUHy .PokemonApp__rightColumn__1xE25{flex-grow:1;align-items:start}
|
||||
|
||||
.ExplorerLoading__wrapper__MGSlF{display:flex;flex-wrap:wrap;width:480px;margin:0 auto}@media only screen and (max-width: 767px){.ExplorerLoading__wrapper__MGSlF{flex-direction:column}}.ExplorerLoading__wrapper__MGSlF .icon{animation:ExplorerLoading__bounce__F9WGl 0.6s both linear infinite}@media only screen and (max-width: 767px){.ExplorerLoading__wrapper__MGSlF .icon{margin:0 auto}}@keyframes ExplorerLoading__bounce__F9WGl{0%,100%{transform:translateY(0)}50%{transform:translateY(-5px)}}.ExplorerLoading__wrapper__MGSlF .icon:nth-child(2){animation-delay:0.2s}.ExplorerLoading__wrapper__MGSlF .icon:nth-child(3){animation-delay:0.4s}.ExplorerLoading__loading__kpcaU{width:100%;text-align:center;margin-top:0.5em}.ExplorerLoading__loading__kpcaU::after{position:absolute;overflow:hidden;display:inline-block;vertical-align:bottom;animation:ExplorerLoading__ellipsis__3kLb6 steps(4, end) 900ms infinite;content:"\2026";width:0}@keyframes ExplorerLoading__ellipsis__3kLb6{to{width:1.25em}}
|
||||
|
||||
.nes-field.is-inline .IvForm__ivInput__xR5IU{width:4.25em;padding-left:0.45em;padding-right:0.25em}.nes-field.is-inline .IvForm__ivInput__xR5IU.IvForm__levelInput__1n6We{width:6.5em}.nes-field.is-inline.IvForm__fieldRow__3HcBN{font-size:0.9em;justify-content:space-between;align-items:baseline}.nes-field.is-inline.IvForm__fieldRow__3HcBN label{flex-grow:0;margin-left:1em}.nes-field.is-inline.IvForm__fieldRow__3HcBN label:first-child{margin-left:0}
|
||||
|
||||
.LeagueSelector__wrapper__fxmRz{font-size:0.8em;display:flex;justify-content:space-around;margin:0 0 0.5rem 0}.LeagueSelector__leagueRadioLabel__3aPV9{display:flex;align-items:center}.LeagueSelector__leagueRadio__3hY7B{display:none}
|
||||
|
||||
2
dist/global-bundle.js
vendored
2
dist/global-bundle.js
vendored
File diff suppressed because one or more lines are too long
14
dist/main-bundle.js
vendored
14
dist/main-bundle.js
vendored
File diff suppressed because one or more lines are too long
45
src/ts/app/components/PokemonExplorer/ExplorerLoading.tsx
Normal file
45
src/ts/app/components/PokemonExplorer/ExplorerLoading.tsx
Normal file
@ -0,0 +1,45 @@
|
||||
import React from 'react';
|
||||
|
||||
import classNames from 'classnames';
|
||||
|
||||
import { formatDexNumber } from 'app/utils/formatter';
|
||||
|
||||
import * as styles from 'app/components/PokemonExplorer/styles/ExplorerLoading.scss';
|
||||
|
||||
export interface IExplorerLoadingProps {}
|
||||
|
||||
export class ExplorerLoading extends React.Component<IExplorerLoadingProps> {
|
||||
|
||||
public render() {
|
||||
|
||||
const pokemonGroups = [
|
||||
[1, 2, 3],
|
||||
[4, 5, 6],
|
||||
[7, 8, 9],
|
||||
[172, 25, 26],
|
||||
[144, 145, 146],
|
||||
];
|
||||
|
||||
const pokemonIconCss = classNames(
|
||||
'icon',
|
||||
'pixel',
|
||||
'sprite',
|
||||
);
|
||||
|
||||
const groupIndex = Math.floor(Math.random() * pokemonGroups.length);
|
||||
const pokemonIcons = pokemonGroups[groupIndex].map((dex) => {
|
||||
const pokemonCss = classNames(
|
||||
pokemonIconCss,
|
||||
`pokemon-${ formatDexNumber(dex) }`,
|
||||
);
|
||||
return <div key={ dex } className={ pokemonCss } />;
|
||||
});
|
||||
|
||||
return (
|
||||
<div className={ styles.wrapper }>
|
||||
{ pokemonIcons }
|
||||
<h2 className={ styles.loading }>Loading</h2>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -21,6 +21,7 @@ import {
|
||||
} from 'app/components/PokemonExplorer/types';
|
||||
import { IRouterProps, Navigation as NavigationType } from 'app/types';
|
||||
|
||||
import { ExplorerLoading } from 'app/components/PokemonExplorer/ExplorerLoading';
|
||||
import { LeagueIvExplorer } from 'app/components/PokemonExplorer/LeagueIvExplorer';
|
||||
import { MovesExplorer } from 'app/components/PokemonExplorer/MovesExplorer';
|
||||
import { Navigation } from 'app/components/PokemonExplorer/Navigation';
|
||||
@ -55,6 +56,7 @@ class PokemonExplorer extends React.Component<IConnectedPokemonExplorerProps> {
|
||||
attackTypeEffectiveness,
|
||||
} = this.props;
|
||||
const {
|
||||
isLoading,
|
||||
league,
|
||||
individualValues,
|
||||
widgets,
|
||||
@ -88,67 +90,74 @@ class PokemonExplorer extends React.Component<IConnectedPokemonExplorerProps> {
|
||||
|
||||
return (
|
||||
<div className={ styles.body }>
|
||||
<div className={ navWrapperCss }>
|
||||
<div className={ displayWrapperCss }>
|
||||
{ leaguePokemon !== null &&
|
||||
<PokemonDisplay
|
||||
leaguePokemon={ leaguePokemon }
|
||||
isHighlighted={ isOverlayShown }
|
||||
/>
|
||||
}
|
||||
{ widgets.types && leaguePokemon !== null &&
|
||||
<div className="nes-container with-title">
|
||||
<h3 className="title">Type Effectivess</h3>
|
||||
<TypeEffectiveDisplay
|
||||
mode={ EffectivenessMode.DEFENSE }
|
||||
effectiveness={ leaguePokemon.effectiveness }
|
||||
coverage={ moveTypeStrengths }
|
||||
/>
|
||||
{ (leaguePokemon === null || isLoading) &&
|
||||
<ExplorerLoading />
|
||||
}
|
||||
{ leaguePokemon !== null && !isLoading &&
|
||||
<React.Fragment>
|
||||
<div className={ navWrapperCss }>
|
||||
<div className={ displayWrapperCss }>
|
||||
{ leaguePokemon !== null &&
|
||||
<PokemonDisplay
|
||||
leaguePokemon={ leaguePokemon }
|
||||
isHighlighted={ isOverlayShown }
|
||||
/>
|
||||
}
|
||||
{ widgets.types && leaguePokemon !== null &&
|
||||
<div className="nes-container with-title">
|
||||
<h3 className="title">Type Effectivess</h3>
|
||||
<TypeEffectiveDisplay
|
||||
mode={ EffectivenessMode.DEFENSE }
|
||||
effectiveness={ leaguePokemon.effectiveness }
|
||||
coverage={ moveTypeStrengths }
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
{ widgets.moves && leaguePokemon !== null &&
|
||||
<MovesExplorer
|
||||
movesById={ combatMoves }
|
||||
quickMoves={ leaguePokemon.moves.quick }
|
||||
chargeMoves={ leaguePokemon.moves.cinematic }
|
||||
selectedMoves={ selectedCombatMoves }
|
||||
pokemonTypeWeaknesses={ pokemonTypeWeaknesses }
|
||||
attackTypeEffectiveness={ attackTypeEffectiveness }
|
||||
combatMoveSelectorsOpen={ combatMoveSelectorsOpen }
|
||||
handleToggleDropdownOpen={ this.handleToggleDropdownOpen }
|
||||
handleChangeSelectedMove={ this.handleChangeSelectedMove }
|
||||
/>
|
||||
}
|
||||
{ widgets.pvp && leaguePokemon !== null &&
|
||||
<LeagueIvExplorer
|
||||
activeLeague={ league }
|
||||
leaguePokemon={ leaguePokemon }
|
||||
individualValues={ individualValues }
|
||||
handleChangeIndividualValue={ this.handleChangeIndividualValue }
|
||||
handleMaximizeLevel={ this.handleMaximizeLevel }
|
||||
handleChangeLeague={ this.handleChangeLeague }
|
||||
/>
|
||||
}
|
||||
</div>
|
||||
<Media query={ { minWidth: MIN_TABLET_WIDTH } }>
|
||||
<Navigation
|
||||
isMenu={ false }
|
||||
widgets={ widgets }
|
||||
handleNavigationClick={ this.handleNavigationClick }
|
||||
/>
|
||||
</Media>
|
||||
{ isMenuOpen &&
|
||||
<Media query={ { maxWidth: MAX_MOBILE_WIDTH } }>
|
||||
<Navigation
|
||||
isMenu={ true }
|
||||
widgets={ widgets }
|
||||
handleNavigationClick={ this.handleNavigationClick }
|
||||
/>
|
||||
</Media>
|
||||
}
|
||||
</div>
|
||||
{ isOverlayShown &&
|
||||
<div className={ overLayCss } onClick={ this.handleOverlayClick } />
|
||||
}
|
||||
{ widgets.moves && leaguePokemon !== null &&
|
||||
<MovesExplorer
|
||||
movesById={ combatMoves }
|
||||
quickMoves={ leaguePokemon.moves.quick }
|
||||
chargeMoves={ leaguePokemon.moves.cinematic }
|
||||
selectedMoves={ selectedCombatMoves }
|
||||
pokemonTypeWeaknesses={ pokemonTypeWeaknesses }
|
||||
attackTypeEffectiveness={ attackTypeEffectiveness }
|
||||
combatMoveSelectorsOpen={ combatMoveSelectorsOpen }
|
||||
handleToggleDropdownOpen={ this.handleToggleDropdownOpen }
|
||||
handleChangeSelectedMove={ this.handleChangeSelectedMove }
|
||||
/>
|
||||
}
|
||||
{ widgets.pvp && leaguePokemon !== null &&
|
||||
<LeagueIvExplorer
|
||||
activeLeague={ league }
|
||||
leaguePokemon={ leaguePokemon }
|
||||
individualValues={ individualValues }
|
||||
handleChangeIndividualValue={ this.handleChangeIndividualValue }
|
||||
handleMaximizeLevel={ this.handleMaximizeLevel }
|
||||
handleChangeLeague={ this.handleChangeLeague }
|
||||
/>
|
||||
}
|
||||
</div>
|
||||
<Media query={ { minWidth: MIN_TABLET_WIDTH } }>
|
||||
<Navigation
|
||||
isMenu={ false }
|
||||
widgets={ widgets }
|
||||
handleNavigationClick={ this.handleNavigationClick }
|
||||
/>
|
||||
</Media>
|
||||
{ isMenuOpen &&
|
||||
<Media query={ { maxWidth: MAX_MOBILE_WIDTH } }>
|
||||
<Navigation
|
||||
isMenu={ true }
|
||||
widgets={ widgets }
|
||||
handleNavigationClick={ this.handleNavigationClick }
|
||||
/>
|
||||
</Media>
|
||||
}
|
||||
</div>
|
||||
{ isOverlayShown &&
|
||||
<div className={ overLayCss } onClick={ this.handleOverlayClick } />
|
||||
</React.Fragment>
|
||||
}
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -6,7 +6,7 @@ import * as Actions from 'app/components/PokemonExplorer/actions';
|
||||
import { IPokemonExplorerState, PokemonExplorerActionTypes } from 'app/components/PokemonExplorer/types';
|
||||
|
||||
export const initialState : IPokemonExplorerState = {
|
||||
isLoading: false,
|
||||
isLoading: true,
|
||||
leaguePokemon: null,
|
||||
widgets: {
|
||||
types: false,
|
||||
|
||||
@ -0,0 +1,61 @@
|
||||
@import '~styles/Variables.scss';
|
||||
|
||||
.wrapper {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
width: 480px;
|
||||
margin: 0 auto;
|
||||
|
||||
@media only screen and (max-width: $max-mobile-width) {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
:global(.icon) {
|
||||
animation: bounce 0.6s both linear infinite;
|
||||
|
||||
@media only screen and (max-width: $max-mobile-width) {
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
@keyframes bounce {
|
||||
0%,
|
||||
100% {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
50% {
|
||||
transform: translateY(-5px);
|
||||
}
|
||||
}
|
||||
|
||||
&:nth-child(2) {
|
||||
animation-delay: 0.2s;
|
||||
}
|
||||
|
||||
&:nth-child(3) {
|
||||
animation-delay: 0.4s;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.loading {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
margin-top: 0.5em;
|
||||
|
||||
&::after {
|
||||
position: absolute;
|
||||
overflow: hidden;
|
||||
display: inline-block;
|
||||
vertical-align: bottom;
|
||||
animation: ellipsis steps(4, end) 900ms infinite;
|
||||
content: "\2026"; // ascii code for the ellipsis character
|
||||
width: 0;
|
||||
|
||||
@keyframes ellipsis {
|
||||
to {
|
||||
width: 1.25em;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
6
src/ts/app/components/PokemonExplorer/styles/ExplorerLoading.scss.d.ts
vendored
Normal file
6
src/ts/app/components/PokemonExplorer/styles/ExplorerLoading.scss.d.ts
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
// This file is automatically generated.
|
||||
// Please do not change this file!
|
||||
export const bounce: string;
|
||||
export const ellipsis: string;
|
||||
export const loading: string;
|
||||
export const wrapper: string;
|
||||
Loading…
x
Reference in New Issue
Block a user