Add flagging functionality to search results (#3803)

This commit is contained in:
Joram Wilander
2016-08-18 18:37:09 -04:00
committed by Corey Hulen
parent a820b1640b
commit 4a2fbcaf98
2 changed files with 62 additions and 31 deletions

View File

@@ -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 (
<SearchResultsItem
key={post.id}
@@ -222,9 +237,10 @@ export default class SearchResults extends React.Component {
user={profile}
term={searchTerm}
isMentionSearch={this.props.isMentionSearch}
isFlaggedSearch={this.props.isFlaggedPosts}
useMilitaryTime={this.props.useMilitaryTime}
shrink={this.props.shrink}
isFlagged={this.props.isFlaggedPosts}
isFlagged={isFlagged}
/>
);
}, this);

View File

@@ -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 = (
<Tooltip id='flagTooltip'>
@@ -129,24 +134,21 @@ export default class SearchResultsItem extends React.Component {
/>
</Tooltip>
);
flagFunc = this.unflagPost;
flag = (
<OverlayTrigger
delayShow={Constants.OVERLAY_TIME_DELAY}
placement='top'
overlay={flagTooltip}
>
<a
href='#'
className={'flag-icon__container ' + flagVisible}
onClick={this.unflagPost}
>
<span
className='icon'
dangerouslySetInnerHTML={{__html: flagIcon}}
/>
</a>
</OverlayTrigger>
<span
className='icon'
dangerouslySetInnerHTML={{__html: flagIcon}}
/>
);
} else {
flag = (
<span
className='icon'
dangerouslySetInnerHTML={{__html: flagIcon}}
/>
);
flagFunc = this.flagPost;
}
return (
@@ -187,7 +189,19 @@ export default class SearchResultsItem extends React.Component {
minute='2-digit'
/>
</time>
{flag}
<OverlayTrigger
delayShow={Constants.OVERLAY_TIME_DELAY}
placement='top'
overlay={flagTooltip}
>
<a
href='#'
className={'flag-icon__container ' + flagVisible}
onClick={flagFunc}
>
{flag}
</a>
</OverlayTrigger>
</li>
<li className='col__controls'>
<a
@@ -256,6 +270,7 @@ SearchResultsItem.propTypes = {
channel: React.PropTypes.object,
compactDisplay: React.PropTypes.bool,
isMentionSearch: React.PropTypes.bool,
isFlaggedSearch: React.PropTypes.bool,
term: React.PropTypes.string,
useMilitaryTime: React.PropTypes.bool.isRequired,
shrink: React.PropTypes.function,