import React, { useRef } from 'react';
import PropTypes from 'prop-types';
import './Message.scss';
import Linkify from 'linkifyjs/react';
import ReactMarkdown from 'react-markdown';
import gfm from 'remark-gfm';
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';
import { coy } from 'react-syntax-highlighter/dist/esm/styles/prism';
import parse from 'html-react-parser';
import twemoji from 'twemoji';
import { getUsername } from '../../../util/matrixUtil';
import Text from '../../atoms/text/Text';
import RawIcon from '../../atoms/system-icons/RawIcon';
import Button from '../../atoms/button/Button';
import Tooltip from '../../atoms/tooltip/Tooltip';
import Input from '../../atoms/input/Input';
import ReplyArrowIC from '../../../../public/res/ic/outlined/reply-arrow.svg';
const components = {
code({
// eslint-disable-next-line react/prop-types
inline, className, children,
}) {
const match = /language-(\w+)/.exec(className || '');
return !inline && match ? (
{String(children).replace(/\n$/, '')}
) : (
{String(children)}
);
},
};
function linkifyContent(content) {
return {content};
}
function genMarkdown(content) {
return {content};
}
function PlaceholderMessage() {
return (
);
}
function MessageHeader({
userId, name, color, time,
}) {
return (
);
}
MessageHeader.propTypes = {
userId: PropTypes.string.isRequired,
name: PropTypes.string.isRequired,
color: PropTypes.string.isRequired,
time: PropTypes.string.isRequired,
};
function MessageReply({ name, color, content }) {
return (
{name}
<>{` ${content}`}>
);
}
MessageReply.propTypes = {
name: PropTypes.string.isRequired,
color: PropTypes.string.isRequired,
content: PropTypes.string.isRequired,
};
function MessageContent({ content, isMarkdown, isEdited }) {
return (
{ isMarkdown ? genMarkdown(content) : linkifyContent(content) }
{ isEdited &&
(edited)}
);
}
MessageContent.defaultProps = {
isMarkdown: false,
isEdited: false,
};
MessageContent.propTypes = {
content: PropTypes.node.isRequired,
isMarkdown: PropTypes.bool,
isEdited: PropTypes.bool,
};
function MessageEdit({ content, onSave, onCancel }) {
const editInputRef = useRef(null);
return (
);
}
MessageEdit.propTypes = {
content: PropTypes.string.isRequired,
onSave: PropTypes.func.isRequired,
onCancel: PropTypes.func.isRequired,
};
function MessageReactionGroup({ children }) {
return (
{ children }
);
}
MessageReactionGroup.propTypes = {
children: PropTypes.node.isRequired,
};
function genReactionMsg(userIds, reaction) {
const genLessContText = (text) => {text};
let msg = <>>;
userIds.forEach((userId, index) => {
if (index === 0) msg = <>{getUsername(userId)}>;
// eslint-disable-next-line react/jsx-one-expression-per-line
else if (index === userIds.length - 1) msg = <>{msg}{genLessContText(' and ')}{getUsername(userId)}>;
// eslint-disable-next-line react/jsx-one-expression-per-line
else msg = <>{msg}{genLessContText(', ')}{getUsername(userId)}>;
});
return (
<>
{msg}
{genLessContText(' reacted with')}
{parse(twemoji.parse(reaction))}
>
);
}
function MessageReaction({
reaction, users, isActive, onClick,
}) {
return (
{genReactionMsg(users, reaction)}}
>
);
}
MessageReaction.propTypes = {
reaction: PropTypes.node.isRequired,
users: PropTypes.arrayOf(PropTypes.string).isRequired,
isActive: PropTypes.bool.isRequired,
onClick: PropTypes.func.isRequired,
};
function MessageOptions({ children }) {
return (
{children}
);
}
MessageOptions.propTypes = {
children: PropTypes.node.isRequired,
};
function Message({
avatar, header, reply, content, editContent, reactions, options,
}) {
const msgClass = header === null ? ' message--content-only' : ' message--full';
return (
{avatar !== null && avatar}
{header !== null && header}
{reply !== null && reply}
{content !== null && content}
{editContent !== null && editContent}
{reactions !== null && reactions}
{options !== null && options}
);
}
Message.defaultProps = {
avatar: null,
header: null,
reply: null,
content: null,
editContent: null,
reactions: null,
options: null,
};
Message.propTypes = {
avatar: PropTypes.node,
header: PropTypes.node,
reply: PropTypes.node,
content: PropTypes.node,
editContent: PropTypes.node,
reactions: PropTypes.node,
options: PropTypes.node,
};
export {
Message,
MessageHeader,
MessageReply,
MessageContent,
MessageEdit,
MessageReactionGroup,
MessageReaction,
MessageOptions,
PlaceholderMessage,
};