summaryrefslogtreecommitdiffstats
path: root/web/react
diff options
context:
space:
mode:
Diffstat (limited to 'web/react')
-rw-r--r--web/react/components/channel_header.jsx15
-rw-r--r--web/react/components/mention_list.jsx6
-rw-r--r--web/react/components/new_channel.jsx7
-rw-r--r--web/react/components/post_list.jsx15
-rw-r--r--web/react/components/setting_picture.jsx30
-rw-r--r--web/react/components/sidebar_header.jsx117
-rw-r--r--web/react/components/user_profile.jsx3
-rw-r--r--web/react/components/user_settings.jsx107
-rw-r--r--web/react/utils/constants.jsx2
9 files changed, 179 insertions, 123 deletions
diff --git a/web/react/components/channel_header.jsx b/web/react/components/channel_header.jsx
index b6182cfa5..90a776791 100644
--- a/web/react/components/channel_header.jsx
+++ b/web/react/components/channel_header.jsx
@@ -67,7 +67,7 @@ var PopoverListMembers = React.createClass({
return (
<div id='member_popover' data-toggle='popover' data-content={popoverHtml} data-original-title='Members' >
- <div id='member_tooltip' data-toggle='tooltip' title='View Channel Members'>
+ <div id='member_tooltip' data-placement='left' data-toggle='tooltip' title='View Channel Members'>
{count} <span className='glyphicon glyphicon-user' aria-hidden='true'></span>
</div>
</div>
@@ -175,6 +175,11 @@ module.exports = React.createClass({
}
}
+ var channelTerm = 'Channel';
+ if (channel.type === 'P') {
+ channelTerm = 'Group';
+ }
+
return (
<table className='channel-header alt'>
<tr>
@@ -196,18 +201,18 @@ module.exports = React.createClass({
<li role='presentation'><a role='menuitem' data-toggle='modal' data-target='#channel_members' href='#'>Manage Members</a></li>
: null
}
- <li role='presentation'><a role='menuitem' href='#' data-toggle='modal' data-target='#edit_channel' data-desc={channel.description} data-title={channel.display_name} data-channelid={channel.id}>Set Channel Description...</a></li>
+ <li role='presentation'><a role='menuitem' href='#' data-toggle='modal' data-target='#edit_channel' data-desc={channel.description} data-title={channel.display_name} data-channelid={channel.id}>Set {channelTerm} Description...</a></li>
<li role='presentation'><a role='menuitem' href='#' data-toggle='modal' data-target='#channel_notifications' data-title={channel.display_name} data-channelid={channel.id}>Notification Preferences</a></li>
{isAdmin && !ChannelStore.isDefault(channel) ?
- <li role='presentation'><a role='menuitem' href='#' data-toggle='modal' data-target='#rename_channel' data-display={channel.display_name} data-name={channel.name} data-channelid={channel.id}>Rename Channel...</a></li>
+ <li role='presentation'><a role='menuitem' href='#' data-toggle='modal' data-target='#rename_channel' data-display={channel.display_name} data-name={channel.name} data-channelid={channel.id}>Rename {channelTerm}...</a></li>
: null
}
{isAdmin && !ChannelStore.isDefault(channel) ?
- <li role='presentation'><a role='menuitem' href='#' data-toggle='modal' data-target='#delete_channel' data-title={channel.display_name} data-channelid={channel.id}>Delete Channel...</a></li>
+ <li role='presentation'><a role='menuitem' href='#' data-toggle='modal' data-target='#delete_channel' data-title={channel.display_name} data-channelid={channel.id}>Delete {channelTerm}...</a></li>
: null
}
{!ChannelStore.isDefault(channel) ?
- <li role='presentation'><a role='menuitem' href='#' onClick={this.handleLeave}>Leave Channel</a></li>
+ <li role='presentation'><a role='menuitem' href='#' onClick={this.handleLeave}>Leave {channelTerm}</a></li>
: null
}
</ul>
diff --git a/web/react/components/mention_list.jsx b/web/react/components/mention_list.jsx
index a0f68df98..5f1bb6d0e 100644
--- a/web/react/components/mention_list.jsx
+++ b/web/react/components/mention_list.jsx
@@ -20,6 +20,12 @@ module.exports = React.createClass({
PostStore.addMentionDataChangeListener(this.onListenerChange);
var self = this;
+ $('.post-right__scroll').scroll(function(){
+ if($('.mentions--top').length){
+ $('#reply_mention_tab .mentions--top').css({ bottom: $(window).height() - $('.post-right__scroll #reply_textbox').offset().top });
+ }
+ });
+
$('body').on('keydown.mentionlist', '#' + this.props.id,
function(e) {
if (!self.isEmpty() && self.state.mentionText !== '-1' && (e.which === 13 || e.which === 9)) {
diff --git a/web/react/components/new_channel.jsx b/web/react/components/new_channel.jsx
index 93884f6eb..ffcbfd32d 100644
--- a/web/react/components/new_channel.jsx
+++ b/web/react/components/new_channel.jsx
@@ -107,6 +107,11 @@ module.exports = React.createClass({
serverError = <div className='form-group has-error'><label className='control-label'>{this.state.serverError}</label></div>;
}
+ var channelTerm = 'Channel';
+ if (this.state.channelType === 'P') {
+ channelTerm = 'Group';
+ }
+
return (
<div className='modal fade' id='new_channel' ref='modal' tabIndex='-1' role='dialog' aria-hidden='true'>
<div className='modal-dialog'>
@@ -116,7 +121,7 @@ module.exports = React.createClass({
<span aria-hidden='true'>&times;</span>
<span className='sr-only'>Cancel</span>
</button>
- <h4 className='modal-title'>New Channel</h4>
+ <h4 className='modal-title'>New {channelTerm}</h4>
</div>
<form role='form'>
<div className='modal-body'>
diff --git a/web/react/components/post_list.jsx b/web/react/components/post_list.jsx
index 3f59d5843..bb1b1704c 100644
--- a/web/react/components/post_list.jsx
+++ b/web/react/components/post_list.jsx
@@ -37,15 +37,23 @@ module.exports = React.createClass({
componentDidMount: function() {
var user = UserStore.getCurrentUser();
if (user.props && user.props.theme) {
- utils.changeCss('a.theme', 'color:'+user.props.theme+'; fill:'+user.props.theme+'!important;');
utils.changeCss('div.theme', 'background-color:'+user.props.theme+';');
utils.changeCss('.btn.btn-primary', 'background: ' + user.props.theme+';');
- utils.changeCss('.btn.btn-primary:hover, .btn.btn-primary:active, .btn.btn-primary:focus', 'background: ' + utils.changeColor(user.props.theme, -10) +';');
utils.changeCss('.modal .modal-header', 'background: ' + user.props.theme+';');
utils.changeCss('.mention', 'background: ' + user.props.theme+';');
utils.changeCss('.mention-link', 'color: ' + user.props.theme+';');
utils.changeCss('@media(max-width: 768px){.search-bar__container', 'background: ' + user.props.theme+';}');
}
+ if (user.props.theme != '#000000' && user.props.theme != '#585858') {
+ utils.changeCss('.btn.btn-primary:hover, .btn.btn-primary:active, .btn.btn-primary:focus', 'background: ' + utils.changeColor(user.props.theme, -10) +';');
+ utils.changeCss('a.theme', 'color:'+user.props.theme+'; fill:'+user.props.theme+'!important;');
+ } else if (user.props.theme == '#000000') {
+ utils.changeCss('.btn.btn-primary:hover, .btn.btn-primary:active, .btn.btn-primary:focus', 'background: ' + utils.changeColor(user.props.theme, +50) +';');
+ $('.team__header').addClass('theme--black');
+ } else if (user.props.theme == '#585858') {
+ utils.changeCss('.btn.btn-primary:hover, .btn.btn-primary:active, .btn.btn-primary:focus', 'background: ' + utils.changeColor(user.props.theme, +10) +';');
+ $('.team__header').addClass('theme--gray');
+ }
PostStore.addChangeListener(this._onChange);
ChannelStore.addChangeListener(this._onChange);
@@ -311,7 +319,6 @@ module.exports = React.createClass({
} else if (channel.type === 'D') {
var teammate = utils.getDirectTeammate(channel.id)
-
if (teammate) {
var teammate_name = teammate.nickname.length > 0 ? teammate.nickname : teammate.username;
more_messages = (
@@ -399,7 +406,7 @@ module.exports = React.createClass({
var postCtls = [];
if (posts) {
- var previousPostDay = posts[order[order.length-1]] ? utils.getDateForUnixTicks(posts[order[order.length-1]].create_at): new Date();
+ var previousPostDay = new Date(0);
var currentPostDay;
for (var i = order.length-1; i >= 0; i--) {
diff --git a/web/react/components/setting_picture.jsx b/web/react/components/setting_picture.jsx
index fa4c8bb62..e97b67706 100644
--- a/web/react/components/setting_picture.jsx
+++ b/web/react/components/setting_picture.jsx
@@ -20,8 +20,14 @@ module.exports = React.createClass({
}
},
render: function() {
- var client_error = this.props.client_error ? <div className='form-group has-error'><label className='control-label'>{ this.props.client_error }</label></div> : null;
- var server_error = this.props.server_error ? <div className='form-group has-error'><label className='control-label'>{ this.props.server_error }</label></div> : null;
+ var clientError = null;
+ if (this.props.client_error) {
+ clientError = <div className='form-group has-error'><label className='control-label'>{this.props.client_error}</label></div>;
+ }
+ var serverError = null;
+ if (this.props.server_error) {
+ serverError = <div className='form-group has-error'><label className='control-label'>{this.props.server_error}</label></div>;
+ }
var img = null;
if (this.props.picture) {
@@ -30,8 +36,20 @@ module.exports = React.createClass({
img = (<img ref='image' className='profile-img' src={this.props.src}/>);
}
- var self = this;
+ var confirmButton;
+ if (this.props.loadingPicture) {
+ confirmButton = <img className='spinner' src='/static/images/load.gif'/>;
+ } else {
+ var confirmButtonClass = 'btn btn-sm';
+ if (this.props.submitActive) {
+ confirmButtonClass += ' btn-primary';
+ } else {
+ confirmButtonClass += ' btn-inactive disabled';
+ }
+ confirmButton = <a className={confirmButtonClass} onClick={this.props.submit}>Save</a>;
+ }
+ var self = this;
return (
<ul className='section-max'>
<li className='col-xs-12 section-title'>{this.props.title}</li>
@@ -41,10 +59,10 @@ module.exports = React.createClass({
{img}
</li>
<li className='setting-list-item'>
- {server_error}
- {client_error}
+ {serverError}
+ {clientError}
<span className='btn btn-sm btn-primary btn-file sel-btn'>Select<input ref='input' accept='.jpg,.png,.bmp' type='file' onChange={this.props.pictureChange}/></span>
- <a className={this.props.submitActive ? 'btn btn-sm btn-primary' : 'btn btn-sm btn-inactive disabled'} onClick={this.props.submit}>Save</a>
+ {confirmButton}
<a className='btn btn-sm theme' href='#' onClick={self.props.updateSection}>Cancel</a>
</li>
</ul>
diff --git a/web/react/components/sidebar_header.jsx b/web/react/components/sidebar_header.jsx
index e01ddcd05..ba8f9bacd 100644
--- a/web/react/components/sidebar_header.jsx
+++ b/web/react/components/sidebar_header.jsx
@@ -1,15 +1,15 @@
// Copyright (c) 2015 Spinpunch, Inc. All Rights Reserved.
// See License.txt for license information.
-
var utils = require('../utils/utils.jsx');
var client = require('../utils/client.jsx');
var UserStore = require('../stores/user_store.jsx');
+var TeamStore = require('../stores/team_store.jsx');
var Constants = require('../utils/constants.jsx');
function getStateFromStores() {
- return { teams: UserStore.getTeams() };
+ return {teams: UserStore.getTeams(), currentTeam: TeamStore.getCurrent()};
}
var NavbarDropdown = React.createClass({
@@ -19,20 +19,24 @@ var NavbarDropdown = React.createClass({
},
blockToggle: false,
componentDidMount: function() {
- UserStore.addTeamsChangeListener(this._onChange);
+ UserStore.addTeamsChangeListener(this.onListenerChange);
+ TeamStore.addChangeListener(this.onListenerChange);
var self = this;
- $(this.refs.dropdown.getDOMNode()).on('hide.bs.dropdown', function(e) {
+ $(this.refs.dropdown.getDOMNode()).on('hide.bs.dropdown', function() {
self.blockToggle = true;
- setTimeout(function(){self.blockToggle = false;}, 100);
+ setTimeout(function() {
+ self.blockToggle = false;
+ }, 100);
});
},
componentWillUnmount: function() {
- UserStore.removeTeamsChangeListener(this._onChange);
+ UserStore.removeTeamsChangeListener(this.onListenerChange);
+ TeamStore.removeChangeListener(this.onListenerChange);
$(this.refs.dropdown.getDOMNode()).off('hide.bs.dropdown');
},
- _onChange: function() {
+ onListenerChange: function() {
if (this.isMounted()) {
var newState = getStateFromStores();
if (!utils.areStatesEqual(newState, this.state)) {
@@ -44,62 +48,65 @@ var NavbarDropdown = React.createClass({
return getStateFromStores();
},
render: function() {
- var team_link = "";
- var invite_link = "";
- var manage_link = "";
- var rename_link = "";
+ var teamLink = '';
+ var inviteLink = '';
+ var manageLink = '';
+ var renameLink = '';
var currentUser = UserStore.getCurrentUser();
var isAdmin = false;
+ var teamSettings = null;
if (currentUser != null) {
- isAdmin = currentUser.roles.indexOf("admin") > -1;
+ isAdmin = currentUser.roles.indexOf('admin') > -1;
- invite_link = ( <li> <a href="#" data-toggle="modal" data-target="#invite_member">Invite New Member</a> </li>);
+ inviteLink = (<li> <a href='#' data-toggle='modal' data-target='#invite_member'>Invite New Member</a> </li>);
- if (this.props.teamType == "O") {
- team_link = (
+ if (this.props.teamType === 'O') {
+ teamLink = (
<li>
- <a href="#" data-toggle="modal" data-target="#get_link" data-title="Team Invite" data-value={location.origin+"/signup_user_complete/?id="+currentUser.team_id}>Get Team Invite Link</a>
+ <a href='#' data-toggle='modal' data-target='#get_link' data-title='Team Invite' data-value={location.origin + '/signup_user_complete/?id=' + currentUser.team_id}>Get Team Invite Link</a>
</li>
);
}
}
if (isAdmin) {
- manage_link = ( <li> <a href="#" data-toggle="modal" data-target="#team_members">Manage Team</a> </li>);
- rename_link = ( <li> <a href="#" data-toggle="modal" data-target="#rename_team_link">Rename</a> </li>);
+ manageLink = (<li> <a href='#' data-toggle='modal' data-target='#team_members'>Manage Team</a> </li>);
+ renameLink = (<li> <a href='#' data-toggle='modal' data-target='#rename_team_link'>Rename</a> </li>);
+ teamSettings = (<li> <a href='#' data-toggle='modal' data-target='#team_settings'>Team Settings</a> </li>);
}
var teams = [];
- teams.push(<li className="divider" key="div"></li>);
- if (this.state.teams.length > 1) {
- for (var i = 0; i < this.state.teams.length; i++) {
- var teamName = this.state.teams[i];
-
- teams.push(<li key={ teamName }><a href={utils.getWindowLocationOrigin() + "/" + teamName }>Switch to { teamName }</a></li>);
- }
+ teams.push(<li className='divider' key='div'></li>);
+ if (this.state.teams.length > 1 && this.state.currentTeam) {
+ var curTeamName = this.state.currentTeam.name;
+ this.state.teams.forEach(function(teamName) {
+ if (teamName !== curTeamName) {
+ teams.push(<li key={teamName}><a href={utils.getWindowLocationOrigin() + '/' + teamName}>Switch to {teamName}</a></li>);
+ }
+ });
}
- teams.push(<li><a href={utils.getWindowLocationOrigin() + "/signup_team" }>Create a New Team</a></li>);
+ teams.push(<li><a href={utils.getWindowLocationOrigin() + '/signup_team'}>Create a New Team</a></li>);
return (
- <ul className="nav navbar-nav navbar-right">
- <li ref="dropdown" className="dropdown">
- <a href="#" className="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">
- <span className="dropdown__icon" dangerouslySetInnerHTML={{__html: Constants.MENU_ICON }} />
+ <ul className='nav navbar-nav navbar-right'>
+ <li ref='dropdown' className='dropdown'>
+ <a href='#' className='dropdown-toggle' data-toggle='dropdown' role='button' aria-expanded='false'>
+ <span className='dropdown__icon' dangerouslySetInnerHTML={{__html: Constants.MENU_ICON}} />
</a>
- <ul className="dropdown-menu" role="menu">
- <li><a href="#" data-toggle="modal" data-target="#user_settings1">Account Settings</a></li>
- { isAdmin ? <li><a href="#" data-toggle="modal" data-target="#team_settings">Team Settings</a></li> : null }
- { invite_link }
- { team_link }
- { manage_link }
- { rename_link }
- <li><a href="#" onClick={this.handleLogoutClick}>Logout</a></li>
- { teams }
- <li className="divider"></li>
- <li><a target="_blank" href={config.HelpLink}>Help</a></li>
- <li><a target="_blank" href={config.ReportProblemLink}>Report a Problem</a></li>
+ <ul className='dropdown-menu' role='menu'>
+ <li><a href='#' data-toggle='modal' data-target='#user_settings1'>Account Settings</a></li>
+ {teamSettings}
+ {inviteLink}
+ {teamLink}
+ {manageLink}
+ {renameLink}
+ <li><a href='#' onClick={this.handleLogoutClick}>Logout</a></li>
+ {teams}
+ <li className='divider'></li>
+ <li><a target='_blank' href={config.HelpLink}>Help</a></li>
+ <li><a target='_blank' href={config.ReportProblemLink}>Report a Problem</a></li>
</ul>
</li>
</ul>
@@ -109,14 +116,13 @@ var NavbarDropdown = React.createClass({
module.exports = React.createClass({
displayName: 'SidebarHeader',
-
getDefaultProps: function() {
return {
teamDisplayName: config.SiteName
};
},
- toggleDropdown: function(e) {
+ toggleDropdown: function() {
if (this.refs.dropdown.blockToggle) {
this.refs.dropdown.blockToggle = false;
return;
@@ -126,25 +132,26 @@ module.exports = React.createClass({
render: function() {
var me = UserStore.getCurrentUser();
+ var profilePicture = null;
if (!me) {
return null;
}
+ if (me.last_picture_update) {
+ profilePicture = (<img className='user__picture' src={'/api/v1/users/' + me.id + '/image?time=' + me.update_at} />);
+ }
+
return (
- <div className="team__header theme">
- <a href="#" onClick={this.toggleDropdown}>
- { me.last_picture_update ?
- <img className="user__picture" src={"/api/v1/users/" + me.id + "/image?time=" + me.update_at} />
- :
- null
- }
- <div className="header__info">
- <div className="user__name">{ '@' + me.username}</div>
- <div className="team__name">{ this.props.teamDisplayName }</div>
+ <div className='team__header theme'>
+ <a href='#' onClick={this.toggleDropdown}>
+ {profilePicture}
+ <div className='header__info'>
+ <div className='user__name'>{'@' + me.username}</div>
+ <div className='team__name'>{this.props.teamDisplayName }</div>
</div>
</a>
- <NavbarDropdown ref="dropdown" teamType={this.props.teamType} />
+ <NavbarDropdown ref='dropdown' teamType={this.props.teamType} />
</div>
);
}
diff --git a/web/react/components/user_profile.jsx b/web/react/components/user_profile.jsx
index 65f025919..5c4d26a23 100644
--- a/web/react/components/user_profile.jsx
+++ b/web/react/components/user_profile.jsx
@@ -28,6 +28,7 @@ module.exports = React.createClass({
componentDidMount: function() {
UserStore.addChangeListener(this._onChange);
$("#profile_" + this.uniqueId).popover({placement : 'right', container: 'body', trigger: 'hover', html: true, delay: { "show": 200, "hide": 100 }});
+ $('body').tooltip( {selector: '[data-toggle=tooltip]', trigger: 'hover click'} );
},
componentWillUnmount: function() {
UserStore.removeChangeListener(this._onChange);
@@ -57,7 +58,7 @@ module.exports = React.createClass({
if (!config.ShowEmail) {
data_content += "<div class='text-nowrap'>Email not shared</div>";
} else {
- data_content += "<div><a href='mailto:" + this.state.profile.email + "' class='text-nowrap text-lowercase'>" + this.state.profile.email + "</a></div>";
+ data_content += "<div data-toggle='tooltip' title= '" + this.state.profile.email + "'><a href='mailto:" + this.state.profile.email + "' class='text-nowrap text-lowercase user-popover__email'>" + this.state.profile.email + "</a></div>";
}
return (
diff --git a/web/react/components/user_settings.jsx b/web/react/components/user_settings.jsx
index c574d2365..e224f2a87 100644
--- a/web/react/components/user_settings.jsx
+++ b/web/react/components/user_settings.jsx
@@ -5,8 +5,6 @@ var UserStore = require('../stores/user_store.jsx');
var SettingItemMin = require('./setting_item_min.jsx');
var SettingItemMax = require('./setting_item_max.jsx');
var SettingPicture = require('./setting_picture.jsx');
-var AccessHistoryModal = require('./access_history_modal.jsx');
-var ActivityLogModal = require('./activity_log_modal.jsx');
var client = require('../utils/client.jsx');
var AsyncClient = require('../utils/async_client.jsx');
var utils = require('../utils/utils.jsx');
@@ -642,17 +640,17 @@ var GeneralTab = React.createClass({
var user = this.props.user;
var username = this.state.username.trim();
- var username_error = utils.isValidUsername(username);
- if (username_error === 'Cannot use a reserved word as a username.') {
- this.setState({client_error: 'This username is reserved, please choose a new one.' });
+ var usernameError = utils.isValidUsername(username);
+ if (usernameError === 'Cannot use a reserved word as a username.') {
+ this.setState({clientError: 'This username is reserved, please choose a new one.'});
return;
- } else if (username_error) {
- this.setState({client_error: "Username must begin with a letter, and contain between 3 to 15 lowercase characters made up of numbers, letters, and the symbols '.', '-' and '_'." });
+ } else if (usernameError) {
+ this.setState({clientError: "Username must begin with a letter, and contain between 3 to 15 lowercase characters made up of numbers, letters, and the symbols '.', '-' and '_'."});
return;
}
if (user.username === username) {
- this.setState({client_error: 'You must submit a new username'});
+ this.setState({clientError: 'You must submit a new username'});
return;
}
@@ -667,7 +665,7 @@ var GeneralTab = React.createClass({
var nickname = this.state.nickname.trim();
if (user.nickname === nickname) {
- this.setState({client_error: 'You must submit a new nickname'})
+ this.setState({clientError: 'You must submit a new nickname'});
return;
}
@@ -679,11 +677,11 @@ var GeneralTab = React.createClass({
e.preventDefault();
var user = UserStore.getCurrentUser();
- var firstName = this.state.first_name.trim();
- var lastName = this.state.last_name.trim();
+ var firstName = this.state.firstName.trim();
+ var lastName = this.state.lastName.trim();
if (user.first_name === firstName && user.last_name === lastName) {
- this.setState({client_error: 'You must submit a new first or last name'})
+ this.setState({clientError: 'You must submit a new first or last name'});
return;
}
@@ -703,7 +701,7 @@ var GeneralTab = React.createClass({
}
if (email === '' || !utils.isEmail(email)) {
- this.setState({ email_error: 'Please enter a valid email address' });
+ this.setState({emailError: 'Please enter a valid email address'});
return;
}
@@ -718,11 +716,11 @@ var GeneralTab = React.createClass({
AsyncClient.getMe();
}.bind(this),
function(err) {
- state = this.getInitialState();
+ var state = this.getInitialState();
if (err.message) {
- state.server_error = err.message;
+ state.serverError = err.message;
} else {
- state.server_error = err;
+ state.serverError = err;
}
this.setState(state);
}.bind(this)
@@ -742,12 +740,13 @@ var GeneralTab = React.createClass({
var picture = this.state.picture;
if (picture.type !== 'image/jpeg' && picture.type !== 'image/png') {
- this.setState({client_error: 'Only JPG or PNG images may be used for profile pictures'});
+ this.setState({clientError: 'Only JPG or PNG images may be used for profile pictures'});
return;
}
var formData = new FormData();
formData.append('image', picture, picture.name);
+ this.setState({loadingPicture: true});
client.uploadProfileImage(formData,
function() {
@@ -756,8 +755,8 @@ var GeneralTab = React.createClass({
window.location.reload();
}.bind(this),
function(err) {
- state = this.getInitialState();
- state.server_error = err;
+ var state = this.getInitialState();
+ state.serverError = err;
this.setState(state);
}.bind(this)
);
@@ -766,10 +765,10 @@ var GeneralTab = React.createClass({
this.setState({username: e.target.value});
},
updateFirstName: function(e) {
- this.setState({first_name: e.target.value});
+ this.setState({firstName: e.target.value});
},
updateLastName: function(e) {
- this.setState({last_name: e.target.value});
+ this.setState({lastName: e.target.value});
},
updateNickname: function(e) {
this.setState({nickname: e.target.value});
@@ -779,17 +778,16 @@ var GeneralTab = React.createClass({
},
updatePicture: function(e) {
if (e.target.files && e.target.files[0]) {
- this.setState({ picture: e.target.files[0] });
+ this.setState({picture: e.target.files[0]});
this.submitActive = true;
- this.setState({client_error: null});
-
+ this.setState({clientError: null});
} else {
this.setState({picture: null});
}
},
updateSection: function(section) {
- this.setState({client_error:''});
+ this.setState({clientError: ''});
this.submitActive = false;
this.props.updateSection(section);
},
@@ -798,7 +796,7 @@ var GeneralTab = React.createClass({
this.value = '';
});
- this.setState(assign({}, this.getInitialState(), {client_error: null, server_error: null, email_error: null}));
+ this.setState(assign({}, this.getInitialState(), {clientError: null, serverError: null, emailError: null}));
this.props.updateSection('');
},
componentDidMount: function() {
@@ -810,15 +808,24 @@ var GeneralTab = React.createClass({
getInitialState: function() {
var user = this.props.user;
- return { username: user.username, first_name: user.first_name, last_name: user.last_name, nickname: user.nickname,
- email: user.email, picture: null };
+ return {username: user.username, firstName: user.first_name, lastName: user.last_name, nickname: user.nickname,
+ email: user.email, picture: null, loadingPicture: false};
},
render: function() {
var user = this.props.user;
- var client_error = this.state.client_error ? this.state.client_error : null;
- var server_error = this.state.server_error ? this.state.server_error : null;
- var email_error = this.state.email_error ? this.state.email_error : null;
+ var clientError = null;
+ if (this.state.clientError) {
+ clientError = this.state.clientError;
+ }
+ var serverError = null;
+ if (this.state.serverError) {
+ serverError = this.state.serverError;
+ }
+ var emailError = null;
+ if (this.state.emailError) {
+ emailError = this.state.emailError;
+ }
var nameSection;
var self = this;
@@ -829,7 +836,7 @@ var GeneralTab = React.createClass({
<div className='form-group'>
<label className='col-sm-5 control-label'>First Name</label>
<div className='col-sm-7'>
- <input className='form-control' type='text' onChange={this.updateFirstName} value={this.state.first_name}/>
+ <input className='form-control' type='text' onChange={this.updateFirstName} value={this.state.firstName}/>
</div>
</div>
);
@@ -838,7 +845,7 @@ var GeneralTab = React.createClass({
<div className='form-group'>
<label className='col-sm-5 control-label'>Last Name</label>
<div className='col-sm-7'>
- <input className='form-control' type='text' onChange={this.updateLastName} value={this.state.last_name}/>
+ <input className='form-control' type='text' onChange={this.updateLastName} value={this.state.lastName}/>
</div>
</div>
);
@@ -848,8 +855,8 @@ var GeneralTab = React.createClass({
title='Full Name'
inputs={inputs}
submit={this.submitName}
- server_error={server_error}
- client_error={client_error}
+ server_error={serverError}
+ client_error={clientError}
updateSection={function(e) {
self.updateSection('');
e.preventDefault();
@@ -857,20 +864,20 @@ var GeneralTab = React.createClass({
/>
);
} else {
- var full_name = '';
+ var fullName = '';
if (user.first_name && user.last_name) {
- full_name = user.first_name + ' ' + user.last_name;
+ fullName = user.first_name + ' ' + user.last_name;
} else if (user.first_name) {
- full_name = user.first_name;
+ fullName = user.first_name;
} else if (user.last_name) {
- full_name = user.last_name;
+ fullName = user.last_name;
}
nameSection = (
<SettingItemMin
title='Full Name'
- describe={full_name}
+ describe={fullName}
updateSection={function() {
self.updateSection('name');
}}
@@ -880,7 +887,6 @@ var GeneralTab = React.createClass({
var nicknameSection;
if (this.props.activeSection === 'nickname') {
-
inputs.push(
<div className='form-group'>
<label className='col-sm-5 control-label'>{utils.isMobile() ? '' : 'Nickname'}</label>
@@ -895,8 +901,8 @@ var GeneralTab = React.createClass({
title='Nickname'
inputs={inputs}
submit={this.submitNickname}
- server_error={server_error}
- client_error={client_error}
+ server_error={serverError}
+ client_error={clientError}
updateSection={function(e) {
self.updateSection('');
e.preventDefault();
@@ -919,7 +925,7 @@ var GeneralTab = React.createClass({
if (this.props.activeSection === 'username') {
inputs.push(
<div className='form-group'>
- <label className='col-sm-5 control-label'>{utils.isMobile() ? '': 'Username'}</label>
+ <label className='col-sm-5 control-label'>{utils.isMobile() ? '' : 'Username'}</label>
<div className='col-sm-7'>
<input className='form-control' type='text' onChange={this.updateUsername} value={this.state.username}/>
</div>
@@ -931,8 +937,8 @@ var GeneralTab = React.createClass({
title='Username'
inputs={inputs}
submit={this.submitUsername}
- server_error={server_error}
- client_error={client_error}
+ server_error={serverError}
+ client_error={clientError}
updateSection={function(e) {
self.updateSection('');
e.preventDefault();
@@ -966,8 +972,8 @@ var GeneralTab = React.createClass({
title='Email'
inputs={inputs}
submit={this.submitEmail}
- server_error={server_error}
- client_error={email_error}
+ server_error={serverError}
+ client_error={emailError}
updateSection={function(e) {
self.updateSection('');
e.preventDefault();
@@ -993,8 +999,8 @@ var GeneralTab = React.createClass({
title='Profile Picture'
submit={this.submitPicture}
src={'/api/v1/users/' + user.id + '/image?time=' + user.last_picture_update}
- server_error={server_error}
- client_error={client_error}
+ server_error={serverError}
+ client_error={clientError}
updateSection={function(e) {
self.updateSection('');
e.preventDefault();
@@ -1002,6 +1008,7 @@ var GeneralTab = React.createClass({
picture={this.state.picture}
pictureChange={this.updatePicture}
submitActive={this.submitActive}
+ loadingPicture={this.state.loadingPicture}
/>
);
} else {
diff --git a/web/react/utils/constants.jsx b/web/react/utils/constants.jsx
index 2b0976afd..bed0ec556 100644
--- a/web/react/utils/constants.jsx
+++ b/web/react/utils/constants.jsx
@@ -82,7 +82,7 @@ module.exports = {
"channel",
],
MONTHS: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
- MAX_DMS: 10,
+ MAX_DMS: 20,
ONLINE_ICON_SVG: "<svg version='1.1' id='Layer_1' xmlns:dc='http://purl.org/dc/elements/1.1/' xmlns:cc='http://creativecommons.org/ns#' xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#' xmlns:svg='http://www.w3.org/2000/svg' xmlns:sodipodi='http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd' xmlns:inkscape='http://www.inkscape.org/namespaces/inkscape' sodipodi:docname='TRASH_1_4.svg' inkscape:version='0.48.4 r9939' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' width='12px' height='12px' viewBox='0 0 12 12' enable-background='new 0 0 12 12' xml:space='preserve'><sodipodi:namedview inkscape:cy='139.7898' inkscape:cx='26.358185' inkscape:zoom='1.18' showguides='true' showgrid='false' id='namedview6' guidetolerance='10' gridtolerance='10' objecttolerance='10' borderopacity='1' bordercolor='#666666' pagecolor='#ffffff' inkscape:current-layer='Layer_1' inkscape:window-maximized='1' inkscape:window-y='-8' inkscape:window-x='-8' inkscape:window-height='705' inkscape:window-width='1366' inkscape:guide-bbox='true' inkscape:pageshadow='2' inkscape:pageopacity='0'><sodipodi:guide position='50.036793,85.991376' orientation='1,0' id='guide2986'></sodipodi:guide><sodipodi:guide position='58.426196,66.216355' orientation='0,1' id='guide3047'></sodipodi:guide></sodipodi:namedview><g><g><path class='online--icon' d='M6,5.487c1.371,0,2.482-1.116,2.482-2.493c0-1.378-1.111-2.495-2.482-2.495S3.518,1.616,3.518,2.994C3.518,4.371,4.629,5.487,6,5.487z M10.452,8.545c-0.101-0.829-0.36-1.968-0.726-2.541C9.475,5.606,8.5,5.5,8.5,5.5S8.43,7.521,6,7.521C3.507,7.521,3.5,5.5,3.5,5.5S2.527,5.606,2.273,6.004C1.908,6.577,1.648,7.716,1.547,8.545C1.521,8.688,1.49,9.082,1.498,9.142c0.161,1.295,2.238,2.322,4.375,2.358C5.916,11.501,5.958,11.501,6,11.501c0.043,0,0.084,0,0.127-0.001c2.076-0.026,4.214-1.063,4.375-2.358C10.509,9.082,10.471,8.696,10.452,8.545z'/></g></g></svg>",
OFFLINE_ICON_SVG: "<svg version='1.1' id='Layer_1' xmlns:dc='http://purl.org/dc/elements/1.1/' xmlns:cc='http://creativecommons.org/ns#' xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#' xmlns:svg='http://www.w3.org/2000/svg' xmlns:sodipodi='http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd' xmlns:inkscape='http://www.inkscape.org/namespaces/inkscape' sodipodi:docname='TRASH_1_4.svg' inkscape:version='0.48.4 r9939' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' width='12px' height='12px' viewBox='0 0 12 12' enable-background='new 0 0 12 12' xml:space='preserve'><sodipodi:namedview inkscape:cy='139.7898' inkscape:cx='26.358185' inkscape:zoom='1.18' showguides='true' showgrid='false' id='namedview6' guidetolerance='10' gridtolerance='10' objecttolerance='10' borderopacity='1' bordercolor='#666666' pagecolor='#ffffff' inkscape:current-layer='Layer_1' inkscape:window-maximized='1' inkscape:window-y='-8' inkscape:window-x='-8' inkscape:window-height='705' inkscape:window-width='1366' inkscape:guide-bbox='true' inkscape:pageshadow='2' inkscape:pageopacity='0'><sodipodi:guide position='50.036793,85.991376' orientation='1,0' id='guide2986'></sodipodi:guide><sodipodi:guide position='58.426196,66.216355' orientation='0,1' id='guide3047'></sodipodi:guide></sodipodi:namedview><g><g><path fill='#cccccc' d='M6.002,7.143C5.645,7.363,5.167,7.52,4.502,7.52c-2.493,0-2.5-2.02-2.5-2.02S1.029,5.607,0.775,6.004C0.41,6.577,0.15,7.716,0.049,8.545c-0.025,0.145-0.057,0.537-0.05,0.598c0.162,1.295,2.237,2.321,4.375,2.357c0.043,0.001,0.085,0.001,0.127,0.001c0.043,0,0.084,0,0.127-0.001c1.879-0.023,3.793-0.879,4.263-2h-2.89L6.002,7.143L6.002,7.143z M4.501,5.488c1.372,0,2.483-1.117,2.483-2.494c0-1.378-1.111-2.495-2.483-2.495c-1.371,0-2.481,1.117-2.481,2.495C2.02,4.371,3.13,5.488,4.501,5.488z M7.002,6.5v2h5v-2H7.002z'/></g></g></svg>",
MENU_ICON: "<svg version='1.1' id='Layer_1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px'width='4px' height='16px' viewBox='0 0 8 32' enable-background='new 0 0 8 32' xml:space='preserve'> <g> <circle cx='4' cy='4.062' r='4'/> <circle cx='4' cy='16' r='4'/> <circle cx='4' cy='28' r='4'/> </g> </svg>",