ensl_gathers/public/js/app.js

1568 lines
35 KiB
JavaScript
Raw Normal View History

2015-07-22 00:00:05 +00:00
"use strict";
2015-08-09 14:48:42 +00:00
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
var SelectPlayerButton = React.createClass({
displayName: "SelectPlayerButton",
selectPlayer: function selectPlayer(e) {
2015-07-28 15:54:29 +00:00
e.preventDefault();
2015-07-28 23:32:50 +00:00
socket.emit("gather:select", {
player: parseInt(e.target.value, 10)
2015-08-09 14:48:42 +00:00
});
2015-07-28 15:54:29 +00:00
},
2015-08-11 00:19:04 +00:00
2015-08-09 14:48:42 +00:00
render: function render() {
2015-07-28 23:32:50 +00:00
if (this.props.gatherer.leader) {
2015-08-09 14:48:42 +00:00
return React.createElement(
"button",
{
className: "btn btn-xs btn-default",
"data-disabled": "true" },
"Leader"
);
2015-08-08 17:13:17 +00:00
} else if (this.props.gatherer.team !== "lobby") {
2015-08-09 14:48:42 +00:00
return React.createElement(
"button",
{
onClick: this.selectPlayer,
value: this.props.gatherer.id,
className: "btn btn-xs btn-default" },
" Reselect"
2015-08-08 17:13:17 +00:00
);
2015-07-28 15:54:29 +00:00
} else {
2015-08-09 14:48:42 +00:00
return React.createElement(
"button",
{
onClick: this.selectPlayer,
value: this.props.gatherer.id,
className: "btn btn-xs btn-primary" },
" Select"
2015-07-28 15:54:29 +00:00
);
}
}
2015-07-28 23:32:50 +00:00
});
2015-07-28 15:54:29 +00:00
2015-08-09 14:48:42 +00:00
var GathererList = React.createClass({
displayName: "GathererList",
memberList: function memberList() {
2015-08-08 19:14:16 +00:00
var self = this;
2015-07-28 15:54:29 +00:00
return this.props.gather.gatherers.filter(function (gatherer) {
2015-08-08 19:14:16 +00:00
return gatherer.team === self.props.team;
2015-07-28 15:54:29 +00:00
}).sort(function (gatherer) {
2015-08-09 14:48:42 +00:00
return gatherer.leader ? 1 : -1;
2015-07-28 15:54:29 +00:00
});
},
2015-08-11 00:19:04 +00:00
2015-08-09 14:48:42 +00:00
render: function render() {
var extractGatherer = function extractGatherer(gatherer) {
2015-07-28 15:54:29 +00:00
var image;
if (gatherer.leader) {
2015-08-09 14:48:42 +00:00
image = React.createElement("img", { src: "/images/commander.png",
alt: "Commander",
height: "20",
width: "20" });
2015-07-28 15:54:29 +00:00
}
2015-08-09 14:48:42 +00:00
return React.createElement(
"tr",
{ key: gatherer.id },
React.createElement(
"td",
{ className: "col-md-1" },
image
),
React.createElement(
"td",
{ className: "col-md-11" },
gatherer.user.username
2015-07-28 15:54:29 +00:00
)
);
2015-08-09 14:48:42 +00:00
};
2015-08-08 19:14:16 +00:00
var members = this.memberList().map(extractGatherer);
2015-08-09 14:48:42 +00:00
return React.createElement(
"table",
{ className: "table" },
React.createElement(
"tbody",
null,
members
2015-08-08 19:14:16 +00:00
)
);
}
});
2015-08-09 14:48:42 +00:00
var GatherTeams = React.createClass({
displayName: "GatherTeams",
render: function render() {
return React.createElement(
"div",
{ className: "panel-body" },
React.createElement(
"div",
{ className: "row" },
React.createElement(
"div",
{ className: "col-md-6" },
React.createElement(
"div",
{ className: "panel panel-default" },
React.createElement(
"div",
{ className: "panel-heading" },
"Aliens"
),
React.createElement(GathererList, { gather: this.props.gather, team: "alien" })
)
),
React.createElement(
"div",
{ className: "col-md-6" },
React.createElement(
"div",
{ className: "panel panel-default" },
React.createElement(
"div",
{ className: "panel-heading" },
"Marines"
),
React.createElement(GathererList, { gather: this.props.gather, team: "marine" })
2015-07-28 15:54:29 +00:00
)
)
)
);
}
2015-08-08 19:14:16 +00:00
});
2015-07-28 15:54:29 +00:00
2015-08-09 14:48:42 +00:00
var ElectionProgressBar = React.createClass({
displayName: "ElectionProgressBar",
componentDidMount: function componentDidMount() {
2015-07-31 15:54:08 +00:00
var self = this;
this.timer = setInterval(function () {
self.forceUpdate();
}, 900);
},
2015-08-11 00:19:04 +00:00
2015-08-09 14:48:42 +00:00
progress: function progress() {
2015-07-31 15:54:08 +00:00
var interval = this.props.gather.election.interval;
2015-08-09 14:48:42 +00:00
var startTime = new Date(this.props.gather.election.startTime).getTime();
var msTranspired = Math.floor(new Date().getTime() - startTime);
2015-07-31 15:54:08 +00:00
return {
num: msTranspired,
den: interval,
barMessage: Math.floor((interval - msTranspired) / 1000) + "s remaining"
2015-08-09 14:48:42 +00:00
};
2015-07-31 15:54:08 +00:00
},
2015-08-11 00:19:04 +00:00
2015-08-09 14:48:42 +00:00
componentWillUnmount: function componentWillUnmount() {
2015-07-31 15:54:08 +00:00
clearInterval(this.timer);
},
2015-08-11 00:19:04 +00:00
2015-08-09 14:48:42 +00:00
render: function render() {
return React.createElement(ProgressBar, { progress: this.progress() });
2015-07-31 15:54:08 +00:00
}
});
2015-08-09 14:48:42 +00:00
var ProgressBar = React.createClass({
displayName: "ProgressBar",
render: function render() {
2015-07-31 15:54:08 +00:00
var style = {
2015-08-09 14:48:42 +00:00
width: Math.round(this.props.progress.num / this.props.progress.den * 100) + "%"
2015-07-31 15:54:08 +00:00
};
var barMessage = this.props.progress.barMessage || "";
2015-08-09 14:48:42 +00:00
return React.createElement(
"div",
{ className: "progress" },
React.createElement(
"div",
{ className: "progress-bar progress-bar-striped active",
"data-role": "progressbar",
"data-aria-valuenow": this.props.progress.num,
"data-aria-valuemin": "0",
"data-aria-valuemax": this.props.progress.den,
style: style },
barMessage
)
2015-07-31 15:54:08 +00:00
);
}
});
2015-08-09 14:48:42 +00:00
var GatherProgress = React.createClass({
displayName: "GatherProgress",
stateDescription: function stateDescription() {
switch (this.props.gather.state) {
2015-07-28 15:54:29 +00:00
case "gathering":
return "Waiting for more gatherers.";
case "election":
return "Currently voting for team leaders.";
case "selection":
2015-07-31 16:34:27 +00:00
return "Waiting for leaders to pick teams.";
2015-07-28 15:54:29 +00:00
case "done":
return "Gather completed.";
default:
return "Initialising gather.";
}
},
2015-08-11 00:19:04 +00:00
2015-08-09 14:48:42 +00:00
gatheringProgress: function gatheringProgress() {
2015-07-26 11:54:35 +00:00
var num = this.props.gather.gatherers.length;
var den = 12;
2015-07-28 15:54:29 +00:00
var remaining = den - num;
2015-08-09 14:48:42 +00:00
var message = remaining === 1 ? "Waiting for last player" : "Waiting for " + remaining + " more players";
2015-07-26 11:54:35 +00:00
return {
num: num,
den: den,
2015-07-28 15:54:29 +00:00
message: message
2015-07-26 11:54:35 +00:00
};
},
2015-08-11 00:19:04 +00:00
2015-08-09 14:48:42 +00:00
electionProgress: function electionProgress() {
2015-07-26 11:54:35 +00:00
var num = this.props.gather.gatherers.reduce(function (acc, gatherer) {
if (gatherer.leaderVote) acc++;
return acc;
}, 0);
var den = 12;
return {
num: num,
den: den,
message: den - num + " more votes required"
};
},
2015-08-11 00:19:04 +00:00
2015-08-09 14:48:42 +00:00
selectionProgress: function selectionProgress() {
2015-07-26 11:54:35 +00:00
var num = this.props.gather.gatherers.reduce(function (acc, gatherer) {
if (gatherer.team !== "lobby") acc++;
return acc;
}, 0);
var den = 12;
return {
num: num,
den: den,
message: num + " out of " + den + " players assigned"
};
},
2015-08-11 00:19:04 +00:00
2015-08-09 14:48:42 +00:00
render: function render() {
2015-07-31 15:54:08 +00:00
var progress, progressBar;
2015-07-26 11:54:35 +00:00
var gatherState = this.props.gather.state;
if (gatherState === 'gathering' && this.props.gather.gatherers.length) {
progress = this.gatheringProgress();
2015-08-09 14:48:42 +00:00
progressBar = React.createElement(ProgressBar, { progress: progress });
2015-07-26 11:54:35 +00:00
} else if (gatherState === 'election') {
progress = this.electionProgress();
2015-08-09 14:48:42 +00:00
progressBar = React.createElement(ElectionProgressBar, _extends({}, this.props, { progress: progress }));
2015-07-26 11:54:35 +00:00
} else if (gatherState === 'selection') {
progress = this.selectionProgress();
2015-08-09 14:48:42 +00:00
progressBar = React.createElement(ProgressBar, { progress: progress });
2015-07-26 11:54:35 +00:00
}
2015-07-31 15:54:08 +00:00
if (!progress) return false;
2015-08-09 14:48:42 +00:00
return React.createElement(
"div",
{ className: "panel-body no-bottom" },
React.createElement(
"p",
null,
React.createElement(
"strong",
null,
this.stateDescription()
),
" ",
progress.message
),
progressBar
2015-07-31 15:54:08 +00:00
);
2015-07-26 11:54:35 +00:00
}
});
2015-08-27 11:57:35 +00:00
var TeamSpeakButton = React.createClass({
displayName: "TeamSpeakButton",
getDefaultProps: function getDefaultProps() {
var password = "ns2gather";
return {
url: "ts3server://ensl.org/",
password: password,
alien: {
channel: "NS2 Gather/Gather #1/Alien (Team Y)",
password: password
},
marine: {
channel: "NS2 Gather/Gather #1/Marine (Team X)",
password: password
}
};
},
marineUrl: function marineUrl() {
2015-08-27 14:00:10 +00:00
return this.teamSpeakUrl(this.props.marine);
2015-08-27 11:57:35 +00:00
},
alienUrl: function alienUrl() {
2015-08-27 14:00:10 +00:00
return this.teamSpeakUrl(this.props.alien);
2015-08-27 11:57:35 +00:00
},
teamSpeakUrl: function teamSpeakUrl(conn) {
var params = "channel=" + encodeURIComponent(conn.channel) + "&channelpassword=" + encodeURIComponent(conn.password);
return this.props.url + "?" + params;
},
render: function render() {
return React.createElement(
"div",
{ className: "btn-group dropup" },
React.createElement(
"button",
{ type: "button", className: "btn btn-primary dropdown-toggle", "data-toggle": "dropdown", "aria-haspopup": "true", "aria-expanded": "false" },
"Teamspeak ",
React.createElement("span", { className: "caret" })
),
React.createElement(
"ul",
{ className: "dropdown-menu" },
React.createElement(
"li",
null,
React.createElement(
"a",
{ href: this.props.url },
"Join Teamspeak Lobby"
)
),
React.createElement(
"li",
null,
React.createElement(
"a",
{ href: this.marineUrl() },
"Join Marine Teamspeak"
)
),
React.createElement(
"li",
null,
React.createElement(
"a",
{ href: this.alienUrl() },
"Join Alien Teamspeak"
)
),
React.createElement("li", { role: "separator", className: "divider" }),
React.createElement(
"li",
null,
React.createElement(
"a",
{ href: "#", "data-toggle": "modal", "data-target": "#teamspeakmodal" },
2015-08-27 14:00:10 +00:00
"Teamspeak Details"
2015-08-27 11:57:35 +00:00
)
)
),
React.createElement(
"div",
{ className: "modal fade text-left", id: "teamspeakmodal" },
React.createElement(
"div",
{ className: "modal-dialog" },
React.createElement(
"div",
{ className: "modal-content" },
React.createElement(
"div",
{ className: "modal-header" },
React.createElement(
"button",
{ type: "button", className: "close", "data-dismiss": "modal", "aria-label": "Close" },
React.createElement(
"span",
{ "aria-hidden": "true" },
"×"
)
),
React.createElement(
"h4",
{ className: "modal-title" },
"Teamspeak Server Information"
)
),
React.createElement(
"div",
{ className: "modal-body" },
React.createElement(
"dl",
{ className: "dl-horizontal" },
React.createElement(
"dt",
null,
"Server"
),
React.createElement(
"dd",
null,
this.props.url
),
React.createElement(
"dt",
null,
"Password"
),
React.createElement(
"dd",
null,
this.props.password
),
React.createElement(
"dt",
null,
"Marine Channel"
),
React.createElement(
"dd",
null,
this.props.marine.channel
),
React.createElement(
"dt",
null,
"Alien Channel"
),
React.createElement(
"dd",
null,
this.props.alien.channel
)
)
)
)
)
)
);
}
});
2015-08-09 14:48:42 +00:00
var GatherActions = React.createClass({
displayName: "GatherActions",
joinGather: function joinGather(e) {
2015-07-29 14:35:58 +00:00
e.preventDefault();
socket.emit("gather:join");
},
2015-08-11 00:19:04 +00:00
2015-08-09 14:48:42 +00:00
leaveGather: function leaveGather(e) {
2015-07-24 17:05:12 +00:00
e.preventDefault();
2015-07-28 23:32:50 +00:00
socket.emit("gather:leave");
},
2015-08-11 00:19:04 +00:00
2015-08-09 14:48:42 +00:00
confirmTeam: function confirmTeam(e) {
2015-07-28 23:32:50 +00:00
e.preventDefault();
socket.emit("gather:select:confirm");
2015-07-24 17:05:12 +00:00
},
2015-08-11 00:19:04 +00:00
2015-08-09 14:48:42 +00:00
inviteToGather: function inviteToGather(e) {
2015-07-26 11:54:35 +00:00
e.preventDefault();
2015-07-29 14:35:58 +00:00
alert("Boop!");
2015-07-26 11:54:35 +00:00
},
2015-08-11 00:19:04 +00:00
2015-08-09 14:48:42 +00:00
render: function render() {
2015-07-24 17:05:12 +00:00
var joinButton;
2015-07-28 23:32:50 +00:00
if (this.props.currentGatherer) {
2015-08-09 14:48:42 +00:00
joinButton = React.createElement(
"li",
null,
React.createElement(
"button",
{
onClick: this.leaveGather,
className: "btn btn-danger" },
"Leave Gather"
)
);
2015-07-29 14:35:58 +00:00
} else if (this.props.gather.state === 'gathering') {
2015-08-09 14:48:42 +00:00
joinButton = React.createElement(
"button",
{
onClick: this.joinGather,
className: "btn btn-success" },
"Join Gather"
2015-07-29 14:35:58 +00:00
);
2015-07-26 11:54:35 +00:00
}
2015-07-28 23:32:50 +00:00
var confirmTeam;
2015-08-09 14:48:42 +00:00
if (this.props.currentGatherer && this.props.currentGatherer.leader && this.props.gather.state === 'selection' && this.props.gather.gatherers.every(function (gatherer) {
return gatherer.team !== 'lobby';
})) {
2015-07-28 23:32:50 +00:00
if (this.props.currentGatherer.confirm) {
2015-08-09 14:48:42 +00:00
confirmTeam = React.createElement(
"li",
null,
React.createElement(
"button",
{
className: "btn btn-default",
2015-07-28 23:32:50 +00:00
"data-disabled": "true"
2015-08-09 14:48:42 +00:00
},
"Confirmed"
2015-07-28 23:32:50 +00:00
)
);
} else {
2015-08-09 14:48:42 +00:00
confirmTeam = React.createElement(
"li",
null,
React.createElement(
"button",
{
className: "btn btn-success",
onClick: this.confirmTeam
},
2015-07-28 23:32:50 +00:00
"Confirm Team"
)
);
}
}
2015-07-26 11:54:35 +00:00
var inviteButton;
if (this.props.gather.state === 'gathering') {
2015-08-09 14:48:42 +00:00
inviteButton = React.createElement(
"li",
null,
React.createElement(
"button",
{
onClick: this.inviteToGather,
className: "btn btn-primary" },
"Invite to Gather"
)
);
2015-07-24 17:05:12 +00:00
}
2015-07-28 23:32:50 +00:00
2015-08-09 14:48:42 +00:00
return React.createElement(
"div",
{ className: "panel-footer text-right" },
React.createElement(
"ul",
{ className: "list-inline no-bottom" },
2015-08-27 11:57:35 +00:00
React.createElement(TeamSpeakButton, null),
2015-08-09 14:48:42 +00:00
confirmTeam,
inviteButton,
joinButton
2015-07-28 23:32:50 +00:00
)
);
}
});
2015-08-27 14:53:11 +00:00
var VoteButton = React.createClass({
displayName: "VoteButton",
cancelVote: function cancelVote(e) {
socket.emit("gather:vote", {
leader: {
candidate: null
}
});
},
2015-08-09 14:48:42 +00:00
2015-08-27 14:53:11 +00:00
vote: function vote(e) {
2015-07-29 13:50:39 +00:00
e.preventDefault();
socket.emit("gather:vote", {
2015-08-27 14:53:11 +00:00
leader: {
candidate: parseInt(e.target.value, 10)
2015-07-29 13:50:39 +00:00
}
});
},
2015-08-11 00:19:04 +00:00
2015-08-27 14:53:11 +00:00
render: function render() {
if (this.props.currentGatherer === null) {
return false;
}
if (this.props.currentGatherer.leaderVote === this.props.candidate.id) {
return React.createElement(
"button",
{
onClick: this.cancelVote,
className: "btn btn-xs btn-success" },
"Voted"
);
} else {
return React.createElement(
"button",
{
onClick: this.vote,
className: "btn btn-xs btn-default",
value: this.props.candidate.id },
"Vote"
);
}
}
});
var ServerVoting = React.createClass({
displayName: "ServerVoting",
voteHandler: function voteHandler(serverId) {
return function (e) {
e.preventDefault();
socket.emit("gather:vote", {
server: {
id: serverId
}
});
};
},
2015-08-09 14:48:42 +00:00
votesForServer: function votesForServer(server) {
2015-07-29 13:50:39 +00:00
return this.props.gather.gatherers.reduce(function (acc, gatherer) {
if (server.id === gatherer.serverVote) acc++;
return acc;
}, 0);
},
2015-08-11 00:19:04 +00:00
2015-08-09 14:48:42 +00:00
render: function render() {
2015-07-29 13:50:39 +00:00
var self = this;
var servers = self.props.servers.map(function (server) {
2015-08-27 14:53:11 +00:00
var votes = self.votesForServer(server);
2015-07-29 13:50:39 +00:00
if (self.props.currentGatherer.serverVote === server.id) {
2015-08-27 14:53:11 +00:00
return React.createElement(
"a",
{ href: "#", className: "list-group-item list-group-item-success", key: server.id },
React.createElement(
"span",
{ className: "badge" },
votes
),
server.description || server.dns
2015-08-09 14:48:42 +00:00
);
2015-07-29 13:50:39 +00:00
} else {
2015-08-27 14:53:11 +00:00
return React.createElement(
"a",
{ href: "#", className: "list-group-item",
onClick: self.voteHandler(server.id),
key: server.id },
React.createElement(
"span",
{ className: "badge" },
votes
),
server.description || server.dns
2015-08-09 14:48:42 +00:00
);
2015-07-29 13:50:39 +00:00
}
});
2015-08-27 14:53:11 +00:00
2015-08-27 15:11:54 +00:00
var voted = self.props.currentGatherer.serverVote !== null;
2015-08-27 14:53:11 +00:00
2015-08-09 14:48:42 +00:00
return React.createElement(
"div",
{ className: "panel panel-default" },
React.createElement(
"div",
{ className: "panel-heading" },
2015-08-27 15:11:54 +00:00
voted ? "Server Votes" : "Please Vote for a Server"
2015-08-09 14:48:42 +00:00
),
React.createElement(
2015-08-27 14:53:11 +00:00
"div",
{ className: "list-group gather-voting" },
2015-08-09 14:48:42 +00:00
servers
2015-07-29 13:50:39 +00:00
)
);
}
2015-08-09 14:48:42 +00:00
});
var MapVoting = React.createClass({
displayName: "MapVoting",
2015-07-29 13:50:39 +00:00
2015-08-27 14:53:11 +00:00
voteHandler: function voteHandler(mapId) {
return function (e) {
e.preventDefault();
socket.emit("gather:vote", {
map: {
id: mapId
}
});
};
2015-07-29 13:50:39 +00:00
},
2015-08-11 00:19:04 +00:00
2015-08-09 14:48:42 +00:00
votesForMap: function votesForMap(map) {
2015-07-29 13:50:39 +00:00
return this.props.gather.gatherers.reduce(function (acc, gatherer) {
if (map.id === gatherer.mapVote) acc++;
return acc;
}, 0);
},
2015-08-11 00:19:04 +00:00
2015-08-09 14:48:42 +00:00
render: function render() {
2015-07-29 13:50:39 +00:00
var self = this;
var maps = self.props.maps.map(function (map) {
2015-08-27 14:53:11 +00:00
var votes = self.votesForMap(map);
2015-07-29 13:50:39 +00:00
if (self.props.currentGatherer.mapVote === map.id) {
2015-08-27 14:53:11 +00:00
return React.createElement(
"a",
{ href: "#",
key: map.id,
className: "list-group-item list-group-item-success" },
React.createElement(
"span",
{ className: "badge" },
votes
),
map.name
2015-08-09 14:48:42 +00:00
);
2015-07-29 13:50:39 +00:00
} else {
2015-08-27 14:53:11 +00:00
return React.createElement(
"a",
{ href: "#",
key: map.id,
onClick: self.voteHandler(map.id),
className: "list-group-item" },
React.createElement(
"span",
{ className: "badge" },
votes
),
map.name
2015-08-09 14:48:42 +00:00
);
2015-07-29 13:50:39 +00:00
}
});
2015-08-27 15:11:54 +00:00
var voted = self.props.currentGatherer.mapVote !== null;
2015-08-09 14:48:42 +00:00
return React.createElement(
"div",
{ className: "panel panel-default" },
React.createElement(
"div",
{ className: "panel-heading" },
2015-08-27 15:11:54 +00:00
voted ? "Map Votes" : "Please Vote for a Map"
2015-08-09 14:48:42 +00:00
),
React.createElement(
2015-08-27 14:53:11 +00:00
"div",
{ className: "list-group gather-voting" },
2015-08-09 14:48:42 +00:00
maps
2015-07-29 13:50:39 +00:00
)
);
}
2015-08-09 14:48:42 +00:00
});
2015-07-29 13:50:39 +00:00
2015-08-09 14:48:42 +00:00
var Gather = React.createClass({
displayName: "Gather",
getDefaultProps: function getDefaultProps() {
2015-07-28 23:32:50 +00:00
return {
gather: {
gatherers: []
}
2015-08-09 14:48:42 +00:00
};
2015-07-28 23:32:50 +00:00
},
2015-08-11 00:19:04 +00:00
2015-08-09 14:48:42 +00:00
componentDidMount: function componentDidMount() {
2015-07-28 23:32:50 +00:00
var self = this;
socket.on("gather:refresh", function (data) {
2015-08-11 00:19:04 +00:00
return self.setProps(data);
2015-07-28 23:32:50 +00:00
});
},
2015-08-09 14:48:42 +00:00
render: function render() {
2015-07-28 23:32:50 +00:00
if (this.props.gather.state === 'done') {
2015-08-09 14:48:42 +00:00
return React.createElement(CompletedGather, this.props);
2015-07-28 23:32:50 +00:00
}
2015-07-29 13:50:39 +00:00
var voting;
if (this.props.currentGatherer) {
2015-08-09 14:48:42 +00:00
voting = React.createElement(
"div",
{ className: "panel-body" },
React.createElement(
"div",
{ className: "row" },
React.createElement(
"div",
{ className: "col-md-6" },
React.createElement(MapVoting, this.props)
),
React.createElement(
"div",
{ className: "col-md-6" },
React.createElement(ServerVoting, this.props)
2015-07-29 13:50:39 +00:00
)
)
);
}
2015-07-28 15:54:29 +00:00
var gatherTeams;
if (this.props.gather.state === 'selection') {
2015-08-09 14:48:42 +00:00
gatherTeams = React.createElement(GatherTeams, { gather: this.props.gather });
2015-07-28 15:54:29 +00:00
}
var previousGather;
if (this.props.previousGather) {
previousGather = React.createElement(CompletedGather, _extends({}, this.props, { gather: this.props.previousGather }));
}
2015-08-09 14:48:42 +00:00
return React.createElement(
"div",
null,
2015-08-09 14:48:42 +00:00
React.createElement(
"div",
{ className: "panel panel-default" },
2015-08-09 14:48:42 +00:00
React.createElement(
"div",
{ className: "panel-heading" },
React.createElement(
"strong",
null,
"Current Gather"
),
React.createElement(
"span",
{ className: "badge add-left" },
this.props.gather.gatherers.length
)
2015-08-09 14:48:42 +00:00
),
React.createElement(GatherProgress, this.props),
React.createElement(Gatherers, this.props),
gatherTeams,
voting,
React.createElement(GatherActions, this.props)
2015-08-09 14:48:42 +00:00
),
previousGather
2015-07-22 22:34:57 +00:00
);
}
});
2015-08-09 14:48:42 +00:00
var Gatherers = React.createClass({
displayName: "Gatherers",
joinGather: function joinGather(e) {
2015-07-29 14:35:58 +00:00
e.preventDefault();
socket.emit("gather:join");
},
2015-08-11 00:19:04 +00:00
2015-08-09 14:48:42 +00:00
render: function render() {
2015-07-27 11:55:36 +00:00
var self = this;
var gatherers = this.props.gather.gatherers.map(function (gatherer) {
2015-08-09 14:48:42 +00:00
2015-08-08 17:13:17 +00:00
// Country
var country;
if (gatherer.user.country) {
2015-08-09 14:48:42 +00:00
country = React.createElement("img", { src: "images/blank.gif",
className: "flag flag-" + gatherer.user.country.toLowerCase(),
alt: gatherer.user.country });
2015-08-08 17:13:17 +00:00
};
2015-07-25 12:00:56 +00:00
2015-08-09 14:48:42 +00:00
var division = React.createElement(
"span",
{ className: "label label-primary" },
gatherer.user.ability.division
2015-08-05 00:06:09 +00:00
);
2015-08-09 14:48:42 +00:00
var lifeform = gatherer.user.ability.lifeforms.map(function (lifeform) {
return React.createElement(
"span",
{ className: "label label-default",
key: [lifeform, gatherer.id].join("-") },
lifeform
);
});
var team;
2015-08-08 15:27:17 +00:00
if (gatherer.user.team) {
2015-08-09 14:48:42 +00:00
team = React.createElement(
"span",
{ className: "label label-primary" },
gatherer.user.team.name
);
2015-08-08 15:27:17 +00:00
}
2015-07-28 23:32:50 +00:00
2015-08-05 00:06:09 +00:00
var action;
2015-07-28 23:32:50 +00:00
2015-07-27 11:55:36 +00:00
if (self.props.gather.state === "election") {
var votes = self.props.gather.gatherers.reduce(function (acc, voter) {
if (voter.leaderVote === gatherer.id) acc++;
return acc;
2015-08-09 14:48:42 +00:00
}, 0);
action = React.createElement(
"span",
null,
React.createElement(
"small",
null,
votes + " votes",
"  "
),
React.createElement(VoteButton, { currentGatherer: self.props.currentGatherer, candidate: gatherer })
2015-07-27 11:55:36 +00:00
);
}
2015-07-28 23:32:50 +00:00
if (self.props.gather.state === 'selection') {
2015-08-08 17:13:17 +00:00
if (self.props.currentGatherer && self.props.currentGatherer.leader) {
2015-08-09 14:48:42 +00:00
action = React.createElement(
"span",
null,
React.createElement(SelectPlayerButton, { gatherer: gatherer })
2015-08-08 17:13:17 +00:00
);
} else {
if (gatherer.team !== "lobby") {
2015-08-09 14:48:42 +00:00
action = React.createElement(
"span",
{ className: "label label-success" },
gatherer.team
);
2015-08-08 17:13:17 +00:00
}
}
2015-07-28 23:32:50 +00:00
}
2015-08-09 14:48:42 +00:00
return React.createElement(
"tr",
2015-08-18 09:56:35 +00:00
{ key: gatherer.user.id, "data-userid": gatherer.user.id },
2015-08-09 14:48:42 +00:00
React.createElement(
"td",
{ className: "col-md-5" },
country,
" ",
gatherer.user.username,
2015-08-18 09:56:35 +00:00
" "
2015-08-09 14:48:42 +00:00
),
React.createElement(
"td",
{ className: "col-md-5" },
lifeform,
" ",
division,
" ",
team,
" "
),
React.createElement(
"td",
{ className: "col-md-2 text-right" },
action,
" "
2015-07-24 17:05:12 +00:00
)
);
2015-08-09 14:48:42 +00:00
});
2015-07-27 11:55:36 +00:00
if (this.props.gather.gatherers.length) {
2015-08-09 14:48:42 +00:00
return React.createElement(
"div",
{ className: "panel-body" },
React.createElement(
"div",
{ className: "panel panel-default" },
React.createElement(
"table",
{ className: "table roster-table" },
React.createElement(
"tbody",
null,
gatherers
2015-07-26 11:54:35 +00:00
)
2015-07-24 17:05:12 +00:00
)
)
2015-07-26 11:54:35 +00:00
);
} else {
2015-08-09 14:48:42 +00:00
return React.createElement(
"div",
{ className: "panel-body text-center join-hero" },
React.createElement(
"button",
{
onClick: this.joinGather,
className: "btn btn-success btn-lg" },
"Start a Gather"
2015-07-29 10:46:30 +00:00
)
);
2015-07-26 11:54:35 +00:00
}
2015-07-24 15:01:56 +00:00
}
});
2015-08-09 14:48:42 +00:00
var CompletedGather = React.createClass({
displayName: "CompletedGather",
countVotes: function countVotes(voteType) {
2015-08-08 19:14:16 +00:00
return this.props.gather.gatherers.reduce(function (acc, gatherer) {
if (gatherer[voteType] !== null) acc.push(gatherer[voteType]);
return acc;
}, []);
2015-07-29 14:35:58 +00:00
},
2015-08-11 00:19:04 +00:00
2015-08-09 14:48:42 +00:00
selectedMaps: function selectedMaps() {
return rankVotes(this.countVotes('mapVote'), this.props.maps).slice(0, 2);
2015-08-08 19:14:16 +00:00
},
2015-08-11 00:19:04 +00:00
2015-08-09 14:48:42 +00:00
selectedServer: function selectedServer() {
2015-08-08 19:14:16 +00:00
return rankVotes(this.countVotes('serverVote'), this.props.servers).slice(0, 1);
2015-07-29 14:35:58 +00:00
},
2015-08-11 00:19:04 +00:00
2015-08-09 14:48:42 +00:00
render: function render() {
2015-08-08 19:14:16 +00:00
var maps = this.selectedMaps();
var server = this.selectedServer().pop();
2015-08-09 14:48:42 +00:00
return React.createElement(
"div",
{ className: "panel panel-default" },
React.createElement(
"div",
{ className: "panel-heading" },
React.createElement(
"strong",
null,
"Previous Gather"
2015-08-09 14:48:42 +00:00
)
),
React.createElement(GatherTeams, { gather: this.props.gather }),
React.createElement(
"div",
{ className: "panel-body" },
React.createElement(
"dl",
{ className: "dl-horizontal" },
React.createElement(
"dt",
null,
"Maps"
),
React.createElement(
"dd",
null,
maps.map(function (map) {
return map.name;
}).join(" & ")
),
React.createElement(
"dt",
null,
"Server"
),
React.createElement(
"dd",
null,
server.name
),
React.createElement(
"dt",
null,
"Address"
),
React.createElement(
"dd",
null,
server.ip,
":",
server.port
),
React.createElement(
"dt",
null,
"Password"
),
React.createElement(
"dd",
null,
server.password
),
React.createElement("br", null),
React.createElement(
"dt",
null,
" "
),
React.createElement(
"dd",
null,
React.createElement(
"a",
{ href: ["steam://run/4920/connect", server.ip + ":" + server.port, server.password].join("/"),
className: "btn btn-primary" },
"Click to Join"
)
2015-08-08 19:14:16 +00:00
)
)
2015-07-29 14:35:58 +00:00
)
);
}
});
2015-07-28 15:54:29 +00:00
"use strict";
2015-07-22 00:00:05 +00:00
var socket;
2015-08-11 00:37:43 +00:00
var initialiseVisibilityMonitoring = function initialiseVisibilityMonitoring(socket) {
var hidden = undefined,
visibilityChange = undefined;
2015-08-09 14:48:42 +00:00
if (typeof document.hidden !== "undefined") {
// Opera 12.10 and Firefox 18 and later support
hidden = "hidden";
visibilityChange = "visibilitychange";
2015-07-29 10:46:30 +00:00
} else if (typeof document.mozHidden !== "undefined") {
2015-08-09 14:48:42 +00:00
hidden = "mozHidden";
visibilityChange = "mozvisibilitychange";
2015-07-29 10:46:30 +00:00
} else if (typeof document.msHidden !== "undefined") {
2015-08-09 14:48:42 +00:00
hidden = "msHidden";
visibilityChange = "msvisibilitychange";
2015-07-29 10:46:30 +00:00
} else if (typeof document.webkitHidden !== "undefined") {
2015-08-09 14:48:42 +00:00
hidden = "webkitHidden";
visibilityChange = "webkitvisibilitychange";
2015-07-29 10:46:30 +00:00
}
document.addEventListener(visibilityChange, function () {
if (document[hidden]) {
socket.emit("users:away");
} else {
socket.emit("users:online");
}
}, false);
2015-08-11 00:37:43 +00:00
};
2015-07-29 10:46:30 +00:00
2015-08-18 09:56:35 +00:00
var removeAuthWidget = function removeAuthWidget() {
$("#authenticating").remove();
};
var showAuthenticationNotice = function showAuthenticationNotice() {
$("#auth-required").show();
};
2015-08-27 12:11:38 +00:00
var showGatherBanNotice = function showGatherBanNotice() {
$("#gather-banned").show();
};
2015-08-18 09:56:35 +00:00
var renderPage = function renderPage(socket) {
initialiseVisibilityMonitoring(socket);
React.render(React.createElement(UserMenu, null), document.getElementById('side-menu'));
React.render(React.createElement(Chatroom, null), document.getElementById('chatroom'));
React.render(React.createElement(Gather, null), document.getElementById('gathers'));
React.render(React.createElement(CurrentUser, null), document.getElementById('currentuser'));
React.render(React.createElement(AdminPanel, null), document.getElementById('admin-menu'));
};
2015-08-11 00:37:43 +00:00
var initialiseComponents = function initialiseComponents() {
2015-07-22 14:13:08 +00:00
var socketUrl = window.location.protocol + "//" + window.location.host;
2015-08-09 14:48:42 +00:00
socket = io(socketUrl).on("connect", function () {
console.log("Connected");
2015-08-18 09:56:35 +00:00
removeAuthWidget();
renderPage(socket);
2015-08-27 11:07:45 +00:00
socket.on("reconnect", function () {
socket.emit("message:refresh");
socket.emit("gather:refresh");
socket.emit("users:refresh");
console.log("Reconnected");
}).on("disconnect", function () {
console.log("Disconnected");
});
2015-08-18 09:56:35 +00:00
}).on("error", function (error, foo) {
console.log(error);
if (error === "Authentication Failed") {
removeAuthWidget();
showAuthenticationNotice();
2015-08-27 12:11:38 +00:00
} else if (error === "Gather Banned") {
removeAuthWidget();
showGatherBanNotice();
2015-08-18 09:56:35 +00:00
}
2015-08-09 14:48:42 +00:00
});
2015-07-22 00:00:05 +00:00
};
2015-07-29 10:56:01 +00:00
2015-07-28 15:54:29 +00:00
"use strict";
2015-08-09 14:48:42 +00:00
var Chatroom = React.createClass({
displayName: "Chatroom",
getDefaultProps: function getDefaultProps() {
2015-07-28 15:54:29 +00:00
return {
history: []
};
},
2015-08-11 00:37:43 +00:00
2015-08-09 14:48:42 +00:00
componentDidMount: function componentDidMount() {
2015-07-28 15:54:29 +00:00
var self = this;
socket.on("message:new", function (data) {
var history = self.props.history;
history.push(data);
self.setProps({
history: history
});
self.scrollToBottom();
});
// Message History Retrieved
socket.on("message:refresh", function (data) {
self.setProps({
history: data.chatHistory
});
self.scrollToBottom();
});
socket.emit("message:refresh", {});
},
2015-08-09 14:48:42 +00:00
sendMessage: function sendMessage(message) {
socket.emit("newMessage", { message: message });
2015-07-28 15:54:29 +00:00
},
2015-08-11 00:37:43 +00:00
2015-08-09 14:48:42 +00:00
scrollToBottom: function scrollToBottom() {
2015-07-28 15:54:29 +00:00
var node = React.findDOMNode(this.refs.messageContainer);
2015-08-09 14:48:42 +00:00
node.scrollTop = node.scrollHeight;
2015-07-28 15:54:29 +00:00
},
2015-08-11 00:37:43 +00:00
2015-08-09 14:48:42 +00:00
render: function render() {
2015-07-28 15:54:29 +00:00
var messages = this.props.history.map(function (message) {
2015-08-11 00:37:43 +00:00
return React.createElement(ChatMessage, { message: message, key: message.id });
2015-07-28 15:54:29 +00:00
});
2015-08-09 14:48:42 +00:00
return React.createElement(
"div",
2015-08-27 14:14:00 +00:00
{ className: "panel panel-default chatbox" },
2015-08-09 14:48:42 +00:00
React.createElement(
"div",
{ className: "panel-heading" },
"Gather Chat"
),
React.createElement(
"div",
{ className: "panel-body" },
React.createElement(
"ul",
{ className: "chat", id: "chatmessages", ref: "messageContainer" },
messages
2015-07-28 15:54:29 +00:00
)
2015-08-09 14:48:42 +00:00
),
React.createElement(
"div",
{ className: "panel-footer" },
React.createElement(MessageBar, null)
2015-07-28 15:54:29 +00:00
)
);
}
});
2015-07-22 00:00:05 +00:00
2015-07-31 11:23:55 +00:00
var updateMessageCallbacks = [];
var timer = setInterval(function () {
updateMessageCallbacks.forEach(function (callback) {
2015-08-11 00:37:43 +00:00
return callback();
2015-07-31 11:23:55 +00:00
});
}, 60000);
2015-08-09 14:48:42 +00:00
var ChatMessage = React.createClass({
displayName: "ChatMessage",
componentDidMount: function componentDidMount() {
2015-07-28 15:54:29 +00:00
var self = this;
2015-07-31 11:23:55 +00:00
updateMessageCallbacks.push(function () {
self.forceUpdate();
2015-07-28 15:54:29 +00:00
});
},
2015-08-11 00:37:43 +00:00
2015-08-09 14:48:42 +00:00
render: function render() {
return React.createElement(
"li",
{ className: "left clearfix" },
React.createElement(
"span",
{ className: "chat-img pull-left" },
React.createElement("img", {
src: this.props.message.author.avatar,
alt: "User Avatar",
height: "40",
width: "40",
className: "img-circle" })
),
React.createElement(
"div",
{ className: "chat-body clearfix" },
React.createElement(
"div",
{ className: "header" },
React.createElement(
"strong",
{ className: "primary-font" },
this.props.message.author.username
),
React.createElement(
"small",
{ className: "pull-right text-muted" },
React.createElement("i", { className: "fa fa-clock-o fa-fw" }),
" ",
$.timeago(this.props.message.createdAt)
)
),
React.createElement(
"p",
null,
this.props.message.content
2015-07-28 15:54:29 +00:00
)
)
);
}
});
2015-07-22 00:00:05 +00:00
2015-08-09 14:48:42 +00:00
var MessageBar = React.createClass({
displayName: "MessageBar",
sendMessage: function sendMessage(content) {
2015-07-28 15:54:29 +00:00
socket.emit("message:new", {
content: content
});
},
2015-08-11 00:37:43 +00:00
2015-08-09 14:48:42 +00:00
handleSubmit: function handleSubmit(e) {
2015-07-28 15:54:29 +00:00
e.preventDefault();
var content = React.findDOMNode(this.refs.content).value.trim();
if (!content) return;
React.findDOMNode(this.refs.content).value = '';
this.sendMessage(content);
return;
},
2015-08-11 00:37:43 +00:00
2015-08-09 14:48:42 +00:00
render: function render() {
return React.createElement(
"form",
{ onSubmit: this.handleSubmit },
React.createElement(
"div",
{ className: "input-group" },
React.createElement("input", {
id: "btn-input",
type: "text",
className: "form-control",
ref: "content",
placeholder: "Be polite please..." }),
React.createElement(
"span",
{ className: "input-group-btn" },
2015-07-28 15:54:29 +00:00
React.createElement("input", {
2015-08-09 14:48:42 +00:00
type: "submit",
className: "btn btn-primary",
id: "btn-chat",
value: "Send" })
2015-07-28 15:54:29 +00:00
)
)
);
}
});
2015-07-22 00:00:05 +00:00
2015-07-28 15:54:29 +00:00
"use strict";
2015-07-22 00:00:05 +00:00
2015-08-09 14:48:42 +00:00
var UserLogin = React.createClass({
displayName: "UserLogin",
authorizeId: function authorizeId(id) {
2015-07-28 15:54:29 +00:00
socket.emit("users:authorize", {
2015-07-31 11:23:55 +00:00
id: parseInt(id, 10)
2015-07-28 15:54:29 +00:00
});
2015-07-28 23:32:50 +00:00
setTimeout(function () {
socket.emit("gather:refresh");
2015-08-08 19:14:16 +00:00
}, 1000);
2015-07-28 15:54:29 +00:00
},
2015-08-11 00:25:25 +00:00
2015-08-09 14:48:42 +00:00
handleSubmit: function handleSubmit(e) {
2015-07-28 15:54:29 +00:00
e.preventDefault();
var id = React.findDOMNode(this.refs.authorize_id).value.trim();
if (!id) return;
React.findDOMNode(this.refs.authorize_id).value = '';
this.authorizeId(id);
},
2015-08-11 00:25:25 +00:00
2015-08-09 14:48:42 +00:00
render: function render() {
return React.createElement(
"form",
{ onSubmit: this.handleSubmit },
React.createElement(
"div",
{ className: "input-group signin" },
React.createElement("input", {
id: "btn-input",
type: "text",
className: "form-control",
ref: "authorize_id",
2015-08-18 09:56:35 +00:00
placeholder: "Change user" }),
2015-08-09 14:48:42 +00:00
React.createElement(
"span",
{ className: "input-group-btn" },
2015-07-28 15:54:29 +00:00
React.createElement("input", {
2015-08-09 14:48:42 +00:00
type: "submit",
className: "btn btn-primary",
id: "btn-chat",
2015-08-18 09:56:35 +00:00
value: "Assume ID" })
2015-07-28 15:54:29 +00:00
)
)
);
}
2015-08-09 14:48:42 +00:00
});
2015-07-28 15:54:29 +00:00
2015-08-09 14:48:42 +00:00
var UserMenu = React.createClass({
displayName: "UserMenu",
getDefaultProps: function getDefaultProps() {
2015-07-28 15:54:29 +00:00
return {
users: []
};
},
2015-08-11 00:25:25 +00:00
2015-08-09 14:48:42 +00:00
componentDidMount: function componentDidMount() {
2015-07-31 10:49:59 +00:00
var self = this;
socket.on('users:update', function (data) {
2015-08-11 00:25:25 +00:00
return self.setProps({ users: data.users });
2015-07-28 15:54:29 +00:00
});
},
2015-08-11 00:25:25 +00:00
2015-08-09 14:48:42 +00:00
render: function render() {
2015-07-28 15:54:29 +00:00
var users = this.props.users.map(function (user) {
2015-08-09 14:48:42 +00:00
return React.createElement(
"li",
{ key: user.id },
React.createElement(
"a",
{ href: "#" },
user.username
)
2015-07-28 15:54:29 +00:00
);
});
2015-08-09 14:48:42 +00:00
return React.createElement(
"ul",
{ className: "nav", id: "side-menu" },
React.createElement(
"li",
null,
React.createElement(
"a",
{ href: "#" },
React.createElement("i", { className: "fa fa-users fa-fw" }),
" Online",
React.createElement(
"span",
{ className: "badge add-left" },
" ",
this.props.users.length,
" "
2015-07-31 10:49:59 +00:00
)
2015-08-09 14:48:42 +00:00
)
),
2015-08-18 09:56:35 +00:00
users
2015-07-28 15:54:29 +00:00
);
}
});
2015-07-22 14:13:08 +00:00
2015-08-09 14:48:42 +00:00
var AdminPanel = React.createClass({
displayName: "AdminPanel",
handleGatherReset: function handleGatherReset() {
2015-07-29 14:35:58 +00:00
socket.emit("gather:reset");
},
2015-08-11 00:25:25 +00:00
2015-08-09 14:48:42 +00:00
render: function render() {
return React.createElement(
2015-08-18 11:02:27 +00:00
"div",
null,
2015-08-09 14:48:42 +00:00
React.createElement(
2015-08-18 11:02:27 +00:00
"h5",
null,
"Swap Into a Different Account"
),
React.createElement(UserLogin, null),
React.createElement(
"h5",
null,
"Gather Options"
),
React.createElement(
"div",
2015-08-09 14:48:42 +00:00
null,
React.createElement(
2015-08-18 11:02:27 +00:00
"button",
{
className: "btn btn-danger max-width",
onClick: this.handleGatherReset },
"Reset Gather"
2015-07-29 14:35:58 +00:00
)
)
2015-08-09 14:48:42 +00:00
);
2015-07-29 14:35:58 +00:00
}
});
2015-08-09 14:48:42 +00:00
var CurrentUser = React.createClass({
displayName: "CurrentUser",
componentDidMount: function componentDidMount() {
2015-07-28 15:54:29 +00:00
var self = this;
socket.on("users:update", function (data) {
2015-08-11 00:25:25 +00:00
return self.setProps({ user: data.currentUser });
2015-07-28 15:54:29 +00:00
});
2015-07-31 10:51:38 +00:00
socket.emit("users:refresh");
2015-07-28 15:54:29 +00:00
},
2015-08-11 00:25:25 +00:00
2015-08-09 14:48:42 +00:00
render: function render() {
2015-07-28 15:54:29 +00:00
if (this.props.user) {
2015-08-18 11:02:27 +00:00
var adminOptions;
if (this.props.user.admin) {
adminOptions = React.createElement(
"li",
null,
React.createElement(
"a",
{ href: "#", "data-toggle": "modal", "data-target": "#adminmodal" },
"Administration"
)
);
}
2015-08-09 14:48:42 +00:00
return React.createElement(
"li",
{ className: "dropdown" },
React.createElement(
"a",
{ className: "dropdown-toggle", "data-toggle": "dropdown", href: "#" },
this.props.user.username,
"  ",
React.createElement("img", { src: this.props.user.avatar,
alt: "User Avatar",
height: "20",
width: "20" }),
" ",
React.createElement("i", { className: "fa fa-caret-down" })
),
React.createElement(
"ul",
{ className: "dropdown-menu dropdown-user" },
React.createElement(
"li",
null,
React.createElement(
"a",
{ href: "#" },
React.createElement("i", { className: "fa fa-gear fa-fw" }),
" Profile"
)
),
React.createElement(
"li",
null,
React.createElement(
"a",
{ href: "#" },
React.createElement("i", { className: "fa fa-flag fa-fw" }),
" Notifications"
)
),
React.createElement(
"li",
null,
React.createElement(
"a",
{ href: "#" },
React.createElement("i", { className: "fa fa-music fa-fw" }),
" Sounds"
)
),
React.createElement(
"li",
null,
React.createElement(
"a",
{ href: "#", "data-toggle": "modal", "data-target": "#designmodal" },
"Design Goals"
)
2015-08-18 11:02:27 +00:00
),
adminOptions
)
2015-07-28 15:54:29 +00:00
);
} else {
return false;
}
}
2015-08-09 14:48:42 +00:00
});