Implemented user modal

This commit is contained in:
Chris Blanchard 2016-02-03 16:55:34 +00:00
parent 5bf039dce1
commit 63e97c8608
2 changed files with 266 additions and 238 deletions

View file

@ -12,6 +12,7 @@ const Sound = require("javascripts/components/sound");
const SoundController = Sound.SoundController;
const helper = require("javascripts/helper");
const storageAvailable = helper.storageAvailable;
const SplashScreen = React.createClass({
getInitialState() {
return {
@ -22,27 +23,20 @@ const SplashScreen = React.createClass({
componentDidMount() {
const socketUrl = window.location.protocol + "//" + window.location.host;
let socket = io(socketUrl)
const socket = io(socketUrl)
.on("connect", () => {
console.log("Connected");
this.setState({ status: "connected" });
socket
.on("reconnect", () => {
console.log("Reconnected");
})
.on("disconnect", () => {
console.log("Disconnected")
});
.on("reconnect", () => {})
.on("disconnect", () => {});
})
.on("error", error => {
console.log(error);
if (error === "Authentication Failed") {
this.setState({ status: "authFailed" });
} else if (error === "Gather Banned") {
this.setState({ status: "banned" });
}
});
this.setState({ socket: socket });
},
@ -177,58 +171,6 @@ const App = React.createClass({
};
},
updateTitle() {
let gather = this.state.gather;
if (gather && this.state.updateTitle) {
document.title = `NSL Gathers (${gather.gatherers.length}/12)`;
return;
}
document.title = "NSL Gathers";
},
toggleEventsPanel(event) {
let newState = event.target.checked;
this.setState({ showEventsPanel: newState });
if (storageAvailable('localStorage')) {
localStorage.setItem("showEventsPanel", newState)
}
},
toggleUpdateTitle(event) {
let newState = event.target.checked;
this.setState({ updateTitle: newState });
if (storageAvailable('localStorage')) {
localStorage.setItem("updateTitle", newState)
}
this.updateTitle();
},
thisGatherer() {
let gather = this.state.gather;
let user = this.state.user;
if (gather && user && gather.gatherers.length) {
return gather.gatherers
.filter(gatherer => gatherer.id === user.id)
.pop() || null;
}
return null;
},
mountModal(options) {
this.setState({ modal: options });
},
closeModal() {
this.setState({ modal: null });
},
modal() {
const options = this.state.modal;
if (!options) return;
const Component = options.component;
return <Component {...options.props} close={this.closeModal} />;
},
componentDidMount() {
let self = this;
let socket = this.props.socket;
@ -320,9 +262,64 @@ const App = React.createClass({
socket.emit("gather:refresh");
},
updateTitle() {
let gather = this.state.gather;
if (gather && this.state.updateTitle) {
document.title = `NSL Gathers (${gather.gatherers.length}/12)`;
return;
}
document.title = "NSL Gathers";
},
toggleEventsPanel(event) {
let newState = event.target.checked;
this.setState({ showEventsPanel: newState });
if (storageAvailable('localStorage')) {
localStorage.setItem("showEventsPanel", newState)
}
},
toggleUpdateTitle(event) {
let newState = event.target.checked;
this.setState({ updateTitle: newState });
if (storageAvailable('localStorage')) {
localStorage.setItem("updateTitle", newState)
}
this.updateTitle();
},
thisGatherer() {
let gather = this.state.gather;
let user = this.state.user;
if (gather && user && gather.gatherers.length) {
return gather.gatherers
.filter(gatherer => gatherer.id === user.id)
.pop() || null;
}
return null;
},
mountModal(options) {
this.setState({ modal: options });
},
closeModal() {
this.setState({ modal: null });
},
modal() {
const options = this.state.modal;
if (!options) return;
const Component = options.component;
return (
<div className="modal fade in" style={{display: "block"}}>
<Component {...options.props} close={this.closeModal} />
</div>
);
},
toggleMessageBox(e) {
e.preventDefault();
console.log("FOO")
this.setState({
showMessageBox: !this.state.showMessageBox
});
@ -335,6 +332,17 @@ const App = React.createClass({
});
},
openProfileModal(e) {
e.preventDefault();
this.mountModal({
component: ProfileModal,
props: {
user: this.state.user,
socket: this.props.socket
}
});
},
render() {
const socket = this.props.socket;
@ -343,9 +351,15 @@ const App = React.createClass({
eventsPanel = <Events events={this.state.events} />;
}
let profileModal, chatroom, currentUser;
let chatroom, currentUser, profileLink;
if (this.state.user) {
profileModal = <ProfileModal user={this.state.user} />;
profileLink = (
<li className="dropdown messages-menu">
<a href="#" className="dropdown-toggle" onClick={this.openProfileModal}>
<i className="fa fa-user"></i>
</a>
</li>
);
chatroom = <Chatroom messages={this.state.messages}
user={this.state.user} socket={socket} />;
currentUser = (
@ -391,18 +405,15 @@ const App = React.createClass({
<div className="navbar-custom-menu">
<ul className="nav navbar-nav">
<li className="dropdown messages-menu">
<a href="#">
<a href="#" className="dropdown-toggle">
<i className="fa fa-headphones"></i>
</a>
</li>
<li className="dropdown messages-menu">
<a href="#">
<i className="fa fa-newspaper-o"></i>
<span className="label label-success">4</span>
</a>
</li>
{profileLink}
<li>
<a href="#" onClick={this.toggleMessageBox}><i className="fa fa-comment"></i></a>
<a href="#" onClick={this.toggleMessageBox} className="dropdown-toggle">
<i className="fa fa-comment"></i>
</a>
</li>
</ul>
</div>
@ -450,54 +461,52 @@ const App = React.createClass({
</div>
);
return (
<div id="wrapper">
<nav className="navbar navbar-default navbar-static-top"
role="navigation"
style={{marginBottom: "0"}}>
<div className="navbar-header">
<a className="navbar-brand" href="/">NSL Gathers <small><i>Alpha</i></small></a>
</div>
{currentUser}
<ul className="nav navbar-top-links navbar-right" id="soundcontroller">
<SoundPanel soundController={this.state.soundController} />
</ul>
</nav>
<AdminPanel socket={socket} />
<SettingsPanel
toggleEventsPanel={this.toggleEventsPanel}
showEventsPanel={this.state.showEventsPanel}
toggleUpdateTitle={this.toggleUpdateTitle}
updateTitle={this.state.updateTitle} />
<TeamSpeakModal />
{profileModal}
<div style={{minHeight: "750px"}}>
<div className="container-fluid">
<div className="row">
<div className="col-md-4">
{chatroom}
</div>
<div className="col-md-6">
<Gather
socket={socket}
maps={this.state.maps}
user={this.state.user}
gather={this.state.gather}
servers={this.state.servers}
thisGatherer={this.thisGatherer()}
previousGather={this.state.previousGather}
soundController={this.state.soundController} />
{eventsPanel}
<hr />
<ArchivedGathers archive={this.state.archive}
maps={this.state.maps}
servers={this.state.servers} />
</div>
</div>
</div>
</div>
</div>
);
// return (
// <div id="wrapper">
// <nav className="navbar navbar-default navbar-static-top"
// role="navigation"
// style={{marginBottom: "0"}}>
// <div className="navbar-header">
// <a className="navbar-brand" href="/">NSL Gathers <small><i>Alpha</i></small></a>
// </div>
// {currentUser}
// <ul className="nav navbar-top-links navbar-right" id="soundcontroller">
// <SoundPanel soundController={this.state.soundController} />
// </ul>
// </nav>
// <AdminPanel socket={socket} />
// <SettingsPanel
// toggleEventsPanel={this.toggleEventsPanel}
// showEventsPanel={this.state.showEventsPanel}
// toggleUpdateTitle={this.toggleUpdateTitle}
// updateTitle={this.state.updateTitle} />
// <div style={{minHeight: "750px"}}>
// <div className="container-fluid">
// <div className="row">
// <div className="col-md-4">
// {chatroom}
// </div>
// <div className="col-md-6">
// <Gather
// socket={socket}
// maps={this.state.maps}
// user={this.state.user}
// gather={this.state.gather}
// servers={this.state.servers}
// thisGatherer={this.thisGatherer()}
// previousGather={this.state.previousGather}
// soundController={this.state.soundController} />
// {eventsPanel}
// <hr />
// <ArchivedGathers archive={this.state.archive}
// maps={this.state.maps}
// servers={this.state.servers} />
// </div>
// </div>
// </div>
// </div>
// </div>
// );
}
});

View file

@ -125,56 +125,54 @@ const UserModal = React.createClass({
}
return (
<div className="modal fade in" style={{display: "block"}}>
<div className="modal-dialog">
<div className="modal-content">
<div className="modal-header">
<button type="button" className="close" onClick={this.props.close}
aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
<h4 className="modal-title">
<img src="blank.gif"
className={"flag flag-" + ((user.country === null) ? "eu" :
user.country.toLowerCase()) }
alt={user.country} />&nbsp;
{user.username}
</h4>
</div>
<div className="modal-body">
<div className="text-center">
<img
src={user.avatar}
alt="User Avatar" />
</div>
<table className="table">
<tbody>
<tr>
<td>Lifeforms</td>
<td><LifeformIcons gatherer={{user: user}} /></td>
</tr>
<tr>
<td>Links</td>
<td>
<a href={enslUrl(user)}
className="btn btn-xs btn-primary"
target="_blank">ENSL Profile</a>&nbsp;
<a href={hiveUrl({user: user})}
className="btn btn-xs btn-primary"
target="_blank">Hive Profile</a>
</td>
</tr>
{hiveStats}
</tbody>
</table>
</div>
<div className="modal-footer">
{adminOptions}
<button type="button"
className="btn btn-default"
onClick={this.props.close}
>Close</button>
<div className="modal-dialog">
<div className="modal-content">
<div className="modal-header">
<button type="button" className="close" onClick={this.props.close}
aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
<h4 className="modal-title">
<img src="blank.gif"
className={"flag flag-" + ((user.country === null) ? "eu" :
user.country.toLowerCase()) }
alt={user.country} />&nbsp;
{user.username}
</h4>
</div>
<div className="modal-body">
<div className="text-center">
<img
src={user.avatar}
alt="User Avatar" />
</div>
<table className="table">
<tbody>
<tr>
<td>Lifeforms</td>
<td><LifeformIcons gatherer={{user: user}} /></td>
</tr>
<tr>
<td>Links</td>
<td>
<a href={enslUrl(user)}
className="btn btn-xs btn-primary"
target="_blank">ENSL Profile</a>&nbsp;
<a href={hiveUrl({user: user})}
className="btn btn-xs btn-primary"
target="_blank">Hive Profile</a>
</td>
</tr>
{hiveStats}
</tbody>
</table>
</div>
<div className="modal-footer">
{adminOptions}
<button type="button"
className="btn btn-default"
onClick={this.props.close}
>Close</button>
</div>
</div>
</div>
@ -190,7 +188,8 @@ const UserItem = React.createClass({
mountModal: React.PropTypes.func.isRequired
},
openModal() {
openModal(e) {
e.preventDefault();
this.props.mountModal({
component: UserModal,
props: {
@ -286,98 +285,118 @@ const AdminPanel = exports.AdminPanel = React.createClass({
const ProfileModal = exports.ProfileModal = React.createClass({
propTypes: {
user: React.PropTypes.object.isRequired
user: React.PropTypes.object.isRequired,
socket: React.PropTypes.object.isRequired,
close: React.PropTypes.func.isRequired
},
getInitialState() {
const user = this.props.user;
console.log(user.profile);
return {
abilities: {
skulk: user.profile.abilities.skulk,
lerk: user.profile.abilities.lerk,
gorge: user.profile.abilities.gorge,
fade: user.profile.abilities.fade,
onos: user.profile.abilities.onos,
commander: user.profile.abilities.commander
},
skill: user.profile.skill
};
},
handleUserUpdate(e) {
e.preventDefault();
let abilities = {
skulk: React.findDOMNode(this.refs.skulk).checked,
lerk: React.findDOMNode(this.refs.lerk).checked,
gorge: React.findDOMNode(this.refs.gorge).checked,
fade: React.findDOMNode(this.refs.fade).checked,
onos: React.findDOMNode(this.refs.onos).checked,
commander: React.findDOMNode(this.refs.commander).checked
};
let skill = React.findDOMNode(this.refs.playerskill).value;
socket.emit("users:update:profile", {
this.props.socket.emit("users:update:profile", {
id: this.props.user.id,
profile: {
abilities: abilities,
skill: skill
abilities: this.state.abilities,
skill: this.state.skill
}
});
this.props.close();
},
handleAbilityChange(e) {
let abilities = this.state.abilities;
abilities[e.target.name] = e.target.checked;
this.setState({abilities: abilities});
},
handleSkillChange(e) {
this.setState({ skill: e.target.value });
},
render() {
if (!this.props.user) return false;
let abilities = this.props.user.profile.abilities;
const user = this.props.user;
if (!user) return false;
const abilities = this.state.abilities;
let abilitiesForm = [];
for (let lifeform in abilities) {
abilitiesForm.push(
<div key={lifeform} className="checkbox">
<label className="checkbox-inline">
<input type="checkbox"
ref={lifeform}
defaultChecked={abilities[lifeform]}/> {_.capitalize(lifeform)}
<input type="checkbox" name={lifeform}
checked={abilities[lifeform]} onChange={this.handleAbilityChange} />
{_.capitalize(lifeform)}
</label>
</div>
);
}
let skillLevel = this.props.user.profile.skill;
let skillLevel = user.profile.skill;
let skillLevels = _.uniq(["Low Skill", "Medium Skill", "High Skill", skillLevel])
.filter(skill => { return typeof skill === 'string' })
.map(skill => { return <option key={skill}>{skill}</option>});
.map(skill => { return <option key={skill} value={skill}>{skill}</option>});
return (
<div className="modal fade" id="profilemodal">
<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">&times;</span>
</button>
<h4 className="modal-title">Profile</h4>
</div>
<div className="modal-body" id="profile-panel">
<form>
<div className="form-group">
<label>Player Skill</label><br />
<select
defaultValue={skillLevel}
className="form-control"
ref="playerskill">
{skillLevels}
</select>
<p className="add-top"><small>
Try to give an accurate representation of your skill to raise
the quality of your gathers
</small></p>
</div>
<hr />
<div className="form-group">
<label>Preferred Lifeforms</label><br />
{abilitiesForm}
<p><small>
Specify which lifeforms you'd like to play in the gather
</small></p>
</div>
<hr />
<p className="small">
You will need to rejoin the gather to see your updated profile
</p>
<div className="form-group">
<button
type="submit"
className="btn btn-primary"
data-dismiss="modal"
onClick={this.handleUserUpdate}>
Update &amp; Close</button>
</div>
</form>
</div>
<div className="modal-dialog">
<div className="modal-content">
<div className="modal-header">
<button type="button" className="close" aria-label="Close"
onClick={this.props.close}>
<span aria-hidden="true">&times;</span>
</button>
<h4 className="modal-title">Profile</h4>
</div>
<div className="modal-body" id="profile-panel">
<form>
<div className="form-group">
<label>Player Skill</label><br />
<select
value={skillLevel}
className="form-control"
onChange={this.handleSkillChange}>
{skillLevels}
</select>
<p className="add-top"><small>
Try to give an accurate representation of your skill to raise
the quality of your gathers
</small></p>
</div>
<hr />
<div className="form-group">
<label>Preferred Lifeforms</label><br />
{abilitiesForm}
<p><small>
Specify which lifeforms you'd like to play in the gather
</small></p>
</div>
<hr />
<p className="small">
You will need to rejoin the gather to see your updated profile
</p>
<div className="form-group">
<button
type="submit"
className="btn btn-primary"
onClick={this.handleUserUpdate}>
Update &amp; Close</button>
</div>
</form>
</div>
</div>
</div>