mirror of
https://github.com/ENSL/ensl_gathers.git
synced 2024-11-26 22:31:08 +00:00
635 lines
18 KiB
JavaScript
635 lines
18 KiB
JavaScript
"use strict";
|
||
|
||
var VoteButton = React.createClass({displayName: "VoteButton",
|
||
cancelVote: function (e) {
|
||
socket.emit("gather:vote", {
|
||
leader: {
|
||
candidate: null
|
||
}
|
||
});
|
||
},
|
||
vote: function (e) {
|
||
e.preventDefault();
|
||
socket.emit("gather:vote", {
|
||
leader: {
|
||
candidate: parseInt(e.target.value, 10)
|
||
}
|
||
});
|
||
},
|
||
render: function () {
|
||
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 JoinGatherButton = React.createClass({displayName: "JoinGatherButton",
|
||
joinGather: function (e) {
|
||
e.preventDefault();
|
||
socket.emit("gather:join", {});
|
||
},
|
||
render: function () {
|
||
var message = this.props.buttonName || "Join Gather";
|
||
var buttonClass = "btn btn-primary";
|
||
if (this.props.buttonClass) {
|
||
buttonClass += " " + this.props.buttonClass;
|
||
}
|
||
return (React.createElement("button", {
|
||
onClick: this.joinGather,
|
||
className: buttonClass}, message))
|
||
}
|
||
});
|
||
|
||
var SelectPlayerButton = React.createClass({displayName: "SelectPlayerButton",
|
||
selectPlayer: function (e) {
|
||
e.preventDefault();
|
||
},
|
||
render: function () {
|
||
if (!this.props.currentGatherer.leader) {
|
||
return false;
|
||
} else {
|
||
return (React.createElement("button", {
|
||
onClick: this.selectPlayer,
|
||
className: "btn btn-xs btn-primary"}, " Select"
|
||
)
|
||
);
|
||
}
|
||
}
|
||
})
|
||
|
||
var GatherTeams = React.createClass({displayName: "GatherTeams",
|
||
alienGatherers: function () {
|
||
return this.props.gather.gatherers.filter(function (gatherer) {
|
||
return gatherer.team === "alien";
|
||
}).sort(function (gatherer) {
|
||
return (gatherer.leader) ? 1 : 0;
|
||
});
|
||
},
|
||
marineGatherers: function () {
|
||
return this.props.gather.gatherers.filter(function (gatherer) {
|
||
return gatherer.team === "marine";
|
||
}).sort(function (gatherer) {
|
||
return (gatherer.leader) ? 1 : 0;
|
||
});
|
||
},
|
||
render: function () {
|
||
var extractGatherer = function (gatherer) {
|
||
var image;
|
||
if (gatherer.leader) {
|
||
image = (React.createElement("img", {src: "/images/commander.png",
|
||
alt: "Commander",
|
||
height: "20",
|
||
width: "20"}));
|
||
}
|
||
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)
|
||
)
|
||
);
|
||
}
|
||
var marines = this.marineGatherers().map(extractGatherer);
|
||
var aliens = this.alienGatherers().map(extractGatherer);
|
||
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("table", {className: "table"},
|
||
React.createElement("tbody", null,
|
||
aliens
|
||
)
|
||
)
|
||
)
|
||
),
|
||
React.createElement("div", {className: "col-md-6"},
|
||
React.createElement("div", {className: "panel panel-default"},
|
||
React.createElement("div", {className: "panel-heading"},
|
||
"Marines"
|
||
),
|
||
React.createElement("table", {className: "table"},
|
||
React.createElement("tbody", null,
|
||
marines
|
||
)
|
||
)
|
||
)
|
||
)
|
||
)
|
||
)
|
||
);
|
||
}
|
||
})
|
||
|
||
var GatherProgress = React.createClass({displayName: "GatherProgress",
|
||
stateDescription: function () {
|
||
switch(this.props.gather.state) {
|
||
case "gathering":
|
||
return "Waiting for more gatherers.";
|
||
case "election":
|
||
return "Currently voting for team leaders.";
|
||
case "selection":
|
||
return "Waiting for leaders to picking teams.";
|
||
case "done":
|
||
return "Gather completed.";
|
||
default:
|
||
return "Initialising gather.";
|
||
}
|
||
},
|
||
gatheringProgress: function () {
|
||
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";
|
||
return {
|
||
num: num,
|
||
den: den,
|
||
message: message
|
||
};
|
||
},
|
||
electionProgress: function () {
|
||
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"
|
||
};
|
||
},
|
||
selectionProgress: function () {
|
||
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"
|
||
};
|
||
},
|
||
render: function () {
|
||
var progress;
|
||
var gatherState = this.props.gather.state;
|
||
if (gatherState === 'gathering' && this.props.gather.gatherers.length) {
|
||
progress = this.gatheringProgress();
|
||
} else if (gatherState === 'election') {
|
||
progress = this.electionProgress();
|
||
} else if (gatherState === 'selection') {
|
||
progress = this.selectionProgress();
|
||
}
|
||
if (progress) {
|
||
var style = {
|
||
width: Math.round((progress.num / progress.den * 100)) + "%"
|
||
};
|
||
return (
|
||
React.createElement("div", {className: "panel-body"},
|
||
React.createElement("p", null, React.createElement("strong", null, this.stateDescription()), " ", progress.message),
|
||
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;
|
||
}
|
||
}
|
||
});
|
||
|
||
var Gather = React.createClass({displayName: "Gather",
|
||
getDefaultProps: function () {
|
||
return {
|
||
gather: {
|
||
gatherers: []
|
||
}
|
||
}
|
||
},
|
||
joinedGather: function () {
|
||
return this.props.currentGatherer !== null;
|
||
},
|
||
componentDidMount: function () {
|
||
var self = this;
|
||
socket.on("gather:refresh", function (data) {
|
||
self.setProps({
|
||
gather: data.gather,
|
||
currentGatherer: data.currentGatherer
|
||
});
|
||
});
|
||
},
|
||
leaveGather: function (e) {
|
||
e.preventDefault();
|
||
socket.emit("gather:leave", {});
|
||
},
|
||
inviteToGather: function (e) {
|
||
e.preventDefault();
|
||
},
|
||
render: function () {
|
||
var joinButton;
|
||
if (this.joinedGather()) {
|
||
joinButton = (React.createElement("li", null, React.createElement("button", {
|
||
onClick: this.leaveGather,
|
||
className: "btn btn-danger"}, "Leave Gather")));
|
||
} else {
|
||
joinButton = (React.createElement("li", null, React.createElement(JoinGatherButton, null)));
|
||
}
|
||
var inviteButton;
|
||
if (this.props.gather.state === 'gathering') {
|
||
inviteButton = (React.createElement("li", null, React.createElement("button", {
|
||
onClick: this.inviteToGather,
|
||
className: "btn btn-primary"}, "Invite to Gather")));
|
||
}
|
||
var gatherTeams;
|
||
if (this.props.gather.state === 'selection') {
|
||
gatherTeams = React.createElement(GatherTeams, {gather: this.props.gather})
|
||
}
|
||
return (
|
||
React.createElement("div", {className: "panel panel-default"},
|
||
React.createElement("div", {className: "panel-heading"},
|
||
React.createElement("strong", null, "NS2 Gather "),
|
||
React.createElement("span", {className: "badge add-left"}, this.props.gather.gatherers.length)
|
||
),
|
||
React.createElement(Gatherers, {gather: this.props.gather, currentGatherer: this.props.currentGatherer}),
|
||
gatherTeams,
|
||
React.createElement(GatherProgress, {gather: this.props.gather}),
|
||
React.createElement("div", {className: "panel-footer text-right"},
|
||
React.createElement("ul", {className: "list-inline"},
|
||
inviteButton,
|
||
joinButton
|
||
)
|
||
)
|
||
)
|
||
);
|
||
}
|
||
});
|
||
|
||
var Gatherers = React.createClass({displayName: "Gatherers",
|
||
render: function () {
|
||
var self = this;
|
||
var gatherers = this.props.gather.gatherers.map(function (gatherer) {
|
||
var lifeforms = (
|
||
gatherer.user.ability.lifeforms.map(function (lifeform) {
|
||
return (React.createElement("span", {className: "label label-default"}, lifeform));
|
||
})
|
||
);
|
||
|
||
// Switch this to online status
|
||
var online= (React.createElement("span", {src: "/images/commander.png",
|
||
alt: "online",
|
||
className: "user-online"}, " "));
|
||
|
||
var division = (React.createElement("span", {className: "label label-primary"}, gatherer.user.ability.division));
|
||
var action = lifeforms;
|
||
if (self.props.gather.state === "election") {
|
||
var votes = self.props.gather.gatherers.reduce(function (acc, voter) {
|
||
if (voter.leaderVote === gatherer.id) acc++;
|
||
return acc;
|
||
}, 0)
|
||
action = (
|
||
React.createElement("span", null,
|
||
React.createElement("small", null, votes + " votes", " "),
|
||
React.createElement(VoteButton, {currentGatherer: self.props.currentGatherer, candidate: gatherer})
|
||
)
|
||
);
|
||
}
|
||
|
||
return (
|
||
React.createElement("tr", {key: gatherer.user.id},
|
||
React.createElement("td", {className: "col-md-1"}, online),
|
||
React.createElement("td", {className: "col-md-5"}, gatherer.user.username),
|
||
React.createElement("td", {className: "col-md-3"}, division, " "),
|
||
React.createElement("td", {className: "col-md-2 text-right"}, action, " ")
|
||
)
|
||
);
|
||
})
|
||
if (this.props.gather.gatherers.length) {
|
||
return (
|
||
React.createElement("div", {className: "panel-body"},
|
||
React.createElement("div", {className: "panel panel-default"},
|
||
React.createElement("div", {className: "panel-heading"},
|
||
React.createElement("h5", {className: "panel-title"}, "Roster")
|
||
),
|
||
React.createElement("table", {className: "table roster-table"},
|
||
React.createElement("tbody", null,
|
||
gatherers
|
||
)
|
||
)
|
||
)
|
||
)
|
||
);
|
||
} else {
|
||
return (React.createElement("div", {className: "panel-body text-center"}, React.createElement(JoinGatherButton, {buttonClass: "btn-lg", buttonName: "Start a Gather"})));
|
||
}
|
||
}
|
||
});
|
||
|
||
|
||
|
||
|
||
"use strict";
|
||
|
||
var socket;
|
||
|
||
function initialiseComponents () {
|
||
var socketUrl = window.location.protocol + "//" + window.location.host;
|
||
socket = io(socketUrl)
|
||
.on("connect", function () {
|
||
console.log("Connected");
|
||
})
|
||
.on("reconnect", function () {
|
||
console.log("Reconnected");
|
||
})
|
||
.on("disconnect", function () {
|
||
console.log("Disconnected")
|
||
});
|
||
|
||
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'));
|
||
};
|
||
"use strict";
|
||
|
||
var Chatroom = React.createClass({displayName: "Chatroom",
|
||
getDefaultProps: function () {
|
||
return {
|
||
history: []
|
||
};
|
||
},
|
||
componentDidMount: function () {
|
||
var self = this;
|
||
var TIMER_INTERVAL = 60000; // Every minute
|
||
|
||
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", {});
|
||
|
||
self.timer = setInterval(function () {
|
||
if (self.refs.messages) self.refs.messages.refreshTime();
|
||
}, TIMER_INTERVAL);
|
||
},
|
||
|
||
componentDidUnmount: function () {
|
||
clearInterval(this.timer);
|
||
},
|
||
sendMessage: function (message) {
|
||
socket.emit("newMessage", {message: message});
|
||
},
|
||
scrollToBottom: function () {
|
||
var node = React.findDOMNode(this.refs.messageContainer);
|
||
node.scrollTop = node.scrollHeight;
|
||
},
|
||
render: function () {
|
||
var messages = this.props.history.map(function (message) {
|
||
return (
|
||
React.createElement(ChatMessage, {
|
||
avatar: message.author.avatar,
|
||
username: message.author.username,
|
||
content: message.content,
|
||
ref: "messages",
|
||
createdAt: message.createdAt})
|
||
);
|
||
});
|
||
return (
|
||
React.createElement("div", {className: "panel panel-default"},
|
||
React.createElement("div", {className: "panel-heading"}, "Gather Chat"),
|
||
React.createElement("div", {className: "panel-body"},
|
||
React.createElement("ul", {className: "chat", id: "chatmessages", ref: "messageContainer"},
|
||
messages
|
||
)
|
||
),
|
||
React.createElement("div", {className: "panel-footer"},
|
||
React.createElement(MessageBar, null)
|
||
)
|
||
)
|
||
);
|
||
}
|
||
});
|
||
|
||
var ChatMessage = React.createClass({displayName: "ChatMessage",
|
||
getInitialState: function () {
|
||
return {
|
||
timeAgo: $.timeago(this.props.createdAt)
|
||
}
|
||
},
|
||
refreshTime: function () {
|
||
var self = this;
|
||
self.setState({
|
||
timeAgo: $.timeago(self.props.createdAt)
|
||
});
|
||
},
|
||
render: function () {
|
||
return (
|
||
React.createElement("li", {className: "left clearfix"},
|
||
React.createElement("span", {className: "chat-img pull-left"},
|
||
React.createElement("img", {
|
||
src: this.props.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.username),
|
||
React.createElement("small", {className: "pull-right text-muted"},
|
||
React.createElement("i", {className: "fa fa-clock-o fa-fw"}), " ", this.state.timeAgo
|
||
)
|
||
),
|
||
React.createElement("p", null, this.props.content)
|
||
)
|
||
)
|
||
);
|
||
}
|
||
});
|
||
|
||
var MessageBar = React.createClass({displayName: "MessageBar",
|
||
sendMessage: function (content) {
|
||
socket.emit("message:new", {
|
||
content: content
|
||
});
|
||
},
|
||
handleSubmit: function (e) {
|
||
e.preventDefault();
|
||
var content = React.findDOMNode(this.refs.content).value.trim();
|
||
if (!content) return;
|
||
React.findDOMNode(this.refs.content).value = '';
|
||
this.sendMessage(content);
|
||
return;
|
||
},
|
||
render: function () {
|
||
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"},
|
||
React.createElement("input", {
|
||
type: "submit",
|
||
className: "btn btn-primary",
|
||
id: "btn-chat",
|
||
value: "Send"})
|
||
)
|
||
)
|
||
)
|
||
);
|
||
}
|
||
});
|
||
|
||
"use strict";
|
||
|
||
var UserCounter = React.createClass({displayName: "UserCounter",
|
||
render: function () {
|
||
return (
|
||
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.count, " ")
|
||
)
|
||
)
|
||
);
|
||
}
|
||
});
|
||
|
||
var UserLogin = React.createClass({displayName: "UserLogin",
|
||
authorizeId: function (id) {
|
||
id = parseInt(id, 10);
|
||
socket.emit("users:authorize", {
|
||
id: id
|
||
});
|
||
},
|
||
handleSubmit: function (e) {
|
||
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);
|
||
return;
|
||
},
|
||
render: function () {
|
||
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",
|
||
placeholder: "Choose an ID..."}),
|
||
React.createElement("span", {className: "input-group-btn"},
|
||
React.createElement("input", {
|
||
type: "submit",
|
||
className: "btn btn-primary",
|
||
id: "btn-chat",
|
||
value: "Login"})
|
||
)
|
||
),
|
||
React.createElement("div", {className: "signin"},
|
||
React.createElement("p", {className: "text-center"}, React.createElement("small", null, "Just a temporary measure until genuine authentication is implemented"))
|
||
)
|
||
)
|
||
);
|
||
}
|
||
})
|
||
|
||
var UserMenu = React.createClass({displayName: "UserMenu",
|
||
getDefaultProps: function () {
|
||
return {
|
||
count: 0,
|
||
users: []
|
||
};
|
||
},
|
||
componentDidMount: function () {
|
||
socket.on('users:update', this.updateUsers);
|
||
},
|
||
updateUsers: function (data) {
|
||
this.setProps({
|
||
count: data.count,
|
||
users: data.users
|
||
});
|
||
},
|
||
render: function () {
|
||
var users = this.props.users.map(function (user) {
|
||
return (
|
||
React.createElement("li", {key: user.id}, React.createElement("a", {href: "#"}, user.username))
|
||
);
|
||
});
|
||
return (
|
||
React.createElement("ul", {className: "nav", id: "side-menu"},
|
||
React.createElement(UserCounter, React.__spread({}, this.props)),
|
||
users,
|
||
React.createElement("li", null, React.createElement("br", null), React.createElement(UserLogin, null), React.createElement("br", null))
|
||
)
|
||
);
|
||
}
|
||
});
|
||
|
||
var CurrentUser = React.createClass({displayName: "CurrentUser",
|
||
componentDidMount: function () {
|
||
var self = this;
|
||
socket.on("users:update", function (data) {
|
||
self.setProps({
|
||
user: data.currentUser
|
||
});
|
||
});
|
||
socket.emit("users:refresh", {});
|
||
},
|
||
render: function () {
|
||
if (this.props.user) {
|
||
return (
|
||
React.createElement("a", {href: "#"}, this.props.user.username, " ", React.createElement("img", {src: this.props.user.avatar,
|
||
alt: "User Avatar",
|
||
height: "20",
|
||
width: "20"}))
|
||
);
|
||
} else {
|
||
return false;
|
||
}
|
||
}
|
||
});
|