[PLT-6363-1] Create PostFlagIcon component and add flag IDs to posts (#6271)
* [UI-AUTO] add IDs to last 10 posts' text * create FlagPost component and add flag IDs for posts at center, RHS and search results
Этот коммит содержится в:
коммит произвёл
Joram Wilander
родитель
882172b298
Коммит
f88769d1f2
87
webapp/components/common/post_flag_icon.jsx
Обычный файл
87
webapp/components/common/post_flag_icon.jsx
Обычный файл
@@ -0,0 +1,87 @@
|
|||||||
|
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||||
|
// See License.txt for license information.
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
import {FormattedMessage} from 'react-intl';
|
||||||
|
import {Tooltip, OverlayTrigger} from 'react-bootstrap';
|
||||||
|
|
||||||
|
import {flagPost, unflagPost} from 'actions/post_actions.jsx';
|
||||||
|
import Constants from 'utils/constants.jsx';
|
||||||
|
import * as Utils from 'utils/utils.jsx';
|
||||||
|
|
||||||
|
function flagToolTip(isFlagged) {
|
||||||
|
return (
|
||||||
|
<Tooltip id='flagTooltip'>
|
||||||
|
<FormattedMessage
|
||||||
|
id={isFlagged ? 'flag_post.unflag' : 'flag_post.flag'}
|
||||||
|
defaultMessage={isFlagged ? 'Unflag' : 'Flag for follow up'}
|
||||||
|
/>
|
||||||
|
</Tooltip>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function flagIcon() {
|
||||||
|
return (
|
||||||
|
<span
|
||||||
|
className='icon'
|
||||||
|
dangerouslySetInnerHTML={{__html: Constants.FLAG_ICON_SVG}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function PostFlagIcon(props) {
|
||||||
|
function onFlagPost(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
flagPost(props.postId);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onUnflagPost(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
unflagPost(props.postId);
|
||||||
|
}
|
||||||
|
|
||||||
|
const flagFunc = props.isFlagged ? onUnflagPost : onFlagPost;
|
||||||
|
const flagVisible = props.isFlagged ? 'visible' : '';
|
||||||
|
|
||||||
|
let flagIconId = null;
|
||||||
|
if (props.idCount > -1) {
|
||||||
|
flagIconId = Utils.createSafeId(props.idPrefix + props.idCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!props.isEphemeral) {
|
||||||
|
return (
|
||||||
|
<OverlayTrigger
|
||||||
|
key={'flagtooltipkey' + flagVisible}
|
||||||
|
delayShow={Constants.OVERLAY_TIME_DELAY}
|
||||||
|
placement='top'
|
||||||
|
overlay={flagToolTip(props.isFlagged)}
|
||||||
|
>
|
||||||
|
<a
|
||||||
|
id={flagIconId}
|
||||||
|
href='#'
|
||||||
|
className={'flag-icon__container ' + flagVisible}
|
||||||
|
onClick={flagFunc}
|
||||||
|
>
|
||||||
|
{flagIcon()}
|
||||||
|
</a>
|
||||||
|
</OverlayTrigger>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
PostFlagIcon.propTypes = {
|
||||||
|
idPrefix: React.PropTypes.string.isRequired,
|
||||||
|
idCount: React.PropTypes.number,
|
||||||
|
postId: React.PropTypes.string.isRequired,
|
||||||
|
isFlagged: React.PropTypes.bool.isRequired,
|
||||||
|
isEphemeral: React.PropTypes.bool
|
||||||
|
};
|
||||||
|
|
||||||
|
PostFlagIcon.defaultProps = {
|
||||||
|
idCount: -1,
|
||||||
|
postId: '',
|
||||||
|
isFlagged: false,
|
||||||
|
isEphemeral: false
|
||||||
|
};
|
||||||
@@ -292,6 +292,7 @@ export default class Post extends Component {
|
|||||||
ref='header'
|
ref='header'
|
||||||
post={post}
|
post={post}
|
||||||
sameRoot={this.props.sameRoot}
|
sameRoot={this.props.sameRoot}
|
||||||
|
lastPostCount={this.props.lastPostCount}
|
||||||
commentCount={this.props.commentCount}
|
commentCount={this.props.commentCount}
|
||||||
handleCommentClick={this.handleCommentClick}
|
handleCommentClick={this.handleCommentClick}
|
||||||
handleDropdownOpened={this.handleDropdownOpened}
|
handleDropdownOpened={this.handleDropdownOpened}
|
||||||
|
|||||||
@@ -79,6 +79,7 @@ export default class PostHeader extends React.Component {
|
|||||||
<li className='col'>
|
<li className='col'>
|
||||||
<PostInfo
|
<PostInfo
|
||||||
post={post}
|
post={post}
|
||||||
|
lastPostCount={this.props.lastPostCount}
|
||||||
commentCount={this.props.commentCount}
|
commentCount={this.props.commentCount}
|
||||||
handleCommentClick={this.props.handleCommentClick}
|
handleCommentClick={this.props.handleCommentClick}
|
||||||
handleDropdownOpened={this.props.handleDropdownOpened}
|
handleDropdownOpened={this.props.handleDropdownOpened}
|
||||||
@@ -105,6 +106,7 @@ PostHeader.propTypes = {
|
|||||||
post: React.PropTypes.object.isRequired,
|
post: React.PropTypes.object.isRequired,
|
||||||
user: React.PropTypes.object,
|
user: React.PropTypes.object,
|
||||||
currentUser: React.PropTypes.object.isRequired,
|
currentUser: React.PropTypes.object.isRequired,
|
||||||
|
lastPostCount: React.PropTypes.number,
|
||||||
commentCount: React.PropTypes.number.isRequired,
|
commentCount: React.PropTypes.number.isRequired,
|
||||||
isLastComment: React.PropTypes.bool.isRequired,
|
isLastComment: React.PropTypes.bool.isRequired,
|
||||||
handleCommentClick: React.PropTypes.func.isRequired,
|
handleCommentClick: React.PropTypes.func.isRequired,
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import $ from 'jquery';
|
|||||||
import ReactDOM from 'react-dom';
|
import ReactDOM from 'react-dom';
|
||||||
|
|
||||||
import PostTime from './post_time.jsx';
|
import PostTime from './post_time.jsx';
|
||||||
|
import PostFlagIcon from 'components/common/post_flag_icon.jsx';
|
||||||
|
|
||||||
import * as GlobalActions from 'actions/global_actions.jsx';
|
import * as GlobalActions from 'actions/global_actions.jsx';
|
||||||
import * as PostActions from 'actions/post_actions.jsx';
|
import * as PostActions from 'actions/post_actions.jsx';
|
||||||
@@ -13,7 +14,7 @@ import * as Utils from 'utils/utils.jsx';
|
|||||||
import * as PostUtils from 'utils/post_utils.jsx';
|
import * as PostUtils from 'utils/post_utils.jsx';
|
||||||
import Constants from 'utils/constants.jsx';
|
import Constants from 'utils/constants.jsx';
|
||||||
import DelayedAction from 'utils/delayed_action.jsx';
|
import DelayedAction from 'utils/delayed_action.jsx';
|
||||||
import {Tooltip, OverlayTrigger, Overlay} from 'react-bootstrap';
|
import {Overlay} from 'react-bootstrap';
|
||||||
import EmojiPicker from 'components/emoji_picker/emoji_picker.jsx';
|
import EmojiPicker from 'components/emoji_picker/emoji_picker.jsx';
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
@@ -325,7 +326,11 @@ export default class PostInfo extends React.Component {
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
var post = this.props.post;
|
var post = this.props.post;
|
||||||
const flagIcon = Constants.FLAG_ICON_SVG;
|
|
||||||
|
let idCount = -1;
|
||||||
|
if (this.props.lastPostCount >= 0 && this.props.lastPostCount < Constants.TEST_ID_COUNT) {
|
||||||
|
idCount = this.props.lastPostCount;
|
||||||
|
}
|
||||||
|
|
||||||
this.canDelete = PostUtils.canDeletePost(post);
|
this.canDelete = PostUtils.canDeletePost(post);
|
||||||
this.canEdit = PostUtils.canEditPost(post, this.editDisableAction);
|
this.canEdit = PostUtils.canEditPost(post, this.editDisableAction);
|
||||||
@@ -420,64 +425,6 @@ export default class PostInfo extends React.Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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';
|
|
||||||
flag = (
|
|
||||||
<span
|
|
||||||
className='icon'
|
|
||||||
dangerouslySetInnerHTML={{__html: flagIcon}}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
flagFunc = this.unflagPost;
|
|
||||||
flagTooltip = (
|
|
||||||
<Tooltip id='flagTooltip'>
|
|
||||||
<FormattedMessage
|
|
||||||
id='flag_post.unflag'
|
|
||||||
defaultMessage='Unflag'
|
|
||||||
/>
|
|
||||||
</Tooltip>
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
flag = (
|
|
||||||
<span
|
|
||||||
className='icon'
|
|
||||||
dangerouslySetInnerHTML={{__html: flagIcon}}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
flagFunc = this.flagPost;
|
|
||||||
}
|
|
||||||
|
|
||||||
let flagTrigger;
|
|
||||||
if (!isEphemeral) {
|
|
||||||
flagTrigger = (
|
|
||||||
<OverlayTrigger
|
|
||||||
key={'flagtooltipkey' + flagVisible}
|
|
||||||
delayShow={Constants.OVERLAY_TIME_DELAY}
|
|
||||||
placement='top'
|
|
||||||
overlay={flagTooltip}
|
|
||||||
>
|
|
||||||
<a
|
|
||||||
href='#'
|
|
||||||
className={'flag-icon__container ' + flagVisible}
|
|
||||||
onClick={flagFunc}
|
|
||||||
>
|
|
||||||
{flag}
|
|
||||||
</a>
|
|
||||||
</OverlayTrigger>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
let pinnedBadge;
|
let pinnedBadge;
|
||||||
if (post.is_pinned) {
|
if (post.is_pinned) {
|
||||||
pinnedBadge = (
|
pinnedBadge = (
|
||||||
@@ -502,7 +449,13 @@ export default class PostInfo extends React.Component {
|
|||||||
/>
|
/>
|
||||||
{pinnedBadge}
|
{pinnedBadge}
|
||||||
{this.state.showEmojiPicker}
|
{this.state.showEmojiPicker}
|
||||||
{flagTrigger}
|
<PostFlagIcon
|
||||||
|
idPrefix={'centerPostFlag'}
|
||||||
|
idCount={idCount}
|
||||||
|
postId={post.id}
|
||||||
|
isFlagged={this.props.isFlagged}
|
||||||
|
isEphemeral={isEphemeral}
|
||||||
|
/>
|
||||||
</li>
|
</li>
|
||||||
{options}
|
{options}
|
||||||
</ul>
|
</ul>
|
||||||
@@ -518,6 +471,7 @@ PostInfo.defaultProps = {
|
|||||||
};
|
};
|
||||||
PostInfo.propTypes = {
|
PostInfo.propTypes = {
|
||||||
post: React.PropTypes.object.isRequired,
|
post: React.PropTypes.object.isRequired,
|
||||||
|
lastPostCount: React.PropTypes.number,
|
||||||
commentCount: React.PropTypes.number.isRequired,
|
commentCount: React.PropTypes.number.isRequired,
|
||||||
isLastComment: React.PropTypes.bool.isRequired,
|
isLastComment: React.PropTypes.bool.isRequired,
|
||||||
handleCommentClick: React.PropTypes.func.isRequired,
|
handleCommentClick: React.PropTypes.func.isRequired,
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import PostMessageContainer from 'components/post_view/components/post_message_c
|
|||||||
import ProfilePicture from 'components/profile_picture.jsx';
|
import ProfilePicture from 'components/profile_picture.jsx';
|
||||||
import ReactionListContainer from 'components/post_view/components/reaction_list_container.jsx';
|
import ReactionListContainer from 'components/post_view/components/reaction_list_container.jsx';
|
||||||
import RhsDropdown from 'components/rhs_dropdown.jsx';
|
import RhsDropdown from 'components/rhs_dropdown.jsx';
|
||||||
|
import PostFlagIcon from 'components/common/post_flag_icon.jsx';
|
||||||
|
|
||||||
import * as GlobalActions from 'actions/global_actions.jsx';
|
import * as GlobalActions from 'actions/global_actions.jsx';
|
||||||
import {flagPost, unflagPost, pinPost, unpinPost, addReaction} from 'actions/post_actions.jsx';
|
import {flagPost, unflagPost, pinPost, unpinPost, addReaction} from 'actions/post_actions.jsx';
|
||||||
@@ -19,7 +20,7 @@ import * as PostUtils from 'utils/post_utils.jsx';
|
|||||||
|
|
||||||
import Constants from 'utils/constants.jsx';
|
import Constants from 'utils/constants.jsx';
|
||||||
import DelayedAction from 'utils/delayed_action.jsx';
|
import DelayedAction from 'utils/delayed_action.jsx';
|
||||||
import {Tooltip, OverlayTrigger, Overlay} from 'react-bootstrap';
|
import {Overlay} from 'react-bootstrap';
|
||||||
|
|
||||||
import {FormattedMessage} from 'react-intl';
|
import {FormattedMessage} from 'react-intl';
|
||||||
|
|
||||||
@@ -128,6 +129,10 @@ export default class RhsComment extends React.Component {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (nextProps.lastPostCount !== this.props.lastPostCount) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -384,9 +389,13 @@ export default class RhsComment extends React.Component {
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
const post = this.props.post;
|
const post = this.props.post;
|
||||||
const flagIcon = Constants.FLAG_ICON_SVG;
|
|
||||||
const mattermostLogo = Constants.MATTERMOST_ICON_SVG;
|
const mattermostLogo = Constants.MATTERMOST_ICON_SVG;
|
||||||
|
|
||||||
|
let idCount = -1;
|
||||||
|
if (this.props.lastPostCount >= 0 && this.props.lastPostCount < Constants.TEST_ID_COUNT) {
|
||||||
|
idCount = this.props.lastPostCount;
|
||||||
|
}
|
||||||
|
|
||||||
const isEphemeral = Utils.isPostEphemeral(post);
|
const isEphemeral = Utils.isPostEphemeral(post);
|
||||||
const isPending = post.state === Constants.POST_FAILED || post.state === Constants.POST_LOADING;
|
const isPending = post.state === Constants.POST_FAILED || post.state === Constants.POST_LOADING;
|
||||||
const isSystemMessage = PostUtils.isSystemMessage(post);
|
const isSystemMessage = PostUtils.isSystemMessage(post);
|
||||||
@@ -523,64 +532,6 @@ export default class RhsComment extends React.Component {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
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';
|
|
||||||
flag = (
|
|
||||||
<span
|
|
||||||
className='icon'
|
|
||||||
dangerouslySetInnerHTML={{__html: flagIcon}}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
flagFunc = this.unflagPost;
|
|
||||||
flagTooltip = (
|
|
||||||
<Tooltip id='flagTooltip'>
|
|
||||||
<FormattedMessage
|
|
||||||
id='flag_post.unflag'
|
|
||||||
defaultMessage='Unflag'
|
|
||||||
/>
|
|
||||||
</Tooltip>
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
flag = (
|
|
||||||
<span
|
|
||||||
className='icon'
|
|
||||||
dangerouslySetInnerHTML={{__html: flagIcon}}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
flagFunc = this.flagPost;
|
|
||||||
}
|
|
||||||
|
|
||||||
let flagTrigger;
|
|
||||||
if (!isEphemeral) {
|
|
||||||
flagTrigger = (
|
|
||||||
<OverlayTrigger
|
|
||||||
key={'commentflagtooltipkey' + flagVisible}
|
|
||||||
delayShow={Constants.OVERLAY_TIME_DELAY}
|
|
||||||
placement='top'
|
|
||||||
overlay={flagTooltip}
|
|
||||||
>
|
|
||||||
<a
|
|
||||||
href='#'
|
|
||||||
className={'flag-icon__container ' + flagVisible}
|
|
||||||
onClick={flagFunc}
|
|
||||||
>
|
|
||||||
{flag}
|
|
||||||
</a>
|
|
||||||
</OverlayTrigger>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
let react;
|
let react;
|
||||||
let reactOverlay;
|
let reactOverlay;
|
||||||
|
|
||||||
@@ -668,7 +619,13 @@ export default class RhsComment extends React.Component {
|
|||||||
<li className='col'>
|
<li className='col'>
|
||||||
{this.renderTimeTag(post, timeOptions)}
|
{this.renderTimeTag(post, timeOptions)}
|
||||||
{pinnedBadge}
|
{pinnedBadge}
|
||||||
{flagTrigger}
|
<PostFlagIcon
|
||||||
|
idPrefix={'rhsCommentFlag'}
|
||||||
|
idCount={idCount}
|
||||||
|
postId={post.id}
|
||||||
|
isFlagged={this.props.isFlagged}
|
||||||
|
isEphemeral={isEphemeral}
|
||||||
|
/>
|
||||||
</li>
|
</li>
|
||||||
{options}
|
{options}
|
||||||
</ul>
|
</ul>
|
||||||
@@ -689,6 +646,7 @@ export default class RhsComment extends React.Component {
|
|||||||
|
|
||||||
RhsComment.propTypes = {
|
RhsComment.propTypes = {
|
||||||
post: React.PropTypes.object,
|
post: React.PropTypes.object,
|
||||||
|
lastPostCount: React.PropTypes.number,
|
||||||
user: React.PropTypes.object.isRequired,
|
user: React.PropTypes.object.isRequired,
|
||||||
currentUser: React.PropTypes.object.isRequired,
|
currentUser: React.PropTypes.object.isRequired,
|
||||||
compactDisplay: React.PropTypes.bool,
|
compactDisplay: React.PropTypes.bool,
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import FileAttachmentListContainer from './file_attachment_list_container.jsx';
|
|||||||
import ProfilePicture from 'components/profile_picture.jsx';
|
import ProfilePicture from 'components/profile_picture.jsx';
|
||||||
import ReactionListContainer from 'components/post_view/components/reaction_list_container.jsx';
|
import ReactionListContainer from 'components/post_view/components/reaction_list_container.jsx';
|
||||||
import RhsDropdown from 'components/rhs_dropdown.jsx';
|
import RhsDropdown from 'components/rhs_dropdown.jsx';
|
||||||
|
import PostFlagIcon from 'components/common/post_flag_icon.jsx';
|
||||||
|
|
||||||
import ChannelStore from 'stores/channel_store.jsx';
|
import ChannelStore from 'stores/channel_store.jsx';
|
||||||
import UserStore from 'stores/user_store.jsx';
|
import UserStore from 'stores/user_store.jsx';
|
||||||
@@ -24,7 +25,7 @@ import ReactDOM from 'react-dom';
|
|||||||
|
|
||||||
import Constants from 'utils/constants.jsx';
|
import Constants from 'utils/constants.jsx';
|
||||||
import DelayedAction from 'utils/delayed_action.jsx';
|
import DelayedAction from 'utils/delayed_action.jsx';
|
||||||
import {Tooltip, OverlayTrigger, Overlay} from 'react-bootstrap';
|
import {Overlay} from 'react-bootstrap';
|
||||||
|
|
||||||
import {FormattedMessage} from 'react-intl';
|
import {FormattedMessage} from 'react-intl';
|
||||||
|
|
||||||
@@ -203,7 +204,6 @@ export default class RhsRootPost extends React.Component {
|
|||||||
const mattermostLogo = Constants.MATTERMOST_ICON_SVG;
|
const mattermostLogo = Constants.MATTERMOST_ICON_SVG;
|
||||||
var timestamp = user ? user.last_picture_update : 0;
|
var timestamp = user ? user.last_picture_update : 0;
|
||||||
var channel = ChannelStore.get(post.channel_id);
|
var channel = ChannelStore.get(post.channel_id);
|
||||||
const flagIcon = Constants.FLAG_ICON_SVG;
|
|
||||||
|
|
||||||
this.canDelete = PostUtils.canDeletePost(post);
|
this.canDelete = PostUtils.canDeletePost(post);
|
||||||
this.canEdit = PostUtils.canEditPost(post, this.editDisableAction);
|
this.canEdit = PostUtils.canEditPost(post, this.editDisableAction);
|
||||||
@@ -530,44 +530,6 @@ export default class RhsRootPost extends React.Component {
|
|||||||
|
|
||||||
const profilePicContainer = (<div className='post__img'>{profilePic}</div>);
|
const profilePicContainer = (<div className='post__img'>{profilePic}</div>);
|
||||||
|
|
||||||
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';
|
|
||||||
flag = (
|
|
||||||
<span
|
|
||||||
className='icon'
|
|
||||||
dangerouslySetInnerHTML={{__html: flagIcon}}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
flagFunc = this.unflagPost;
|
|
||||||
flagTooltip = (
|
|
||||||
<Tooltip id='flagTooltip'>
|
|
||||||
<FormattedMessage
|
|
||||||
id='flag_post.unflag'
|
|
||||||
defaultMessage='Unflag'
|
|
||||||
/>
|
|
||||||
</Tooltip>
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
flag = (
|
|
||||||
<span
|
|
||||||
className='icon'
|
|
||||||
dangerouslySetInnerHTML={{__html: flagIcon}}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
flagFunc = this.flagPost;
|
|
||||||
}
|
|
||||||
|
|
||||||
let pinnedBadge;
|
let pinnedBadge;
|
||||||
if (post.is_pinned) {
|
if (post.is_pinned) {
|
||||||
pinnedBadge = (
|
pinnedBadge = (
|
||||||
@@ -601,20 +563,11 @@ export default class RhsRootPost extends React.Component {
|
|||||||
<li className='col'>
|
<li className='col'>
|
||||||
{this.renderTimeTag(post, timeOptions)}
|
{this.renderTimeTag(post, timeOptions)}
|
||||||
{pinnedBadge}
|
{pinnedBadge}
|
||||||
<OverlayTrigger
|
<PostFlagIcon
|
||||||
key={'rootpostflagtooltipkey' + flagVisible}
|
idPrefix={'rhsRootPostFlag'}
|
||||||
delayShow={Constants.OVERLAY_TIME_DELAY}
|
postId={post.id}
|
||||||
placement='top'
|
isFlagged={this.props.isFlagged}
|
||||||
overlay={flagTooltip}
|
/>
|
||||||
>
|
|
||||||
<a
|
|
||||||
href='#'
|
|
||||||
className={'flag-icon__container ' + flagVisible}
|
|
||||||
onClick={flagFunc}
|
|
||||||
>
|
|
||||||
{flag}
|
|
||||||
</a>
|
|
||||||
</OverlayTrigger>
|
|
||||||
</li>
|
</li>
|
||||||
<li className='col col__reply'>
|
<li className='col col__reply'>
|
||||||
{reactOverlay}
|
{reactOverlay}
|
||||||
@@ -645,6 +598,7 @@ RhsRootPost.defaultProps = {
|
|||||||
};
|
};
|
||||||
RhsRootPost.propTypes = {
|
RhsRootPost.propTypes = {
|
||||||
post: React.PropTypes.object.isRequired,
|
post: React.PropTypes.object.isRequired,
|
||||||
|
lastPostCount: React.PropTypes.number,
|
||||||
user: React.PropTypes.object.isRequired,
|
user: React.PropTypes.object.isRequired,
|
||||||
currentUser: React.PropTypes.object.isRequired,
|
currentUser: React.PropTypes.object.isRequired,
|
||||||
commentCount: React.PropTypes.number,
|
commentCount: React.PropTypes.number,
|
||||||
|
|||||||
@@ -352,7 +352,8 @@ export default class RhsThread extends React.Component {
|
|||||||
let previousPostDay = rootPostDay;
|
let previousPostDay = rootPostDay;
|
||||||
|
|
||||||
const commentsLists = [];
|
const commentsLists = [];
|
||||||
for (let i = 0; i < postsArray.length; i++) {
|
const postsLength = postsArray.length;
|
||||||
|
for (let i = 0; i < postsLength; i++) {
|
||||||
const comPost = postsArray[i];
|
const comPost = postsArray[i];
|
||||||
let p;
|
let p;
|
||||||
if (UserStore.getCurrentId() === comPost.user_id) {
|
if (UserStore.getCurrentId() === comPost.user_id) {
|
||||||
@@ -371,10 +372,7 @@ export default class RhsThread extends React.Component {
|
|||||||
status = this.state.statuses[p.id] || 'offline';
|
status = this.state.statuses[p.id] || 'offline';
|
||||||
}
|
}
|
||||||
|
|
||||||
const keyPrefix = comPost.id ? comPost.id : comPost.pending_post_id;
|
|
||||||
|
|
||||||
const currentPostDay = Utils.getDateForUnixTicks(comPost.create_at);
|
const currentPostDay = Utils.getDateForUnixTicks(comPost.create_at);
|
||||||
|
|
||||||
if (currentPostDay.toDateString() !== previousPostDay.toDateString()) {
|
if (currentPostDay.toDateString() !== previousPostDay.toDateString()) {
|
||||||
previousPostDay = currentPostDay;
|
previousPostDay = currentPostDay;
|
||||||
commentsLists.push(
|
commentsLists.push(
|
||||||
@@ -383,11 +381,14 @@ export default class RhsThread extends React.Component {
|
|||||||
/>);
|
/>);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const keyPrefix = comPost.id ? comPost.id : comPost.pending_post_id;
|
||||||
|
const reverseCount = postsLength - i - 1;
|
||||||
commentsLists.push(
|
commentsLists.push(
|
||||||
<div key={keyPrefix + 'commentKey'}>
|
<div key={keyPrefix + 'commentKey'}>
|
||||||
<Comment
|
<Comment
|
||||||
ref={comPost.id}
|
ref={comPost.id}
|
||||||
post={comPost}
|
post={comPost}
|
||||||
|
lastPostCount={(reverseCount >= 0 && reverseCount < Constants.TEST_ID_COUNT) ? reverseCount : -1}
|
||||||
user={p}
|
user={p}
|
||||||
currentUser={this.props.currentUser}
|
currentUser={this.props.currentUser}
|
||||||
compactDisplay={this.state.compactDisplay}
|
compactDisplay={this.state.compactDisplay}
|
||||||
@@ -431,12 +432,12 @@ export default class RhsThread extends React.Component {
|
|||||||
className='post-right__scroll'
|
className='post-right__scroll'
|
||||||
>
|
>
|
||||||
<DateSeparator
|
<DateSeparator
|
||||||
date={rootPostDay.toDateString()}
|
date={rootPostDay}
|
||||||
/>
|
/>
|
||||||
<RootPost
|
<RootPost
|
||||||
ref={selected.id}
|
ref={selected.id}
|
||||||
post={selected}
|
post={selected}
|
||||||
commentCount={postsArray.length}
|
commentCount={postsLength}
|
||||||
user={profile}
|
user={profile}
|
||||||
currentUser={this.props.currentUser}
|
currentUser={this.props.currentUser}
|
||||||
compactDisplay={this.state.compactDisplay}
|
compactDisplay={this.state.compactDisplay}
|
||||||
@@ -456,7 +457,7 @@ export default class RhsThread extends React.Component {
|
|||||||
<CreateComment
|
<CreateComment
|
||||||
channelId={selected.channel_id}
|
channelId={selected.channel_id}
|
||||||
rootId={selected.id}
|
rootId={selected.id}
|
||||||
latestPostId={postsArray.length > 0 ? postsArray[postsArray.length - 1].id : selected.id}
|
latestPostId={postsLength > 0 ? postsArray[postsLength - 1].id : selected.id}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -267,7 +267,7 @@ export default class SearchResults extends React.Component {
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
ctls = results.order.map(function mymap(id) {
|
ctls = results.order.map(function searchResults(id, idx, arr) {
|
||||||
const post = results.posts[id];
|
const post = results.posts[id];
|
||||||
let profile;
|
let profile;
|
||||||
if (UserStore.getCurrentId() === post.user_id) {
|
if (UserStore.getCurrentId() === post.user_id) {
|
||||||
@@ -285,12 +285,16 @@ export default class SearchResults extends React.Component {
|
|||||||
if (this.state.flaggedPosts) {
|
if (this.state.flaggedPosts) {
|
||||||
isFlagged = this.state.flaggedPosts.get(post.id) === 'true';
|
isFlagged = this.state.flaggedPosts.get(post.id) === 'true';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const reverseCount = arr.length - idx - 1;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SearchResultsItem
|
<SearchResultsItem
|
||||||
key={post.id}
|
key={post.id}
|
||||||
channel={this.state.channels.get(post.channel_id)}
|
channel={this.state.channels.get(post.channel_id)}
|
||||||
compactDisplay={this.state.compactDisplay}
|
compactDisplay={this.state.compactDisplay}
|
||||||
post={post}
|
post={post}
|
||||||
|
lastPostCount={(reverseCount >= 0 && reverseCount < Constants.TEST_ID_COUNT) ? reverseCount : -1}
|
||||||
user={profile}
|
user={profile}
|
||||||
term={searchTerm}
|
term={searchTerm}
|
||||||
isMentionSearch={this.props.isMentionSearch}
|
isMentionSearch={this.props.isMentionSearch}
|
||||||
|
|||||||
@@ -13,12 +13,12 @@ import UserStore from 'stores/user_store.jsx';
|
|||||||
import AppDispatcher from '../dispatcher/app_dispatcher.jsx';
|
import AppDispatcher from '../dispatcher/app_dispatcher.jsx';
|
||||||
import * as GlobalActions from 'actions/global_actions.jsx';
|
import * as GlobalActions from 'actions/global_actions.jsx';
|
||||||
import {flagPost, unflagPost} from 'actions/post_actions.jsx';
|
import {flagPost, unflagPost} from 'actions/post_actions.jsx';
|
||||||
|
import PostFlagIcon from 'components/common/post_flag_icon.jsx';
|
||||||
|
|
||||||
import * as Utils from 'utils/utils.jsx';
|
import * as Utils from 'utils/utils.jsx';
|
||||||
import * as PostUtils from 'utils/post_utils.jsx';
|
import * as PostUtils from 'utils/post_utils.jsx';
|
||||||
|
|
||||||
import Constants from 'utils/constants.jsx';
|
import Constants from 'utils/constants.jsx';
|
||||||
import {Tooltip, OverlayTrigger} from 'react-bootstrap';
|
|
||||||
const ActionTypes = Constants.ActionTypes;
|
const ActionTypes = Constants.ActionTypes;
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
@@ -114,7 +114,11 @@ export default class SearchResultsItem extends React.Component {
|
|||||||
const timestamp = UserStore.getCurrentUser().last_picture_update;
|
const timestamp = UserStore.getCurrentUser().last_picture_update;
|
||||||
const user = this.props.user || {};
|
const user = this.props.user || {};
|
||||||
const post = this.props.post;
|
const post = this.props.post;
|
||||||
const flagIcon = Constants.FLAG_ICON_SVG;
|
|
||||||
|
let idCount = -1;
|
||||||
|
if (this.props.lastPostCount >= 0 && this.props.lastPostCount < Constants.TEST_ID_COUNT) {
|
||||||
|
idCount = this.props.lastPostCount;
|
||||||
|
}
|
||||||
|
|
||||||
if (channel) {
|
if (channel) {
|
||||||
channelName = channel.display_name;
|
channelName = channel.display_name;
|
||||||
@@ -185,59 +189,13 @@ export default class SearchResultsItem extends React.Component {
|
|||||||
</p>
|
</p>
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
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 = (
|
|
||||||
<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 = (
|
flagContent = (
|
||||||
<OverlayTrigger
|
<PostFlagIcon
|
||||||
delayShow={Constants.OVERLAY_TIME_DELAY}
|
idPrefix={'searchPostFlag'}
|
||||||
placement='top'
|
idCount={idCount}
|
||||||
overlay={flagTooltip}
|
postId={post.id}
|
||||||
>
|
isFlagged={this.props.isFlagged}
|
||||||
<a
|
/>
|
||||||
href='#'
|
|
||||||
className={'flag-icon__container ' + flagVisible}
|
|
||||||
onClick={flagFunc}
|
|
||||||
>
|
|
||||||
{flag}
|
|
||||||
</a>
|
|
||||||
</OverlayTrigger>
|
|
||||||
);
|
);
|
||||||
|
|
||||||
rhsControls = (
|
rhsControls = (
|
||||||
@@ -364,6 +322,7 @@ export default class SearchResultsItem extends React.Component {
|
|||||||
|
|
||||||
SearchResultsItem.propTypes = {
|
SearchResultsItem.propTypes = {
|
||||||
post: React.PropTypes.object,
|
post: React.PropTypes.object,
|
||||||
|
lastPostCount: React.PropTypes.number,
|
||||||
user: React.PropTypes.object,
|
user: React.PropTypes.object,
|
||||||
channel: React.PropTypes.object,
|
channel: React.PropTypes.object,
|
||||||
compactDisplay: React.PropTypes.bool,
|
compactDisplay: React.PropTypes.bool,
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user