@@ -89,10 +89,6 @@ export default class PermalinkView extends React.Component {
}
}
-PermalinkView.defaultProps = {
-};
-
PermalinkView.propTypes = {
- params: React.PropTypes.object.isRequired,
- profiles: React.PropTypes.object
+ params: React.PropTypes.object.isRequired
};
diff --git a/webapp/components/post_body.jsx b/webapp/components/post_body.jsx
index 884dbbbbb0..a159dcbb18 100644
--- a/webapp/components/post_body.jsx
+++ b/webapp/components/post_body.jsx
@@ -10,24 +10,13 @@ import * as TextFormatting from 'utils/text_formatting.jsx';
import twemoji from 'twemoji';
import PostBodyAdditionalContent from './post_body_additional_content.jsx';
-import {intlShape, injectIntl, defineMessages, FormattedMessage} from 'react-intl';
+import {FormattedMessage} from 'react-intl';
import loadingGif from 'images/load.gif';
-const holders = defineMessages({
- plusOne: {
- id: 'post_body.plusOne',
- defaultMessage: ' plus 1 other file'
- },
- plusMore: {
- id: 'post_body.plusMore',
- defaultMessage: ' plus {count} other files'
- }
-});
-
import React from 'react';
-class PostBody extends React.Component {
+export default class PostBody extends React.Component {
constructor(props) {
super(props);
@@ -61,8 +50,27 @@ class PostBody extends React.Component {
this.parseEmojis();
}
+ shouldComponentUpdate(nextProps) {
+ if (!Utils.areObjectsEqual(nextProps.post, this.props.post)) {
+ return true;
+ }
+
+ if (!Utils.areObjectsEqual(nextProps.parentPost, this.props.parentPost)) {
+ return true;
+ }
+
+ if (nextProps.retryPost.toString() !== this.props.retryPost.toString()) {
+ return true;
+ }
+
+ if (nextProps.handleCommentClick.toString() !== this.props.handleCommentClick.toString()) {
+ return true;
+ }
+
+ return false;
+ }
+
render() {
- const {formatMessage} = this.props.intl;
const post = this.props.post;
const filenames = this.props.post.filenames;
const parentPost = this.props.parentPost;
@@ -106,9 +114,9 @@ class PostBody extends React.Component {
message = parentPost.filenames[0].split('/').pop();
if (parentPost.filenames.length === 2) {
- message += formatMessage(holders.plusOne);
+ message += Utils.localizeMessage('post_body.plusOne', ' plus 1 other file');
} else if (parentPost.filenames.length > 2) {
- message += formatMessage(holders.plusMore, {count: (parentPost.filenames.length - 1)});
+ message += Utils.localizeMessage('post_body.plusMore', ' plus {count} other files').replace('{count}', (parentPost.filenames.length - 1).toString());
}
}
@@ -119,8 +127,8 @@ class PostBody extends React.Component {
id='post_body.commentedOn'
defaultMessage='Commented on {name}{apostrophe} message: '
values={{
- name: (name),
- apostrophe: apostrophe
+ name,
+ apostrophe
}}
/>
);
}
}
-PostFocusView.defaultProps = {
-};
-
-PostFocusView.propTypes = {
- profiles: React.PropTypes.object
-};
diff --git a/webapp/components/posts_view.jsx b/webapp/components/posts_view.jsx
index be098086f6..327756723a 100644
--- a/webapp/components/posts_view.jsx
+++ b/webapp/components/posts_view.jsx
@@ -2,19 +2,25 @@
// See License.txt for license information.
import $ from 'jquery';
-import ReactDOM from 'react-dom';
-import PreferenceStore from 'stores/preference_store.jsx';
-import * as GlobalActions from 'action_creators/global_actions.jsx';
-import * as Utils from 'utils/utils.jsx';
+
import Post from './post.jsx';
-import Constants from 'utils/constants.jsx';
+import FloatingTimestamp from './floating_timestamp.jsx';
+
+import * as GlobalActions from 'action_creators/global_actions.jsx';
+
+import PreferenceStore from 'stores/preference_store.jsx';
+import UserStore from 'stores/user_store.jsx';
+
+import * as Utils from 'utils/utils.jsx';
import DelayedAction from 'utils/delayed_action.jsx';
+import Constants from 'utils/constants.jsx';
+const Preferences = Constants.Preferences;
+
import {FormattedDate, FormattedMessage} from 'react-intl';
-const Preferences = Constants.Preferences;
-
import React from 'react';
+import ReactDOM from 'react-dom';
export default class PostsView extends React.Component {
constructor(props) {
@@ -31,6 +37,7 @@ export default class PostsView extends React.Component {
this.handleResize = this.handleResize.bind(this);
this.scrollToBottom = this.scrollToBottom.bind(this);
this.scrollToBottomAnimated = this.scrollToBottomAnimated.bind(this);
+ this.onUserChange = this.onUserChange.bind(this);
this.jumpToPostNode = null;
this.wasAtBottom = true;
@@ -43,7 +50,9 @@ export default class PostsView extends React.Component {
centerPosts: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.CHANNEL_DISPLAY_MODE, Preferences.CHANNEL_DISPLAY_MODE_DEFAULT) === Preferences.CHANNEL_DISPLAY_MODE_CENTERED,
isScrolling: false,
topPostId: null,
- showUnreadMessageAlert: false
+ showUnreadMessageAlert: false,
+ currentUser: UserStore.getCurrentUser(),
+ profiles: UserStore.getProfiles()
};
}
static get SCROLL_TYPE_FREE() {
@@ -67,6 +76,9 @@ export default class PostsView extends React.Component {
centerPosts: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.CHANNEL_DISPLAY_MODE, Preferences.CHANNEL_DISPLAY_MODE_DEFAULT) === Preferences.CHANNEL_DISPLAY_MODE_CENTERED
});
}
+ onUserChange() {
+ this.setState({currentUser: UserStore.getCurrentUser(), profiles: UserStore.getProfiles()});
+ }
isAtBottom() {
// consider the view to be at the bottom if it's within this many pixels of the bottom
const atBottomMargin = 10;
@@ -152,8 +164,8 @@ export default class PostsView extends React.Component {
createPosts(posts, order) {
const postCtls = [];
let previousPostDay = new Date(0);
- const userId = this.props.currentUser.id;
- const profiles = this.props.profiles || {};
+ const userId = this.state.currentUser.id;
+ const profiles = this.state.profiles || {};
let renderedLastViewed = false;
@@ -229,8 +241,8 @@ export default class PostsView extends React.Component {
const shouldHighlight = this.props.postsToHighlight && this.props.postsToHighlight.hasOwnProperty(post.id);
let profile;
- if (this.props.currentUser.id === post.user_id) {
- profile = this.props.currentUser;
+ if (userId === post.user_id) {
+ profile = this.state.currentUser;
} else {
profile = profiles[post.user_id];
}
@@ -250,7 +262,7 @@ export default class PostsView extends React.Component {
onClick={() => GlobalActions.emitPostFocusEvent(post.id)} //eslint-disable-line no-loop-func
displayNameType={this.state.displayNameType}
user={profile}
- currentUser={this.props.currentUser}
+ currentUser={this.state.currentUser}
center={this.state.centerPosts}
/>
);
@@ -377,13 +389,19 @@ export default class PostsView extends React.Component {
if (this.props.postList != null) {
this.updateScrolling();
}
+
+ if (this.props.isActive) {
+ PreferenceStore.addChangeListener(this.updateState);
+ UserStore.addChangeListener(this.onUserChange);
+ }
+
window.addEventListener('resize', this.handleResize);
- PreferenceStore.addChangeListener(this.updateState);
}
componentWillUnmount() {
window.removeEventListener('resize', this.handleResize);
this.scrollStopAction.cancel();
PreferenceStore.removeChangeListener(this.updateState);
+ UserStore.removeChangeListener(this.onUserChange);
}
componentDidUpdate() {
if (this.props.postList != null) {
@@ -401,8 +419,10 @@ export default class PostsView extends React.Component {
if (!this.props.isActive && nextProps.isActive) {
this.updateState();
PreferenceStore.addChangeListener(this.updateState);
+ UserStore.addChangeListener(this.onUserChange);
} else if (this.props.isActive && !nextProps.isActive) {
PreferenceStore.removeChangeListener(this.updateState);
+ UserStore.removeChangeListener(this.onUserChange);
}
}
shouldComponentUpdate(nextProps, nextState) {
@@ -436,7 +456,7 @@ export default class PostsView extends React.Component {
if (this.state.centerPosts !== nextState.centerPosts) {
return true;
}
- if (!Utils.areObjectsEqual(this.props.profiles, nextProps.profiles)) {
+ if (!Utils.areObjectsEqual(this.state.profiles, nextState.profiles)) {
return true;
}
@@ -497,16 +517,17 @@ export default class PostsView extends React.Component {
}
}
- let topPost = null;
+ let topPostCreateAt = 0;
if (this.state.topPostId) {
- topPost = this.props.postList.posts[this.state.topPostId];
+ topPostCreateAt = this.props.postList.posts[this.state.topPostId].create_at;
}
return (