refactor store for router navigation
This commit is contained in:
parent
c6fccae553
commit
ea3d340dc2
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
@ -4,8 +4,6 @@ import { RouteComponentProps } from 'react-router-dom';
|
||||
|
||||
import classNames from 'classnames';
|
||||
|
||||
import { League } from 'app/models/League';
|
||||
|
||||
import { appReducers } from 'app/index';
|
||||
|
||||
import * as ActionsPokemonApp from 'app/actions';
|
||||
@ -13,6 +11,8 @@ import * as ActionsPokemonExplorer from 'app/components/PokemonExplorer/actions'
|
||||
import * as ActionsPokemonSelectList from 'app/components/PokemonSelectList/actions';
|
||||
import { IPokemonAppDispatch, IRouterProps } from 'app/types';
|
||||
|
||||
import { convertFormParamToPokemonForm, convertIdParamToPokemonId } from 'app/utils/navigation';
|
||||
|
||||
import { Footer } from 'app/components/Footer';
|
||||
import { Header } from 'app/components/Header';
|
||||
import { ConnectedPokemonExplorer } from 'app/components/PokemonExplorer/PokemonExplorer';
|
||||
@ -53,25 +53,6 @@ class PokemonApp extends React.Component<IConnectedPokemonAppProps, IState> {
|
||||
dispatch(ActionsPokemonSelectList.fetchPokemonList())
|
||||
]);
|
||||
dispatch(ActionsPokemonSelectList.setIsLoading(false));
|
||||
|
||||
const {
|
||||
id,
|
||||
form,
|
||||
league,
|
||||
} = this.props.match.params;
|
||||
|
||||
const pokemonId = id ? parseInt(id, 10) : null;
|
||||
const pokemonForm = form ? parseInt(form, 10) : null;
|
||||
if (pokemonId !== null && typeof PVPogoProtos.PokemonId[pokemonId] !== 'undefined' &&
|
||||
pokemonForm !== null && typeof PVPogoProtos.PokemonForm[pokemonForm] !== 'undefined'
|
||||
) {
|
||||
this.handleActivatePokemon(pokemonId, pokemonForm);
|
||||
}
|
||||
|
||||
const activeLeague = league ? parseInt(league, 10) : null;
|
||||
if (activeLeague !== null && typeof League[activeLeague] !== 'undefined') {
|
||||
this.handleChangeLeague(activeLeague);
|
||||
}
|
||||
}
|
||||
|
||||
public render() {
|
||||
@ -81,15 +62,19 @@ class PokemonApp extends React.Component<IConnectedPokemonAppProps, IState> {
|
||||
combatMoves,
|
||||
} = this.props.pokemonAppState;
|
||||
const {
|
||||
activePokemonId,
|
||||
activePokemonForm,
|
||||
pokemonList,
|
||||
pokemonListFiltered,
|
||||
filterTerm,
|
||||
} = this.props.pokemonSelectListState;
|
||||
const {
|
||||
leaguePokemon,
|
||||
} = this.props.pokemonExplorerState;
|
||||
const {
|
||||
activeNavigation,
|
||||
} = this.state;
|
||||
const matchParams = this.props.match.params;
|
||||
const activePokemonId = convertIdParamToPokemonId(matchParams.id);
|
||||
const activePokemonForm = convertFormParamToPokemonForm(matchParams.form);
|
||||
|
||||
const wrapperCss = classNames(
|
||||
styles.wrapper,
|
||||
@ -117,6 +102,10 @@ class PokemonApp extends React.Component<IConnectedPokemonAppProps, IState> {
|
||||
// }
|
||||
);
|
||||
|
||||
// react optimization for rendering on pokemon switching
|
||||
// https://reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html#recommendation-fully-uncontrolled-component-with-a-key
|
||||
const uniquePokemonId = leaguePokemon !== null ? `${leaguePokemon.id}~${leaguePokemon.form}` : undefined;
|
||||
|
||||
return (
|
||||
<div className={ wrapperCss }>
|
||||
<Header>
|
||||
@ -133,6 +122,7 @@ class PokemonApp extends React.Component<IConnectedPokemonAppProps, IState> {
|
||||
<button className={ pokedexButtonCss } onClick={ this.handlePokedexClick }><i className={ pokedexCss } /></button>
|
||||
</Header>
|
||||
<ConnectedPokemonExplorer
|
||||
key={ uniquePokemonId }
|
||||
isOverlaid={ isInterruption }
|
||||
attackTypeEffectiveness={ attackTypeEffectiveness }
|
||||
combatMoves={ combatMoves }
|
||||
@ -174,42 +164,26 @@ class PokemonApp extends React.Component<IConnectedPokemonAppProps, IState> {
|
||||
this.handleSearchInterruption(true);
|
||||
}
|
||||
|
||||
private readonly handleActivatePokemon = (pokemonId : PVPogoProtos.PokemonId, form : PVPogoProtos.PokemonForm) => {
|
||||
private readonly handleActivatePokemon = async (pokemonId : PVPogoProtos.PokemonId, form : PVPogoProtos.PokemonForm) => {
|
||||
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));
|
||||
dispatch(ActionsPokemonExplorer.setSelectedCombatMoves({
|
||||
quickMove: null,
|
||||
chargeMove1: null,
|
||||
chargeMove2: null,
|
||||
}));
|
||||
})
|
||||
.catch((error) => {
|
||||
dispatch(ActionsPokemonExplorer.setIsLoading(true));
|
||||
try {
|
||||
const leaguePokemon = await dispatch(ActionsPokemonApp.fetchPokemonLeagueStats(pokemonId, form));
|
||||
dispatch(ActionsPokemonExplorer.reset(leaguePokemon));
|
||||
} catch (error) {
|
||||
// tslint:disable-next-line:no-console
|
||||
console.error(error);
|
||||
dispatch(ActionsPokemonExplorer.setLeaguePokemon(null));
|
||||
})
|
||||
.then(() => {
|
||||
}
|
||||
dispatch(ActionsPokemonExplorer.setIsLoading(false));
|
||||
this.handleSearchInterruption(false);
|
||||
});
|
||||
}
|
||||
|
||||
private readonly handleChangeFilter = (filterTerm : string) => {
|
||||
this.handleSearchInterruption(true);
|
||||
return this.props.dispatch(ActionsPokemonSelectList.filterPokemonList(filterTerm));
|
||||
}
|
||||
|
||||
private readonly handleChangeLeague = (league : League) => {
|
||||
this.props.dispatch(ActionsPokemonExplorer.setActiveLeague(league));
|
||||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = (state : PokemonAppProps) : PokemonAppProps => {
|
||||
|
||||
@ -1,9 +1,12 @@
|
||||
import { action } from 'typesafe-actions';
|
||||
|
||||
import { ILeaguePokemon } from 'app/models/League';
|
||||
import { CombatMoveStats, IMaxStats } from 'app/models/Pokemon';
|
||||
import * as PVPogoProtos from 'common/models/PVPogoProtos';
|
||||
|
||||
import { PokemonAppActionTypes, ThunkResult } from 'app/types';
|
||||
|
||||
import { AttackTypeEffectiveness } from 'app/models/Config';
|
||||
import { CombatMoveStats, IMaxStats } from 'app/models/Pokemon';
|
||||
|
||||
export const setIsInterruption = (isInterruption : boolean) => action(PokemonAppActionTypes.SET_IS_INTERRUPTION, { isInterruption });
|
||||
|
||||
@ -13,6 +16,12 @@ export const setAttackTypeEffectiveness = (attackTypeEffectiveness : AttackTypeE
|
||||
|
||||
export const setCombatMoveStats = (combatMoves : CombatMoveStats) => action(PokemonAppActionTypes.SET_COMBAT_MOVE_STATS, { combatMoves });
|
||||
|
||||
export const setPokemonLeagueStats = (
|
||||
pokemonId : PVPogoProtos.PokemonId,
|
||||
form : PVPogoProtos.PokemonForm,
|
||||
pokemonLeagueStats : ILeaguePokemon
|
||||
) => action(PokemonAppActionTypes.SET_POKEMON_LEAGUE_STATS, { pokemonId, form, pokemonLeagueStats });
|
||||
|
||||
export const fetchConfig = (
|
||||
) : ThunkResult<Promise<void>> => {
|
||||
return async (dispatch, getState, extraArguments) => {
|
||||
@ -22,3 +31,21 @@ export const fetchConfig = (
|
||||
dispatch(setCombatMoveStats(config.combatMoves));
|
||||
};
|
||||
};
|
||||
|
||||
export const fetchPokemonLeagueStats = (
|
||||
pokemonId : PVPogoProtos.PokemonId,
|
||||
form : PVPogoProtos.PokemonForm
|
||||
) : ThunkResult<Promise<ILeaguePokemon>> => {
|
||||
return async (dispatch, getState, extraArguments) => {
|
||||
const leagueStats = getState().pokemonAppState.pokemonLeagueStats;
|
||||
// TODO: need better accessor so `~` isn't floating around all over the place, maybe make a class
|
||||
const cachedLeaguePokemon = leagueStats[pokemonId + '~' + form];
|
||||
if (typeof cachedLeaguePokemon !== 'undefined') {
|
||||
return Promise.resolve(cachedLeaguePokemon);
|
||||
}
|
||||
|
||||
const pokemonLeagueStats = await extraArguments.services.pokemonService.getPokemonLeagueStats(pokemonId, form);
|
||||
dispatch(setPokemonLeagueStats(pokemonId, form, pokemonLeagueStats));
|
||||
return pokemonLeagueStats;
|
||||
};
|
||||
};
|
||||
|
||||
@ -40,7 +40,7 @@ export class Header extends React.Component<IHeaderProps> {
|
||||
to="/explorer/1/0"
|
||||
// style={ style }
|
||||
// className={ anchorCss }
|
||||
onClick={ this.reload }
|
||||
// onClick={ this.reload }
|
||||
>
|
||||
PVPokemon
|
||||
</Link>
|
||||
@ -56,6 +56,4 @@ export class Header extends React.Component<IHeaderProps> {
|
||||
</header>
|
||||
);
|
||||
}
|
||||
|
||||
private readonly reload = () => window.location.reload();
|
||||
}
|
||||
|
||||
@ -29,8 +29,24 @@ export const setSelectedCombatMoves = (moves : SelectedCombatMoves) => action(Po
|
||||
|
||||
export const setCombatMoveSelectorsOpen = (selectorsOpen : CombatMoveSelectorsOpen) => action(PokemonExplorerActionTypes.SET_COMBAT_MOVE_SELECTORS_OPEN, { selectorsOpen });
|
||||
|
||||
export const maximizeLevel = (
|
||||
export const reset = (
|
||||
leaguePokemon : ILeaguePokemon | null
|
||||
) : ThunkResult<Promise<void>> => {
|
||||
return async (dispatch, getState, extraArguments) => {
|
||||
dispatch(setIvLevel(null));
|
||||
dispatch(setIvHp(null));
|
||||
dispatch(setIvAtk(null));
|
||||
dispatch(setIvDef(null));
|
||||
dispatch(setLeaguePokemon(leaguePokemon));
|
||||
dispatch(setSelectedCombatMoves({
|
||||
quickMove: null,
|
||||
chargeMove1: null,
|
||||
chargeMove2: null,
|
||||
}));
|
||||
};
|
||||
};
|
||||
|
||||
export const maximizeLevel = () : ThunkResult<Promise<void>> => {
|
||||
return async (dispatch, getState, extraArguments) => {
|
||||
const pokemonExplorerState = getState().pokemonExplorerState;
|
||||
const {
|
||||
|
||||
@ -14,10 +14,6 @@ export const setPokemonList = (pokemonList : Array<IPokemon>) => action(PokemonS
|
||||
|
||||
export const setPokemonListFiltered = (filterTerm : string, pokemonListFiltered : Array<IPokemon>) => action(PokemonSelectListActionTypes.SET_POKEMON_LIST_FILTERED, { filterTerm, pokemonListFiltered });
|
||||
|
||||
export const setActivePokemonId = (activePokemonId : PVPogoProtos.PokemonId | null, activePokemonForm : PVPogoProtos.PokemonForm | null) => action(PokemonSelectListActionTypes.SET_ACTIVE_POKEMON_ID, { activePokemonId, activePokemonForm });
|
||||
|
||||
export const setPokemonLeagueStats = (pokemonId : PVPogoProtos.PokemonId, pokemonLeagueStats : ILeaguePokemon) => action(PokemonSelectListActionTypes.SET_POKEMON_LEAGUE_STATS, { pokemonId, pokemonLeagueStats });
|
||||
|
||||
export const filterPokemonList = (
|
||||
filterTerm : string
|
||||
) : ThunkResult<Promise<void>> => {
|
||||
@ -26,6 +22,10 @@ export const filterPokemonList = (
|
||||
if (filterTerm !== '') {
|
||||
const pokemonList = getState().pokemonSelectListState.pokemonList;
|
||||
const normalizedFilterTerm = filterTerm.toLowerCase();
|
||||
// TODO: memoize the filtering, move to component instance variable?
|
||||
// filter = memoize(
|
||||
// (list, filterText) => list.filter(item => item.text.includes(filterText))
|
||||
// );
|
||||
pokemonListFiltered = pokemonList.reduce((result : Array<IPokemon>, pokemon) => {
|
||||
const pokemonName = pokemon.name.toLowerCase();
|
||||
const pokemonDex = '' + pokemon.dex;
|
||||
@ -50,14 +50,3 @@ export const fetchPokemonList = (
|
||||
dispatch(setPokemonList(pokemonList));
|
||||
};
|
||||
};
|
||||
|
||||
export const fetchPokemonLeagueStats = (
|
||||
pokemonId : PVPogoProtos.PokemonId,
|
||||
form : PVPogoProtos.PokemonForm
|
||||
) : ThunkResult<Promise<ILeaguePokemon>> => {
|
||||
return async (dispatch, getState, extraArguments) => {
|
||||
const pokemonLeagueStats = await extraArguments.services.pokemonService.getPokemonLeagueStats(pokemonId, form);
|
||||
dispatch(setPokemonLeagueStats(pokemonId, pokemonLeagueStats));
|
||||
return pokemonLeagueStats;
|
||||
};
|
||||
};
|
||||
|
||||
@ -5,12 +5,9 @@ import { IPokemonSelectListState, PokemonSelectListActionTypes } from './types';
|
||||
|
||||
export const initialState : IPokemonSelectListState = {
|
||||
isLoading: true,
|
||||
activePokemonId: null,
|
||||
activePokemonForm: null,
|
||||
pokemonList: [],
|
||||
pokemonListFiltered: [],
|
||||
filterTerm: '',
|
||||
pokemonLeagueStats: {},
|
||||
};
|
||||
|
||||
const reduceSetIsLoading = (
|
||||
@ -38,26 +35,6 @@ const reduceSetPokemonListFiltered = (
|
||||
pokemonListFiltered: action.payload.pokemonListFiltered,
|
||||
});
|
||||
|
||||
const reduceSetActivePokemonId = (
|
||||
state : IPokemonSelectListState,
|
||||
action : ReturnType<typeof Actions.setActivePokemonId>
|
||||
) : IPokemonSelectListState => ({
|
||||
...state,
|
||||
activePokemonId: action.payload.activePokemonId,
|
||||
activePokemonForm: action.payload.activePokemonForm,
|
||||
});
|
||||
|
||||
const reduceSetPokemonLeagueStats = (
|
||||
state : IPokemonSelectListState,
|
||||
action : ReturnType<typeof Actions.setPokemonLeagueStats>
|
||||
) : IPokemonSelectListState => ({
|
||||
...state,
|
||||
pokemonLeagueStats: {
|
||||
...state.pokemonLeagueStats,
|
||||
[action.payload.pokemonId] : action.payload.pokemonLeagueStats,
|
||||
},
|
||||
});
|
||||
|
||||
export const PokemonSelectListReducers : Reducer<IPokemonSelectListState> = (
|
||||
state : IPokemonSelectListState = initialState,
|
||||
action,
|
||||
@ -69,10 +46,6 @@ export const PokemonSelectListReducers : Reducer<IPokemonSelectListState> = (
|
||||
return reduceSetPokemonList(state, action as ReturnType<typeof Actions.setPokemonList>);
|
||||
case PokemonSelectListActionTypes.SET_POKEMON_LIST_FILTERED:
|
||||
return reduceSetPokemonListFiltered(state, action as ReturnType<typeof Actions.setPokemonListFiltered>);
|
||||
case PokemonSelectListActionTypes.SET_ACTIVE_POKEMON_ID:
|
||||
return reduceSetActivePokemonId(state, action as ReturnType<typeof Actions.setActivePokemonId>);
|
||||
case PokemonSelectListActionTypes.SET_POKEMON_LEAGUE_STATS:
|
||||
return reduceSetPokemonLeagueStats(state, action as ReturnType<typeof Actions.setPokemonLeagueStats>);
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
|
||||
@ -1,22 +1,14 @@
|
||||
import { ILeaguePokemon } from 'app/models/League';
|
||||
import { IPokemon } from 'app/models/Pokemon';
|
||||
|
||||
import * as PVPogoProtos from 'common/models/PVPogoProtos';
|
||||
|
||||
export interface IPokemonSelectListState {
|
||||
isLoading : boolean;
|
||||
activePokemonId : PVPogoProtos.PokemonId | null;
|
||||
activePokemonForm : PVPogoProtos.PokemonForm | null;
|
||||
pokemonList : Array<IPokemon>;
|
||||
pokemonListFiltered : Array<IPokemon>;
|
||||
filterTerm : string;
|
||||
pokemonLeagueStats : { [id in keyof typeof PVPogoProtos.PokemonId]? : ILeaguePokemon };
|
||||
}
|
||||
|
||||
export const PokemonSelectListActionTypes = {
|
||||
SET_IS_LOADING: 'POKEMON_SELECT_LIST/SET_IS_LOADING',
|
||||
SET_POKEMON_LIST: 'POKEMON_SELECT_LIST/SET_POKEMON_LIST',
|
||||
SET_POKEMON_LIST_FILTERED: 'POKEMON_SELECT_LIST/SET_POKEMON_LIST_FILTERED',
|
||||
SET_ACTIVE_POKEMON_ID: 'POKEMON_SELECT_LIST/SET_ACTIVE_POKEMON_ID',
|
||||
SET_POKEMON_LEAGUE_STATS: 'POKEMON_SELECT_LIST/SET_POKEMON_LEAGUE_STATS',
|
||||
};
|
||||
|
||||
@ -5,7 +5,8 @@ import { BrowserRouter as Router, Redirect, Route, Switch } from 'react-router-d
|
||||
import * as Redux from 'redux';
|
||||
import thunk from 'redux-thunk';
|
||||
|
||||
import { IPokemonAppExtraArguments } from 'app/types';
|
||||
import { routePokemonApp } from 'app/router';
|
||||
import { IPokemonAppExtraArguments, IRouterProps } from 'app/types';
|
||||
|
||||
import { PokemonService } from 'api/PokemonService';
|
||||
|
||||
@ -13,7 +14,7 @@ import { PokemonExplorerReducers } from 'app/components/PokemonExplorer/reducers
|
||||
import { PokemonSelectListReducers } from 'app/components/PokemonSelectList/reducers';
|
||||
import { PokemonAppReducers } from 'app/reducers';
|
||||
|
||||
import { ConnectedPokemonApp } from './PokemonApp';
|
||||
import { ConnectedPokemonApp } from 'app/PokemonApp';
|
||||
|
||||
export const appReducers = Redux.combineReducers({
|
||||
pokemonAppState: PokemonAppReducers,
|
||||
@ -35,11 +36,22 @@ const store = Redux.createStore(
|
||||
)
|
||||
);
|
||||
|
||||
const renderRoutePokemonApp = (props : IRouterProps) => {
|
||||
routePokemonApp(props, store.dispatch);
|
||||
return (
|
||||
<ConnectedPokemonApp
|
||||
history={ props.history }
|
||||
location={ props.location }
|
||||
match={ props.match }
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
ReactDOM.render(
|
||||
<Provider store={ store }>
|
||||
<Router>
|
||||
<Switch>
|
||||
<Route path="/explorer/:id/:form" component={ ConnectedPokemonApp } />
|
||||
<Route path="/explorer/:id/:form" render={ renderRoutePokemonApp } />
|
||||
|
||||
<Redirect from="/" to="/explorer/1/0" />
|
||||
</Switch>
|
||||
|
||||
@ -11,8 +11,9 @@ export const initialState : IPokemonAppState = {
|
||||
baseDefense: 0,
|
||||
level: 0,
|
||||
},
|
||||
attackTypeEffectiveness: new Map(),
|
||||
combatMoves: new Map(),
|
||||
attackTypeEffectiveness: new Map(), // TODO: READONLY after init
|
||||
combatMoves: new Map(), // TODO: READONLY after init
|
||||
pokemonLeagueStats: {}, // TODO: this should be a map, but only if it makes sense with action reducers
|
||||
};
|
||||
|
||||
const reduceSetInterruption = (
|
||||
@ -49,6 +50,17 @@ const reduceSetCombatMoveStats = (
|
||||
combatMoves: action.payload.combatMoves,
|
||||
});
|
||||
|
||||
const reduceSetPokemonLeagueStats = (
|
||||
state : IPokemonAppState,
|
||||
action : ReturnType<typeof Actions.setPokemonLeagueStats>
|
||||
) : IPokemonAppState => ({
|
||||
...state,
|
||||
pokemonLeagueStats: {
|
||||
...state.pokemonLeagueStats,
|
||||
[action.payload.pokemonId + '~' + action.payload.form] : action.payload.pokemonLeagueStats,
|
||||
},
|
||||
});
|
||||
|
||||
export const PokemonAppReducers : Reducer<IPokemonAppState> = (
|
||||
state : IPokemonAppState = initialState,
|
||||
action,
|
||||
@ -62,6 +74,8 @@ export const PokemonAppReducers : Reducer<IPokemonAppState> = (
|
||||
return reduceSetAttackTypeEffectiveness(state, action as ReturnType<typeof Actions.setAttackTypeEffectiveness>);
|
||||
case PokemonAppActionTypes.SET_COMBAT_MOVE_STATS:
|
||||
return reduceSetCombatMoveStats(state, action as ReturnType<typeof Actions.setCombatMoveStats>);
|
||||
case PokemonAppActionTypes.SET_POKEMON_LEAGUE_STATS:
|
||||
return reduceSetPokemonLeagueStats(state, action as ReturnType<typeof Actions.setPokemonLeagueStats>);
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
|
||||
34
src/ts/app/router.ts
Normal file
34
src/ts/app/router.ts
Normal file
@ -0,0 +1,34 @@
|
||||
import { IPokemonAppDispatch, IRouterProps } from 'app/types';
|
||||
|
||||
import * as ActionsPokemonApp from 'app/actions';
|
||||
import * as ActionsPokemonExplorer from 'app/components/PokemonExplorer/actions';
|
||||
|
||||
import { convertFormParamToPokemonForm, convertIdParamToPokemonId, convertLeagueParamToLeague } from 'app/utils/navigation';
|
||||
|
||||
export const routePokemonApp = async (props : IRouterProps, dispatch : IPokemonAppDispatch['dispatch']) => {
|
||||
const {
|
||||
id,
|
||||
form,
|
||||
league,
|
||||
} = props.match.params;
|
||||
|
||||
const pokemonId = convertIdParamToPokemonId(id);
|
||||
const pokemonForm = convertFormParamToPokemonForm(form);
|
||||
if (pokemonId !== null && pokemonForm !== null) {
|
||||
dispatch(ActionsPokemonExplorer.setIsLoading(true));
|
||||
try {
|
||||
const leaguePokemon = await dispatch(ActionsPokemonApp.fetchPokemonLeagueStats(pokemonId, pokemonForm));
|
||||
dispatch(ActionsPokemonExplorer.reset(leaguePokemon));
|
||||
} catch (error) {
|
||||
// tslint:disable-next-line:no-console
|
||||
console.error(error);
|
||||
dispatch(ActionsPokemonExplorer.setLeaguePokemon(null));
|
||||
}
|
||||
dispatch(ActionsPokemonExplorer.setIsLoading(false));
|
||||
}
|
||||
|
||||
const activeLeague = convertLeagueParamToLeague(league);
|
||||
if (activeLeague !== null) {
|
||||
dispatch(ActionsPokemonExplorer.setActiveLeague(activeLeague));
|
||||
}
|
||||
};
|
||||
@ -2,12 +2,13 @@ import { RouteComponentProps } from 'react-router-dom';
|
||||
import { Action } from 'redux';
|
||||
import { ThunkAction, ThunkDispatch } from 'redux-thunk';
|
||||
|
||||
import { AttackTypeEffectiveness } from 'app/models/Config';
|
||||
import { ILeaguePokemon } from 'app/models/League';
|
||||
import { CombatMoveStats, IMaxStats } from 'app/models/Pokemon';
|
||||
import { IProviderExtraArguments } from 'common/models/IProviderExtraArguments';
|
||||
|
||||
import { IPokemonExplorerStore } from 'app/components/PokemonExplorer/types';
|
||||
import { IPokemonSelectListState } from 'app/components/PokemonSelectList/types';
|
||||
import { AttackTypeEffectiveness } from 'app/models/Config';
|
||||
import { CombatMoveStats, IMaxStats } from 'app/models/Pokemon';
|
||||
|
||||
import { PokemonService } from 'api/PokemonService';
|
||||
|
||||
@ -16,6 +17,7 @@ export interface IPokemonAppState {
|
||||
maxPossibleStats : IMaxStats;
|
||||
attackTypeEffectiveness : AttackTypeEffectiveness;
|
||||
combatMoves : CombatMoveStats;
|
||||
pokemonLeagueStats : { [key : string] : ILeaguePokemon }; // TODO: map?
|
||||
}
|
||||
|
||||
export const PokemonAppActionTypes = {
|
||||
@ -23,9 +25,11 @@ export const PokemonAppActionTypes = {
|
||||
SET_MAX_STATS: 'POKEMON_APP/SET_MAX_STATS',
|
||||
SET_ATTACK_TYPE_EFFECTIVENESS: 'POKEMON_APP/SET_ATTACK_TYPE_EFFECTIVENESS',
|
||||
SET_COMBAT_MOVE_STATS: 'POKEMON_APP/SET_COMBAT_MOVE_STATS',
|
||||
SET_POKEMON_LEAGUE_STATS: 'POKEMON_SELECT_LIST/SET_POKEMON_LEAGUE_STATS',
|
||||
};
|
||||
|
||||
export interface IPokemonAppStore extends IPokemonExplorerStore {
|
||||
pokemonAppState : IPokemonAppState;
|
||||
pokemonSelectListState : IPokemonSelectListState;
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,8 @@
|
||||
import { RouteComponentProps } from 'react-router-dom';
|
||||
|
||||
import { League } from 'app/models/League';
|
||||
import * as PVPogoProtos from 'common/models/PVPogoProtos';
|
||||
|
||||
export const getCurrentQueryString = (location : RouteComponentProps['location'] | Window['location']) => {
|
||||
const search = new URLSearchParams(location.search);
|
||||
return '?' + search.toString();
|
||||
@ -17,3 +20,30 @@ export const appendQueryString = (location : RouteComponentProps['location'] | W
|
||||
});
|
||||
return '?' + search.toString();
|
||||
};
|
||||
|
||||
export const convertIdParamToPokemonId = (id : string) : PVPogoProtos.PokemonId | null => {
|
||||
const pokemonId = id ? parseInt(id, 10) : null;
|
||||
if (pokemonId !== null && typeof PVPogoProtos.PokemonId[pokemonId] !== 'undefined') {
|
||||
return pokemonId;
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
export const convertFormParamToPokemonForm = (form : string) : PVPogoProtos.PokemonForm | null => {
|
||||
const pokemonForm = form ? parseInt(form, 10) : null;
|
||||
if (pokemonForm !== null && typeof PVPogoProtos.PokemonForm[pokemonForm] !== 'undefined') {
|
||||
return pokemonForm;
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
export const convertLeagueParamToLeague = (leagueParam : string) : League | null => {
|
||||
const league = leagueParam ? parseInt(leagueParam, 10) : null;
|
||||
if (league !== null && typeof League[league] !== 'undefined') {
|
||||
return league;
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user