From 13ff97b1a2def499ea47bd80d3ecc668c3043372 Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Sat, 8 Jun 2019 13:33:09 +1000 Subject: [PATCH] Got the BadgeText working --- server/badges.js | 25 +--- server/profiles.js | 163 +++++++++++++++++-------- server/utilities.js | 25 ++++ src/actions/profile.js | 22 +++- src/components/pages/profile.jsx | 13 +- src/components/panels/badge.jsx | 8 +- src/components/panels/badge_text.jsx | 33 +++++ src/components/panels/paged_ladder.jsx | 13 +- src/reducers/profile.js | 16 ++- 9 files changed, 229 insertions(+), 89 deletions(-) create mode 100644 src/components/panels/badge_text.jsx diff --git a/server/badges.js b/server/badges.js index c0c1ae7..f2238b8 100644 --- a/server/badges.js +++ b/server/badges.js @@ -4,30 +4,7 @@ require('dotenv').config(); //utilities let { log } = require('../common/utilities.js'); -let { logActivity } = require('./utilities.js'); - -const getBadgesStatistics = (cb) => { - //TODO: apiVisible field - return cb(undefined, { 'statistics': require('./badge_statistics.json') }); -}; - -const getBadgesOwned = (connection, id, cb) => { - let query = 'SELECT name, active FROM badges WHERE accountId = ?;'; - connection.query(query, [id], (err, results) => { - if (err) throw err; - - let ret = {}; //names, active - - Object.keys(results).map((key) => { - if (ret[results[key].name] !== undefined) { - log('WARNING: Invalid database state, badges owned', id, JSON.stringify(results)); - } - ret[results[key].name] = { active: results[key].active }; - }); - - return cb(undefined, { 'owned': ret }); - }); -} +let { logActivity, getBadgesStatistics, getBadgesOwned } = require('./utilities.js'); const listRequest = (connection) => (req, res) => { getBadgesStatistics((err, results) => { diff --git a/server/profiles.js b/server/profiles.js index 9bd6ed9..6676bff 100644 --- a/server/profiles.js +++ b/server/profiles.js @@ -4,7 +4,7 @@ require('dotenv').config(); //libraries let CronJob = require('cron').CronJob; -let { isAttacking, isSpying, logActivity } = require('./utilities.js'); +let { getBadgesStatistics, getBadgesOwned, isAttacking, isSpying, logActivity } = require('./utilities.js'); //utilities let { logDiagnostics } = require('./diagnostics.js'); @@ -77,17 +77,28 @@ function profileRequestInner(connection, req, res, body) { } }); } else { - //results.length === 1 - res.status(200).json({ - username: body.username, - gold: results[0].gold, - recruits: results[0].recruits, - soldiers: results[0].soldiers, - spies: results[0].spies, - scientists: results[0].scientists + getBadgesOwned(connection, results[0].accountId, (err, { owned }) => { + if (err) throw err; + + getBadgesStatistics((err, { statistics }) => { + if (err) throw err; + + let activeBadge = Object.keys(owned).find(name => owned[name].active) || null; + + res.status(200).json({ + username: body.username, + gold: results[0].gold, + recruits: results[0].recruits, + soldiers: results[0].soldiers, + spies: results[0].spies, + scientists: results[0].scientists, + activeBadge: activeBadge, + activeBadgeFilename: activeBadge ? statistics[activeBadge].filename : null + }); + res.end(); + log('Profile sent', body.username, body.id, body.token); + }); }); - res.end(); - log('Profile sent', body.username, body.id, body.token); } }); }; @@ -142,20 +153,31 @@ const recruitRequest = (connection) => (req, res) => { return; } - //results.length === 1 - res.status(200).json({ - username: results[0].username, - gold: results[0].gold, - recruits: results[0].recruits, - soldiers: results[0].soldiers, - spies: results[0].spies, - scientists: results[0].scientists - }); - res.end(); + getBadgesOwned(connection, results[0].accountId, (err, { owned }) => { + if (err) throw err; - log('Recruit successful', results[0].username, req.body.id, req.body.token); - logDiagnostics(connection, 'recruit', 1); - logActivity(connection, req.body.id); + getBadgesStatistics((err, { statistics }) => { + if (err) throw err; + + let activeBadge = Object.keys(owned).find(name => owned[name].active) || null; + + res.status(200).json({ + username: results[0].username, + gold: results[0].gold, + recruits: results[0].recruits, + soldiers: results[0].soldiers, + spies: results[0].spies, + scientists: results[0].scientists, + activeBadge: activeBadge, + activeBadgeFilename: activeBadge ? statistics[activeBadge].filename : null + }); + res.end(); + + log('Recruit successful', results[0].username, req.body.id, req.body.token); + logDiagnostics(connection, 'recruit', 1); + logActivity(connection, req.body.id); + }); + }); }); }); }); @@ -250,18 +272,30 @@ const trainRequest = (connection) => (req, res) => { return; } - //results.length === 1 - res.status(200).json({ - username: results[0].username, - gold: results[0].gold, - recruits: results[0].recruits, - soldiers: results[0].soldiers, - spies: results[0].spies, - scientists: results[0].scientists + getBadgesOwned(connection, results[0].accountId, (err, { owned }) => { + if (err) throw err; + + getBadgesStatistics((err, { statistics }) => { + if (err) throw err; + + let activeBadge = Object.keys(owned).find(name => owned[name].active) || null; + + res.status(200).json({ + username: results[0].username, + gold: results[0].gold, + recruits: results[0].recruits, + soldiers: results[0].soldiers, + spies: results[0].spies, + scientists: results[0].scientists, + activeBadge: activeBadge, + activeBadgeFilename: activeBadge ? statistics[activeBadge].filename : null + }); + res.end(); + + log('Train executed', results[0].username, req.body.role, req.body.id, req.body.token); + logActivity(connection, req.body.id); + }); }); - res.end(); - log('Train executed', results[0].username, req.body.role, req.body.id, req.body.token); - logActivity(connection, req.body.id); }); }); }); @@ -363,18 +397,30 @@ const untrainRequest = (connection) => (req, res) => { return; } - //results.length === 1 - res.status(200).json({ - username: results[0].username, - gold: results[0].gold, - recruits: results[0].recruits, - soldiers: results[0].soldiers, - spies: results[0].spies, - scientists: results[0].scientists + getBadgesOwned(connection, results[0].accountId, (err, { owned }) => { + if (err) throw err; + + getBadgesStatistics((err, { statistics }) => { + if (err) throw err; + + let activeBadge = Object.keys(owned).find(name => owned[name].active) || null; + + res.status(200).json({ + username: results[0].username, + gold: results[0].gold, + recruits: results[0].recruits, + soldiers: results[0].soldiers, + spies: results[0].spies, + scientists: results[0].scientists, + activeBadge: activeBadge, + activeBadgeFilename: activeBadge ? statistics[activeBadge].filename : null + }); + res.end(); + + log('Untrain executed', results[0].username, roleName, req.body.id, req.body.token); + logActivity(connection, req.body.id); + }); }); - res.end(); - log('Untrain executed', results[0].username, roleName, req.body.id, req.body.token); - logActivity(connection, req.body.id); }); }); }); @@ -384,12 +430,31 @@ const untrainRequest = (connection) => (req, res) => { }; const ladderRequest = (connection) => (req, res) => { - let query = 'SELECT username, soldiers, recruits, gold FROM accounts JOIN profiles ON accounts.id = profiles.accountId ORDER BY soldiers DESC, recruits DESC, gold DESC LIMIT ?, ?;'; + let query = 'SELECT accounts.id AS id, username, soldiers, recruits, gold FROM accounts JOIN profiles ON accounts.id = profiles.accountId ORDER BY soldiers DESC, recruits DESC, gold DESC LIMIT ?, ?;'; connection.query(query, [req.body.start, req.body.length], (err, results) => { if (err) throw err; - res.status(200).json(results); - log('Ladder sent', req.body.start, req.body.length, results); + getBadgesStatistics((err, { statistics }) => { + if (err) throw err; + + for(let i = 0; i < results.length; i++) { + getBadgesOwned(connection, results[i].id, (err, { owned }) => { + if (err) throw err; + + results[i].activeBadge = Object.keys(owned).find(name => owned[name].active) || null; + results[i].activeBadgeUrl = results[i].activeBadge ? statistics[results[i].activeBadge].filename : null; + + //don't share IDs + delete results[i].id; + + //weird, because of async + if (i + 1 === results.length) { + res.status(200).json(results); + log('Ladder sent', req.body.start, req.body.length, results); + } + }); + } + }); }); }; diff --git a/server/utilities.js b/server/utilities.js index 75fd8ff..0465a98 100644 --- a/server/utilities.js +++ b/server/utilities.js @@ -27,6 +27,29 @@ const getEquipmentOwned = (connection, id, cb) => { }); }; +const getBadgesStatistics = (cb) => { + //TODO: apiVisible field + return cb(undefined, { 'statistics': require('./badge_statistics.json') }); +}; + +const getBadgesOwned = (connection, id, cb) => { + let query = 'SELECT name, active FROM badges WHERE accountId = ?;'; + connection.query(query, [id], (err, results) => { + if (err) throw err; + + let ret = {}; //names, active + + Object.keys(results).map((key) => { + if (ret[results[key].name] !== undefined) { + log('WARNING: Invalid database state, badges owned', id, JSON.stringify(results)); + } + ret[results[key].name] = { active: results[key].active }; + }); + + return cb(undefined, { 'owned': ret }); + }); +} + const isNormalInteger = (str) => { let n = Math.floor(Number(str)); return n !== Infinity && String(n) == str && n >= 0; @@ -96,6 +119,8 @@ const logActivity = (connection, id) => { module.exports = { getEquipmentStatistics: getEquipmentStatistics, getEquipmentOwned: getEquipmentOwned, + getBadgesStatistics: getBadgesStatistics, + getBadgesOwned: getBadgesOwned, isAttacking: isAttacking, isSpying: isSpying, logActivity: logActivity diff --git a/src/actions/profile.js b/src/actions/profile.js index 17103bd..988a2f5 100644 --- a/src/actions/profile.js +++ b/src/actions/profile.js @@ -5,9 +5,11 @@ export const STORE_RECRUITS = 'STORE_RECRUITS'; export const STORE_SOLDIERS = 'STORE_SOLDIERS'; export const STORE_SPIES = 'STORE_SPIES'; export const STORE_SCIENTISTS = 'STORE_SCIENTISTS'; +export const STORE_ACTIVE_BADGE = 'STORE_ACTIVE_BADGE'; +export const STORE_ACTIVE_BADGE_FILENAME = 'STORE_ACTIVE_BADGE_FILENAME'; export const CLEAR_PROFILE = 'CLEAR_PROFILE'; -export const storeProfile = (username, gold, recruits, soldiers, spies, scientists) => { +export const storeProfile = (username, gold, recruits, soldiers, spies, scientists, activeBadge, activeBadgeFilename) => { return { type: STORE_PROFILE, username: username, @@ -15,7 +17,9 @@ export const storeProfile = (username, gold, recruits, soldiers, spies, scientis recruits: recruits, soldiers: soldiers, spies: spies, - scientists: scientists + scientists: scientists, + activeBadge: activeBadge, + activeBadgeFilename: activeBadgeFilename }; } @@ -61,6 +65,20 @@ export const storeScientists = (scientists) => { }; } +export const storeActiveBadge = (activeBadge) => { + return { + tpye: STORE_ACTIVE_BADGE, + activeBadge: activeBadge + }; +} + +export const storeActiveBadgeFilename = (activeBadgeFilename) => { + return { + tpye: STORE_ACTIVE_BADGE, + activeBadgeFilename: activeBadgeFilename + }; +} + export const clearProfile = () => { return { type: CLEAR_PROFILE diff --git a/src/components/pages/profile.jsx b/src/components/pages/profile.jsx index 1153f16..bc2ed05 100644 --- a/src/components/pages/profile.jsx +++ b/src/components/pages/profile.jsx @@ -10,6 +10,7 @@ import { storeProfile, clearProfile } from '../../actions/profile.js'; import CommonLinks from '../panels/common_links.jsx'; import AttackButton from '../panels/attack_button.jsx'; import Markdown from '../panels/markdown.jsx'; +import BadgeText from '../panels/badge_text.jsx'; class Profile extends React.Component { constructor(props) { @@ -103,7 +104,9 @@ class Profile extends React.Component { json.recruits, json.soldiers, json.spies, - json.scientists + json.scientists, + json.activeBadge, + json.activeBadgeFilename ); } else if (xhr.status === 400) { @@ -136,7 +139,7 @@ class Profile extends React.Component {

