Cosmetic reformatting of multiple jsx files

Этот коммит содержится в:
Reed Garmsen
2015-08-31 09:35:31 -07:00
родитель 5b81125e4d
Коммит e2a24f40b7
24 изменённых файлов: 1326 добавлений и 699 удалений

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

@@ -10,13 +10,18 @@ var SocketStore = require('../stores/socket_store.jsx');
var ChannelStore = require('../stores/channel_store.jsx');
var PostStore = require('../stores/post_store.jsx');
var UserStore = require('../stores/user_store.jsx');
var Constants = require('../utils/constants.jsx');
var utils = require('../utils/utils.jsx');
var Utils = require('../utils/utils.jsx');
module.exports = React.createClass({
componentDidMount: function() {
export default class ChannelLoader extends React.Component {
constructor(props) {
super(props);
this.onSocketChange = this.onSocketChange.bind(this);
this.state = {};
}
componentDidMount() {
/* Initial aysnc loads */
AsyncClient.getMe();
AsyncClient.getPosts(ChannelStore.getCurrentId());
@@ -60,32 +65,32 @@ module.exports = React.createClass({
var user = UserStore.getCurrentUser();
if (user.props && user.props.theme) {
utils.changeCss('div.theme', 'background-color:' + user.props.theme + ';');
utils.changeCss('.btn.btn-primary', 'background: ' + user.props.theme + ';');
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 + ';}');
utils.changeCss('.search-item-container:hover', 'background: ' + utils.changeOpacity(user.props.theme, 0.05) + ';');
Utils.changeCss('div.theme', 'background-color:' + user.props.theme + ';');
Utils.changeCss('.btn.btn-primary', 'background: ' + user.props.theme + ';');
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 + ';}');
Utils.changeCss('.search-item-container:hover', 'background: ' + Utils.changeOpacity(user.props.theme, 0.05) + ';');
}
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;');
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) + ';');
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) + ';');
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');
}
},
onSocketChange: function(msg) {
}
onSocketChange(msg) {
if (msg && msg.user_id && msg.user_id !== UserStore.getCurrentId()) {
UserStore.setStatus(msg.user_id, 'online');
}
},
render: function() {
}
render() {
return <div/>;
}
});
}

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

