import React from 'preact/compat'; import Comment from './Comment'; import TextEntryField from './TextEntryField'; import i18n from '../../../i18n'; import PurposeDropdown from './PurposeDropdown'; const purposes = ['assessing', 'bookmarking', 'classifying', 'commenting', 'describing', 'editing', 'highlighting', 'identifying', 'linking', 'moderating', 'questioning'] /** * Comments are TextualBodies where the purpose field is either * blank or 'commenting' or 'replying' */ const isComment = body => body.type === 'TextualBody' && ( !body.hasOwnProperty('purpose') || purposes.indexOf(body.purpose) > -1 ); /** * The draft reply is a comment body with a 'draft' flag */ const getDraftReply = (existingDraft, isReply) => { let draft = existingDraft ? existingDraft : { type: 'TextualBody', value: '', draft: true }; draft.purpose = draft.purpose ? draft.purpose : isReply ? 'replying' : 'commenting'; return draft; }; /** * Renders a list of comment bodies, followed by a 'reply' field. */ const CommentWidget = props => { // All comments (draft + non-draft) const all = props.annotation ? props.annotation.bodies.filter(isComment) : []; // Last draft comment without a creator field goes into the reply field const draftReply = getDraftReply(all.slice().reverse().find(b => b.draft && !b.creator), all.length > 1); // All except draft reply const comments = all.filter(b => b != draftReply); const onEditReply = evt => { const prev = draftReply.value; const updated = evt.target.value; if (prev.length === 0 && updated.length > 0) { props.onAppendBody({ ...draftReply, value: updated }); } else if (prev.length > 0 && updated.length === 0) { props.onRemoveBody(draftReply); } else { props.onUpdateBody(draftReply, { ...draftReply, value: updated }); } } const onUpdatePurpose = evt => { const prev = draftReply.purpose.trim(); const updated = evt.value.trim(); if (draftReply.value == '' && updated.length > 0) { draftReply.purpose = updated; } else { props.onUpdateBody(draftReply, { ...draftReply, purpose: updated }); } } // A comment should be read-only if: // - the global read-only flag is set // - the current rule is 'MINE_ONLY' and the creator ID differs // The 'editable' config flag overrides the global setting, if any const isReadOnly = body => { if (props.editable === true) return false; if (props.editable === false) return true; if (props.editable === 'MINE_ONLY') { // The original creator of the body const creator = body.creator?.id; // The current user const me = props.env.user?.id; return me !== creator; } // Global setting as last possible option return props.readOnly; } return ( <> { comments.map((body, idx) => )} { !props.readOnly && props.annotation &&
0 ? i18n.t('Add a reply...') : i18n.t('Add a comment...')} onChange={onEditReply} onSaveAndClose={() => props.onSaveAndClose()} /> { props.purpose == true && draftReply.value.length > 0 && props.onSaveAndClose()} /> }
} ) } export default CommentWidget;