Username:

-

{this.props.profile.username}

+ {this.props.profile.username}
@@ -209,7 +212,7 @@ class Profile extends React.Component {

Username:

-

{this.props.profile.username}

+ {this.props.profile.username}
@@ -294,7 +297,7 @@ class Profile extends React.Component {

Username:

-

{this.props.profile.username}

+ {this.props.profile.username}
@@ -366,7 +369,7 @@ const mapStoreToProps = (store) => { const mapDispatchToProps = (dispatch) => { return { - storeProfile: (username, gold, recruits, soldiers, spies, scientists) => dispatch(storeProfile(username, gold, recruits, soldiers, spies, scientists)), + storeProfile: (username, gold, recruits, soldiers, spies, scientists, activeBadge, activeBadgeFilename) => dispatch(storeProfile(username, gold, recruits, soldiers, spies, scientists, activeBadge, activeBadgeFilename)), clearProfile: () => dispatch(clearProfile()) }; }; diff --git a/src/components/panels/badge.jsx b/src/components/panels/badge.jsx index 23b495f..a77b66c 100644 --- a/src/components/panels/badge.jsx +++ b/src/components/panels/badge.jsx @@ -10,6 +10,10 @@ class Badge extends React.Component { } render() { + if (!this.props.filename) { + return null; + } + let realSize = typeof(this.props.size) === 'number' ? this.props.number : this.parseSize(this.props.size); return ( @@ -18,8 +22,8 @@ class Badge extends React.Component { } parseSize(sizeString) { - if (sizeString === 'small') return 12; - if (sizeString === 'medium') return 20; + if (sizeString === 'small') return 20; + if (sizeString === 'medium') return 50; return 100; } }; diff --git a/src/components/panels/badge_text.jsx b/src/components/panels/badge_text.jsx new file mode 100644 index 0000000..bd7e1fe --- /dev/null +++ b/src/components/panels/badge_text.jsx @@ -0,0 +1,33 @@ +import React from 'react'; +import Badge from './badge.jsx'; + +class BadgeText extends React.Component { + render() { + if (!this.props.filename) { + return ( +

{this.props.children}

+ ); + } + + let centerStyle = { + display: 'flex', + justifyContent: 'center', + alignItems: 'center' + }; + + let leftStyle = { + display: 'flex' + }; + + let style = this.props.centered ? centerStyle : leftStyle; + + return ( +
+ +

{this.props.children}

+
+ ); + } +}; + +export default BadgeText; \ No newline at end of file diff --git a/src/components/panels/paged_ladder.jsx b/src/components/panels/paged_ladder.jsx index cc4d3d4..2390f1c 100644 --- a/src/components/panels/paged_ladder.jsx +++ b/src/components/panels/paged_ladder.jsx @@ -2,6 +2,7 @@ import React from 'react'; import { withRouter, Link } from 'react-router-dom'; import PropTypes from 'prop-types'; +import BadgeText from './badge_text.jsx'; import ProgressiveRainbowText from './progressive_rainbow_text.jsx'; class PagedLadder extends React.Component { @@ -28,12 +29,12 @@ class PagedLadder extends React.Component { {Object.keys(this.state).map((key) =>

-
- { - this.state[key].username === 'Ratstail91' ? - {this.state[key].username} : -

{this.state[key].username}

- } + +
+ + {this.state[key].username} + +

Soldiers: {this.state[key].soldiers}

Recruits: {this.state[key].recruits}

Gold: {this.state[key].gold}

diff --git a/src/reducers/profile.js b/src/reducers/profile.js index c4baa51..160df70 100644 --- a/src/reducers/profile.js +++ b/src/reducers/profile.js @@ -6,6 +6,8 @@ import { STORE_SOLDIERS, STORE_SPIES, STORE_SCIENTISTS, + STORE_ACTIVE_BADGE, + STORE_ACTIVE_BADGE_FILENAME, CLEAR_PROFILE } from '../actions/profile.js'; @@ -15,7 +17,9 @@ const initialStore = { recruits: 0, soldiers: 0, spies: 0, - scientists: 0 + scientists: 0, + activeBadge: '', + activeBadgeFilename: '' }; export const profileReducer = (store = initialStore, action) => { @@ -29,6 +33,8 @@ export const profileReducer = (store = initialStore, action) => { newStore.soldiers = action.soldiers; newStore.spies = action.spies; newStore.scientists = action.scientists; + newStore.activeBadge = action.activeBadge; + newStore.activeBadgeFilename = action.activeBadgeFilename; break; case STORE_USERNAME: @@ -55,6 +61,14 @@ export const profileReducer = (store = initialStore, action) => { newStore.scientists = action.scientists; break; + case STORE_ACTIVE_BADGE: + newStore.activeBadge = action.activeBadge; + break; + + case STORE_ACTIVE_BADGE_FILENAME: + newStore.activeBadgeFilename = action.activeBadgeFilename; + break; + case CLEAR_PROFILE: newStore = JSON.parse(JSON.stringify(initialStore)); break;