diff --git a/config/socketio.js b/config/socketio.js index 0d1ca81..89fcba8 100644 --- a/config/socketio.js +++ b/config/socketio.js @@ -9,7 +9,6 @@ var userController = require("../lib/user/controller"); var getRandomUser = function (callback) { var id = Math.floor(Math.random() * 5000) + 1; - console.log(id); client.getUserById({ id: id }, function (error, response, body) { @@ -29,6 +28,7 @@ module.exports = function (io) { return next(error) }; socket._user = new User(body); + console.log("You:", body.username, body.id); next(); }) }); diff --git a/lib/gather/controller.js b/lib/gather/controller.js index f126cbb..e155dc2 100644 --- a/lib/gather/controller.js +++ b/lib/gather/controller.js @@ -5,6 +5,7 @@ * * Server API * gather:refresh - Refreshes active gather + * gather:select - Selects a player for team * gather:notification - Creates a notification * * Client API @@ -40,6 +41,7 @@ for (var i = 0; i < 11; i++) { instructions.push(function (callback) { getRandomUser(function (error, response, body) { if (error) return callback(error); + console.log(body.username, body.id) if (gather.can("addGatherer")) { gather.addGatherer(new User(body)); } @@ -82,6 +84,13 @@ module.exports = function (namespace) { } }); + socket.on("gather:refresh", function () { + socket.emit("gather:refresh", { + gather: gather.toJson(), + currentGatherer: gather.getGatherer(socket._user) + }); + }); + socket.on("gather:leave", function (data) { if (gather.can("removeGatherer")) { gather.removeGatherer(socket._user); @@ -89,6 +98,38 @@ module.exports = function (namespace) { } }); + socket.on("gather:select", function (data) { + var playerId = data.player; + // Check team & leader + var gatherLeader = gather.getGatherer(socket._user); + + // Cancel if not gatherer or leader + if (gatherLeader === null || gatherLeader.leader === false) { + return null; + } + + // Cancel if id belongs to a leader + var selectedPlayer = gather.getGatherer({id: playerId}); + + if (selectedPlayer === null || selectedPlayer.leader) { + return null; + } + + var team = gatherLeader.team; + + var method = (team === 'alien') ? gather.moveToAlien : gather.moveToMarine; + method.call(gather, selectedPlayer.user); + + refreshGather(); + }); + + socket.on("gather:select:confirm", function () { + var user = socket._user; + if (gather.can("confirmSelection")) { + gather.confirmSelection(user); + } + }); + socket.on("disconnect", function () { }); diff --git a/lib/react/gather.jsx b/lib/react/gather.jsx index 4e3ab91..25b29e5 100644 --- a/lib/react/gather.jsx +++ b/lib/react/gather.jsx @@ -59,33 +59,39 @@ var JoinGatherButton = React.createClass({ var SelectPlayerButton = React.createClass({ selectPlayer: function (e) { e.preventDefault(); + socket.emit("gather:select", { + player: parseInt(e.target.value, 10) + }) }, render: function () { - if (!this.props.currentGatherer.leader) { - return false; + if (this.props.gatherer.leader) { + return (); } else { return ( ); } } -}) +}); var GatherTeams = React.createClass({ alienGatherers: function () { return this.props.gather.gatherers.filter(function (gatherer) { return gatherer.team === "alien"; }).sort(function (gatherer) { - return (gatherer.leader) ? 1 : 0; + return (gatherer.leader) ? 1 : -1; }); }, marineGatherers: function () { return this.props.gather.gatherers.filter(function (gatherer) { return gatherer.team === "marine"; }).sort(function (gatherer) { - return (gatherer.leader) ? 1 : 0; + return (gatherer.leader) ? 1 : -1; }); }, render: function () { @@ -224,6 +230,79 @@ var GatherProgress = React.createClass({ } }); +var GatherActions = React.createClass({ + leaveGather: function (e) { + e.preventDefault(); + socket.emit("gather:leave"); + }, + confirmTeam: function (e) { + e.preventDefault(); + socket.emit("gather:select:confirm"); + }, + inviteToGather: function (e) { + e.preventDefault(); + }, + render: function () { + var joinButton; + if (this.props.currentGatherer) { + joinButton = (
  • ); + } else { + joinButton = (
  • ); + } + + var confirmTeam; + if (this.props.currentGatherer && + this.props.currentGatherer.leader && + this.props.gather.state === 'selection' && + this.props.gather.gatherers.every(function (gatherer) { + return gatherer.team !== 'lobby'; + }) ) { + if (this.props.currentGatherer.confirm) { + confirmTeam = ( +
  • + +
  • + ); + } else { + confirmTeam = ( +
  • + +
  • + ); + } + } + + var inviteButton; + if (this.props.gather.state === 'gathering') { + inviteButton = (
  • ); + } + + return ( +
    + +
    + ); + } +}); + var Gather = React.createClass({ getDefaultProps: function () { return { @@ -232,9 +311,6 @@ var Gather = React.createClass({ } } }, - joinedGather: function () { - return this.props.currentGatherer !== null; - }, componentDidMount: function () { var self = this; socket.on("gather:refresh", function (data) { @@ -244,28 +320,13 @@ var Gather = React.createClass({ }); }); }, - leaveGather: function (e) { - e.preventDefault(); - socket.emit("gather:leave", {}); - }, - inviteToGather: function (e) { - e.preventDefault(); - }, + render: function () { - var joinButton; - if (this.joinedGather()) { - joinButton = (
  • ); - } else { - joinButton = (
  • ); - } - var inviteButton; - if (this.props.gather.state === 'gathering') { - inviteButton = (
  • ); + if (this.props.gather.state === 'done') { + return (

    Gather Completed! Now restart the app

    ); } + + var gatherTeams; if (this.props.gather.state === 'selection') { gatherTeams = @@ -279,12 +340,7 @@ var Gather = React.createClass({ {gatherTeams} -
    -
      - {inviteButton} - {joinButton} -
    -
    + ); } @@ -294,19 +350,20 @@ var Gatherers = React.createClass({ render: function () { var self = this; var gatherers = this.props.gather.gatherers.map(function (gatherer) { - var lifeforms = ( - gatherer.user.ability.lifeforms.map(function (lifeform) { - return ({lifeform}); - }) - ); - // Switch this to online status - var online= ( ); + var online= (
    ); var division = ({gatherer.user.ability.division}); - var action = lifeforms; + var action; + + if (self.props.gather.state === 'gathering') { + action = ( + gatherer.user.ability.lifeforms.map(function (lifeform) { + return ({lifeform}); + }) + ); + } + if (self.props.gather.state === "election") { var votes = self.props.gather.gatherers.reduce(function (acc, voter) { if (voter.leaderVote === gatherer.id) acc++; @@ -320,12 +377,20 @@ var Gatherers = React.createClass({ ); } + if (self.props.gather.state === 'selection') { + action = ( + + + + ); + } + return ( - {online} - {gatherer.user.username} + {online} + {gatherer.user.username} {division}  - {action}  + {action}  ); }) diff --git a/lib/react/user.jsx b/lib/react/user.jsx index 9c6fe65..0a02a6d 100644 --- a/lib/react/user.jsx +++ b/lib/react/user.jsx @@ -19,6 +19,9 @@ var UserLogin = React.createClass({ socket.emit("users:authorize", { id: id }); + setTimeout(function () { + socket.emit("gather:refresh"); + }, 5000); }, handleSubmit: function (e) { e.preventDefault(); diff --git a/public/css/app.css b/public/css/app.css index 5eb4315..81b02c8 100644 --- a/public/css/app.css +++ b/public/css/app.css @@ -21,12 +21,15 @@ margin: 0px 10px; } -.user-online { +.dot { + width: 8px; + height: 8px; border-radius: 50%; - width: 10px; - height: 10px; - - background-image: -moz-radial-gradient(45px 45px 45deg, circle cover, yellow 0%, orange 100%, red 95%); - background-image: -webkit-radial-gradient(45px 45px, circle cover, yellow, orange); - background-image: radial-gradient(45px 45px 45deg, circle cover, yellow 0%, orange 100%, red 95%); + vertical-align: middle; + position:relative; + display: inline-block; +} + +.online { + background: #0f0; } \ No newline at end of file diff --git a/public/js/app.js b/public/js/app.js index 0314448..00ff1fc 100644 --- a/public/js/app.js +++ b/public/js/app.js @@ -59,33 +59,39 @@ var JoinGatherButton = React.createClass({displayName: "JoinGatherButton", var SelectPlayerButton = React.createClass({displayName: "SelectPlayerButton", selectPlayer: function (e) { e.preventDefault(); + socket.emit("gather:select", { + player: parseInt(e.target.value, 10) + }) }, render: function () { - if (!this.props.currentGatherer.leader) { - return false; + if (this.props.gatherer.leader) { + return (React.createElement("button", { + className: "btn btn-xs btn-default", + "data-disabled": "true"}, "Leader")); } else { return (React.createElement("button", { onClick: this.selectPlayer, + value: this.props.gatherer.id, className: "btn btn-xs btn-primary"}, " Select" ) ); } } -}) +}); var GatherTeams = React.createClass({displayName: "GatherTeams", alienGatherers: function () { return this.props.gather.gatherers.filter(function (gatherer) { return gatherer.team === "alien"; }).sort(function (gatherer) { - return (gatherer.leader) ? 1 : 0; + return (gatherer.leader) ? 1 : -1; }); }, marineGatherers: function () { return this.props.gather.gatherers.filter(function (gatherer) { return gatherer.team === "marine"; }).sort(function (gatherer) { - return (gatherer.leader) ? 1 : 0; + return (gatherer.leader) ? 1 : -1; }); }, render: function () { @@ -224,6 +230,79 @@ var GatherProgress = React.createClass({displayName: "GatherProgress", } }); +var GatherActions = React.createClass({displayName: "GatherActions", + leaveGather: function (e) { + e.preventDefault(); + socket.emit("gather:leave"); + }, + confirmTeam: function (e) { + e.preventDefault(); + socket.emit("gather:select:confirm"); + }, + inviteToGather: function (e) { + e.preventDefault(); + }, + render: function () { + var joinButton; + if (this.props.currentGatherer) { + joinButton = (React.createElement("li", null, React.createElement("button", { + onClick: this.leaveGather, + className: "btn btn-danger"}, "Leave Gather"))); + } else { + joinButton = (React.createElement("li", null, React.createElement(JoinGatherButton, null))); + } + + var confirmTeam; + if (this.props.currentGatherer && + this.props.currentGatherer.leader && + this.props.gather.state === 'selection' && + this.props.gather.gatherers.every(function (gatherer) { + return gatherer.team !== 'lobby'; + }) ) { + if (this.props.currentGatherer.confirm) { + confirmTeam = ( + React.createElement("li", null, + React.createElement("button", { + className: "btn btn-default", + "data-disabled": "true" + }, + "Confirmed" + ) + ) + ); + } else { + confirmTeam = ( + React.createElement("li", null, + React.createElement("button", { + className: "btn btn-primary", + onClick: this.confirmTeam + }, + "Confirm Team" + ) + ) + ); + } + } + + var inviteButton; + if (this.props.gather.state === 'gathering') { + inviteButton = (React.createElement("li", null, React.createElement("button", { + onClick: this.inviteToGather, + className: "btn btn-primary"}, "Invite to Gather"))); + } + + return ( + React.createElement("div", {className: "panel-footer text-right"}, + React.createElement("ul", {className: "list-inline"}, + confirmTeam, + inviteButton, + joinButton + ) + ) + ); + } +}); + var Gather = React.createClass({displayName: "Gather", getDefaultProps: function () { return { @@ -232,9 +311,6 @@ var Gather = React.createClass({displayName: "Gather", } } }, - joinedGather: function () { - return this.props.currentGatherer !== null; - }, componentDidMount: function () { var self = this; socket.on("gather:refresh", function (data) { @@ -244,28 +320,13 @@ var Gather = React.createClass({displayName: "Gather", }); }); }, - leaveGather: function (e) { - e.preventDefault(); - socket.emit("gather:leave", {}); - }, - inviteToGather: function (e) { - e.preventDefault(); - }, + render: function () { - var joinButton; - if (this.joinedGather()) { - joinButton = (React.createElement("li", null, React.createElement("button", { - onClick: this.leaveGather, - className: "btn btn-danger"}, "Leave Gather"))); - } else { - joinButton = (React.createElement("li", null, React.createElement(JoinGatherButton, null))); - } - var inviteButton; - if (this.props.gather.state === 'gathering') { - inviteButton = (React.createElement("li", null, React.createElement("button", { - onClick: this.inviteToGather, - className: "btn btn-primary"}, "Invite to Gather"))); + if (this.props.gather.state === 'done') { + return (React.createElement("h1", null, "Gather Completed! Now restart the app")); } + + var gatherTeams; if (this.props.gather.state === 'selection') { gatherTeams = React.createElement(GatherTeams, {gather: this.props.gather}) @@ -279,12 +340,7 @@ var Gather = React.createClass({displayName: "Gather", React.createElement(Gatherers, {gather: this.props.gather, currentGatherer: this.props.currentGatherer}), gatherTeams, React.createElement(GatherProgress, {gather: this.props.gather}), - React.createElement("div", {className: "panel-footer text-right"}, - React.createElement("ul", {className: "list-inline"}, - inviteButton, - joinButton - ) - ) + React.createElement(GatherActions, React.__spread({}, this.props)) ) ); } @@ -294,19 +350,20 @@ var Gatherers = React.createClass({displayName: "Gatherers", render: function () { var self = this; var gatherers = this.props.gather.gatherers.map(function (gatherer) { - var lifeforms = ( - gatherer.user.ability.lifeforms.map(function (lifeform) { - return (React.createElement("span", {className: "label label-default"}, lifeform)); - }) - ); - // Switch this to online status - var online= (React.createElement("span", {src: "/images/commander.png", - alt: "online", - className: "user-online"}, " ")); + var online= (React.createElement("div", {className: "dot online"})); var division = (React.createElement("span", {className: "label label-primary"}, gatherer.user.ability.division)); - var action = lifeforms; + var action; + + if (self.props.gather.state === 'gathering') { + action = ( + gatherer.user.ability.lifeforms.map(function (lifeform) { + return (React.createElement("span", {className: "label label-default"}, lifeform)); + }) + ); + } + if (self.props.gather.state === "election") { var votes = self.props.gather.gatherers.reduce(function (acc, voter) { if (voter.leaderVote === gatherer.id) acc++; @@ -320,12 +377,20 @@ var Gatherers = React.createClass({displayName: "Gatherers", ); } + if (self.props.gather.state === 'selection') { + action = ( + React.createElement("span", null, + React.createElement(SelectPlayerButton, {gatherer: gatherer}) + ) + ); + } + return ( React.createElement("tr", {key: gatherer.user.id}, - React.createElement("td", {className: "col-md-1"}, online), - React.createElement("td", {className: "col-md-5"}, gatherer.user.username), + React.createElement("td", {className: "col-md-2"}, online), + React.createElement("td", {className: "col-md-4"}, gatherer.user.username), React.createElement("td", {className: "col-md-3"}, division, " "), - React.createElement("td", {className: "col-md-2 text-right"}, action, " ") + React.createElement("td", {className: "col-md-3 text-right"}, action, " ") ) ); }) @@ -543,6 +608,9 @@ var UserLogin = React.createClass({displayName: "UserLogin", socket.emit("users:authorize", { id: id }); + setTimeout(function () { + socket.emit("gather:refresh"); + }, 5000); }, handleSubmit: function (e) { e.preventDefault(); diff --git a/views/partials/menu.hbs b/views/partials/menu.hbs index 38e433d..76b7143 100644 --- a/views/partials/menu.hbs +++ b/views/partials/menu.hbs @@ -37,9 +37,6 @@