diff --git a/server/index.js b/server/index.js index 2e9f906..d8f1f24 100644 --- a/server/index.js +++ b/server/index.js @@ -38,6 +38,7 @@ app.post('/recruitrequest', profiles.recruitRequest(connection)); app.post('/trainrequest', profiles.trainRequest(connection)); app.post('/untrainrequest', profiles.untrainRequest(connection)); app.post('/ladderrequest', profiles.ladderRequest(connection)); +app.post('/attackrequest', profiles.attackRequest(connection)); profiles.runGoldTick(connection); //static directories diff --git a/server/profiles.js b/server/profiles.js index 8ba6dba..013078e 100644 --- a/server/profiles.js +++ b/server/profiles.js @@ -366,6 +366,11 @@ const ladderRequest = (connection) => (req, res) => { }); } +const attackRequest = (connection) => (req, res) => { + res.status(400).write(log('Not yet implemented')); + res.end(); +} + const runGoldTick = (connection) => { let goldTickJob = new CronJob('0 */30 * * * *', () => { let query = 'UPDATE profiles SET gold = gold + recruits;'; @@ -386,5 +391,6 @@ module.exports = { trainRequest: trainRequest, untrainRequest: untrainRequest, ladderRequest: ladderRequest, + attackRequest: attackRequest, runGoldTick: runGoldTick } \ No newline at end of file diff --git a/src/actions/combat.js b/src/actions/combat.js new file mode 100644 index 0000000..1906331 --- /dev/null +++ b/src/actions/combat.js @@ -0,0 +1,8 @@ +export const SET_ATTACK_DISABLED = 'SET_ATTACK_DISABLED'; + +export function setAttackDisabled(disabled) { + return { + type: SET_ATTACK_DISABLED, + disabled: disabled + } +} \ No newline at end of file diff --git a/src/components/app.jsx b/src/components/app.jsx index fe6781b..afcb050 100644 --- a/src/components/app.jsx +++ b/src/components/app.jsx @@ -5,11 +5,37 @@ import Loadable from 'react-loadable'; //other stuff import Footer from './panels/footer.jsx'; -//lazy route loading +//lazy route loading (with error handling) const LazyRoute = (props) => { const component = Loadable({ loader: props.component, - loading: () =>

Loading...

, + + loading: (props) => { + if (props.error) { + return ( +
+
+

{props.error}

+
+
+ ); + } else if (props.timeOut) { + return ( +
+
+

Timed Out

+
+
+ ); + } else { + return ( +
+

Loading...

+
+ ); + } + }, + timeout: 10000 }); return ; diff --git a/src/components/pages/profile.jsx b/src/components/pages/profile.jsx index 9227ddf..b02d975 100644 --- a/src/components/pages/profile.jsx +++ b/src/components/pages/profile.jsx @@ -6,6 +6,7 @@ import queryString from 'query-string'; //panels import CommonLinks from '../panels/common_links.jsx'; +import AttackButton from '../panels/attack_button.jsx'; class Profile extends React.Component { constructor(props) { @@ -123,7 +124,7 @@ class Profile extends React.Component { //panel functions MyProfileSidePanel() { - //finally return the side panel + //return the side panel return (
@@ -178,7 +179,7 @@ class Profile extends React.Component { } NotMyProfileSidePanel() { - //finally return the side panel + //return the side panel return (
{e.preventDefault(); this.sendRequest('/profilerequest', this.props.username); this.setWarning(''); this.props.history.push('/profile');}} /> @@ -206,8 +207,7 @@ class Profile extends React.Component {

Recruits:

{this.state.recruits}

-
-
+
diff --git a/src/components/panels/attack_button.jsx b/src/components/panels/attack_button.jsx new file mode 100644 index 0000000..049b5df --- /dev/null +++ b/src/components/panels/attack_button.jsx @@ -0,0 +1,78 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { connect } from 'react-redux'; + +import { setAttackDisabled } from '../../actions/combat.js'; + +class AttackButton extends React.Component { + constructor(props) { + super(props); + this.state = { + // + }; + } + + render() { + return ( + + ); + } + + sendAttackRequest() { + //build the XHR + let xhr = new XMLHttpRequest(); + xhr.open('POST', '/attackrequest', true); + + xhr.onreadystatechange = () => { + if (xhr.readyState === 4) { + if (xhr.status === 200) { + //DO NOTHING + } else if (xhr.status === 400) { + if (this.props.setWarning) { + this.props.setWarning(xhr.responseText); + } + } + } + } + + xhr.setRequestHeader('Content-Type', 'application/json; charset=UTF-8'); + xhr.send(JSON.stringify({ + attacker: this.props.attacker, + defender: this.props.defender + })); + + if (this.props.onClick) { + this.props.onClick(); + } + + this.props.setDisabled(true); + } +}; + +AttackButton.propTypes = { + className: PropTypes.string, + style: PropTypes.object, + onClick: PropTypes.func, + setWarning: PropTypes.func, + attacker: PropTypes.string.isRequired, + defender: PropTypes.string.isRequired, + + disabled: PropTypes.bool.isRequired, + setDisabled: PropTypes.func.isRequired +}; + +function mapStoreToProps(store) { + return { + disabled: store.combat.attackDisabled + } +} + +function mapDispatchToProps(dispatch) { + return { + setDisabled: (disabled) => dispatch(setAttackDisabled(disabled)) + } +} + +AttackButton = connect(mapStoreToProps, mapDispatchToProps)(AttackButton); + +export default AttackButton; \ No newline at end of file diff --git a/src/components/panels/login.jsx b/src/components/panels/login.jsx index ef95e07..378a7c8 100644 --- a/src/components/panels/login.jsx +++ b/src/components/panels/login.jsx @@ -128,7 +128,7 @@ function mapStoreToProps(store) { function mapDispatchToProps(dispatch) { return { - login: (id, email, username, token) => { dispatch(login(id, email, username, token)) } + login: (id, email, username, token) => dispatch(login(id, email, username, token)) } } diff --git a/src/reducers/combat.js b/src/reducers/combat.js new file mode 100644 index 0000000..a4397c4 --- /dev/null +++ b/src/reducers/combat.js @@ -0,0 +1,18 @@ +import { SET_ATTACK_DISABLED } from '../actions/combat.js'; + +const initialStore = { + attackDisabled: true +}; + +export function combatReducer(store = initialStore, action) { + switch(action.type) { + case SET_ATTACK_DISABLED: { + let newStore = JSON.parse(JSON.stringify(initialStore)); + newStore.attackDisabled = action.disabled; + return newStore; + } + + default: + return store; + } +} \ No newline at end of file diff --git a/src/reducers/reducer.js b/src/reducers/reducer.js index abaf44b..9e5affd 100644 --- a/src/reducers/reducer.js +++ b/src/reducers/reducer.js @@ -1,8 +1,10 @@ import { combineReducers } from 'redux'; import { accountReducer } from './accounts.js'; +import { combatReducer } from './combat.js'; //compile all reducers together export default combineReducers({ - account: accountReducer + account: accountReducer, + combat: combatReducer });