load pokemon league stats into state

This commit is contained in:
Jeff Colombo 2019-01-19 00:41:50 -05:00
parent 790df65780
commit 6b93730057
13 changed files with 191 additions and 38 deletions

View File

@ -175,7 +175,8 @@ Pokemon.forEach((mon) => {
fs.mkdir(outPath, {recursive: true}, () => {
fs.writeFile(outPath + mon.id + '.json', JSON.stringify(pokemon), (err) => {
if(err) {
if (err) {
/* tslint:disable-next-line:no-console */
return console.log(mon.name, err);
}
});
@ -202,7 +203,8 @@ familyOrder.forEach((familyId) => {
fs.mkdir(outPath, {recursive: true}, () => {
fs.writeFile(outPath + 'order.json', JSON.stringify(pokemonOrder), (err) => {
if(err) {
if (err) {
/* tslint:disable-next-line:no-console */
return console.log('order', err);
}
});

View File

@ -1,24 +1,13 @@
import { AjaxUtils } from 'api/AjaxUtils';
import { IPokemon } from 'app/models/Pokemon';
import { ILeaguePokemon, IPokemon, League } from 'app/models/Pokemon';
interface IPokemonJSON extends IPokemon {}
interface ILeaguePokemonJSON extends ILeaguePokemon {}
interface IPokemonService {}
export class PokemonService implements IPokemonService {
public getPokemonList() {
const queryParameters = {
type: 'no touch',
is_active: true,
};
return AjaxUtils.ajaxGet('/dist/db/order.json', queryParameters)
.then((response : Array<IPokemonJSON>) => {
return Promise.resolve(this.serializePokemonList(response));
});
}
private serializePokemonList(jsonPokemonList : Array<IPokemonJSON>) : Array<IPokemon> {
private static serializePokemonList(jsonPokemonList : Array<IPokemonJSON>) : Array<IPokemon> {
const pokemonList = jsonPokemonList.reduce((result : Array<IPokemon>, pokemonJson) => {
try {
if (typeof pokemonJson.name !== 'string') {
@ -46,4 +35,62 @@ export class PokemonService implements IPokemonService {
}, []);
return pokemonList;
}
private static serializePokemonLeagueStats(jsonPokemonLeagueStats : ILeaguePokemonJSON) : ILeaguePokemon {
let pokemonLeagueStats : ILeaguePokemon;
try {
if (typeof jsonPokemonLeagueStats.name !== 'string') {
throw new Error('pokemon league stats missing name');
}
if (typeof jsonPokemonLeagueStats.id !== 'string') {
throw new Error('pokemon league stats missing id');
}
if (typeof jsonPokemonLeagueStats.family !== 'string') {
throw new Error('pokemon league stats missing family');
}
if (typeof jsonPokemonLeagueStats.dex !== 'number') {
throw new Error('pokemon league stats missing dex');
}
if (typeof jsonPokemonLeagueStats.stats !== 'object') {
throw new Error('pokemon league stats missing stats');
}
if (typeof jsonPokemonLeagueStats.pvp !== 'object') {
throw new Error('pokemon league stats missing pvp');
}
pokemonLeagueStats = { ...jsonPokemonLeagueStats };
Object.keys(pokemonLeagueStats.pvp).forEach((key) => {
const league = key as League;
if (!Array.isArray(pokemonLeagueStats.pvp[league])) {
throw new Error('pokemon league not an array');
}
pokemonLeagueStats.pvp[league] = [ ...jsonPokemonLeagueStats.pvp[league] ];
});
} catch (e) {
/* tslint:disable-next-line:no-console */
console.error(jsonPokemonLeagueStats, e.message);
throw e;
}
return pokemonLeagueStats;
}
public getPokemonList() {
const queryParameters = {
};
return AjaxUtils.ajaxGet('/dist/db/order.json', queryParameters)
.then((response : Array<IPokemonJSON>) => {
return Promise.resolve(PokemonService.serializePokemonList(response));
});
}
public getPokemonLeagueStats(pokemonId : string) {
const queryParameters = {
};
return AjaxUtils.ajaxGet(`/dist/db/${ pokemonId }.json`, queryParameters)
.then((response : ILeaguePokemonJSON) => {
return Promise.resolve(PokemonService.serializePokemonLeagueStats(response));
});
}
}

View File

@ -4,10 +4,10 @@ import { Dispatch } from 'redux';
import { appReducers } from './index';
import * as ActionsPokemonSelectList from './PokemonSelectList/actions';
import { ThunkDispatchPokemonSelectList } from './PokemonSelectList/types';
import * as ActionsPokemonApp from './actions';
import { ThunkDispatchPokemonSelectList } from './types';
import { PokemonSelectList } from './PokemonSelectList/PokemonSelectList';
import { PokemonSelectList } from './components/PokemonSelectList';
type PokemonAppProps = ReturnType<typeof appReducers>;
@ -21,7 +21,7 @@ class PokemonApp extends React.Component<IConnectedPokemonAppProps> {
}
public componentWillMount() {
this.props.dispatch(ActionsPokemonSelectList.fetchPokemonList());
this.props.dispatch(ActionsPokemonApp.fetchPokemonList());
}
public render() {
@ -36,7 +36,8 @@ class PokemonApp extends React.Component<IConnectedPokemonAppProps> {
}
private readonly onActivatePokemon = (pokemonIndex : number) => {
this.props.dispatch(ActionsPokemonSelectList.setActivePokemonIndex(pokemonIndex));
this.props.dispatch(ActionsPokemonApp.setActivePokemonIndex(pokemonIndex));
this.props.dispatch(ActionsPokemonApp.fetchPokemonLeagueStats(this.props.pokemonSelectListState.pokemonList[pokemonIndex].id));
}
}

31
src/ts/app/actions.js Normal file
View File

@ -0,0 +1,31 @@
"use strict";
exports.__esModule = true;
var typesafe_actions_1 = require("typesafe-actions");
var types_1 = require("./types");
exports.setPokemonList = function (pokemonList) { return typesafe_actions_1.action(types_1.PokemonSelectListActionTypes.SET_POKEMON_LIST, { pokemonList: pokemonList }); };
exports.setActivePokemonIndex = function (activePokemonIndex) { return typesafe_actions_1.action(types_1.PokemonSelectListActionTypes.SET_ACTIVE_POKEMON_INDEX, { activePokemonIndex: activePokemonIndex }); };
exports.setPokemonLeagueStats = function (pokemonId, pokemonLeagueStats) { return typesafe_actions_1.action(types_1.PokemonSelectListActionTypes.SET_POKEMON_LEAGUE_STATS, { pokemonId: pokemonId, pokemonLeagueStats: pokemonLeagueStats }); };
exports.fetchPokemonList = function () {
return function (dispatch, getState, extraArguments) {
return new Promise(function (resolve, reject) {
extraArguments.services.pokemonService.getPokemonList()
.then(function (pokemonList) {
dispatch(exports.setPokemonList(pokemonList));
resolve();
});
});
};
};
exports.fetchPokemonLeagueStats = function (pokemonId) {
return function (dispatch, getState, extraArguments) {
return new Promise(function (resolve, reject) {
extraArguments.services.pokemonService.getPokemonLeagueStats(pokemonId)
.then(function (pokemonLeagueStats) {
dispatch(exports.setPokemonLeagueStats(pokemonId, pokemonLeagueStats));
resolve();
})["catch"](function () {
reject();
});
});
};
};

View File

@ -1,6 +1,6 @@
import { action } from 'typesafe-actions';
import { IPokemon } from 'app/models/Pokemon';
import { ILeaguePokemon, IPokemon } from 'app/models/Pokemon';
import { PokemonSelectListActionTypes, ThunkResult } from './types';
@ -8,6 +8,8 @@ export const setPokemonList = (pokemonList : Array<IPokemon>) => action(PokemonS
export const setActivePokemonIndex = (activePokemonIndex : number) => action(PokemonSelectListActionTypes.SET_ACTIVE_POKEMON_INDEX, { activePokemonIndex });
export const setPokemonLeagueStats = (pokemonId : string, pokemonLeagueStats : ILeaguePokemon) => action(PokemonSelectListActionTypes.SET_POKEMON_LEAGUE_STATS, { pokemonId, pokemonLeagueStats });
export const fetchPokemonList = (
) : ThunkResult<Promise<void>> => {
return (dispatch, getState, extraArguments) => {
@ -20,3 +22,20 @@ export const fetchPokemonList = (
});
};
};
export const fetchPokemonLeagueStats = (
pokemonId : string
) : ThunkResult<Promise<void>> => {
return (dispatch, getState, extraArguments) => {
return new Promise<void>((resolve, reject) => {
extraArguments.services.pokemonService.getPokemonLeagueStats(pokemonId)
.then((pokemonLeagueStats) => {
dispatch(setPokemonLeagueStats(pokemonId, pokemonLeagueStats));
resolve();
})
.catch(() => {
reject();
});
});
};
};

View File

@ -4,11 +4,11 @@ import { Provider } from 'react-redux';
import * as Redux from 'redux';
import thunk from 'redux-thunk';
import { IPokemonSelectListExtraArguments } from 'app/PokemonSelectList/types';
import { IPokemonSelectListExtraArguments } from 'app/types';
import { PokemonService } from 'api/PokemonService';
import { PokemonSelectListReducers } from './PokemonSelectList/reducers';
import { PokemonSelectListReducers } from './reducers';
import { ConnectedPokemonApp } from './PokemonApp';

39
src/ts/app/reducers.js Normal file
View File

@ -0,0 +1,39 @@
"use strict";
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
exports.__esModule = true;
var types_1 = require("./types");
exports.initialState = {
activePokemonIndex: -1,
pokemonList: [],
pokemonListFiltered: [],
pokemonLeagueStats: {}
};
var reduceSetPokemonList = function (state, action) { return (__assign({}, state, { pokemonList: action.payload.pokemonList })); };
var reduceSetActivePokemonIndex = function (state, action) { return (__assign({}, state, { activePokemonIndex: action.payload.activePokemonIndex })); };
var reduceSetPokemonLeagueStats = function (state, action) {
var _a;
return (__assign({}, state, { pokemonLeagueStats: __assign({}, state.pokemonLeagueStats, (_a = {}, _a[action.payload.pokemonId] = action.payload.pokemonStats, _a)) }));
};
exports.PokemonSelectListReducers = function (state, action) {
if (state === void 0) { state = exports.initialState; }
switch (action.type) {
case types_1.PokemonSelectListActionTypes.SET_POKEMON_LIST:
return reduceSetPokemonList(state, action);
case types_1.PokemonSelectListActionTypes.SET_ACTIVE_POKEMON_INDEX:
return reduceSetActivePokemonIndex(state, action);
case types_1.PokemonSelectListActionTypes.SET_POKEMON_LEAGUE_STATS:
return reduceSetPokemonLeagueStats(state, action);
default:
return state;
}
};

View File

@ -7,6 +7,7 @@ export const initialState : IPokemonSelectListState = {
activePokemonIndex: -1,
pokemonList: [],
pokemonListFiltered: [],
pokemonLeagueStats: {}
};
const reduceSetPokemonList = (
@ -25,6 +26,17 @@ const reduceSetActivePokemonIndex = (
activePokemonIndex: action.payload.activePokemonIndex,
});
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,
@ -34,6 +46,8 @@ export const PokemonSelectListReducers : Reducer<IPokemonSelectListState> = (
return reduceSetPokemonList(state, action as ReturnType<typeof Actions.setPokemonList>);
case PokemonSelectListActionTypes.SET_ACTIVE_POKEMON_INDEX:
return reduceSetActivePokemonIndex(state, action as ReturnType<typeof Actions.setActivePokemonIndex>);
case PokemonSelectListActionTypes.SET_POKEMON_LEAGUE_STATS:
return reduceSetPokemonLeagueStats(state, action as ReturnType<typeof Actions.setPokemonLeagueStats>);
default:
return state;
}

7
src/ts/app/types.js Normal file
View File

@ -0,0 +1,7 @@
"use strict";
exports.__esModule = true;
exports.PokemonSelectListActionTypes = {
SET_POKEMON_LIST: 'POKEMON_APP/SET_POKEMON_LIST',
SET_ACTIVE_POKEMON_INDEX: 'POKEMON_APP/SET_ACTIVE_POKEMON_INDEX',
SET_POKEMON_LEAGUE_STATS: 'POKEMON_APP/SET_POKEMON_LEAGUE_STATS'
};

View File

@ -5,12 +5,13 @@ import { IProviderExtraArguments } from 'common/models/IProviderExtraArguments';
import { PokemonService } from 'api/PokemonService';
import { IPokemon } from 'app/models/Pokemon';
import { ILeaguePokemon, IPokemon } from 'app/models/Pokemon';
export interface IPokemonSelectListState {
activePokemonIndex : number;
pokemonList : Array<IPokemon>;
pokemonListFiltered : Array<IPokemon>;
pokemonLeagueStats : { [id : string] : ILeaguePokemon };
}
export interface IPokemonSelectListStore {
@ -29,6 +30,7 @@ export type ThunkResult<R> = ThunkAction<R, IPokemonSelectListStore, IPokemonSel
export type ThunkDispatchPokemonSelectList = ThunkDispatch<IPokemonSelectListStore, IPokemonSelectListExtraArguments, Action>;
export const PokemonSelectListActionTypes = {
SET_POKEMON_LIST: 'POKEMON_SELECT_LIST/SET_POKEMON_LIST',
SET_ACTIVE_POKEMON_INDEX: 'POKEMON_SELECT_LIST/SET_ACTIVE_POKEMON_INDEX',
SET_POKEMON_LIST: 'POKEMON_APP/SET_POKEMON_LIST',
SET_ACTIVE_POKEMON_INDEX: 'POKEMON_APP/SET_ACTIVE_POKEMON_INDEX',
SET_POKEMON_LEAGUE_STATS: 'POKEMON_APP/SET_POKEMON_LEAGUE_STATS',
};

View File

@ -17,11 +17,8 @@ const typescriptResolve = {
extensions: ['.ts', '.tsx', '.js'],
};
module.exports = function (env, tsLoaderHappyPackMode) {
module.exports = function (env) {
env = env || {};
tsLoaderHappyPackMode = (typeof tsLoaderHappyPackMode === 'undefined') ? true : tsLoaderHappyPackMode;
console.log('Webpack Environment:', env, 'tsLoaderHappyPackMode:', !!tsLoaderHappyPackMode);
const plugins = [
new StyleLintPlugin({
@ -99,13 +96,7 @@ module.exports = function (env, tsLoaderHappyPackMode) {
exclude: /node_modules/,
use: [
{ loader: 'babel-loader' },
{
loader: 'ts-loader',
options: {
silent: true,
happyPackMode: tsLoaderHappyPackMode, // setting as true also implies transpileOnly: true,
}
}
{ loader: 'ts-loader' },
]
},
{