@wordpress/editor
Version:
Enhanced block editor for WordPress posts.
342 lines (331 loc) • 11 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = CollabSidebar;
var _i18n = require("@wordpress/i18n");
var _data = require("@wordpress/data");
var _element = require("@wordpress/element");
var _icons = require("@wordpress/icons");
var _hooks = require("@wordpress/hooks");
var _notices = require("@wordpress/notices");
var _coreData = require("@wordpress/core-data");
var _blockEditor = require("@wordpress/block-editor");
var _interface = require("@wordpress/interface");
var _pluginSidebar = _interopRequireDefault(require("../plugin-sidebar"));
var _constants = require("./constants");
var _comments = require("./comments");
var _addComment = require("./add-comment");
var _store = require("../../store");
var _commentButton = _interopRequireDefault(require("./comment-button"));
var _commentButtonToolbar = _interopRequireDefault(require("./comment-button-toolbar"));
var _globalStylesProvider = require("../global-styles-provider");
var _utils = require("./utils");
var _jsxRuntime = require("react/jsx-runtime");
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
const modifyBlockCommentAttributes = settings => {
if (!settings.attributes.blockCommentId) {
settings.attributes = {
...settings.attributes,
blockCommentId: {
type: 'number'
}
};
}
return settings;
};
// Apply the filter to all core blocks
(0, _hooks.addFilter)('blocks.registerBlockType', 'block-comment/modify-core-block-attributes', modifyBlockCommentAttributes);
function CollabSidebarContent({
showCommentBoard,
setShowCommentBoard,
styles,
comments
}) {
const {
createNotice
} = (0, _data.useDispatch)(_notices.store);
const {
saveEntityRecord,
deleteEntityRecord
} = (0, _data.useDispatch)(_coreData.store);
const {
getEntityRecord
} = (0, _data.resolveSelect)(_coreData.store);
const {
postId
} = (0, _data.useSelect)(select => {
const {
getCurrentPostId
} = select(_store.store);
const _postId = getCurrentPostId();
return {
postId: _postId
};
}, []);
const {
getSelectedBlockClientId
} = (0, _data.useSelect)(_blockEditor.store);
const {
updateBlockAttributes
} = (0, _data.useDispatch)(_blockEditor.store);
// Function to save the comment.
const addNewComment = async (comment, parentCommentId) => {
const args = {
post: postId,
content: comment,
comment_type: 'block_comment',
comment_approved: 0
};
// Create a new object, conditionally including the parent property
const updatedArgs = {
...args,
...(parentCommentId ? {
parent: parentCommentId
} : {})
};
const savedRecord = await saveEntityRecord('root', 'comment', updatedArgs);
if (savedRecord) {
// If it's a main comment, update the block attributes with the comment id.
if (!parentCommentId) {
updateBlockAttributes(getSelectedBlockClientId(), {
blockCommentId: savedRecord?.id
});
}
createNotice('snackbar', parentCommentId ?
// translators: Reply added successfully
(0, _i18n.__)('Reply added successfully.') :
// translators: Comment added successfully
(0, _i18n.__)('Comment added successfully.'), {
type: 'snackbar',
isDismissible: true
});
} else {
onError();
}
};
const onCommentResolve = async commentId => {
const savedRecord = await saveEntityRecord('root', 'comment', {
id: commentId,
status: 'approved'
});
if (savedRecord) {
// translators: Comment resolved successfully
createNotice('snackbar', (0, _i18n.__)('Comment marked as resolved.'), {
type: 'snackbar',
isDismissible: true
});
} else {
onError();
}
};
const onEditComment = async (commentId, comment) => {
const savedRecord = await saveEntityRecord('root', 'comment', {
id: commentId,
content: comment
});
if (savedRecord) {
createNotice('snackbar',
// translators: Comment edited successfully
(0, _i18n.__)('Comment edited successfully.'), {
type: 'snackbar',
isDismissible: true
});
} else {
onError();
}
};
const onError = () => {
createNotice('error',
// translators: Error message when comment submission fails
(0, _i18n.__)('Something went wrong. Please try publishing the post, or you may have already submitted your comment earlier.'), {
isDismissible: true
});
};
const onCommentDelete = async commentId => {
const childComment = await getEntityRecord('root', 'comment', commentId);
await deleteEntityRecord('root', 'comment', commentId);
if (childComment && !childComment.parent) {
updateBlockAttributes(getSelectedBlockClientId(), {
blockCommentId: undefined
});
}
createNotice('snackbar',
// translators: Comment deleted successfully
(0, _i18n.__)('Comment deleted successfully.'), {
type: 'snackbar',
isDismissible: true
});
};
return /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
className: "editor-collab-sidebar-panel",
style: styles,
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_addComment.AddComment, {
onSubmit: addNewComment,
showCommentBoard: showCommentBoard,
setShowCommentBoard: setShowCommentBoard
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_comments.Comments, {
threads: comments,
onEditComment: onEditComment,
onAddReply: addNewComment,
onCommentDelete: onCommentDelete,
onCommentResolve: onCommentResolve,
showCommentBoard: showCommentBoard,
setShowCommentBoard: setShowCommentBoard
}, getSelectedBlockClientId())]
});
}
/**
* Renders the Collab sidebar.
*/
function CollabSidebar() {
const [showCommentBoard, setShowCommentBoard] = (0, _element.useState)(false);
const {
enableComplementaryArea
} = (0, _data.useDispatch)(_interface.store);
const {
getActiveComplementaryArea
} = (0, _data.useSelect)(_interface.store);
const {
postId,
postType,
postStatus,
threads
} = (0, _data.useSelect)(select => {
const {
getCurrentPostId,
getCurrentPostType
} = select(_store.store);
const _postId = getCurrentPostId();
const data = !!_postId && typeof _postId === 'number' ? select(_coreData.store).getEntityRecords('root', 'comment', {
post: _postId,
type: 'block_comment',
status: 'any',
per_page: 100
}) : null;
return {
postId: _postId,
postType: getCurrentPostType(),
postStatus: select(_store.store).getEditedPostAttribute('status'),
threads: data
};
}, []);
const {
blockCommentId
} = (0, _data.useSelect)(select => {
const {
getBlockAttributes,
getSelectedBlockClientId
} = select(_blockEditor.store);
const _clientId = getSelectedBlockClientId();
return {
blockCommentId: _clientId ? getBlockAttributes(_clientId)?.blockCommentId : null
};
}, []);
const openCollabBoard = () => {
setShowCommentBoard(true);
enableComplementaryArea('core', 'edit-post/collab-sidebar');
};
const [blocks] = (0, _coreData.useEntityBlockEditor)('postType', postType, {
id: postId
});
// Process comments to build the tree structure
const {
resultComments,
sortedThreads
} = (0, _element.useMemo)(() => {
// Create a compare to store the references to all objects by id
const compare = {};
const result = [];
const filteredComments = (threads !== null && threads !== void 0 ? threads : []).filter(comment => comment.status !== 'trash');
// Initialize each object with an empty `reply` array
filteredComments.forEach(item => {
compare[item.id] = {
...item,
reply: []
};
});
// Iterate over the data to build the tree structure
filteredComments.forEach(item => {
if (item.parent === 0) {
// If parent is 0, it's a root item, push it to the result array
result.push(compare[item.id]);
} else if (compare[item.parent]) {
// Otherwise, find its parent and push it to the parent's `reply` array
compare[item.parent].reply.push(compare[item.id]);
}
});
if (0 === result?.length) {
return {
resultComments: [],
sortedThreads: []
};
}
const updatedResult = result.map(item => ({
...item,
reply: [...item.reply].reverse()
}));
const blockCommentIds = (0, _utils.getCommentIdsFromBlocks)(blocks);
const threadIdMap = new Map(updatedResult.map(thread => [thread.id, thread]));
const sortedComments = blockCommentIds.map(id => threadIdMap.get(id)).filter(thread => thread !== undefined);
return {
resultComments: updatedResult,
sortedThreads: sortedComments
};
}, [threads, blocks]);
// Get the global styles to set the background color of the sidebar.
const {
merged: GlobalStyles
} = (0, _globalStylesProvider.useGlobalStylesContext)();
const backgroundColor = GlobalStyles?.styles?.color?.background;
if (0 < resultComments.length) {
const unsubscribe = (0, _data.subscribe)(() => {
const activeSidebar = getActiveComplementaryArea('core');
if (!activeSidebar) {
enableComplementaryArea('core', _constants.collabSidebarName);
unsubscribe();
}
});
}
if (postStatus === 'publish') {
return null; // or maybe return some message indicating no threads are available.
}
const AddCommentComponent = blockCommentId ? _commentButtonToolbar.default : _commentButton.default;
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(AddCommentComponent, {
onClick: openCollabBoard
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_pluginSidebar.default, {
identifier: _constants.collabHistorySidebarName
// translators: Comments sidebar title
,
title: (0, _i18n.__)('Comments'),
icon: _icons.comment,
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(CollabSidebarContent, {
comments: resultComments,
showCommentBoard: showCommentBoard,
setShowCommentBoard: setShowCommentBoard
})
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_pluginSidebar.default, {
isPinnable: false,
header: false,
identifier: _constants.collabSidebarName,
className: "editor-collab-sidebar",
headerClassName: "editor-collab-sidebar__header",
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(CollabSidebarContent, {
comments: sortedThreads,
showCommentBoard: showCommentBoard,
setShowCommentBoard: setShowCommentBoard,
styles: {
backgroundColor
}
})
})]
});
}
//# sourceMappingURL=index.js.map