@@ -1,31 +1,70 @@
// Copyright (c) 2015 Spinpunch, Inc. All Rights Reserved.
// See License.txt for license information.
module.exports = React.createClass({
handleConfirm: function() {
$('#'+this.props.parent_id).attr('data-confirm', 'true');
$('#'+this.props.parent_id).modal('hide');
$('#'+this.props.id).modal('hide');
},
render: function() {
export default class ConfirmModal extends React.Component {
constructor(props) {
super(props);
this.handleConfirm = this.handleConfirm.bind(this);
this.state = {};
}
handleConfirm() {
$('#' + this.props.parent_id).attr('data-confirm', 'true');
$('#' + this.props.parent_id).modal('hide');
$('#' + this.props.id).modal('hide');
}
render() {
return (
<div className="modal fade" id={this.props.id} tabIndex="-1" role="dialog" aria-hidden="true">
<div className="modal-dialog">
<div className="modal-content">
<div className="modal-header">
<h4 className="modal-title">{this.props.title}</h4>
<div
className='modal fade'
id={this.props.id}
tabIndex='-1'
role='dialog'
aria-hidden='true'
>
<div className='modal-dialog'>
<div className='modal-content'>
<div className='modal-header'>
<h4 className='modal-title'>{this.props.title}</h4>
</div>
<div className='modal-body'>
{this.props.message}
</div>
<div className='modal-footer'>
<button
type='button'
className='btn btn-default'
data-dismiss='modal'
>
Cancel
</button>
<button
onClick={this.handleConfirm}
type='button'
className='btn btn-primary'
>
{this.props.confirm_button}
</button>
</div>
</div>
<div className="modal-body">
{this.props.message}
</div>
<div className="modal-footer">
<button type="button" className="btn btn-default" data-dismiss="modal">Cancel</button>
<button onClick={this.handleConfirm} type="button" className="btn btn-primary">{this.props.confirm_button}</button>
</div>
</div>
</div>
</div>
</div>
);
}
});
}
ConfirmModal.defaultProps = {
parent_id: '',
id: '',
title: '',
message: '',
confirm_button: ''
};
ConfirmModal.propTypes = {
parent_id: React.PropTypes.string,
id: React.PropTypes.string,
title: React.PropTypes.string,
message: React.PropTypes.string,
confirm_button: React.PropTypes.string
};

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

@@ -4,20 +4,28 @@
var Client = require('../utils/client.jsx');
var PostStore = require('../stores/post_store.jsx');
var BrowserStore = require('../stores/browser_store.jsx');
var utils = require('../utils/utils.jsx');
var Utils = require('../utils/utils.jsx');
var AsyncClient = require('../utils/async_client.jsx');
var AppDispatcher = require('../dispatcher/app_dispatcher.jsx');
var Constants = require('../utils/constants.jsx');
var ActionTypes = Constants.ActionTypes;
module.exports = React.createClass({
handleDelete: function(e) {
Client.deletePost(this.state.channel_id, this.state.post_id,
function(data) {
var selected_list = this.state.selectedList;
if (selected_list && selected_list.order && selected_list.order.length > 0) {
var selected_post = selected_list.posts[selected_list.order[0]];
if ((selected_post.id === this.state.post_id && this.state.title === "Post") || selected_post.root_id === this.state.post_id) {
export default class DeletePostModal extends React.Component {
constructor(props) {
super(props);
this.handleDelete = this.handleDelete.bind(this);
this.onListenerChange = this.onListenerChange.bind(this);
this.state = {title: '', postId: '', channelId: '', selectedList: PostStore.getSelectedPost(), comments: 0};
}
handleDelete() {
Client.deletePost(this.state.channelId, this.state.postId,
function deleteSuccess() {
var selectedList = this.state.selectedList;
if (selectedList && selectedList.order && selectedList.order.length > 0) {
var selectedPost = selectedList.posts[selectedList.order[0]];
if ((selectedPost.id === this.state.postId && this.state.title === 'Post') || selectedPost.root_id === this.state.postId) {
AppDispatcher.handleServerAction({
type: ActionTypes.RECIEVED_SEARCH,
results: null
@@ -27,14 +35,14 @@ module.exports = React.createClass({
type: ActionTypes.RECIEVED_POST_SELECTED,
results: null
});
} else if (selected_post.id === this.state.post_id && this.state.title === "Comment") {
if (selected_post.root_id && selected_post.root_id.length > 0 && selected_list.posts[selected_post.root_id]) {
selected_list.order = [selected_post.root_id];
delete selected_list.posts[selected_post.id];
} else if (selectedPost.id === this.state.postId && this.state.title === 'Comment') {
if (selectedPost.root_id && selectedPost.root_id.length > 0 && selectedList.posts[selectedPost.root_id]) {
selectedList.order = [selectedPost.root_id];
delete selectedList.posts[selectedPost.id];
AppDispatcher.handleServerAction({
type: ActionTypes.RECIEVED_POST_SELECTED,
post_list: selected_list
post_list: selectedList
});
AppDispatcher.handleServerAction({
@@ -44,67 +52,98 @@ module.exports = React.createClass({
}
}
}
PostStore.removePost(this.state.post_id, this.state.channel_id);
AsyncClient.getPosts(this.state.channel_id);
PostStore.removePost(this.state.postId, this.state.channelId);
AsyncClient.getPosts(this.state.channelId);
}.bind(this),
function(err) {
AsyncClient.dispatchError(err, "deletePost");
}.bind(this)
function deleteFailed(err) {
AsyncClient.dispatchError(err, 'deletePost');
}
);
},
componentDidMount: function() {
}
componentDidMount() {
var self = this;
$(this.refs.modal.getDOMNode()).on('show.bs.modal', function(e) {
$(this.refs.modal.getDOMNode()).on('show.bs.modal', function freshOpen(e) {
var newState = {};
if(BrowserStore.getItem('edit_state_transfer')) {
if (BrowserStore.getItem('edit_state_transfer')) {
newState = BrowserStore.getItem('edit_state_transfer');
BrowserStore.removeItem('edit_state_transfer');
} else {
var button = e.relatedTarget;
newState = { title: $(button).attr('data-title'), channel_id: $(button).attr('data-channelid'), post_id: $(button).attr('data-postid'), comments: $(button).attr('data-comments') };
newState = {title: $(button).attr('data-title'), channelId: $(button).attr('data-channelid'), postId: $(button).attr('data-postid'), comments: $(button).attr('data-comments')};
}
self.setState(newState);
});
PostStore.addSelectedPostChangeListener(this._onChange);
},
componentWillUnmount: function() {
PostStore.removeSelectedPostChangeListener(this._onChange);
},
_onChange: function() {
PostStore.addSelectedPostChangeListener(this.onListenerChange);
}
componentWillUnmount() {
PostStore.removeSelectedPostChangeListener(this.onListenerChange);
}
onListenerChange() {
var newList = PostStore.getSelectedPost();
if (!utils.areStatesEqual(this.state.selectedList, newList)) {
this.setState({ selectedList: newList });
if (!Utils.areStatesEqual(this.state.selectedList, newList)) {
this.setState({selectedList: newList});
}
}
render() {
var error = null;
if (this.state.error) {
error = <div className='form-group has-error'><label className='control-label'>{this.state.error}</label></div>;
}
var commentWarning = '';
if (this.state.comments > 0) {
commentWarning = 'This post has ' + this.state.comments + ' comment(s) on it.';
}
},
getInitialState: function() {
return { title: "", post_id: "", channel_id: "", selectedList: PostStore.getSelectedPost(), comments: 0 };
},
render: function() {
var error = this.state.error ? <div className='form-group has-error'><label className='control-label'>{ this.state.error }</label></div> : null;
return (
<div className="modal fade" id="delete_post" ref="modal" role="dialog" tabIndex="-1" aria-hidden="true">
<div className="modal-dialog modal-push-down">
<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">Confirm {this.state.title} Delete</h4>
<div
className='modal fade'
id='delete_post'
ref='modal'
role='dialog'
tabIndex='-1'
aria-hidden='true'
>
<div className='modal-dialog modal-push-down'>
<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'>Confirm {this.state.title} Delete</h4>
</div>
<div className="modal-body">
<div className='modal-body'>
Are you sure you want to delete the {this.state.title.toLowerCase()}?
<br/>
<br/>
{ this.state.comments > 0 ?
"This post has " + this.state.comments + " comment(s) on it."
: "" }
{commentWarning}
</div>
<div className="modal-footer">
<button type="button" className="btn btn-default" data-dismiss="modal">Cancel</button>
<button type="button" className="btn btn-danger" data-dismiss="modal" onClick={this.handleDelete}>Delete</button>
{error}
<div className='modal-footer'>
<button
type='button'
className='btn btn-default'
data-dismiss='modal'
>
Cancel
</button>
<button
type='button'
className='btn btn-danger'
data-dismiss='modal'
onClick={this.handleDelete}
>
Delete
</button>
</div>
</div>
</div>
</div>
);
}
});
}

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

@@ -1,35 +1,58 @@
// Copyright (c) 2015 Spinpunch, Inc. All Rights Reserved.
// See License.txt for license information.
module.exports = React.createClass({
handleResend: function() {
window.location.href = window.location.href + "&resend=true"
},
render: function() {
var title = "";
var body = "";
var resend = "";
if (this.props.isVerified === "true") {
title = config.SiteName + " Email Verified";
body = <p>Your email has been verified! Click <a href={this.props.teamURL + "?email=" + this.props.userEmail}>here</a> to log in.</p>;
export default class EmailVerify extends React.Component {
constructor(props) {
super(props);
this.handleResend = this.handleResend.bind(this);
this.state = {};
}
handleResend() {
window.location.href = window.location.href + '&resend=true';
}
render() {
var title = '';
var body = '';
var resend = '';
if (this.props.isVerified === 'true') {
title = config.SiteName + ' Email Verified';
body = <p>Your email has been verified! Click <a href={this.props.teamURL + '?email=' + this.props.userEmail}>here</a> to log in.</p>;
} else {
title = config.SiteName + " Email Not Verified";
title = config.SiteName + ' Email Not Verified';
body = <p>Please verify your email address. Check your inbox for an email.</p>;
resend = <button onClick={this.handleResend} className="btn btn-primary">Resend Email</button>
resend = (<button
onClick={this.handleResend}
className='btn btn-primary'
>
Resend Email
</button>);
}
return (
<div className="col-sm-offset-4 col-sm-4">
<div className="panel panel-default">
<div className="panel-heading">
<h3 className="panel-title">{ title }</h3>
<div className='col-sm-offset-4 col-sm-4'>
<div className='panel panel-default'>
<div className='panel-heading'>
<h3 className='panel-title'>{title}</h3>
</div>
<div className="panel-body">
{ body }
{ resend }
<div className='panel-body'>
{body}
{resend}
</div>
</div>
</div>
);
}
});
}
EmailVerify.defaultProps = {
isVerified: 'false',
teamURL: '',
userEmail: ''
};
EmailVerify.propTypes = {
isVerified: React.PropTypes.string,
teamURL: React.PropTypes.string,
userEmail: React.PropTypes.string
};

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

@@ -1,14 +1,17 @@
// Copyright (c) 2015 Spinpunch, Inc. All Rights Reserved.
// See License.txt for license information.
var UserStore = require('../stores/user_store.jsx');
var ChannelStore = require('../stores/channel_store.jsx');
var client = require('../utils/client.jsx');
var utils = require('../utils/utils.jsx');
var Constants = require('../utils/constants.jsx');
var Utils = require('../utils/utils.jsx');
module.exports = React.createClass({
handleRemove: function(e) {
export default class FilePreview extends React.Component {
constructor(props) {
super(props);
this.handleRemove = this.handleRemove.bind(this);
this.state = {};
}
handleRemove(e) {
var previewDiv = e.target.parentNode.parentNode;
if (previewDiv.hasAttribute('data-filename')) {
@@ -16,51 +19,96 @@ module.exports = React.createClass({
} else if (previewDiv.hasAttribute('data-client-id')) {
this.props.onRemove(previewDiv.getAttribute('data-client-id'));
}
},
render: function() {
}
render() {
var previews = [];
this.props.files.forEach(function(filename) {
this.props.files.forEach(function setupPreview(fullFilename) {
var filename = fullFilename;
var originalFilename = filename;
var filenameSplit = filename.split('.');
var ext = filenameSplit[filenameSplit.length-1];
var type = utils.getFileType(ext);
// This is a temporary patch to fix issue with old files using absolute paths
if (filename.indexOf("/api/v1/files/get") != -1) {
filename = filename.split("/api/v1/files/get")[1];
}
filename = utils.getWindowLocationOrigin() + "/api/v1/files/get" + filename;
var ext = filenameSplit[filenameSplit.length - 1];
var type = Utils.getFileType(ext);
if (type === "image") {
// This is a temporary patch to fix issue with old files using absolute paths
if (filename.indexOf('/api/v1/files/get') !== -1) {
filename = filename.split('/api/v1/files/get')[1];
}
filename = Utils.getWindowLocationOrigin() + '/api/v1/files/get' + filename;
if (type === 'image') {
previews.push(
<div key={filename} className="preview-div" data-filename={originalFilename}>
<img className="preview-img" src={filename}/>
<a className="remove-preview" onClick={this.handleRemove}><i className="glyphicon glyphicon-remove"/></a>
<div
key={filename}
className='preview-div'
data-filename={originalFilename}
>
<img
className='preview-img'
src={filename}
/>
<a
className='remove-preview'
onClick={this.handleRemove}
>
<i className='glyphicon glyphicon-remove'/>
</a>
</div>
);
} else {
previews.push(
<div key={filename} className="preview-div custom-file" data-filename={originalFilename}>
<div className={"file-icon "+utils.getIconClassName(type)}/>
<a className="remove-preview" onClick={this.handleRemove}><i className="glyphicon glyphicon-remove"/></a>
<div
key={filename}
className='preview-div custom-file'
data-filename={originalFilename}
>
<div className={'file-icon ' + Utils.getIconClassName(type)}/>
<a
className='remove-preview'
onClick={this.handleRemove}
>
<i className='glyphicon glyphicon-remove'/>
</a>
</div>
);
}
}.bind(this));
this.props.uploadsInProgress.forEach(function(clientId) {
this.props.uploadsInProgress.forEach(function addUploadsInProgress(clientId) {
previews.push(
<div className="preview-div" data-client-id={clientId}>
<img className="spinner" src="/static/images/load.gif"/>
<a className="remove-preview" onClick={this.handleRemove}><i className="glyphicon glyphicon-remove"/></a>
<div
key={clientId}
className='preview-div'
data-client-id={clientId}
>
<img
className='spinner'
src='/static/images/load.gif'
/>
<a
className='remove-preview'
onClick={this.handleRemove}
>
<i className='glyphicon glyphicon-remove'/>
</a>
</div>
);
}.bind(this));
return (
<div className="preview-container">
<div className='preview-container'>
{previews}
</div>
);
}
});
}
FilePreview.defaultProps = {
files: null,
uploadsInProgress: null
};
FilePreview.propTypes = {
onRemove: React.PropTypes.func.isRequired,
files: React.PropTypes.array,
uploadsInProgress: React.PropTypes.array
};

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

@@ -1,30 +1,57 @@
// Copyright (c) 2015 Spinpunch, Inc. All Rights Reserved.
// See License.txt for license information.
var UserStore = require("../stores/user_store.jsx");
var UserStore = require('../stores/user_store.jsx');
module.exports = React.createClass({
handleClick: function() {
export default class Mention extends React.Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
this.state = null;
}
handleClick() {
this.props.handleClick(this.props.username);
},
getInitialState: function() {
return null;
},
render: function() {
var self = this;
}
render() {
var icon;
var timestamp = UserStore.getCurrentUser().update_at;
if (this.props.id === "allmention" || this.props.id === "channelmention") {
icon = <span><i className="mention-img fa fa-users fa-2x"></i></span>;
if (this.props.id === 'allmention' || this.props.id === 'channelmention') {
icon = <span><i className='mention-img fa fa-users fa-2x'></i></span>;
} else if (this.props.id != null) {
icon = <span><img className="mention-img" src={"/api/v1/users/" + this.props.id + "/image?time=" + timestamp}/></span>;
icon = (<span><img
className='mention-img'
src={'/api/v1/users/' + this.props.id + '/image?time=' + timestamp}
/>
</span>);
} else {
icon = <span><i className="mention-img fa fa-users fa-2x"></i></span>;
icon = <span><i className='mention-img fa fa-users fa-2x'></i></span>;
}
return (
<div className={"mentions-name " + this.props.isFocused} id={this.props.id + "_mentions"} onClick={this.handleClick} onMouseEnter={this.props.handleMouseEnter}>
<div className="pull-left">{icon}</div>
<div className="pull-left mention-align"><span>@{this.props.username}</span><span className="mention-fullname">{this.props.secondary_text}</span></div>
<div
className={'mentions-name ' + this.props.isFocused}
id={this.props.id + '_mentions'}
onClick={this.handleClick}
onMouseEnter={this.props.handleMouseEnter}
>
<div className='pull-left'>{icon}</div>
<div className='pull-left mention-align'><span>@{this.props.username}</span><span className='mention-fullname'>{this.props.secondary_text}</span></div>
</div>
);
}
});
}
Mention.defaultProps = {
username: '',
id: '',
isFocused: '',
secondary_text: ''
};
Mention.propTypes = {
handleClick: React.PropTypes.func.isRequired,
handleMouseEnter: React.PropTypes.func.isRequired,
username: React.PropTypes.string,
id: React.PropTypes.string,
isFocused: React.PropTypes.string,
secondary_text: React.PropTypes.string
};

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

@@ -1,17 +1,30 @@
// Copyright (c) 2015 Spinpunch, Inc. All Rights Reserved.
// See License.txt for license information.
var utils = require('../utils/utils.jsx');
var Utils = require('../utils/utils.jsx');
module.exports = React.createClass({
render: function() {
export default class MessageWrapper extends React.Component {
constructor(props) {
super(props);
this.state = {};
}
render() {
if (this.props.message) {
var inner = utils.textToJsx(this.props.message, this.props.options);
var inner = Utils.textToJsx(this.props.message, this.props.options);
return (
<div>{inner}</div>
);
} else {
return <div/>
}
return <div/>;
}
});
}
MessageWrapper.defaultProps = {
message: null,
options: null
};
MessageWrapper.propTypes = {
message: React.PropTypes.string,
options: React.PropTypes.object
};

210
web/react/components/navbar_dropdown.jsx Обычный файл
Просмотреть файл

@@ -0,0 +1,210 @@
// 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(), currentTeam: TeamStore.getCurrent()};
}
export default class NavbarDropdown extends React.Component {
constructor(props) {
super(props);
this.blockToggle = false;
this.handleLogoutClick = this.handleLogoutClick.bind(this);
this.onListenerChange = this.onListenerChange.bind(this);
this.state = getStateFromStores();
}
handleLogoutClick(e) {
e.preventDefault();
client.logout();
}
componentDidMount() {
UserStore.addTeamsChangeListener(this.onListenerChange);
TeamStore.addChangeListener(this.onListenerChange);
var self = this;
$(this.refs.dropdown.getDOMNode()).on('hide.bs.dropdown', function resetDropdown() {
self.blockToggle = true;
setTimeout(function blockTimeout() {
self.blockToggle = false;
}, 100);
});
}
componentWillUnmount() {
UserStore.removeTeamsChangeListener(this.onListenerChange);
TeamStore.removeChangeListener(this.onListenerChange);
$(this.refs.dropdown.getDOMNode()).off('hide.bs.dropdown');
}
onListenerChange() {
var newState = getStateFromStores();
if (!Utils.areStatesEqual(newState, this.state)) {
this.setState(newState);
}
}
render() {
var teamLink = '';
var inviteLink = '';
var manageLink = '';
var currentUser = UserStore.getCurrentUser();
var isAdmin = false;
var teamSettings = null;
if (currentUser != null) {
isAdmin = currentUser.roles.indexOf('admin') > -1;
inviteLink = (<li>
<a
href='#'
data-toggle='modal'
data-target='#invite_member'
>
Invite New Member
</a>
</li>);
if (this.props.teamType === 'O') {
teamLink = (
<li>
<a
href='#'
data-toggle='modal'
data-target='#get_link'
data-title='Team Invite'
data-value={Utils.getWindowLocationOrigin() + '/signup_user_complete/?id=' + currentUser.team_id}
>
Get Team Invite Link
</a>
</li>
);
}
}
if (isAdmin) {
manageLink = (<li>
<a
href='#'
data-toggle='modal'
data-target='#team_members'
>
Manage Team
</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 && this.state.currentTeam) {
var curTeamName = this.state.currentTeam.name;
this.state.teams.forEach(function listTeams(teamName) {
if (teamName !== curTeamName) {
teams.push(<li key={teamName}><a href={Utils.getWindowLocationOrigin() + '/' + teamName}>Switch to {teamName}</a></li>);
}
});
}
teams.push(<li key='newTeam_li'>
<a
key='newTeam_a'
target='_blank'
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}}
/>
</a>
<ul
className='dropdown-menu'
role='menu'
>
<li>
<a
href='#'
data-toggle='modal'
data-target='#user_settings'
>
Account Settings
</a>
</li>
{teamSettings}
{inviteLink}
{teamLink}
{manageLink}
<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>
);
}
}
NavbarDropdown.defaultProps = {
teamType: ''
};
NavbarDropdown.propTypes = {
teamType: React.PropTypes.string
};

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

@@ -23,27 +23,30 @@ function getCountsStateFromStores() {
return {count: count};
}
module.exports = React.createClass({
displayName: 'NotifyCounts',
componentDidMount: function() {
export default class NotifyCounts extends React.Component {
constructor(props) {
super(props);
this.onListenerChange = this.onListenerChange.bind(this);
this.state = getCountsStateFromStores();
}
componentDidMount() {
ChannelStore.addChangeListener(this.onListenerChange);
},
componentWillUnmount: function() {
}
componentWillUnmount() {
ChannelStore.removeChangeListener(this.onListenerChange);
},
onListenerChange: function() {
}
onListenerChange() {
var newState = getCountsStateFromStores();
if (!utils.areStatesEqual(newState, this.state)) {
this.setState(newState);
}
},
getInitialState: function() {
return getCountsStateFromStores();
},
render: function() {
}
render() {
if (this.state.count) {
return <span className='badge badge-notify'>{this.state.count}</span>;
}
return null;
}
});
}

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

@@ -1,143 +1,47 @@
// 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 PasswordResetSendLink = require('./password_reset_send_link.jsx');
var PasswordResetForm = require('./password_reset_form.jsx');
SendResetPasswordLink = React.createClass({
handleSendLink: function(e) {
e.preventDefault();
var state = {};
export default class PasswordReset extends React.Component {
constructor(props) {
super(props);
var email = this.refs.email.getDOMNode().value.trim();
if (!email) {
state.error = "Please enter a valid email address."
this.setState(state);
return;
}
state.error = null;
this.setState(state);
data = {};
data['email'] = email;
data['name'] = this.props.teamName;
client.sendPasswordReset(data,
function(data) {
this.setState({ error: null, update_text: <p>A password reset link has been sent to <b>{email}</b> for your <b>{this.props.teamDisplayName}</b> team on {window.location.hostname}.</p>, more_update_text: "Please check your inbox." });
$(this.refs.reset_form.getDOMNode()).hide();
}.bind(this),
function(err) {
this.setState({ error: err.message, update_text: null, more_update_text: null });
}.bind(this)
);
},
getInitialState: function() {
return {};
},
render: function() {
var update_text = this.state.update_text ? <div className="reset-form alert alert-success">{this.state.update_text}{this.state.more_update_text}</div> : null;
var error = this.state.error ? <div className="form-group has-error"><label className="control-label">{this.state.error}</label></div> : null;
return (
<div className="col-sm-12">
<div className="signup-team__container">
<h3>Password Reset</h3>
{ update_text }
<form onSubmit={this.handleSendLink} ref="reset_form">
<p>{"To reset your password, enter the email address you used to sign up for " + this.props.teamDisplayName + "."}</p>
<div className={error ? 'form-group has-error' : 'form-group'}>
<input type="text" className="form-control" name="email" ref="email" placeholder="Email" />
</div>
{ error }
<button type="submit" className="btn btn-primary">Reset my password</button>
</form>
</div>
</div>
);
this.state = {};
}
});
ResetPassword = React.createClass({
handlePasswordReset: function(e) {
e.preventDefault();
var state = {};
var password = this.refs.password.getDOMNode().value.trim();
if (!password || password.length < 5) {
state.error = "Please enter at least 5 characters."
this.setState(state);
return;
}
state.error = null;
this.setState(state);
data = {};
data['new_password'] = password;
data['hash'] = this.props.hash;
data['data'] = this.props.data;
data['name'] = this.props.teamName;
client.resetPassword(data,
function(data) {
this.setState({ error: null, update_text: "Your password has been updated successfully." });
}.bind(this),
function(err) {
this.setState({ error: err.message, update_text: null });
}.bind(this)
);
},
getInitialState: function() {
return {};
},
render: function() {
var update_text = this.state.update_text ? <div className="form-group"><br/><label className="control-label reset-form">{this.state.update_text} Click <a href={"/" + this.props.teamName + "/login"}>here</a> to log in.</label></div> : null;
var error = this.state.error ? <div className="form-group has-error"><label className="control-label">{this.state.error}</label></div> : null;
return (
<div className="col-sm-12">
<div className="signup-team__container">
<h3>Password Reset</h3>
<form onSubmit={this.handlePasswordReset}>
<p>{"Enter a new password for your " + this.props.teamDisplayName + " " + config.SiteName + " account."}</p>
<div className={error ? 'form-group has-error' : 'form-group'}>
<input type="password" className="form-control" name="password" ref="password" placeholder="Password" />
</div>
{ error }
<button type="submit" className="btn btn-primary">Change my password</button>
{ update_text }
</form>
</div>
</div>
);
}
});
module.exports = React.createClass({
getInitialState: function() {
return {};
},
render: function() {
if (this.props.isReset === "false") {
render() {
if (this.props.isReset === 'false') {
return (
<SendResetPasswordLink
<PasswordResetSendLink
teamDisplayName={this.props.teamDisplayName}
teamName={this.props.teamName}
/>
);
} else {
return (
<ResetPassword
teamDisplayName={this.props.teamDisplayName}
teamName={this.props.teamName}
hash={this.props.hash}
data={this.props.data}
/>
);
}
return (
<PasswordResetForm
teamDisplayName={this.props.teamDisplayName}
teamName={this.props.teamName}
hash={this.props.hash}
data={this.props.data}
/>
);
}
});
}
PasswordReset.defaultProps = {
isReset: '',
teamName: '',
teamDisplayName: '',
hash: '',
data: ''
};
PasswordReset.propTypes = {
isReset: React.PropTypes.string,
teamName: React.PropTypes.string,
teamDisplayName: React.PropTypes.string,
hash: React.PropTypes.string,
data: React.PropTypes.string
};

100
web/react/components/password_reset_form.jsx Обычный файл
Просмотреть файл

@@ -0,0 +1,100 @@
// Copyright (c) 2015 Spinpunch, Inc. All Rights Reserved.
// See License.txt for license information.
var client = require('../utils/client.jsx');
export default class PasswordResetForm extends React.Component {
constructor(props) {
super(props);
this.handlePasswordReset = this.handlePasswordReset.bind(this);
this.state = {};
}
handlePasswordReset(e) {
e.preventDefault();
var state = {};
var password = this.refs.password.getDOMNode().value.trim();
if (!password || password.length < 5) {
state.error = 'Please enter at least 5 characters.';
this.setState(state);
return;
}
state.error = null;
this.setState(state);
var data = {};
data.new_password = password;
data.hash = this.props.hash;
data.data = this.props.data;
data.name = this.props.teamName;
client.resetPassword(data,
function resetSuccess() {
this.setState({error: null, updateText: 'Your password has been updated successfully.'});
}.bind(this),
function resetFailure(err) {
this.setState({error: err.message, updateText: null});
}.bind(this)
);
}
render() {
var updateText = null;
if (this.state.updateText) {
updateText = <div className='form-group'><br/><label className='control-label reset-form'>{this.state.updateText} Click <a href={'/' + this.props.teamName + '/login'}>here</a> to log in.</label></div>;
}
var error = null;
if (this.state.error) {
error = <div className='form-group has-error'><label className='control-label'>{this.state.error}</label></div>;
}
var formClass = 'form-group';
if (error) {
formClass += ' has-error';
}
return (
<div className='col-sm-12'>
<div className='signup-team__container'>
<h3>Password Reset</h3>
<form onSubmit={this.handlePasswordReset}>
<p>{'Enter a new password for your ' + this.props.teamDisplayName + ' ' + config.SiteName + ' account.'}</p>
<div className={formClass}>
<input
type='password'
className='form-control'
name='password'
ref='password'
placeholder='Password'
/>
</div>
{error}
<button
type='submit'
className='btn btn-primary'
>
Change my password
</button>
{updateText}
</form>
</div>
</div>
);
}
}
PasswordResetForm.defaultProps = {
teamName: '',
teamDisplayName: '',
hash: '',
data: ''
};
PasswordResetForm.propTypes = {
teamName: React.PropTypes.string,
teamDisplayName: React.PropTypes.string,
hash: React.PropTypes.string,
data: React.PropTypes.string
};

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

@@ -0,0 +1,98 @@
// Copyright (c) 2015 Spinpunch, Inc. All Rights Reserved.
// See License.txt for license information.
var client = require('../utils/client.jsx');
export default class PasswordResetSendLink extends React.Component {
constructor(props) {
super(props);
this.handleSendLink = this.handleSendLink.bind(this);
this.state = {};
}
handleSendLink(e) {
e.preventDefault();
var state = {};
var email = this.refs.email.getDOMNode().value.trim();
if (!email) {
state.error = 'Please enter a valid email address.';
this.setState(state);
return;
}
state.error = null;
this.setState(state);
var data = {};
data.email = email;
data.name = this.props.teamName;
client.sendPasswordReset(data,
function passwordResetSent() {
this.setState({error: null, updateText: <p>A password reset link has been sent to <b>{email}</b> for your <b>{this.props.teamDisplayName}</b> team on {window.location.hostname}.</p>, moreUpdateText: 'Please check your inbox.'});
$(this.refs.reset_form.getDOMNode()).hide();
}.bind(this),
function passwordResetFailedToSend(err) {
this.setState({error: err.message, update_text: null, moreUpdateText: null});
}.bind(this)
);
}
render() {
var updateText = null;
if (this.state.updateText) {
updateText = <div className='reset-form alert alert-success'>{this.state.updateText}{this.state.moreUpdateText}</div>;
}
var error = null;
if (this.state.error) {
error = <div className='form-group has-error'><label className='control-label'>{this.state.error}</label></div>;
}
var formClass = 'form-group';
if (error) {
formClass += ' has-error';
}
return (
<div className='col-sm-12'>
<div className='signup-team__container'>
<h3>Password Reset</h3>
{updateText}
<form
onSubmit={this.handleSendLink}
ref='reset_form'
>
<p>{'To reset your password, enter the email address you used to sign up for ' + this.props.teamDisplayName + '.'}</p>
<div className={formClass}>
<input
type='text'
className='form-control'
name='email'
ref='email'
placeholder='Email'
/>
</div>
{error}
<button
type='submit'
className='btn btn-primary'
>
Reset my password
</button>
</form>
</div>
</div>
);
}
}
PasswordResetSendLink.defaultProps = {
teamName: '',
teamDisplayName: ''
};
PasswordResetSendLink.propTypes = {
teamName: React.PropTypes.string,
teamDisplayName: React.PropTypes.string
};

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

@@ -3,34 +3,61 @@
var UserStore = require('../stores/user_store.jsx');
module.exports = React.createClass({
getInitialState: function() {
return { };
},
render: function() {
var currentUser = UserStore.getCurrentUser()
export default class PostDeletedModal extends React.Component {
constructor(props) {
super(props);
this.state = {};
}
render() {
var currentUser = UserStore.getCurrentUser();
if (currentUser != null) {
return (
<div className="modal fade" ref="modal" id="post_deleted" tabIndex="-1" role="dialog" aria-hidden="true">
<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" id="myModalLabel">Comment could not be posted</h4>
<div
className='modal fade'
ref='modal'
id='post_deleted'
tabIndex='-1'
role='dialog'
aria-hidden='true'
>
<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'
id='myModalLabel'
>
Comment could not be posted
</h4>
</div>
<div className='modal-body'>
<p>Someone deleted the message on which you tried to post a comment.</p>
</div>
<div className='modal-footer'>
<button
type='button'
className='btn btn-primary'
data-dismiss='modal'
>
Okay
</button>
</div>
</div>
<div className="modal-body">
<p>Someone deleted the message on which you tried to post a comment.</p>
</div>
<div className="modal-footer">
<button type="button" className="btn btn-primary" data-dismiss="modal">Okay</button>
</div>
</div>
</div>
</div>
</div>
);
} else {
return <div/>;
}
return <div/>;
}
});
}

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

@@ -6,10 +6,10 @@ var ChannelStore = require('../stores/channel_store.jsx');
var UserProfile = require('./user_profile.jsx');
var UserStore = require('../stores/user_store.jsx');
var AppDispatcher = require('../dispatcher/app_dispatcher.jsx');
var utils = require('../utils/utils.jsx');
var Utils = require('../utils/utils.jsx');
var Constants = require('../utils/constants.jsx');
var FileAttachmentList = require('./file_attachment_list.jsx');
var client = require('../utils/client.jsx');
var Client = require('../utils/client.jsx');
var AsyncClient = require('../utils/async_client.jsx');
var ActionTypes = Constants.ActionTypes;
@@ -25,7 +25,7 @@ export default class RhsComment extends React.Component {
e.preventDefault();
var post = this.props.post;
client.createPost(post, post.channel_id,
Client.createPost(post, post.channel_id,
function success(data) {
AsyncClient.getPosts(post.channel_id);
@@ -52,7 +52,7 @@ export default class RhsComment extends React.Component {
this.forceUpdate();
}
shouldComponentUpdate(nextProps) {
if (!utils.areStatesEqual(nextProps.post, this.props.post)) {
if (!Utils.areStatesEqual(nextProps.post, this.props.post)) {
return true;
}
@@ -73,7 +73,7 @@ export default class RhsComment extends React.Component {
type = 'Comment';
}
var message = utils.textToJsx(post.message);
var message = Utils.textToJsx(post.message);
var timestamp = UserStore.getCurrentUser().update_at;
var loading;
@@ -182,7 +182,7 @@ export default class RhsComment extends React.Component {
</li>
<li className='post-header-col'>
<time className='post-right-comment-time'>
{utils.displayCommentDateTime(post.create_at)}
{Utils.displayCommentDateTime(post.create_at)}
</time>
</li>
<li className='post-header-col post-header__reply'>

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

@@ -1,133 +1,25 @@
// 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 NavbarDropdown = require('./navbar_dropdown.jsx');
var UserStore = require('../stores/user_store.jsx');
var TeamStore = require('../stores/team_store.jsx');
var Constants = require('../utils/constants.jsx');
export default class SidebarHeader extends React.Component {
constructor(props) {
super(props);
function getStateFromStores() {
return {teams: UserStore.getTeams(), currentTeam: TeamStore.getCurrent()};
}
this.toggleDropdown = this.toggleDropdown.bind(this);
var NavbarDropdown = React.createClass({
handleLogoutClick: function(e) {
e.preventDefault();
client.logout();
},
blockToggle: false,
componentDidMount: function() {
UserStore.addTeamsChangeListener(this.onListenerChange);
TeamStore.addChangeListener(this.onListenerChange);
var self = this;
$(this.refs.dropdown.getDOMNode()).on('hide.bs.dropdown', function() {
self.blockToggle = true;
setTimeout(function() {
self.blockToggle = false;
}, 100);
});
},
componentWillUnmount: function() {
UserStore.removeTeamsChangeListener(this.onListenerChange);
TeamStore.removeChangeListener(this.onListenerChange);
$(this.refs.dropdown.getDOMNode()).off('hide.bs.dropdown');
},
onListenerChange: function() {
if (this.isMounted()) {
var newState = getStateFromStores();
if (!utils.areStatesEqual(newState, this.state)) {
this.setState(newState);
}
}
},
getInitialState: function() {
return getStateFromStores();
},
render: function() {
var teamLink = '';
var inviteLink = '';
var manageLink = '';
var currentUser = UserStore.getCurrentUser();
var isAdmin = false;
var teamSettings = null;
if (currentUser != null) {
isAdmin = currentUser.roles.indexOf('admin') > -1;
inviteLink = (<li> <a href='#' data-toggle='modal' data-target='#invite_member'>Invite New Member</a> </li>);
if (this.props.teamType === 'O') {
teamLink = (
<li>
<a href='#' data-toggle='modal' data-target='#get_link' data-title='Team Invite' data-value={utils.getWindowLocationOrigin() + '/signup_user_complete/?id=' + currentUser.team_id}>Get Team Invite Link</a>
</li>
);
}
}
if (isAdmin) {
manageLink = (<li> <a href='#' data-toggle='modal' data-target='#team_members'>Manage Team</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 && 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 key='newTeam_li'><a key='newTeam_a' target="_blank" 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}} />
</a>
<ul className='dropdown-menu' role='menu'>
<li><a href='#' data-toggle='modal' data-target='#user_settings'>Account Settings</a></li>
{teamSettings}
{inviteLink}
{teamLink}
{manageLink}
<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>
);
this.state = {};
}
});
module.exports = React.createClass({
displayName: 'SidebarHeader',
getDefaultProps: function() {
return {
teamDisplayName: config.SiteName
};
},
toggleDropdown: function() {
toggleDropdown() {
if (this.refs.dropdown.blockToggle) {
this.refs.dropdown.blockToggle = false;
return;
}
$('.team__header').find('.dropdown-toggle').dropdown('toggle');
},
render: function() {
}
render() {
var me = UserStore.getCurrentUser();
var profilePicture = null;
@@ -136,20 +28,38 @@ module.exports = React.createClass({
}
if (me.last_picture_update) {
profilePicture = (<img className='user__picture' src={'/api/v1/users/' + me.id + '/image?time=' + me.update_at} />);
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}>
<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 className='team__name'>{this.props.teamDisplayName}</div>
</div>
</a>
<NavbarDropdown ref='dropdown' teamType={this.props.teamType} />
<NavbarDropdown
ref='dropdown'
teamType={this.props.teamType}
/>
</div>
);
}
});
}
SidebarHeader.defaultProps = {
teamDisplayName: config.SiteName,
teamType: ''
};
SidebarHeader.propTypes = {
teamDisplayName: React.PropTypes.string,
teamType: React.PropTypes.string
};

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

@@ -4,47 +4,49 @@
var SearchResults = require('./search_results.jsx');
var RhsThread = require('./rhs_thread.jsx');
var PostStore = require('../stores/post_store.jsx');
var utils = require('../utils/utils.jsx');
var Utils = require('../utils/utils.jsx');
function getStateFromStores(from_search) {
return { search_visible: PostStore.getSearchResults() != null, post_right_visible: PostStore.getSelectedPost() != null, is_mention_search: PostStore.getIsMentionSearch() };
function getStateFromStores() {
return {search_visible: PostStore.getSearchResults() != null, post_right_visible: PostStore.getSelectedPost() != null, is_mention_search: PostStore.getIsMentionSearch()};
}
module.exports = React.createClass({
componentDidMount: function() {
PostStore.addSearchChangeListener(this._onSearchChange);
PostStore.addSelectedPostChangeListener(this._onSelectedChange);
},
componentWillUnmount: function() {
PostStore.removeSearchChangeListener(this._onSearchChange);
PostStore.removeSelectedPostChangeListener(this._onSelectedChange);
},
_onSelectedChange: function(from_search) {
if (this.isMounted()) {
var newState = getStateFromStores(from_search);
newState.from_search = from_search;
if (!utils.areStatesEqual(newState, this.state)) {
this.setState(newState);
}
export default class SidebarRight extends React.Component {
constructor(props) {
super(props);
this.onSelectedChange = this.onSelectedChange.bind(this);
this.onSearchChange = this.onSearchChange.bind(this);
this.resize = this.resize.bind(this);
this.state = getStateFromStores();
}
componentDidMount() {
PostStore.addSearchChangeListener(this.onSearchChange);
PostStore.addSelectedPostChangeListener(this.onSelectedChange);
}
componentWillUnmount() {
PostStore.removeSearchChangeListener(this.onSearchChange);
PostStore.removeSelectedPostChangeListener(this.onSelectedChange);
}
onSelectedChange(fromSearch) {
var newState = getStateFromStores(fromSearch);
newState.from_search = fromSearch;
if (!Utils.areStatesEqual(newState, this.state)) {
this.setState(newState);
}
},
_onSearchChange: function() {
if (this.isMounted()) {
var newState = getStateFromStores();
if (!utils.areStatesEqual(newState, this.state)) {
this.setState(newState);
}
}
onSearchChange() {
var newState = getStateFromStores();
if (!Utils.areStatesEqual(newState, this.state)) {
this.setState(newState);
}
},
resize: function() {
}
resize() {
var postHolder = $('.post-list-holder-by-time');
postHolder[0].scrollTop = postHolder[0].scrollHeight - 224;
},
getInitialState: function() {
return getStateFromStores();
},
render: function() {
if (! (this.state.search_visible || this.state.post_right_visible)) {
}
render() {
if (!(this.state.search_visible || this.state.post_right_visible)) {
$('.inner__wrap').removeClass('move--left').removeClass('move--right');
$('.sidebar--right').removeClass('move--left');
this.resize();
@@ -58,25 +60,27 @@ module.exports = React.createClass({
$('.sidebar--right').addClass('move--left');
$('.sidebar--right').prepend('<div class="sidebar__overlay"></div>');
this.resize();
setTimeout(function(){
$('.sidebar__overlay').fadeOut("200", function(){
setTimeout(function overlayTimer() {
$('.sidebar__overlay').fadeOut('200', function fadeOverlay() {
$(this).remove();
});
},500)
}, 500);
var content = "";
var content = '';
if (this.state.search_visible) {
content = <SearchResults isMentionSearch={this.state.is_mention_search} />;
}
else if (this.state.post_right_visible) {
content = <RhsThread fromSearch={this.state.from_search} isMentionSearch={this.state.is_mention_search} />;
} else if (this.state.post_right_visible) {
content = (<RhsThread
fromSearch={this.state.from_search}
isMentionSearch={this.state.is_mention_search}
/>);
}
return (
<div className="sidebar-right-container">
{ content }
<div className='sidebar-right-container'>
{content}
</div>
);
}
});
}

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

@@ -10,69 +10,99 @@ var UsernamePage = require('./team_signup_username_page.jsx');
var PasswordPage = require('./team_signup_password_page.jsx');
var BrowserStore = require('../stores/browser_store.jsx');
module.exports = React.createClass({
displayName: 'SignupTeamComplete',
propTypes: {
hash: React.PropTypes.string,
email: React.PropTypes.string,
data: React.PropTypes.string
},
updateParent: function(state, skipSet) {
export default class SignupTeamComplete extends React.Component {
constructor(props) {
super(props);
this.updateParent = this.updateParent.bind(this);
var initialState = BrowserStore.getGlobalItem(props.hash);
if (!initialState) {
initialState = {};
initialState.wizard = 'welcome';
initialState.team = {};
initialState.team.email = this.props.email;
initialState.team.allowed_domains = '';
initialState.invites = [];
initialState.invites.push('');
initialState.invites.push('');
initialState.invites.push('');
initialState.user = {};
initialState.hash = this.props.hash;
initialState.data = this.props.data;
}
this.state = initialState;
}
updateParent(state, skipSet) {
BrowserStore.setGlobalItem(this.props.hash, state);
if (!skipSet) {
this.setState(state);
}
},
getInitialState: function() {
var props = BrowserStore.getGlobalItem(this.props.hash);
if (!props) {
props = {};
props.wizard = 'welcome';
props.team = {};
props.team.email = this.props.email;
props.team.allowed_domains = '';
props.invites = [];
props.invites.push('');
props.invites.push('');
props.invites.push('');
props.user = {};
props.hash = this.props.hash;
props.data = this.props.data;
}
return props;
},
render: function() {
}
render() {
if (this.state.wizard === 'welcome') {
return <WelcomePage state={this.state} updateParent={this.updateParent} />;
return (<WelcomePage
state={this.state}
updateParent={this.updateParent}
/>);
}
if (this.state.wizard === 'team_display_name') {
return <TeamDisplayNamePage state={this.state} updateParent={this.updateParent} />;
return (<TeamDisplayNamePage
state={this.state}
updateParent={this.updateParent}
/>);
}
if (this.state.wizard === 'team_url') {
return <TeamURLPage state={this.state} updateParent={this.updateParent} />;
return (<TeamURLPage
state={this.state}
updateParent={this.updateParent}
/>);
}
if (this.state.wizard === 'allowed_domains') {
return <AllowedDomainsPage state={this.state} updateParent={this.updateParent} />;
return (<AllowedDomainsPage
state={this.state}
updateParent={this.updateParent}
/>);
}
if (this.state.wizard === 'send_invites') {
return <SendInivtesPage state={this.state} updateParent={this.updateParent} />;
return (<SendInivtesPage
state={this.state}
updateParent={this.updateParent}
/>);
}
if (this.state.wizard === 'username') {
return <UsernamePage state={this.state} updateParent={this.updateParent} />;
return (<UsernamePage
state={this.state}
updateParent={this.updateParent}
/>);
}
if (this.state.wizard === 'password') {
return <PasswordPage state={this.state} updateParent={this.updateParent} />;
return (<PasswordPage
state={this.state}
updateParent={this.updateParent}
/>);
}
return (<div>You've already completed the signup process for this invitation or this invitation has expired.</div>);
}
});
}
SignupTeamComplete.defaultProps = {
hash: '',
email: '',
data: ''
};
SignupTeamComplete.propTypes = {
hash: React.PropTypes.string,
email: React.PropTypes.string,
data: React.PropTypes.string
};

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

@@ -7,8 +7,28 @@ var UserStore = require('../stores/user_store.jsx');
var BrowserStore = require('../stores/browser_store.jsx');
var Constants = require('../utils/constants.jsx');
module.exports = React.createClass({
handleSubmit: function(e) {
export default class SignupUserComplete extends React.Component {
constructor(props) {
super(props);
this.handleSubmit = this.handleSubmit.bind(this);
var initialState = BrowserStore.getGlobalItem(this.props.hash);
if (!initialState) {
initialState = {};
initialState.wizard = 'welcome';
initialState.user = {};
initialState.user.team_id = this.props.teamId;
initialState.user.email = this.props.email;
initialState.hash = this.props.hash;
initialState.data = this.props.data;
initialState.original_email = this.props.email;
}
this.state = initialState;
}
handleSubmit(e) {
e.preventDefault();
this.state.user.username = this.refs.name.getDOMNode().value.trim();
@@ -38,7 +58,7 @@ module.exports = React.createClass({
}
this.state.user.password = this.refs.password.getDOMNode().value.trim();
if (!this.state.user.password || this.state.user.password .length < 5) {
if (!this.state.user.password || this.state.user.password .length < 5) {
this.setState({nameError: '', emailError: '', passwordError: 'Please enter at least 5 characters', serverError: ''});
return;
}
@@ -48,11 +68,11 @@ module.exports = React.createClass({
this.state.user.allow_marketing = true;
client.createUser(this.state.user, this.state.data, this.state.hash,
function(data) {
function createUserSuccess() {
client.track('signup', 'signup_user_02_complete');
client.loginByEmail(this.props.teamName, this.state.user.email, this.state.user.password,
function(data) {
function emailLoginSuccess(data) {
UserStore.setLastEmail(this.state.user.email);
UserStore.setCurrentUser(data);
if (this.props.hash > 0) {
@@ -60,7 +80,7 @@ module.exports = React.createClass({
}
window.location.href = '/';
}.bind(this),
function(err) {
function emailLoginFailure(err) {
if (err.message === 'Login failed because email address has not been verified') {
window.location.href = '/verify_email?email=' + encodeURIComponent(this.state.user.email) + '&teamname=' + encodeURIComponent(this.props.teamName);
} else {
@@ -69,28 +89,12 @@ module.exports = React.createClass({
}.bind(this)
);
}.bind(this),
function(err) {
function createUserFailure(err) {
this.setState({serverError: err.message});
}.bind(this)
);
},
getInitialState: function() {
var state = BrowserStore.getGlobalItem(this.props.hash);
if (!state) {
state = {};
state.wizard = 'welcome';
state.user = {};
state.user.team_id = this.props.teamId;
state.user.email = this.props.email;
state.hash = this.props.hash;
state.data = this.props.data;
state.original_email = this.props.email;
}
return state;
},
render: function() {
}
render() {
client.track('signup', 'signup_user_01_welcome');
if (this.state.wizard === 'finished') {
@@ -134,16 +138,24 @@ module.exports = React.createClass({
yourEmailIs = <span>Your email address is {this.state.user.email}. You'll use this address to sign in to {config.SiteName}.</span>;
}
var emailContainerStyle = "margin--extra";
var emailContainerStyle = 'margin--extra';
if (this.state.original_email) {
emailContainerStyle = "hidden";
emailContainerStyle = 'hidden';
}
var email = (
<div className={emailContainerStyle}>
<h5><strong>What's your email address?</strong></h5>
<div className={emailDivStyle}>
<input type='email' ref='email' className='form-control' defaultValue={this.state.user.email} placeholder='' maxLength='128' autoFocus={true} />
<input
type='email'
ref='email'
className='form-control'
defaultValue={this.state.user.email}
placeholder=''
maxLength='128'
autoFocus={true}
/>
{emailError}
</div>
</div>
@@ -155,7 +167,10 @@ module.exports = React.createClass({
var signupMessage = [];
if (authServices.indexOf(Constants.GITLAB_SERVICE) >= 0) {
signupMessage.push(
<a className='btn btn-custom-login gitlab' href={'/' + this.props.teamName + '/signup/gitlab' + window.location.search}>
<a
className='btn btn-custom-login gitlab'
href={'/' + this.props.teamName + '/signup/gitlab' + window.location.search}
>
<span className='icon' />
<span>with GitLab</span>
</a>
@@ -172,7 +187,13 @@ module.exports = React.createClass({
<div className='margin--extra'>
<h5><strong>Choose your username</strong></h5>
<div className={nameDivStyle}>
<input type='text' ref='name' className='form-control' placeholder='' maxLength='128' />
<input
type='text'
ref='name'
className='form-control'
placeholder=''
maxLength='128'
/>
{nameError}
<p className='form__hint'>Username must begin with a letter, and contain between 3 to 15 lowercase characters made up of numbers, letters, and the symbols '.', '-' and '_'</p>
</div>
@@ -180,12 +201,26 @@ module.exports = React.createClass({
<div className='margin--extra'>
<h5><strong>Choose your password</strong></h5>
<div className={passwordDivStyle}>
<input type='password' ref='password' className='form-control' placeholder='' maxLength='128' />
<input
type='password'
ref='password'
className='form-control'
placeholder=''
maxLength='128'
/>
{passwordError}
</div>
</div>
</div>
<p className='margin--extra'><button type='submit' onClick={this.handleSubmit} className='btn-primary btn'>Create Account</button></p>
<p className='margin--extra'>
<button
type='submit'
onClick={this.handleSubmit}
className='btn-primary btn'
>
Create Account
</button>
</p>
</div>
);
}
@@ -209,7 +244,10 @@ module.exports = React.createClass({
return (
<div>
<form>
<img className='signup-team-logo' src='/static/images/logo.png' />
<img
className='signup-team-logo'
src='/static/images/logo.png'
/>
<h5 className='margin--less'>Welcome to:</h5>
<h2 className='signup-team__name'>{this.props.teamDisplayName}</h2>
<h2 className='signup-team__subdomain'>on {config.SiteName}</h2>
@@ -222,6 +260,23 @@ module.exports = React.createClass({
</div>
);
}
});
}
SignupUserComplete.defaultProps = {
teamName: '',
hash: '',
teamId: '',
email: '',
data: null,
authServices: '',
teamDisplayName: ''
};
SignupUserComplete.propTypes = {
teamName: React.PropTypes.string,
hash: React.PropTypes.string,
teamId: React.PropTypes.string,
email: React.PropTypes.string,
data: React.PropTypes.string,
authServices: React.PropTypes.string,
teamDisplayName: React.PropTypes.string
};

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

@@ -2,9 +2,9 @@
// See License.txt for license information.
var EmailItem = require('./team_signup_email_item.jsx');
var utils = require('../utils/utils.jsx');
var Utils = require('../utils/utils.jsx');
var ConfigStore = require('../stores/config_store.jsx');
var client = require('../utils/client.jsx');
var Client = require('../utils/client.jsx');
export default class TeamSignupSendInvitesPage extends React.Component {
constructor(props) {
@@ -71,7 +71,7 @@ export default class TeamSignupSendInvitesPage extends React.Component {
}
keySubmit(e) {
if (e && e.keyCode === 13) {
this.submitNext(e)
this.submitNext(e);
}
}
componentWillMount() {
@@ -92,7 +92,7 @@ export default class TeamSignupSendInvitesPage extends React.Component {
}
}
render() {
client.track('signup', 'signup_team_05_send_invites');
Client.track('signup', 'signup_team_05_send_invites');
var content = null;
var bottomContent = null;
@@ -165,7 +165,7 @@ export default class TeamSignupSendInvitesPage extends React.Component {
className='signup-team-logo'
src='/static/images/logo.png'
/>
<h2>{'Invite ' + utils.toTitleCase(strings.Team) + ' Members'}</h2>
<h2>{'Invite ' + Utils.toTitleCase(strings.Team) + ' Members'}</h2>
{content}
<div className='form-group'>
<button
@@ -190,6 +190,7 @@ export default class TeamSignupSendInvitesPage extends React.Component {
);
}
}
TeamSignupSendInvitesPage.propTypes = {
state: React.PropTypes.object.isRequired,
updateParent: React.PropTypes.func.isRequired

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

@@ -1,26 +1,29 @@
// 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 Utils = require('../utils/utils.jsx');
var Client = require('../utils/client.jsx');
module.exports = React.createClass({
displayName: 'TeamSignupUsernamePage',
propTypes: {
state: React.PropTypes.object,
updateParent: React.PropTypes.func
},
submitBack: function(e) {
export default class TeamSignupUsernamePage extends React.Component {
constructor(props) {
super(props);
this.submitBack = this.submitBack.bind(this);
this.submitNext = this.submitNext.bind(this);
this.state = {};
}
submitBack(e) {
e.preventDefault();
this.props.state.wizard = 'send_invites';
this.props.updateParent(this.props.state);
},
submitNext: function(e) {
}
submitNext(e) {
e.preventDefault();
var name = this.refs.name.getDOMNode().value.trim();
var usernameError = utils.isValidUsername(name);
var usernameError = Utils.isValidUsername(name);
if (usernameError === 'Cannot use a reserved word as a username.') {
this.setState({nameError: 'This username is reserved, please choose a new one.'});
return;
@@ -32,12 +35,9 @@ module.exports = React.createClass({
this.props.state.wizard = 'password';
this.props.state.user.username = name;
this.props.updateParent(this.props.state);
},
getInitialState: function() {
return {};
},
render: function() {
client.track('signup', 'signup_team_06_username');
}
render() {
Client.track('signup', 'signup_team_06_username');
var nameError = null;
var nameDivClass = 'form-group';
@@ -49,7 +49,10 @@ module.exports = React.createClass({
return (
<div>
<form>
<img className='signup-team-logo' src='/static/images/logo.png' />
<img
className='signup-team-logo'
src='/static/images/logo.png'
/>
<h2 className='margin--less'>Your username</h2>
<h5 className='color--light'>{'Select a memorable username that makes it easy for ' + strings.Team + 'mates to identify you:'}</h5>
<div className='inner__content margin--extra'>
@@ -57,19 +60,47 @@ module.exports = React.createClass({
<div className='row'>
<div className='col-sm-11'>
<h5><strong>Choose your username</strong></h5>
<input autoFocus={true} type='text' ref='name' className='form-control' placeholder='' defaultValue={this.props.state.user.username} maxLength='128' />
<input
autoFocus={true}
type='text'
ref='name'
className='form-control'
placeholder=''
defaultValue={this.props.state.user.username}
maxLength='128'
/>
<div className='color--light form__hint'>Usernames must begin with a letter and contain 3 to 15 characters made up of lowercase letters, numbers, and the symbols '.', '-' and '_'</div>
</div>
</div>
{nameError}
</div>
</div>
<button type='submit' className='btn btn-primary margin--extra' onClick={this.submitNext}>Next<i className='glyphicon glyphicon-chevron-right'></i></button>
<button
type='submit'
className='btn btn-primary margin--extra'
onClick={this.submitNext}
>
Next
<i className='glyphicon glyphicon-chevron-right'></i>
</button>
<div className='margin--extra'>
<a href='#' onClick={this.submitBack}>Back to previous step</a>
<a
href='#'
onClick={this.submitBack}
>
Back to previous step
</a>
</div>
</form>
</div>
);
}
});
}
TeamSignupUsernamePage.defaultProps = {
state: null
};
TeamSignupUsernamePage.propTypes = {
state: React.PropTypes.object,
updateParent: React.PropTypes.func
};

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

@@ -1,17 +1,22 @@
// 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 Utils = require('../utils/utils.jsx');
var Client = require('../utils/client.jsx');
var BrowserStore = require('../stores/browser_store.jsx');
module.exports = React.createClass({
displayName: 'TeamSignupWelcomePage',
propTypes: {
state: React.PropTypes.object,
updateParent: React.PropTypes.func
},
submitNext: function(e) {
export default class TeamSignupWelcomePage extends React.Component {
constructor(props) {
super(props);
this.submitNext = this.submitNext.bind(this);
this.handleDiffEmail = this.handleDiffEmail.bind(this);
this.handleDiffSubmit = this.handleDiffSubmit.bind(this);
this.handleKeyPress = this.handleKeyPress.bind(this);
this.state = {useDiff: false};
}
submitNext(e) {
if (!BrowserStore.isLocalStorageSupported()) {
this.setState({storageError: 'This service requires local storage to be enabled. Please enable it or exit private browsing.'});
return;
@@ -19,18 +24,18 @@ module.exports = React.createClass({
e.preventDefault();
this.props.state.wizard = 'team_display_name';
this.props.updateParent(this.props.state);
},
handleDiffEmail: function(e) {
}
handleDiffEmail(e) {
e.preventDefault();
this.setState({useDiff: true});
},
handleDiffSubmit: function(e) {
}
handleDiffSubmit(e) {
e.preventDefault();
var state = {useDiff: true, serverError: ''};
var email = this.refs.email.getDOMNode().value.trim().toLowerCase();
if (!email || !utils.isEmail(email)) {
if (!email || !Utils.isEmail(email)) {
state.emailError = 'Please enter a valid email address';
this.setState(state);
return;
@@ -41,7 +46,7 @@ module.exports = React.createClass({
}
state.emailError = '';
client.signupTeam(email,
Client.signupTeam(email,
function success(data) {
if (data.follow_link) {
window.location.href = data.follow_link;
@@ -56,23 +61,20 @@ module.exports = React.createClass({
this.setState(this.state);
}.bind(this)
);
},
getInitialState: function() {
return {useDiff: false};
},
handleKeyPress: function(event) {
}
handleKeyPress(event) {
if (event.keyCode === 13) {
this.submitNext(event);
}
},
componentWillMount: function() {
}
componentWillMount() {
document.addEventListener('keyup', this.handleKeyPress, false);
},
componentWillUnmount: function() {
}
componentWillUnmount() {
document.removeEventListener('keyup', this.handleKeyPress, false);
},
render: function() {
client.track('signup', 'signup_team_01_welcome');
}
render() {
Client.track('signup', 'signup_team_01_welcome');
var storageError = null;
if (this.state.storageError) {
@@ -105,7 +107,10 @@ module.exports = React.createClass({
return (
<div>
<p>
<img className='signup-team-logo' src='/static/images/logo.png' />
<img
className='signup-team-logo'
src='/static/images/logo.png'
/>
<h3 className='sub-heading'>Welcome to:</h3>
<h1 className='margin--top-none'>{config.SiteName}</h1>
</p>
@@ -121,7 +126,14 @@ module.exports = React.createClass({
You can add other administrators later.
</p>
<div className='form-group'>
<button className='btn-primary btn form-group' type='submit' onClick={this.submitNext}><i className='glyphicon glyphicon-ok'></i>Yes, this address is correct</button>
<button
className='btn-primary btn form-group'
type='submit'
onClick={this.submitNext}
>
<i className='glyphicon glyphicon-ok'></i>
Yes, this address is correct
</button>
{storageError}
</div>
<hr />
@@ -129,16 +141,42 @@ module.exports = React.createClass({
<div className={emailDivClass}>
<div className='row'>
<div className='col-sm-9'>
<input type='email' ref='email' className='form-control' placeholder='Email Address' maxLength='128' />
<input
type='email'
ref='email'
className='form-control'
placeholder='Email Address'
maxLength='128'
/>
</div>
</div>
{emailError}
</div>
{serverError}
<button className='btn btn-md btn-primary' type='button' onClick={this.handleDiffSubmit}>Use this instead</button>
<button
className='btn btn-md btn-primary'
type='button'
onClick={this.handleDiffSubmit}
>
Use this instead
</button>
</div>
<a href='#' onClick={this.handleDiffEmail} className={differentEmailLinkClass}>Use a different email</a>
<a
href='#'
onClick={this.handleDiffEmail}
className={differentEmailLinkClass}
>
Use a different email
</a>
</div>
);
}
});
}
TeamSignupWelcomePage.defaultProps = {
state: {}
};
TeamSignupWelcomePage.propTypes = {
updateParent: React.PropTypes.func.isRequired,
state: React.PropTypes.object
};

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

@@ -4,51 +4,75 @@
var SettingsSidebar = require('./settings_sidebar.jsx');
var UserSettings = require('./user_settings.jsx');
module.exports = React.createClass({
componentDidMount: function() {
$('body').on('click', '.modal-back', function(){
export default class UserSettingsModal extends React.Component {
constructor(props) {
super(props);
this.updateTab = this.updateTab.bind(this);
this.updateSection = this.updateSection.bind(this);
this.state = {active_tab: 'general', active_section: ''};
}
componentDidMount() {
$('body').on('click', '.modal-back', function changeDisplay() {
$(this).closest('.modal-dialog').removeClass('display--content');
});
$('body').on('click', '.modal-header .close', function(){
setTimeout(function() {
$('body').on('click', '.modal-header .close', function closeModal() {
setTimeout(function finishClose() {
$('.modal-dialog.display--content').removeClass('display--content');
}, 500);
});
},
updateTab: function(tab) {
this.setState({ active_tab: tab });
},
updateSection: function(section) {
this.setState({ active_section: section });
},
getInitialState: function() {
return { active_tab: "general", active_section: "" };
},
render: function() {
}
updateTab(tab) {
this.setState({active_tab: tab});
}
updateSection(section) {
this.setState({active_section: section});
}
render() {
var tabs = [];
tabs.push({name: "general", uiName: "General", icon: "glyphicon glyphicon-cog"});
tabs.push({name: "security", uiName: "Security", icon: "glyphicon glyphicon-lock"});
tabs.push({name: "notifications", uiName: "Notifications", icon: "glyphicon glyphicon-exclamation-sign"});
tabs.push({name: "appearance", uiName: "Appearance", icon: "glyphicon glyphicon-wrench"});
tabs.push({name: 'general', uiName: 'General', icon: 'glyphicon glyphicon-cog'});
tabs.push({name: 'security', uiName: 'Security', icon: 'glyphicon glyphicon-lock'});
tabs.push({name: 'notifications', uiName: 'Notifications', icon: 'glyphicon glyphicon-exclamation-sign'});
tabs.push({name: 'appearance', uiName: 'Appearance', icon: 'glyphicon glyphicon-wrench'});
return (
<div className="modal fade" ref="modal" id="user_settings" role="dialog" tabIndex="-1" aria-hidden="true">
<div className="modal-dialog settings-modal">
<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" ref="title">Account Settings</h4>
<div
className='modal fade'
ref='modal'
id='user_settings'
role='dialog'
tabIndex='-1'
aria-hidden='true'
>
<div className='modal-dialog settings-modal'>
<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'
ref='title'
>
Account Settings
</h4>
</div>
<div className="modal-body">
<div className="settings-table">
<div className="settings-links">
<div className='modal-body'>
<div className='settings-table'>
<div className='settings-links'>
<SettingsSidebar
tabs={tabs}
activeTab={this.state.active_tab}
updateTab={this.updateTab}
/>
</div>
<div className="settings-content minimize-settings">
<div className='settings-content minimize-settings'>
<UserSettings
activeTab={this.state.active_tab}
activeSection={this.state.active_section}
@@ -63,4 +87,4 @@ module.exports = React.createClass({
</div>
);
}
});
}

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

@@ -229,7 +229,7 @@ export default class NotificationsTab extends React.Component {
let inputs = [];
inputs.push(
<div>
<div key='userNotificationLevelOption'>
<div className='radio'>
<label>
<input type='radio'
@@ -276,7 +276,7 @@ export default class NotificationsTab extends React.Component {
<div className='setting-list__hint'>
These settings will override the global notification settings for the <b>{this.state.curChannel}</b> channel
</div>
)
);
desktopSection = (
<SettingItemMax
@@ -324,7 +324,7 @@ export default class NotificationsTab extends React.Component {
let inputs = [];
inputs.push(
<div>
<div key='userNotificationSoundOptions'>
<div className='radio'>
<label>
<input
@@ -403,7 +403,7 @@ export default class NotificationsTab extends React.Component {
let inputs = [];
inputs.push(
<div>
<div key='userNotificationEmailOptions'>
<div className='radio'>
<label>
<input
@@ -483,7 +483,7 @@ export default class NotificationsTab extends React.Component {
self.updateFirstNameKey(e.target.checked);
};
inputs.push(
<div>
<div key='userNotificationFirstNameOption'>
<div className='checkbox'>
<label>
<input
@@ -503,7 +503,7 @@ export default class NotificationsTab extends React.Component {
self.updateUsernameKey(e.target.checked);
};
inputs.push(
<div>
<div key='userNotificationUsernameOption'>
<div className='checkbox'>
<label>
<input
@@ -522,7 +522,7 @@ export default class NotificationsTab extends React.Component {
self.updateMentionKey(e.target.checked);
};
inputs.push(
<div>
<div key='userNotificationMentionOption'>
<div className='checkbox'>
<label>
<input
@@ -541,7 +541,7 @@ export default class NotificationsTab extends React.Component {
self.updateAllKey(e.target.checked);
};
inputs.push(
<div>
<div key='userNotificationAllOption'>
<div className='checkbox'>
<label>
<input
@@ -560,7 +560,7 @@ export default class NotificationsTab extends React.Component {
self.updateChannelKey(e.target.checked);
};
inputs.push(
<div>
<div key='userNotificationChannelOption'>
<div className='checkbox'>
<label>
<input
@@ -576,7 +576,7 @@ export default class NotificationsTab extends React.Component {
);
inputs.push(
<div>
<div key='userNotificationCustomOption'>
<div className='checkbox'>
<label>
<input

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

@@ -8,23 +8,21 @@ var Constants = require('../utils/constants.jsx');
var PayloadSources = Constants.PayloadSources;
var AppDispatcher = assign(new Dispatcher(), {
handleServerAction: function performServerAction(action) {
var payload = {
source: PayloadSources.SERVER_ACTION,
action: action
};
this.dispatch(payload);
},
handleServerAction: function(action) {
var payload = {
source: PayloadSources.SERVER_ACTION,
action: action
};
this.dispatch(payload);
},
handleViewAction: function(action) {
var payload = {
source: PayloadSources.VIEW_ACTION,
action: action
};
this.dispatch(payload);
}
handleViewAction: function performViewAction(action) {
var payload = {
source: PayloadSources.VIEW_ACTION,
action: action
};
this.dispatch(payload);
}
});
module.exports = AppDispatcher;