// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
import {Parser, ProcessNodeDefinitions} from 'html-to-react';
import PropTypes from 'prop-types';
import React from 'react';
import {FormattedMessage} from 'react-intl';
import AtMention from 'components/at_mention';
import store from 'stores/redux_store.jsx';
import * as PostUtils from 'utils/post_utils.jsx';
import * as TextFormatting from 'utils/text_formatting.jsx';
import * as Utils from 'utils/utils.jsx';
import {getChannelsNameMapInCurrentTeam} from 'mattermost-redux/selectors/entities/channels';
import {Posts} from 'mattermost-redux/constants';
import {renderSystemMessage} from './system_message_helpers.jsx';
export default class PostMessageView extends React.PureComponent {
static propTypes = {
/*
* The post to render the message for
*/
post: PropTypes.object.isRequired,
/*
* Object using emoji names as keys with custom emojis as the values
*/
emojis: PropTypes.object.isRequired,
/*
* The team the post was made in
*/
team: PropTypes.object.isRequired,
/*
* Set to enable Markdown formatting
*/
enableFormatting: PropTypes.bool,
/*
* An array of words that can be used to mention a user
*/
mentionKeys: PropTypes.arrayOf(PropTypes.string),
/*
* The URL that the app is hosted on
*/
siteUrl: PropTypes.string,
/*
* Options specific to text formatting
*/
options: PropTypes.object,
/*
* Post identifiers for selenium tests
*/
lastPostCount: PropTypes.number
};
static defaultProps = {
options: {},
mentionKeys: []
};
renderDeletedPost() {
return (
);
}
renderEditedIndicator() {
if (!PostUtils.isEdited(this.props.post)) {
return null;
}
return (
);
}
postMessageHtmlToComponent(html) {
const parser = new Parser();
const attrib = 'data-mention';
const processNodeDefinitions = new ProcessNodeDefinitions(React);
function isValidNode() {
return true;
}
const processingInstructions = [
{
replaceChildren: true,
shouldProcessNode: (node) => node.attribs && node.attribs[attrib],
processNode: (node) => {
const mentionName = node.attribs[attrib];
return ;
}
},
{
shouldProcessNode: () => true,
processNode: processNodeDefinitions.processDefaultNode
}
];
return parser.parseWithInstructions(html, isValidNode, processingInstructions);
}
render() {
if (this.props.post.state === Posts.POST_DELETED) {
return this.renderDeletedPost();
}
if (!this.props.enableFormatting) {
return {this.props.post.message};
}
const options = Object.assign({}, this.props.options, {
emojis: this.props.emojis,
siteURL: this.props.siteUrl,
mentionKeys: this.props.mentionKeys,
atMentions: true,
channelNamesMap: getChannelsNameMapInCurrentTeam(store.getState()),
team: this.props.team
});
const renderedSystemMessage = renderSystemMessage(this.props.post, options);
if (renderedSystemMessage) {
return {renderedSystemMessage}
;
}
let postId = null;
if (this.props.lastPostCount >= 0) {
postId = Utils.createSafeId('lastPostMessageText' + this.props.lastPostCount);
}
const htmlFormattedText = TextFormatting.formatText(this.props.post.message, options);
const postMessageComponent = this.postMessageHtmlToComponent(htmlFormattedText);
return (
{postMessageComponent}
{this.renderEditedIndicator()}
);
}
}