diff --git a/app/javascripts/app.js b/app/javascripts/app.js index 43d28db..f184a21 100644 --- a/app/javascripts/app.js +++ b/app/javascripts/app.js @@ -5,3 +5,21 @@ const App = require("javascripts/components/main"); module.exports = function (mount) { ReactDOM.render(, mount); }; + +toastr.options = { + "closeButton": true, + "debug": false, + "newestOnTop": false, + "progressBar": false, + "positionClass": "toast-top-center", + "preventDuplicates": false, + "onclick": null, + "showDuration": "300", + "hideDuration": "1000", + "timeOut": "5000", + "extendedTimeOut": "1000", + "showEasing": "swing", + "hideEasing": "linear", + "showMethod": "fadeIn", + "hideMethod": "fadeOut" +} \ No newline at end of file diff --git a/app/javascripts/components/main.js b/app/javascripts/components/main.js index 4a5659c..ccbdee5 100644 --- a/app/javascripts/components/main.js +++ b/app/javascripts/components/main.js @@ -208,6 +208,8 @@ const GatherPage = React.createClass({ } }); + socket.on("notify", data => toastr[data.type](data.message)); + socket.on('event:append', data => { let events = self.state.events; events.unshift(data); diff --git a/brunch-config.js b/brunch-config.js index 923c0ad..f1d4d81 100644 --- a/brunch-config.js +++ b/brunch-config.js @@ -50,15 +50,17 @@ exports.config = { npm: { enabled: true, styles: { - "bootstrap-solarized": ["bootstrap-solarized-dark.css"] + "bootstrap-solarized": ["bootstrap-solarized-dark.css"], + "toastr": ["build/toastr.min.css"] }, whitelist: ["react", "react-dom", "jquery", "lodash", "react-autolink", "react-dom", "react-emoji", "howler", - "bootstrap", "perfect-scrollbar", "moment"], + "bootstrap", "perfect-scrollbar", "moment", "toastr"], globals: { "_": "lodash", "jQuery": "jquery", - "$": "jquery" + "$": "jquery", + "toastr": "toastr" } }, diff --git a/lib/ensl/client.js b/lib/ensl/client.js index 97c6e0e..ee800d0 100644 --- a/lib/ensl/client.js +++ b/lib/ensl/client.js @@ -29,6 +29,15 @@ EnslClient.prototype.getUserById = function (options, callback) { }, callback); }; +EnslClient.prototype.getTeamById = function (options, callback) { + const id = options.id; + const url = `${this.baseUrl}api/v1/teams/${id}`; + return request({ + url: url, + json: true + }, callback); +}; + EnslClient.prototype.getServers = function (callback) { const url = this.baseUrl + "api/v1/servers"; return request({ diff --git a/lib/gather/controller.js b/lib/gather/controller.js index 053afb9..7dfdffa 100644 --- a/lib/gather/controller.js +++ b/lib/gather/controller.js @@ -120,9 +120,18 @@ module.exports = function (namespace) { const gatherManager = GatherPool.get(data.type); if (!gatherManager) return; const gather = gatherManager.current; - if (gather.can("addGatherer")) gather.addGatherer(socket._user); - Event.joiner(socket._user); - refreshGather(data.type); + if (gather.can("addGatherer")) { + gather.addGatherer(socket._user); + if (gather.containsUser(socket._user)) { + Event.joiner(socket._user); + } else { + socket.emit("notify", { + type: "error", + message: "Unable to add you to the gather" + }); + } + refreshGather(data.type); + } }); socket.on("gather:refresh", function (data) { diff --git a/lib/gather/gather.js b/lib/gather/gather.js index 619679c..72420b8 100644 --- a/lib/gather/gather.js +++ b/lib/gather/gather.js @@ -49,6 +49,10 @@ function Gather (options) { timer: null }; + if (typeof options.membershipTest === 'function') { + this.membershipTest = options.membershipTest.bind(this); + } + this.initState(); } @@ -80,6 +84,7 @@ StateMachine.create({ // Gathering State onbeforeaddGatherer: function (event, from, to, user) { if (this.needsToCoolOff(user)) return false; + if (this.failsTest(user)) return false; this.addUser(user); if (!this.lobbyFull()) return false; }, @@ -400,4 +405,9 @@ Gather.prototype.needsToCoolOff = function (user) { } }; +Gather.prototype.failsTest = function (user) { + if (!this.membershipTest) return false; + return !this.membershipTest(user); +} + module.exports = Gather; diff --git a/lib/gather/gather_pool.js b/lib/gather/gather_pool.js index 27096ad..cdd6493 100644 --- a/lib/gather/gather_pool.js +++ b/lib/gather/gather_pool.js @@ -11,6 +11,7 @@ const Gather = require("./gather"); const winston = require("winston"); const mongoose = require("mongoose"); const ArchivedGather = mongoose.model("ArchivedGather"); +const InvitationalGather = require("./invitational_gather"); let gatherCallbacks = {}; let archiveUpdatedCallback = () => {}; @@ -21,6 +22,15 @@ const GATHER_CONFIGS = [ name: "Classic Gather", description: "No Requirements" }, + { + type: "invitational", + name: "Invitational Gather", + description: "Join on ensl.org/teams/949", + // Grant invite if on list + membershipTest: function (user) { + return InvitationalGather.list.some(m => m.id === user.id); + } + }, { type: "casual", name: "Casual Gather", diff --git a/lib/gather/invitational_gather.js b/lib/gather/invitational_gather.js new file mode 100644 index 0000000..d7e2a1d --- /dev/null +++ b/lib/gather/invitational_gather.js @@ -0,0 +1,32 @@ +"use strict"; + +const winston = require("winston"); +const env = process.env.NODE_ENV || "development"; +const client = require("../ensl/client")(); +const REFRESH_INTERVAL = 1000 * 60; // Check every minute +const invitationalTeamId = env === "production" ? 949 : 866; + +function InvitationalGather () { + +} + +InvitationalGather.list = []; + +InvitationalGather.updateList = function () { + client.getTeamById({ + id: invitationalTeamId + }, (error, result) => { + if (error) { + winston.error("Unable to download team list") + winston.error(error); + return; + }; + InvitationalGather.list = result.body.members; + }); +}; + +InvitationalGather.updateList(); + +setInterval(InvitationalGather.updateList, REFRESH_INTERVAL); + +module.exports = InvitationalGather; diff --git a/package.json b/package.json index 59d0c4e..45aef5d 100644 --- a/package.json +++ b/package.json @@ -63,6 +63,7 @@ "socket.io": "~1.3.7", "steam": "~1.1.0", "steamidconvert": "~0.2.4", + "toastr": "^2.1.2", "uglify-js-brunch": ">= 1.0 < 1.8", "winston": "~1.0.1" }, diff --git a/spec/gather.js b/spec/gather.js index 2b44763..854d2ee 100644 --- a/spec/gather.js +++ b/spec/gather.js @@ -31,6 +31,23 @@ describe("Gather Model:", function () { }); }); + describe("membership", () => { + it ("does not allow user to join if membership criteria not met", () => { + gather = Gather({ + membershipTest: function (user) { return false } + }); + gather.addGatherer(user); + assert.equal(gather.gatherers.length, 0); + }); + it ("does not allow user to join if membership criteria met", () => { + gather = Gather({ + membershipTest: function (user) { return true } + }); + gather.addGatherer(user); + assert.equal(gather.gatherers.length, 1); + }); + }); + describe("removeUser", function () { it ("removes gatherer altogether", function () { gather.addUser(user);