@selfcommunity/react-ui
Version:
React UI Components to integrate a Community created with SelfCommunity Platform.
323 lines (314 loc) • 22.9 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 styles_1 = require("@mui/material/styles");
const CardContent_1 = tslib_1.__importDefault(require("@mui/material/CardContent"));
const Comment_1 = tslib_1.__importDefault(require("./Comment"));
const UserFollow_1 = tslib_1.__importDefault(require("./UserFollow"));
const UndeletedFor_1 = tslib_1.__importDefault(require("./UndeletedFor"));
const DeletedFor_1 = tslib_1.__importDefault(require("./DeletedFor"));
const UserConnection_1 = tslib_1.__importDefault(require("./UserConnection"));
const PrivateMessage_1 = tslib_1.__importDefault(require("./PrivateMessage"));
const UserBlocked_1 = tslib_1.__importDefault(require("./UserBlocked"));
const Mention_1 = tslib_1.__importDefault(require("./Mention"));
const CollapsedFor_1 = tslib_1.__importDefault(require("./CollapsedFor"));
const KindlyNoticeFor_1 = tslib_1.__importDefault(require("./KindlyNoticeFor"));
const react_intl_1 = require("react-intl");
const KindlyNoticeFlag_1 = tslib_1.__importDefault(require("./KindlyNoticeFlag"));
const VoteUp_1 = tslib_1.__importDefault(require("./VoteUp"));
const Event_1 = tslib_1.__importDefault(require("./Event/Event"));
const LiveStream_1 = tslib_1.__importDefault(require("./LiveStream/LiveStream"));
const Icon_1 = tslib_1.__importDefault(require("@mui/material/Icon"));
const Errors_1 = require("../../constants/Errors");
const contribution_1 = require("../../utils/contribution");
const ContributionFollow_1 = tslib_1.__importDefault(require("./ContributionFollow"));
const material_1 = require("@mui/material");
const IncubatorApproved_1 = tslib_1.__importDefault(require("./IncubatorApproved"));
const api_services_1 = require("@selfcommunity/api-services");
const react_core_1 = require("@selfcommunity/react-core");
const Contribution_1 = tslib_1.__importDefault(require("./Contribution"));
const classnames_1 = tslib_1.__importDefault(require("classnames"));
const LoadingButton_1 = tslib_1.__importDefault(require("@mui/lab/LoadingButton"));
const Widget_1 = tslib_1.__importDefault(require("../Widget"));
const system_1 = require("@mui/system");
const utils_1 = require("@selfcommunity/utils");
const types_1 = require("@selfcommunity/types");
const UserDeletedSnackBar_1 = tslib_1.__importDefault(require("../../shared/UserDeletedSnackBar"));
const UserAvatar_1 = tslib_1.__importDefault(require("../../shared/UserAvatar"));
const constants_1 = require("./constants");
const Group_1 = tslib_1.__importDefault(require("./Group"));
const messages = (0, react_intl_1.defineMessages)({
receivePrivateMessage: {
id: 'ui.notification.receivePrivateMessage',
defaultMessage: 'ui.notification.receivePrivateMessage'
}
});
const classes = {
root: `${constants_1.PREFIX}-root`,
header: `${constants_1.PREFIX}-header`,
avatar: `${constants_1.PREFIX}-avatar`,
title: `${constants_1.PREFIX}-title`,
image: `${constants_1.PREFIX}-image`,
username: `${constants_1.PREFIX}-username`,
content: `${constants_1.PREFIX}-content`,
unCollapsed: `${constants_1.PREFIX}-uncollapsed`,
collapsed: `${constants_1.PREFIX}-collapsed`,
stopButton: `${constants_1.PREFIX}-stop-button`,
showOtherAggregated: `${constants_1.PREFIX}-show-other-aggregated`
};
const Root = (0, styles_1.styled)(Widget_1.default, {
name: constants_1.PREFIX,
slot: 'Root'
})(() => ({}));
/**
*
> API documentation for the Community-JS UserNotification component. Learn about the available props and the CSS API.
#### Import
```jsx
import {UserNotification} from '@selfcommunity/react-ui';
```
#### Component Name
The name `SCNotification` can be used when providing style overrides in the theme.
#### CSS
|Rule Name|Global class|Description|
|---|---|---|
|root|.SCNotification-root|Styles applied to the root element.|
|content|.SCNotification-notification-wrap|Styles applied to the element wrap.|
|header|.SCNotification-notification-wrap|Styles applied to the notification header.|
|title|.SCNotification-title|Styles applied to the title element in the notification header.|
|image|.SCNotification-image|Styles applied to the image element in the notification header.|
|username|.SCNotification-username|Styles applied to the user element in the notification header.|
|content|.SCNotification-notification-content|Styles applied to the notification content.|
|unCollapsed|.SCNotification-notification-wrap|Styles applied to the uncollapsed elements.|
|collapsed|.SCNotification-notification-wrap|Styles applied to the collapsed elements.|
|stopButton|.SCNotification-stop-notification-button|Styles applied to the stop notification button.|
|showOtherAggregated|.SCNotification-show-other-aggregated|Styles applied to the show other aggregated element.|
* @param inProps
*/
function UserNotification(inProps) {
// PROPS
const props = (0, system_1.useThemeProps)({
props: inProps,
name: constants_1.PREFIX
});
const { id = `notification_${props.notificationObject.sid}`, className, notificationObject, handleCustomNotification, showMaxAggregated = 2, collapsedOtherAggregated = true, onStateChange, onHeightChange } = props, rest = tslib_1.__rest(props, ["id", "className", "notificationObject", "handleCustomNotification", "showMaxAggregated", "collapsedOtherAggregated", "onStateChange", "onHeightChange"]);
// ROUTING
const scRoutingContext = (0, react_core_1.useSCRouting)();
// STATE
const [obj, setObj] = (0, react_1.useState)(notificationObject);
const [loadingSuspendNotification, setLoadingSuspendNotification] = (0, react_1.useState)(false);
const [openOtherAggregated, setOpenOtherAggregated] = (0, react_1.useState)(!collapsedOtherAggregated);
const [openAlert, setOpenAlert] = (0, react_1.useState)(false);
//INTL
const intl = (0, react_intl_1.useIntl)();
/**
* Notify changes to Feed if the FeedObject is contained in the feed
*/
const notifyFeedChanges = (0, react_1.useMemo)(() => (state) => {
if (onStateChange && state) {
onStateChange(state);
}
onHeightChange && onHeightChange();
}, [onStateChange, onHeightChange]);
/**
* Performs notification suspension
*/
const performSuspendNotification = (0, react_1.useMemo)(() => (obj) => {
return api_services_1.http
.request({
url: api_services_1.Endpoints.UserSuspendContributionNotification.url({ type: obj.type, id: obj.id }),
method: api_services_1.Endpoints.UserSuspendContributionNotification.method
})
.then((res) => {
if (res.status >= 300) {
return Promise.reject(res);
}
return Promise.resolve(res.data);
});
}, [obj]);
/**
* Handles stop notification for contribution
* @param contribution
*/
function handleStopContentNotification(contribution) {
setLoadingSuspendNotification(true);
performSuspendNotification(contribution)
.then((data) => {
const newObj = obj;
newObj[contribution.type].suspended = !newObj[contribution.type].suspended;
setObj(newObj);
setLoadingSuspendNotification(false);
})
.catch((error) => {
utils_1.Logger.error(Errors_1.SCOPE_SC_UI, error);
});
}
/**
* Handles vote
* @param index
*/
const handleVote = (index) => {
return (contribution) => {
const newObj = Object.assign({}, notificationObject);
const _notification = Object.assign({}, newObj.aggregated[index]);
_notification[contribution.type] = contribution;
newObj.aggregated[index] = _notification;
setObj(newObj);
};
};
/**
* Open/close other aggregated activities
* The layout change -> call onStateChange
*/
function setStateAggregated() {
const _openOtherAggregated = !openOtherAggregated;
notifyFeedChanges({ collapsedOtherAggregated: _openOtherAggregated });
setOpenOtherAggregated(_openOtherAggregated);
}
/**
* Render:
* - discussion/post/status summary if notification include contribute
* - user header for private message
*/
function renderNotificationHeader() {
/**
* Private messages header
*/
if (notificationObject.aggregated && notificationObject.aggregated[0].type === types_1.SCNotificationTypologyType.PRIVATE_MESSAGE) {
let messageNotification = notificationObject.aggregated[0];
return ((0, jsx_runtime_1.jsx)(material_1.CardHeader, { className: classes.header, avatar: (0, jsx_runtime_1.jsx)(react_core_1.Link, Object.assign({}, (!messageNotification.message.sender.deleted && {
to: scRoutingContext.url(react_core_1.SCRoutes.USER_PROFILE_ROUTE_NAME, messageNotification.message.sender)
}), { onClick: messageNotification.message.sender.deleted ? () => setOpenAlert(true) : null }, { children: (0, jsx_runtime_1.jsx)(UserAvatar_1.default, Object.assign({ hide: !messageNotification.message.sender.community_badge, smaller: true }, { children: (0, jsx_runtime_1.jsx)(material_1.Avatar, { className: classes.avatar, alt: messageNotification.message.sender.username, variant: "circular", src: messageNotification.message.sender.avatar }) })) })), titleTypographyProps: { className: classes.title, variant: 'subtitle1' }, title: (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(react_core_1.Link, Object.assign({}, (!messageNotification.message.sender.deleted && {
to: scRoutingContext.url(react_core_1.SCRoutes.USER_PROFILE_ROUTE_NAME, messageNotification.message.sender)
}), { onClick: messageNotification.message.sender.deleted ? () => setOpenAlert(true) : null, className: classes.username }, { children: messageNotification.message.sender.username })), ' ', intl.formatMessage(messages.receivePrivateMessage, {
total: notificationObject.aggregated.length,
b: (...chunks) => (0, jsx_runtime_1.jsx)("strong", { children: chunks })
})] }) }));
}
/**
* Group notifications header
*/
if (notificationObject.aggregated &&
(notificationObject.aggregated[0].type === types_1.SCNotificationTypologyType.USER_INVITED_TO_JOIN_GROUP ||
notificationObject.aggregated[0].type === types_1.SCNotificationTypologyType.USER_ACCEPTED_TO_JOIN_GROUP ||
notificationObject.aggregated[0].type === types_1.SCNotificationTypologyType.USER_ADDED_TO_GROUP ||
notificationObject.aggregated[0].type === types_1.SCNotificationTypologyType.USER_REQUESTED_TO_JOIN_GROUP)) {
let groupNotification = notificationObject.aggregated[0];
return ((0, jsx_runtime_1.jsx)(material_1.CardHeader, { className: classes.header, avatar: (0, jsx_runtime_1.jsx)(react_core_1.Link, Object.assign({}, (!groupNotification.user.deleted && {
to: scRoutingContext.url(react_core_1.SCRoutes.USER_PROFILE_ROUTE_NAME, groupNotification.user)
}), { onClick: groupNotification.user.deleted ? () => setOpenAlert(true) : null }, { children: (0, jsx_runtime_1.jsx)(UserAvatar_1.default, Object.assign({ hide: !groupNotification.user.community_badge, smaller: true }, { children: (0, jsx_runtime_1.jsx)(material_1.Avatar, { className: classes.avatar, alt: groupNotification.user.username, variant: "circular", src: groupNotification.user.avatar }) })) })), titleTypographyProps: { className: classes.title, variant: 'subtitle1' }, title: (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(react_core_1.Link, Object.assign({}, (!groupNotification.user.deleted && {
to: scRoutingContext.url(react_core_1.SCRoutes.USER_PROFILE_ROUTE_NAME, groupNotification.user)
}), { onClick: groupNotification.user.deleted ? () => setOpenAlert(true) : null, className: classes.username }, { children: groupNotification.user.username })), ' ', (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: `ui.notification.${notificationObject.aggregated[0].type}`, defaultMessage: `ui.notification.${notificationObject.aggregated[0].type}`, values: {
group: groupNotification.group.name,
link: (...chunks) => ((0, jsx_runtime_1.jsx)(react_core_1.Link, Object.assign({ to: notificationObject.aggregated[0].type === types_1.SCNotificationTypologyType.USER_REQUESTED_TO_JOIN_GROUP ||
notificationObject.aggregated[0].type === types_1.SCNotificationTypologyType.USER_ACCEPTED_TO_JOIN_GROUP
? scRoutingContext.url(react_core_1.SCRoutes.GROUP_MEMBERS_ROUTE_NAME, groupNotification.group)
: scRoutingContext.url(react_core_1.SCRoutes.GROUP_ROUTE_NAME, groupNotification.group) }, { children: chunks })))
} })] }) }));
}
/**
* Comment, NestedComment, Follow Contribution header
*/
if (notificationObject.aggregated &&
(notificationObject.aggregated[0].type === types_1.SCNotificationTypologyType.COMMENT ||
notificationObject.aggregated[0].type === types_1.SCNotificationTypologyType.NESTED_COMMENT ||
notificationObject.aggregated[0].type === types_1.SCNotificationTypologyType.FOLLOW ||
notificationObject.aggregated[0].type === types_1.SCNotificationTypologyType.MENTION ||
notificationObject.aggregated[0].type === types_1.SCNotificationTypologyType.VOTE_UP ||
notificationObject.aggregated[0].type === types_1.SCNotificationTypologyType.CONTRIBUTION)) {
const contribution = (0, contribution_1.getContribution)(notificationObject);
return ((0, jsx_runtime_1.jsx)(material_1.CardHeader, { className: classes.header, titleTypographyProps: { className: classes.title, variant: 'subtitle1' }, title: (0, jsx_runtime_1.jsx)(react_core_1.Link, Object.assign({ to: scRoutingContext.url((0, contribution_1.getContributionRouteName)(contribution), (0, contribution_1.getRouteData)(notificationObject[contribution.type])) }, { children: (0, contribution_1.getContributionSnippet)(contribution) })), action: contribution && ((0, jsx_runtime_1.jsx)(material_1.Tooltip, Object.assign({ title: contribution.suspended ? ((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: 'ui.notification.notificationSuspended', defaultMessage: 'ui.notification.notificationSuspended' })) : ((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: 'ui.notification.notificationSuspend', defaultMessage: 'ui.notification.notificationSuspend' })) }, { children: (0, jsx_runtime_1.jsx)(LoadingButton_1.default, Object.assign({ variant: "text", size: "small", loading: loadingSuspendNotification, color: 'inherit', classes: { root: classes.stopButton }, onClick: () => handleStopContentNotification(contribution) }, { children: contribution.suspended ? (0, jsx_runtime_1.jsx)(Icon_1.default, Object.assign({ color: 'primary' }, { children: "notifications_off" })) : (0, jsx_runtime_1.jsx)(Icon_1.default, Object.assign({ color: 'inherit' }, { children: "notifications_active" })) })) }))) }));
}
return null;
}
/**
* Render every single notification in aggregated group
* @param n
* @param i
*/
function renderAggregatedItem(n, i) {
if (n.type === types_1.SCNotificationTypologyType.COMMENT || n.type === types_1.SCNotificationTypologyType.NESTED_COMMENT) {
return (0, jsx_runtime_1.jsx)(Comment_1.default, { notificationObject: n, onVote: handleVote(i) }, i);
}
else if (n.type === types_1.SCNotificationTypologyType.FOLLOW) {
return (0, jsx_runtime_1.jsx)(ContributionFollow_1.default, { notificationObject: n }, i);
}
else if (n.type === types_1.SCNotificationTypologyType.USER_FOLLOW) {
return (0, jsx_runtime_1.jsx)(UserFollow_1.default, { notificationObject: n }, i);
}
else if (n.type === types_1.SCNotificationTypologyType.CONNECTION_REQUEST || n.type === types_1.SCNotificationTypologyType.CONNECTION_ACCEPT) {
return (0, jsx_runtime_1.jsx)(UserConnection_1.default, { notificationObject: n }, i);
}
else if (n.type === types_1.SCNotificationTypologyType.VOTE_UP) {
return (0, jsx_runtime_1.jsx)(VoteUp_1.default, { notificationObject: n }, i);
}
else if (n.type === types_1.SCNotificationTypologyType.KINDLY_NOTICE_ADVERTISING ||
n.type === types_1.SCNotificationTypologyType.KINDLY_NOTICE_AGGRESSIVE ||
n.type === types_1.SCNotificationTypologyType.KINDLY_NOTICE_POOR ||
n.type === types_1.SCNotificationTypologyType.KINDLY_NOTICE_VULGAR ||
n.type === types_1.SCNotificationTypologyType.KINDLY_NOTICE_OFFTOPIC) {
return (0, jsx_runtime_1.jsx)(KindlyNoticeFor_1.default, { notificationObject: n }, i);
}
else if (n.type === types_1.SCNotificationTypologyType.KINDLY_NOTICE_FLAG) {
return (0, jsx_runtime_1.jsx)(KindlyNoticeFlag_1.default, { notificationObject: n }, i);
}
else if (n.type === types_1.SCNotificationTypologyType.DELETED_FOR_ADVERTISING ||
n.type === types_1.SCNotificationTypologyType.DELETED_FOR_AGGRESSIVE ||
n.type === types_1.SCNotificationTypologyType.DELETED_FOR_POOR ||
n.type === types_1.SCNotificationTypologyType.DELETED_FOR_VULGAR ||
n.type === types_1.SCNotificationTypologyType.DELETED_FOR_OFFTOPIC) {
return (0, jsx_runtime_1.jsx)(DeletedFor_1.default, { notificationObject: n }, i);
}
else if (n.type === types_1.SCNotificationTypologyType.UNDELETED_FOR) {
return (0, jsx_runtime_1.jsx)(UndeletedFor_1.default, { notificationObject: n }, i);
}
else if (n.type === types_1.SCNotificationTypologyType.COLLAPSED_FOR_ADVERTISING ||
n.type === types_1.SCNotificationTypologyType.COLLAPSED_FOR_AGGRESSIVE ||
n.type === types_1.SCNotificationTypologyType.COLLAPSED_FOR_POOR ||
n.type === types_1.SCNotificationTypologyType.COLLAPSED_FOR_VULGAR ||
n.type === types_1.SCNotificationTypologyType.COLLAPSED_FOR_OFFTOPIC) {
return (0, jsx_runtime_1.jsx)(CollapsedFor_1.default, { notificationObject: n }, i);
}
else if (n.type === types_1.SCNotificationTypologyType.PRIVATE_MESSAGE) {
return (0, jsx_runtime_1.jsx)(PrivateMessage_1.default, { notificationObject: n }, i);
}
else if (n.type === types_1.SCNotificationTypologyType.BLOCKED_USER || n.type === types_1.SCNotificationTypologyType.UNBLOCKED_USER) {
return (0, jsx_runtime_1.jsx)(UserBlocked_1.default, { notificationObject: n }, i);
}
else if (n.type === types_1.SCNotificationTypologyType.MENTION) {
return (0, jsx_runtime_1.jsx)(Mention_1.default, { notificationObject: n }, i);
}
else if (n.type === types_1.SCNotificationTypologyType.INCUBATOR_APPROVED) {
return (0, jsx_runtime_1.jsx)(IncubatorApproved_1.default, { notificationObject: n }, i);
}
else if (n.type === types_1.SCNotificationTypologyType.CUSTOM_NOTIFICATION) {
handleCustomNotification && handleCustomNotification(n);
}
else if (n.type === types_1.SCNotificationTypologyType.CONTRIBUTION) {
return (0, jsx_runtime_1.jsx)(Contribution_1.default, { notificationObject: n, onVote: handleVote(i) }, i);
}
else if (n.type === types_1.SCNotificationTypologyType.USER_ADDED_TO_GROUP ||
n.type === types_1.SCNotificationTypologyType.USER_INVITED_TO_JOIN_GROUP ||
n.type === types_1.SCNotificationTypologyType.USER_ACCEPTED_TO_JOIN_GROUP ||
n.type === types_1.SCNotificationTypologyType.USER_REQUESTED_TO_JOIN_GROUP) {
return (0, jsx_runtime_1.jsx)(Group_1.default, { notificationObject: n }, i);
}
else if (n.type === types_1.SCNotificationTypologyType.USER_ADDED_TO_EVENT ||
n.type === types_1.SCNotificationTypologyType.USER_INVITED_TO_JOIN_EVENT ||
n.type === types_1.SCNotificationTypologyType.USER_ACCEPTED_TO_JOIN_EVENT ||
n.type === types_1.SCNotificationTypologyType.USER_REQUESTED_TO_JOIN_EVENT) {
return (0, jsx_runtime_1.jsx)(Event_1.default, { notificationObject: n }, i);
}
else if (n.type === types_1.SCNotificationTypologyType.LIVE_STREAM_STARTED) {
return (0, jsx_runtime_1.jsx)(LiveStream_1.default, { notificationObject: n }, i);
}
return null;
}
/**
* Renders root object
*/
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)(Root, Object.assign({ id: id, className: (0, classnames_1.default)(classes.root, className) }, rest, { children: [renderNotificationHeader(), (0, jsx_runtime_1.jsxs)(CardContent_1.default, Object.assign({ className: classes.content }, { children: [(0, jsx_runtime_1.jsx)("div", Object.assign({ className: classes.unCollapsed }, { children: notificationObject.aggregated.slice(0, showMaxAggregated).map((n, i) => renderAggregatedItem(n, i)) })), notificationObject.aggregated.length > showMaxAggregated && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)(material_1.ListItemButton, Object.assign({ onClick: setStateAggregated, classes: { root: classes.showOtherAggregated } }, { children: [(0, jsx_runtime_1.jsx)(material_1.ListItemText, { primary: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: 'ui.notification.showOthers', defaultMessage: 'ui.notification.showOthers' }) }), openOtherAggregated ? (0, jsx_runtime_1.jsx)(Icon_1.default, { children: "expand_less" }) : (0, jsx_runtime_1.jsx)(Icon_1.default, { children: "expand_more" })] })), (0, jsx_runtime_1.jsx)(material_1.Collapse, Object.assign({ in: openOtherAggregated, timeout: "auto", unmountOnExit: true, classes: { root: classes.collapsed } }, { children: notificationObject.aggregated.slice(showMaxAggregated).map((n, i) => renderAggregatedItem(n, i)) }))] }))] }))] })), openAlert && (0, jsx_runtime_1.jsx)(UserDeletedSnackBar_1.default, { open: openAlert, handleClose: () => setOpenAlert(false) })] }));
}
exports.default = UserNotification;