From 58c6a70d3e225fcc423d4f0ee9316150e097b2c2 Mon Sep 17 00:00:00 2001 From: Saturnino Abril 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/actions/post_actions.jsx | 6 +- webapp/actions/websocket_actions.jsx | 6 ++ webapp/components/search_results_item.jsx | 136 +++++++++++++++--------------- webapp/stores/search_store.jsx | 19 ++++- webapp/utils/constants.jsx | 3 +- webapp/yarn.lock | 129 +++++----------------------- 6 files changed, 116 insertions(+), 183 deletions(-) (limited to 'webapp') diff --git a/webapp/actions/post_actions.jsx b/webapp/actions/post_actions.jsx index 09cc14e40..e96e8306b 100644 --- a/webapp/actions/post_actions.jsx +++ b/webapp/actions/post_actions.jsx @@ -326,7 +326,8 @@ export function pinPost(postId) { await PostActions.pinPost(postId)(doDispatch, doGetState); AppDispatcher.handleServerAction({ - type: ActionTypes.RECEIVED_POST_PINNED + type: ActionTypes.RECEIVED_POST_PINNED, + postId }); }; } @@ -336,7 +337,8 @@ export function unpinPost(postId) { await PostActions.unpinPost(postId)(doDispatch, doGetState); AppDispatcher.handleServerAction({ - type: ActionTypes.RECEIVED_POST_UNPINNED + type: ActionTypes.RECEIVED_POST_UNPINNED, + postId }); }; } diff --git a/webapp/actions/websocket_actions.jsx b/webapp/actions/websocket_actions.jsx index 184013179..da64e209d 100644 --- a/webapp/actions/websocket_actions.jsx +++ b/webapp/actions/websocket_actions.jsx @@ -261,6 +261,12 @@ function handlePostEditEvent(msg) { viewChannel(ChannelStore.getCurrentId())(dispatch, getState); } } + + // Needed for search store + AppDispatcher.handleViewAction({ + type: Constants.ActionTypes.POST_UPDATED, + post + }); } function handlePostDeleteEvent(msg) { 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 = (
{profilePic}
); - 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 = (
+ { - 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' >
-
-
- {channelName} -
+
+
{channelName}
{profilePicContainer}
-
- -
+
+ + + +
{botIndicator}
{this.renderTimeTag(post)} diff --git a/webapp/stores/search_store.jsx b/webapp/stores/search_store.jsx index 7c9c4b8ef..5dfea6867 100644 --- a/webapp/stores/search_store.jsx +++ b/webapp/stores/search_store.jsx @@ -120,6 +120,17 @@ class SearchStoreClass extends EventEmitter { } } + updatePost(post) { + const results = this.getSearchResults(); + if (results == null) { + return; + } + + if (post.id in results.posts) { + results.posts[post.id] = Object.assign({}, post); + } + } + togglePinPost(postId, isPinned) { const results = this.getSearchResults(); if (results == null || results.posts == null) { @@ -176,12 +187,16 @@ SearchStore.dispatchToken = AppDispatcher.register((payload) => { SearchStore.deletePost(action.post); SearchStore.emitSearchChange(); break; + case ActionTypes.POST_UPDATED: + SearchStore.updatePost(action.post); + SearchStore.emitSearchChange(); + break; case ActionTypes.RECEIVED_POST_PINNED: - SearchStore.togglePinPost(action.reaction, true); + SearchStore.togglePinPost(action.postId, true); SearchStore.emitSearchChange(); break; case ActionTypes.RECEIVED_POST_UNPINNED: - SearchStore.togglePinPost(action.reaction, false); + SearchStore.togglePinPost(action.postId, false); SearchStore.emitSearchChange(); break; case ActionTypes.REMOVE_POST: diff --git a/webapp/utils/constants.jsx b/webapp/utils/constants.jsx index 4ff20854f..ddebec293 100644 --- a/webapp/utils/constants.jsx +++ b/webapp/utils/constants.jsx @@ -965,7 +965,8 @@ export const Constants = { SHOW_USERNAME: 'username', SHOW_NICKNAME_FULLNAME: 'nickname_full_name', SHOW_FULLNAME: 'full_name' - } + }, + SEARCH_POST: 'searchpost' }; export default Constants; diff --git a/webapp/yarn.lock b/webapp/yarn.lock index a2e48a39d..0b6275bcf 100644 --- a/webapp/yarn.lock +++ b/webapp/yarn.lock @@ -111,13 +111,7 @@ ansi-styles@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" -ansi-styles@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.0.0.tgz#5404e93a544c4fec7f048262977bebfe3155e0c1" - dependencies: - color-convert "^1.0.0" - -ansi-styles@^3.1.0: +ansi-styles@^3.0.0, ansi-styles@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.1.0.tgz#09c202d5c917ec23188caa5c9cb9179cd9547750" dependencies: @@ -274,13 +268,7 @@ async@^1.4.0: version "1.5.2" resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" -async@^2.1.2, async@^2.1.4, async@^2.1.5: - version "2.3.0" - resolved "https://registry.yarnpkg.com/async/-/async-2.3.0.tgz#1013d1051047dd320fe24e494d5c66ecaf6147d9" - dependencies: - lodash "^4.14.0" - -async@^2.4.1: +async@^2.1.2, async@^2.1.4, async@^2.1.5, async@^2.4.1: version "2.5.0" resolved "https://registry.yarnpkg.com/async/-/async-2.5.0.tgz#843190fd6b7357a0b9e1c956edddd5ec8462b54d" dependencies: @@ -342,7 +330,7 @@ babel-code-frame@^6.11.0, babel-code-frame@^6.16.0, babel-code-frame@^6.22.0: esutils "^2.0.2" js-tokens "^3.0.0" -babel-core@6.25.0: +babel-core@6.25.0, babel-core@^6.0.0, babel-core@^6.24.1: version "6.25.0" resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.25.0.tgz#7dd42b0463c742e9d5296deb3ec67a9322dad729" dependencies: @@ -366,30 +354,6 @@ babel-core@6.25.0: slash "^1.0.0" source-map "^0.5.0" -babel-core@^6.0.0, babel-core@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.24.1.tgz#8c428564dce1e1f41fb337ec34f4c3b022b5ad83" - dependencies: - babel-code-frame "^6.22.0" - babel-generator "^6.24.1" - babel-helpers "^6.24.1" - babel-messages "^6.23.0" - babel-register "^6.24.1" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - babylon "^6.11.0" - convert-source-map "^1.1.0" - debug "^2.1.1" - json5 "^0.5.0" - lodash "^4.2.0" - minimatch "^3.0.2" - path-is-absolute "^1.0.0" - private "^0.1.6" - slash "^1.0.0" - source-map "^0.5.0" - babel-eslint@7.1.1: version "7.1.1" resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-7.1.1.tgz#8a6a884f085aa7060af69cfc77341c2f99370fb2" @@ -400,20 +364,7 @@ babel-eslint@7.1.1: babylon "^6.13.0" lodash.pickby "^4.6.0" -babel-generator@^6.18.0, babel-generator@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.24.1.tgz#e715f486c58ded25649d888944d52aa07c5d9497" - dependencies: - babel-messages "^6.23.0" - babel-runtime "^6.22.0" - babel-types "^6.24.1" - detect-indent "^4.0.0" - jsesc "^1.3.0" - lodash "^4.2.0" - source-map "^0.5.0" - trim-right "^1.0.1" - -babel-generator@^6.25.0: +babel-generator@^6.18.0, babel-generator@^6.25.0: version "6.25.0" resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.25.0.tgz#33a1af70d5f2890aeb465a4a7793c1df6a9ea9fc" dependencies: @@ -1071,17 +1022,7 @@ babel-runtime@^6.11.6, babel-runtime@^6.18.0, babel-runtime@^6.22.0: core-js "^2.4.0" regenerator-runtime "^0.10.0" -babel-template@^6.16.0, babel-template@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.24.1.tgz#04ae514f1f93b3a2537f2a0f60a5a45fb8308333" - dependencies: - babel-runtime "^6.22.0" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - babylon "^6.11.0" - lodash "^4.2.0" - -babel-template@^6.25.0: +babel-template@^6.16.0, babel-template@^6.24.1, babel-template@^6.25.0: version "6.25.0" resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.25.0.tgz#665241166b7c2aa4c619d71e192969552b10c071" dependencies: @@ -1091,21 +1032,7 @@ babel-template@^6.25.0: babylon "^6.17.2" lodash "^4.2.0" -babel-traverse@^6.15.0, babel-traverse@^6.18.0, babel-traverse@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.24.1.tgz#ab36673fd356f9a0948659e7b338d5feadb31695" - dependencies: - babel-code-frame "^6.22.0" - babel-messages "^6.23.0" - babel-runtime "^6.22.0" - babel-types "^6.24.1" - babylon "^6.15.0" - debug "^2.2.0" - globals "^9.0.0" - invariant "^2.2.0" - lodash "^4.2.0" - -babel-traverse@^6.25.0: +babel-traverse@^6.15.0, babel-traverse@^6.18.0, babel-traverse@^6.24.1, babel-traverse@^6.25.0: version "6.25.0" resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.25.0.tgz#2257497e2fcd19b89edc13c4c91381f9512496f1" dependencies: @@ -1119,16 +1046,7 @@ babel-traverse@^6.25.0: invariant "^2.2.0" lodash "^4.2.0" -babel-types@^6.15.0, babel-types@^6.18.0, babel-types@^6.19.0, babel-types@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.24.1.tgz#a136879dc15b3606bda0d90c1fc74304c2ff0975" - dependencies: - babel-runtime "^6.22.0" - esutils "^2.0.2" - lodash "^4.2.0" - to-fast-properties "^1.0.1" - -babel-types@^6.25.0: +babel-types@^6.15.0, babel-types@^6.18.0, babel-types@^6.19.0, babel-types@^6.24.1, babel-types@^6.25.0: version "6.25.0" resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.25.0.tgz#70afb248d5660e5d18f811d91c8303b54134a18e" dependencies: @@ -1137,11 +1055,7 @@ babel-types@^6.25.0: lodash "^4.2.0" to-fast-properties "^1.0.1" -babylon@^6.11.0, babylon@^6.13.0, babylon@^6.15.0: - version "6.17.0" - resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.17.0.tgz#37da948878488b9c4e3c4038893fa3314b3fc932" - -babylon@^6.17.2: +babylon@^6.13.0, babylon@^6.17.2: version "6.17.4" resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.17.4.tgz#3e8b7402b88d22c3423e137a1577883b15ff869a" @@ -2098,13 +2012,13 @@ debug@2.6.1: dependencies: ms "0.7.2" -debug@2.6.7, debug@^2.6.3: +debug@2.6.7: version "2.6.7" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.7.tgz#92bad1f6d05bbb6bba22cca88bcd0ec894c2861e" dependencies: ms "2.0.0" -debug@^2.1.1, debug@^2.2.0: +debug@^2.1.1, debug@^2.2.0, debug@^2.6.3: version "2.6.4" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.4.tgz#7586a9b3c39741c0282ae33445c4e8ac74734fe0" dependencies: @@ -5095,7 +5009,6 @@ mattermost-redux@mattermost/mattermost-redux#master: deep-equal "1.0.1" harmony-reflect "1.5.1" isomorphic-fetch "2.2.1" - key-mirror "1.0.1" mime-db "1.27.0" redux "3.6.0" redux-action-buffer "1.0.1" @@ -5488,11 +5401,7 @@ number-is-nan@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" -"nwmatcher@>= 1.3.9 < 2.0.0": - version "1.3.9" - resolved "https://registry.yarnpkg.com/nwmatcher/-/nwmatcher-1.3.9.tgz#8bab486ff7fa3dfd086656bbe8b17116d3692d2a" - -nwmatcher@^1.4.1: +"nwmatcher@>= 1.3.9 < 2.0.0", nwmatcher@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/nwmatcher/-/nwmatcher-1.4.1.tgz#7ae9b07b0ea804db7e25f05cb5fe4097d4e4949f" @@ -7656,18 +7565,18 @@ ua-parser-js@^0.7.9: version "0.7.12" resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.12.tgz#04c81a99bdd5dc52263ea29d24c6bf8d4818a4bb" -uglify-js@^2.6, uglify-js@~2.8.22: - version "2.8.22" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.22.tgz#d54934778a8da14903fa29a326fb24c0ab51a1a0" +uglify-js@^2.6, uglify-js@^2.8.29: + version "2.8.29" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.29.tgz#29c5733148057bb4e1f75df35b7a9cb72e6a59dd" dependencies: source-map "~0.5.1" yargs "~3.10.0" optionalDependencies: uglify-to-browserify "~1.0.0" -uglify-js@^2.8.29: - version "2.8.29" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.29.tgz#29c5733148057bb4e1f75df35b7a9cb72e6a59dd" +uglify-js@~2.8.22: + version "2.8.22" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.22.tgz#d54934778a8da14903fa29a326fb24c0ab51a1a0" dependencies: source-map "~0.5.1" yargs "~3.10.0" @@ -7816,7 +7725,7 @@ utils-merge@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.0.tgz#0294fb922bb9375153541c4f7096231f287c8af8" -uuid@3.0.1, uuid@^3.0.0: +uuid@3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.0.1.tgz#6544bba2dfda8c1cf17e629a3a305e2bb1fee6c1" @@ -7824,7 +7733,7 @@ uuid@^2.0.1: version "2.0.3" resolved "https://registry.yarnpkg.com/uuid/-/uuid-2.0.3.tgz#67e2e863797215530dff318e5bf9dcebfd47b21a" -uuid@^3.0.1: +uuid@^3.0.0, uuid@^3.0.1: version "3.1.0" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.1.0.tgz#3dd3d3e790abc24d7b0d3a034ffababe28ebbc04" -- cgit v1.2.3-1-g7c22