From 58c6a70d3e225fcc423d4f0ee9316150e097b2c2 Mon Sep 17 00:00:00 2001
From: Saturnino Abril <saturnino.abril@gmail.com>
Date: Sat, 22 Jul 2017 07:02:14 +0800
Subject: Add [...] menu to search results list (#6663)

* Add [...] menu to search results list

* fix updates on search results when post is pinned or edited

* remove app dispatcher from component
---
 webapp/components/search_results_item.jsx | 136 +++++++++++++++---------------
 1 file changed, 68 insertions(+), 68 deletions(-)

(limited to 'webapp/components/search_results_item.jsx')

diff --git a/webapp/components/search_results_item.jsx b/webapp/components/search_results_item.jsx
index 56b91fe68..929dc379e 100644
--- a/webapp/components/search_results_item.jsx
+++ b/webapp/components/search_results_item.jsx
@@ -1,25 +1,20 @@
 // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
 // See License.txt for license information.
 
-import $ from 'jquery';
 import PostMessageContainer from 'components/post_view/post_message_view';
 import UserProfile from './user_profile.jsx';
 import FileAttachmentListContainer from 'components/file_attachment_list';
 import ProfilePicture from './profile_picture.jsx';
 import CommentIcon from 'components/common/comment_icon.jsx';
+import DotMenu from 'components/dot_menu';
+import PostFlagIcon from 'components/post_view/post_flag_icon.jsx';
 
 import TeamStore from 'stores/team_store.jsx';
 
-import AppDispatcher from '../dispatcher/app_dispatcher.jsx';
 import * as GlobalActions from 'actions/global_actions.jsx';
-import {flagPost, unflagPost} from 'actions/post_actions.jsx';
-import PostFlagIcon from 'components/post_view/post_flag_icon.jsx';
-
 import * as Utils from 'utils/utils.jsx';
 import * as PostUtils from 'utils/post_utils.jsx';
-
 import Constants from 'utils/constants.jsx';
-const ActionTypes = Constants.ActionTypes;
 
 import React from 'react';
 import PropTypes from 'prop-types';
@@ -31,17 +26,34 @@ export default class SearchResultsItem extends React.Component {
         super(props);
 
         this.handleFocusRHSClick = this.handleFocusRHSClick.bind(this);
+        this.handleJumpClick = this.handleJumpClick.bind(this);
+        this.handleDropdownOpened = this.handleDropdownOpened.bind(this);
         this.shrinkSidebar = this.shrinkSidebar.bind(this);
-        this.unflagPost = this.unflagPost.bind(this);
-        this.flagPost = this.flagPost.bind(this);
 
         this.state = {
             currentTeamDisplayName: TeamStore.getCurrent().name,
             width: '',
-            height: ''
+            height: '',
+            dropdownOpened: false
         };
     }
 
+    shouldComponentUpdate(nextProps, nextState) {
+        if (!Utils.areObjectsEqual(nextState.post, this.props.post)) {
+            return true;
+        }
+
+        if (nextProps.isFlagged !== this.props.isFlagged) {
+            return true;
+        }
+
+        if (nextState.dropdownOpened !== this.state.dropdownOpened) {
+            return true;
+        }
+
+        return false;
+    }
+
     componentDidMount() {
         window.addEventListener('resize', () => {
             Utils.updateWindowDimensions(this);
@@ -54,10 +66,6 @@ export default class SearchResultsItem extends React.Component {
         });
     }
 
-    hideSidebar() {
-        $('.sidebar--right').removeClass('move--left');
-    }
-
     shrinkSidebar() {
         setTimeout(() => {
             this.props.shrink();
@@ -69,14 +77,19 @@ export default class SearchResultsItem extends React.Component {
         GlobalActions.emitPostFocusRightHandSideFromSearch(this.props.post, this.props.isMentionSearch);
     }
 
-    flagPost(e) {
-        e.preventDefault();
-        flagPost(this.props.post.id);
+    handleJumpClick() {
+        if (Utils.isMobile()) {
+            GlobalActions.toggleSideBarAction(false);
+        }
+
+        this.shrinkSidebar();
+        browserHistory.push(TeamStore.getCurrentTeamRelativeUrl() + '/pl/' + this.props.post.id);
     }
 
-    unflagPost(e) {
-        e.preventDefault();
-        unflagPost(this.props.post.id);
+    handleDropdownOpened = (isOpened) => {
+        this.setState({
+            dropdownOpened: isOpened
+        });
     }
 
     timeTag(post) {
@@ -109,6 +122,20 @@ export default class SearchResultsItem extends React.Component {
             );
     }
 
+    getClassName = () => {
+        let className = 'post post--thread';
+
+        if (this.props.compactDisplay) {
+            className = ' post--compact';
+        }
+
+        if (this.state.dropdownOpened) {
+            className += ' post--hovered';
+        }
+
+        return className;
+    }
+
     render() {
         let channelName = null;
         const channel = this.props.channel;
@@ -160,11 +187,7 @@ export default class SearchResultsItem extends React.Component {
 
         );
 
-        let compactClass = '';
         const profilePicContainer = (<div className='post__img'>{profilePic}</div>);
-        if (this.props.compactDisplay) {
-            compactClass = ' post--compact';
-        }
 
         let postClass = '';
         if (PostUtils.isEdited(this.props.post)) {
@@ -205,6 +228,13 @@ export default class SearchResultsItem extends React.Component {
 
             rhsControls = (
                 <div className='col__controls'>
+                    <DotMenu
+                        idPrefix={Constants.SEARCH_POST}
+                        idCount={idCount}
+                        post={post}
+                        isFlagged={this.props.isFlagged}
+                        handleDropdownOpened={this.handleDropdownOpened}
+                    />
                     <CommentIcon
                         idPrefix={'searchCommentIcon'}
                         idCount={idCount}
@@ -212,32 +242,7 @@ export default class SearchResultsItem extends React.Component {
                         searchStyle={'search-item__comment'}
                     />
                     <a
-                        onClick={
-                            () => {
-                                if (Utils.isMobile()) {
-                                    AppDispatcher.handleServerAction({
-                                        type: ActionTypes.RECEIVED_SEARCH,
-                                        results: null
-                                    });
-
-                                    AppDispatcher.handleServerAction({
-                                        type: ActionTypes.RECEIVED_SEARCH_TERM,
-                                        term: null,
-                                        do_search: false,
-                                        is_mention_search: false
-                                    });
-
-                                    AppDispatcher.handleServerAction({
-                                        type: ActionTypes.RECEIVED_POST_SELECTED,
-                                        postId: null
-                                    });
-
-                                    this.hideSidebar();
-                                }
-                                this.shrinkSidebar();
-                                browserHistory.push(TeamStore.getCurrentTeamRelativeUrl() + '/pl/' + post.id);
-                            }
-                        }
+                        onClick={this.handleJumpClick}
                         className='search-item__jump'
                     >
                         <FormattedMessage
@@ -284,28 +289,23 @@ export default class SearchResultsItem extends React.Component {
                         />
                     </div>
                 </div>
-                <div
-                    className={'post post--thread ' + compactClass}
-                >
-                    <div
-                        id={idCount === -1 ? null : Utils.createSafeId('searchChannelName' + idCount)}
-                        className='search-channel__name'
-                    >
-                        {channelName}
-                    </div>
+                <div className={this.getClassName()}>
+                    <div className='search-channel__name'>{channelName}</div>
                     <div className='post__content'>
                         {profilePicContainer}
                         <div>
                             <div className='post__header'>
-                                <div className='col col__name'><strong>
-                                    <UserProfile
-                                        user={user}
-                                        overwriteName={overrideUsername}
-                                        disablePopover={disableProfilePopover}
-                                        status={this.props.status}
-                                        isBusy={this.props.isBusy}
-                                    />
-                                </strong></div>
+                                <div className='col col__name'>
+                                    <strong>
+                                        <UserProfile
+                                            user={user}
+                                            overwriteName={overrideUsername}
+                                            disablePopover={disableProfilePopover}
+                                            status={this.props.status}
+                                            isBusy={this.props.isBusy}
+                                        />
+                                    </strong>
+                                </div>
                                 {botIndicator}
                                 <div className='col'>
                                     {this.renderTimeTag(post)}
-- 
cgit v1.2.3-1-g7c22

