diff --git a/components/post_view/post/index.js b/components/post_view/post/index.js
index c7bc19b9b58e..893c71dc667f 100644
--- a/components/post_view/post/index.js
+++ b/components/post_view/post/index.js
@@ -3,21 +3,20 @@
import {connect} from 'react-redux';
import {bindActionCreators} from 'redux';
-import {createSelector} from 'reselect';
import {Posts} from 'mattermost-redux/constants';
import {getChannel} from 'mattermost-redux/selectors/entities/channels';
import {getPost, makeIsPostCommentMention} from 'mattermost-redux/selectors/entities/posts';
import {get} from 'mattermost-redux/selectors/entities/preferences';
import {getCurrentUserId} from 'mattermost-redux/selectors/entities/users';
-import {isPostEphemeral, isSystemMessage} from 'mattermost-redux/utils/post_utils';
+import {isSystemMessage} from 'mattermost-redux/utils/post_utils';
import {markPostAsUnread} from 'actions/post_actions';
import {selectPost, selectPostCard} from 'actions/views/rhs';
import {isArchivedChannel} from 'utils/channel_utils';
import {Preferences} from 'utils/constants';
-import {makeCreateAriaLabelForPost} from 'utils/post_utils.jsx';
+import {makeCreateAriaLabelForPost, makeGetReplyCount} from 'utils/post_utils.jsx';
import Post from './post.jsx';
@@ -37,21 +36,6 @@ export function isFirstReply(post, previousPost) {
return false;
}
-export function makeGetReplyCount() {
- return createSelector(
- (state) => state.entities.posts.posts,
- (state, post) => state.entities.posts.postsInThread[post.root_id || post.id],
- (allPosts, postIds) => {
- if (!postIds) {
- return 0;
- }
-
- // Count the number of non-ephemeral posts in the thread
- return postIds.map((id) => allPosts[id]).filter((post) => post && !isPostEphemeral(post)).length;
- }
- );
-}
-
function makeMapStateToProps() {
const getReplyCount = makeGetReplyCount();
const isPostCommentMention = makeIsPostCommentMention();
diff --git a/components/post_view/post/index.test.js b/components/post_view/post/index.test.js
index 39bdbbc8656a..7e6cd362efb7 100644
--- a/components/post_view/post/index.test.js
+++ b/components/post_view/post/index.test.js
@@ -1,9 +1,7 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
-import {Posts} from 'mattermost-redux/constants';
-
-import {isFirstReply, makeGetReplyCount} from './index';
+import {isFirstReply} from './index';
describe('isFirstReply', () => {
for (const testCase of [
@@ -61,89 +59,3 @@ describe('isFirstReply', () => {
});
}
});
-
-describe('makeGetReplyCount', () => {
- test('should return the number of comments when called on a root post', () => {
- const getReplyCount = makeGetReplyCount();
-
- const state = {
- entities: {
- posts: {
- posts: {
- post1: {id: 'post1'},
- post2: {id: 'post2', root_id: 'post1'},
- post3: {id: 'post3', root_id: 'post1'},
- },
- postsInThread: {
- post1: ['post2', 'post3'],
- },
- },
- },
- };
- const post = state.entities.posts.posts.post1;
-
- expect(getReplyCount(state, post)).toBe(2);
- });
-
- test('should return the number of comments when called on a comment', () => {
- const getReplyCount = makeGetReplyCount();
-
- const state = {
- entities: {
- posts: {
- posts: {
- post1: {id: 'post1'},
- post2: {id: 'post2', root_id: 'post1'},
- post3: {id: 'post3', root_id: 'post1'},
- },
- postsInThread: {
- post1: ['post2', 'post3'],
- },
- },
- },
- };
- const post = state.entities.posts.posts.post3;
-
- expect(getReplyCount(state, post)).toBe(2);
- });
-
- test('should return 0 when called on a post without comments', () => {
- const getReplyCount = makeGetReplyCount();
-
- const state = {
- entities: {
- posts: {
- posts: {
- post1: {id: 'post1'},
- },
- postsInThread: {},
- },
- },
- };
- const post = state.entities.posts.posts.post1;
-
- expect(getReplyCount(state, post)).toBe(0);
- });
-
- test('should not count ephemeral comments', () => {
- const getReplyCount = makeGetReplyCount();
-
- const state = {
- entities: {
- posts: {
- posts: {
- post1: {id: 'post1'},
- post2: {id: 'post2', root_id: 'post1', type: Posts.POST_TYPES.EPHEMERAL},
- post3: {id: 'post3', root_id: 'post1'},
- },
- postsInThread: {
- post1: ['post2', 'post3'],
- },
- },
- },
- };
- const post = state.entities.posts.posts.post1;
-
- expect(getReplyCount(state, post)).toBe(1);
- });
-});
diff --git a/components/search_results_item/index.js b/components/search_results_item/index.js
index 4bf787609a43..30691f3a4deb 100644
--- a/components/search_results_item/index.js
+++ b/components/search_results_item/index.js
@@ -3,6 +3,7 @@
import {connect} from 'react-redux';
import {bindActionCreators} from 'redux';
+
import {getChannel} from 'mattermost-redux/selectors/entities/channels';
import {getConfig} from 'mattermost-redux/selectors/entities/general';
import {getUser} from 'mattermost-redux/selectors/entities/users';
@@ -18,12 +19,13 @@ import {
setRhsExpanded,
} from 'actions/views/rhs';
-import {makeCreateAriaLabelForPost} from 'utils/post_utils.jsx';
+import {makeCreateAriaLabelForPost, makeGetReplyCount} from 'utils/post_utils.jsx';
import {getDirectTeammate, getDisplayNameByUser} from 'utils/utils.jsx';
import SearchResultsItem from './search_results_item.jsx';
function mapStateToProps() {
+ const getReplyCount = makeGetReplyCount();
const createAriaLabelForPost = makeCreateAriaLabelForPost();
const getCommentCountForPost = makeGetCommentCountForPost();
@@ -48,7 +50,8 @@ function mapStateToProps() {
isFlagged: isPostFlagged(post.id, preferences),
isBot: user ? user.is_bot : false,
directTeammate,
- displayName: getDisplayNameByUser(state, directTeammate)
+ displayName: getDisplayNameByUser(state, directTeammate),
+ replyCount: getReplyCount(state, post),
};
};
}
diff --git a/components/search_results_item/search_results_item.jsx b/components/search_results_item/search_results_item.jsx
index 36d2f75b181b..c7e477a23b85 100644
--- a/components/search_results_item/search_results_item.jsx
+++ b/components/search_results_item/search_results_item.jsx
@@ -109,6 +109,11 @@ class SearchResultsItem extends React.PureComponent {
intl: intlShape.isRequired,
directTeammate: PropTypes.string.isRequired,
displayName: PropTypes.string.isRequired,
+
+ /**
+ * The number of replies in the same thread as this post
+ */
+ replyCount: PropTypes.number,
};
static defaultProps = {
@@ -307,8 +312,10 @@ class SearchResultsItem extends React.PureComponent {
item.indexOf(PostListRowListIds.START_OF_NEW_MESSAGES) === 0
);
}
+
+export function makeGetReplyCount() {
+ return createSelector(
+ (state) => state.entities.posts.posts,
+ (state, post) => state.entities.posts.postsInThread[post.root_id || post.id],
+ (allPosts, postIds) => {
+ if (!postIds) {
+ return 0;
+ }
+
+ // Count the number of non-ephemeral posts in the thread
+ return postIds.map((id) => allPosts[id]).filter((post) => post && !isPostEphemeral(post)).length;
+ }
+ );
+}
diff --git a/utils/post_utils.test.jsx b/utils/post_utils.test.jsx
index 6d2677050760..43a5c1d9ce72 100644
--- a/utils/post_utils.test.jsx
+++ b/utils/post_utils.test.jsx
@@ -4,6 +4,7 @@
import assert from 'assert';
import {createIntl} from 'react-intl';
+import {Posts} from 'mattermost-redux/constants';
import * as PostUtils from 'utils/post_utils.jsx';
import {PostListRowListIds} from 'utils/constants';
@@ -741,3 +742,89 @@ describe('PostUtils.splitMessageBasedOnCaretPosition', () => {
assert.equal('st Message', stringPieces.lastPiece);
});
});
+
+describe('makeGetReplyCount', () => {
+ test('should return the number of comments when called on a root post', () => {
+ const getReplyCount = PostUtils.makeGetReplyCount();
+
+ const state = {
+ entities: {
+ posts: {
+ posts: {
+ post1: {id: 'post1'},
+ post2: {id: 'post2', root_id: 'post1'},
+ post3: {id: 'post3', root_id: 'post1'},
+ },
+ postsInThread: {
+ post1: ['post2', 'post3'],
+ },
+ },
+ },
+ };
+ const post = state.entities.posts.posts.post1;
+
+ expect(getReplyCount(state, post)).toBe(2);
+ });
+
+ test('should return the number of comments when called on a comment', () => {
+ const getReplyCount = PostUtils.makeGetReplyCount();
+
+ const state = {
+ entities: {
+ posts: {
+ posts: {
+ post1: {id: 'post1'},
+ post2: {id: 'post2', root_id: 'post1'},
+ post3: {id: 'post3', root_id: 'post1'},
+ },
+ postsInThread: {
+ post1: ['post2', 'post3'],
+ },
+ },
+ },
+ };
+ const post = state.entities.posts.posts.post3;
+
+ expect(getReplyCount(state, post)).toBe(2);
+ });
+
+ test('should return 0 when called on a post without comments', () => {
+ const getReplyCount = PostUtils.makeGetReplyCount();
+
+ const state = {
+ entities: {
+ posts: {
+ posts: {
+ post1: {id: 'post1'},
+ },
+ postsInThread: {},
+ },
+ },
+ };
+ const post = state.entities.posts.posts.post1;
+
+ expect(getReplyCount(state, post)).toBe(0);
+ });
+
+ test('should not count ephemeral comments', () => {
+ const getReplyCount = PostUtils.makeGetReplyCount();
+
+ const state = {
+ entities: {
+ posts: {
+ posts: {
+ post1: {id: 'post1'},
+ post2: {id: 'post2', root_id: 'post1', type: Posts.POST_TYPES.EPHEMERAL},
+ post3: {id: 'post3', root_id: 'post1'},
+ },
+ postsInThread: {
+ post1: ['post2', 'post3'],
+ },
+ },
+ },
+ };
+ const post = state.entities.posts.posts.post1;
+
+ expect(getReplyCount(state, post)).toBe(1);
+ });
+});