// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. // See License.txt for license information. import $ from 'jquery'; import ReactDOM from 'react-dom'; import PostTime from './post_time.jsx'; import * as GlobalActions from 'actions/global_actions.jsx'; import * as PostActions from 'actions/post_actions.jsx'; import * as Utils from 'utils/utils.jsx'; import * as PostUtils from 'utils/post_utils.jsx'; import Constants from 'utils/constants.jsx'; import DelayedAction from 'utils/delayed_action.jsx'; import {Tooltip, OverlayTrigger, Overlay} from 'react-bootstrap'; import EmojiPicker from 'components/emoji_picker/emoji_picker.jsx'; import React from 'react'; import {FormattedMessage} from 'react-intl'; export default class PostInfo extends React.Component { constructor(props) { super(props); this.handleDropdownOpened = this.handleDropdownOpened.bind(this); this.handlePermalink = this.handlePermalink.bind(this); this.removePost = this.removePost.bind(this); this.flagPost = this.flagPost.bind(this); this.unflagPost = this.unflagPost.bind(this); this.pinPost = this.pinPost.bind(this); this.unpinPost = this.unpinPost.bind(this); this.reactEmojiClick = this.reactEmojiClick.bind(this); this.emojiPickerClick = this.emojiPickerClick.bind(this); this.canEdit = false; this.canDelete = false; this.editDisableAction = new DelayedAction(this.handleEditDisable); this.state = { showEmojiPicker: false, reactionPickerOffset: 21 }; } handleDropdownOpened() { this.props.handleDropdownOpened(true); const position = $('#post-list').height() - $(this.refs.dropdownToggle).offset().top; const dropdown = $(this.refs.dropdown); if (position < dropdown.height()) { dropdown.addClass('bottom'); } } handleEditDisable() { this.canEdit = false; } componentDidMount() { $('#post_dropdown' + this.props.post.id).on('shown.bs.dropdown', this.handleDropdownOpened); $('#post_dropdown' + this.props.post.id).on('hidden.bs.dropdown', () => this.props.handleDropdownOpened(false)); } createDropdown() { const post = this.props.post; const isSystemMessage = PostUtils.isSystemMessage(post); if (post.state === Constants.POST_FAILED || post.state === Constants.POST_LOADING) { return ''; } var type = 'Post'; if (post.root_id && post.root_id.length > 0) { type = 'Comment'; } var dropdownContents = []; var dataComments = 0; if (type === 'Post') { dataComments = this.props.commentCount; } if (this.props.allowReply) { dropdownContents.push(
  • ); } if (Utils.isMobile()) { if (this.props.isFlagged) { dropdownContents.push(
  • ); } else { dropdownContents.push(
  • ); } } if (!isSystemMessage) { dropdownContents.push(
  • ); } if (this.props.post.is_pinned) { dropdownContents.push(
  • ); } else { dropdownContents.push(
  • ); } if (this.canDelete) { dropdownContents.push(
  • { e.preventDefault(); GlobalActions.showDeletePostModal(post, dataComments); }} >
  • ); } if (this.canEdit) { dropdownContents.push(
  • ); } if (dropdownContents.length === 0) { return ''; } return (
    {'×'} ); } pinPost(e) { e.preventDefault(); PostActions.pinPost(this.props.post.channel_id, this.props.post.id); } unpinPost(e) { e.preventDefault(); PostActions.unpinPost(this.props.post.channel_id, this.props.post.id); } flagPost(e) { e.preventDefault(); PostActions.flagPost(this.props.post.id); } unflagPost(e) { e.preventDefault(); PostActions.unflagPost(this.props.post.id); } reactEmojiClick(emoji) { const pickerOffset = 21; const emojiName = emoji.name || emoji.aliases[0]; PostActions.addReaction(this.props.post.channel_id, this.props.post.id, emojiName); this.setState({showEmojiPicker: false, reactionPickerOffset: pickerOffset}); } render() { var post = this.props.post; var comments = ''; var showCommentClass = ''; var commentCountText = this.props.commentCount; const flagIcon = Constants.FLAG_ICON_SVG; this.canDelete = PostUtils.canDeletePost(post); this.canEdit = PostUtils.canEditPost(post, this.editDisableAction); if (this.props.commentCount >= 1) { showCommentClass = ' icon--show'; } else { commentCountText = ''; } if (post.state !== Constants.POST_FAILED && post.state !== Constants.POST_LOADING && !Utils.isPostEphemeral(post) && this.props.allowReply) { comments = ( {commentCountText} ); } let react; if (post.state !== Constants.POST_FAILED && post.state !== Constants.POST_LOADING && !Utils.isPostEphemeral(post) && Utils.isFeatureEnabled(Constants.PRE_RELEASE_FEATURES.EMOJI_PICKER_PREVIEW)) { react = ( this.setState({showEmojiPicker: false})} target={() => ReactDOM.findDOMNode(this.refs['reactIcon_' + post.id])} > ); } let options; if (Utils.isPostEphemeral(post)) { options = (
  • {this.createRemovePostButton()}
  • ); } else { const dropdown = this.createDropdown(); if (dropdown) { options = (
  • {dropdown}
    {react} {comments}
  • ); } } let flag; let flagFunc; let flagVisible = ''; let flagTooltip = ( ); if (this.props.isFlagged) { flagVisible = 'visible'; flag = ( ); flagFunc = this.unflagPost; flagTooltip = ( ); } else { flag = ( ); flagFunc = this.flagPost; } let flagTrigger; if (!Utils.isPostEphemeral(post)) { flagTrigger = ( {flag} ); } let pinnedBadge; if (post.is_pinned) { pinnedBadge = ( ); } return (
    • {pinnedBadge} {this.state.showEmojiPicker} {flagTrigger}
    • {options}
    ); } } PostInfo.defaultProps = { post: null, commentCount: 0, isLastComment: false, allowReply: false, sameUser: false }; PostInfo.propTypes = { post: React.PropTypes.object.isRequired, commentCount: React.PropTypes.number.isRequired, isLastComment: React.PropTypes.bool.isRequired, allowReply: React.PropTypes.bool.isRequired, handleCommentClick: React.PropTypes.func.isRequired, handleDropdownOpened: React.PropTypes.func.isRequired, sameUser: React.PropTypes.bool.isRequired, currentUser: React.PropTypes.object.isRequired, compactDisplay: React.PropTypes.bool, useMilitaryTime: React.PropTypes.bool.isRequired, isFlagged: React.PropTypes.bool };