Finish player selection phase

This commit is contained in:
Chris Blanchard 2015-07-29 00:32:50 +01:00
parent 9515c8c6f7
commit 755cb50dcd
7 changed files with 286 additions and 106 deletions

View file

@ -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();
})
});

View file

@ -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 () {
});

View file

@ -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 (<button
className="btn btn-xs btn-default"
data-disabled="true">Leader</button>);
} else {
return (<button
onClick={this.selectPlayer}
value={this.props.gatherer.id}
className="btn btn-xs btn-primary"> Select
</button>
);
}
}
})
});
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 = (<li><button
onClick={this.leaveGather}
className="btn btn-danger">Leave Gather</button></li>);
} else {
joinButton = (<li><JoinGatherButton /></li>);
}
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 = (
<li>
<button
className="btn btn-default"
data-disabled="true"
>
Confirmed
</button>
</li>
);
} else {
confirmTeam = (
<li>
<button
className="btn btn-primary"
onClick={this.confirmTeam}
>
Confirm Team
</button>
</li>
);
}
}
var inviteButton;
if (this.props.gather.state === 'gathering') {
inviteButton = (<li><button
onClick={this.inviteToGather}
className="btn btn-primary">Invite to Gather</button></li>);
}
return (
<div className="panel-footer text-right">
<ul className="list-inline">
{confirmTeam}
{inviteButton}
{joinButton}
</ul>
</div>
);
}
});
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 = (<li><button
onClick={this.leaveGather}
className="btn btn-danger">Leave Gather</button></li>);
} else {
joinButton = (<li><JoinGatherButton /></li>);
}
var inviteButton;
if (this.props.gather.state === 'gathering') {
inviteButton = (<li><button
onClick={this.inviteToGather}
className="btn btn-primary">Invite to Gather</button></li>);
if (this.props.gather.state === 'done') {
return (<h1>Gather Completed! Now restart the app</h1>);
}
var gatherTeams;
if (this.props.gather.state === 'selection') {
gatherTeams = <GatherTeams gather={this.props.gather} />
@ -279,12 +340,7 @@ var Gather = React.createClass({
<Gatherers gather={this.props.gather} currentGatherer={this.props.currentGatherer} />
{gatherTeams}
<GatherProgress gather={this.props.gather} />
<div className="panel-footer text-right">
<ul className="list-inline">
{inviteButton}
{joinButton}
</ul>
</div>
<GatherActions {...this.props} />
</div>
);
}
@ -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 (<span className="label label-default">{lifeform}</span>);
})
);
// Switch this to online status
var online= (<span src="/images/commander.png"
alt="online"
className="user-online">&nbsp;</span>);
var online= (<div className="dot online"></div>);
var division = (<span className="label label-primary">{gatherer.user.ability.division}</span>);
var action = lifeforms;
var action;
if (self.props.gather.state === 'gathering') {
action = (
gatherer.user.ability.lifeforms.map(function (lifeform) {
return (<span className="label label-default">{lifeform}</span>);
})
);
}
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 = (
<span>
<SelectPlayerButton gatherer={gatherer} />
</span>
);
}
return (
<tr key={gatherer.user.id}>
<td className="col-md-1">{online}</td>
<td className="col-md-5">{gatherer.user.username}</td>
<td className="col-md-2">{online}</td>
<td className="col-md-4">{gatherer.user.username}</td>
<td className="col-md-3">{division}&nbsp;</td>
<td className="col-md-2 text-right">{action}&nbsp;</td>
<td className="col-md-3 text-right">{action}&nbsp;</td>
</tr>
);
})

View file

@ -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();

View file

@ -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;
}

View file

@ -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();

View file

@ -37,9 +37,6 @@
</div>
<ul class="nav navbar-top-links navbar-right">
<li>
<a href="#" data-toggle="modal" data-target="#designmodal">Design Goals</a>
</li>
<li class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
<i class="fa fa-user fa-fw"></i> Settings <i class="fa fa-caret-down"></i>
@ -51,8 +48,11 @@
</li>
<li><a href="#"><i class="fa fa-music fa-fw"></i> Sounds</a>
</li>
<li>
<a href="#" data-toggle="modal" data-target="#designmodal">Design Goals</a>
</li>
<li class="divider"></li>
<li><a href="login.html"><i class="fa fa-sign-out fa-fw"></i> Logout</a>
<li><a href="login.html"><i class="fa fa-sign-out fa-fw"></i> Logout</a>
</li>
</ul>
</li>