@wordpress/block-library
Version:
Block library for the WordPress editor.
290 lines (257 loc) • 9.7 kB
JavaScript
;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = CommentTemplateEdit;
var _element = require("@wordpress/element");
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
var _data = require("@wordpress/data");
var _i18n = require("@wordpress/i18n");
var _blockEditor = require("@wordpress/block-editor");
var _components = require("@wordpress/components");
var _coreData = require("@wordpress/core-data");
var _hooks = require("./hooks");
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
const TEMPLATE = [['core/avatar'], ['core/comment-author-name'], ['core/comment-date'], ['core/comment-content'], ['core/comment-reply-link'], ['core/comment-edit-link']];
/**
* Function that returns a comment structure that will be rendered with default placehoders.
*
* Each comment has a `commentId` property that is always a negative number in
* case of the placeholders. This is to ensure that the comment does not
* conflict with the actual (real) comments.
*
* @param {Object} settings Discussion Settings.
* @param {number} [settings.perPage] - Comments per page setting or block attribute.
* @param {boolean} [settings.threadComments] - Enable threaded (nested) comments setting.
* @param {number} [settings.threadCommentsDepth] - Level deep of threaded comments.
*
* @typedef {{id: null, children: EmptyComment[]}} EmptyComment
* @return {EmptyComment[]} Inner blocks of the Comment Template
*/
const getCommentsPlaceholder = _ref => {
let {
perPage,
threadComments,
threadCommentsDepth
} = _ref;
// In case that `threadCommentsDepth` is falsy, we default to a somewhat
// arbitrary value of 3.
// In case that the value is set but larger than 3 we truncate it to 3.
const commentsDepth = Math.min(threadCommentsDepth || 3, 3); // We set a limit in order not to overload the editor of empty comments.
const defaultCommentsToShow = perPage <= commentsDepth ? perPage : commentsDepth;
if (!threadComments || defaultCommentsToShow === 1) {
// If displaying threaded comments is disabled, we only show one comment
// A commentId is negative in order to avoid conflicts with the actual comments.
return [{
commentId: -1,
children: []
}];
} else if (defaultCommentsToShow === 2) {
return [{
commentId: -1,
children: [{
commentId: -2,
children: []
}]
}];
} // In case that the value is set but larger than 3 we truncate it to 3.
return [{
commentId: -1,
children: [{
commentId: -2,
children: [{
commentId: -3,
children: []
}]
}]
}];
};
/**
* Component which renders the inner blocks of the Comment Template.
*
* @param {Object} props Component props.
* @param {Array} [props.comment] - A comment object.
* @param {Array} [props.activeCommentId] - The ID of the comment that is currently active.
* @param {Array} [props.setActiveCommentId] - The setter for activeCommentId.
* @param {Array} [props.firstCommentId] - ID of the first comment in the array.
* @param {Array} [props.blocks] - Array of blocks returned from
* getBlocks() in parent .
* @return {WPElement} Inner blocks of the Comment Template
*/
function CommentTemplateInnerBlocks(_ref2) {
var _comment$children;
let {
comment,
activeCommentId,
setActiveCommentId,
firstCommentId,
blocks
} = _ref2;
const {
children,
...innerBlocksProps
} = (0, _blockEditor.useInnerBlocksProps)({}, {
template: TEMPLATE
});
return (0, _element.createElement)("li", innerBlocksProps, comment.commentId === (activeCommentId || firstCommentId) ? children : null, (0, _element.createElement)(MemoizedCommentTemplatePreview, {
blocks: blocks,
commentId: comment.commentId,
setActiveCommentId: setActiveCommentId,
isHidden: comment.commentId === (activeCommentId || firstCommentId)
}), (comment === null || comment === void 0 ? void 0 : (_comment$children = comment.children) === null || _comment$children === void 0 ? void 0 : _comment$children.length) > 0 ? (0, _element.createElement)(CommentsList, {
comments: comment.children,
activeCommentId: activeCommentId,
setActiveCommentId: setActiveCommentId,
blocks: blocks,
firstCommentId: firstCommentId
}) : null);
}
const CommentTemplatePreview = _ref3 => {
let {
blocks,
commentId,
setActiveCommentId,
isHidden
} = _ref3;
const blockPreviewProps = (0, _blockEditor.__experimentalUseBlockPreview)({
blocks
});
const handleOnClick = () => {
setActiveCommentId(commentId);
}; // We have to hide the preview block if the `comment` props points to
// the curently active block!
// Or, to put it differently, every preview block is visible unless it is the
// currently active block - in this case we render its inner blocks.
const style = {
display: isHidden ? 'none' : undefined
};
return (0, _element.createElement)("div", (0, _extends2.default)({}, blockPreviewProps, {
tabIndex: 0,
role: "button",
style: style // eslint-disable-next-line jsx-a11y/no-noninteractive-element-to-interactive-role
,
onClick: handleOnClick,
onKeyPress: handleOnClick
}));
};
const MemoizedCommentTemplatePreview = (0, _element.memo)(CommentTemplatePreview);
/**
* Component that renders a list of (nested) comments. It is called recursively.
*
* @param {Object} props Component props.
* @param {Array} [props.comments] - Array of comment objects.
* @param {Array} [props.blockProps] - Props from parent's `useBlockProps()`.
* @param {Array} [props.activeCommentId] - The ID of the comment that is currently active.
* @param {Array} [props.setActiveCommentId] - The setter for activeCommentId.
* @param {Array} [props.blocks] - Array of blocks returned from getBlocks() in parent.
* @param {Object} [props.firstCommentId] - The ID of the first comment in the array of
* comment objects.
* @return {WPElement} List of comments.
*/
const CommentsList = _ref4 => {
let {
comments,
blockProps,
activeCommentId,
setActiveCommentId,
blocks,
firstCommentId
} = _ref4;
return (0, _element.createElement)("ol", blockProps, comments && comments.map((_ref5, index) => {
let {
commentId,
...comment
} = _ref5;
return (0, _element.createElement)(_blockEditor.BlockContextProvider, {
key: comment.commentId || index,
value: {
// If the commentId is negative it means that this comment is a
// "placeholder" and that the block is most likely being used in the
// site editor. In this case, we have to set the commentId to `null`
// because otherwise the (non-existent) comment with a negative ID
// would be reqested from the REST API.
commentId: commentId < 0 ? null : commentId
}
}, (0, _element.createElement)(CommentTemplateInnerBlocks, {
comment: {
commentId,
...comment
},
activeCommentId: activeCommentId,
setActiveCommentId: setActiveCommentId,
blocks: blocks,
firstCommentId: firstCommentId
}));
}));
};
function CommentTemplateEdit(_ref6) {
var _commentTree$;
let {
clientId,
context: {
postId
}
} = _ref6;
const blockProps = (0, _blockEditor.useBlockProps)();
const [activeCommentId, setActiveCommentId] = (0, _element.useState)();
const {
commentOrder,
threadCommentsDepth,
threadComments,
commentsPerPage
} = (0, _data.useSelect)(select => {
const {
getSettings
} = select(_blockEditor.store);
return getSettings().__experimentalDiscussionSettings;
});
const commentQuery = (0, _hooks.useCommentQueryArgs)({
postId
});
const {
topLevelComments,
blocks
} = (0, _data.useSelect)(select => {
const {
getEntityRecords
} = select(_coreData.store);
const {
getBlocks
} = select(_blockEditor.store);
return {
// Request only top-level comments. Replies are embedded.
topLevelComments: commentQuery ? getEntityRecords('root', 'comment', commentQuery) : null,
blocks: getBlocks(clientId)
};
}, [clientId, commentQuery]); // Generate a tree structure of comment IDs.
let commentTree = (0, _hooks.useCommentTree)( // Reverse the order of top comments if needed.
commentOrder === 'desc' && topLevelComments ? [...topLevelComments].reverse() : topLevelComments);
if (!topLevelComments) {
return (0, _element.createElement)("p", blockProps, (0, _element.createElement)(_components.Spinner, null));
}
if (!postId) {
commentTree = getCommentsPlaceholder({
perPage: commentsPerPage,
threadComments,
threadCommentsDepth
});
}
if (!commentTree.length) {
return (0, _element.createElement)("p", blockProps, (0, _i18n.__)('No results found.'));
}
return (0, _element.createElement)(CommentsList, {
comments: commentTree,
blockProps: blockProps,
blocks: blocks,
activeCommentId: activeCommentId,
setActiveCommentId: setActiveCommentId,
firstCommentId: (_commentTree$ = commentTree[0]) === null || _commentTree$ === void 0 ? void 0 : _commentTree$.commentId
});
}
//# sourceMappingURL=edit.js.map