From dd37703417a720fba84a2f3f563d20fa2ac5d767 Mon Sep 17 00:00:00 2001 From: Jeff Colombo Date: Mon, 11 Mar 2019 00:43:22 -0400 Subject: [PATCH] split pokemon explorer from pokemon app --- dist/app.css | 126 +- dist/main-bundle.js | 1120 +++++++++++------ src/ts/app/PokemonApp.tsx | 266 +--- src/ts/app/actions.ts | 62 +- src/ts/app/components/IvForm.tsx | 2 +- src/ts/app/components/LeagueIvExplorer.tsx | 2 +- src/ts/app/components/LeagueStatsList.tsx | 2 +- src/ts/app/components/MovesExplorer.tsx | 4 +- .../PokemonExplorer/PokemonExplorer.tsx | 298 +++++ .../app/components/PokemonExplorer/actions.ts | 62 + .../components/PokemonExplorer/reducers.ts | 144 +++ .../app/components/PokemonExplorer/types.ts | 66 + src/ts/app/index.tsx | 4 +- src/ts/app/reducers.ts | 165 +-- src/ts/app/types.ts | 77 +- 15 files changed, 1453 insertions(+), 947 deletions(-) create mode 100644 src/ts/app/components/PokemonExplorer/PokemonExplorer.tsx create mode 100644 src/ts/app/components/PokemonExplorer/actions.ts create mode 100644 src/ts/app/components/PokemonExplorer/reducers.ts create mode 100644 src/ts/app/components/PokemonExplorer/types.ts diff --git a/dist/app.css b/dist/app.css index 7427db1..8d1dc1f 100644 --- a/dist/app.css +++ b/dist/app.css @@ -440,69 +440,6 @@ align-items: start; align-self: stretch; } -.PokemonSelectList__wrapper__2LQMY { - font-size: 0.8rem; - width: 20em; - display: flex; - flex-flow: column nowrap; - margin: 0 1.5em 0 auto; - position: relative; } - .PokemonSelectList__wrapper__2LQMY .PokemonSelectList__listWrapper__bBtO6 { - flex: 1 1 auto; - display: flex; - padding: 0; - overflow: hidden; - height: 340px; - position: absolute; - top: 100%; - left: 0; - right: 0; - z-index: 2; } - .PokemonSelectList__wrapper__2LQMY .PokemonSelectList__listWrapper__bBtO6 > * { - width: 100%; } - .PokemonSelectList__wrapper__2LQMY .PokemonSelectList__listWrapper__bBtO6.PokemonSelectList__emptyList__1vgpK .PokemonSelectList__emptyState__3sBmb { - align-self: center; - text-align: center; } - .PokemonSelectList__wrapper__2LQMY .PokemonSelectList__listWrapper__bBtO6.PokemonSelectList__emptyList__1vgpK .PokemonSelectList__emptyState__3sBmb > *:first-child { - margin: 1em auto; } - .PokemonSelectList__wrapper__2LQMY a { - color: inherit; - text-decoration: none; - padding: 5px 1em 5px 2em; - justify-content: flex-end; - align-content: space-around; - flex-wrap: wrap; - display: flex; } - .PokemonSelectList__wrapper__2LQMY a .PokemonSelectList__menuIcon__1I2_T { - margin: -4px 0 0 0.5em; - opacity: 0.5; } - .PokemonSelectList__wrapper__2LQMY a.active .PokemonSelectList__menuIcon__1I2_T { - opacity: 1; } - -.PokemonSelectList__filterWrapper__1d1Wl { - position: relative; - margin: 0.1em; } - .PokemonSelectList__filterWrapper__1d1Wl .close { - position: absolute; - top: 1em; - right: 1em; } - -.PokemonSelectList__filterInput__1z_s2 { - margin-left: 0; - margin-right: 0; - padding-right: 3em; } - -.PokemonSelectList__dex__1QHut, -.PokemonSelectList__form__VIw8Q { - font-size: 0.8em; - text-transform: capitalize; } - -.PokemonSelectList__dex__1QHut { - margin-left: auto; } - -.PokemonSelectList__form__VIw8Q { - flex: 0 1 100%; } - .TypeEffectiveDisplay__multiplierWrapper__1E9zx { position: relative; z-index: 0; @@ -567,5 +504,68 @@ flex-basis: unset; width: 6.75rem; } +.PokemonSelectList__wrapper__2LQMY { + font-size: 0.8rem; + width: 20em; + display: flex; + flex-flow: column nowrap; + margin: 0 1.5em 0 auto; + position: relative; } + .PokemonSelectList__wrapper__2LQMY .PokemonSelectList__listWrapper__bBtO6 { + flex: 1 1 auto; + display: flex; + padding: 0; + overflow: hidden; + height: 340px; + position: absolute; + top: 100%; + left: 0; + right: 0; + z-index: 2; } + .PokemonSelectList__wrapper__2LQMY .PokemonSelectList__listWrapper__bBtO6 > * { + width: 100%; } + .PokemonSelectList__wrapper__2LQMY .PokemonSelectList__listWrapper__bBtO6.PokemonSelectList__emptyList__1vgpK .PokemonSelectList__emptyState__3sBmb { + align-self: center; + text-align: center; } + .PokemonSelectList__wrapper__2LQMY .PokemonSelectList__listWrapper__bBtO6.PokemonSelectList__emptyList__1vgpK .PokemonSelectList__emptyState__3sBmb > *:first-child { + margin: 1em auto; } + .PokemonSelectList__wrapper__2LQMY a { + color: inherit; + text-decoration: none; + padding: 5px 1em 5px 2em; + justify-content: flex-end; + align-content: space-around; + flex-wrap: wrap; + display: flex; } + .PokemonSelectList__wrapper__2LQMY a .PokemonSelectList__menuIcon__1I2_T { + margin: -4px 0 0 0.5em; + opacity: 0.5; } + .PokemonSelectList__wrapper__2LQMY a.active .PokemonSelectList__menuIcon__1I2_T { + opacity: 1; } + +.PokemonSelectList__filterWrapper__1d1Wl { + position: relative; + margin: 0.1em; } + .PokemonSelectList__filterWrapper__1d1Wl .close { + position: absolute; + top: 1em; + right: 1em; } + +.PokemonSelectList__filterInput__1z_s2 { + margin-left: 0; + margin-right: 0; + padding-right: 3em; } + +.PokemonSelectList__dex__1QHut, +.PokemonSelectList__form__VIw8Q { + font-size: 0.8em; + text-transform: capitalize; } + +.PokemonSelectList__dex__1QHut { + margin-left: auto; } + +.PokemonSelectList__form__VIw8Q { + flex: 0 1 100%; } + /*# sourceMappingURL=main.tmp.css.map*/ \ No newline at end of file diff --git a/dist/main-bundle.js b/dist/main-bundle.js index 6b19115..7ca21b0 100644 --- a/dist/main-bundle.js +++ b/dist/main-bundle.js @@ -29619,7 +29619,7 @@ function pathToRegexp (path, keys, options) { /*! ModuleConcatenation bailout: Cannot concat with ./node_modules/@babel/runtime/helpers/esm/assertThisInitialized.js because of ./node_modules/react-redux/es/index.js */ /*! ModuleConcatenation bailout: Cannot concat with ./node_modules/@babel/runtime/helpers/esm/extends.js because of ./node_modules/react-redux/es/index.js */ /*! ModuleConcatenation bailout: Cannot concat with ./node_modules/@babel/runtime/helpers/esm/inheritsLoose.js because of ./node_modules/react-redux/es/index.js */ -/*! ModuleConcatenation bailout: Cannot concat with ./node_modules/@babel/runtime/helpers/esm/objectWithoutPropertiesLoose.js because of ./node_modules/react-redux/es/index.js */ +/*! ModuleConcatenation bailout: Cannot concat with ./node_modules/@babel/runtime/helpers/esm/objectWithoutPropertiesLoose.js because of ./node_modules/react-measure/dist/index.esm.js */ /*! ModuleConcatenation bailout: Cannot concat with ./node_modules/react/index.js (<- Module is not an ECMAScript module) */ /***/ (function(module, __webpack_exports__, __webpack_require__) { @@ -36772,6 +36772,8 @@ exports.PokemonService = PokemonService; function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); } function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } @@ -36780,8 +36782,6 @@ function _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } @@ -36856,7 +36856,9 @@ var classnames_1 = __importDefault(__webpack_require__(/*! classnames */ "./node var League_1 = __webpack_require__(/*! app/models/League */ "./src/ts/app/models/League.ts"); -var ActionsPokemonExplorer = __importStar(__webpack_require__(/*! app/actions */ "./src/ts/app/actions.ts")); +var ActionsPokemonApp = __importStar(__webpack_require__(/*! app/actions */ "./src/ts/app/actions.ts")); + +var ActionsPokemonExplorer = __importStar(__webpack_require__(/*! app/components/PokemonExplorer/actions */ "./src/ts/app/components/PokemonExplorer/actions.ts")); var ActionsPokemonSelectList = __importStar(__webpack_require__(/*! app/components/PokemonSelectList/actions */ "./src/ts/app/components/PokemonSelectList/actions.ts")); @@ -36864,16 +36866,10 @@ var Footer_1 = __webpack_require__(/*! app/components/Footer */ "./src/ts/app/co var Header_1 = __webpack_require__(/*! app/components/Header */ "./src/ts/app/components/Header.tsx"); -var LeagueIvExplorer_1 = __webpack_require__(/*! app/components/LeagueIvExplorer */ "./src/ts/app/components/LeagueIvExplorer.tsx"); - -var MovesExplorer_1 = __webpack_require__(/*! app/components/MovesExplorer */ "./src/ts/app/components/MovesExplorer.tsx"); - -var PokemonDisplay_1 = __webpack_require__(/*! app/components/PokemonDisplay */ "./src/ts/app/components/PokemonDisplay.tsx"); +var PokemonExplorer_1 = __webpack_require__(/*! app/components/PokemonExplorer/PokemonExplorer */ "./src/ts/app/components/PokemonExplorer/PokemonExplorer.tsx"); var PokemonSelectList_1 = __webpack_require__(/*! app/components/PokemonSelectList/PokemonSelectList */ "./src/ts/app/components/PokemonSelectList/PokemonSelectList.tsx"); -var TypeEffectiveDisplay_1 = __webpack_require__(/*! app/components/TypeEffectiveDisplay */ "./src/ts/app/components/TypeEffectiveDisplay.tsx"); - var navigation_1 = __webpack_require__(/*! app/utils/navigation */ "./src/ts/app/utils/navigation.ts"); var styles = __importStar(__webpack_require__(/*! app/styles/PokemonApp.scss */ "./src/ts/app/styles/PokemonApp.scss")); @@ -36890,63 +36886,34 @@ function (_react_1$default$Comp) { _this = _possibleConstructorReturn(this, _getPrototypeOf(PokemonApp).call(this, props)); - _this.handleToggleDropdownOpen = function (menu, isOpen) { + _this.handleSearchInterruption = function (isInterruption) { _this.setState({ - isInterruption: isOpen + activeNavigation: isInterruption ? 'pokedex' : null }); - var combatMoveSelectorsOpen = Object.assign({}, _this.props.pokemonExplorerState.combatMoveSelectorsOpen, _defineProperty({}, menu, isOpen)); + _this.props.dispatch(ActionsPokemonApp.setIsInterruption(isInterruption)); - _this.props.dispatch(ActionsPokemonExplorer.setCombatMoveSelectorsOpen(combatMoveSelectorsOpen)); + if (isInterruption) { + _this.props.dispatch(ActionsPokemonExplorer.setCombatMoveSelectorsOpen({ + quickMove: false, + chargeMove1: false, + chargeMove2: false + })); + } }; - _this.handleOverlayClick = function () { - _this.setState({ - activeNavigation: null, - isInterruption: false - }); + _this.handleToggleInterruption = function (isInterruption) { + _this.props.dispatch(ActionsPokemonApp.setIsInterruption(isInterruption)); - _this.props.dispatch(ActionsPokemonExplorer.setCombatMoveSelectorsOpen({ - quickMove: false, - chargeMove1: false, - chargeMove2: false - })); + if (!isInterruption) { + _this.setState({ + activeNavigation: null + }); + } }; _this.handlePokedexClick = function () { - _this.setState({ - activeNavigation: _this.state.activeNavigation !== 'pokedex' ? 'pokedex' : null - }); - }; - - _this.handlePvpClick = function () { - var widgets = _this.state.widgets; - - _this.setState({ - widgets: Object.assign({}, widgets, { - pvp: !widgets.pvp - }) - }); - }; - - _this.handleTypesClick = function () { - var widgets = _this.state.widgets; - - _this.setState({ - widgets: Object.assign({}, widgets, { - types: !widgets.types - }) - }); - }; - - _this.handleMovesClick = function () { - var widgets = _this.state.widgets; - - _this.setState({ - widgets: Object.assign({}, widgets, { - moves: !widgets.moves - }) - }); + _this.handleSearchInterruption(true); }; _this.handleActivatePokemon = function (pokemonId, form) { @@ -36973,71 +36940,17 @@ function (_react_1$default$Comp) { }; _this.handleChangeFilter = function (filterTerm) { - _this.setState({ - activeNavigation: 'pokedex' - }); + _this.handleSearchInterruption(true); return _this.props.dispatch(ActionsPokemonSelectList.filterPokemonList(filterTerm)); }; - _this.handleChangeIndividualValue = function (stat, value) { - var dispatch = _this.props.dispatch; - - 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; - } - }; - - _this.handleMaximizeLevel = function () { - _this.props.dispatch(ActionsPokemonExplorer.maximizeLevel()); - }; - - _this.handleChangeSelectedMove = function (moves) { - _this.props.dispatch(ActionsPokemonExplorer.setSelectedCombatMoves(moves)); - }; - - _this.handleChangeLeagueNavigation = function (league) { - var _this$props = _this.props, - history = _this$props.history, - location = _this$props.location; - history.push({ - search: navigation_1.appendQueryString(location, { - league: league.toString() - }) - }); - - _this.handleChangeLeague(league); - }; - _this.handleChangeLeague = function (league) { _this.props.dispatch(ActionsPokemonExplorer.setActiveLeague(league)); }; _this.state = { - isInterruption: false, - activeNavigation: null, - widgets: { - pvp: true, - types: false, - moves: false - } + activeNavigation: null }; return _this; } @@ -37048,15 +36961,16 @@ function (_react_1$default$Comp) { return __awaiter(this, void 0, void 0, /*#__PURE__*/ regeneratorRuntime.mark(function _callee() { - var _this$props2, location, dispatch, _navigation_1$getCurr, _navigation_1$getCurr2, pokemonIdValue, pokemonFormValue, activeLeagueValue, pokemonId, pokemonForm, activeLeague; + var _this$props, location, dispatch, _navigation_1$getCurr, _navigation_1$getCurr2, pokemonIdValue, pokemonFormValue, activeLeagueValue, pokemonId, pokemonForm, activeLeague; return regeneratorRuntime.wrap(function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: - _this$props2 = this.props, location = _this$props2.location, dispatch = _this$props2.dispatch; + _this$props = this.props, location = _this$props.location, dispatch = _this$props.dispatch; _context.next = 3; - return Promise.all([dispatch(ActionsPokemonExplorer.fetchConfig()), dispatch(ActionsPokemonSelectList.fetchPokemonList())]); + return Promise.all([dispatch(ActionsPokemonApp.fetchConfig()), // TODO: move this action to PokemonApp actions + dispatch(ActionsPokemonSelectList.fetchPokemonList())]); case 3: dispatch(ActionsPokemonSelectList.setIsLoading(false)); @@ -37085,44 +36999,23 @@ function (_react_1$default$Comp) { }, { key: "render", value: function render() { + var _this$props$pokemonAp = this.props.pokemonAppState, + isInterruption = _this$props$pokemonAp.isInterruption, + attackTypeEffectiveness = _this$props$pokemonAp.attackTypeEffectiveness, + combatMoves = _this$props$pokemonAp.combatMoves; var _this$props$pokemonSe = this.props.pokemonSelectListState, activePokemonId = _this$props$pokemonSe.activePokemonId, activePokemonForm = _this$props$pokemonSe.activePokemonForm, pokemonList = _this$props$pokemonSe.pokemonList, pokemonListFiltered = _this$props$pokemonSe.pokemonListFiltered, filterTerm = _this$props$pokemonSe.filterTerm; - var _this$props$pokemonEx = this.props.pokemonExplorerState, - league = _this$props$pokemonEx.league, - individualValues = _this$props$pokemonEx.individualValues, - leaguePokemon = _this$props$pokemonEx.leaguePokemon, - combatMoves = _this$props$pokemonEx.combatMoves, - selectedCombatMoves = _this$props$pokemonEx.selectedCombatMoves, - combatMoveSelectorsOpen = _this$props$pokemonEx.combatMoveSelectorsOpen; - var _this$state = this.state, - isInterruption = _this$state.isInterruption, - activeNavigation = _this$state.activeNavigation, - widgets = _this$state.widgets; - var isOverlayShown = isInterruption || activeNavigation === 'pokedex'; - var wrapperCss = classnames_1.default(styles.wrapper, _defineProperty({}, styles.overlaid, isOverlayShown)); - var leftNavCss = classnames_1.default(styles.leftNavigation); - var displayWrapperCss = classnames_1.default(styles.displayWrapper); + var activeNavigation = this.state.activeNavigation; + var wrapperCss = classnames_1.default(styles.wrapper, _defineProperty({}, styles.overlaid, isInterruption)); var iconCss = classnames_1.default('icon', 'pixel', 'sprite'); var pokedexCss = classnames_1.default(iconCss, 'pokedex', { active: activeNavigation === 'pokedex' }); var pokedexButtonCss = classnames_1.default(); - var pvpCss = classnames_1.default(iconCss, 'pvp', { - active: widgets.pvp - }); - var pvpButtonCss = classnames_1.default(); - var badgeCss = classnames_1.default(iconCss, 'badge', { - active: widgets.types - }); - var badgeButtonCss = classnames_1.default(); - var tmCss = classnames_1.default(iconCss, 'tm', { - active: widgets.moves - }); - var tmButtonCss = classnames_1.default(); return react_1.default.createElement("div", { className: wrapperCss }, react_1.default.createElement(Header_1.Header, null, react_1.default.createElement(PokemonSelectList_1.PokemonSelectList, { @@ -37139,53 +37032,14 @@ function (_react_1$default$Comp) { onClick: this.handlePokedexClick }, react_1.default.createElement("i", { className: pokedexCss - }))), react_1.default.createElement("div", { - className: styles.body - }, react_1.default.createElement("div", { - className: displayWrapperCss - }, leaguePokemon !== null && react_1.default.createElement(PokemonDisplay_1.PokemonDisplay, { - leaguePokemon: leaguePokemon, - isHighlighted: isOverlayShown - }), widgets.types && leaguePokemon !== null && react_1.default.createElement(TypeEffectiveDisplay_1.TypeEffectiveDisplay, { - effectiveness: leaguePokemon.effectiveness, - pokemonName: leaguePokemon.name - }), widgets.pvp && leaguePokemon !== null && react_1.default.createElement(LeagueIvExplorer_1.LeagueIvExplorer, { - activeLeague: league, - leaguePokemon: leaguePokemon, - individualValues: individualValues, - handleChangeIndividualValue: this.handleChangeIndividualValue, - handleMaximizeLevel: this.handleMaximizeLevel, - handleChangeLeague: this.handleChangeLeague - }), widgets.moves && leaguePokemon !== null && react_1.default.createElement(MovesExplorer_1.MovesExplorer, { - movesById: combatMoves, - quickMoves: leaguePokemon.moves.quick, - chargeMoves: leaguePokemon.moves.cinematic, - selectedMoves: selectedCombatMoves, - attackTypeEffectiveness: null, - combatMoveSelectorsOpen: combatMoveSelectorsOpen, - handleToggleDropdownOpen: this.handleToggleDropdownOpen, - handleChangeSelectedMove: this.handleChangeSelectedMove - })), react_1.default.createElement("div", { - className: leftNavCss - }, react_1.default.createElement("button", { - className: pvpButtonCss, - onClick: this.handlePvpClick - }, react_1.default.createElement("i", { - className: pvpCss - })), react_1.default.createElement("button", { - className: badgeButtonCss, - onClick: this.handleTypesClick - }, react_1.default.createElement("i", { - className: badgeCss - })), react_1.default.createElement("button", { - className: tmButtonCss, - onClick: this.handleMovesClick - }, react_1.default.createElement("i", { - className: tmCss - }))), isOverlayShown && react_1.default.createElement("div", { - className: styles.overlay, - onClick: this.handleOverlayClick - })), react_1.default.createElement(Footer_1.Footer, null)); + }))), react_1.default.createElement(PokemonExplorer_1.ConnectedPokemonExplorer, { + isOverlaid: isInterruption, + attackTypeEffectiveness: attackTypeEffectiveness, + combatMoves: combatMoves, + toggleInterruption: this.handleToggleInterruption, + history: this.props.history, + location: this.props.location + }), react_1.default.createElement(Footer_1.Footer, null)); } }]); @@ -37194,6 +37048,7 @@ function (_react_1$default$Comp) { var mapStateToProps = function mapStateToProps(state) { return { + pokemonAppState: state.pokemonAppState, pokemonExplorerState: state.pokemonExplorerState, pokemonSelectListState: state.pokemonSelectListState }; @@ -37265,74 +37120,30 @@ var typesafe_actions_1 = __webpack_require__(/*! typesafe-actions */ "./node_mod var types_1 = __webpack_require__(/*! app/types */ "./src/ts/app/types.ts"); -var calculator_1 = __webpack_require__(/*! app/utils/calculator */ "./src/ts/app/utils/calculator.ts"); - -exports.setIsLoading = function (isLoading) { - return typesafe_actions_1.action(types_1.PokemonExplorerActionTypes.SET_IS_LOADING, { - isLoading: isLoading +exports.setIsInterruption = function (isInterruption) { + return typesafe_actions_1.action(types_1.PokemonAppActionTypes.SET_IS_INTERRUPTION, { + isInterruption: isInterruption }); }; exports.setMaxPossibleStats = function (maxStats) { - return typesafe_actions_1.action(types_1.PokemonExplorerActionTypes.SET_MAX_STATS, { + return typesafe_actions_1.action(types_1.PokemonAppActionTypes.SET_MAX_STATS, { maxStats: maxStats }); }; +exports.setAttackTypeEffectiveness = function (attackTypeEffectiveness) { + return typesafe_actions_1.action(types_1.PokemonAppActionTypes.SET_COMBAT_MOVE_STATS, { + attackTypeEffectiveness: attackTypeEffectiveness + }); +}; + exports.setCombatMoveStats = function (combatMoves) { - return typesafe_actions_1.action(types_1.PokemonExplorerActionTypes.SET_COMBAT_MOVE_STATS, { + return typesafe_actions_1.action(types_1.PokemonAppActionTypes.SET_COMBAT_MOVE_STATS, { combatMoves: combatMoves }); }; -exports.setLeaguePokemon = function (leaguePokemon) { - return typesafe_actions_1.action(types_1.PokemonExplorerActionTypes.SET_LEAGUE_POKEMON, { - leaguePokemon: leaguePokemon - }); -}; - -exports.setIvLevel = function (level) { - return typesafe_actions_1.action(types_1.PokemonExplorerActionTypes.SET_IV_LEVEL, { - level: level - }); -}; - -exports.setIvHp = function (ivHp) { - return typesafe_actions_1.action(types_1.PokemonExplorerActionTypes.SET_IV_HP, { - ivHp: ivHp - }); -}; - -exports.setIvAtk = function (ivAtk) { - return typesafe_actions_1.action(types_1.PokemonExplorerActionTypes.SET_IV_ATK, { - ivAtk: ivAtk - }); -}; - -exports.setIvDef = function (ivDef) { - return typesafe_actions_1.action(types_1.PokemonExplorerActionTypes.SET_IV_DEF, { - ivDef: ivDef - }); -}; - -exports.setActiveLeague = function (league) { - return typesafe_actions_1.action(types_1.PokemonExplorerActionTypes.SET_ACTIVE_LEAGUE, { - league: league - }); -}; - -exports.setSelectedCombatMoves = function (moves) { - return typesafe_actions_1.action(types_1.PokemonExplorerActionTypes.SET_SELECTED_COMBAT_MOVES, { - moves: moves - }); -}; - -exports.setCombatMoveSelectorsOpen = function (selectorsOpen) { - return typesafe_actions_1.action(types_1.PokemonExplorerActionTypes.SET_COMBAT_MOVE_SELECTORS_OPEN, { - selectorsOpen: selectorsOpen - }); -}; - exports.fetchConfig = function () { return function (dispatch, getState, extraArguments) { return __awaiter(_this, void 0, void 0, @@ -37349,9 +37160,10 @@ exports.fetchConfig = function () { case 2: config = _context.sent; dispatch(exports.setMaxPossibleStats(config.maxPossibleStats)); + dispatch(exports.setAttackTypeEffectiveness(config.attackTypeEffectiveness)); dispatch(exports.setCombatMoveStats(config.combatMoves)); - case 5: + case 6: case "end": return _context.stop(); } @@ -37361,49 +37173,6 @@ exports.fetchConfig = function () { }; }; -exports.maximizeLevel = function () { - return function (dispatch, getState, extraArguments) { - return __awaiter(_this, void 0, void 0, - /*#__PURE__*/ - regeneratorRuntime.mark(function _callee2() { - var pokemonExplorerState, _pokemonExplorerState, ivHp, ivAtk, ivDef, pokemonLeagueValues, statsSet; - - return regeneratorRuntime.wrap(function _callee2$(_context2) { - while (1) { - switch (_context2.prev = _context2.next) { - case 0: - pokemonExplorerState = getState().pokemonExplorerState; - _pokemonExplorerState = pokemonExplorerState.individualValues, ivHp = _pokemonExplorerState.ivHp, ivAtk = _pokemonExplorerState.ivAtk, ivDef = _pokemonExplorerState.ivDef; - - if (pokemonExplorerState.leaguePokemon !== null) { - pokemonLeagueValues = pokemonExplorerState.leaguePokemon.pvp[pokemonExplorerState.league]; - statsSet = pokemonLeagueValues.some(function (stats) { - if ((ivHp === null || stats.ivHp === ivHp) && (ivAtk === null || stats.ivAtk === ivAtk) && (ivDef === null || stats.ivDef === ivDef)) { - dispatch(exports.setIvHp(stats.ivHp)); - dispatch(exports.setIvAtk(stats.ivAtk)); - dispatch(exports.setIvDef(stats.ivDef)); - dispatch(exports.setIvLevel(stats.level)); - return true; - } - - return false; - }); - - if (!statsSet && ivHp !== null && ivAtk !== null && ivDef !== null) { - dispatch(exports.setIvLevel(calculator_1.calculateMaxLevelForLeague(pokemonExplorerState.leaguePokemon.stats, ivHp, ivAtk, ivDef, pokemonExplorerState.league))); - } - } - - case 3: - case "end": - return _context2.stop(); - } - } - }, _callee2); - })); - }; -}; - /***/ }), /***/ "./src/ts/app/components/Footer.tsx": @@ -39016,6 +38785,621 @@ exports.PokemonDisplay = PokemonDisplay; /***/ }), +/***/ "./src/ts/app/components/PokemonExplorer/PokemonExplorer.tsx": +/*!*******************************************************************!*\ + !*** ./src/ts/app/components/PokemonExplorer/PokemonExplorer.tsx ***! + \*******************************************************************/ +/*! no static exports found */ +/*! ModuleConcatenation bailout: Module is not an ECMAScript module */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } + +function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } + +function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); } + +function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } + +function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); } + +function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } + +var __importDefault = this && this.__importDefault || function (mod) { + return mod && mod.__esModule ? mod : { + "default": mod + }; +}; + +var __importStar = this && this.__importStar || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) { + if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; + } + result["default"] = mod; + return result; +}; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var react_1 = __importDefault(__webpack_require__(/*! react */ "./node_modules/react/index.js")); + +var react_redux_1 = __webpack_require__(/*! react-redux */ "./node_modules/react-redux/es/index.js"); + +var classnames_1 = __importDefault(__webpack_require__(/*! classnames */ "./node_modules/classnames/index.js")); + +var ActionsPokemonExplorer = __importStar(__webpack_require__(/*! app/components/PokemonExplorer/actions */ "./src/ts/app/components/PokemonExplorer/actions.ts")); + +var LeagueIvExplorer_1 = __webpack_require__(/*! app/components/LeagueIvExplorer */ "./src/ts/app/components/LeagueIvExplorer.tsx"); + +var MovesExplorer_1 = __webpack_require__(/*! app/components/MovesExplorer */ "./src/ts/app/components/MovesExplorer.tsx"); + +var PokemonDisplay_1 = __webpack_require__(/*! app/components/PokemonDisplay */ "./src/ts/app/components/PokemonDisplay.tsx"); + +var TypeEffectiveDisplay_1 = __webpack_require__(/*! app/components/TypeEffectiveDisplay */ "./src/ts/app/components/TypeEffectiveDisplay.tsx"); + +var navigation_1 = __webpack_require__(/*! app/utils/navigation */ "./src/ts/app/utils/navigation.ts"); + +var styles = __importStar(__webpack_require__(/*! app/styles/PokemonApp.scss */ "./src/ts/app/styles/PokemonApp.scss")); + +var PokemonExplorer = +/*#__PURE__*/ +function (_react_1$default$Comp) { + _inherits(PokemonExplorer, _react_1$default$Comp); + + function PokemonExplorer(props) { + var _this; + + _classCallCheck(this, PokemonExplorer); + + _this = _possibleConstructorReturn(this, _getPrototypeOf(PokemonExplorer).call(this, props)); + + _this.handleToggleDropdownOpen = function (menu, isOpen) { + var combatMoveSelectorsOpen = Object.assign({}, _this.props.pokemonExplorerState.combatMoveSelectorsOpen, _defineProperty({}, menu, isOpen)); + + _this.props.dispatch(ActionsPokemonExplorer.setCombatMoveSelectorsOpen(combatMoveSelectorsOpen)); + + _this.props.toggleInterruption(true); + }; + + _this.handleOverlayClick = function () { + _this.props.dispatch(ActionsPokemonExplorer.setCombatMoveSelectorsOpen({ + quickMove: false, + chargeMove1: false, + chargeMove2: false + })); + + _this.props.toggleInterruption(false); + }; + + _this.handlePvpClick = function () { + var widgets = _this.state.widgets; + + _this.setState({ + widgets: Object.assign({}, widgets, { + pvp: !widgets.pvp + }) + }); + }; + + _this.handleTypesClick = function () { + var widgets = _this.state.widgets; + + _this.setState({ + widgets: Object.assign({}, widgets, { + types: !widgets.types + }) + }); + }; + + _this.handleMovesClick = function () { + var widgets = _this.state.widgets; + + _this.setState({ + widgets: Object.assign({}, widgets, { + moves: !widgets.moves + }) + }); + }; + + _this.handleChangeIndividualValue = function (stat, value) { + var dispatch = _this.props.dispatch; + + 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; + } + }; + + _this.handleMaximizeLevel = function () { + _this.props.dispatch(ActionsPokemonExplorer.maximizeLevel()); + }; + + _this.handleChangeSelectedMove = function (moves) { + _this.props.dispatch(ActionsPokemonExplorer.setSelectedCombatMoves(moves)); + }; // TODO: make this not overwrite other query parameters + + + _this.handleChangeLeagueNavigation = function (league) { + var _this$props = _this.props, + history = _this$props.history, + location = _this$props.location; + history.push({ + search: navigation_1.appendQueryString(location, { + league: league.toString() + }) + }); + + _this.handleChangeLeague(league); + }; + + _this.handleChangeLeague = function (league) { + _this.props.dispatch(ActionsPokemonExplorer.setActiveLeague(league)); + }; + + _this.state = { + widgets: { + pvp: true, + types: false, + moves: false + } + }; + return _this; + } + + _createClass(PokemonExplorer, [{ + key: "render", + value: function render() { + var _this$props2 = this.props, + combatMoves = _this$props2.combatMoves, + attackTypeEffectiveness = _this$props2.attackTypeEffectiveness; + var _this$props$pokemonEx = this.props.pokemonExplorerState, + league = _this$props$pokemonEx.league, + individualValues = _this$props$pokemonEx.individualValues, + leaguePokemon = _this$props$pokemonEx.leaguePokemon, + selectedCombatMoves = _this$props$pokemonEx.selectedCombatMoves, + combatMoveSelectorsOpen = _this$props$pokemonEx.combatMoveSelectorsOpen; + var widgets = this.state.widgets; + var isOverlayShown = this.props.isOverlaid || combatMoveSelectorsOpen.quickMove || combatMoveSelectorsOpen.chargeMove1 || combatMoveSelectorsOpen.chargeMove2; + var leftNavCss = classnames_1.default(styles.leftNavigation); + var displayWrapperCss = classnames_1.default(styles.displayWrapper); + var iconCss = classnames_1.default('icon', 'pixel', 'sprite'); + var pvpCss = classnames_1.default(iconCss, 'pvp', { + active: widgets.pvp + }); + var pvpButtonCss = classnames_1.default(); + var badgeCss = classnames_1.default(iconCss, 'badge', { + active: widgets.types + }); + var badgeButtonCss = classnames_1.default(); + var tmCss = classnames_1.default(iconCss, 'tm', { + active: widgets.moves + }); + var tmButtonCss = classnames_1.default(); + return react_1.default.createElement("div", { + className: styles.body + }, react_1.default.createElement("div", { + className: displayWrapperCss + }, leaguePokemon !== null && react_1.default.createElement(PokemonDisplay_1.PokemonDisplay, { + leaguePokemon: leaguePokemon, + isHighlighted: isOverlayShown + }), widgets.types && leaguePokemon !== null && react_1.default.createElement(TypeEffectiveDisplay_1.TypeEffectiveDisplay, { + effectiveness: leaguePokemon.effectiveness, + pokemonName: leaguePokemon.name + }), widgets.pvp && leaguePokemon !== null && react_1.default.createElement(LeagueIvExplorer_1.LeagueIvExplorer, { + activeLeague: league, + leaguePokemon: leaguePokemon, + individualValues: individualValues, + handleChangeIndividualValue: this.handleChangeIndividualValue, + handleMaximizeLevel: this.handleMaximizeLevel, + handleChangeLeague: this.handleChangeLeague + }), widgets.moves && leaguePokemon !== null && react_1.default.createElement(MovesExplorer_1.MovesExplorer, { + movesById: combatMoves, + quickMoves: leaguePokemon.moves.quick, + chargeMoves: leaguePokemon.moves.cinematic, + selectedMoves: selectedCombatMoves, + attackTypeEffectiveness: attackTypeEffectiveness, + combatMoveSelectorsOpen: combatMoveSelectorsOpen, + handleToggleDropdownOpen: this.handleToggleDropdownOpen, + handleChangeSelectedMove: this.handleChangeSelectedMove + })), react_1.default.createElement("div", { + className: leftNavCss + }, react_1.default.createElement("button", { + className: pvpButtonCss, + onClick: this.handlePvpClick + }, react_1.default.createElement("i", { + className: pvpCss + })), react_1.default.createElement("button", { + className: badgeButtonCss, + onClick: this.handleTypesClick + }, react_1.default.createElement("i", { + className: badgeCss + })), react_1.default.createElement("button", { + className: tmButtonCss, + onClick: this.handleMovesClick + }, react_1.default.createElement("i", { + className: tmCss + }))), isOverlayShown && react_1.default.createElement("div", { + className: styles.overlay, + onClick: this.handleOverlayClick + })); + } + }]); + + return PokemonExplorer; +}(react_1.default.Component); + +var mapStateToProps = function mapStateToProps(state) { + return Object.assign({}, state); +}; + +var mapDispatchToProps = function mapDispatchToProps(dispatch) { + return { + dispatch: dispatch + }; +}; + +var mergeProps = function mergeProps(state, dispatchProps, ownProps) { + return Object.assign({}, state, dispatchProps, ownProps, { + history: ownProps.history, + location: ownProps.location + }); +}; + +exports.ConnectedPokemonExplorer = react_redux_1.connect(mapStateToProps, mapDispatchToProps, mergeProps)(PokemonExplorer); + +/***/ }), + +/***/ "./src/ts/app/components/PokemonExplorer/actions.ts": +/*!**********************************************************!*\ + !*** ./src/ts/app/components/PokemonExplorer/actions.ts ***! + \**********************************************************/ +/*! no static exports found */ +/*! ModuleConcatenation bailout: Module is not an ECMAScript module */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var _this = this; + +var __awaiter = this && this.__awaiter || function (thisArg, _arguments, P, generator) { + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + + function step(result) { + result.done ? resolve(result.value) : new P(function (resolve) { + resolve(result.value); + }).then(fulfilled, rejected); + } + + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var typesafe_actions_1 = __webpack_require__(/*! typesafe-actions */ "./node_modules/typesafe-actions/dist/index.umd.js"); + +var types_1 = __webpack_require__(/*! app/components/PokemonExplorer/types */ "./src/ts/app/components/PokemonExplorer/types.ts"); + +var calculator_1 = __webpack_require__(/*! app/utils/calculator */ "./src/ts/app/utils/calculator.ts"); + +exports.setIsLoading = function (isLoading) { + return typesafe_actions_1.action(types_1.PokemonExplorerActionTypes.SET_IS_LOADING, { + isLoading: isLoading + }); +}; + +exports.setLeaguePokemon = function (leaguePokemon) { + return typesafe_actions_1.action(types_1.PokemonExplorerActionTypes.SET_LEAGUE_POKEMON, { + leaguePokemon: leaguePokemon + }); +}; + +exports.setIvLevel = function (level) { + return typesafe_actions_1.action(types_1.PokemonExplorerActionTypes.SET_IV_LEVEL, { + level: level + }); +}; + +exports.setIvHp = function (ivHp) { + return typesafe_actions_1.action(types_1.PokemonExplorerActionTypes.SET_IV_HP, { + ivHp: ivHp + }); +}; + +exports.setIvAtk = function (ivAtk) { + return typesafe_actions_1.action(types_1.PokemonExplorerActionTypes.SET_IV_ATK, { + ivAtk: ivAtk + }); +}; + +exports.setIvDef = function (ivDef) { + return typesafe_actions_1.action(types_1.PokemonExplorerActionTypes.SET_IV_DEF, { + ivDef: ivDef + }); +}; + +exports.setActiveLeague = function (league) { + return typesafe_actions_1.action(types_1.PokemonExplorerActionTypes.SET_ACTIVE_LEAGUE, { + league: league + }); +}; + +exports.setSelectedCombatMoves = function (moves) { + return typesafe_actions_1.action(types_1.PokemonExplorerActionTypes.SET_SELECTED_COMBAT_MOVES, { + moves: moves + }); +}; + +exports.setCombatMoveSelectorsOpen = function (selectorsOpen) { + return typesafe_actions_1.action(types_1.PokemonExplorerActionTypes.SET_COMBAT_MOVE_SELECTORS_OPEN, { + selectorsOpen: selectorsOpen + }); +}; + +exports.maximizeLevel = function () { + return function (dispatch, getState, extraArguments) { + return __awaiter(_this, void 0, void 0, + /*#__PURE__*/ + regeneratorRuntime.mark(function _callee() { + var pokemonExplorerState, _pokemonExplorerState, ivHp, ivAtk, ivDef, pokemonLeagueValues, statsSet; + + return regeneratorRuntime.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + pokemonExplorerState = getState().pokemonExplorerState; + _pokemonExplorerState = pokemonExplorerState.individualValues, ivHp = _pokemonExplorerState.ivHp, ivAtk = _pokemonExplorerState.ivAtk, ivDef = _pokemonExplorerState.ivDef; + + if (pokemonExplorerState.leaguePokemon !== null) { + pokemonLeagueValues = pokemonExplorerState.leaguePokemon.pvp[pokemonExplorerState.league]; + statsSet = pokemonLeagueValues.some(function (stats) { + if ((ivHp === null || stats.ivHp === ivHp) && (ivAtk === null || stats.ivAtk === ivAtk) && (ivDef === null || stats.ivDef === ivDef)) { + dispatch(exports.setIvHp(stats.ivHp)); + dispatch(exports.setIvAtk(stats.ivAtk)); + dispatch(exports.setIvDef(stats.ivDef)); + dispatch(exports.setIvLevel(stats.level)); + return true; + } + + return false; + }); + + if (!statsSet && ivHp !== null && ivAtk !== null && ivDef !== null) { + dispatch(exports.setIvLevel(calculator_1.calculateMaxLevelForLeague(pokemonExplorerState.leaguePokemon.stats, ivHp, ivAtk, ivDef, pokemonExplorerState.league))); + } + } + + case 3: + case "end": + return _context.stop(); + } + } + }, _callee); + })); + }; +}; + +/***/ }), + +/***/ "./src/ts/app/components/PokemonExplorer/reducers.ts": +/*!***********************************************************!*\ + !*** ./src/ts/app/components/PokemonExplorer/reducers.ts ***! + \***********************************************************/ +/*! no static exports found */ +/*! ModuleConcatenation bailout: Module is not an ECMAScript module */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var League_1 = __webpack_require__(/*! app/models/League */ "./src/ts/app/models/League.ts"); + +var types_1 = __webpack_require__(/*! app/components/PokemonExplorer/types */ "./src/ts/app/components/PokemonExplorer/types.ts"); + +exports.initialState = { + isLoading: false, + leaguePokemon: null, + individualValues: { + level: null, + ivHp: null, + ivAtk: null, + ivDef: null + }, + league: League_1.League.GREAT, + selectedCombatMoves: { + quickMove: null, + chargeMove1: null, + chargeMove2: null + }, + combatMoveSelectorsOpen: { + quickMove: false, + chargeMove1: false, + chargeMove2: false + } +}; + +var reduceSetIsLoading = function reduceSetIsLoading(state, action) { + return Object.assign({}, state, { + isLoading: action.payload.isLoading + }); +}; + +var reduceSetLeaguePokemon = function reduceSetLeaguePokemon(state, action) { + return Object.assign({}, state, { + leaguePokemon: action.payload.leaguePokemon + }); +}; + +var reduceSetIvLevel = function reduceSetIvLevel(state, action) { + return Object.assign({}, state, { + individualValues: Object.assign({}, state.individualValues, { + level: action.payload.level + }) + }); +}; + +var reduceSetIvHp = function reduceSetIvHp(state, action) { + return Object.assign({}, state, { + individualValues: Object.assign({}, state.individualValues, { + ivHp: action.payload.ivHp + }) + }); +}; + +var reduceSetIvAtk = function reduceSetIvAtk(state, action) { + return Object.assign({}, state, { + individualValues: Object.assign({}, state.individualValues, { + ivAtk: action.payload.ivAtk + }) + }); +}; + +var reduceSetIvDef = function reduceSetIvDef(state, action) { + return Object.assign({}, state, { + individualValues: Object.assign({}, state.individualValues, { + ivDef: action.payload.ivDef + }) + }); +}; + +var reduceSetActiveLeague = function reduceSetActiveLeague(state, action) { + return Object.assign({}, state, { + league: action.payload.league + }); +}; + +var reduceSetSelectedCombatMoves = function reduceSetSelectedCombatMoves(state, action) { + return Object.assign({}, state, { + selectedCombatMoves: Object.assign({}, action.payload.moves) + }); +}; + +var reduceSetCombatMoveSelectorsOpen = function reduceSetCombatMoveSelectorsOpen(state, action) { + return Object.assign({}, state, { + combatMoveSelectorsOpen: Object.assign({}, action.payload.selectorsOpen) + }); +}; + +exports.PokemonExplorerReducers = function () { + var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : exports.initialState; + var action = arguments.length > 1 ? arguments[1] : undefined; + + switch (action.type) { + case types_1.PokemonExplorerActionTypes.SET_IS_LOADING: + return reduceSetIsLoading(state, action); + + case types_1.PokemonExplorerActionTypes.SET_LEAGUE_POKEMON: + return reduceSetLeaguePokemon(state, action); + + case types_1.PokemonExplorerActionTypes.SET_IV_LEVEL: + return reduceSetIvLevel(state, action); + + case types_1.PokemonExplorerActionTypes.SET_IV_HP: + return reduceSetIvHp(state, action); + + case types_1.PokemonExplorerActionTypes.SET_IV_ATK: + return reduceSetIvAtk(state, action); + + case types_1.PokemonExplorerActionTypes.SET_IV_DEF: + return reduceSetIvDef(state, action); + + case types_1.PokemonExplorerActionTypes.SET_ACTIVE_LEAGUE: + return reduceSetActiveLeague(state, action); + + case types_1.PokemonExplorerActionTypes.SET_SELECTED_COMBAT_MOVES: + return reduceSetSelectedCombatMoves(state, action); + + case types_1.PokemonExplorerActionTypes.SET_COMBAT_MOVE_SELECTORS_OPEN: + return reduceSetCombatMoveSelectorsOpen(state, action); + + default: + return state; + } +}; + +/***/ }), + +/***/ "./src/ts/app/components/PokemonExplorer/types.ts": +/*!********************************************************!*\ + !*** ./src/ts/app/components/PokemonExplorer/types.ts ***! + \********************************************************/ +/*! no static exports found */ +/*! ModuleConcatenation bailout: Module is not an ECMAScript module */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.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', + SET_ACTIVE_LEAGUE: 'POKEMON_EXPLORER/SET_ACTIVE_LEAGUE', + SET_SELECTED_COMBAT_MOVES: 'POKEMON_EXPLORER/SET_SELECTED_COMBAT_MOVES', + SET_COMBAT_MOVE_SELECTORS_OPEN: 'POKEMON_EXPLORER/SET_COMBAT_MOVE_SELECTORS_OPEN' +}; + +/***/ }), + /***/ "./src/ts/app/components/PokemonSelectList/PokemonSelectList.tsx": /*!***********************************************************************!*\ !*** ./src/ts/app/components/PokemonSelectList/PokemonSelectList.tsx ***! @@ -40019,15 +40403,18 @@ var redux_thunk_1 = __importDefault(__webpack_require__(/*! redux-thunk */ "./no var PokemonService_1 = __webpack_require__(/*! api/PokemonService */ "./src/ts/api/PokemonService.ts"); -var reducers_1 = __webpack_require__(/*! app/components/PokemonSelectList/reducers */ "./src/ts/app/components/PokemonSelectList/reducers.ts"); +var reducers_1 = __webpack_require__(/*! app/components/PokemonExplorer/reducers */ "./src/ts/app/components/PokemonExplorer/reducers.ts"); -var reducers_2 = __webpack_require__(/*! app/reducers */ "./src/ts/app/reducers.ts"); +var reducers_2 = __webpack_require__(/*! app/components/PokemonSelectList/reducers */ "./src/ts/app/components/PokemonSelectList/reducers.ts"); + +var reducers_3 = __webpack_require__(/*! app/reducers */ "./src/ts/app/reducers.ts"); var PokemonApp_1 = __webpack_require__(/*! ./PokemonApp */ "./src/ts/app/PokemonApp.tsx"); exports.appReducers = Redux.combineReducers({ - pokemonSelectListState: reducers_1.PokemonSelectListReducers, - pokemonExplorerState: reducers_2.PokemonExplorerReducers + pokemonAppState: reducers_3.PokemonAppReducers, + pokemonSelectListState: reducers_2.PokemonSelectListReducers, + pokemonExplorerState: reducers_1.PokemonExplorerReducers }); var extraArguments = { services: { @@ -40192,42 +40579,23 @@ Object.defineProperty(exports, "__esModule", { value: true }); -var League_1 = __webpack_require__(/*! app/models/League */ "./src/ts/app/models/League.ts"); - var types_1 = __webpack_require__(/*! app/types */ "./src/ts/app/types.ts"); exports.initialState = { - isLoading: false, - leaguePokemon: null, + isInterruption: false, maxPossibleStats: { baseStamina: 0, baseAttack: 0, baseDefense: 0, level: 0 }, - individualValues: { - level: null, - ivHp: null, - ivAtk: null, - ivDef: null - }, - league: League_1.League.GREAT, - combatMoves: new Map(), - selectedCombatMoves: { - quickMove: null, - chargeMove1: null, - chargeMove2: null - }, - combatMoveSelectorsOpen: { - quickMove: false, - chargeMove1: false, - chargeMove2: false - } + attackTypeEffectiveness: new Map(), + combatMoves: new Map() }; -var reduceSetIsLoading = function reduceSetIsLoading(state, action) { +var reduceSetInterruption = function reduceSetInterruption(state, action) { return Object.assign({}, state, { - isLoading: action.payload.isLoading + isInterruption: action.payload.isInterruption }); }; @@ -40237,106 +40605,35 @@ var reduceSetMaxPossibleStats = function reduceSetMaxPossibleStats(state, action }); }; +var reduceSetAttackTypeEffectiveness = function reduceSetAttackTypeEffectiveness(state, action) { + return Object.assign({}, state, { + attackTypeEffectiveness: action.payload.attackTypeEffectiveness + }); +}; + var reduceSetCombatMoveStats = function reduceSetCombatMoveStats(state, action) { return Object.assign({}, state, { combatMoves: action.payload.combatMoves }); }; -var reduceSetLeaguePokemon = function reduceSetLeaguePokemon(state, action) { - return Object.assign({}, state, { - leaguePokemon: action.payload.leaguePokemon - }); -}; - -var reduceSetIvLevel = function reduceSetIvLevel(state, action) { - return Object.assign({}, state, { - individualValues: Object.assign({}, state.individualValues, { - level: action.payload.level - }) - }); -}; - -var reduceSetIvHp = function reduceSetIvHp(state, action) { - return Object.assign({}, state, { - individualValues: Object.assign({}, state.individualValues, { - ivHp: action.payload.ivHp - }) - }); -}; - -var reduceSetIvAtk = function reduceSetIvAtk(state, action) { - return Object.assign({}, state, { - individualValues: Object.assign({}, state.individualValues, { - ivAtk: action.payload.ivAtk - }) - }); -}; - -var reduceSetIvDef = function reduceSetIvDef(state, action) { - return Object.assign({}, state, { - individualValues: Object.assign({}, state.individualValues, { - ivDef: action.payload.ivDef - }) - }); -}; - -var reduceSetActiveLeague = function reduceSetActiveLeague(state, action) { - return Object.assign({}, state, { - league: action.payload.league - }); -}; - -var reduceSetSelectedCombatMoves = function reduceSetSelectedCombatMoves(state, action) { - return Object.assign({}, state, { - selectedCombatMoves: Object.assign({}, action.payload.moves) - }); -}; - -var reduceSetCombatMoveSelectorsOpen = function reduceSetCombatMoveSelectorsOpen(state, action) { - return Object.assign({}, state, { - combatMoveSelectorsOpen: Object.assign({}, action.payload.selectorsOpen) - }); -}; - -exports.PokemonExplorerReducers = function () { +exports.PokemonAppReducers = function () { var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : exports.initialState; var action = arguments.length > 1 ? arguments[1] : undefined; switch (action.type) { - case types_1.PokemonExplorerActionTypes.SET_IS_LOADING: - return reduceSetIsLoading(state, action); + case types_1.PokemonAppActionTypes.SET_IS_INTERRUPTION: + return reduceSetInterruption(state, action); - case types_1.PokemonExplorerActionTypes.SET_MAX_STATS: + case types_1.PokemonAppActionTypes.SET_MAX_STATS: return reduceSetMaxPossibleStats(state, action); - case types_1.PokemonExplorerActionTypes.SET_COMBAT_MOVE_STATS: + case types_1.PokemonAppActionTypes.SET_ATTACK_TYPE_EFFECTIVENESS: + return reduceSetAttackTypeEffectiveness(state, action); + + case types_1.PokemonAppActionTypes.SET_COMBAT_MOVE_STATS: return reduceSetCombatMoveStats(state, action); - case types_1.PokemonExplorerActionTypes.SET_LEAGUE_POKEMON: - return reduceSetLeaguePokemon(state, action); - - case types_1.PokemonExplorerActionTypes.SET_IV_LEVEL: - return reduceSetIvLevel(state, action); - - case types_1.PokemonExplorerActionTypes.SET_IV_HP: - return reduceSetIvHp(state, action); - - case types_1.PokemonExplorerActionTypes.SET_IV_ATK: - return reduceSetIvAtk(state, action); - - case types_1.PokemonExplorerActionTypes.SET_IV_DEF: - return reduceSetIvDef(state, action); - - case types_1.PokemonExplorerActionTypes.SET_ACTIVE_LEAGUE: - return reduceSetActiveLeague(state, action); - - case types_1.PokemonExplorerActionTypes.SET_SELECTED_COMBAT_MOVES: - return reduceSetSelectedCombatMoves(state, action); - - case types_1.PokemonExplorerActionTypes.SET_COMBAT_MOVE_SELECTORS_OPEN: - return reduceSetCombatMoveSelectorsOpen(state, action); - default: return state; } @@ -40501,18 +40798,11 @@ module.exports = {"pokemonType":"TypeIndicator__pokemonType__1rrg9"}; Object.defineProperty(exports, "__esModule", { value: true }); -exports.PokemonExplorerActionTypes = { - SET_IS_LOADING: 'POKEMON_EXPLORER/SET_IS_LOADING', - SET_MAX_STATS: 'POKEMON_EXPLORER/SET_MAX_STATS', - SET_COMBAT_MOVE_STATS: 'POKEMON_EXPLORER/SET_COMBAT_MOVE_STATS', - 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', - SET_ACTIVE_LEAGUE: 'POKEMON_EXPLORER/SET_ACTIVE_LEAGUE', - SET_SELECTED_COMBAT_MOVES: 'POKEMON_EXPLORER/SET_SELECTED_COMBAT_MOVES', - SET_COMBAT_MOVE_SELECTORS_OPEN: 'POKEMON_EXPLORER/SET_COMBAT_MOVE_SELECTORS_OPEN' +exports.PokemonAppActionTypes = { + SET_IS_INTERRUPTION: 'POKEMON_APP/SET_IS_INTERRUPTION', + 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' }; /***/ }), diff --git a/src/ts/app/PokemonApp.tsx b/src/ts/app/PokemonApp.tsx index dca6d8e..9ee240c 100644 --- a/src/ts/app/PokemonApp.tsx +++ b/src/ts/app/PokemonApp.tsx @@ -10,35 +10,28 @@ import { League } from 'app/models/League'; import { appReducers } from 'app/index'; -import * as ActionsPokemonExplorer from 'app/actions'; +import * as ActionsPokemonApp from 'app/actions'; +import * as ActionsPokemonExplorer from 'app/components/PokemonExplorer/actions'; import * as ActionsPokemonSelectList from 'app/components/PokemonSelectList/actions'; -import { CombatMoveSelectorsOpen, IndividualValueKey, IPokemonAppDispatch, SelectedCombatMoves } from 'app/types'; +import { IPokemonAppDispatch, IRouterProps } from 'app/types'; import { Footer } from 'app/components/Footer'; import { Header } from 'app/components/Header'; -import { LeagueIvExplorer } from 'app/components/LeagueIvExplorer'; -import { MovesExplorer } from 'app/components/MovesExplorer'; -import { PokemonDisplay } from 'app/components/PokemonDisplay'; +import { ConnectedPokemonExplorer } from 'app/components/PokemonExplorer/PokemonExplorer'; import { PokemonSelectList } from 'app/components/PokemonSelectList/PokemonSelectList'; -import { TypeEffectiveDisplay } from 'app/components/TypeEffectiveDisplay'; -import { appendQueryString, getCurrentQueryStringVlaues } from 'app/utils/navigation'; +import { getCurrentQueryStringVlaues } from 'app/utils/navigation'; import * as styles from 'app/styles/PokemonApp.scss'; type PokemonAppProps = ReturnType; -interface IConnectedPokemonAppProps extends PokemonAppProps, IPokemonAppDispatch { - history : RouteComponentProps['history']; - location : RouteComponentProps['location']; -} +interface IConnectedPokemonAppProps extends PokemonAppProps, IPokemonAppDispatch, IRouterProps {} +// TODO: this should be on PokemonAppState export type Navigation = 'pokedex'; -type SubNavigation = 'pvp' | 'types' | 'moves'; interface IState { - isInterruption : boolean; activeNavigation : Navigation | null; - widgets : { [ key in SubNavigation ] : boolean }; } class PokemonApp extends React.Component { @@ -47,13 +40,7 @@ class PokemonApp extends React.Component { super(props); this.state = { - isInterruption: false, activeNavigation: null, - widgets: { - pvp: true, - types: false, - moves: false, - }, }; } @@ -64,7 +51,8 @@ class PokemonApp extends React.Component { } = this.props; await Promise.all([ - dispatch(ActionsPokemonExplorer.fetchConfig()), + dispatch(ActionsPokemonApp.fetchConfig()), + // TODO: move this action to PokemonApp actions dispatch(ActionsPokemonSelectList.fetchPokemonList()) ]); dispatch(ActionsPokemonSelectList.setIsLoading(false)); @@ -90,6 +78,11 @@ class PokemonApp extends React.Component { } public render() { + const { + isInterruption, + attackTypeEffectiveness, + combatMoves, + } = this.props.pokemonAppState; const { activePokemonId, activePokemonForm, @@ -98,36 +91,16 @@ class PokemonApp extends React.Component { filterTerm, } = this.props.pokemonSelectListState; const { - league, - individualValues, - leaguePokemon, - combatMoves, - selectedCombatMoves, - combatMoveSelectorsOpen, - } = this.props.pokemonExplorerState; - const { - isInterruption, activeNavigation, - widgets, } = this.state; - const isOverlayShown = isInterruption || activeNavigation === 'pokedex'; - const wrapperCss = classNames( styles.wrapper, { - [styles.overlaid]: isOverlayShown, + [styles.overlaid]: isInterruption, } ); - const leftNavCss = classNames( - styles.leftNavigation, - ); - - const displayWrapperCss = classNames( - styles.displayWrapper, - ); - const iconCss = classNames( 'icon', 'pixel', @@ -147,43 +120,6 @@ class PokemonApp extends React.Component { // } ); - const pvpCss = classNames( - iconCss, - 'pvp', - { - active: widgets.pvp, - } - ); - const pvpButtonCss = classNames( - // { - // [styles.activeNavigationButton]: widgets.pvp, - // } - ); - const badgeCss = classNames( - iconCss, - 'badge', - { - active: widgets.types, - } - ); - const badgeButtonCss = classNames( - // { - // [styles.activeNavigationButton]: widgets.types, - // } - ); - const tmCss = classNames( - iconCss, - 'tm', - { - active: widgets.moves, - } - ); - const tmButtonCss = classNames( - // { - // [styles.activeNavigationButton]: widgets.moves, - // } - ); - return (
@@ -199,114 +135,45 @@ class PokemonApp extends React.Component { />
-
-
- { leaguePokemon !== null && - - } - { widgets.types && leaguePokemon !== null && - - } - { widgets.pvp && leaguePokemon !== null && - - } - { widgets.moves && leaguePokemon !== null && - - } -
-
- - - -
- { isOverlayShown && -
- } -
+
); } - private readonly handleToggleDropdownOpen = (menu : keyof CombatMoveSelectorsOpen, isOpen : boolean) => { + private readonly handleSearchInterruption = (isInterruption : boolean) => { this.setState({ - isInterruption: isOpen, + activeNavigation: isInterruption ? 'pokedex' : null, }); - const combatMoveSelectorsOpen : CombatMoveSelectorsOpen = { - ...this.props.pokemonExplorerState.combatMoveSelectorsOpen, - [menu]: isOpen, // 3/10/2019: TyepScript is not checking this! - }; - this.props.dispatch(ActionsPokemonExplorer.setCombatMoveSelectorsOpen(combatMoveSelectorsOpen)); + this.props.dispatch(ActionsPokemonApp.setIsInterruption(isInterruption)); + + if (isInterruption) { + this.props.dispatch(ActionsPokemonExplorer.setCombatMoveSelectorsOpen({ + quickMove: false, + chargeMove1: false, + chargeMove2: false, + })); + } } - private readonly handleOverlayClick = () => { - this.setState({ - activeNavigation: null, - isInterruption: false, - }); - this.props.dispatch(ActionsPokemonExplorer.setCombatMoveSelectorsOpen({ - quickMove: false, - chargeMove1: false, - chargeMove2: false, - })); + private readonly handleToggleInterruption = (isInterruption : boolean) => { + this.props.dispatch(ActionsPokemonApp.setIsInterruption(isInterruption)); + if (!isInterruption) { + this.setState({ + activeNavigation: null, + }); + } } private readonly handlePokedexClick = () => { - this.setState({ - activeNavigation: this.state.activeNavigation !== 'pokedex' ? 'pokedex' : null, - }); - } - - private readonly handlePvpClick = () => { - const widgets = this.state.widgets; - this.setState({ - widgets: { - ...widgets, - pvp: !widgets.pvp - } - }); - } - - private readonly handleTypesClick = () => { - const widgets = this.state.widgets; - this.setState({ - widgets: { - ...widgets, - types: !widgets.types - } - }); - } - - private readonly handleMovesClick = () => { - const widgets = this.state.widgets; - this.setState({ - widgets: { - ...widgets, - moves: !widgets.moves - } - }); + this.handleSearchInterruption(true); } private readonly handleActivatePokemon = (pokemonId : POGOProtos.Enums.PokemonId, form : POGOProtos.Enums.Form) => { @@ -335,56 +202,10 @@ class PokemonApp extends React.Component { } private readonly handleChangeFilter = (filterTerm : string) => { - this.setState({ - activeNavigation: 'pokedex', - }); + this.handleSearchInterruption(true); 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 handleChangeSelectedMove = (moves : SelectedCombatMoves) => { - this.props.dispatch(ActionsPokemonExplorer.setSelectedCombatMoves(moves)); - } - - 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)); } @@ -392,6 +213,7 @@ class PokemonApp extends React.Component { const mapStateToProps = (state : PokemonAppProps) : PokemonAppProps => { return { + pokemonAppState: state.pokemonAppState, pokemonExplorerState: state.pokemonExplorerState, pokemonSelectListState: state.pokemonSelectListState, }; diff --git a/src/ts/app/actions.ts b/src/ts/app/actions.ts index 6926af0..eac40eb 100644 --- a/src/ts/app/actions.ts +++ b/src/ts/app/actions.ts @@ -1,71 +1,23 @@ import { action } from 'typesafe-actions'; -import { CombatMoveSelectorsOpen, PokemonExplorerActionTypes, SelectedCombatMoves, ThunkResult } from 'app/types'; +import { PokemonAppActionTypes, ThunkResult } from 'app/types'; -import { calculateMaxLevelForLeague } from 'app/utils/calculator'; - -import { ILeaguePokemon, League } from 'app/models/League'; +import { AttackTypeEffectiveness } from 'app/models/Config'; import { CombatMoveStats, IMaxStats } from 'app/models/Pokemon'; -export const setIsLoading = (isLoading : boolean) => action(PokemonExplorerActionTypes.SET_IS_LOADING, { isLoading }); +export const setIsInterruption = (isInterruption : boolean) => action(PokemonAppActionTypes.SET_IS_INTERRUPTION, { isInterruption }); +export const setMaxPossibleStats = (maxStats : IMaxStats) => action(PokemonAppActionTypes.SET_MAX_STATS, { maxStats }); -export const setMaxPossibleStats = (maxStats : IMaxStats) => action(PokemonExplorerActionTypes.SET_MAX_STATS, { maxStats }); +export const setAttackTypeEffectiveness = (attackTypeEffectiveness : AttackTypeEffectiveness) => action(PokemonAppActionTypes.SET_COMBAT_MOVE_STATS, { attackTypeEffectiveness }); -export const setCombatMoveStats = (combatMoves : CombatMoveStats) => action(PokemonExplorerActionTypes.SET_COMBAT_MOVE_STATS, { combatMoves }); - -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 = (ivHp : number | null) => action(PokemonExplorerActionTypes.SET_IV_HP, { ivHp }); - -export const setIvAtk = (ivAtk : number | null) => action(PokemonExplorerActionTypes.SET_IV_ATK, { ivAtk }); - -export const setIvDef = (ivDef : number | null) => action(PokemonExplorerActionTypes.SET_IV_DEF, { ivDef }); - -export const setActiveLeague = (league : League) => action(PokemonExplorerActionTypes.SET_ACTIVE_LEAGUE, { league }); - -export const setSelectedCombatMoves = (moves : SelectedCombatMoves) => action(PokemonExplorerActionTypes.SET_SELECTED_COMBAT_MOVES, { moves }); - -export const setCombatMoveSelectorsOpen = (selectorsOpen : CombatMoveSelectorsOpen) => action(PokemonExplorerActionTypes.SET_COMBAT_MOVE_SELECTORS_OPEN, { selectorsOpen }); +export const setCombatMoveStats = (combatMoves : CombatMoveStats) => action(PokemonAppActionTypes.SET_COMBAT_MOVE_STATS, { combatMoves }); export const fetchConfig = ( ) : ThunkResult> => { return async (dispatch, getState, extraArguments) => { const config = await extraArguments.services.pokemonService.getConfig(); dispatch(setMaxPossibleStats(config.maxPossibleStats)); + dispatch(setAttackTypeEffectiveness(config.attackTypeEffectiveness)); dispatch(setCombatMoveStats(config.combatMoves)); }; }; - -export const maximizeLevel = ( -) : ThunkResult> => { - return async (dispatch, getState, extraArguments) => { - const pokemonExplorerState = getState().pokemonExplorerState; - const { - ivHp, - ivAtk, - ivDef, - } = pokemonExplorerState.individualValues; - - if (pokemonExplorerState.leaguePokemon !== null) { - const pokemonLeagueValues = pokemonExplorerState.leaguePokemon.pvp[pokemonExplorerState.league]; - const statsSet = pokemonLeagueValues.some((stats) => { - if (((ivHp === null) || (stats.ivHp === ivHp)) && - ((ivAtk === null) || (stats.ivAtk === ivAtk)) && - ((ivDef === null) || (stats.ivDef === ivDef)) - ) { - dispatch(setIvHp(stats.ivHp)); - dispatch(setIvAtk(stats.ivAtk)); - dispatch(setIvDef(stats.ivDef)); - dispatch(setIvLevel(stats.level)); - return true; - } - return false; - }); - if (!statsSet && ivHp !== null && ivAtk !== null && ivDef !== null) { - dispatch(setIvLevel(calculateMaxLevelForLeague(pokemonExplorerState.leaguePokemon.stats, ivHp, ivAtk, ivDef, pokemonExplorerState.league))); - } - } - }; -}; diff --git a/src/ts/app/components/IvForm.tsx b/src/ts/app/components/IvForm.tsx index c561689..8e00506 100644 --- a/src/ts/app/components/IvForm.tsx +++ b/src/ts/app/components/IvForm.tsx @@ -2,7 +2,7 @@ import React from 'react'; import classNames from 'classnames'; -import { IIndividualValues, IndividualValueKey } from '../types'; +import { IIndividualValues, IndividualValueKey } from 'app/components/PokemonExplorer/types'; import * as styles from 'app/styles/IvForm.scss'; diff --git a/src/ts/app/components/LeagueIvExplorer.tsx b/src/ts/app/components/LeagueIvExplorer.tsx index 0a8adcd..ee18e23 100644 --- a/src/ts/app/components/LeagueIvExplorer.tsx +++ b/src/ts/app/components/LeagueIvExplorer.tsx @@ -6,7 +6,7 @@ import { IBestWorstStats, ILeaguePokemon, League, MaxCpByLeague } from 'app/mode import { Grade, IStats } from 'app/models/Pokemon'; import { calculateCp, calculateStatAtLevel } from 'app/utils/calculator'; -import { IIndividualValues, IndividualValueKey } from 'app/types'; +import { IIndividualValues, IndividualValueKey } from 'app/components/PokemonExplorer/types'; import { IvForm } from './IvForm'; import { LeagueSelector } from './LeagueSelector'; diff --git a/src/ts/app/components/LeagueStatsList.tsx b/src/ts/app/components/LeagueStatsList.tsx index 797a138..1cb6f52 100644 --- a/src/ts/app/components/LeagueStatsList.tsx +++ b/src/ts/app/components/LeagueStatsList.tsx @@ -6,8 +6,8 @@ import { FixedSizeList } from 'react-window'; import classNames from 'classnames'; +import { IIndividualValues } from 'app/components/PokemonExplorer/types'; import { Grade, IStats } from 'app/models/Pokemon'; -import { IIndividualValues } from 'app/types'; import * as styles from 'app/styles/LeagueStatsList.scss'; diff --git a/src/ts/app/components/MovesExplorer.tsx b/src/ts/app/components/MovesExplorer.tsx index ffa7372..5850129 100644 --- a/src/ts/app/components/MovesExplorer.tsx +++ b/src/ts/app/components/MovesExplorer.tsx @@ -5,7 +5,7 @@ import classNames from 'classnames'; import { AttackTypeEffectiveness } from 'app/models/Config'; import { CombatMoveStats, ICombatMoveStats, IPokemonMove } from 'app/models/Pokemon'; -import { CombatMoveSelectorsOpen, SelectedCombatMoves } from 'app/types'; +import { CombatMoveSelectorsOpen, SelectedCombatMoves } from 'app/components/PokemonExplorer/types'; import { MovesDropdown } from 'app/components/MovesDropdown'; import { TypeIndicator } from './TypeIndicator'; @@ -21,7 +21,7 @@ export interface IMovesExplorerProps { chargeMove1 : IPokemonMove | null; chargeMove2 : IPokemonMove | null; }; - attackTypeEffectiveness : AttackTypeEffectiveness | null; + attackTypeEffectiveness : AttackTypeEffectiveness; combatMoveSelectorsOpen : CombatMoveSelectorsOpen; handleToggleDropdownOpen : (menu : keyof CombatMoveSelectorsOpen, isOpen : boolean) => void; handleChangeSelectedMove : (moves : SelectedCombatMoves) => void; diff --git a/src/ts/app/components/PokemonExplorer/PokemonExplorer.tsx b/src/ts/app/components/PokemonExplorer/PokemonExplorer.tsx new file mode 100644 index 0000000..f677e0c --- /dev/null +++ b/src/ts/app/components/PokemonExplorer/PokemonExplorer.tsx @@ -0,0 +1,298 @@ +import React from 'react'; +import { connect } from 'react-redux'; +import { RouteComponentProps } from 'react-router-dom'; + +import classNames from 'classnames'; + +import { AttackTypeEffectiveness } from 'app/models/Config'; +import { League } from 'app/models/League'; +import { CombatMoveStats } from 'app/models/Pokemon'; + +import * as ActionsPokemonExplorer from 'app/components/PokemonExplorer/actions'; +import { + CombatMoveSelectorsOpen, + IndividualValueKey, + IPokemonExplorerDispatch, + IPokemonExplorerStore, + SelectedCombatMoves +} from 'app/components/PokemonExplorer/types'; +import { IRouterProps } from 'app/types'; + +import { LeagueIvExplorer } from 'app/components/LeagueIvExplorer'; +import { MovesExplorer } from 'app/components/MovesExplorer'; +import { PokemonDisplay } from 'app/components/PokemonDisplay'; +import { TypeEffectiveDisplay } from 'app/components/TypeEffectiveDisplay'; + +import { appendQueryString } from 'app/utils/navigation'; + +import * as styles from 'app/styles/PokemonApp.scss'; + +// TODO: better way to expose IRouterProps than just passing them in??? +interface IPokemonExplorerProps extends IRouterProps { + isOverlaid : boolean; + attackTypeEffectiveness : AttackTypeEffectiveness; + combatMoves : CombatMoveStats; + toggleInterruption : (isInterruption : boolean) => void; +} + +interface IConnectedPokemonExplorerProps extends IPokemonExplorerStore, IPokemonExplorerDispatch, IPokemonExplorerProps {} + +type SubNavigation = 'pvp' | 'types' | 'moves'; +interface IState { + widgets : { [ key in SubNavigation ] : boolean }; +} + +class PokemonExplorer extends React.Component { + + constructor(props : IConnectedPokemonExplorerProps) { + super(props); + + this.state = { + widgets: { + pvp: true, + types: false, + moves: false, + }, + }; + } + + public render() { + const { + combatMoves, + attackTypeEffectiveness, + } = this.props; + const { + league, + individualValues, + leaguePokemon, + selectedCombatMoves, + combatMoveSelectorsOpen, + } = this.props.pokemonExplorerState; + const { + widgets, + } = this.state; + + const isOverlayShown = this.props.isOverlaid || combatMoveSelectorsOpen.quickMove || combatMoveSelectorsOpen.chargeMove1 || combatMoveSelectorsOpen.chargeMove2; + + const leftNavCss = classNames( + styles.leftNavigation, + ); + + const displayWrapperCss = classNames( + styles.displayWrapper, + ); + + const iconCss = classNames( + 'icon', + 'pixel', + 'sprite', + ); + + const pvpCss = classNames( + iconCss, + 'pvp', + { + active: widgets.pvp, + } + ); + const pvpButtonCss = classNames( + // { + // [styles.activeNavigationButton]: widgets.pvp, + // } + ); + const badgeCss = classNames( + iconCss, + 'badge', + { + active: widgets.types, + } + ); + const badgeButtonCss = classNames( + // { + // [styles.activeNavigationButton]: widgets.types, + // } + ); + const tmCss = classNames( + iconCss, + 'tm', + { + active: widgets.moves, + } + ); + const tmButtonCss = classNames( + // { + // [styles.activeNavigationButton]: widgets.moves, + // } + ); + + return ( +
+
+ { leaguePokemon !== null && + + } + { widgets.types && leaguePokemon !== null && + + } + { widgets.pvp && leaguePokemon !== null && + + } + { widgets.moves && leaguePokemon !== null && + + } +
+
+ + + +
+ { isOverlayShown && +
+ } +
+ ); + } + + private readonly handleToggleDropdownOpen = (menu : keyof CombatMoveSelectorsOpen, isOpen : boolean) => { + const combatMoveSelectorsOpen : CombatMoveSelectorsOpen = { + ...this.props.pokemonExplorerState.combatMoveSelectorsOpen, + [menu]: isOpen, // 3/10/2019: TyepScript is not checking this! + }; + this.props.dispatch(ActionsPokemonExplorer.setCombatMoveSelectorsOpen(combatMoveSelectorsOpen)); + this.props.toggleInterruption(true); + } + + private readonly handleOverlayClick = () => { + this.props.dispatch(ActionsPokemonExplorer.setCombatMoveSelectorsOpen({ + quickMove: false, + chargeMove1: false, + chargeMove2: false, + })); + this.props.toggleInterruption(false); + } + + private readonly handlePvpClick = () => { + const widgets = this.state.widgets; + this.setState({ + widgets: { + ...widgets, + pvp: !widgets.pvp + } + }); + } + + private readonly handleTypesClick = () => { + const widgets = this.state.widgets; + this.setState({ + widgets: { + ...widgets, + types: !widgets.types + } + }); + } + + private readonly handleMovesClick = () => { + const widgets = this.state.widgets; + this.setState({ + widgets: { + ...widgets, + moves: !widgets.moves + } + }); + } + + 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 handleChangeSelectedMove = (moves : SelectedCombatMoves) => { + this.props.dispatch(ActionsPokemonExplorer.setSelectedCombatMoves(moves)); + } + + // TODO: make this not overwrite other query parameters + 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 : IPokemonExplorerStore) : IPokemonExplorerStore => { + return { + ...state, + }; +}; + +const mapDispatchToProps = (dispatch : IPokemonExplorerDispatch['dispatch']) : IPokemonExplorerDispatch => { + return { + dispatch + }; +}; + +const mergeProps = (state : IPokemonExplorerStore, dispatchProps : IPokemonExplorerDispatch, ownProps : IPokemonExplorerProps) : IConnectedPokemonExplorerProps => { + return { + ...state, + ...dispatchProps, + ...ownProps, + history: ownProps.history, + location: ownProps.location, + }; +}; + +export const ConnectedPokemonExplorer = connect(mapStateToProps, mapDispatchToProps, mergeProps)(PokemonExplorer); diff --git a/src/ts/app/components/PokemonExplorer/actions.ts b/src/ts/app/components/PokemonExplorer/actions.ts new file mode 100644 index 0000000..7919757 --- /dev/null +++ b/src/ts/app/components/PokemonExplorer/actions.ts @@ -0,0 +1,62 @@ +import { action } from 'typesafe-actions'; + +import { + CombatMoveSelectorsOpen, + PokemonExplorerActionTypes, + SelectedCombatMoves, + ThunkResult +} from 'app/components/PokemonExplorer/types'; + +import { calculateMaxLevelForLeague } from 'app/utils/calculator'; + +import { ILeaguePokemon, League } from 'app/models/League'; + +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 = (ivHp : number | null) => action(PokemonExplorerActionTypes.SET_IV_HP, { ivHp }); + +export const setIvAtk = (ivAtk : number | null) => action(PokemonExplorerActionTypes.SET_IV_ATK, { ivAtk }); + +export const setIvDef = (ivDef : number | null) => action(PokemonExplorerActionTypes.SET_IV_DEF, { ivDef }); + +export const setActiveLeague = (league : League) => action(PokemonExplorerActionTypes.SET_ACTIVE_LEAGUE, { league }); + +export const setSelectedCombatMoves = (moves : SelectedCombatMoves) => action(PokemonExplorerActionTypes.SET_SELECTED_COMBAT_MOVES, { moves }); + +export const setCombatMoveSelectorsOpen = (selectorsOpen : CombatMoveSelectorsOpen) => action(PokemonExplorerActionTypes.SET_COMBAT_MOVE_SELECTORS_OPEN, { selectorsOpen }); + +export const maximizeLevel = ( + ) : ThunkResult> => { + return async (dispatch, getState, extraArguments) => { + const pokemonExplorerState = getState().pokemonExplorerState; + const { + ivHp, + ivAtk, + ivDef, + } = pokemonExplorerState.individualValues; + + if (pokemonExplorerState.leaguePokemon !== null) { + const pokemonLeagueValues = pokemonExplorerState.leaguePokemon.pvp[pokemonExplorerState.league]; + const statsSet = pokemonLeagueValues.some((stats) => { + if (((ivHp === null) || (stats.ivHp === ivHp)) && + ((ivAtk === null) || (stats.ivAtk === ivAtk)) && + ((ivDef === null) || (stats.ivDef === ivDef)) + ) { + dispatch(setIvHp(stats.ivHp)); + dispatch(setIvAtk(stats.ivAtk)); + dispatch(setIvDef(stats.ivDef)); + dispatch(setIvLevel(stats.level)); + return true; + } + return false; + }); + if (!statsSet && ivHp !== null && ivAtk !== null && ivDef !== null) { + dispatch(setIvLevel(calculateMaxLevelForLeague(pokemonExplorerState.leaguePokemon.stats, ivHp, ivAtk, ivDef, pokemonExplorerState.league))); + } + } + }; + }; diff --git a/src/ts/app/components/PokemonExplorer/reducers.ts b/src/ts/app/components/PokemonExplorer/reducers.ts new file mode 100644 index 0000000..8abd682 --- /dev/null +++ b/src/ts/app/components/PokemonExplorer/reducers.ts @@ -0,0 +1,144 @@ +import { Reducer } from 'redux'; + +import { League } from 'app/models/League'; + +import * as Actions from 'app/components/PokemonExplorer/actions'; +import { IPokemonExplorerState, PokemonExplorerActionTypes } from 'app/components/PokemonExplorer/types'; + +export const initialState : IPokemonExplorerState = { + isLoading: false, + leaguePokemon: null, + individualValues: { + level: null, + ivHp: null, + ivAtk: null, + ivDef: null, + }, + league: League.GREAT, + selectedCombatMoves: { + quickMove: null, + chargeMove1: null, + chargeMove2: null, + }, + combatMoveSelectorsOpen: { + quickMove: false, + chargeMove1: false, + chargeMove2: false, + }, +}; + +const reduceSetIsLoading = ( + state : IPokemonExplorerState, + action : ReturnType +) : IPokemonExplorerState => ({ + ...state, + isLoading: action.payload.isLoading, +}); + +const reduceSetLeaguePokemon = ( + state : IPokemonExplorerState, + action : ReturnType +) : IPokemonExplorerState => ({ + ...state, + leaguePokemon: action.payload.leaguePokemon, +}); + +const reduceSetIvLevel = ( + state : IPokemonExplorerState, + action : ReturnType +) : IPokemonExplorerState => ({ + ...state, + individualValues: { + ...state.individualValues, + level: action.payload.level, + } +}); + +const reduceSetIvHp = ( + state : IPokemonExplorerState, + action : ReturnType +) : IPokemonExplorerState => ({ + ...state, + individualValues: { + ...state.individualValues, + ivHp: action.payload.ivHp, + } +}); + +const reduceSetIvAtk = ( + state : IPokemonExplorerState, + action : ReturnType +) : IPokemonExplorerState => ({ + ...state, + individualValues: { + ...state.individualValues, + ivAtk: action.payload.ivAtk, + } +}); + +const reduceSetIvDef = ( + state : IPokemonExplorerState, + action : ReturnType +) : IPokemonExplorerState => ({ + ...state, + individualValues: { + ...state.individualValues, + ivDef: action.payload.ivDef, + } +}); + +const reduceSetActiveLeague = ( + state : IPokemonExplorerState, + action : ReturnType +) : IPokemonExplorerState => ({ + ...state, + league: action.payload.league +}); + +const reduceSetSelectedCombatMoves = ( + state : IPokemonExplorerState, + action : ReturnType +) : IPokemonExplorerState => ({ + ...state, + selectedCombatMoves: { + ...action.payload.moves + } +}); + +const reduceSetCombatMoveSelectorsOpen = ( + state : IPokemonExplorerState, + action : ReturnType +) : IPokemonExplorerState => ({ + ...state, + combatMoveSelectorsOpen: { + ...action.payload.selectorsOpen + } +}); + +export const PokemonExplorerReducers : Reducer = ( + state : IPokemonExplorerState = initialState, + action, +) : IPokemonExplorerState => { + switch (action.type) { + case PokemonExplorerActionTypes.SET_IS_LOADING: + return reduceSetIsLoading(state, action as ReturnType); + case PokemonExplorerActionTypes.SET_LEAGUE_POKEMON: + return reduceSetLeaguePokemon(state, action as ReturnType); + case PokemonExplorerActionTypes.SET_IV_LEVEL: + return reduceSetIvLevel(state, action as ReturnType); + case PokemonExplorerActionTypes.SET_IV_HP: + return reduceSetIvHp(state, action as ReturnType); + case PokemonExplorerActionTypes.SET_IV_ATK: + return reduceSetIvAtk(state, action as ReturnType); + case PokemonExplorerActionTypes.SET_IV_DEF: + return reduceSetIvDef(state, action as ReturnType); + case PokemonExplorerActionTypes.SET_ACTIVE_LEAGUE: + return reduceSetActiveLeague(state, action as ReturnType); + case PokemonExplorerActionTypes.SET_SELECTED_COMBAT_MOVES: + return reduceSetSelectedCombatMoves(state, action as ReturnType); + case PokemonExplorerActionTypes.SET_COMBAT_MOVE_SELECTORS_OPEN: + return reduceSetCombatMoveSelectorsOpen(state, action as ReturnType); + default: + return state; + } +}; diff --git a/src/ts/app/components/PokemonExplorer/types.ts b/src/ts/app/components/PokemonExplorer/types.ts new file mode 100644 index 0000000..168f162 --- /dev/null +++ b/src/ts/app/components/PokemonExplorer/types.ts @@ -0,0 +1,66 @@ +import { Action } from 'redux'; +import { ThunkAction, ThunkDispatch } from 'redux-thunk'; + +import { IProviderExtraArguments } from 'common/models/IProviderExtraArguments'; + +import { ILeaguePokemon, League } from 'app/models/League'; +import { IPokemonMove } from 'app/models/Pokemon'; + +import { PokemonService } from 'api/PokemonService'; + +export type IndividualValueKey = 'level' | 'hp' | 'atk' | 'def'; +export interface IIndividualValues { + level : number | null; + ivHp : number | null; + ivAtk : number | null; + ivDef : number | null; +} + +type MoveTypes = 'quickMove' | 'chargeMove1' | 'chargeMove2'; + +export type SelectedCombatMoves = { + [ key in MoveTypes ] : IPokemonMove | null; +}; + +export type CombatMoveSelectorsOpen = { + [ key in MoveTypes ] : boolean; +}; + +export interface IPokemonExplorerState { + isLoading : boolean; + leaguePokemon : ILeaguePokemon | null; + individualValues : IIndividualValues; + league : League; + selectedCombatMoves : SelectedCombatMoves; + combatMoveSelectorsOpen : CombatMoveSelectorsOpen; +} + +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', + SET_ACTIVE_LEAGUE: 'POKEMON_EXPLORER/SET_ACTIVE_LEAGUE', + SET_SELECTED_COMBAT_MOVES: 'POKEMON_EXPLORER/SET_SELECTED_COMBAT_MOVES', + SET_COMBAT_MOVE_SELECTORS_OPEN: 'POKEMON_EXPLORER/SET_COMBAT_MOVE_SELECTORS_OPEN', +}; + +export interface IPokemonExplorerStore { + pokemonExplorerState : IPokemonExplorerState; +} + +export interface IPokemonExplorerServices { + pokemonService : PokemonService; +} + +export interface IPokemonExplorerExtraArguments extends IProviderExtraArguments { + services : IPokemonExplorerServices; +} + +export type ThunkResult = ThunkAction; +type ThunkDispatchPokemonExplorer = ThunkDispatch; +export interface IPokemonExplorerDispatch { + dispatch : ThunkDispatchPokemonExplorer; +} diff --git a/src/ts/app/index.tsx b/src/ts/app/index.tsx index 5e8e219..e827e06 100644 --- a/src/ts/app/index.tsx +++ b/src/ts/app/index.tsx @@ -9,12 +9,14 @@ import { IPokemonAppExtraArguments } from 'app/types'; import { PokemonService } from 'api/PokemonService'; +import { PokemonExplorerReducers } from 'app/components/PokemonExplorer/reducers'; import { PokemonSelectListReducers } from 'app/components/PokemonSelectList/reducers'; -import { PokemonExplorerReducers } from 'app/reducers'; +import { PokemonAppReducers } from 'app/reducers'; import { ConnectedPokemonApp } from './PokemonApp'; export const appReducers = Redux.combineReducers({ + pokemonAppState: PokemonAppReducers, pokemonSelectListState: PokemonSelectListReducers, pokemonExplorerState: PokemonExplorerReducers, }); diff --git a/src/ts/app/reducers.ts b/src/ts/app/reducers.ts index a6c965e..ad00a6d 100644 --- a/src/ts/app/reducers.ts +++ b/src/ts/app/reducers.ts @@ -1,172 +1,67 @@ import { Reducer } from 'redux'; -import { League } from 'app/models/League'; - import * as Actions from 'app/actions'; -import { IPokemonExplorerState, PokemonExplorerActionTypes } from 'app/types'; +import { IPokemonAppState, PokemonAppActionTypes } from 'app/types'; -export const initialState : IPokemonExplorerState = { - isLoading: false, - leaguePokemon: null, +export const initialState : IPokemonAppState = { + isInterruption: false, maxPossibleStats: { baseStamina: 0, baseAttack: 0, baseDefense: 0, level: 0, }, - individualValues: { - level: null, - ivHp: null, - ivAtk: null, - ivDef: null, - }, - league: League.GREAT, + attackTypeEffectiveness: new Map(), combatMoves: new Map(), - selectedCombatMoves: { - quickMove: null, - chargeMove1: null, - chargeMove2: null, - }, - combatMoveSelectorsOpen: { - quickMove: false, - chargeMove1: false, - chargeMove2: false, - }, }; -const reduceSetIsLoading = ( - state : IPokemonExplorerState, - action : ReturnType -) : IPokemonExplorerState => ({ +const reduceSetInterruption = ( + state : IPokemonAppState, + action : ReturnType +) : IPokemonAppState => ({ ...state, - isLoading: action.payload.isLoading, + isInterruption: action.payload.isInterruption, }); const reduceSetMaxPossibleStats = ( - state : IPokemonExplorerState, + state : IPokemonAppState, action : ReturnType -) : IPokemonExplorerState => ({ +) : IPokemonAppState => ({ ...state, maxPossibleStats: { ...action.payload.maxStats, }, }); +const reduceSetAttackTypeEffectiveness = ( + state : IPokemonAppState, + action : ReturnType +) : IPokemonAppState => ({ + ...state, + attackTypeEffectiveness: action.payload.attackTypeEffectiveness, +}); + const reduceSetCombatMoveStats = ( - state : IPokemonExplorerState, + state : IPokemonAppState, action : ReturnType -) : IPokemonExplorerState => ({ +) : IPokemonAppState => ({ ...state, combatMoves: action.payload.combatMoves, }); -const reduceSetLeaguePokemon = ( - state : IPokemonExplorerState, - action : ReturnType -) : IPokemonExplorerState => ({ - ...state, - leaguePokemon: action.payload.leaguePokemon, -}); - -const reduceSetIvLevel = ( - state : IPokemonExplorerState, - action : ReturnType -) : IPokemonExplorerState => ({ - ...state, - individualValues: { - ...state.individualValues, - level: action.payload.level, - } -}); - -const reduceSetIvHp = ( - state : IPokemonExplorerState, - action : ReturnType -) : IPokemonExplorerState => ({ - ...state, - individualValues: { - ...state.individualValues, - ivHp: action.payload.ivHp, - } -}); - -const reduceSetIvAtk = ( - state : IPokemonExplorerState, - action : ReturnType -) : IPokemonExplorerState => ({ - ...state, - individualValues: { - ...state.individualValues, - ivAtk: action.payload.ivAtk, - } -}); - -const reduceSetIvDef = ( - state : IPokemonExplorerState, - action : ReturnType -) : IPokemonExplorerState => ({ - ...state, - individualValues: { - ...state.individualValues, - ivDef: action.payload.ivDef, - } -}); - -const reduceSetActiveLeague = ( - state : IPokemonExplorerState, - action : ReturnType -) : IPokemonExplorerState => ({ - ...state, - league: action.payload.league -}); - -const reduceSetSelectedCombatMoves = ( - state : IPokemonExplorerState, - action : ReturnType -) : IPokemonExplorerState => ({ - ...state, - selectedCombatMoves: { - ...action.payload.moves - } -}); - -const reduceSetCombatMoveSelectorsOpen = ( - state : IPokemonExplorerState, - action : ReturnType -) : IPokemonExplorerState => ({ - ...state, - combatMoveSelectorsOpen: { - ...action.payload.selectorsOpen - } -}); - -export const PokemonExplorerReducers : Reducer = ( - state : IPokemonExplorerState = initialState, +export const PokemonAppReducers : Reducer = ( + state : IPokemonAppState = initialState, action, -) : IPokemonExplorerState => { +) : IPokemonAppState => { switch (action.type) { - case PokemonExplorerActionTypes.SET_IS_LOADING: - return reduceSetIsLoading(state, action as ReturnType); - case PokemonExplorerActionTypes.SET_MAX_STATS: + case PokemonAppActionTypes.SET_IS_INTERRUPTION: + return reduceSetInterruption(state, action as ReturnType); + case PokemonAppActionTypes.SET_MAX_STATS: return reduceSetMaxPossibleStats(state, action as ReturnType); - case PokemonExplorerActionTypes.SET_COMBAT_MOVE_STATS: + case PokemonAppActionTypes.SET_ATTACK_TYPE_EFFECTIVENESS: + return reduceSetAttackTypeEffectiveness(state, action as ReturnType); + case PokemonAppActionTypes.SET_COMBAT_MOVE_STATS: return reduceSetCombatMoveStats(state, action as ReturnType); - case PokemonExplorerActionTypes.SET_LEAGUE_POKEMON: - return reduceSetLeaguePokemon(state, action as ReturnType); - case PokemonExplorerActionTypes.SET_IV_LEVEL: - return reduceSetIvLevel(state, action as ReturnType); - case PokemonExplorerActionTypes.SET_IV_HP: - return reduceSetIvHp(state, action as ReturnType); - case PokemonExplorerActionTypes.SET_IV_ATK: - return reduceSetIvAtk(state, action as ReturnType); - case PokemonExplorerActionTypes.SET_IV_DEF: - return reduceSetIvDef(state, action as ReturnType); - case PokemonExplorerActionTypes.SET_ACTIVE_LEAGUE: - return reduceSetActiveLeague(state, action as ReturnType); - case PokemonExplorerActionTypes.SET_SELECTED_COMBAT_MOVES: - return reduceSetSelectedCombatMoves(state, action as ReturnType); - case PokemonExplorerActionTypes.SET_COMBAT_MOVE_SELECTORS_OPEN: - return reduceSetCombatMoveSelectorsOpen(state, action as ReturnType); default: return state; } diff --git a/src/ts/app/types.ts b/src/ts/app/types.ts index 64953b6..fb154aa 100644 --- a/src/ts/app/types.ts +++ b/src/ts/app/types.ts @@ -1,22 +1,35 @@ -import POGOProtos from 'pogo-protos'; - +import { RouteComponentProps } from 'react-router-dom'; import { Action } from 'redux'; import { ThunkAction, ThunkDispatch } from 'redux-thunk'; import { IProviderExtraArguments } from 'common/models/IProviderExtraArguments'; +import { IPokemonExplorerStore } from 'app/components/PokemonExplorer/types'; import { IPokemonSelectListState } from 'app/components/PokemonSelectList/types'; - -import { ILeaguePokemon, League } from 'app/models/League'; -import { CombatMoveStats, IMaxStats, IPokemonMove } from 'app/models/Pokemon'; +import { AttackTypeEffectiveness } from 'app/models/Config'; +import { CombatMoveStats, IMaxStats } from 'app/models/Pokemon'; import { PokemonService } from 'api/PokemonService'; -export interface IPokemonAppStore { - pokemonSelectListState : IPokemonSelectListState; - pokemonExplorerState : IPokemonExplorerState; +export interface IPokemonAppState { + isInterruption : boolean; + maxPossibleStats : IMaxStats; + attackTypeEffectiveness : AttackTypeEffectiveness; + combatMoves : CombatMoveStats; } +export const PokemonAppActionTypes = { + SET_IS_INTERRUPTION: 'POKEMON_APP/SET_IS_INTERRUPTION', + 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', +}; + +export interface IPokemonAppStore extends IPokemonExplorerStore { + pokemonSelectListState : IPokemonSelectListState; +} + +// TODO: do i need to import/extend a service from PokemonExplorer? export interface IPokemonAppServices { pokemonService : PokemonService; } @@ -25,51 +38,13 @@ export interface IPokemonAppExtraArguments extends IProviderExtraArguments { services : IPokemonAppServices; } +export interface IRouterProps { + history : RouteComponentProps['history']; + location : RouteComponentProps['location']; +} + export type ThunkResult = ThunkAction; type ThunkDispatchPokemonApp = ThunkDispatch; export interface IPokemonAppDispatch { dispatch : ThunkDispatchPokemonApp; } - -export type IndividualValueKey = 'level' | 'hp' | 'atk' | 'def'; -export interface IIndividualValues { - level : number | null; - ivHp : number | null; - ivAtk : number | null; - ivDef : number | null; -} - -type MoveTypes = 'quickMove' | 'chargeMove1' | 'chargeMove2'; - -export type SelectedCombatMoves = { - [ key in MoveTypes ] : IPokemonMove | null; -}; - -export type CombatMoveSelectorsOpen = { - [ key in MoveTypes ] : boolean; -}; - -export interface IPokemonExplorerState { - isLoading : boolean; - leaguePokemon : ILeaguePokemon | null; - maxPossibleStats : IMaxStats; - individualValues : IIndividualValues; - league : League; - combatMoves : CombatMoveStats; - selectedCombatMoves : SelectedCombatMoves; - combatMoveSelectorsOpen : CombatMoveSelectorsOpen; -} - -export const PokemonExplorerActionTypes = { - SET_IS_LOADING: 'POKEMON_EXPLORER/SET_IS_LOADING', - SET_MAX_STATS: 'POKEMON_EXPLORER/SET_MAX_STATS', - SET_COMBAT_MOVE_STATS: 'POKEMON_EXPLORER/SET_COMBAT_MOVE_STATS', - 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', - SET_ACTIVE_LEAGUE: 'POKEMON_EXPLORER/SET_ACTIVE_LEAGUE', - SET_SELECTED_COMBAT_MOVES: 'POKEMON_EXPLORER/SET_SELECTED_COMBAT_MOVES', - SET_COMBAT_MOVE_SELECTORS_OPEN: 'POKEMON_EXPLORER/SET_COMBAT_MOVE_SELECTORS_OPEN', -};