UNPKG

@selfcommunity/react-ui

Version:

React UI Components to integrate a Community created with SelfCommunity Platform.

292 lines (283 loc) • 18.5 kB
"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 Comment_1 = tslib_1.__importDefault(require("../Notification/Comment")); const UserFollow_1 = tslib_1.__importDefault(require("../Notification/UserFollow")); const UndeletedFor_1 = tslib_1.__importDefault(require("../Notification/UndeletedFor")); const DeletedFor_1 = tslib_1.__importDefault(require("../Notification/DeletedFor")); const UserConnection_1 = tslib_1.__importDefault(require("../Notification/UserConnection")); const PrivateMessage_1 = tslib_1.__importDefault(require("../Notification/PrivateMessage")); const UserBlocked_1 = tslib_1.__importDefault(require("../Notification/UserBlocked")); const Mention_1 = tslib_1.__importDefault(require("../Notification/Mention")); const CollapsedFor_1 = tslib_1.__importDefault(require("../Notification/CollapsedFor")); const KindlyNoticeFor_1 = tslib_1.__importDefault(require("../Notification/KindlyNoticeFor")); const KindlyNoticeFlag_1 = tslib_1.__importDefault(require("../Notification/KindlyNoticeFlag")); const VoteUp_1 = tslib_1.__importDefault(require("../Notification/VoteUp")); const Errors_1 = require("../../constants/Errors"); const pubsub_js_1 = tslib_1.__importDefault(require("pubsub-js")); const ContributionFollow_1 = tslib_1.__importDefault(require("../Notification/ContributionFollow")); const material_1 = require("@mui/material"); const IncubatorApproved_1 = tslib_1.__importDefault(require("../Notification/IncubatorApproved")); const classnames_1 = tslib_1.__importDefault(require("classnames")); const Skeleton_1 = tslib_1.__importDefault(require("./Skeleton")); const types_1 = require("../../types"); const ScrollContainer_1 = tslib_1.__importDefault(require("../../shared/ScrollContainer")); const react_intl_1 = require("react-intl"); const types_2 = require("@selfcommunity/types"); const api_services_1 = require("@selfcommunity/api-services"); const utils_1 = require("@selfcommunity/utils"); const react_core_1 = require("@selfcommunity/react-core"); const system_1 = require("@mui/system"); const Contribution_1 = tslib_1.__importDefault(require("../Notification/Contribution")); const NotificationItem_1 = tslib_1.__importDefault(require("../../shared/NotificationItem")); const constants_1 = require("./constants"); const Group_1 = tslib_1.__importDefault(require("../Notification/Group")); const Event_1 = tslib_1.__importDefault(require("../Notification/Event/Event")); const LiveStream_1 = tslib_1.__importDefault(require("../Notification/LiveStream")); const classes = { root: `${constants_1.PREFIX}-root`, notificationsWrap: `${constants_1.PREFIX}-notifications-wrap`, emptyBoxNotifications: `${constants_1.PREFIX}-empty-box-notifications`, list: `${constants_1.PREFIX}-list`, broadcastMessagesBanner: `${constants_1.PREFIX}-broadcast-messages-banner`, item: `${constants_1.PREFIX}-item` }; const Root = (0, styles_1.styled)(material_1.Box, { name: constants_1.PREFIX, slot: 'Root' })(() => ({})); const PREFERENCES = [react_core_1.SCPreferences.LOGO_NAVBAR_LOGO_MOBILE, react_core_1.SCPreferences.TEXT_APPLICATION_NAME]; /** * > API documentation for the Community-JS SnippetNotifications component. Learn about the available props and the CSS API. * * * This component renders the notification list. * Take a look at our <strong>demo</strong> component [here](/docs/sdk/community-js/react-ui/Components/SnippetNotifications) #### Import ```jsx import {SnippetNotifications} from '@selfcommunity/react-ui'; ``` #### Component Name The name `SCSnippetNotifications` can be used when providing style overrides in the theme. #### CSS |Rule Name|Global class|Description| |---|---|---| |root|.SCSnippetNotification-root|Styles applied to the root element.| |notificationsWrap|.SCSnippetNotification-notification-wrap|Styles applied to the notifications wrap.| |emptyBoxNotifications|.SCSnippetNotification-empty-box-notifications|Styles applied to the box indicating that there are no notifications.| |list|.SCSnippetNotification-list|Styles applied to the list of notifications.| |item|.SCSnippetNotification-item|Styles applied to the single notification.| |broadcastMessagesBanner|.SCSnippetNotification-broadcast-messages-banner|Styles applied to the broadcast message banner.| * @param inProps */ function SnippetNotifications(inProps) { // PROPS const props = (0, system_1.useThemeProps)({ props: inProps, name: constants_1.PREFIX }); const { id = `snippetNotifications`, className, showMax = 20, handleCustomNotification, handleNotification, ScrollContainerProps = {}, onNotificationClick, onFetchNotifications } = props, rest = tslib_1.__rest(props, ["id", "className", "showMax", "handleCustomNotification", "handleNotification", "ScrollContainerProps", "onNotificationClick", "onFetchNotifications"]); // CONTEXT const scUserContext = (0, react_core_1.useSCUser)(); const scRoutingContext = (0, react_core_1.useSCRouting)(); // STATE const [notifications, setNotifications] = (0, react_1.useState)([]); const [initialized, setInitialized] = (0, react_1.useState)(false); const [loading, setLoading] = (0, react_1.useState)(false); // REFS const notificationSubscription = (0, react_1.useRef)(null); // Compute preferences const scPreferences = (0, react_core_1.useSCPreferences)(); const preferences = (0, react_1.useMemo)(() => { const _preferences = {}; PREFERENCES.map((p) => (_preferences[p] = p in scPreferences.preferences ? scPreferences.preferences[p].value : null)); return _preferences; }, [scPreferences.preferences]); // HOOKS const intl = (0, react_intl_1.useIntl)(); /** * Perform vote */ const performFetchNotifications = (0, react_1.useMemo)(() => () => { return api_services_1.http .request({ url: api_services_1.Endpoints.UserNotificationList.url(), method: api_services_1.Endpoints.UserNotificationList.method }) .then((res) => { if (res.status >= 300) { return Promise.reject(res); } return Promise.resolve(res.data); }); }, []); /** * Handles vote * @param comment */ const fetchNotifications = (0, react_1.useMemo)(() => () => { setInitialized(true); if (!loading) { setLoading(true); performFetchNotifications() .then((data) => { setNotifications(data.results); setLoading(false); scUserContext.refreshCounters(); onFetchNotifications && onFetchNotifications(data.results); }) .catch((error) => { utils_1.Logger.error(Errors_1.SCOPE_SC_UI, error); }); } }, [loading, notifications.length, onFetchNotifications, setInitialized]); /** * Fetch notifications */ (0, react_1.useEffect)(() => { let _t; if (scUserContext.user && !initialized) { _t = setTimeout(fetchNotifications); return () => { _t && clearTimeout(_t); }; } }, [scUserContext.user, initialized]); /** * Notification subscriber * @param msg * @param data */ const notificationSubscriber = (msg, data) => { /** * Ignore notifications of type: notification_banner * (data.data.activity_type === SCNotificationTypologyType.NOTIFICATION_BANNER) */ if (data && data.type === types_2.SCNotificationTopicType.INTERACTION && react_core_1.SCNotification.SCNotificationMapping[data.data.activity_type] && !react_core_1.SCNotification.SCSilentSnippetNotifications.includes(data.data.activity_type)) { if (data.data.notification_obj) { setNotifications([...[{ is_new: true, sid: '', aggregated: [data.data.notification_obj] }], ...notifications]); } } }; const handleSingleNotificationClick = (e, n) => { if (onNotificationClick) { onNotificationClick(e, n); } }; /** * On mount, fetches first page of notifications * On mount, subscribe to receive notification updates */ (0, react_1.useEffect)(() => { if (!loading) { notificationSubscription.current = pubsub_js_1.default.subscribe(types_2.SCNotificationTopicType.INTERACTION, notificationSubscriber); } return () => { notificationSubscription.current && pubsub_js_1.default.unsubscribe(notificationSubscription.current); }; }, [loading]); /** * Render every single notification in aggregated group * @param n * @param i */ const renderAggregatedItem = (n, i) => { const type = n.type; let content; if (type === types_2.SCNotificationTypologyType.COMMENT || type === types_2.SCNotificationTypologyType.NESTED_COMMENT) { content = (0, jsx_runtime_1.jsx)(Comment_1.default, { notificationObject: n, index: i, template: types_1.SCNotificationObjectTemplateType.SNIPPET }, i); } else if (type === types_2.SCNotificationTypologyType.FOLLOW) { content = (0, jsx_runtime_1.jsx)(ContributionFollow_1.default, { notificationObject: n, template: types_1.SCNotificationObjectTemplateType.SNIPPET }, i); } else if (type === types_2.SCNotificationTypologyType.USER_FOLLOW) { content = (0, jsx_runtime_1.jsx)(UserFollow_1.default, { notificationObject: n, template: types_1.SCNotificationObjectTemplateType.SNIPPET }, i); } else if (type === types_2.SCNotificationTypologyType.CONNECTION_REQUEST || type === types_2.SCNotificationTypologyType.CONNECTION_ACCEPT) { content = (0, jsx_runtime_1.jsx)(UserConnection_1.default, { notificationObject: n, template: types_1.SCNotificationObjectTemplateType.SNIPPET }, i); } else if (type === types_2.SCNotificationTypologyType.VOTE_UP) { content = (0, jsx_runtime_1.jsx)(VoteUp_1.default, { notificationObject: n, template: types_1.SCNotificationObjectTemplateType.SNIPPET }, i); } else if (type === types_2.SCNotificationTypologyType.KINDLY_NOTICE_ADVERTISING || type === types_2.SCNotificationTypologyType.KINDLY_NOTICE_AGGRESSIVE || type === types_2.SCNotificationTypologyType.KINDLY_NOTICE_POOR || type === types_2.SCNotificationTypologyType.KINDLY_NOTICE_VULGAR || type === types_2.SCNotificationTypologyType.KINDLY_NOTICE_OFFTOPIC) { content = (0, jsx_runtime_1.jsx)(KindlyNoticeFor_1.default, { notificationObject: n, template: types_1.SCNotificationObjectTemplateType.SNIPPET }, i); } else if (type === types_2.SCNotificationTypologyType.KINDLY_NOTICE_FLAG) { content = (0, jsx_runtime_1.jsx)(KindlyNoticeFlag_1.default, { notificationObject: n, template: types_1.SCNotificationObjectTemplateType.SNIPPET }, i); } else if (type === types_2.SCNotificationTypologyType.DELETED_FOR_ADVERTISING || type === types_2.SCNotificationTypologyType.DELETED_FOR_AGGRESSIVE || type === types_2.SCNotificationTypologyType.DELETED_FOR_POOR || type === types_2.SCNotificationTypologyType.DELETED_FOR_VULGAR || type === types_2.SCNotificationTypologyType.DELETED_FOR_OFFTOPIC) { content = (0, jsx_runtime_1.jsx)(DeletedFor_1.default, { notificationObject: n, template: types_1.SCNotificationObjectTemplateType.SNIPPET }, i); } else if (type === types_2.SCNotificationTypologyType.UNDELETED_FOR) { content = (0, jsx_runtime_1.jsx)(UndeletedFor_1.default, { notificationObject: n, template: types_1.SCNotificationObjectTemplateType.SNIPPET }, i); } else if (type === types_2.SCNotificationTypologyType.COLLAPSED_FOR_ADVERTISING || type === types_2.SCNotificationTypologyType.COLLAPSED_FOR_AGGRESSIVE || type === types_2.SCNotificationTypologyType.COLLAPSED_FOR_POOR || type === types_2.SCNotificationTypologyType.COLLAPSED_FOR_VULGAR || type === types_2.SCNotificationTypologyType.COLLAPSED_FOR_OFFTOPIC) { content = (0, jsx_runtime_1.jsx)(CollapsedFor_1.default, { notificationObject: n, template: types_1.SCNotificationObjectTemplateType.SNIPPET }, i); } else if (type === types_2.SCNotificationTypologyType.PRIVATE_MESSAGE) { content = (0, jsx_runtime_1.jsx)(PrivateMessage_1.default, { notificationObject: n, template: types_1.SCNotificationObjectTemplateType.SNIPPET }, i); } else if (type === types_2.SCNotificationTypologyType.BLOCKED_USER || type === types_2.SCNotificationTypologyType.UNBLOCKED_USER) { content = (0, jsx_runtime_1.jsx)(UserBlocked_1.default, { notificationObject: n, template: types_1.SCNotificationObjectTemplateType.SNIPPET }, i); } else if (type === types_2.SCNotificationTypologyType.MENTION) { content = (0, jsx_runtime_1.jsx)(Mention_1.default, { notificationObject: n, template: types_1.SCNotificationObjectTemplateType.SNIPPET }, i); } else if (type === types_2.SCNotificationTypologyType.INCUBATOR_APPROVED) { content = (0, jsx_runtime_1.jsx)(IncubatorApproved_1.default, { notificationObject: n, template: types_1.SCNotificationObjectTemplateType.SNIPPET }, i); } else if (type === types_2.SCNotificationTypologyType.CUSTOM_NOTIFICATION && handleCustomNotification) { content = handleCustomNotification(n); } else if (type === types_2.SCNotificationTypologyType.CONTRIBUTION) { content = (0, jsx_runtime_1.jsx)(Contribution_1.default, { notificationObject: n, template: types_1.SCNotificationObjectTemplateType.SNIPPET }, i); } else if (n.type === types_2.SCNotificationTypologyType.USER_ADDED_TO_GROUP || n.type === types_2.SCNotificationTypologyType.USER_INVITED_TO_JOIN_GROUP || n.type === types_2.SCNotificationTypologyType.USER_ACCEPTED_TO_JOIN_GROUP || n.type === types_2.SCNotificationTypologyType.USER_REQUESTED_TO_JOIN_GROUP) { return (0, jsx_runtime_1.jsx)(Group_1.default, { notificationObject: n, template: types_1.SCNotificationObjectTemplateType.SNIPPET }, i); } else if (n.type === types_2.SCNotificationTypologyType.USER_ADDED_TO_EVENT || n.type === types_2.SCNotificationTypologyType.USER_INVITED_TO_JOIN_EVENT || n.type === types_2.SCNotificationTypologyType.USER_ACCEPTED_TO_JOIN_EVENT || n.type === types_2.SCNotificationTypologyType.USER_REQUESTED_TO_JOIN_EVENT) { return (0, jsx_runtime_1.jsx)(Event_1.default, { notificationObject: n, template: types_1.SCNotificationObjectTemplateType.SNIPPET }, i); } else if (type === types_2.SCNotificationTypologyType.LIVE_STREAM_STARTED) { content = (0, jsx_runtime_1.jsx)(LiveStream_1.default, { notificationObject: n, template: types_1.SCNotificationObjectTemplateType.SNIPPET }, i); } if (type && handleNotification) { /** Override content */ content = handleNotification(type, n, content); } return content; }; /** * Renders root object */ 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.jsx)(material_1.Box, Object.assign({ className: classes.notificationsWrap }, { children: !initialized || loading ? ((0, jsx_runtime_1.jsx)(Skeleton_1.default, { elevation: 0 })) : ((0, jsx_runtime_1.jsx)(ScrollContainer_1.default, Object.assign({}, ScrollContainerProps, { children: (0, jsx_runtime_1.jsxs)(material_1.MenuList, Object.assign({ className: classes.list, disabledItemsFocusable: true, disableListWrap: true }, { children: [scUserContext.user.unseen_notification_banners_counter ? ((0, jsx_runtime_1.jsx)(material_1.MenuItem, Object.assign({ className: (0, classnames_1.default)(classes.item, classes.broadcastMessagesBanner), component: react_core_1.Link, to: scRoutingContext.url(react_core_1.SCRoutes.USER_NOTIFICATIONS_ROUTE_NAME, {}) }, { children: (0, jsx_runtime_1.jsx)(NotificationItem_1.default, { template: types_1.SCNotificationObjectTemplateType.SNIPPET, isNew: true, disableTypography: true, image: (0, jsx_runtime_1.jsx)(material_1.Avatar, { alt: preferences[react_core_1.SCPreferences.TEXT_APPLICATION_NAME], src: preferences[react_core_1.SCPreferences.LOGO_NAVBAR_LOGO_MOBILE] }), primary: (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ component: 'div' }, { children: intl.formatMessage({ id: 'ui.snippetNotifications.broadcastMessages', defaultMessage: 'ui.snippetNotifications.broadcastMessages' }, { count: scUserContext.user.unseen_notification_banners_counter, b: (...chunks) => (0, jsx_runtime_1.jsx)("strong", { children: chunks }), link: (...chunks) => (0, jsx_runtime_1.jsx)(react_core_1.Link, Object.assign({ to: scRoutingContext.url(react_core_1.SCRoutes.USER_NOTIFICATIONS_ROUTE_NAME, {}) }, { children: chunks })) }) })) }) }), "banner")) : null, notifications.length === 0 ? ((0, jsx_runtime_1.jsx)(material_1.MenuItem, Object.assign({ className: classes.emptyBoxNotifications }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.snippetNotifications.noNotifications", defaultMessage: "ui.snippetNotifications.noNotifications" }) }))) : (notifications.slice(0, showMax).map((notificationObject, i) => notificationObject.aggregated.map((n, k) => ((0, jsx_runtime_1.jsx)(material_1.MenuItem, Object.assign({ className: classes.item, onClick: (e) => handleSingleNotificationClick(e, n), disableRipple: true, disableTouchRipple: true }, { children: renderAggregatedItem(n, i) }), k)))))] })) }))) })) }))); } exports.default = SnippetNotifications;