mirror of
https://github.com/mattermost/mattermost.git
synced 2025-02-25 18:55:24 -06:00
Add flagging functionality to search results (#3803)
This commit is contained in:
committed by
Corey Hulen
parent
a820b1640b
commit
4a2fbcaf98
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user