206 lines
7.4 KiB
TypeScript
206 lines
7.4 KiB
TypeScript
import POGOProtos from 'pogo-protos';
|
|
|
|
import React from 'react';
|
|
import { connect } from 'react-redux';
|
|
import { RouteComponentProps } from 'react-router-dom';
|
|
|
|
import { League } from 'app/models/League';
|
|
|
|
import { appReducers } from './index';
|
|
|
|
import * as ActionsPokemonExplorer from './components/PokemonExplorer/actions';
|
|
import * as ActionsPokemonSelectList from './components/PokemonSelectList/actions';
|
|
import { IPokemonAppDispatch } from './types';
|
|
|
|
import { IndividualValueKey } from './components/PokemonExplorer/types';
|
|
|
|
import { Footer } from './components/Footer';
|
|
import { Header } from './components/Header';
|
|
import { PokemonExplorer } from './components/PokemonExplorer/PokemonExplorer';
|
|
import { PokemonSelectList } from './components/PokemonSelectList/PokemonSelectList';
|
|
|
|
import { appendQueryString, getCurrentQueryStringVlaues } from 'app/utils/navigation';
|
|
|
|
import * as styles from './styles/PokemonApp.scss';
|
|
|
|
type PokemonAppProps = ReturnType<typeof appReducers>;
|
|
|
|
interface IConnectedPokemonAppProps extends PokemonAppProps, IPokemonAppDispatch {
|
|
history : RouteComponentProps['history'];
|
|
location : RouteComponentProps['location'];
|
|
}
|
|
|
|
class PokemonApp extends React.Component<IConnectedPokemonAppProps> {
|
|
constructor(props : IConnectedPokemonAppProps) {
|
|
super(props);
|
|
}
|
|
|
|
public async componentWillMount() {
|
|
const {
|
|
location,
|
|
dispatch
|
|
} = this.props;
|
|
|
|
await Promise.all([
|
|
dispatch(ActionsPokemonExplorer.fetchConfig()),
|
|
dispatch(ActionsPokemonSelectList.fetchPokemonList())
|
|
]);
|
|
dispatch(ActionsPokemonSelectList.setIsLoading(false));
|
|
|
|
const [
|
|
pokemonIdValue,
|
|
pokemonFormValue,
|
|
activeLeagueValue,
|
|
] = getCurrentQueryStringVlaues(location, 'id', 'form', 'league');
|
|
|
|
const pokemonId = pokemonIdValue !== null ? parseInt(pokemonIdValue, 10) : null;
|
|
const pokemonForm = pokemonFormValue ? parseInt(pokemonFormValue, 10) : null;
|
|
if (pokemonId !== null && typeof POGOProtos.Enums.PokemonId[pokemonId] !== 'undefined' &&
|
|
pokemonForm !== null && typeof POGOProtos.Enums.Form[pokemonForm] !== 'undefined'
|
|
) {
|
|
this.handleActivatePokemon(pokemonId, pokemonForm);
|
|
}
|
|
|
|
const activeLeague = activeLeagueValue ? parseInt(activeLeagueValue, 10) : null;
|
|
if (activeLeague !== null && typeof League[activeLeague] !== 'undefined') {
|
|
this.handleChangeLeague(activeLeague);
|
|
}
|
|
}
|
|
|
|
public render() {
|
|
const {
|
|
activePokemonId,
|
|
activePokemonForm,
|
|
pokemonList,
|
|
pokemonListFiltered,
|
|
filterTerm,
|
|
} = this.props.pokemonSelectListState;
|
|
const {
|
|
league,
|
|
individualValues,
|
|
leaguePokemon,
|
|
} = this.props.pokemonExplorerState;
|
|
|
|
return (
|
|
<div className={ styles.wrapper }>
|
|
<Header />
|
|
<div className={ styles.body }>
|
|
<PokemonSelectList
|
|
isLoading={ this.props.pokemonSelectListState.isLoading }
|
|
activePokemonId={ activePokemonId }
|
|
activePokemonForm={ activePokemonForm }
|
|
pokemonList={ filterTerm === '' ? pokemonList : pokemonListFiltered }
|
|
filterTerm={ this.props.pokemonSelectListState.filterTerm }
|
|
handleActivatePokemon={ this.handleActivatePokemon }
|
|
handleChangeFilter={ this.handleChangeFilter }
|
|
/>
|
|
{ leaguePokemon !== null &&
|
|
<PokemonExplorer
|
|
isLoading={ this.props.pokemonExplorerState.isLoading }
|
|
activeLeague={ league }
|
|
leaguePokemon={ leaguePokemon }
|
|
individualValues={ individualValues }
|
|
handleChangeIndividualValue={ this.handleChangeIndividualValue }
|
|
handleMaximizeLevel={ this.handleMaximizeLevel }
|
|
handleChangeLeague={ this.handleChangeLeagueNavigation }
|
|
/>
|
|
}
|
|
</div>
|
|
<Footer />
|
|
</div>
|
|
);
|
|
}
|
|
|
|
private readonly handleActivatePokemon = (pokemonId : POGOProtos.Enums.PokemonId, form : POGOProtos.Enums.Form) => {
|
|
const { dispatch } = this.props;
|
|
|
|
dispatch(ActionsPokemonSelectList.fetchPokemonLeagueStats(pokemonId, form))
|
|
.then((leaguePokemon) => {
|
|
dispatch(ActionsPokemonSelectList.setActivePokemonId(pokemonId, form));
|
|
dispatch(ActionsPokemonExplorer.setIvLevel(null));
|
|
dispatch(ActionsPokemonExplorer.setIvHp(null));
|
|
dispatch(ActionsPokemonExplorer.setIvAtk(null));
|
|
dispatch(ActionsPokemonExplorer.setIvDef(null));
|
|
dispatch(ActionsPokemonExplorer.setLeaguePokemon(leaguePokemon));
|
|
})
|
|
.catch((error) => {
|
|
// tslint:disable-next-line:no-console
|
|
console.error(error);
|
|
dispatch(ActionsPokemonExplorer.setLeaguePokemon(null));
|
|
})
|
|
.then(() => dispatch(ActionsPokemonExplorer.setIsLoading(false)));
|
|
}
|
|
|
|
private readonly handleChangeFilter = (filterTerm : string) => {
|
|
return this.props.dispatch(ActionsPokemonSelectList.filterPokemonList(filterTerm));
|
|
}
|
|
|
|
private readonly handleChangeIndividualValue = (stat : IndividualValueKey, value : number | null) => {
|
|
const {
|
|
dispatch,
|
|
} = this.props;
|
|
|
|
switch (stat) {
|
|
case 'level':
|
|
dispatch(ActionsPokemonExplorer.setIvLevel(value));
|
|
break;
|
|
case 'hp':
|
|
dispatch(ActionsPokemonExplorer.setIvHp(value));
|
|
break;
|
|
case 'atk':
|
|
dispatch(ActionsPokemonExplorer.setIvAtk(value));
|
|
break;
|
|
case 'def':
|
|
dispatch(ActionsPokemonExplorer.setIvDef(value));
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
private readonly handleMaximizeLevel = () => {
|
|
this.props.dispatch(ActionsPokemonExplorer.maximizeLevel());
|
|
}
|
|
|
|
private readonly handleChangeLeagueNavigation = (league : League) => {
|
|
const {
|
|
history,
|
|
location,
|
|
} = this.props;
|
|
|
|
history.push({
|
|
search: appendQueryString(location, { league: league.toString() })
|
|
});
|
|
|
|
this.handleChangeLeague(league);
|
|
}
|
|
|
|
private readonly handleChangeLeague = (league : League) => {
|
|
this.props.dispatch(ActionsPokemonExplorer.setActiveLeague(league));
|
|
}
|
|
}
|
|
|
|
const mapStateToProps = (state : PokemonAppProps) : PokemonAppProps => {
|
|
return {
|
|
pokemonExplorerState: state.pokemonExplorerState,
|
|
pokemonSelectListState: state.pokemonSelectListState,
|
|
};
|
|
};
|
|
|
|
const mapDispatchToProps = (dispatch : IPokemonAppDispatch['dispatch']) : IPokemonAppDispatch => {
|
|
return {
|
|
dispatch
|
|
};
|
|
};
|
|
|
|
const mergeProps = (state : PokemonAppProps, dispatchProps : IPokemonAppDispatch, ownProps : RouteComponentProps) : IConnectedPokemonAppProps => {
|
|
return {
|
|
...state,
|
|
...dispatchProps,
|
|
history: ownProps.history,
|
|
location: ownProps.location,
|
|
};
|
|
};
|
|
|
|
export const ConnectedPokemonApp = connect(mapStateToProps, mapDispatchToProps, mergeProps)(PokemonApp);
|