From 4a2fbcaf983e3180e00bb846f4ed65a2670b9251 Mon Sep 17 00:00:00 2001 From: Joram Wilander Date: Thu, 18 Aug 2016 18:37:09 -0400 Subject: Add flagging functionality to search results (#3803) --- webapp/components/search_results.jsx | 36 +++++++++++++------ webapp/components/search_results_item.jsx | 57 +++++++++++++++++++------------ 2 files changed, 62 insertions(+), 31 deletions(-) (limited to 'webapp/components') diff --git a/webapp/components/search_results.jsx b/webapp/components/search_results.jsx index f66f28fcd..f128245e4 100644 --- a/webapp/components/search_results.jsx +++ b/webapp/components/search_results.jsx @@ -1,18 +1,21 @@ // Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. // See License.txt for license information. -import $ from 'jquery'; +import SearchResultsHeader from './search_results_header.jsx'; +import SearchResultsItem from './search_results_item.jsx'; +import SearchBox from './search_bar.jsx'; + import ChannelStore from 'stores/channel_store.jsx'; import SearchStore from 'stores/search_store.jsx'; import UserStore from 'stores/user_store.jsx'; import PreferenceStore from 'stores/preference_store.jsx'; -import SearchBox from './search_bar.jsx'; + import * as Utils from 'utils/utils.jsx'; import Constants from 'utils/constants.jsx'; const Preferences = Constants.Preferences; -import SearchResultsHeader from './search_results_header.jsx'; -import SearchResultsItem from './search_results_item.jsx'; +import $ from 'jquery'; +import React from 'react'; import {FormattedMessage, FormattedHTMLMessage} from 'react-intl'; function getStateFromStores() { @@ -34,12 +37,11 @@ function getStateFromStores() { return { results, channels, - searchTerm: SearchStore.getSearchTerm() + searchTerm: SearchStore.getSearchTerm(), + flaggedPosts: PreferenceStore.getCategory(Constants.Preferences.CATEGORY_FLAGGED_POST) }; } -import React from 'react'; - export default class SearchResults extends React.Component { constructor(props) { super(props); @@ -48,6 +50,7 @@ export default class SearchResults extends React.Component { this.onChange = this.onChange.bind(this); this.onUserChange = this.onUserChange.bind(this); + this.onPreferenceChange = this.onPreferenceChange.bind(this); this.resize = this.resize.bind(this); this.onPreferenceChange = this.onPreferenceChange.bind(this); this.handleResize = this.handleResize.bind(this); @@ -62,10 +65,13 @@ export default class SearchResults extends React.Component { componentDidMount() { this.mounted = true; + SearchStore.addSearchChangeListener(this.onChange); ChannelStore.addChangeListener(this.onChange); PreferenceStore.addChangeListener(this.onPreferenceChange); UserStore.addChangeListener(this.onUserChange); + PreferenceStore.addChangeListener(this.onPreferenceChange); + this.resize(); window.addEventListener('resize', this.handleResize); if (!Utils.isMobile()) { @@ -94,11 +100,14 @@ export default class SearchResults extends React.Component { } componentWillUnmount() { + this.mounted = false; + SearchStore.removeSearchChangeListener(this.onChange); ChannelStore.removeChangeListener(this.onChange); PreferenceStore.removeChangeListener(this.onPreferenceChange); UserStore.removeChangeListener(this.onUserChange); - this.mounted = false; + PreferenceStore.removeChangeListener(this.onPreferenceChange); + window.removeEventListener('resize', this.handleResize); } @@ -111,7 +120,8 @@ export default class SearchResults extends React.Component { onPreferenceChange() { this.setState({ - compactDisplay: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.MESSAGE_DISPLAY, Preferences.MESSAGE_DISPLAY_DEFAULT) === Preferences.MESSAGE_DISPLAY_COMPACT + compactDisplay: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.MESSAGE_DISPLAY, Preferences.MESSAGE_DISPLAY_DEFAULT) === Preferences.MESSAGE_DISPLAY_COMPACT, + flaggedPosts: PreferenceStore.getCategory(Constants.Preferences.CATEGORY_FLAGGED_POST) }); } @@ -213,6 +223,11 @@ export default class SearchResults extends React.Component { } else { profile = profiles[post.user_id]; } + + let isFlagged = false; + if (this.state.flaggedPosts) { + isFlagged = this.state.flaggedPosts.get(post.id) === 'true'; + } return ( ); }, this); diff --git a/webapp/components/search_results_item.jsx b/webapp/components/search_results_item.jsx index 65abc516e..ada5e0ea6 100644 --- a/webapp/components/search_results_item.jsx +++ b/webapp/components/search_results_item.jsx @@ -9,7 +9,7 @@ import UserStore from 'stores/user_store.jsx'; import AppDispatcher from '../dispatcher/app_dispatcher.jsx'; import * as GlobalActions from 'actions/global_actions.jsx'; -import {unflagPost, getFlaggedPosts} from 'actions/post_actions.jsx'; +import {flagPost, unflagPost} from 'actions/post_actions.jsx'; import * as TextFormatting from 'utils/text_formatting.jsx'; import * as Utils from 'utils/utils.jsx'; @@ -30,6 +30,7 @@ export default class SearchResultsItem extends React.Component { this.handleFocusRHSClick = this.handleFocusRHSClick.bind(this); this.shrinkSidebar = this.shrinkSidebar.bind(this); this.unflagPost = this.unflagPost.bind(this); + this.flagPost = this.flagPost.bind(this); } hideSidebar() { @@ -47,11 +48,14 @@ export default class SearchResultsItem extends React.Component { GlobalActions.emitPostFocusRightHandSideFromSearch(this.props.post, this.props.isMentionSearch); } + flagPost(e) { + e.preventDefault(); + flagPost(this.props.post.id); + } + unflagPost(e) { e.preventDefault(); - unflagPost(this.props.post.id, - () => getFlaggedPosts() - ); + unflagPost(this.props.post.id); } render() { @@ -110,6 +114,7 @@ export default class SearchResultsItem extends React.Component { } let flag; + let flagFunc; let flagVisible = ''; let flagTooltip = ( @@ -129,24 +134,21 @@ export default class SearchResultsItem extends React.Component { /> ); + flagFunc = this.unflagPost; flag = ( - - - - - + ); + } else { + flag = ( + + ); + flagFunc = this.flagPost; } return ( @@ -187,7 +189,19 @@ export default class SearchResultsItem extends React.Component { minute='2-digit' /> - {flag} + + + {flag} + +