From 1f049af2b7ea41a5e1e79a8263e10fa58f186c8d Mon Sep 17 00:00:00 2001 From: JoramWilander Date: Tue, 23 Feb 2016 11:09:59 -0500 Subject: Refactor listener out of user profile and fix thread logic --- web/react/components/delete_post_modal.jsx | 4 +- web/react/components/navbar.jsx | 2 +- web/react/components/post.jsx | 44 ++++---- web/react/components/post_body.jsx | 4 +- web/react/components/post_deleted_modal.jsx | 2 +- web/react/components/post_header.jsx | 10 +- web/react/components/posts_view.jsx | 27 +++-- web/react/components/posts_view_container.jsx | 11 +- web/react/components/rhs_comment.jsx | 30 +++-- web/react/components/rhs_header_post.jsx | 4 +- web/react/components/rhs_root_post.jsx | 24 ++-- web/react/components/rhs_thread.jsx | 149 ++++++++++--------------- web/react/components/search_bar.jsx | 2 +- web/react/components/search_results_header.jsx | 2 +- web/react/components/user_profile.jsx | 45 ++------ web/react/stores/post_store.jsx | 122 +++++++++----------- web/react/stores/user_store.jsx | 2 +- web/react/utils/utils.jsx | 4 + 18 files changed, 218 insertions(+), 270 deletions(-) diff --git a/web/react/components/delete_post_modal.jsx b/web/react/components/delete_post_modal.jsx index 773d0b420..f8e3e406a 100644 --- a/web/react/components/delete_post_modal.jsx +++ b/web/react/components/delete_post_modal.jsx @@ -68,7 +68,7 @@ export default class DeletePostModal extends React.Component { AppDispatcher.handleServerAction({ type: ActionTypes.RECEIVED_POST_SELECTED, - results: null + postId: null }); } else if (selectedPost.id === this.state.post.id && this.state.root_id) { if (selectedPost.root_id && selectedPost.root_id.length > 0 && selectedList.posts[selectedPost.root_id]) { @@ -77,7 +77,7 @@ export default class DeletePostModal extends React.Component { AppDispatcher.handleServerAction({ type: ActionTypes.RECEIVED_POST_SELECTED, - post_list: selectedList + postId: selectedPost.root_id }); AppDispatcher.handleServerAction({ diff --git a/web/react/components/navbar.jsx b/web/react/components/navbar.jsx index a06fb449b..76abf2b20 100644 --- a/web/react/components/navbar.jsx +++ b/web/react/components/navbar.jsx @@ -90,7 +90,7 @@ export default class Navbar extends React.Component { AppDispatcher.handleServerAction({ type: ActionTypes.RECEIVED_POST_SELECTED, - results: null + postId: null }); if (e.target.className !== 'navbar-toggle' && e.target.className !== 'icon-bar') { diff --git a/web/react/components/post.jsx b/web/react/components/post.jsx index 5a850d1c5..889d4311e 100644 --- a/web/react/components/post.jsx +++ b/web/react/components/post.jsx @@ -3,15 +3,18 @@ import PostHeader from './post_header.jsx'; import PostBody from './post_body.jsx'; -import AppDispatcher from '../dispatcher/app_dispatcher.jsx'; -import Constants from '../utils/constants.jsx'; + import UserStore from '../stores/user_store.jsx'; import PostStore from '../stores/post_store.jsx'; import ChannelStore from '../stores/channel_store.jsx'; -import * as client from '../utils/client.jsx'; + +import Constants from '../utils/constants.jsx'; +const ActionTypes = Constants.ActionTypes; + +import * as Client from '../utils/client.jsx'; import * as AsyncClient from '../utils/async_client.jsx'; -var ActionTypes = Constants.ActionTypes; -import * as utils from '../utils/utils.jsx'; +import * as Utils from '../utils/utils.jsx'; +import AppDispatcher from '../dispatcher/app_dispatcher.jsx'; export default class Post extends React.Component { constructor(props) { @@ -26,13 +29,9 @@ export default class Post extends React.Component { handleCommentClick(e) { e.preventDefault(); - var data = {}; - data.order = [this.props.post.id]; - data.posts = this.props.posts; - AppDispatcher.handleServerAction({ type: ActionTypes.RECEIVED_POST_SELECTED, - post_list: data + postId: Utils.getRootId(this.props.post) }); AppDispatcher.handleServerAction({ @@ -48,14 +47,14 @@ export default class Post extends React.Component { e.preventDefault(); var post = this.props.post; - client.createPost(post, post.channel_id, + Client.createPost(post, post.channel_id, (data) => { AsyncClient.getPosts(); var channel = ChannelStore.get(post.channel_id); var member = ChannelStore.getMember(post.channel_id); member.msg_count = channel.total_msg_count; - member.last_viewed_at = utils.getTimestamp(); + member.last_viewed_at = Utils.getTimestamp(); ChannelStore.setChannelMember(member); AppDispatcher.handleServerAction({ @@ -75,7 +74,7 @@ export default class Post extends React.Component { this.forceUpdate(); } shouldComponentUpdate(nextProps) { - if (!utils.areObjectsEqual(nextProps.post, this.props.post)) { + if (!Utils.areObjectsEqual(nextProps.post, this.props.post)) { return true; } @@ -129,6 +128,7 @@ export default class Post extends React.Component { const post = this.props.post; const parentPost = this.props.parentPost; const posts = this.props.posts; + const user = this.props.user || {}; if (!post.props) { post.props = {}; @@ -156,15 +156,13 @@ export default class Post extends React.Component { } let currentUserCss = ''; - if (UserStore.getCurrentId() === post.user_id && !post.props.from_webhook && !utils.isSystemMessage(post)) { + if (UserStore.getCurrentId() === post.user_id && !post.props.from_webhook && !Utils.isSystemMessage(post)) { currentUserCss = 'current--user'; } - const userProfile = UserStore.getProfile(post.user_id); - - let timestamp = UserStore.getCurrentUser().update_at; - if (userProfile) { - timestamp = userProfile.update_at; + let timestamp = user.update_at; + if (timestamp == null) { + timestamp = UserStore.getCurrentUser().update_at; } let sameUserClass = ''; @@ -178,18 +176,18 @@ export default class Post extends React.Component { } let systemMessageClass = ''; - if (utils.isSystemMessage(post)) { + if (Utils.isSystemMessage(post)) { systemMessageClass = 'post--system'; } let profilePic = null; if (!this.props.hideProfilePic) { - let src = '/api/v1/users/' + post.user_id + '/image?time=' + timestamp + '&' + utils.getSessionIndex(); + let src = '/api/v1/users/' + post.user_id + '/image?time=' + timestamp + '&' + Utils.getSessionIndex(); if (post.props && post.props.from_webhook && global.window.mm_config.EnablePostIconOverride === 'true') { if (post.props.override_icon_url) { src = post.props.override_icon_url; } - } else if (utils.isSystemMessage(post)) { + } else if (Utils.isSystemMessage(post)) { src = Constants.SYSTEM_MESSAGE_PROFILE_IMAGE; } @@ -219,6 +217,7 @@ export default class Post extends React.Component { handleCommentClick={this.handleCommentClick} isLastComment={this.props.isLastComment} sameUser={this.props.sameUser} + user={this.props.user} /> 1 + post: this.props.post }; } diff --git a/web/react/components/post_deleted_modal.jsx b/web/react/components/post_deleted_modal.jsx index be22989a6..1f5c15aa9 100644 --- a/web/react/components/post_deleted_modal.jsx +++ b/web/react/components/post_deleted_modal.jsx @@ -38,7 +38,7 @@ export default class PostDeletedModal extends React.Component { AppDispatcher.handleServerAction({ type: ActionTypes.RECEIVED_POST_SELECTED, - results: null + postId: null }); this.props.onHide(); diff --git a/web/react/components/post_header.jsx b/web/react/components/post_header.jsx index c52391daa..2803fe387 100644 --- a/web/react/components/post_header.jsx +++ b/web/react/components/post_header.jsx @@ -13,16 +13,17 @@ export default class PostHeader extends React.Component { this.state = {}; } render() { - var post = this.props.post; + const post = this.props.post; + const user = this.props.user; - let userProfile = ; + let userProfile = ; let botIndicator; if (post.props && post.props.from_webhook) { if (post.props.override_username && global.window.mm_config.EnablePostUsernameOverride === 'true') { userProfile = ( @@ -33,7 +34,7 @@ export default class PostHeader extends React.Component { } else if (Utils.isSystemMessage(post)) { userProfile = ( EventHelpers.emitPostFocusEvent(post.id)} //eslint-disable-line no-loop-func displayNameType={this.state.displayNameType} - hasProfiles={this.state.hasProfiles} + hasProfiles={profiles && Object.keys(profiles).length > 1} + user={profile} /> ); @@ -370,11 +377,9 @@ export default class PostsView extends React.Component { if (this.props.postList != null) { this.updateScrolling(); } - UserStore.addChangeListener(this.onUserChange); window.addEventListener('resize', this.handleResize); } componentWillUnmount() { - UserStore.removeChangeListener(this.onUserChange); window.removeEventListener('resize', this.handleResize); } componentDidUpdate() { @@ -418,19 +423,12 @@ export default class PostsView extends React.Component { if (this.state.isScrolling !== nextState.isScrolling) { return true; } - if (this.state.hasProfiles !== nextState.hasProfiles) { + if (!Utils.areObjectsEqual(this.props.profiles, nextProps.profiles)) { return true; } return false; } - onUserChange() { - if (!this.state.hasProfiles) { - const profiles = UserStore.getProfiles(); - - this.setState({hasProfiles: profiles && Object.keys(profiles).length > 1}); - } - } render() { let posts = []; let order = []; @@ -528,6 +526,7 @@ PostsView.defaultProps = { PostsView.propTypes = { isActive: React.PropTypes.bool, postList: React.PropTypes.object, + profiles: React.PropTypes.object, scrollPostId: React.PropTypes.string, scrollType: React.PropTypes.number, postViewScrolled: React.PropTypes.func.isRequired, diff --git a/web/react/components/posts_view_container.jsx b/web/react/components/posts_view_container.jsx index 972342021..1b14e8681 100644 --- a/web/react/components/posts_view_container.jsx +++ b/web/react/components/posts_view_container.jsx @@ -6,6 +6,7 @@ import LoadingScreen from './loading_screen.jsx'; import ChannelStore from '../stores/channel_store.jsx'; import PostStore from '../stores/post_store.jsx'; +import UserStore from '../stores/user_store.jsx'; import * as Utils from '../utils/utils.jsx'; import * as EventHelpers from '../dispatcher/event_helpers.jsx'; @@ -24,11 +25,13 @@ export default class PostsViewContainer extends React.Component { this.handlePostsViewScroll = this.handlePostsViewScroll.bind(this); this.loadMorePostsTop = this.loadMorePostsTop.bind(this); this.handlePostsViewJumpRequest = this.handlePostsViewJumpRequest.bind(this); + this.onUserChange = this.onUserChange.bind(this); const currentChannelId = ChannelStore.getCurrentId(); const state = { scrollType: PostsView.SCROLL_TYPE_BOTTOM, - scrollPost: null + scrollPost: null, + profiles: JSON.parse(JSON.stringify(UserStore.getProfiles())) }; if (currentChannelId) { Object.assign(state, { @@ -54,12 +57,14 @@ export default class PostsViewContainer extends React.Component { ChannelStore.addLeaveListener(this.onChannelLeave); PostStore.addChangeListener(this.onPostsChange); PostStore.addPostsViewJumpListener(this.handlePostsViewJumpRequest); + UserStore.addChangeListener(this.onUserChange); } componentWillUnmount() { ChannelStore.removeChangeListener(this.onChannelChange); ChannelStore.removeLeaveListener(this.onChannelLeave); PostStore.removeChangeListener(this.onPostsChange); PostStore.removePostsViewJumpListener(this.handlePostsViewJumpRequest); + UserStore.removeChangeListener(this.onUserChange); } handlePostsViewJumpRequest(type, post) { switch (type) { @@ -135,6 +140,9 @@ export default class PostsViewContainer extends React.Component { atTop[this.state.currentChannelIndex] = PostStore.getVisibilityAtTop(currentChannelId); this.setState({postLists, atTop}); } + onUserChange() { + this.setState({profiles: JSON.parse(JSON.stringify(UserStore.getProfiles()))}); + } getChannelPosts(id) { return PostStore.getVisiblePosts(id); } @@ -180,6 +188,7 @@ export default class PostsViewContainer extends React.Component { showMoreMessagesBottom={false} introText={channel ? createChannelIntroMessage(channel) : null} messageSeparatorTime={this.state.currentLastViewed} + profiles={this.state.profiles} /> ); if (!postLists[i] && isActive) { diff --git a/web/react/components/rhs_comment.jsx b/web/react/components/rhs_comment.jsx index 2ebca9b8d..9588809eb 100644 --- a/web/react/components/rhs_comment.jsx +++ b/web/react/components/rhs_comment.jsx @@ -194,8 +194,16 @@ class RhsComment extends React.Component { var timestamp = UserStore.getCurrentUser().update_at; - var loading; - var postClass = ''; + let loading; + let postClass = ''; + let message = ( +
+ ); + if (post.state === Constants.POST_FAILED) { postClass += ' post-fail'; loading = ( @@ -218,6 +226,13 @@ class RhsComment extends React.Component { src='/static/images/load.gif' /> ); + } else if (this.props.post.state === Constants.POST_DELETED) { + message = ( + + ); } var dropdown = this.createDropdown(); @@ -246,7 +261,7 @@ class RhsComment extends React.Component {
  • - +