import React, {PropTypes} from 'react'; import {notifyForNewCommentStatus} from 'coral-plugin-commentbox/CommentBox'; import {CommentForm} from 'coral-plugin-commentbox/CommentForm'; import styles from './Comment.css'; import {CountdownSeconds} from './CountdownSeconds'; import {getEditableUntilDate} from './util'; import {can} from 'coral-framework/services/perms'; import {Icon} from 'coral-ui'; import t from 'coral-framework/services/i18n'; /** * Renders a Comment's body in such a way that the end-user can edit it and save changes */ export class EditableCommentContent extends React.Component { static propTypes = { // show notification to the user (e.g. for errors) addNotification: PropTypes.func.isRequired, asset: PropTypes.shape({ settings: PropTypes.shape({ charCountEnable: PropTypes.bool, }), }).isRequired, // comment that is being edited comment: PropTypes.shape({ body: PropTypes.string, editing: PropTypes.shape({ edited: PropTypes.bool, // ISO8601 editableUntil: PropTypes.string, }) }).isRequired, // logged in user currentUser: PropTypes.shape({ id: PropTypes.string.isRequired }), maxCharCount: PropTypes.number, // edit a comment, passed {{ body }} editComment: React.PropTypes.func, // called when editing should be stopped stopEditing: React.PropTypes.func, } constructor(props) { super(props); this.editWindowExpiryTimeout = null; } componentDidMount() { const editableUntil = getEditableUntilDate(this.props.comment); const now = new Date(); const editWindowRemainingMs = editableUntil && (editableUntil - now); if (editWindowRemainingMs > 0) { this.editWindowExpiryTimeout = setTimeout(() => { this.forceUpdate(); }, editWindowRemainingMs); } } componentWillUnmount() { if (this.editWindowExpiryTimeout) { this.editWindowExpiryTimeout = clearTimeout(this.editWindowExpiryTimeout); } } editComment = async (edit) => { if (!can(this.props.currentUser, 'INTERACT_WITH_COMMUNITY')) { this.props.addNotification('error', t('error.NOT_AUTHORIZED')); return; } const {editComment, addNotification, stopEditing} = this.props; if (typeof editComment !== 'function') {return;} let response; let successfullyEdited = false; try { response = await editComment(edit); const errors = (response && response.data && response.data.editComment) ? response.data.editComment.errors : null; if (errors && (errors.length === 1)) { throw errors[0]; } successfullyEdited = true; } catch (error) { const errors = error.errors || [error]; errors.forEach((e) => { if (e.translation_key) { addNotification('error', t(`error.${e.translation_key}`)); } else if (error.networkError) { addNotification('error', t('error.network_error')); } else { addNotification('error', t('edit_comment.unexpected_error')); console.error(e); } }); } if (successfullyEdited) { const status = response.data.editComment.comment.status; notifyForNewCommentStatus(this.props.addNotification, status); } if (successfullyEdited && typeof stopEditing === 'function') { stopEditing(); } } render() { const originalBody = this.props.comment.body; const editableUntil = getEditableUntilDate(this.props.comment); const editWindowExpired = (editableUntil - new Date()) < 0; return (
{ // should be disabled if user hasn't actually changed their // original comment return (comment.body !== originalBody) && !editWindowExpired; }} saveComment={this.editComment} bodyLabel={t('edit_comment.body_input_label')} bodyPlaceholder="" submitText={{t('edit_comment.save_button')}} saveButtonCStyle="green" cancelButtonClicked={this.props.stopEditing} buttonClass={styles.button} buttonContainerStart={
{ editWindowExpired ? {t('edit_comment.edit_window_expired')} { typeof this.props.stopEditing === 'function' ?  {t('edit_comment.edit_window_expired_close')} : null } : {t('edit_comment.edit_window_timer_prefix')} (remainingMs <= 10 * 1000) ? styles.editWindowAlmostOver : '' } /> }
} />
); } }