/* eslint-disable import/no-absolute-path */
/* eslint-disable jsx-a11y/media-has-caption */
import React from 'react';
import PropTypes from 'prop-types';
import { withTracker } from 'meteor/react-meteor-data';
import { withTranslation } from 'react-i18next';
import { Meteor } from 'meteor/meteor';
import moment from 'moment';
import CommentsCollection from '/imports/api/Comments/Comments';
import './Comments.scss';
function MediaEmbed({ media }) {
if (!media || !media.content) return null;
if (media.type === 'image') {
return ;
}
if (media.type === 'youtube') {
return (
);
}
return null;
}
MediaEmbed.propTypes = { media: PropTypes.object };
MediaEmbed.defaultProps = { media: null };
class CommentsBox extends React.Component {
constructor(props) {
super(props);
this.state = { draft: '', editingId: null, editDraft: '' };
}
call(method, ...args) {
Meteor.call(method, ...args, (err) => {
if (err) console.warn(`${method}: ${err.reason || err.message}`);
});
}
submit = (e) => {
e.preventDefault();
const content = this.state.draft.trim();
if (!content) return;
this.setState({ draft: '' });
this.call('comments.insert', this.props.referenceId, content);
};
saveEdit = (id) => {
const content = this.state.editDraft.trim();
if (!content) return;
this.setState({ editingId: null, editDraft: '' });
this.call('comments.edit', id, content);
};
renderComment(c) {
const { t } = this.props;
const currentUserId = Meteor.userId();
const isOwner = currentUserId && c.userId === currentUserId;
const likes = (c.likes || []).length;
const dislikes = (c.dislikes || []).length;
const liked = currentUserId && (c.likes || []).includes(currentUserId);
const disliked = currentUserId && (c.dislikes || []).includes(currentUserId);
const author = c.username || t('Anónimo');
return (
{author}
{moment(c.createdAt).format('LLL')}
{this.state.editingId === c._id ? (
) : (
// Plain text (whitespace preserved via CSS). Rendered as text — not
// HTML — so user content can never inject markup (safer than the old
// markdown-to-HTML comments package).
{c.content}
)}
this.call('comments.like', c._id)}>
{'👍'} {likes}
this.call('comments.dislike', c._id)}>
{'👎'} {dislikes}
{isOwner && (
this.setState({ editingId: c._id, editDraft: c.content })}>{t('Editar')}
this.call('comments.remove', c._id)}>{t('Borrar')}
)}
);
}
render() {
const { t, comments, ready } = this.props;
const loggedIn = !!Meteor.userId();
return (
{comments.map(c => this.renderComment(c))}
{ready && comments.length === 0 && (
{t('Añadir un comentario')}
)}
{loggedIn ? (
) : (
{t('Necesitas iniciar sesión para')} {t('añadir comentarios')}
)}
);
}
}
CommentsBox.propTypes = {
t: PropTypes.func.isRequired,
referenceId: PropTypes.string.isRequired,
comments: PropTypes.arrayOf(PropTypes.object).isRequired,
ready: PropTypes.bool.isRequired
};
const CommentsBoxContainer = withTracker(({ referenceId }) => {
const handle = Meteor.subscribe('comments.forReference', referenceId);
return {
ready: handle.ready(),
comments: CommentsCollection.find({ referenceId }, { sort: { createdAt: 1 } }).fetch()
};
})(CommentsBox);
export default withTranslation()(CommentsBoxContainer);