Added election countdown

This commit is contained in:
Chris Blanchard 2015-07-31 16:54:08 +01:00
parent cbc486de77
commit d6d0e94b01
5 changed files with 142 additions and 55 deletions

View file

@ -22,13 +22,21 @@
var Map = require("./map"); var Map = require("./map");
var Server = require("./server"); var Server = require("./server");
var Gather = require("./gather"); var Gather = require("./gather");
var gather = new Gather(); var gather;
// ***** Generate Test Users *****
var helper = require("./helper");
helper.createTestUsers({ gather: gather });
module.exports = function (namespace) { module.exports = function (namespace) {
gather = Gather({
onElectionTimeout: function () {
console.log("Election timeout")
refreshGather();
}
});
// ***** Generate Test Users *****
var helper = require("./helper");
helper.createTestUsers({ gather: gather });
var refreshGather = function () { var refreshGather = function () {
namespace.sockets.forEach(function (socket) { namespace.sockets.forEach(function (socket) {
socket.emit("gather:refresh", { socket.emit("gather:refresh", {

View file

@ -19,7 +19,7 @@ function Gather (options) {
return new Gather(options); return new Gather(options);
} }
if (typeof options.onElectionTimeout === 'function') { if (options && typeof options.onElectionTimeout === 'function') {
this.onElectionTimeout = options.onElectionTimeout; this.onElectionTimeout = options.onElectionTimeout;
} }
@ -138,7 +138,7 @@ Gather.prototype.toJson = function () {
gatherers: this.gatherers, gatherers: this.gatherers,
state: this.current, state: this.current,
election: { election: {
startTime: this.electionStartTime, startTime: (this.electionStartTime === null) ? null : this.electionStartTime.toISOString(),
interval: this.ELECTION_INTERVAL interval: this.ELECTION_INTERVAL
} }
} }
@ -238,6 +238,9 @@ StateMachine.create({
if (self.can("electionTimeout")) { if (self.can("electionTimeout")) {
self.electionTimeout(); self.electionTimeout();
} }
if (self.onElectionTimeout) {
self.onElectionTimeout.bind(self)();
}
}, self.ELECTION_INTERVAL); }, self.ELECTION_INTERVAL);
}, },

View file

@ -128,6 +128,52 @@ var GatherTeams = React.createClass({
} }
}) })
var ElectionProgressBar = React.createClass({
componentDidMount: function () {
var self = this;
this.timer = setInterval(function () {
self.forceUpdate();
}, 900);
},
progress: function () {
var interval = this.props.gather.election.interval;
var startTime = (new Date(this.props.gather.election.startTime)).getTime();
var msTranspired = Math.floor((new Date()).getTime() - startTime);
return {
num: msTranspired,
den: interval,
barMessage: Math.floor((interval - msTranspired) / 100) + "s remaining"
}
},
componentWillUnmount: function () {
clearInterval(this.timer);
},
render: function () {
return (<ProgressBar progress={this.progress()} />);
}
});
var ProgressBar = React.createClass({
render: function () {
var style = {
width: Math.round((this.props.progress.num / this.props.progress.den * 100)) + "%"
};
var barMessage = this.props.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-valuemin="0"
data-aria-valuemax={this.props.progress.den}
style={style}>{barMessage}
</div>
</div>
);
}
});
var GatherProgress = React.createClass({ var GatherProgress = React.createClass({
stateDescription: function () { stateDescription: function () {
switch(this.props.gather.state) { switch(this.props.gather.state) {
@ -180,36 +226,27 @@ var GatherProgress = React.createClass({
}; };
}, },
render: function () { render: function () {
var progress; var progress, progressBar;
var gatherState = this.props.gather.state; var gatherState = this.props.gather.state;
if (gatherState === 'gathering' && this.props.gather.gatherers.length) { if (gatherState === 'gathering' && this.props.gather.gatherers.length) {
progress = this.gatheringProgress(); progress = this.gatheringProgress();
progressBar = (<ProgressBar progress={progress} />);
} else if (gatherState === 'election') { } else if (gatherState === 'election') {
progress = this.electionProgress(); progress = this.electionProgress();
progressBar = (<ElectionProgressBar {...this.props} progress={progress} />);
} else if (gatherState === 'selection') { } else if (gatherState === 'selection') {
progress = this.selectionProgress(); progress = this.selectionProgress();
progressBar = (<ProgressBar progress={progress} />);
} }
if (progress) {
var style = { if (!progress) return false;
width: Math.round((progress.num / progress.den * 100)) + "%"
}; return (
return ( <div className="panel-body no-bottom">
<div className="panel-body no-bottom"> <p><strong>{this.stateDescription()}</strong> {progress.message}</p>
<p><strong>{this.stateDescription()}</strong> {progress.message}</p> {progressBar}
<div className="progress"> </div>
<div className="progress-bar progress-bar-striped active" );
data-role="progressbar"
data-aria-valuenow={progress.num}
data-aria-valuemin="0"
data-aria-valuemax={progress.den}
style={style}>
</div>
</div>
</div>
);
} else {
return false;
}
} }
}); });
@ -414,6 +451,7 @@ var Gather = React.createClass({
componentDidMount: function () { componentDidMount: function () {
var self = this; var self = this;
socket.on("gather:refresh", function (data) { socket.on("gather:refresh", function (data) {
console.log(data);
self.setProps(data); self.setProps(data);
}); });
}, },
@ -449,8 +487,8 @@ var Gather = React.createClass({
<strong>NS2 Gather </strong> <strong>NS2 Gather </strong>
<span className="badge add-left">{this.props.gather.gatherers.length}</span> <span className="badge add-left">{this.props.gather.gatherers.length}</span>
</div> </div>
<GatherProgress gather={this.props.gather} /> <GatherProgress {...this.props} />
<Gatherers gather={this.props.gather} currentGatherer={this.props.currentGatherer} /> <Gatherers {...this.props} />
{gatherTeams} {gatherTeams}
{voting} {voting}
<GatherActions {...this.props} /> <GatherActions {...this.props} />

View file

@ -128,6 +128,52 @@ var GatherTeams = React.createClass({displayName: "GatherTeams",
} }
}) })
var ElectionProgressBar = React.createClass({displayName: "ElectionProgressBar",
componentDidMount: function () {
var self = this;
this.timer = setInterval(function () {
self.forceUpdate();
}, 900);
},
progress: function () {
var interval = this.props.gather.election.interval;
var startTime = (new Date(this.props.gather.election.startTime)).getTime();
var msTranspired = Math.floor((new Date()).getTime() - startTime);
return {
num: msTranspired,
den: interval,
barMessage: Math.floor((interval - msTranspired) / 100) + "s remaining"
}
},
componentWillUnmount: function () {
clearInterval(this.timer);
},
render: function () {
return (React.createElement(ProgressBar, {progress: this.progress()}));
}
});
var ProgressBar = React.createClass({displayName: "ProgressBar",
render: function () {
var style = {
width: Math.round((this.props.progress.num / this.props.progress.den * 100)) + "%"
};
var barMessage = this.props.progress.barMessage || "";
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
)
)
);
}
});
var GatherProgress = React.createClass({displayName: "GatherProgress", var GatherProgress = React.createClass({displayName: "GatherProgress",
stateDescription: function () { stateDescription: function () {
switch(this.props.gather.state) { switch(this.props.gather.state) {
@ -180,36 +226,27 @@ var GatherProgress = React.createClass({displayName: "GatherProgress",
}; };
}, },
render: function () { render: function () {
var progress; var progress, progressBar;
var gatherState = this.props.gather.state; var gatherState = this.props.gather.state;
if (gatherState === 'gathering' && this.props.gather.gatherers.length) { if (gatherState === 'gathering' && this.props.gather.gatherers.length) {
progress = this.gatheringProgress(); progress = this.gatheringProgress();
progressBar = (React.createElement(ProgressBar, {progress: progress}));
} else if (gatherState === 'election') { } else if (gatherState === 'election') {
progress = this.electionProgress(); progress = this.electionProgress();
progressBar = (React.createElement(ElectionProgressBar, React.__spread({}, this.props, {progress: progress})));
} else if (gatherState === 'selection') { } else if (gatherState === 'selection') {
progress = this.selectionProgress(); progress = this.selectionProgress();
progressBar = (React.createElement(ProgressBar, {progress: progress}));
} }
if (progress) {
var style = { if (!progress) return false;
width: Math.round((progress.num / progress.den * 100)) + "%"
}; return (
return ( React.createElement("div", {className: "panel-body no-bottom"},
React.createElement("div", {className: "panel-body no-bottom"}, React.createElement("p", null, React.createElement("strong", null, this.stateDescription()), " ", progress.message),
React.createElement("p", null, React.createElement("strong", null, this.stateDescription()), " ", progress.message), progressBar
React.createElement("div", {className: "progress"}, )
React.createElement("div", {className: "progress-bar progress-bar-striped active", );
"data-role": "progressbar",
"data-aria-valuenow": progress.num,
"data-aria-valuemin": "0",
"data-aria-valuemax": progress.den,
style: style}
)
)
)
);
} else {
return false;
}
} }
}); });
@ -414,6 +451,7 @@ var Gather = React.createClass({displayName: "Gather",
componentDidMount: function () { componentDidMount: function () {
var self = this; var self = this;
socket.on("gather:refresh", function (data) { socket.on("gather:refresh", function (data) {
console.log(data);
self.setProps(data); self.setProps(data);
}); });
}, },
@ -449,8 +487,8 @@ var Gather = React.createClass({displayName: "Gather",
React.createElement("strong", null, "NS2 Gather "), React.createElement("strong", null, "NS2 Gather "),
React.createElement("span", {className: "badge add-left"}, this.props.gather.gatherers.length) React.createElement("span", {className: "badge add-left"}, this.props.gather.gatherers.length)
), ),
React.createElement(GatherProgress, {gather: this.props.gather}), React.createElement(GatherProgress, React.__spread({}, this.props)),
React.createElement(Gatherers, {gather: this.props.gather, currentGatherer: this.props.currentGatherer}), React.createElement(Gatherers, React.__spread({}, this.props)),
gatherTeams, gatherTeams,
voting, voting,
React.createElement(GatherActions, React.__spread({}, this.props)) React.createElement(GatherActions, React.__spread({}, this.props))

View file

@ -52,7 +52,7 @@ describe("Gather Model:", function () {
done(); done();
} }
}); });
gather.ELECTION_INTERVAL = 100; // 1 second gather.ELECTION_INTERVAL = 10; // 10ms
assert.isNull(gather.electionStartTime); assert.isNull(gather.electionStartTime);
gatherers.forEach(function (gatherer) { gatherers.forEach(function (gatherer) {
gather.addGatherer(gatherer); gather.addGatherer(gatherer);