@selfcommunity/react-ui
Version:
React UI Components to integrate a Community created with SelfCommunity Platform.
185 lines (177 loc) • 9.62 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = require("react");
const react_intl_1 = require("react-intl");
const LessonCommentObject_1 = tslib_1.__importStar(require("../LessonCommentObject"));
const material_1 = require("@mui/material");
const classnames_1 = tslib_1.__importDefault(require("classnames"));
const system_1 = require("@mui/system");
const types_1 = require("@selfcommunity/types");
const utils_1 = require("@selfcommunity/utils");
const react_core_1 = require("@selfcommunity/react-core");
const constants_1 = require("./constants");
const Skeleton_1 = tslib_1.__importDefault(require("./Skeleton"));
const CommentObjectReply_1 = tslib_1.__importDefault(require("../CommentObjectReply"));
const notistack_1 = require("notistack");
const Errors_1 = require("../../constants/Errors");
const api_services_1 = require("@selfcommunity/api-services");
const InfiniteScroll_1 = tslib_1.__importDefault(require("../../shared/InfiniteScroll"));
const HiddenPlaceholder_1 = tslib_1.__importDefault(require("../../shared/HiddenPlaceholder"));
const messages = (0, react_intl_1.defineMessages)({
commentEditorPlaceholder: {
id: 'ui.lessonCommentObjects.editor.placeholder',
defaultMessage: 'ui.lessonCommentObjects.editor.placeholder'
}
});
const classes = {
root: `${constants_1.PREFIX}-root`,
loadNextCommentsButton: `${constants_1.PREFIX}-load-more-comments-button`,
loadPreviousCommentsButton: `${constants_1.PREFIX}-load-previous-comments-button`,
paginationLink: `${constants_1.PREFIX}-pagination-link`,
pagination: `${constants_1.PREFIX}-pagination`,
commentsCounter: `${constants_1.PREFIX}-comments-counter`,
commentNotFound: `${constants_1.PREFIX}-comment-not-found`,
noOtherComments: `${constants_1.PREFIX}-no-other-comment`
};
const Root = (0, material_1.styled)(material_1.Box, {
name: constants_1.PREFIX,
slot: 'Root'
})(() => ({}));
/**
* > API documentation for the Community-JS Comments Object component. Learn about the available props and the CSS API.
#### Import
```jsx
import {LessonCommentObjects} from '@selfcommunity/react-ui';
```
#### Component Name
The name `SCLessonCommentObjects` can be used when providing style overrides in the theme.
#### CSS
|Rule Name|Global class|Description|
|---|---|---|
|root|.SCLessonCommentObjects-root|Styles applied to the root element.|
|pagination|.SCLessonCommentObjects-pagination|Styles applied to the pagination controls.|
|paginationLink|.SCLessonCommentObjects-pagination-link|Styles applied to the pagination link.|
|loadNextCommentsButton|.SCLessonCommentObjects-load-next-comments-button|Styles applied to the load next comments button.|
|loadPreviousCommentsButton|.SCLessonCommentObjects-load-previous-comments-button|Styles applied to the load previous comments button.|
|commentsCounter|.SCLessonCommentObjects-comments-counter|Styles applied to the comments counter element.|
* @param inProps
*/
function LessonCommentObjects(inProps) {
const props = (0, system_1.useThemeProps)({
props: inProps,
name: constants_1.PREFIX
});
// PROPS
const { id = `lesson_comment_objects_lesson_${props.lessonObjectId ? props.lessonObjectId : props.lessonObject ? props.lessonObject.id : ''}`, className, lessonObjectId, lessonObject, CommentComponentProps = {}, CommentObjectSkeletonProps = { elevation: 0 }, CommentsObjectSkeletonProps = {}, cacheStrategy = utils_1.CacheStrategies.STALE_WHILE_REVALIDATE } = props, rest = tslib_1.__rest(props, ["id", "className", "lessonObjectId", "lessonObject", "CommentComponentProps", "CommentObjectSkeletonProps", "CommentsObjectSkeletonProps", "cacheStrategy"]);
//STATE
const [commenting, setIsCommenting] = (0, react_1.useState)(false);
const [editing, setIsEditing] = (0, react_1.useState)(false);
const [replyKey, setReplyKey] = (0, react_1.useState)(0);
// CONTEXT
const scUserContext = (0, react_core_1.useSCUser)();
// INTL
const intl = (0, react_intl_1.useIntl)();
// REF
const commentsEndRef = (0, react_1.useRef)(null);
// STATE
const commentsObject = (0, react_core_1.useSCFetchLessonCommentObjects)({
id: lessonObject.id,
lessonObject: lessonObject,
orderBy: types_1.SCCommentsOrderBy.ADDED_AT_ASC,
cacheStrategy
});
// EFFECTS
(0, react_1.useEffect)(() => {
if (commentsObject.lessonObject) {
commentsObject.getNextPage();
}
}, [commentsObject.lessonObject]);
//HANDLERS
function handleNext() {
commentsObject.getNextPage();
}
const scrollToBottom = () => {
var _a;
(_a = commentsEndRef.current) === null || _a === void 0 ? void 0 : _a.scrollIntoView({ block: 'end', behavior: 'smooth' });
};
(0, react_1.useEffect)(() => {
if (commentsObject.comments.length > 0) {
scrollToBottom();
}
}, [commentsObject.comments]);
/**
* Perform save/update comment
*/
const performComment = (comment, medias) => {
const mediaIds = medias ? medias.map((media) => media.id) : [];
return api_services_1.http
.request({
url: api_services_1.Endpoints.CreateCourseComment.url({ id: lessonObject.course_id, section_id: lessonObject.section_id, lesson_id: lessonObject.id }),
method: api_services_1.Endpoints.CreateCourseComment.method,
data: { text: comment, medias: mediaIds }
})
.then((res) => {
if (res.status >= 300) {
return Promise.reject(res);
}
return Promise.resolve(res.data);
});
};
/**
* Handle save comment
*/
function handleCommentAction(comment, medias) {
if (react_core_1.UserUtils.isBlocked(scUserContext.user)) {
(0, notistack_1.enqueueSnackbar)((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.common.userBlocked", defaultMessage: "ui.common.userBlocked" }), {
variant: 'warning',
autoHideDuration: 3000
});
}
else {
setIsCommenting(true);
performComment(comment, medias)
.then((data) => {
handleCommentsUpdate(data);
setReplyKey(comment.id);
setIsCommenting(false);
})
.catch((error) => {
utils_1.Logger.error(Errors_1.SCOPE_SC_UI, error);
(0, notistack_1.enqueueSnackbar)((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.common.error.action", defaultMessage: "ui.common.error.action" }), {
variant: 'error',
autoHideDuration: 3000
});
});
}
}
const handleCommentsUpdate = (comment, forDeletion) => {
let updated;
if (forDeletion) {
updated = commentsObject.comments.filter((c) => c.id !== comment.id);
}
else {
updated = [...commentsObject.comments, comment];
}
commentsObject.updateLessonComments([...updated]);
utils_1.LRUCache.set(react_core_1.SCCache.getLessonCommentCacheKey(lessonObject.id), updated);
utils_1.LRUCache.deleteKeysWithPrefix(react_core_1.SCCache.getLessonCommentsCachePrefixKeys(lessonObject.id));
};
/**
* Renders root object(if obj)
*/
if (!commentsObject.lessonObject) {
return (0, jsx_runtime_1.jsx)(HiddenPlaceholder_1.default, {});
}
if (!commentsObject.comments.length && commentsObject.isLoadingNext) {
return (0, jsx_runtime_1.jsx)(Skeleton_1.default, Object.assign({ count: 5 }, CommentsObjectSkeletonProps));
}
return ((0, jsx_runtime_1.jsx)(Root, Object.assign({ id: id, className: (0, classnames_1.default)(classes.root, className) }, rest, { children: (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: commentsObject.comments.length > 0 ? ((0, jsx_runtime_1.jsx)(InfiniteScroll_1.default, Object.assign({ height: '100%', dataLength: commentsObject.comments.length, next: handleNext, hasMoreNext: Boolean(commentsObject.next), loaderNext: (0, jsx_runtime_1.jsx)(LessonCommentObject_1.LessonCommentObjectSkeleton, Object.assign({}, CommentObjectSkeletonProps, { count: 1 })) }, { children: (0, jsx_runtime_1.jsx)(material_1.List, Object.assign({ ref: commentsEndRef }, { children: commentsObject.comments.map((c, index) => ((0, jsx_runtime_1.jsx)(material_1.ListItem, { children: (0, jsx_runtime_1.jsx)(LessonCommentObject_1.default, Object.assign({ commentObject: c, lessonObject: commentsObject.lessonObject, onDelete: (comment) => handleCommentsUpdate(comment, true), isEditing: (editing) => setIsEditing(editing) }, CommentComponentProps, { CommentObjectSkeletonProps: CommentObjectSkeletonProps }), c.id) }, index))) })) }))) : null }), !editing && ((0, jsx_runtime_1.jsx)(CommentObjectReply_1.default, { id: `reply-lessonCommentObjects`, showAvatar: false, replyIcon: true, editable: !commenting, onReply: handleCommentAction, EditorProps: {
placeholder: intl.formatMessage(messages.commentEditorPlaceholder),
uploadFile: true,
uploadImage: false,
isLessonCommentEditor: true
} }, replyKey))] }) })));
}
exports.default = LessonCommentObjects;