Deleted posts now update in search results and flagged posts (#4618)

Этот коммит содержится в:
Joram Wilander
2016-11-22 09:13:14 -05:00
коммит произвёл Harrison Healey
родитель 48d64f3f68
Коммит 3c65a20f45
4 изменённых файлов: 144 добавлений и 97 удалений

Просмотреть файл

@@ -19,7 +19,7 @@ import React from 'react';
import {FormattedMessage, FormattedHTMLMessage} from 'react-intl';
function getStateFromStores() {
const results = SearchStore.getSearchResults();
const results = JSON.parse(JSON.stringify(SearchStore.getSearchResults()));
const channels = new Map();

Просмотреть файл

@@ -111,42 +111,132 @@ export default class SearchResultsItem extends React.Component {
compactClass = 'post--compact';
}
let flag;
let flagFunc;
let flagVisible = '';
let flagTooltip = (
<Tooltip id='flagTooltip'>
<FormattedMessage
id='flag_post.flag'
defaultMessage='Flag for follow up'
/>
</Tooltip>
);
if (this.props.isFlagged) {
flagVisible = 'visible';
flagTooltip = (
let message;
let flagContent;
let rhsControls;
if (post.state === Constants.POST_DELETED) {
message = (
<p>
<FormattedMessage
id='post_body.deleted'
defaultMessage='(message deleted)'
/>
</p>
);
} else {
let flag;
let flagFunc;
let flagVisible = '';
let flagTooltip = (
<Tooltip id='flagTooltip'>
<FormattedMessage
id='flag_post.unflag'
defaultMessage='Unflag'
id='flag_post.flag'
defaultMessage='Flag for follow up'
/>
</Tooltip>
);
flagFunc = this.unflagPost;
flag = (
<span
className='icon'
dangerouslySetInnerHTML={{__html: flagIcon}}
if (this.props.isFlagged) {
flagVisible = 'visible';
flagTooltip = (
<Tooltip id='flagTooltip'>
<FormattedMessage
id='flag_post.unflag'
defaultMessage='Unflag'
/>
</Tooltip>
);
flagFunc = this.unflagPost;
flag = (
<span
className='icon'
dangerouslySetInnerHTML={{__html: flagIcon}}
/>
);
} else {
flag = (
<span
className='icon'
dangerouslySetInnerHTML={{__html: flagIcon}}
/>
);
flagFunc = this.flagPost;
}
flagContent = (
<OverlayTrigger
delayShow={Constants.OVERLAY_TIME_DELAY}
placement='top'
overlay={flagTooltip}
>
<a
href='#'
className={'flag-icon__container ' + flagVisible}
onClick={flagFunc}
>
{flag}
</a>
</OverlayTrigger>
);
rhsControls = (
<li className='col__controls'>
<a
href='#'
className='comment-icon__container search-item__comment'
onClick={this.handleFocusRHSClick}
>
<span
className='comment-icon'
dangerouslySetInnerHTML={{__html: Constants.REPLY_ICON}}
/>
</a>
<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);
}
}
className='search-item__jump'
>
<FormattedMessage
id='search_item.jump'
defaultMessage='Jump'
/>
</a>
</li>
);
message = (
<PostMessageContainer
post={post}
options={{
searchTerm: this.props.term,
mentionHighlight: this.props.isMentionSearch
}}
/>
);
} else {
flag = (
<span
className='icon'
dangerouslySetInnerHTML={{__html: flagIcon}}
/>
);
flagFunc = this.flagPost;
}
return (
@@ -187,75 +277,12 @@ export default class SearchResultsItem extends React.Component {
minute='2-digit'
/>
</time>
<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
href='#'
className='comment-icon__container search-item__comment'
onClick={this.handleFocusRHSClick}
>
<span
className='comment-icon'
dangerouslySetInnerHTML={{__html: Constants.REPLY_ICON}}
/>
</a>
<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);
}
}
className='search-item__jump'
>
<FormattedMessage
id='search_item.jump'
defaultMessage='Jump'
/>
</a>
{flagContent}
</li>
{rhsControls}
</ul>
<div className='search-item-snippet'>
<PostMessageContainer
post={post}
options={{
searchTerm: this.props.term,
mentionHighlight: this.props.isMentionSearch
}}
/>
{message}
</div>
</div>
</div>

Просмотреть файл

@@ -39,7 +39,8 @@ export default class SuggestionBox extends React.Component {
componentWillReceiveProps(nextProps) {
// Clear any suggestions when the SuggestionBox is cleared
if (nextProps.value === '' && this.props.value !== nextProps.value) {
GlobalActions.emitClearSuggestions(this.suggestionId);
// TODO - Find a better way to not "dispatch during dispatch"
setTimeout(() => GlobalActions.emitClearSuggestions(this.suggestionId), 1);
}
}

Просмотреть файл

@@ -96,6 +96,21 @@ class SearchStoreClass extends EventEmitter {
this.isMentionSearch = isMentionSearch;
this.isFlaggedPosts = isFlaggedPosts;
}
deletePost(post) {
const results = this.getSearchResults();
if (results == null) {
return;
}
if (post.id in results.posts) {
// make sure to copy the post so that component state changes work properly
results.posts[post.id] = Object.assign({}, post, {
state: Constants.POST_DELETED,
file_ids: []
});
}
}
}
var SearchStore = new SearchStoreClass();
@@ -115,6 +130,10 @@ SearchStore.dispatchToken = AppDispatcher.register((payload) => {
case ActionTypes.SHOW_SEARCH:
SearchStore.emitShowSearch();
break;
case ActionTypes.POST_DELETED:
SearchStore.deletePost(action.post);
SearchStore.emitSearchChange();
break;
default:
}
});