summaryrefslogtreecommitdiffstats
path: root/web/react
diff options
context:
space:
mode:
Diffstat (limited to 'web/react')
-rw-r--r--web/react/components/channel_loader.jsx3
-rw-r--r--web/react/components/create_post.jsx91
-rw-r--r--web/react/components/file_attachment.jsx11
-rw-r--r--web/react/components/member_list.jsx2
-rw-r--r--web/react/components/more_direct_channels.jsx3
-rw-r--r--web/react/components/post.jsx2
-rw-r--r--web/react/components/post_list.jsx13
-rw-r--r--web/react/components/signup_team_complete.jsx46
-rw-r--r--web/react/components/user_settings.jsx203
-rw-r--r--web/react/stores/post_store.jsx17
-rw-r--r--web/react/utils/async_client.jsx12
-rw-r--r--web/react/utils/constants.jsx4
-rw-r--r--web/react/utils/utils.jsx2
13 files changed, 168 insertions, 241 deletions
diff --git a/web/react/components/channel_loader.jsx b/web/react/components/channel_loader.jsx
index b7cb248db..6b80f6012 100644
--- a/web/react/components/channel_loader.jsx
+++ b/web/react/components/channel_loader.jsx
@@ -8,6 +8,7 @@
var BrowserStore = require('../stores/browser_store.jsx');
var AsyncClient = require('../utils/async_client.jsx');
var SocketStore = require('../stores/socket_store.jsx');
+var ChannelStore = require('../stores/channel_store.jsx');
var Constants = require('../utils/constants.jsx');
module.exports = React.createClass({
@@ -15,7 +16,7 @@ module.exports = React.createClass({
/* Start initial aysnc loads */
AsyncClient.getMe();
- AsyncClient.getPosts(true);
+ AsyncClient.getPosts(true, ChannelStore.getCurrentId(), Constants.POST_CHUNK_SIZE);
AsyncClient.getChannels(true, true);
AsyncClient.getChannelExtraInfo(true);
AsyncClient.findTeams();
diff --git a/web/react/components/create_post.jsx b/web/react/components/create_post.jsx
index 327520210..76286eb88 100644
--- a/web/react/components/create_post.jsx
+++ b/web/react/components/create_post.jsx
@@ -31,11 +31,6 @@ module.exports = React.createClass({
post.message = this.state.messageText;
- // if this is a reply, trim off any carets from the beginning of a message
- if (this.state.rootId && post.message[0] === "^") {
- post.message = post.message.replace(/^\^+\s*/g, "");
- }
-
if (post.message.trim().length === 0 && this.state.previews.length === 0) {
return;
}
@@ -73,9 +68,6 @@ module.exports = React.createClass({
post.channel_id = this.state.channel_id;
post.filenames = this.state.previews;
- post.root_id = this.state.rootId;
- post.parent_id = this.state.parentId;
-
client.createPost(post, ChannelStore.getCurrent(),
function(data) {
PostStore.storeDraft(data.channel_id, null);
@@ -92,12 +84,7 @@ module.exports = React.createClass({
}.bind(this),
function(err) {
var state = {}
-
- if (err.message === "Invalid RootId parameter") {
- if ($('#post_deleted').length > 0) $('#post_deleted').modal('show');
- } else {
- state.server_error = err.message;
- }
+ state.server_error = err.message;
state.submitting = false;
this.setState(state);
@@ -106,17 +93,6 @@ module.exports = React.createClass({
}
$(".post-list-holder-by-time").perfectScrollbar('update');
-
- if (this.state.rootId || this.state.parentId) {
- this.setState({rootId: "", parentId: "", caretCount: 0});
-
- // clear the active thread since we've now sent our message
- AppDispatcher.handleViewAction({
- type: ActionTypes.RECEIVED_ACTIVE_THREAD_CHANGED,
- root_id: "",
- parent_id: ""
- });
- }
},
componentDidUpdate: function() {
this.resizePostHolder();
@@ -138,62 +114,6 @@ module.exports = React.createClass({
this.resizePostHolder();
this.setState({messageText: messageText});
- // look to see if the message begins with any carets to indicate that it's a reply
- var replyMatch = messageText.match(/^\^+/g);
- if (replyMatch) {
- // the number of carets indicates how many message threads back we're replying to
- var caretCount = replyMatch[0].length;
-
- // note that if someone else replies to this thread while a user is typing a reply, the message to which they're replying
- // won't change unless they change the number of carets. this is probably the desired behaviour since we don't want the
- // active message thread to change without the user noticing
- if (caretCount != this.state.caretCount) {
- this.setState({caretCount: caretCount});
-
- var posts = PostStore.getCurrentPosts();
-
- var rootId = "";
-
- // find the nth most recent post that isn't a comment on another (ie it has no parent) where n is caretCount
- for (var i = 0; i < posts.order.length; i++) {
- var postId = posts.order[i];
-
- if (posts.posts[postId].parent_id === "") {
- caretCount -= 1;
-
- if (caretCount < 1) {
- rootId = postId;
- break;
- }
- }
- }
-
- // only dispatch an event if something changed
- if (rootId != this.state.rootId) {
- // set the parent id to match the root id so that we're replying to the first post in the thread
- var parentId = rootId;
-
- // alert the post list so that it can display the active thread
- AppDispatcher.handleViewAction({
- type: ActionTypes.RECEIVED_ACTIVE_THREAD_CHANGED,
- root_id: rootId,
- parent_id: parentId
- });
- }
- }
- } else {
- if (this.state.caretCount > 0) {
- this.setState({caretCount: 0});
-
- // clear the active thread since there no longer is one
- AppDispatcher.handleViewAction({
- type: ActionTypes.RECEIVED_ACTIVE_THREAD_CHANGED,
- root_id: "",
- parent_id: ""
- });
- }
- }
-
var draft = PostStore.getCurrentDraft();
if (!draft) {
draft = {}
@@ -256,12 +176,10 @@ module.exports = React.createClass({
},
componentDidMount: function() {
ChannelStore.addChangeListener(this._onChange);
- PostStore.addActiveThreadChangedListener(this._onActiveThreadChanged);
this.resizePostHolder();
},
componentWillUnmount: function() {
ChannelStore.removeChangeListener(this._onChange);
- PostStore.removeActiveThreadChangedListener(this._onActiveThreadChanged);
},
_onChange: function() {
var channel_id = ChannelStore.getCurrentId();
@@ -278,11 +196,6 @@ module.exports = React.createClass({
this.setState({ channel_id: channel_id, messageText: messageText, initialText: messageText, submitting: false, limit_error: null, server_error: null, post_error: null, previews: previews, uploadsInProgress: uploadsInProgress });
}
},
- _onActiveThreadChanged: function(rootId, parentId) {
- // note that we register for our own events and set the state from there so we don't need to manually set
- // our state and dispatch an event each time the active thread changes
- this.setState({"rootId": rootId, "parentId": parentId});
- },
getInitialState: function() {
PostStore.clearDraftUploads();
@@ -293,7 +206,7 @@ module.exports = React.createClass({
previews = draft['previews'];
messageText = draft['message'];
}
- return { channel_id: ChannelStore.getCurrentId(), messageText: messageText, uploadsInProgress: 0, previews: previews, submitting: false, initialText: messageText, caretCount: 0 };
+ return { channel_id: ChannelStore.getCurrentId(), messageText: messageText, uploadsInProgress: 0, previews: previews, submitting: false, initialText: messageText };
},
setUploads: function(val) {
var oldInProgress = this.state.uploadsInProgress
diff --git a/web/react/components/file_attachment.jsx b/web/react/components/file_attachment.jsx
index 3cd791887..b7ea5734f 100644
--- a/web/react/components/file_attachment.jsx
+++ b/web/react/components/file_attachment.jsx
@@ -2,6 +2,7 @@
// See License.txt for license information.
var utils = require('../utils/utils.jsx');
+var Constants = require('../utils/constants.jsx');
module.exports = React.createClass({
displayName: "FileAttachment",
@@ -44,6 +45,16 @@ module.exports = React.createClass({
$(imgDiv).removeClass('post__load');
$(imgDiv).addClass('post__image');
+ var width = this.width || $(this).width();
+ var height = this.height || $(this).height();
+
+ if (width < Constants.THUMBNAIL_WIDTH
+ && height < Constants.THUMBNAIL_HEIGHT) {
+ $(imgDiv).addClass('small');
+ } else {
+ $(imgDiv).addClass('normal');
+ }
+
var re1 = new RegExp(' ', 'g');
var re2 = new RegExp('\\(', 'g');
var re3 = new RegExp('\\)', 'g');
diff --git a/web/react/components/member_list.jsx b/web/react/components/member_list.jsx
index a37392f96..69da5cfc3 100644
--- a/web/react/components/member_list.jsx
+++ b/web/react/components/member_list.jsx
@@ -13,7 +13,7 @@ module.exports = React.createClass({
var message = "";
if (members.length === 0)
- message = <span>No users to add or manage.</span>;
+ message = <span>No users to add.</span>;
return (
<div className="member-list-holder">
diff --git a/web/react/components/more_direct_channels.jsx b/web/react/components/more_direct_channels.jsx
index 182d8884d..901cd228f 100644
--- a/web/react/components/more_direct_channels.jsx
+++ b/web/react/components/more_direct_channels.jsx
@@ -2,6 +2,7 @@
// See License.txt for license information.
var ChannelStore = require('../stores/channel_store.jsx');
+var TeamStore = require('../stores/team_store.jsx');
var utils = require('../utils/utils.jsx');
module.exports = React.createClass({
@@ -35,7 +36,7 @@ module.exports = React.createClass({
);
} else {
return (
- <li key={channel.name} className={active}><a className={"sidebar-channel " + titleClass} href={"/channels/"+channel.name}>{badge}{channel.display_name}</a></li>
+ <li key={channel.name} className={active}><a className={"sidebar-channel " + titleClass} href={TeamStore.getCurrentTeamUrl() + "/channels/"+channel.name}>{badge}{channel.display_name}</a></li>
);
}
});
diff --git a/web/react/components/post.jsx b/web/react/components/post.jsx
index e3586ecde..e72a2d001 100644
--- a/web/react/components/post.jsx
+++ b/web/react/components/post.jsx
@@ -83,7 +83,7 @@ module.exports = React.createClass({
<img className="post-profile-img" src={"/api/v1/users/" + post.user_id + "/image?time=" + timestamp} height="36" width="36" />
</div>
: null }
- <div className={"post__content" + (this.props.isActiveThread ? " active-thread__content" : "")}>
+ <div className="post__content">
<PostHeader ref="header" post={post} sameRoot={this.props.sameRoot} commentCount={commentCount} handleCommentClick={this.handleCommentClick} isLastComment={this.props.isLastComment} />
<PostBody post={post} sameRoot={this.props.sameRoot} parentPost={parentPost} posts={posts} handleCommentClick={this.handleCommentClick} />
<PostInfo ref="info" post={post} sameRoot={this.props.sameRoot} commentCount={commentCount} handleCommentClick={this.handleCommentClick} allowReply="true" />
diff --git a/web/react/components/post_list.jsx b/web/react/components/post_list.jsx
index 46f77660d..3f59d5843 100644
--- a/web/react/components/post_list.jsx
+++ b/web/react/components/post_list.jsx
@@ -22,8 +22,7 @@ function getStateFromStores() {
return {
post_list: PostStore.getCurrentPosts(),
- channel: channel,
- activeThreadRootId: ""
+ channel: channel
};
}
@@ -52,7 +51,6 @@ module.exports = React.createClass({
ChannelStore.addChangeListener(this._onChange);
UserStore.addStatusesChangeListener(this._onTimeChange);
SocketStore.addChangeListener(this._onSocketChange);
- PostStore.addActiveThreadChangedListener(this._onActiveThreadChanged);
$(".post-list-holder-by-time").perfectScrollbar();
@@ -133,7 +131,6 @@ module.exports = React.createClass({
ChannelStore.removeChangeListener(this._onChange);
UserStore.removeStatusesChangeListener(this._onTimeChange);
SocketStore.removeChangeListener(this._onSocketChange);
- PostStore.removeActiveThreadChangedListener(this._onActiveThreadChanged);
$('body').off('click.userpopover');
},
resize: function() {
@@ -232,9 +229,6 @@ module.exports = React.createClass({
this.refs[id].forceUpdateInfo();
}
},
- _onActiveThreadChanged: function(rootId, parentId) {
- this.setState({"activeThreadRootId": rootId});
- },
getMorePosts: function(e) {
e.preventDefault();
@@ -429,12 +423,9 @@ module.exports = React.createClass({
// it is the last comment if it is last post in the channel or the next post has a different root post
var isLastComment = utils.isComment(post) && (i === 0 || posts[order[i-1]].root_id != post.root_id);
- // check if this is part of the thread that we're currently replying to
- var isActiveThread = this.state.activeThreadRootId && (post.id === this.state.activeThreadRootId || post.root_id === this.state.activeThreadRootId);
-
var postCtl = (
<Post ref={post.id} sameUser={sameUser} sameRoot={sameRoot} post={post} parentPost={parentPost} key={post.id}
- posts={posts} hideProfilePic={hideProfilePic} isLastComment={isLastComment} isActiveThread={isActiveThread}
+ posts={posts} hideProfilePic={hideProfilePic} isLastComment={isLastComment}
/>
);
diff --git a/web/react/components/signup_team_complete.jsx b/web/react/components/signup_team_complete.jsx
index 83daa3b1f..447a405bd 100644
--- a/web/react/components/signup_team_complete.jsx
+++ b/web/react/components/signup_team_complete.jsx
@@ -496,60 +496,58 @@ SendInivtesPage = React.createClass({
});
UsernamePage = React.createClass({
- submitBack: function (e) {
+ submitBack: function(e) {
e.preventDefault();
- this.props.state.wizard = "send_invites";
+ this.props.state.wizard = 'send_invites';
this.props.updateParent(this.props.state);
},
- submitNext: function (e) {
+ submitNext: function(e) {
e.preventDefault();
var name = this.refs.name.getDOMNode().value.trim();
var username_error = utils.isValidUsername(name);
- if (username_error === "Cannot use a reserved word as a username.") {
- this.setState({name_error: "This username is reserved, please choose a new one." });
+ if (username_error === 'Cannot use a reserved word as a username.') {
+ this.setState({name_error: 'This username is reserved, please choose a new one.'});
return;
} else if (username_error) {
- this.setState({name_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({name_error: "Username must begin with a letter, and contain 3 to 15 characters in total, which may be numbers, lowercase letters, or any of the symbols '.', '-', or '_'"});
return;
}
-
- this.props.state.wizard = "password";
+ this.props.state.wizard = 'password';
this.props.state.user.username = name;
this.props.updateParent(this.props.state);
},
getInitialState: function() {
- return { };
+ return {};
},
render: function() {
-
client.track('signup', 'signup_team_06_username');
- var name_error = this.state.name_error ? <label className="control-label">{ this.state.name_error }</label> : null;
+ var name_error = this.state.name_error ? <label className='control-label'>{this.state.name_error}</label> : null;
return (
<div>
<form>
- <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">
- <div className={ name_error ? "form-group has-error" : "form-group" }>
- <div className="row">
- <div className="col-sm-11">
+ <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'>
+ <div className={name_error ? 'form-group has-error' : 'form-group'}>
+ <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" />
- <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>
+ <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>
- { name_error }
+ {name_error}
</div>
</div>
- <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>
+ <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>
</div>
</form>
</div>
diff --git a/web/react/components/user_settings.jsx b/web/react/components/user_settings.jsx
index 819d5494e..c574d2365 100644
--- a/web/react/components/user_settings.jsx
+++ b/web/react/components/user_settings.jsx
@@ -643,8 +643,8 @@ var GeneralTab = React.createClass({
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." });
+ if (username_error === 'Cannot use a reserved word as a username.') {
+ this.setState({client_error: '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 '_'." });
@@ -652,7 +652,7 @@ var GeneralTab = React.createClass({
}
if (user.username === username) {
- this.setState({client_error: "You must submit a new username"});
+ this.setState({client_error: 'You must submit a new username'});
return;
}
@@ -667,7 +667,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({client_error: 'You must submit a new nickname'})
return;
}
@@ -683,7 +683,7 @@ var GeneralTab = React.createClass({
var lastName = this.state.last_name.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({client_error: 'You must submit a new first or last name'})
return;
}
@@ -703,7 +703,7 @@ var GeneralTab = React.createClass({
}
if (email === '' || !utils.isEmail(email)) {
- this.setState({ email_error: "Please enter a valid email address" });
+ this.setState({ email_error: 'Please enter a valid email address' });
return;
}
@@ -713,16 +713,16 @@ var GeneralTab = React.createClass({
},
submitUser: function(user) {
client.updateUser(user,
- function(data) {
- this.updateSection("");
+ function() {
+ this.updateSection('');
AsyncClient.getMe();
}.bind(this),
function(err) {
state = this.getInitialState();
- if(err.message) {
+ if (err.message) {
state.server_error = err.message;
} else {
- state.server_error = err
+ state.server_error = err;
}
this.setState(state);
}.bind(this)
@@ -731,22 +731,26 @@ var GeneralTab = React.createClass({
submitPicture: function(e) {
e.preventDefault();
- if (!this.state.picture) return;
+ if (!this.state.picture) {
+ return;
+ }
- if(!this.submitActive) return;
+ if (!this.submitActive) {
+ return;
+ }
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"});
+ if (picture.type !== 'image/jpeg' && picture.type !== 'image/png') {
+ this.setState({client_error: 'Only JPG or PNG images may be used for profile pictures'});
return;
}
- formData = new FormData();
+ var formData = new FormData();
formData.append('image', picture, picture.name);
client.uploadProfileImage(formData,
- function(data) {
+ function() {
this.submitActive = false;
AsyncClient.getMe();
window.location.reload();
@@ -759,39 +763,39 @@ var GeneralTab = React.createClass({
);
},
updateUsername: function(e) {
- this.setState({ username: e.target.value });
+ this.setState({username: e.target.value});
},
updateFirstName: function(e) {
- this.setState({ first_name: e.target.value });
+ this.setState({first_name: e.target.value});
},
updateLastName: function(e) {
- this.setState({ last_name: e.target.value});
+ this.setState({last_name: e.target.value});
},
updateNickname: function(e) {
this.setState({nickname: e.target.value});
},
updateEmail: function(e) {
- this.setState({ email: e.target.value});
+ this.setState({email: e.target.value});
},
updatePicture: function(e) {
if (e.target.files && e.target.files[0]) {
this.setState({ picture: e.target.files[0] });
this.submitActive = true;
- this.setState({client_error:null})
+ this.setState({client_error: null});
} else {
- this.setState({ picture: null });
+ this.setState({picture: null});
}
},
updateSection: function(section) {
- this.setState({client_error:""})
- this.submitActive = false
+ this.setState({client_error:''});
+ this.submitActive = false;
this.props.updateSection(section);
},
handleClose: function() {
- $(this.getDOMNode()).find(".form-control").each(function() {
- this.value = "";
+ $(this.getDOMNode()).find('.form-control').each(function() {
+ this.value = '';
});
this.setState(assign({}, this.getInitialState(), {client_error: null, server_error: null, email_error: null}));
@@ -818,43 +822,45 @@ var GeneralTab = React.createClass({
var nameSection;
var self = this;
+ var inputs = [];
if (this.props.activeSection === 'name') {
- var inputs = [];
-
inputs.push(
- <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}/>
+ <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}/>
</div>
</div>
);
inputs.push(
- <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}/>
+ <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}/>
</div>
</div>
);
nameSection = (
<SettingItemMax
- title="Full Name"
+ title='Full Name'
inputs={inputs}
submit={this.submitName}
server_error={server_error}
client_error={client_error}
- updateSection={function(e){self.updateSection("");e.preventDefault();}}
+ updateSection={function(e) {
+ self.updateSection('');
+ e.preventDefault();
+ }}
/>
);
} else {
- var full_name = "";
+ var full_name = '';
if (user.first_name && user.last_name) {
- full_name = user.first_name + " " + user.last_name;
+ full_name = user.first_name + ' ' + user.last_name;
} else if (user.first_name) {
full_name = user.first_name;
} else if (user.last_name) {
@@ -863,107 +869,119 @@ var GeneralTab = React.createClass({
nameSection = (
<SettingItemMin
- title="Full Name"
+ title='Full Name'
describe={full_name}
- updateSection={function(){self.updateSection("name");}}
+ updateSection={function() {
+ self.updateSection('name');
+ }}
/>
);
}
var nicknameSection;
if (this.props.activeSection === 'nickname') {
- var inputs = [];
inputs.push(
- <div className="form-group">
- <label className="col-sm-5 control-label">{utils.isMobile() ? "": "Nickname"}</label>
- <div className="col-sm-7">
- <input className="form-control" type="text" onChange={this.updateNickname} value={this.state.nickname}/>
+ <div className='form-group'>
+ <label className='col-sm-5 control-label'>{utils.isMobile() ? '' : 'Nickname'}</label>
+ <div className='col-sm-7'>
+ <input className='form-control' type='text' onChange={this.updateNickname} value={this.state.nickname}/>
</div>
</div>
);
nicknameSection = (
<SettingItemMax
- title="Nickname"
+ title='Nickname'
inputs={inputs}
submit={this.submitNickname}
server_error={server_error}
client_error={client_error}
- updateSection={function(e){self.updateSection("");e.preventDefault();}}
+ updateSection={function(e) {
+ self.updateSection('');
+ e.preventDefault();
+ }}
/>
);
} else {
nicknameSection = (
<SettingItemMin
- title="Nickname"
+ title='Nickname'
describe={UserStore.getCurrentUser().nickname}
- updateSection={function(){self.updateSection("nickname");}}
+ updateSection={function() {
+ self.updateSection('nickname');
+ }}
/>
);
}
var usernameSection;
if (this.props.activeSection === 'username') {
- var inputs = [];
-
inputs.push(
- <div className="form-group">
- <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 className='form-group'>
+ <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>
</div>
);
usernameSection = (
<SettingItemMax
- title="Username"
+ title='Username'
inputs={inputs}
submit={this.submitUsername}
server_error={server_error}
client_error={client_error}
- updateSection={function(e){self.updateSection("");e.preventDefault();}}
+ updateSection={function(e) {
+ self.updateSection('');
+ e.preventDefault();
+ }}
/>
);
} else {
usernameSection = (
<SettingItemMin
- title="Username"
+ title='Username'
describe={UserStore.getCurrentUser().username}
- updateSection={function(){self.updateSection("username");}}
+ updateSection={function() {
+ self.updateSection('username');
+ }}
/>
);
}
var emailSection;
if (this.props.activeSection === 'email') {
- var inputs = [];
-
inputs.push(
- <div className="form-group">
- <label className="col-sm-5 control-label">Primary Email</label>
- <div className="col-sm-7">
- <input className="form-control" type="text" onChange={this.updateEmail} value={this.state.email}/>
+ <div className='form-group'>
+ <label className='col-sm-5 control-label'>Primary Email</label>
+ <div className='col-sm-7'>
+ <input className='form-control' type='text' onChange={this.updateEmail} value={this.state.email}/>
</div>
</div>
);
emailSection = (
<SettingItemMax
- title="Email"
+ title='Email'
inputs={inputs}
submit={this.submitEmail}
server_error={server_error}
client_error={email_error}
- updateSection={function(e){self.updateSection("");e.preventDefault();}}
+ updateSection={function(e) {
+ self.updateSection('');
+ e.preventDefault();
+ }}
/>
);
} else {
emailSection = (
<SettingItemMin
- title="Email"
+ title='Email'
describe={UserStore.getCurrentUser().email}
- updateSection={function(){self.updateSection("email");}}
+ updateSection={function() {
+ self.updateSection('email');
+ }}
/>
);
}
@@ -972,57 +990,60 @@ var GeneralTab = React.createClass({
if (this.props.activeSection === 'picture') {
pictureSection = (
<SettingPicture
- title="Profile Picture"
+ title='Profile Picture'
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}
client_error={client_error}
- updateSection={function(e){self.updateSection("");e.preventDefault();}}
+ updateSection={function(e) {
+ self.updateSection('');
+ e.preventDefault();
+ }}
picture={this.state.picture}
pictureChange={this.updatePicture}
submitActive={this.submitActive}
/>
);
-
} else {
- var minMessage = "Click Edit to upload an image.";
+ var minMessage = 'Click \'Edit\' to upload an image.';
if (user.last_picture_update) {
- minMessage = "Image last updated " + utils.displayDate(user.last_picture_update)
+ minMessage = 'Image last updated ' + utils.displayDate(user.last_picture_update);
}
pictureSection = (
<SettingItemMin
- title="Profile Picture"
+ title='Profile Picture'
describe={minMessage}
- updateSection={function(){self.updateSection("picture");}}
+ updateSection={function() {
+ self.updateSection('picture');
+ }}
/>
);
}
return (
<div>
- <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"><i className="modal-back"></i>General Settings</h4>
+ <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'><i className='modal-back'></i>General Settings</h4>
</div>
- <div className="user-settings">
- <h3 className="tab-header">General Settings</h3>
- <div className="divider-dark first"/>
+ <div className='user-settings'>
+ <h3 className='tab-header'>General Settings</h3>
+ <div className='divider-dark first'/>
{nameSection}
- <div className="divider-light"/>
+ <div className='divider-light'/>
{usernameSection}
- <div className="divider-light"/>
+ <div className='divider-light'/>
{nicknameSection}
- <div className="divider-light"/>
+ <div className='divider-light'/>
{emailSection}
- <div className="divider-light"/>
+ <div className='divider-light'/>
{pictureSection}
- <div className="divider-dark"/>
+ <div className='divider-dark'/>
</div>
</div>
);
}
});
-
var AppearanceTab = React.createClass({
submitTheme: function(e) {
e.preventDefault();
diff --git a/web/react/stores/post_store.jsx b/web/react/stores/post_store.jsx
index 0745fcdc3..ecf54ede6 100644
--- a/web/react/stores/post_store.jsx
+++ b/web/react/stores/post_store.jsx
@@ -18,7 +18,6 @@ var SEARCH_TERM_CHANGE_EVENT = 'search_term_change';
var SELECTED_POST_CHANGE_EVENT = 'selected_post_change';
var MENTION_DATA_CHANGE_EVENT = 'mention_data_change';
var ADD_MENTION_EVENT = 'add_mention';
-var ACTIVE_THREAD_CHANGED_EVENT = 'active_thread_changed';
var PostStore = assign({}, EventEmitter.prototype, {
@@ -94,18 +93,6 @@ var PostStore = assign({}, EventEmitter.prototype, {
this.removeListener(ADD_MENTION_EVENT, callback);
},
- emitActiveThreadChanged: function(rootId, parentId) {
- this.emit(ACTIVE_THREAD_CHANGED_EVENT, rootId, parentId);
- },
-
- addActiveThreadChangedListener: function(callback) {
- this.on(ACTIVE_THREAD_CHANGED_EVENT, callback);
- },
-
- removeActiveThreadChangedListener: function(callback) {
- this.removeListener(ACTIVE_THREAD_CHANGED_EVENT, callback);
- },
-
getCurrentPosts: function() {
var currentId = ChannelStore.getCurrentId();
@@ -211,10 +198,6 @@ PostStore.dispatchToken = AppDispatcher.register(function(payload) {
case ActionTypes.RECIEVED_ADD_MENTION:
PostStore.emitAddMention(action.id, action.username);
break;
- case ActionTypes.RECEIVED_ACTIVE_THREAD_CHANGED:
- PostStore.emitActiveThreadChanged(action.root_id, action.parent_id);
- break;
-
default:
}
});
diff --git a/web/react/utils/async_client.jsx b/web/react/utils/async_client.jsx
index 00bd83ed1..dc4fc1096 100644
--- a/web/react/utils/async_client.jsx
+++ b/web/react/utils/async_client.jsx
@@ -272,17 +272,23 @@ module.exports.search = function(terms) {
);
}
-module.exports.getPosts = function(force, id) {
+module.exports.getPosts = function(force, id, maxPosts) {
if (PostStore.getCurrentPosts() == null || force) {
var channelId = id ? id : ChannelStore.getCurrentId();
if (isCallInProgress("getPosts_"+channelId)) return;
var post_list = PostStore.getCurrentPosts();
+
+ if (!maxPosts) { maxPosts = Constants.POST_CHUNK_SIZE * Constants.MAX_POST_CHUNKS };
+
// if we already have more than POST_CHUNK_SIZE posts,
// let's get the amount we have but rounded up to next multiple of POST_CHUNK_SIZE,
- // with a max at 180
- var numPosts = post_list && post_list.order.length > 0 ? Math.min(180, Constants.POST_CHUNK_SIZE * Math.ceil(post_list.order.length / Constants.POST_CHUNK_SIZE)) : Constants.POST_CHUNK_SIZE;
+ // with a max at maxPosts
+ var numPosts = Math.min(maxPosts, Constants.POST_CHUNK_SIZE);
+ if (post_list && post_list.order.length > 0) {
+ numPosts = Math.min(maxPosts, Constants.POST_CHUNK_SIZE * Math.ceil(post_list.order.length / Constants.POST_CHUNK_SIZE));
+ }
if (channelId != null) {
callTracker["getPosts_"+channelId] = utils.getTimestamp();
diff --git a/web/react/utils/constants.jsx b/web/react/utils/constants.jsx
index 77ce19530..2b0976afd 100644
--- a/web/react/utils/constants.jsx
+++ b/web/react/utils/constants.jsx
@@ -18,7 +18,6 @@ module.exports = {
RECIEVED_POST_SELECTED: null,
RECIEVED_MENTION_DATA: null,
RECIEVED_ADD_MENTION: null,
- RECEIVED_ACTIVE_THREAD_CHANGED: null,
RECIEVED_PROFILES: null,
RECIEVED_ME: null,
@@ -52,9 +51,12 @@ module.exports = {
MAX_DISPLAY_FILES: 5,
MAX_UPLOAD_FILES: 5,
MAX_FILE_SIZE: 50000000, // 50 MB
+ THUMBNAIL_WIDTH: 128,
+ THUMBNAIL_HEIGHT: 100,
DEFAULT_CHANNEL: 'town-square',
OFFTOPIC_CHANNEL: 'off-topic',
POST_CHUNK_SIZE: 60,
+ MAX_POST_CHUNKS: 3,
RESERVED_TEAM_NAMES: [
"www",
"web",
diff --git a/web/react/utils/utils.jsx b/web/react/utils/utils.jsx
index 09240bf06..a759cc579 100644
--- a/web/react/utils/utils.jsx
+++ b/web/react/utils/utils.jsx
@@ -750,7 +750,7 @@ module.exports.switchChannel = function(channel, teammate_name) {
AsyncClient.getChannels(true, true, true);
AsyncClient.getChannelExtraInfo(true);
- AsyncClient.getPosts(true, channel.id);
+ AsyncClient.getPosts(true, channel.id, Constants.POST_CHUNK_SIZE);
$('.inner__wrap').removeClass('move--right');
$('.sidebar--left').removeClass('move--right');