mirror of
https://github.com/ENSL/ensl_gathers.git
synced 2024-11-26 22:31:08 +00:00
Restructured app
This commit is contained in:
parent
e5ae57d8c0
commit
2eb33f3809
12 changed files with 374 additions and 320 deletions
|
@ -20,7 +20,7 @@ var winston = require("winston");
|
|||
|
||||
module.exports = namespace => {
|
||||
var broadcastUpdate = message => {
|
||||
namespace.emit("message:append", { chatHistory: [message.toJson()]});
|
||||
namespace.emit("message:append", { messages: [message.toJson()]});
|
||||
};
|
||||
|
||||
var refreshMessages = socket => {
|
||||
|
@ -33,7 +33,7 @@ module.exports = namespace => {
|
|||
var receiver = (socket === undefined) ? namespace : socket;
|
||||
|
||||
receiver.emit("message:refresh", {
|
||||
chatHistory: messages
|
||||
messages: messages
|
||||
});
|
||||
});
|
||||
};
|
||||
|
|
|
@ -26,15 +26,27 @@ var _ = require("lodash");
|
|||
var winston = require("winston");
|
||||
|
||||
module.exports = function (namespace) {
|
||||
// var refreshGather = _.debounce(function () {
|
||||
// namespace.sockets.forEach(function (socket) {
|
||||
// socket.emit("gather:refresh", {
|
||||
// gather: Gather.current.toJson(),
|
||||
// currentGatherer: Gather.current.getGatherer(socket._user),
|
||||
// maps: Map.list,
|
||||
// servers: Server.list,
|
||||
// previousGather: Gather.previous ? Gather.previous.toJson() : null
|
||||
// });
|
||||
// });
|
||||
// }, 200, {
|
||||
// leading: true,
|
||||
// trailing: true
|
||||
// });
|
||||
|
||||
var refreshGather = _.debounce(function () {
|
||||
namespace.sockets.forEach(function (socket) {
|
||||
socket.emit("gather:refresh", {
|
||||
gather: Gather.current.toJson(),
|
||||
currentGatherer: Gather.current.getGatherer(socket._user),
|
||||
maps: Map.list,
|
||||
servers: Server.list,
|
||||
previousGather: Gather.previous ? Gather.previous.toJson() : null
|
||||
});
|
||||
namespace.emit("gather:refresh", {
|
||||
gather: Gather.current ? Gather.current.toJson() : null,
|
||||
maps: Map.list,
|
||||
servers: Server.list,
|
||||
previousGather: Gather.previous ? Gather.previous.toJson() : null
|
||||
});
|
||||
}, 200, {
|
||||
leading: true,
|
||||
|
@ -54,6 +66,13 @@ module.exports = function (namespace) {
|
|||
|
||||
Gather.registerCallback('onDone', refreshGather);
|
||||
Gather.registerCallback('onEvent', refreshGather);
|
||||
Gather.registerCallback('onEvent', (event, from, to) => {
|
||||
if (from === 'gathering' && to === 'election') {
|
||||
namespace.emit("notification", {
|
||||
sound: "gather_starting"
|
||||
});
|
||||
}
|
||||
});
|
||||
Gather.onArchiveUpdate(refreshArchive);
|
||||
Gather.restart();
|
||||
|
||||
|
|
|
@ -67,7 +67,7 @@ StateMachine.create({
|
|||
callbacks: {
|
||||
// Callbacks for events
|
||||
onafterevent: function () {
|
||||
this.onEvent.call(this);
|
||||
this.onEvent.apply(this, [].slice.call(arguments));
|
||||
},
|
||||
|
||||
// Gathering State
|
||||
|
@ -155,7 +155,7 @@ StateMachine.create({
|
|||
// On enter done
|
||||
onenterdone: function () {
|
||||
this.done.time = new Date();
|
||||
this.onDone.call(this);
|
||||
this.onDone.apply(this, [].slice.call(arguments));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -12,21 +12,17 @@ gatherCallbacks['onDone'] = [function () {
|
|||
rotateGather();
|
||||
}];
|
||||
|
||||
let executeCallbacks = (context, type) => {
|
||||
let cbs = gatherCallbacks[type];
|
||||
if (!cbs) return;
|
||||
cbs.forEach(function (cb) {
|
||||
cb.call(context);
|
||||
});
|
||||
};
|
||||
|
||||
let newGather = () => {
|
||||
return SingletonClass.current = Gather({
|
||||
onEvent: function () {
|
||||
executeCallbacks(this, 'onEvent')
|
||||
gatherCallbacks['onEvent'].forEach(cb => {
|
||||
cb.apply(this, [].slice.call(arguments))
|
||||
});
|
||||
},
|
||||
onDone: function () {
|
||||
executeCallbacks(this, 'onDone')
|
||||
gatherCallbacks['onDone'].forEach(cb => {
|
||||
cb.apply(this, [].slice.call(arguments))
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
|
@ -17,7 +17,8 @@ var SelectPlayerButton = React.createClass({
|
|||
} else if (this.props.gatherer.team !== "lobby") {
|
||||
button = <button
|
||||
data-disabled="true"
|
||||
className="btn btn-xs btn-default team-label"> {_.capitalize(this.props.gatherer.team)}
|
||||
className="btn btn-xs btn-default team-label">
|
||||
{_.capitalize(this.props.gatherer.team)}
|
||||
</button>;
|
||||
} else {
|
||||
button = <button
|
||||
|
@ -123,17 +124,18 @@ var ElectionProgressBar = React.createClass({
|
|||
|
||||
var ProgressBar = React.createClass({
|
||||
render() {
|
||||
let progress = this.props.progress;
|
||||
var style = {
|
||||
width: Math.round((this.props.progress.num / this.props.progress.den * 100)) + "%"
|
||||
width: Math.round((progress.num / progress.den * 100)) + "%"
|
||||
};
|
||||
var barMessage = this.props.progress.barMessage || "";
|
||||
var barMessage = progress.barMessage || "";
|
||||
return (
|
||||
<div className="progress">
|
||||
<div className="progress-bar progress-bar-striped active"
|
||||
data-role="progressbar"
|
||||
data-aria-valuenow={this.props.progress.num}
|
||||
data-aria-valuenow={progress.num}
|
||||
data-aria-valuemin="0"
|
||||
data-aria-valuemax={this.props.progress.den}
|
||||
data-aria-valuemax={progress.den}
|
||||
style={style}>{barMessage}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -161,7 +163,8 @@ var GatherProgress = React.createClass({
|
|||
var num = this.props.gather.gatherers.length;
|
||||
var den = 12;
|
||||
var remaining = den - num;
|
||||
var message = (remaining === 1) ? "Waiting for last player" : "Waiting for " + remaining + " more players";
|
||||
var message = (remaining === 1) ?
|
||||
"Waiting for last player" : `Waiting for ${remaining} more players`;
|
||||
return {
|
||||
num: num,
|
||||
den: den,
|
||||
|
@ -245,13 +248,16 @@ var TeamSpeakButton = React.createClass({
|
|||
return this.teamSpeakUrl(this.props.alien);
|
||||
},
|
||||
teamSpeakUrl(conn) {
|
||||
let params = `channel=${encodeURIComponent(conn.channel)}&channelpassword=${encodeURIComponent(conn.password)}`;
|
||||
let params = `channel=${encodeURIComponent(conn.channel)}&
|
||||
channelpassword=${encodeURIComponent(conn.password)}`;
|
||||
return (`${this.props.url}?${params}`);
|
||||
},
|
||||
render() {
|
||||
return (
|
||||
<div className="btn-group dropup">
|
||||
<button type="button" className="btn btn-primary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<button type="button"
|
||||
className="btn btn-primary dropdown-toggle"
|
||||
data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
Teamspeak <span className="caret"></span>
|
||||
</button>
|
||||
<ul className="dropdown-menu">
|
||||
|
@ -259,13 +265,17 @@ var TeamSpeakButton = React.createClass({
|
|||
<li><a href={this.marineUrl()}>Join Marine Teamspeak</a></li>
|
||||
<li><a href={this.alienUrl()}>Join Alien Teamspeak</a></li>
|
||||
<li role="separator" className="divider"></li>
|
||||
<li><a href="#" data-toggle="modal" data-target="#teamspeakmodal">Teamspeak Details</a></li>
|
||||
<li><a href="#" data-toggle="modal" data-target="#teamspeakmodal">
|
||||
Teamspeak Details</a></li>
|
||||
</ul>
|
||||
<div className="modal fade text-left" id="teamspeakmodal">
|
||||
<div className="modal-dialog">
|
||||
<div className="modal-content">
|
||||
<div className="modal-header">
|
||||
<button type="button" className="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||
<button type="button"
|
||||
className="close"
|
||||
data-dismiss="modal"
|
||||
aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||
<h4 className="modal-title">Teamspeak Server Information</h4>
|
||||
</div>
|
||||
<div className="modal-body">
|
||||
|
@ -320,13 +330,14 @@ var JoinGatherButton = React.createClass({
|
|||
},
|
||||
|
||||
render() {
|
||||
let currentGatherer = this.props.currentGatherer;
|
||||
if (currentGatherer) {
|
||||
let gather = this.props.gather;
|
||||
let thisGatherer = this.props.thisGatherer;
|
||||
if (thisGatherer) {
|
||||
return <button
|
||||
onClick={this.leaveGather}
|
||||
className="btn btn-danger">Leave Gather</button>;
|
||||
}
|
||||
if (this.props.gather.state === 'gathering') {
|
||||
if (gather.state === 'gathering') {
|
||||
let cooldownTime = this.cooldownTime();
|
||||
if (cooldownTime) {
|
||||
return <CooloffButton timeRemaining={cooldownTime} />;
|
||||
|
@ -363,8 +374,9 @@ var GatherActions = React.createClass({
|
|||
},
|
||||
|
||||
regatherVotes() {
|
||||
if (!this.props.gather) return 0;
|
||||
return this.props.gather.gatherers.reduce((acc, gatherer) => {
|
||||
let gather = this.props.gather;
|
||||
if (!gather) return 0;
|
||||
return gather.gatherers.reduce((acc, gatherer) => {
|
||||
if (gatherer.regatherVote) acc++;
|
||||
return acc;
|
||||
}, 0);
|
||||
|
@ -372,21 +384,21 @@ var GatherActions = React.createClass({
|
|||
|
||||
render() {
|
||||
let regatherButton;
|
||||
let currentGatherer = this.props.currentGatherer;
|
||||
if (currentGatherer) {
|
||||
let user = this.props.user;
|
||||
let gather = this.props.gather;
|
||||
let thisGatherer = this.props.thisGatherer;
|
||||
if (thisGatherer) {
|
||||
let regatherVotes = this.regatherVotes();
|
||||
if (currentGatherer.regatherVote) {
|
||||
regatherButton = (
|
||||
<button
|
||||
value="false"
|
||||
onClick={this.voteRegather}
|
||||
className="btn btn-danger">{`Voted Regather (${regatherVotes}/8)`}</button>);
|
||||
if (thisGatherer.regatherVote) {
|
||||
regatherButton = <button value="false" onClick={this.voteRegather}
|
||||
className="btn btn-danger">
|
||||
{`Voted Regather (${regatherVotes}/8)`}
|
||||
</button>;
|
||||
} else {
|
||||
regatherButton = (
|
||||
<button
|
||||
value="true"
|
||||
onClick={this.voteRegather}
|
||||
className="btn btn-danger">{`Vote Regather (${regatherVotes}/8)`}</button>);
|
||||
regatherButton = <button value="true" onClick={this.voteRegather}
|
||||
className="btn btn-danger">
|
||||
{`Vote Regather (${regatherVotes}/8)`}
|
||||
</button>;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -400,10 +412,8 @@ var GatherActions = React.createClass({
|
|||
{regatherButton}
|
||||
</li>
|
||||
<li>
|
||||
<JoinGatherButton
|
||||
gather={this.props.gather}
|
||||
currentGatherer={this.props.currentGatherer}
|
||||
user={this.props.user} />
|
||||
<JoinGatherButton gather={gather} thisGatherer={thisGatherer}
|
||||
user={user} />
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
@ -432,10 +442,12 @@ var VoteButton = React.createClass({
|
|||
},
|
||||
|
||||
render() {
|
||||
if (this.props.currentGatherer === null) {
|
||||
let candidate = this.props.candidate;
|
||||
let thisGatherer = this.props.thisGatherer;
|
||||
if (thisGatherer === null) {
|
||||
return false;
|
||||
}
|
||||
if (this.props.currentGatherer.leaderVote === this.props.candidate.id) {
|
||||
if (thisGatherer.leaderVote === candidate.id) {
|
||||
return (
|
||||
<button
|
||||
onClick={this.cancelVote}
|
||||
|
@ -447,7 +459,7 @@ var VoteButton = React.createClass({
|
|||
<button
|
||||
onClick={this.vote}
|
||||
className="btn btn-xs btn-primary vote-button"
|
||||
value={this.props.candidate.id}>Vote
|
||||
value={candidate.id}>Vote
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
@ -474,23 +486,22 @@ var ServerVoting = React.createClass({
|
|||
},
|
||||
|
||||
render() {
|
||||
var self = this;
|
||||
let servers = self.props.servers
|
||||
.sort((a, b) => {
|
||||
var aVotes = self.votesForServer(a);
|
||||
var bVotes = self.votesForServer(b);
|
||||
return bVotes - aVotes;
|
||||
})
|
||||
.map(server => {
|
||||
let self = this;
|
||||
let thisGatherer = self.props.thisGatherer;
|
||||
let servers = self.props.servers.sort((a, b) => {
|
||||
var aVotes = self.votesForServer(a);
|
||||
var bVotes = self.votesForServer(b);
|
||||
return bVotes - aVotes;
|
||||
}).map(server => {
|
||||
let votes = self.votesForServer(server);
|
||||
if (self.props.currentGatherer.serverVote === server.id) {
|
||||
if (thisGatherer.serverVote === server.id) {
|
||||
return (
|
||||
<a href="#"
|
||||
className="list-group-item list-group-item-success"
|
||||
onClick={ e => e.preventDefault() }
|
||||
key={server.id}>
|
||||
<span className="badge">{votes}</span>
|
||||
{server.name || server.description || server.dns}
|
||||
{server.name || server.description}
|
||||
</a>
|
||||
);
|
||||
} else {
|
||||
|
@ -499,13 +510,13 @@ var ServerVoting = React.createClass({
|
|||
onClick={self.voteHandler(server.id)}
|
||||
key={server.id}>
|
||||
<span className="badge">{votes}</span>
|
||||
{server.name || server.description || server.dns}
|
||||
{server.name || server.description}
|
||||
</a>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
let voted = self.props.currentGatherer.serverVote !== null;
|
||||
let voted = thisGatherer.serverVote !== null;
|
||||
|
||||
return (
|
||||
<div className="panel panel-primary">
|
||||
|
@ -541,38 +552,37 @@ var MapVoting = React.createClass({
|
|||
|
||||
render() {
|
||||
var self = this;
|
||||
let maps = self.props.maps
|
||||
.sort((a, b) => {
|
||||
var aVotes = self.votesForMap(a);
|
||||
var bVotes = self.votesForMap(b);
|
||||
return bVotes - aVotes;
|
||||
})
|
||||
.map(map => {
|
||||
let votes = self.votesForMap(map);
|
||||
if (self.props.currentGatherer.mapVote === map.id) {
|
||||
return (
|
||||
<a href="#"
|
||||
key={map.id}
|
||||
onClick={ e => e.preventDefault() }
|
||||
className="list-group-item list-group-item-success">
|
||||
<span className="badge">{votes}</span>
|
||||
{map.name}
|
||||
</a>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<a href="#"
|
||||
key={map.id}
|
||||
onClick={self.voteHandler(map.id)}
|
||||
className="list-group-item">
|
||||
<span className="badge">{votes}</span>
|
||||
{map.name}
|
||||
</a>
|
||||
);
|
||||
}
|
||||
});
|
||||
let thisGatherer = self.props.thisGatherer
|
||||
let maps = self.props.maps.sort((a, b) => {
|
||||
var aVotes = self.votesForMap(a);
|
||||
var bVotes = self.votesForMap(b);
|
||||
return bVotes - aVotes;
|
||||
}).map(map => {
|
||||
let votes = self.votesForMap(map);
|
||||
if (thisGatherer.mapVote === map.id) {
|
||||
return (
|
||||
<a href="#"
|
||||
key={map.id}
|
||||
onClick={ e => e.preventDefault() }
|
||||
className="list-group-item list-group-item-success">
|
||||
<span className="badge">{votes}</span>
|
||||
{map.name}
|
||||
</a>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<a href="#"
|
||||
key={map.id}
|
||||
onClick={self.voteHandler(map.id)}
|
||||
className="list-group-item">
|
||||
<span className="badge">{votes}</span>
|
||||
{map.name}
|
||||
</a>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
let voted = (self.props.currentGatherer.mapVote !== null);
|
||||
let voted = (thisGatherer.mapVote !== null);
|
||||
|
||||
return (
|
||||
<div className="panel panel-primary">
|
||||
|
@ -590,64 +600,78 @@ var MapVoting = React.createClass({
|
|||
var Gather = React.createClass({
|
||||
getDefaultProps() {
|
||||
return {
|
||||
gather: {
|
||||
gatherers: []
|
||||
}
|
||||
gather: null,
|
||||
user: null
|
||||
}
|
||||
},
|
||||
|
||||
checkForStateChange: function (data) {
|
||||
let previousState = this.props.gather.state;
|
||||
let newState = data.gather.state;
|
||||
if (newState === previousState) return;
|
||||
// checkForStateChange: function (data) {
|
||||
// let previousState = this.props.gather.state;
|
||||
// let newState = data.gather.state;
|
||||
// if (newState === previousState) return;
|
||||
|
||||
// Callbacks for new states
|
||||
if (newState === "election"
|
||||
&& previousState === "gathering"
|
||||
&& data.currentGatherer) {
|
||||
soundController.playGatherMusic();
|
||||
// // Callbacks for new states
|
||||
// if (newState === "election"
|
||||
// && previousState === "gathering"
|
||||
// && data.currentGatherer) {
|
||||
// soundController.playGatherMusic();
|
||||
// }
|
||||
// },
|
||||
|
||||
thisGatherer() {
|
||||
let gather = this.props.gather;
|
||||
let user = this.props.user;
|
||||
if (gather && user && gather.gatherers.length) {
|
||||
return gather.gatherers
|
||||
.filter(gatherer => gatherer.id === user.id)
|
||||
.pop() || null;
|
||||
}
|
||||
},
|
||||
|
||||
componentDidMount() {
|
||||
var self = this;
|
||||
socket.on("users:update", data => self.setProps({user: data.currentUser}));
|
||||
socket.on("gather:refresh", (data) => {
|
||||
self.checkForStateChange(data);
|
||||
self.setProps(data)
|
||||
});
|
||||
return null;
|
||||
},
|
||||
|
||||
render() {
|
||||
if (this.props.gather.state === 'done') {
|
||||
return (<CompletedGather show={true} {...this.props} />);
|
||||
let gather = this.props.gather;
|
||||
let thisGatherer = this.thisGatherer();
|
||||
let servers = this.props.servers;
|
||||
let maps = this.props.maps;
|
||||
let user = this.props.user;
|
||||
|
||||
if (gather === null) return;
|
||||
|
||||
if (gather.state === 'done') {
|
||||
return <CompletedGather maps={maps} servers={servers} show={true}
|
||||
gather={this.props.previousGather} />;
|
||||
}
|
||||
|
||||
var voting;
|
||||
if (this.props.currentGatherer) {
|
||||
let state = this.props.gather.state;
|
||||
let voting;
|
||||
if (thisGatherer) {
|
||||
let state = gather.state;
|
||||
if (state === 'gathering' || state === 'election') {
|
||||
voting = (
|
||||
<div className="row add-top">
|
||||
<div className="col-sm-6">
|
||||
<MapVoting {...this.props} />
|
||||
<MapVoting gather={gather} maps={maps}
|
||||
thisGatherer={thisGatherer} />
|
||||
</div>
|
||||
<div className="col-sm-6">
|
||||
<ServerVoting {...this.props} />
|
||||
<ServerVoting gather={gather} servers={servers}
|
||||
thisGatherer={thisGatherer} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
voting = <GatherVotingResults gather={this.props.gather} servers={this.props.servers} maps={this.props.maps} />;
|
||||
voting = <GatherVotingResults gather={gather}
|
||||
servers={servers}
|
||||
maps={maps} />;
|
||||
}
|
||||
}
|
||||
|
||||
var gatherTeams;
|
||||
if (this.props.gather.state === 'selection') {
|
||||
gatherTeams = <GatherTeams gather={this.props.gather} />
|
||||
let gatherTeams;
|
||||
if (gather.state === 'selection') {
|
||||
gatherTeams = <GatherTeams gather={gather} />;
|
||||
}
|
||||
|
||||
var previousGather;
|
||||
let previousGather;
|
||||
if (this.props.previousGather) {
|
||||
previousGather = (
|
||||
<div className="panel panel-primary">
|
||||
|
@ -655,9 +679,8 @@ var Gather = React.createClass({
|
|||
Previous Gather
|
||||
</div>
|
||||
<div className="panel-body">
|
||||
<CompletedGather {...this.props}
|
||||
gather={this.props.previousGather}
|
||||
show={true} />
|
||||
<CompletedGather maps={maps} servers={servers} show={true}
|
||||
gather={this.props.previousGather} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
@ -667,13 +690,13 @@ var Gather = React.createClass({
|
|||
<div className="panel panel-primary add-bottom">
|
||||
<div className="panel-heading">Current Gather</div>
|
||||
<div className="panel-body">
|
||||
<GatherProgress {...this.props} />
|
||||
<GatherProgress gather={gather} />
|
||||
</div>
|
||||
</div>
|
||||
<Gatherers {...this.props} />
|
||||
<Gatherers gather={gather} user={user} thisGatherer={thisGatherer} />
|
||||
{gatherTeams}
|
||||
{voting}
|
||||
<GatherActions {...this.props} />
|
||||
<GatherActions gather={gather} user={user} thisGatherer={thisGatherer} />
|
||||
{previousGather}
|
||||
</div>
|
||||
);
|
||||
|
@ -688,8 +711,9 @@ var LifeformIcons = React.createClass({
|
|||
gathererLifeforms() {
|
||||
let lifeforms = [];
|
||||
let gatherer = this.props.gatherer;
|
||||
for (let attr in gatherer.user.profile.abilities) {
|
||||
if (gatherer.user.profile.abilities[attr]) lifeforms.push(_.capitalize(attr));
|
||||
let abilities = gatherer.user.profile.abilities;
|
||||
for (let attr in abilities) {
|
||||
if (abilities[attr]) lifeforms.push(_.capitalize(attr));
|
||||
}
|
||||
return lifeforms;
|
||||
},
|
||||
|
@ -732,18 +756,22 @@ var Gatherers = React.createClass({
|
|||
},
|
||||
|
||||
render() {
|
||||
var self = this;
|
||||
var user = this.props.user;
|
||||
var admin = (user && user.admin);
|
||||
var gatherers = this.props.gather.gatherers
|
||||
let self = this;
|
||||
let user = this.props.user;
|
||||
let gather = this.props.gather;
|
||||
let admin = (user && user.admin);
|
||||
let thisGatherer = this.props.thisGatherer;
|
||||
let gatherers = gather.gatherers
|
||||
.sort((a, b) => {
|
||||
return (b.user.hive.skill || 1000) - (a.user.hive.skill || 1000);
|
||||
})
|
||||
.map(gatherer => {
|
||||
if (gatherer.user.country) {
|
||||
var country = (<img src="images/blank.gif"
|
||||
className={"flag flag-" + gatherer.user.country.toLowerCase()}
|
||||
alt={gatherer.user.country} />);
|
||||
var country = (
|
||||
<img src="images/blank.gif"
|
||||
className={"flag flag-" + gatherer.user.country.toLowerCase()}
|
||||
alt={gatherer.user.country} />
|
||||
);
|
||||
};
|
||||
|
||||
let skill = gatherer.user.profile.skill || "Not Available";
|
||||
|
@ -760,23 +788,25 @@ var Gatherers = React.createClass({
|
|||
let team = (gatherer.user.team) ? gatherer.user.team.name : "None";
|
||||
|
||||
let action;
|
||||
if (self.props.gather.state === "election") {
|
||||
var votes = self.props.gather.gatherers.reduce((acc, voter) => {
|
||||
if (gather.state === "election") {
|
||||
let votes = gather.gatherers.reduce((acc, voter) => {
|
||||
if (voter.leaderVote === gatherer.id) acc++;
|
||||
return acc;
|
||||
}, 0)
|
||||
action = (
|
||||
<span>
|
||||
<span className="badge add-right">{votes + " votes"}</span>
|
||||
<VoteButton currentGatherer={self.props.currentGatherer} candidate={gatherer} />
|
||||
<VoteButton
|
||||
thisGatherer={thisGatherer}
|
||||
candidate={gatherer} />
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
if (self.props.gather.state === 'selection') {
|
||||
if (self.props.currentGatherer &&
|
||||
self.props.currentGatherer.leader &&
|
||||
self.props.currentGatherer.team === self.props.gather.pickingTurn) {
|
||||
if (gather.state === 'selection') {
|
||||
if (thisGatherer &&
|
||||
thisGatherer.leader &&
|
||||
thisGatherer.team === gather.pickingTurn) {
|
||||
action = (
|
||||
<span>
|
||||
<SelectPlayerButton gatherer={gatherer} />
|
||||
|
@ -784,16 +814,21 @@ var Gatherers = React.createClass({
|
|||
);
|
||||
} else {
|
||||
if (gatherer.leader) {
|
||||
action = (<span className={`label label-padding label-${gatherer.team} team-label`}>Leader</span>);
|
||||
action = (<span className={`label label-padding
|
||||
label-${gatherer.team}
|
||||
team-label`}>Leader</span>);
|
||||
} else if (gatherer.team !== "lobby") {
|
||||
action = (<span className={`label label-padding label-${gatherer.team} team-label`}>{_.capitalize(gatherer.team)}</span>);
|
||||
action = (<span className={`label label-padding
|
||||
label-${gatherer.team}
|
||||
team-label`}>{_.capitalize(gatherer.team)}</span>);
|
||||
} else {
|
||||
action = (<span className="label label-padding label-default team-label">Lobby</span>);
|
||||
action = (<span className="label label-padding label-default team-label">
|
||||
Lobby</span>);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var adminOptions;
|
||||
let adminOptions;
|
||||
if (admin) {
|
||||
adminOptions = [
|
||||
<dt>Admin</dt>,
|
||||
|
@ -806,14 +841,15 @@ var Gatherers = React.createClass({
|
|||
</button>
|
||||
<AssumeUserIdButton
|
||||
gatherer={gatherer}
|
||||
currentUser={this.props.user} />
|
||||
currentUser={user} />
|
||||
</dd>
|
||||
]
|
||||
}
|
||||
|
||||
let tabColor = gatherer.team !== "lobby" ? `panel-${gatherer.team}` : "panel-info";
|
||||
return (
|
||||
<div className={`panel ${tabColor} gatherer-panel`} key={gatherer.user.id} data-userid={gatherer.user.id}>
|
||||
<div className={`panel ${tabColor} gatherer-panel`}
|
||||
key={gatherer.user.id} data-userid={gatherer.user.id}>
|
||||
<div className="panel-heading">
|
||||
<h4 className="panel-title">
|
||||
{country} {gatherer.user.username}
|
||||
|
@ -846,9 +882,12 @@ var Gatherers = React.createClass({
|
|||
</div>
|
||||
);
|
||||
})
|
||||
if (this.props.gather.gatherers.length) {
|
||||
if (gather.gatherers.length) {
|
||||
return (
|
||||
<div class="panel-group" role="tablist" aria-multiselectable="true" id="gatherers-panel">
|
||||
<div class="panel-group"
|
||||
role="tablist"
|
||||
aria-multiselectable="true"
|
||||
id="gatherers-panel">
|
||||
{gatherers}
|
||||
</div>
|
||||
);
|
||||
|
@ -887,11 +926,14 @@ var CompletedGather = React.createClass({
|
|||
|
||||
render() {
|
||||
let gatherInfo = [];
|
||||
let gather = this.props.gather;
|
||||
let maps = this.props.maps;
|
||||
let servers = this.props.servers;
|
||||
if (this.state.show) {
|
||||
gatherInfo.push(<GatherTeams gather={this.props.gather} />);
|
||||
gatherInfo.push(<GatherVotingResults gather={this.props.gather}
|
||||
maps={this.props.maps}
|
||||
servers={this.props.servers}/>);
|
||||
gatherInfo.push(<GatherTeams gather={gather} />);
|
||||
gatherInfo.push(<GatherVotingResults gather={gather}
|
||||
maps={maps}
|
||||
servers={servers}/>);
|
||||
}
|
||||
return (
|
||||
<div>
|
||||
|
@ -947,7 +989,8 @@ var GatherVotingResults = React.createClass({
|
|||
{password}
|
||||
</dl>
|
||||
<p>
|
||||
<a href={["steam://connect", server.ip +":"+server.port, server.password].join("/")}
|
||||
<a href={`steam://connect/${server.ip}:${server.port}/
|
||||
${server.password}`}
|
||||
className="btn btn-primary max-width">Join Server</a>
|
||||
</p>
|
||||
</div>
|
||||
|
@ -957,25 +1000,6 @@ var GatherVotingResults = React.createClass({
|
|||
});
|
||||
|
||||
var ArchivedGathers = React.createClass({
|
||||
componentDidMount() {
|
||||
let self = this;
|
||||
socket.on("gather:archive:refresh", data => {
|
||||
self.setProps({
|
||||
archive: data.archive,
|
||||
maps: data.maps,
|
||||
servers: data.servers
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
getDefaultProps() {
|
||||
return {
|
||||
archive: [],
|
||||
maps: [],
|
||||
servers: []
|
||||
}
|
||||
},
|
||||
|
||||
render() {
|
||||
let archive = this.props.archive
|
||||
.sort((a, b) => {
|
||||
|
@ -983,6 +1007,7 @@ var ArchivedGathers = React.createClass({
|
|||
})
|
||||
.map(archivedGather => {
|
||||
return <CompletedGather
|
||||
id={archivedGather.gather.done.time}
|
||||
show={false}
|
||||
gather={archivedGather.gather}
|
||||
maps={this.props.maps}
|
||||
|
@ -999,5 +1024,3 @@ var ArchivedGathers = React.createClass({
|
|||
);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
"use strict";
|
||||
|
||||
var socket;
|
||||
var soundController;
|
||||
var socket, soundController;
|
||||
|
||||
var initialiseVisibilityMonitoring = (socket) => {
|
||||
let hidden, visibilityChange;
|
||||
|
@ -28,29 +27,11 @@ var initialiseVisibilityMonitoring = (socket) => {
|
|||
}, false);
|
||||
}
|
||||
|
||||
var removeAuthWidget = () => {
|
||||
$("#authenticating").remove();
|
||||
};
|
||||
var removeAuthWidget = () => $("#authenticating").remove();
|
||||
|
||||
var showAuthenticationNotice = () => {
|
||||
$("#auth-required").show();
|
||||
};
|
||||
var showAuthenticationNotice = () => $("#auth-required").show();
|
||||
|
||||
var showGatherBanNotice = () => {
|
||||
$("#gather-banned").show();
|
||||
};
|
||||
|
||||
var renderPage = (socket) => {
|
||||
// initialiseVisibilityMonitoring(socket);
|
||||
soundController = new SoundController();
|
||||
// React.render(<UserMenu />, document.getElementById('side-menu'));
|
||||
// React.render(<Chatroom />, document.getElementById('chatroom'));
|
||||
// React.render(<Gather />, document.getElementById('gathers'));
|
||||
// React.render(<CurrentUser />, document.getElementById('currentuser'));
|
||||
// React.render(<SoundPanel />, document.getElementById('soundcontroller'));
|
||||
// React.render(<ArchivedGathers />, document.getElementById('archived-gathers'));
|
||||
React.render(<App />, document.getElementById("body_content"));
|
||||
};
|
||||
var showGatherBanNotice = () => $("#gather-banned").show();
|
||||
|
||||
var initialiseComponents = () => {
|
||||
let socketUrl = window.location.protocol + "//" + window.location.host;
|
||||
|
@ -58,12 +39,16 @@ var initialiseComponents = () => {
|
|||
.on("connect", () => {
|
||||
console.log("Connected");
|
||||
removeAuthWidget();
|
||||
renderPage(socket);
|
||||
soundController = new SoundController({
|
||||
socket: socket
|
||||
});
|
||||
React.render(<App socket={socket} soundController={soundController}/>,
|
||||
document.getElementById("body_content"));
|
||||
socket.on("reconnect", () => {
|
||||
console.log("Reconnected");
|
||||
socket.emit("message:refresh");
|
||||
socket.emit("gather:refresh");
|
||||
socket.emit("users:refresh");
|
||||
console.log("Reconnected");
|
||||
})
|
||||
.on("disconnect", () => {
|
||||
console.log("Disconnected")
|
||||
|
|
|
@ -7,33 +7,54 @@ var App = React.createClass({
|
|||
gatherers: []
|
||||
},
|
||||
users: [],
|
||||
messages: []
|
||||
messages: [],
|
||||
maps: [],
|
||||
servers: [],
|
||||
archive: [],
|
||||
soundController: null
|
||||
}
|
||||
},
|
||||
|
||||
componentDidMount() {
|
||||
let self = this;
|
||||
|
||||
socket.on("users:update",
|
||||
data => self.setProps({user: data.currentUser}));
|
||||
let socket = this.props.socket;
|
||||
|
||||
socket.on('users:update',
|
||||
data => self.setProps({users: data.users}));
|
||||
data => self.setProps({
|
||||
users: data.users,
|
||||
user: data.currentUser
|
||||
})
|
||||
);
|
||||
|
||||
socket.on("message:append", data => {
|
||||
self.setProps({
|
||||
messages: self.props.messages
|
||||
.concat(data.chatHistory)
|
||||
messages: self.props.messages.concat(data.messages)
|
||||
.sort((a, b) => {
|
||||
return new Date(a.createdAt) - new Date(b.createdAt);
|
||||
})
|
||||
});
|
||||
});
|
||||
|
||||
// Message History Retrieved
|
||||
socket.on("message:refresh", data => {
|
||||
self.setProps({
|
||||
messages: data.chatHistory
|
||||
messages: data.messages
|
||||
});
|
||||
});
|
||||
|
||||
socket.on("gather:refresh", (data) => {
|
||||
self.setProps({
|
||||
gather: data.gather,
|
||||
maps: data.maps,
|
||||
servers: data.servers,
|
||||
previousGather: data.previousGather
|
||||
});
|
||||
});
|
||||
|
||||
socket.on("gather:archive:refresh", data => {
|
||||
self.setProps({
|
||||
archive: data.archive,
|
||||
maps: data.maps,
|
||||
servers: data.servers
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -53,7 +74,7 @@ var App = React.createClass({
|
|||
<CurrentUser user={this.props.user} />
|
||||
</ul>
|
||||
<ul className="nav navbar-top-links navbar-right" id="soundcontroller">
|
||||
{/*<SoundPanel />*/}
|
||||
<SoundPanel soundController={this.props.soundController} />
|
||||
</ul>
|
||||
<ul className="nav navbar-top-links navbar-right">
|
||||
<li className="dropdown">
|
||||
|
@ -96,10 +117,17 @@ var App = React.createClass({
|
|||
user={this.props.user} />
|
||||
</div>
|
||||
<div className="col-md-6" id="gathers">
|
||||
{/*<Gather />*/}
|
||||
<Gather
|
||||
gather={this.props.gather}
|
||||
user={this.props.user}
|
||||
maps={this.props.maps}
|
||||
servers={this.props.servers}
|
||||
previousGather={this.props.previousGather}/>
|
||||
</div>
|
||||
<div className="col-md-6 col-md-offset-6" id="archived-gathers">
|
||||
{/*<ArchivedGathers />*/}
|
||||
<ArchivedGathers archive={this.props.archive}
|
||||
maps={this.props.maps}
|
||||
servers={this.props.servers} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,98 +1,16 @@
|
|||
"use strict";
|
||||
|
||||
class SoundController {
|
||||
constructor () {
|
||||
if (Howl === undefined) {
|
||||
throw new Error("Howl.js required to created sound controller");
|
||||
}
|
||||
this.minPlayInterval = 180000; // 5 minutes
|
||||
this.isMuted = Howler._muted;
|
||||
this.volume = Howler._volume;
|
||||
this.tunes = {
|
||||
"classic": {
|
||||
description: "Classic",
|
||||
url: 'http://www.ensl.org/sounds/gather-1.mp3'
|
||||
},
|
||||
"eyeofthegorgie": {
|
||||
description: "Eye of the Gorgie",
|
||||
url: 'http://www.ensl.org/files/audio/eyeofthegorgie.mp3'
|
||||
}
|
||||
}
|
||||
this.setupGatherMusic("classic");
|
||||
}
|
||||
|
||||
volume(val) {
|
||||
if (typeof val === 'number' && Math.abs(val) <= 1) {
|
||||
this.volume = val;
|
||||
return Howler.volume(val)
|
||||
}
|
||||
}
|
||||
|
||||
mute() {
|
||||
this.isMuted = true;
|
||||
return Howler.mute();
|
||||
}
|
||||
|
||||
unMute() {
|
||||
this.isMuted = false;
|
||||
return Howler.unmute();
|
||||
}
|
||||
|
||||
play(music) {
|
||||
if (this.gather && this.gather.music) return this.gather.music.play();
|
||||
}
|
||||
|
||||
stop(music) {
|
||||
if (this.gather && this.gather.music) return this.gather.music.stop();
|
||||
}
|
||||
|
||||
setupGatherMusic (musicName) {
|
||||
let self = this;
|
||||
let gatherMusic = this.tunes[musicName];
|
||||
|
||||
if (!gatherMusic) return;
|
||||
if (self.gather && self.gather.name === musicName) return;
|
||||
|
||||
// Stop if already playing
|
||||
if (self.gather && self.gather.music) {
|
||||
self.gather.music.stop();
|
||||
}
|
||||
|
||||
let tune = self.tunes[musicName];
|
||||
self.gather = {
|
||||
name: musicName,
|
||||
description: tune.description,
|
||||
url: tune.url,
|
||||
music: new Howl({
|
||||
urls: [tune.url]
|
||||
}),
|
||||
playable: true
|
||||
};
|
||||
}
|
||||
|
||||
playGatherMusic () {
|
||||
var self = this;
|
||||
if (!self.gather.playable) return;
|
||||
self.gather.music.play();
|
||||
self.gather.playable = false;
|
||||
setTimeout(function () {
|
||||
self.gather.playable = true;
|
||||
}, self.minPlayInterval);
|
||||
}
|
||||
}
|
||||
|
||||
var SoundPanel = React.createClass({
|
||||
mute() {
|
||||
soundController.mute();
|
||||
this.props.soundController.mute();
|
||||
this.forceUpdate();
|
||||
},
|
||||
|
||||
unMute() {
|
||||
soundController.unMute();
|
||||
this.props.soundController.unMute();
|
||||
this.forceUpdate();
|
||||
},
|
||||
|
||||
render() {
|
||||
let soundController = this.props.soundController;
|
||||
if (soundController.isMuted) {
|
||||
return (
|
||||
<li>
|
||||
|
@ -111,4 +29,4 @@ var SoundPanel = React.createClass({
|
|||
);
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
|
|
|
@ -5,9 +5,6 @@ var UserLogin = React.createClass({
|
|||
socket.emit("users:authorize", {
|
||||
id: parseInt(id, 10)
|
||||
});
|
||||
setTimeout(function () {
|
||||
socket.emit("gather:refresh");
|
||||
}, 1000);
|
||||
},
|
||||
|
||||
handleSubmit(e) {
|
||||
|
@ -250,5 +247,3 @@ var AssumeUserIdButton = React.createClass({
|
|||
}
|
||||
}
|
||||
});
|
||||
|
||||
$(function () { initialiseComponents(); });
|
|
@ -1,7 +1,5 @@
|
|||
"use strict";
|
||||
|
||||
// Helper Methods
|
||||
|
||||
var rankVotes = function (votes, candidates) {
|
||||
var initial = candidates.reduce(function (acc, candidate) {
|
||||
acc[candidate.id] = 0;
|
||||
|
@ -37,3 +35,90 @@ var rankVotes = function (votes, candidates) {
|
|||
});
|
||||
});
|
||||
};
|
||||
|
||||
class SoundController {
|
||||
constructor (options) {
|
||||
if (Howl === undefined) {
|
||||
throw new Error("Howl.js required to created sound controller");
|
||||
}
|
||||
|
||||
this.MINIMUM_PLAY_INTERVAL = 120000;
|
||||
|
||||
this.playGatherMusic = _.throttle(() => {
|
||||
this.gather.music.play();
|
||||
}, this.MINIMUM_PLAY_INTERVAL);
|
||||
|
||||
if (options && options.socket) {
|
||||
socket.on("notification", data => {
|
||||
if (data && data.sound === "gather_starting") {
|
||||
this.playGatherMusic();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
this.isMuted = Howler._muted;
|
||||
|
||||
this.volume = Howler._volume;
|
||||
|
||||
this.tunes = {
|
||||
"classic": {
|
||||
description: "Classic",
|
||||
url: 'http://www.ensl.org/sounds/gather-1.mp3'
|
||||
},
|
||||
"eyeofthegorgie": {
|
||||
description: "Eye of the Gorgie",
|
||||
url: 'http://www.ensl.org/files/audio/eyeofthegorgie.mp3'
|
||||
}
|
||||
}
|
||||
|
||||
this.setupGatherMusic("classic");
|
||||
}
|
||||
|
||||
volume(val) {
|
||||
if (typeof val === 'number' && Math.abs(val) <= 1) {
|
||||
this.volume = val;
|
||||
return Howler.volume(val)
|
||||
}
|
||||
}
|
||||
|
||||
mute() {
|
||||
this.isMuted = true;
|
||||
return Howler.mute();
|
||||
}
|
||||
|
||||
unMute() {
|
||||
this.isMuted = false;
|
||||
return Howler.unmute();
|
||||
}
|
||||
|
||||
play(music) {
|
||||
if (this.gather && this.gather.music) return this.gather.music.play();
|
||||
}
|
||||
|
||||
stop(music) {
|
||||
if (this.gather && this.gather.music) return this.gather.music.stop();
|
||||
}
|
||||
|
||||
setupGatherMusic (musicName) {
|
||||
let self = this;
|
||||
let gatherMusic = this.tunes[musicName];
|
||||
|
||||
if (!gatherMusic) return;
|
||||
if (self.gather && self.gather.name === musicName) return;
|
||||
|
||||
// Stop if already playing
|
||||
if (self.gather && self.gather.music) {
|
||||
self.gather.music.stop();
|
||||
}
|
||||
|
||||
let tune = self.tunes[musicName];
|
||||
self.gather = {
|
||||
name: musicName,
|
||||
description: tune.description,
|
||||
url: tune.url,
|
||||
music: new Howl({
|
||||
urls: [tune.url]
|
||||
})
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1 +1,5 @@
|
|||
<script src="/js/app.js"></script>
|
||||
<script>
|
||||
$(function () {
|
||||
initialiseComponents();
|
||||
})
|
||||
</script>
|
|
@ -23,4 +23,5 @@
|
|||
<script src="/js/autolinker.min.js"></script>
|
||||
<script src="/js/emoji.min.js"></script>
|
||||
<script src="/js/helper.js"></script>
|
||||
<script src="/js/app.js"></script>
|
||||
</head>
|
Loading…
Reference in a new issue