set ivs
This commit is contained in:
parent
f887b3e13e
commit
5ba1d48c7a
@ -7,6 +7,8 @@ import * as ActionsPokemonExplorer from './components/PokemonExplorer/actions';
|
||||
import * as ActionsPokemonSelectList from './components/PokemonSelectList/actions';
|
||||
import { ThunkDispatchPokemonSelectList } from './types';
|
||||
|
||||
import { IndividualValueKey } from './components/PokemonExplorer/types';
|
||||
|
||||
import { PokemonExplorer } from './components/PokemonExplorer/PokemonExplorer';
|
||||
import { PokemonSelectList } from './components/PokemonSelectList/PokemonSelectList';
|
||||
|
||||
@ -32,6 +34,7 @@ class PokemonApp extends React.Component<IConnectedPokemonAppProps> {
|
||||
pokemonList,
|
||||
} = this.props.pokemonSelectListState;
|
||||
const {
|
||||
individualValues,
|
||||
leaguePokemon,
|
||||
} = this.props.pokemonExplorerState;
|
||||
|
||||
@ -41,19 +44,21 @@ class PokemonApp extends React.Component<IConnectedPokemonAppProps> {
|
||||
isLoading={ this.props.pokemonSelectListState.isLoading }
|
||||
activePokemonIndex={ activePokemonIndex }
|
||||
pokemonList={ pokemonList }
|
||||
onActivatePokemon={ this.onActivatePokemon }
|
||||
handleActivatePokemon={ this.handleActivatePokemon }
|
||||
/>
|
||||
{ leaguePokemon !== null &&
|
||||
<PokemonExplorer
|
||||
isLoading={ this.props.pokemonExplorerState.isLoading }
|
||||
leaguePokemon={ leaguePokemon }
|
||||
individualValues={ individualValues }
|
||||
handleChangeIndividualValue={ this.handleChangeIndividualValue }
|
||||
/>
|
||||
}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
private readonly onActivatePokemon = (pokemonIndex : number) => {
|
||||
private readonly handleActivatePokemon = (pokemonIndex : number) => {
|
||||
const { dispatch, pokemonSelectListState } = this.props;
|
||||
const pokemonId = pokemonSelectListState.pokemonList[pokemonIndex].id;
|
||||
|
||||
@ -69,6 +74,27 @@ class PokemonApp extends React.Component<IConnectedPokemonAppProps> {
|
||||
})
|
||||
.then(() => dispatch(ActionsPokemonExplorer.setIsLoading(false)));
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = (state : ReturnType<typeof appReducers>) : PokemonAppProps => {
|
||||
|
||||
@ -2,16 +2,157 @@ import React from 'react';
|
||||
|
||||
import { ILeaguePokemon } from 'app/models/Pokemon';
|
||||
|
||||
export interface IPokemonSelectListProps {
|
||||
import { IIndividualValues, IndividualValueKey } from './types';
|
||||
|
||||
export interface IPokemonExplorerProps {
|
||||
isLoading : boolean;
|
||||
leaguePokemon : ILeaguePokemon;
|
||||
individualValues : IIndividualValues;
|
||||
|
||||
handleChangeIndividualValue : (stat : IndividualValueKey, value : number | null) => void;
|
||||
}
|
||||
|
||||
interface IState {
|
||||
}
|
||||
|
||||
export class PokemonExplorer extends React.Component<IPokemonSelectListProps, IState> {
|
||||
export class PokemonExplorer extends React.Component<IPokemonExplorerProps, IState> {
|
||||
private readonly MIN_LEVEL = 1;
|
||||
private readonly MAX_LEVEL = 40;
|
||||
private readonly MIN_IV = 0;
|
||||
private readonly MAX_IV = 15;
|
||||
|
||||
private onChangeHp : (event : React.ChangeEvent<HTMLInputElement>) => void;
|
||||
private onChangeAtk : (event : React.ChangeEvent<HTMLInputElement>) => void;
|
||||
private onChangeDef : (event : React.ChangeEvent<HTMLInputElement>) => void;
|
||||
|
||||
constructor(props : IPokemonExplorerProps) {
|
||||
super(props);
|
||||
|
||||
this.onChangeHp = this.onChangeIvFactory('hp');
|
||||
this.onChangeAtk = this.onChangeIvFactory('atk');
|
||||
this.onChangeDef = this.onChangeIvFactory('def');
|
||||
}
|
||||
|
||||
public render() {
|
||||
return (<div>{ this.props.leaguePokemon.name }</div>);
|
||||
const {
|
||||
individualValues,
|
||||
leaguePokemon
|
||||
} = this.props;
|
||||
|
||||
const placeholderLevel = '40';
|
||||
const placeholderHp = '15';
|
||||
const placeholderAtk = '15';
|
||||
const placeholderDef = '15';
|
||||
|
||||
return (
|
||||
<div id="pokemon-explorer">
|
||||
<h2 className="pokemon-info">
|
||||
<span>{ this.formatDexNumber(leaguePokemon.dex) }</span>
|
||||
{ leaguePokemon.name }
|
||||
</h2>
|
||||
<div className="pokemon-base-stats">
|
||||
<div>Base Stats</div>
|
||||
<div className="pokemon-type type-1">{ }</div>
|
||||
<div className="pokemon-type type-2">{ }</div>
|
||||
<div>{ leaguePokemon.stats.baseStamina }</div>
|
||||
<div>{ leaguePokemon.stats.baseAttack }</div>
|
||||
<div>{ leaguePokemon.stats.baseDefense }</div>
|
||||
</div>
|
||||
<div className="pokemon-individual-stats">
|
||||
<div>
|
||||
<h5>Level</h5>
|
||||
<input
|
||||
name="level"
|
||||
type="number"
|
||||
min={ this.MIN_LEVEL }
|
||||
max={ this.MAX_LEVEL }
|
||||
maxLength={ 2 }
|
||||
onChange={ this.onChangeLevel }
|
||||
value={ individualValues.level || '' }
|
||||
placeholder={ placeholderLevel }
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<h5>IVs</h5>
|
||||
<label>
|
||||
<input
|
||||
name="hp"
|
||||
type="number"
|
||||
min={ this.MIN_IV }
|
||||
max={ this.MAX_IV }
|
||||
maxLength={ 2 }
|
||||
onChange={ this.onChangeHp }
|
||||
value={ individualValues.hp || '' }
|
||||
placeholder={ placeholderHp }
|
||||
/> HP
|
||||
</label>
|
||||
<label>
|
||||
<input
|
||||
name="atk"
|
||||
type="number"
|
||||
min={ this.MIN_IV }
|
||||
max={ this.MAX_IV }
|
||||
maxLength={ 2 }
|
||||
onChange={ this.onChangeAtk }
|
||||
value={ individualValues.atk || '' }
|
||||
placeholder={ placeholderAtk }
|
||||
/> ATK
|
||||
</label>
|
||||
<label>
|
||||
<input
|
||||
name="def"
|
||||
type="number"
|
||||
min={ this.MIN_IV }
|
||||
max={ this.MAX_IV }
|
||||
maxLength={ 2 }
|
||||
onChange={ this.onChangeDef }
|
||||
value={ individualValues.def || '' }
|
||||
placeholder={ placeholderDef }
|
||||
/> DEF
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div className="league-pokemon-rank">
|
||||
<div className="league-pokemon-stat pokemon-rank"><span>{ }</span> Rank</div>
|
||||
<div className="league-pokemon-stat pokemon-cp">CP <span>{ }</span></div>
|
||||
<div className="league-pokemon-stat"><span>{ }</span> HP</div>
|
||||
<div className="league-pokemon-stat"><span>{ }</span> ATK</div>
|
||||
<div className="league-pokemon-stat"><span>{ }</span> DEF</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
private formatDexNumber(dex : number) {
|
||||
let prefix : string = '#';
|
||||
if (dex < 100) {
|
||||
prefix += '0';
|
||||
}
|
||||
if (dex < 10) {
|
||||
prefix += '0';
|
||||
}
|
||||
return prefix + dex;
|
||||
}
|
||||
|
||||
private readonly onChangeLevel = (event : React.ChangeEvent<HTMLInputElement>) => {
|
||||
const raw = event.currentTarget.value;
|
||||
const value = parseInt(raw, 10);
|
||||
if (raw === '' + value && value >= this.MIN_LEVEL && value <= this.MAX_LEVEL) {
|
||||
this.props.handleChangeIndividualValue('level', value);
|
||||
} else if (raw === '') {
|
||||
this.props.handleChangeIndividualValue('level', null);
|
||||
}
|
||||
}
|
||||
|
||||
private readonly onChangeIvFactory = (type : IndividualValueKey) => {
|
||||
return (event : React.ChangeEvent<HTMLInputElement>) => {
|
||||
const raw = event.currentTarget.value;
|
||||
const value = parseInt(raw, 10);
|
||||
if (raw === '' + value && value >= this.MIN_IV && value <= this.MAX_IV) {
|
||||
this.props.handleChangeIndividualValue(type, value);
|
||||
} else if (raw === '') {
|
||||
this.props.handleChangeIndividualValue(type, null);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,3 +7,11 @@ import { ILeaguePokemon } from 'app/models/Pokemon';
|
||||
export const setIsLoading = (isLoading : boolean) => action(PokemonExplorerActionTypes.SET_IS_LOADING, { isLoading });
|
||||
|
||||
export const setLeaguePokemon = (leaguePokemon : ILeaguePokemon | null) => action(PokemonExplorerActionTypes.SET_LEAGUE_POKEMON, { leaguePokemon });
|
||||
|
||||
export const setIvLevel = (level : number | null) => action(PokemonExplorerActionTypes.SET_IV_LEVEL, { level });
|
||||
|
||||
export const setIvHp = (hp : number | null) => action(PokemonExplorerActionTypes.SET_IV_HP, { hp });
|
||||
|
||||
export const setIvAtk = (atk : number | null) => action(PokemonExplorerActionTypes.SET_IV_ATK, { atk });
|
||||
|
||||
export const setIvDef = (def : number | null) => action(PokemonExplorerActionTypes.SET_IV_DEF, { def });
|
||||
|
||||
@ -6,6 +6,12 @@ import { IPokemonExplorerState, PokemonExplorerActionTypes } from './types';
|
||||
export const initialState : IPokemonExplorerState = {
|
||||
isLoading: false,
|
||||
leaguePokemon: null,
|
||||
individualValues: {
|
||||
level: null,
|
||||
hp: null,
|
||||
atk: null,
|
||||
def: null,
|
||||
},
|
||||
};
|
||||
|
||||
const reduceSetIsLoading = (
|
||||
@ -24,6 +30,50 @@ const reduceSetLeaguePokemon = (
|
||||
leaguePokemon: action.payload.leaguePokemon,
|
||||
});
|
||||
|
||||
const reduceSetIvLevel = (
|
||||
state : IPokemonExplorerState,
|
||||
action : ReturnType<typeof Actions.setIvLevel>
|
||||
) : IPokemonExplorerState => ({
|
||||
...state,
|
||||
individualValues: {
|
||||
...state.individualValues,
|
||||
level: action.payload.level,
|
||||
}
|
||||
});
|
||||
|
||||
const reduceSetIvHp = (
|
||||
state : IPokemonExplorerState,
|
||||
action : ReturnType<typeof Actions.setIvHp>
|
||||
) : IPokemonExplorerState => ({
|
||||
...state,
|
||||
individualValues: {
|
||||
...state.individualValues,
|
||||
hp: action.payload.hp,
|
||||
}
|
||||
});
|
||||
|
||||
const reduceSetIvAtk = (
|
||||
state : IPokemonExplorerState,
|
||||
action : ReturnType<typeof Actions.setIvAtk>
|
||||
) : IPokemonExplorerState => ({
|
||||
...state,
|
||||
individualValues: {
|
||||
...state.individualValues,
|
||||
atk: action.payload.atk,
|
||||
}
|
||||
});
|
||||
|
||||
const reduceSetIvDef = (
|
||||
state : IPokemonExplorerState,
|
||||
action : ReturnType<typeof Actions.setIvDef>
|
||||
) : IPokemonExplorerState => ({
|
||||
...state,
|
||||
individualValues: {
|
||||
...state.individualValues,
|
||||
def: action.payload.def,
|
||||
}
|
||||
});
|
||||
|
||||
export const PokemonExplorerReducers : Reducer<IPokemonExplorerState> = (
|
||||
state : IPokemonExplorerState = initialState,
|
||||
action,
|
||||
@ -33,6 +83,14 @@ export const PokemonExplorerReducers : Reducer<IPokemonExplorerState> = (
|
||||
return reduceSetIsLoading(state, action as ReturnType<typeof Actions.setIsLoading>);
|
||||
case PokemonExplorerActionTypes.SET_LEAGUE_POKEMON:
|
||||
return reduceSetLeaguePokemon(state, action as ReturnType<typeof Actions.setLeaguePokemon>);
|
||||
case PokemonExplorerActionTypes.SET_IV_LEVEL:
|
||||
return reduceSetIvLevel(state, action as ReturnType<typeof Actions.setIvLevel>);
|
||||
case PokemonExplorerActionTypes.SET_IV_HP:
|
||||
return reduceSetIvHp(state, action as ReturnType<typeof Actions.setIvHp>);
|
||||
case PokemonExplorerActionTypes.SET_IV_ATK:
|
||||
return reduceSetIvAtk(state, action as ReturnType<typeof Actions.setIvAtk>);
|
||||
case PokemonExplorerActionTypes.SET_IV_DEF:
|
||||
return reduceSetIvDef(state, action as ReturnType<typeof Actions.setIvDef>);
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
|
||||
@ -1,11 +1,24 @@
|
||||
import { ILeaguePokemon } from 'app/models/Pokemon';
|
||||
|
||||
export type IndividualValueKey = 'level' | 'hp' | 'atk' | 'def';
|
||||
export interface IIndividualValues {
|
||||
level : number | null;
|
||||
hp : number | null;
|
||||
atk : number | null;
|
||||
def : number | null;
|
||||
}
|
||||
|
||||
export interface IPokemonExplorerState {
|
||||
isLoading : boolean;
|
||||
leaguePokemon : ILeaguePokemon | null;
|
||||
individualValues : IIndividualValues;
|
||||
}
|
||||
|
||||
export const PokemonExplorerActionTypes = {
|
||||
SET_IS_LOADING: 'POKEMON_EXPLORER/SET_IS_LOADING',
|
||||
SET_LEAGUE_POKEMON: 'POKEMON_EXPLORER/SET_LEAGUE_POKEMON',
|
||||
SET_IV_LEVEL: 'POKEMON_EXPLORER/SET_IV_LEVEL',
|
||||
SET_IV_HP: 'POKEMON_EXPLORER/SET_IV_HP',
|
||||
SET_IV_ATK: 'POKEMON_EXPLORER/SET_IV_ATK',
|
||||
SET_IV_DEF: 'POKEMON_EXPLORER/SET_IV_DEF',
|
||||
};
|
||||
|
||||
@ -11,7 +11,7 @@ export interface IPokemonSelectListProps {
|
||||
activePokemonIndex : number | null;
|
||||
pokemonList : Array<IPokemon>;
|
||||
|
||||
onActivatePokemon : (index : number) => void;
|
||||
handleActivatePokemon : (index : number) => void;
|
||||
}
|
||||
|
||||
interface IState {
|
||||
@ -51,7 +51,7 @@ export class PokemonSelectList extends React.Component<IPokemonSelectListProps,
|
||||
});
|
||||
|
||||
return (
|
||||
<div className={ classes } style={ { height: '400px' } }>
|
||||
<div id="pokemon-select-list" className={ classes } style={ { height: '400px' } }>
|
||||
<Measure
|
||||
bounds={ true }
|
||||
onResize={ onResize }
|
||||
@ -80,7 +80,7 @@ export class PokemonSelectList extends React.Component<IPokemonSelectListProps,
|
||||
const css = classNames({
|
||||
active: this.props.activePokemonIndex === index
|
||||
});
|
||||
const onClick = () => this.props.onActivatePokemon(index);
|
||||
const onClick = () => this.props.handleActivatePokemon(index);
|
||||
return <div key={ index } style={ style } className={ css } onClick={ onClick }>{ pokemon.name }</div>;
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user