Merge pull request #324 from rgarmsen2295/mm-1617

MM-1617 Now shows a loading gif while a profile pic is being uploaded
Этот коммит содержится в:
Christopher Speller
2015-08-06 10:21:51 -04:00
родитель 201d165ed9 3cd0c3b73b
Коммит cc78cc9bac
2 изменённых файлов: 81 добавлений и 56 удалений

Просмотреть файл

@@ -20,8 +20,14 @@ module.exports = React.createClass({
} }
}, },
render: function() { 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 clientError = 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; 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; var img = null;
if (this.props.picture) { if (this.props.picture) {
@@ -30,8 +36,20 @@ module.exports = React.createClass({
img = (<img ref='image' className='profile-img' src={this.props.src}/>); 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 ( return (
<ul className='section-max'> <ul className='section-max'>
<li className='col-xs-12 section-title'>{this.props.title}</li> <li className='col-xs-12 section-title'>{this.props.title}</li>
@@ -41,10 +59,10 @@ module.exports = React.createClass({
{img} {img}
</li> </li>
<li className='setting-list-item'> <li className='setting-list-item'>
{server_error} {serverError}
{client_error} {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> <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> <a className='btn btn-sm theme' href='#' onClick={self.props.updateSection}>Cancel</a>
</li> </li>
</ul> </ul>

Просмотреть файл

@@ -5,8 +5,6 @@ var UserStore = require('../stores/user_store.jsx');
var SettingItemMin = require('./setting_item_min.jsx'); var SettingItemMin = require('./setting_item_min.jsx');
var SettingItemMax = require('./setting_item_max.jsx'); var SettingItemMax = require('./setting_item_max.jsx');
var SettingPicture = require('./setting_picture.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 client = require('../utils/client.jsx');
var AsyncClient = require('../utils/async_client.jsx'); var AsyncClient = require('../utils/async_client.jsx');
var utils = require('../utils/utils.jsx'); var utils = require('../utils/utils.jsx');
@@ -642,17 +640,17 @@ var GeneralTab = React.createClass({
var user = this.props.user; var user = this.props.user;
var username = this.state.username.trim(); var username = this.state.username.trim();
var username_error = utils.isValidUsername(username); var usernameError = utils.isValidUsername(username);
if (username_error === 'Cannot use a reserved word as a username.') { if (usernameError === 'Cannot use a reserved word as a username.') {
this.setState({client_error: 'This username is reserved, please choose a new one.' }); this.setState({clientError: 'This username is reserved, please choose a new one.'});
return; return;
} else if (username_error) { } else if (usernameError) {
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 '_'." }); 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; return;
} }
if (user.username === username) { if (user.username === username) {
this.setState({client_error: 'You must submit a new username'}); this.setState({clientError: 'You must submit a new username'});
return; return;
} }
@@ -667,7 +665,7 @@ var GeneralTab = React.createClass({
var nickname = this.state.nickname.trim(); var nickname = this.state.nickname.trim();
if (user.nickname === nickname) { if (user.nickname === nickname) {
this.setState({client_error: 'You must submit a new nickname'}) this.setState({clientError: 'You must submit a new nickname'});
return; return;
} }
@@ -679,11 +677,11 @@ var GeneralTab = React.createClass({
e.preventDefault(); e.preventDefault();
var user = UserStore.getCurrentUser(); var user = UserStore.getCurrentUser();
var firstName = this.state.first_name.trim(); var firstName = this.state.firstName.trim();
var lastName = this.state.last_name.trim(); var lastName = this.state.lastName.trim();
if (user.first_name === firstName && user.last_name === lastName) { 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; return;
} }
@@ -703,7 +701,7 @@ var GeneralTab = React.createClass({
} }
if (email === '' || !utils.isEmail(email)) { 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; return;
} }
@@ -718,11 +716,11 @@ var GeneralTab = React.createClass({
AsyncClient.getMe(); AsyncClient.getMe();
}.bind(this), }.bind(this),
function(err) { function(err) {
state = this.getInitialState(); var state = this.getInitialState();
if (err.message) { if (err.message) {
state.server_error = err.message; state.serverError = err.message;
} else { } else {
state.server_error = err; state.serverError = err;
} }
this.setState(state); this.setState(state);
}.bind(this) }.bind(this)
@@ -742,12 +740,13 @@ var GeneralTab = React.createClass({
var picture = this.state.picture; var picture = this.state.picture;
if (picture.type !== 'image/jpeg' && picture.type !== 'image/png') { 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; return;
} }
var formData = new FormData(); var formData = new FormData();
formData.append('image', picture, picture.name); formData.append('image', picture, picture.name);
this.setState({loadingPicture: true});
client.uploadProfileImage(formData, client.uploadProfileImage(formData,
function() { function() {
@@ -756,8 +755,8 @@ var GeneralTab = React.createClass({
window.location.reload(); window.location.reload();
}.bind(this), }.bind(this),
function(err) { function(err) {
state = this.getInitialState(); var state = this.getInitialState();
state.server_error = err; state.serverError = err;
this.setState(state); this.setState(state);
}.bind(this) }.bind(this)
); );
@@ -766,10 +765,10 @@ var GeneralTab = React.createClass({
this.setState({username: e.target.value}); this.setState({username: e.target.value});
}, },
updateFirstName: function(e) { updateFirstName: function(e) {
this.setState({first_name: e.target.value}); this.setState({firstName: e.target.value});
}, },
updateLastName: function(e) { updateLastName: function(e) {
this.setState({last_name: e.target.value}); this.setState({lastName: e.target.value});
}, },
updateNickname: function(e) { updateNickname: function(e) {
this.setState({nickname: e.target.value}); this.setState({nickname: e.target.value});
@@ -779,17 +778,16 @@ var GeneralTab = React.createClass({
}, },
updatePicture: function(e) { updatePicture: function(e) {
if (e.target.files && e.target.files[0]) { 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.submitActive = true;
this.setState({client_error: null}); this.setState({clientError: null});
} else { } else {
this.setState({picture: null}); this.setState({picture: null});
} }
}, },
updateSection: function(section) { updateSection: function(section) {
this.setState({client_error:''}); this.setState({clientError: ''});
this.submitActive = false; this.submitActive = false;
this.props.updateSection(section); this.props.updateSection(section);
}, },
@@ -798,7 +796,7 @@ var GeneralTab = React.createClass({
this.value = ''; 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(''); this.props.updateSection('');
}, },
componentDidMount: function() { componentDidMount: function() {
@@ -810,15 +808,24 @@ var GeneralTab = React.createClass({
getInitialState: function() { getInitialState: function() {
var user = this.props.user; var user = this.props.user;
return { username: user.username, first_name: user.first_name, last_name: user.last_name, nickname: user.nickname, return {username: user.username, firstName: user.first_name, lastName: user.last_name, nickname: user.nickname,
email: user.email, picture: null }; email: user.email, picture: null, loadingPicture: false};
}, },
render: function() { render: function() {
var user = this.props.user; var user = this.props.user;
var client_error = this.state.client_error ? this.state.client_error : null; var clientError = null;
var server_error = this.state.server_error ? this.state.server_error : null; if (this.state.clientError) {
var email_error = this.state.email_error ? this.state.email_error : null; 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 nameSection;
var self = this; var self = this;
@@ -829,7 +836,7 @@ var GeneralTab = React.createClass({
<div className='form-group'> <div className='form-group'>
<label className='col-sm-5 control-label'>First Name</label> <label className='col-sm-5 control-label'>First Name</label>
<div className='col-sm-7'> <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>
</div> </div>
); );
@@ -838,7 +845,7 @@ var GeneralTab = React.createClass({
<div className='form-group'> <div className='form-group'>
<label className='col-sm-5 control-label'>Last Name</label> <label className='col-sm-5 control-label'>Last Name</label>
<div className='col-sm-7'> <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>
</div> </div>
); );
@@ -848,8 +855,8 @@ var GeneralTab = React.createClass({
title='Full Name' title='Full Name'
inputs={inputs} inputs={inputs}
submit={this.submitName} submit={this.submitName}
server_error={server_error} server_error={serverError}
client_error={client_error} client_error={clientError}
updateSection={function(e) { updateSection={function(e) {
self.updateSection(''); self.updateSection('');
e.preventDefault(); e.preventDefault();
@@ -857,20 +864,20 @@ var GeneralTab = React.createClass({
/> />
); );
} else { } else {
var full_name = ''; var fullName = '';
if (user.first_name && user.last_name) { 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) { } else if (user.first_name) {
full_name = user.first_name; fullName = user.first_name;
} else if (user.last_name) { } else if (user.last_name) {
full_name = user.last_name; fullName = user.last_name;
} }
nameSection = ( nameSection = (
<SettingItemMin <SettingItemMin
title='Full Name' title='Full Name'
describe={full_name} describe={fullName}
updateSection={function() { updateSection={function() {
self.updateSection('name'); self.updateSection('name');
}} }}
@@ -880,7 +887,6 @@ var GeneralTab = React.createClass({
var nicknameSection; var nicknameSection;
if (this.props.activeSection === 'nickname') { if (this.props.activeSection === 'nickname') {
inputs.push( inputs.push(
<div className='form-group'> <div className='form-group'>
<label className='col-sm-5 control-label'>{utils.isMobile() ? '' : 'Nickname'}</label> <label className='col-sm-5 control-label'>{utils.isMobile() ? '' : 'Nickname'}</label>
@@ -895,8 +901,8 @@ var GeneralTab = React.createClass({
title='Nickname' title='Nickname'
inputs={inputs} inputs={inputs}
submit={this.submitNickname} submit={this.submitNickname}
server_error={server_error} server_error={serverError}
client_error={client_error} client_error={clientError}
updateSection={function(e) { updateSection={function(e) {
self.updateSection(''); self.updateSection('');
e.preventDefault(); e.preventDefault();
@@ -919,7 +925,7 @@ var GeneralTab = React.createClass({
if (this.props.activeSection === 'username') { if (this.props.activeSection === 'username') {
inputs.push( inputs.push(
<div className='form-group'> <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'> <div className='col-sm-7'>
<input className='form-control' type='text' onChange={this.updateUsername} value={this.state.username}/> <input className='form-control' type='text' onChange={this.updateUsername} value={this.state.username}/>
</div> </div>
@@ -931,8 +937,8 @@ var GeneralTab = React.createClass({
title='Username' title='Username'
inputs={inputs} inputs={inputs}
submit={this.submitUsername} submit={this.submitUsername}
server_error={server_error} server_error={serverError}
client_error={client_error} client_error={clientError}
updateSection={function(e) { updateSection={function(e) {
self.updateSection(''); self.updateSection('');
e.preventDefault(); e.preventDefault();
@@ -966,8 +972,8 @@ var GeneralTab = React.createClass({
title='Email' title='Email'
inputs={inputs} inputs={inputs}
submit={this.submitEmail} submit={this.submitEmail}
server_error={server_error} server_error={serverError}
client_error={email_error} client_error={emailError}
updateSection={function(e) { updateSection={function(e) {
self.updateSection(''); self.updateSection('');
e.preventDefault(); e.preventDefault();
@@ -993,8 +999,8 @@ var GeneralTab = React.createClass({
title='Profile Picture' title='Profile Picture'
submit={this.submitPicture} submit={this.submitPicture}
src={'/api/v1/users/' + user.id + '/image?time=' + user.last_picture_update} src={'/api/v1/users/' + user.id + '/image?time=' + user.last_picture_update}
server_error={server_error} server_error={serverError}
client_error={client_error} client_error={clientError}
updateSection={function(e) { updateSection={function(e) {
self.updateSection(''); self.updateSection('');
e.preventDefault(); e.preventDefault();
@@ -1002,6 +1008,7 @@ var GeneralTab = React.createClass({
picture={this.state.picture} picture={this.state.picture}
pictureChange={this.updatePicture} pictureChange={this.updatePicture}
submitActive={this.submitActive} submitActive={this.submitActive}
loadingPicture={this.state.loadingPicture}
/> />
); );
} else { } else {