@selfcommunity/react-ui 0.7.9-alpha.29 → 0.7.9-alpha.30

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -27,15 +27,27 @@ const Root = (0, styles_1.styled)(material_1.Box, {
27
27
  slot: 'ActionFollowRoot'
28
28
  })(() => ({}));
29
29
  function Follow(props) {
30
+ var _a;
30
31
  // PROPS
31
32
  const { className = null, feedObjectId = null, feedObject = null, feedObjectType = types_1.SCContributionType.POST, handleFollow, iconized = true } = props, rest = tslib_1.__rest(props, ["className", "feedObjectId", "feedObject", "feedObjectType", "handleFollow", "iconized"]);
32
33
  // STATE
33
34
  const { obj, setObj } = (0, react_core_1.useSCFetchFeedObject)({ id: feedObjectId, feedObject, feedObjectType });
34
35
  const [isFollowing, setIsFollowing] = (0, react_1.useState)(false);
36
+ const [status, setStatus] = (0, react_1.useState)(null);
35
37
  // CONTEXT
36
38
  const scContext = (0, react_core_1.useSCContext)();
37
39
  const scUserContext = (0, react_core_1.useSCUser)();
40
+ const scGroupsManager = scUserContext.managers.groups;
38
41
  const { enqueueSnackbar } = (0, notistack_1.useSnackbar)();
42
+ /**
43
+ * If the obj has a group, checks the subscription status for the authenticated user
44
+ */
45
+ (0, react_1.useEffect)(() => {
46
+ var _a;
47
+ if (((_a = scUserContext === null || scUserContext === void 0 ? void 0 : scUserContext.user) === null || _a === void 0 ? void 0 : _a.id) && (obj === null || obj === void 0 ? void 0 : obj.group)) {
48
+ setStatus(scGroupsManager.subscriptionStatus(obj === null || obj === void 0 ? void 0 : obj.group));
49
+ }
50
+ }, [(_a = scUserContext === null || scUserContext === void 0 ? void 0 : scUserContext.user) === null || _a === void 0 ? void 0 : _a.id, scGroupsManager.subscriptionStatus, obj === null || obj === void 0 ? void 0 : obj.group]);
39
51
  /**
40
52
  * Perform follow/unfollow
41
53
  * Post, Discussion, Status
@@ -61,6 +73,12 @@ function Follow(props) {
61
73
  if (!scUserContext.user) {
62
74
  scContext.settings.handleAnonymousAction();
63
75
  }
76
+ else if ((obj === null || obj === void 0 ? void 0 : obj.group) && status !== types_1.SCGroupSubscriptionStatusType.SUBSCRIBED) {
77
+ enqueueSnackbar(react_1.default.createElement(react_intl_1.FormattedMessage, { id: "ui.common.group.actions.unsubscribed", defaultMessage: "ui.common.group.actions.unsubscribed" }), {
78
+ variant: 'warning',
79
+ autoHideDuration: 3000
80
+ });
81
+ }
64
82
  else {
65
83
  setIsFollowing(true);
66
84
  performFollow()
@@ -45,6 +45,7 @@ const Root = (0, styles_1.styled)(material_1.Box, {
45
45
  slot: 'ActionShareRoot'
46
46
  })(() => ({}));
47
47
  function Share(props) {
48
+ var _a;
48
49
  // PROPS
49
50
  const { className = null, feedObjectId = null, feedObject = null, feedObjectType = types_1.SCContributionType.POST, withAction = true, withAudience = true, inlineAction = false } = props, rest = tslib_1.__rest(props, ["className", "feedObjectId", "feedObject", "feedObjectType", "withAction", "withAudience", "inlineAction"]);
50
51
  // STATE
@@ -56,6 +57,7 @@ function Share(props) {
56
57
  const [composerShareProps, setComposerShareProps] = (0, react_1.useState)(null);
57
58
  const [openSharesDialog, setOpenSharesDialog] = (0, react_1.useState)(false);
58
59
  const [anchorEl, setAnchorEl] = react_1.default.useState(null);
60
+ const [status, setStatus] = (0, react_1.useState)(null);
59
61
  // CONTEXT
60
62
  const scContext = (0, react_core_1.useSCContext)();
61
63
  const scRoutingContext = (0, react_core_1.useSCRouting)();
@@ -67,6 +69,7 @@ function Share(props) {
67
69
  const linkedinShareEnabled = react_core_1.SCPreferences.ADDONS_SHARE_POST_ON_LINKEDIN_ENABLED in scPreferencesContext.preferences &&
68
70
  scPreferencesContext.preferences[react_core_1.SCPreferences.ADDONS_SHARE_POST_ON_LINKEDIN_ENABLED].value;
69
71
  const scUserContext = (0, react_core_1.useSCUser)();
72
+ const scGroupsManager = scUserContext.managers.groups;
70
73
  const { enqueueSnackbar } = (0, notistack_1.useSnackbar)();
71
74
  const domain = typeof location !== 'undefined' && location.origin ? location.origin : '';
72
75
  const url = domain + scRoutingContext.url((0, contribution_1.getContributionRouteName)(obj), (0, contribution_1.getRouteData)(obj));
@@ -99,6 +102,15 @@ function Share(props) {
99
102
  setObj(Object.assign({}, obj, { share_count: obj.share_count + 1 }));
100
103
  handleComposerOnClose();
101
104
  }
105
+ /**
106
+ * If the obj has a group, checks the subscription status for the authenticated user
107
+ */
108
+ (0, react_1.useEffect)(() => {
109
+ var _a;
110
+ if (((_a = scUserContext === null || scUserContext === void 0 ? void 0 : scUserContext.user) === null || _a === void 0 ? void 0 : _a.id) && (obj === null || obj === void 0 ? void 0 : obj.group)) {
111
+ setStatus(scGroupsManager.subscriptionStatus(obj === null || obj === void 0 ? void 0 : obj.group));
112
+ }
113
+ }, [(_a = scUserContext === null || scUserContext === void 0 ? void 0 : scUserContext.user) === null || _a === void 0 ? void 0 : _a.id, scGroupsManager.subscriptionStatus, obj === null || obj === void 0 ? void 0 : obj.group]);
102
114
  /**
103
115
  * Performs follow/unfollow
104
116
  * Post, Discussion, Status
@@ -141,6 +153,12 @@ function Share(props) {
141
153
  autoHideDuration: 3000
142
154
  });
143
155
  }
156
+ else if ((obj === null || obj === void 0 ? void 0 : obj.group) && status !== types_1.SCGroupSubscriptionStatusType.SUBSCRIBED) {
157
+ enqueueSnackbar(react_1.default.createElement(react_intl_1.FormattedMessage, { id: "ui.common.group.actions.unsubscribed", defaultMessage: "ui.common.group.actions.unsubscribed" }), {
158
+ variant: 'warning',
159
+ autoHideDuration: 3000
160
+ });
161
+ }
144
162
  else {
145
163
  setIsSharing(true);
146
164
  performCreateMediaShare()
@@ -133,7 +133,7 @@ const Root = (0, styles_1.styled)(Widget_1.default, {
133
133
  * @param inProps
134
134
  */
135
135
  function FeedObject(inProps) {
136
- var _a;
136
+ var _a, _b;
137
137
  // PROPS
138
138
  const props = (0, system_1.useThemeProps)({
139
139
  props: inProps,
@@ -144,6 +144,7 @@ function FeedObject(inProps) {
144
144
  const scContext = (0, react_core_1.useSCContext)();
145
145
  const scRoutingContext = (0, react_core_1.useSCRouting)();
146
146
  const scUserContext = (0, react_core_1.useSCUser)();
147
+ const scGroupsManager = scUserContext.managers.groups;
147
148
  const { enqueueSnackbar } = (0, notistack_1.useSnackbar)();
148
149
  // OBJECTS
149
150
  const { obj, setObj, error } = (0, react_core_1.useSCFetchFeedObject)({ id: feedObjectId, feedObject, feedObjectType, cacheStrategy });
@@ -162,6 +163,7 @@ function FeedObject(inProps) {
162
163
  const [isReplying, setIsReplying] = (0, react_1.useState)(false);
163
164
  const [selectedActivities, setSelectedActivities] = (0, react_1.useState)(getInitialSelectedActivitiesType());
164
165
  const [expanded, setExpanded] = (0, react_1.useState)(summaryExpanded);
166
+ const [status, setStatus] = (0, react_1.useState)(null);
165
167
  // INTL
166
168
  const intl = (0, react_intl_1.useIntl)();
167
169
  /**
@@ -193,6 +195,15 @@ function FeedObject(inProps) {
193
195
  }
194
196
  return feedObject_1.SCFeedObjectActivitiesType.RECENT_COMMENTS;
195
197
  }
198
+ /**
199
+ * If the obj has a group, checks the subscription status for the authenticated user
200
+ */
201
+ (0, react_1.useEffect)(() => {
202
+ var _a;
203
+ if (((_a = scUserContext === null || scUserContext === void 0 ? void 0 : scUserContext.user) === null || _a === void 0 ? void 0 : _a.id) && (feedObject === null || feedObject === void 0 ? void 0 : feedObject.group)) {
204
+ setStatus(scGroupsManager.subscriptionStatus(feedObject === null || feedObject === void 0 ? void 0 : feedObject.group));
205
+ }
206
+ }, [(_a = scUserContext === null || scUserContext === void 0 ? void 0 : scUserContext.user) === null || _a === void 0 ? void 0 : _a.id, scGroupsManager.subscriptionStatus, feedObject === null || feedObject === void 0 ? void 0 : feedObject.group]);
196
207
  /**
197
208
  * Open expanded activities
198
209
  */
@@ -350,6 +361,12 @@ function FeedObject(inProps) {
350
361
  autoHideDuration: 3000
351
362
  });
352
363
  }
364
+ else if ((feedObject === null || feedObject === void 0 ? void 0 : feedObject.group) && status !== types_1.SCGroupSubscriptionStatusType.SUBSCRIBED) {
365
+ enqueueSnackbar(react_1.default.createElement(react_intl_1.FormattedMessage, { id: "ui.common.group.actions.unsubscribed", defaultMessage: "ui.common.group.actions.unsubscribed" }), {
366
+ variant: 'warning',
367
+ autoHideDuration: 3000
368
+ });
369
+ }
353
370
  else {
354
371
  setIsReplying(true);
355
372
  performReply(comment)
@@ -447,8 +464,8 @@ function FeedObject(inProps) {
447
464
  obj.location && (react_1.default.createElement(react_1.default.Fragment, null,
448
465
  react_1.default.createElement(Bullet_1.default, null),
449
466
  react_1.default.createElement(material_1.Box, { className: classes.location },
450
- react_1.default.createElement(Icon_1.default, null, "add_location_alt"), (_a = obj.location) === null || _a === void 0 ? void 0 :
451
- _a.location))),
467
+ react_1.default.createElement(Icon_1.default, null, "add_location_alt"), (_b = obj.location) === null || _b === void 0 ? void 0 :
468
+ _b.location))),
452
469
  react_1.default.createElement(Bullet_1.default, null),
453
470
  react_1.default.createElement(material_1.Box, { className: classes.tag }, obj.addressing.length > 0 ? (react_1.default.createElement(Tags_1.default, { tags: obj.addressing, TagChipProps: { disposable: false, clickable: false } })) : obj.group ? (react_1.default.createElement(material_1.Tooltip, { title: `${intl.formatMessage(messages.visibleToGroup, { group: obj.group.name })}` },
454
471
  react_1.default.createElement(Icon_1.default, { color: "disabled", fontSize: "small" }, "groups"))) : (react_1.default.createElement(material_1.Tooltip, { title: `${intl.formatMessage(messages.visibleToAll)}` },
@@ -41,6 +41,7 @@ const Root = (0, styles_1.styled)(NotificationItem_1.default, {
41
41
  * @param props
42
42
  */
43
43
  function PrivateMessageNotification(props) {
44
+ var _a, _b, _c, _d, _e;
44
45
  // PROPS
45
46
  const { notificationObject, id = `n_${props.notificationObject['sid']}`, className, template = types_1.SCNotificationObjectTemplateType.DETAIL } = props, rest = tslib_1.__rest(props, ["notificationObject", "id", "className", "template"]);
46
47
  // CONTEXT
@@ -91,7 +92,9 @@ function PrivateMessageNotification(props) {
91
92
  react_1.default.createElement(react_intl_1.FormattedMessage, { id: 'ui.userToastNotifications.privateMessage.sentMessage', defaultMessage: 'ui.userToastNotifications.privateMessage.sentMessage' }),
92
93
  ":",
93
94
  react_1.default.createElement(material_1.Box, { className: classes.messageWrap },
94
- react_1.default.createElement(react_core_1.Link, { to: scRoutingContext.url(react_core_1.SCRoutes.USER_PRIVATE_MESSAGES_ROUTE_NAME, notificationObject.message.sender), className: classes.message },
95
+ react_1.default.createElement(react_core_1.Link, { to: ((_a = notificationObject.message) === null || _a === void 0 ? void 0 : _a.group)
96
+ ? scRoutingContext.url(react_core_1.SCRoutes.GROUP_MESSAGES_ROUTE_NAME, notificationObject.message.group)
97
+ : scRoutingContext.url(react_core_1.SCRoutes.USER_PRIVATE_MESSAGES_ROUTE_NAME, notificationObject.message.sender), className: classes.message },
95
98
  react_1.default.createElement(material_1.Typography, { variant: "body2", dangerouslySetInnerHTML: { __html: notificationObject.message.message } }))))),
96
99
  isSnippetTemplate && (react_1.default.createElement(material_1.Box, null,
97
100
  react_1.default.createElement(material_1.Typography, { component: "div", color: "inherit" },
@@ -99,13 +102,17 @@ function PrivateMessageNotification(props) {
99
102
  to: scRoutingContext.url(react_core_1.SCRoutes.USER_PROFILE_ROUTE_NAME, notificationObject.message.sender)
100
103
  }), { onClick: notificationObject.message.sender.deleted ? () => setOpenAlert(true) : null, className: classes.username }), notificationObject.message.sender.username),
101
104
  ' ',
102
- react_1.default.createElement(react_core_1.Link, { to: scRoutingContext.url(react_core_1.SCRoutes.USER_PRIVATE_MESSAGES_ROUTE_NAME, notificationObject.message.sender), className: classes.messageLabel }, intl.formatMessage(messages.receivePrivateMessage, {
105
+ react_1.default.createElement(react_core_1.Link, { to: ((_b = notificationObject.message) === null || _b === void 0 ? void 0 : _b.group)
106
+ ? scRoutingContext.url(react_core_1.SCRoutes.GROUP_MESSAGES_ROUTE_NAME, notificationObject.message.group)
107
+ : scRoutingContext.url(react_core_1.SCRoutes.USER_PRIVATE_MESSAGES_ROUTE_NAME, notificationObject.message.sender), className: classes.messageLabel }, intl.formatMessage(messages.receivePrivateMessage, {
103
108
  total: 1,
104
109
  b: (...chunks) => react_1.default.createElement("strong", null, chunks)
105
110
  })))))), footer: isToastTemplate && (react_1.default.createElement(material_1.Stack, { direction: "row", justifyContent: "space-between", alignItems: "center", spacing: 2 },
106
111
  react_1.default.createElement(DateTimeAgo_1.default, { date: notificationObject.active_at }),
107
112
  react_1.default.createElement(material_1.Typography, { color: "primary" },
108
- react_1.default.createElement(react_core_1.Link, { to: scRoutingContext.url(react_core_1.SCRoutes.USER_PRIVATE_MESSAGES_ROUTE_NAME, notificationObject.message.sender) }, scUserContext.user && follower ? (react_1.default.createElement(react_intl_1.FormattedMessage, { id: "ui.userToastNotifications.replyMessage", defaultMessage: 'ui.userToastNotifications.replyMessage' })) : (react_1.default.createElement(react_intl_1.FormattedMessage, { id: "ui.userToastNotifications.viewMessage", defaultMessage: 'ui.userToastNotifications.viewMessage' })))))) }, rest)));
113
+ react_1.default.createElement(react_core_1.Link, { to: ((_c = notificationObject.message) === null || _c === void 0 ? void 0 : _c.group)
114
+ ? scRoutingContext.url(react_core_1.SCRoutes.GROUP_MESSAGES_ROUTE_NAME, notificationObject.message.group)
115
+ : scRoutingContext.url(react_core_1.SCRoutes.USER_PRIVATE_MESSAGES_ROUTE_NAME, notificationObject.message.sender) }, scUserContext.user && follower ? (react_1.default.createElement(react_intl_1.FormattedMessage, { id: "ui.userToastNotifications.replyMessage", defaultMessage: 'ui.userToastNotifications.replyMessage' })) : (react_1.default.createElement(react_intl_1.FormattedMessage, { id: "ui.userToastNotifications.viewMessage", defaultMessage: 'ui.userToastNotifications.viewMessage' })))))) }, rest)));
109
116
  }
110
117
  return (react_1.default.createElement(react_1.default.Fragment, null,
111
118
  react_1.default.createElement(Root, Object.assign({ id: id, className: (0, classnames_1.default)(classes.root, className, `${constants_1.PREFIX}-${template}`), template: template, isNew: notificationObject.is_new, disableTypography: true, actions: react_1.default.createElement(material_1.Stack, { direction: "row", justifyContent: "space-between", alignItems: "center", spacing: 2 },
@@ -114,8 +121,12 @@ function PrivateMessageNotification(props) {
114
121
  ? null
115
122
  : scUserContext.user
116
123
  ? follower === null || manager.isLoading(notificationObject.message.sender)
117
- : null, to: scRoutingContext.url(react_core_1.SCRoutes.USER_PRIVATE_MESSAGES_ROUTE_NAME, notificationObject.message.sender) }, scUserContext.user && follower ? (react_1.default.createElement(react_intl_1.FormattedMessage, { id: "ui.notification.privateMessage.btnReplyLabel", defaultMessage: "ui.notification.privateMessage.btnReplyLabel" })) : (react_1.default.createElement(react_intl_1.FormattedMessage, { id: "ui.notification.privateMessage.btnViewLabel", defaultMessage: "ui.notification.privateMessage.btnViewLabel" })))), primary: react_1.default.createElement(material_1.Box, { className: classes.messageWrap },
118
- react_1.default.createElement(react_core_1.Link, { to: scRoutingContext.url(react_core_1.SCRoutes.USER_PRIVATE_MESSAGES_ROUTE_NAME, notificationObject.message.sender), className: classes.message },
124
+ : null, to: ((_d = notificationObject.message) === null || _d === void 0 ? void 0 : _d.group)
125
+ ? scRoutingContext.url(react_core_1.SCRoutes.GROUP_MESSAGES_ROUTE_NAME, notificationObject.message.group)
126
+ : scRoutingContext.url(react_core_1.SCRoutes.USER_PRIVATE_MESSAGES_ROUTE_NAME, notificationObject.message.sender) }, scUserContext.user && follower ? (react_1.default.createElement(react_intl_1.FormattedMessage, { id: "ui.notification.privateMessage.btnReplyLabel", defaultMessage: "ui.notification.privateMessage.btnReplyLabel" })) : (react_1.default.createElement(react_intl_1.FormattedMessage, { id: "ui.notification.privateMessage.btnViewLabel", defaultMessage: "ui.notification.privateMessage.btnViewLabel" })))), primary: react_1.default.createElement(material_1.Box, { className: classes.messageWrap },
127
+ react_1.default.createElement(react_core_1.Link, { to: ((_e = notificationObject.message) === null || _e === void 0 ? void 0 : _e.group)
128
+ ? scRoutingContext.url(react_core_1.SCRoutes.GROUP_MESSAGES_ROUTE_NAME, notificationObject.message.group)
129
+ : scRoutingContext.url(react_core_1.SCRoutes.USER_PRIVATE_MESSAGES_ROUTE_NAME, notificationObject.message.sender), className: classes.message },
119
130
  react_1.default.createElement(material_1.Typography, { variant: "body2", dangerouslySetInnerHTML: { __html: notificationObject.message.message } }))) }, rest)),
120
131
  openAlert && react_1.default.createElement(UserDeletedSnackBar_1.default, { open: openAlert, handleClose: () => setOpenAlert(false) })));
121
132
  }
@@ -5,6 +5,7 @@ const react_1 = tslib_1.__importStar(require("react"));
5
5
  const styles_1 = require("@mui/material/styles");
6
6
  const lab_1 = require("@mui/lab");
7
7
  const classnames_1 = tslib_1.__importDefault(require("classnames"));
8
+ const types_1 = require("@selfcommunity/types");
8
9
  const system_1 = require("@mui/system");
9
10
  const Icon_1 = tslib_1.__importDefault(require("@mui/material/Icon"));
10
11
  const material_1 = require("@mui/material");
@@ -54,6 +55,7 @@ const PopperRoot = (0, styles_1.styled)(material_1.Popper, {
54
55
  * @param inProps
55
56
  */
56
57
  function VoteButton(inProps) {
58
+ var _a;
57
59
  // PROPS
58
60
  const props = (0, system_1.useThemeProps)({
59
61
  props: inProps,
@@ -62,11 +64,13 @@ function VoteButton(inProps) {
62
64
  const { className, contributionId, contributionType, contribution = null, onVote } = props, rest = tslib_1.__rest(props, ["className", "contributionId", "contributionType", "contribution", "onVote"]);
63
65
  // STATE
64
66
  const [anchorEl, setAnchorEl] = (0, react_1.useState)(null);
67
+ const [status, setStatus] = (0, react_1.useState)(null);
65
68
  // REF
66
69
  const timeoutRef = (0, react_1.useRef)(null);
67
70
  // CONTEXT
68
71
  const scContext = (0, react_core_1.useSCContext)();
69
72
  const scUserContext = (0, react_core_1.useSCUser)();
73
+ const scGroupsManager = scUserContext.managers.groups;
70
74
  const { enqueueSnackbar } = (0, notistack_1.useSnackbar)();
71
75
  // HANDLERS
72
76
  const handleMouseEnter = (event) => {
@@ -81,6 +85,15 @@ function VoteButton(inProps) {
81
85
  timeoutRef.current && clearTimeout(timeoutRef.current);
82
86
  timeoutRef.current = null;
83
87
  };
88
+ /**
89
+ * If the obj has a group, checks the subscription status for the authenticated user
90
+ */
91
+ (0, react_1.useEffect)(() => {
92
+ var _a;
93
+ if (((_a = scUserContext === null || scUserContext === void 0 ? void 0 : scUserContext.user) === null || _a === void 0 ? void 0 : _a.id) && (contribution === null || contribution === void 0 ? void 0 : contribution.group)) {
94
+ setStatus(scGroupsManager.subscriptionStatus(contribution === null || contribution === void 0 ? void 0 : contribution.group));
95
+ }
96
+ }, [(_a = scUserContext === null || scUserContext === void 0 ? void 0 : scUserContext.user) === null || _a === void 0 ? void 0 : _a.id, scGroupsManager.subscriptionStatus, contribution === null || contribution === void 0 ? void 0 : contribution.group]);
84
97
  /**
85
98
  * Perform vote action
86
99
  * @param reaction
@@ -95,6 +108,12 @@ function VoteButton(inProps) {
95
108
  autoHideDuration: 3000
96
109
  });
97
110
  }
111
+ else if ((contribution === null || contribution === void 0 ? void 0 : contribution.group) && status !== types_1.SCGroupSubscriptionStatusType.SUBSCRIBED) {
112
+ enqueueSnackbar(react_1.default.createElement(react_intl_1.FormattedMessage, { id: "ui.common.group.actions.unsubscribed", defaultMessage: "ui.common.group.actions.unsubscribed" }), {
113
+ variant: 'warning',
114
+ autoHideDuration: 3000
115
+ });
116
+ }
98
117
  else {
99
118
  handleVote(reaction);
100
119
  }
@@ -1,5 +1,5 @@
1
1
  import { __rest } from "tslib";
2
- import React, { useMemo, useState } from 'react';
2
+ import React, { useEffect, useMemo, useState } from 'react';
3
3
  import { FormattedMessage } from 'react-intl';
4
4
  import LoadingButton from '@mui/lab/LoadingButton';
5
5
  import { styled } from '@mui/material/styles';
@@ -8,7 +8,7 @@ import { SCOPE_SC_UI } from '../../../../constants/Errors';
8
8
  import classNames from 'classnames';
9
9
  import { useSnackbar } from 'notistack';
10
10
  import Icon from '@mui/material/Icon';
11
- import { SCContributionType } from '@selfcommunity/types';
11
+ import { SCContributionType, SCGroupSubscriptionStatusType } from '@selfcommunity/types';
12
12
  import { Endpoints, http } from '@selfcommunity/api-services';
13
13
  import { Logger } from '@selfcommunity/utils';
14
14
  import { useSCContext, useSCFetchFeedObject, useSCUser } from '@selfcommunity/react-core';
@@ -25,15 +25,27 @@ const Root = styled(Box, {
25
25
  slot: 'ActionFollowRoot'
26
26
  })(() => ({}));
27
27
  export default function Follow(props) {
28
+ var _a;
28
29
  // PROPS
29
30
  const { className = null, feedObjectId = null, feedObject = null, feedObjectType = SCContributionType.POST, handleFollow, iconized = true } = props, rest = __rest(props, ["className", "feedObjectId", "feedObject", "feedObjectType", "handleFollow", "iconized"]);
30
31
  // STATE
31
32
  const { obj, setObj } = useSCFetchFeedObject({ id: feedObjectId, feedObject, feedObjectType });
32
33
  const [isFollowing, setIsFollowing] = useState(false);
34
+ const [status, setStatus] = useState(null);
33
35
  // CONTEXT
34
36
  const scContext = useSCContext();
35
37
  const scUserContext = useSCUser();
38
+ const scGroupsManager = scUserContext.managers.groups;
36
39
  const { enqueueSnackbar } = useSnackbar();
40
+ /**
41
+ * If the obj has a group, checks the subscription status for the authenticated user
42
+ */
43
+ useEffect(() => {
44
+ var _a;
45
+ if (((_a = scUserContext === null || scUserContext === void 0 ? void 0 : scUserContext.user) === null || _a === void 0 ? void 0 : _a.id) && (obj === null || obj === void 0 ? void 0 : obj.group)) {
46
+ setStatus(scGroupsManager.subscriptionStatus(obj === null || obj === void 0 ? void 0 : obj.group));
47
+ }
48
+ }, [(_a = scUserContext === null || scUserContext === void 0 ? void 0 : scUserContext.user) === null || _a === void 0 ? void 0 : _a.id, scGroupsManager.subscriptionStatus, obj === null || obj === void 0 ? void 0 : obj.group]);
37
49
  /**
38
50
  * Perform follow/unfollow
39
51
  * Post, Discussion, Status
@@ -59,6 +71,12 @@ export default function Follow(props) {
59
71
  if (!scUserContext.user) {
60
72
  scContext.settings.handleAnonymousAction();
61
73
  }
74
+ else if ((obj === null || obj === void 0 ? void 0 : obj.group) && status !== SCGroupSubscriptionStatusType.SUBSCRIBED) {
75
+ enqueueSnackbar(React.createElement(FormattedMessage, { id: "ui.common.group.actions.unsubscribed", defaultMessage: "ui.common.group.actions.unsubscribed" }), {
76
+ variant: 'warning',
77
+ autoHideDuration: 3000
78
+ });
79
+ }
62
80
  else {
63
81
  setIsFollowing(true);
64
82
  performFollow()
@@ -1,5 +1,5 @@
1
1
  import { __rest } from "tslib";
2
- import React, { useContext, useMemo, useState } from 'react';
2
+ import React, { useContext, useEffect, useMemo, useState } from 'react';
3
3
  import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
4
4
  import Icon from '@mui/material/Icon';
5
5
  import LoadingButton from '@mui/lab/LoadingButton';
@@ -13,7 +13,7 @@ import { SCOPE_SC_UI } from '../../../../constants/Errors';
13
13
  import classNames from 'classnames';
14
14
  import { useSnackbar } from 'notistack';
15
15
  import Skeleton from '@mui/material/Skeleton';
16
- import { SCContributionType } from '@selfcommunity/types';
16
+ import { SCContributionType, SCGroupSubscriptionStatusType } from '@selfcommunity/types';
17
17
  import { Endpoints, http } from '@selfcommunity/api-services';
18
18
  import { copyTextToClipboard, Logger } from '@selfcommunity/utils';
19
19
  import { SCPreferences, SCPreferencesContext, UserUtils, useSCContext, useSCFetchFeedObject, useSCRouting, useSCUser } from '@selfcommunity/react-core';
@@ -43,6 +43,7 @@ const Root = styled(Box, {
43
43
  slot: 'ActionShareRoot'
44
44
  })(() => ({}));
45
45
  export default function Share(props) {
46
+ var _a;
46
47
  // PROPS
47
48
  const { className = null, feedObjectId = null, feedObject = null, feedObjectType = SCContributionType.POST, withAction = true, withAudience = true, inlineAction = false } = props, rest = __rest(props, ["className", "feedObjectId", "feedObject", "feedObjectType", "withAction", "withAudience", "inlineAction"]);
48
49
  // STATE
@@ -54,6 +55,7 @@ export default function Share(props) {
54
55
  const [composerShareProps, setComposerShareProps] = useState(null);
55
56
  const [openSharesDialog, setOpenSharesDialog] = useState(false);
56
57
  const [anchorEl, setAnchorEl] = React.useState(null);
58
+ const [status, setStatus] = useState(null);
57
59
  // CONTEXT
58
60
  const scContext = useSCContext();
59
61
  const scRoutingContext = useSCRouting();
@@ -65,6 +67,7 @@ export default function Share(props) {
65
67
  const linkedinShareEnabled = SCPreferences.ADDONS_SHARE_POST_ON_LINKEDIN_ENABLED in scPreferencesContext.preferences &&
66
68
  scPreferencesContext.preferences[SCPreferences.ADDONS_SHARE_POST_ON_LINKEDIN_ENABLED].value;
67
69
  const scUserContext = useSCUser();
70
+ const scGroupsManager = scUserContext.managers.groups;
68
71
  const { enqueueSnackbar } = useSnackbar();
69
72
  const domain = typeof location !== 'undefined' && location.origin ? location.origin : '';
70
73
  const url = domain + scRoutingContext.url(getContributionRouteName(obj), getRouteData(obj));
@@ -97,6 +100,15 @@ export default function Share(props) {
97
100
  setObj(Object.assign({}, obj, { share_count: obj.share_count + 1 }));
98
101
  handleComposerOnClose();
99
102
  }
103
+ /**
104
+ * If the obj has a group, checks the subscription status for the authenticated user
105
+ */
106
+ useEffect(() => {
107
+ var _a;
108
+ if (((_a = scUserContext === null || scUserContext === void 0 ? void 0 : scUserContext.user) === null || _a === void 0 ? void 0 : _a.id) && (obj === null || obj === void 0 ? void 0 : obj.group)) {
109
+ setStatus(scGroupsManager.subscriptionStatus(obj === null || obj === void 0 ? void 0 : obj.group));
110
+ }
111
+ }, [(_a = scUserContext === null || scUserContext === void 0 ? void 0 : scUserContext.user) === null || _a === void 0 ? void 0 : _a.id, scGroupsManager.subscriptionStatus, obj === null || obj === void 0 ? void 0 : obj.group]);
100
112
  /**
101
113
  * Performs follow/unfollow
102
114
  * Post, Discussion, Status
@@ -139,6 +151,12 @@ export default function Share(props) {
139
151
  autoHideDuration: 3000
140
152
  });
141
153
  }
154
+ else if ((obj === null || obj === void 0 ? void 0 : obj.group) && status !== SCGroupSubscriptionStatusType.SUBSCRIBED) {
155
+ enqueueSnackbar(React.createElement(FormattedMessage, { id: "ui.common.group.actions.unsubscribed", defaultMessage: "ui.common.group.actions.unsubscribed" }), {
156
+ variant: 'warning',
157
+ autoHideDuration: 3000
158
+ });
159
+ }
142
160
  else {
143
161
  setIsSharing(true);
144
162
  performCreateMediaShare()
@@ -25,7 +25,7 @@ import Activities from './Activities';
25
25
  import CommentObjectReply from '../CommentObjectReply';
26
26
  import { SCOPE_SC_UI } from '../../constants/Errors';
27
27
  import { useSnackbar } from 'notistack';
28
- import { SCContributionType } from '@selfcommunity/types';
28
+ import { SCContributionType, SCGroupSubscriptionStatusType } from '@selfcommunity/types';
29
29
  import { Endpoints, http } from '@selfcommunity/api-services';
30
30
  import { CacheStrategies, Logger, LRUCache } from '@selfcommunity/utils';
31
31
  import { catchUnauthorizedActionByBlockedUser } from '../../utils/errors';
@@ -131,7 +131,7 @@ const Root = styled(Widget, {
131
131
  * @param inProps
132
132
  */
133
133
  export default function FeedObject(inProps) {
134
- var _a;
134
+ var _a, _b;
135
135
  // PROPS
136
136
  const props = useThemeProps({
137
137
  props: inProps,
@@ -142,6 +142,7 @@ export default function FeedObject(inProps) {
142
142
  const scContext = useSCContext();
143
143
  const scRoutingContext = useSCRouting();
144
144
  const scUserContext = useSCUser();
145
+ const scGroupsManager = scUserContext.managers.groups;
145
146
  const { enqueueSnackbar } = useSnackbar();
146
147
  // OBJECTS
147
148
  const { obj, setObj, error } = useSCFetchFeedObject({ id: feedObjectId, feedObject, feedObjectType, cacheStrategy });
@@ -160,6 +161,7 @@ export default function FeedObject(inProps) {
160
161
  const [isReplying, setIsReplying] = useState(false);
161
162
  const [selectedActivities, setSelectedActivities] = useState(getInitialSelectedActivitiesType());
162
163
  const [expanded, setExpanded] = useState(summaryExpanded);
164
+ const [status, setStatus] = useState(null);
163
165
  // INTL
164
166
  const intl = useIntl();
165
167
  /**
@@ -191,6 +193,15 @@ export default function FeedObject(inProps) {
191
193
  }
192
194
  return SCFeedObjectActivitiesType.RECENT_COMMENTS;
193
195
  }
196
+ /**
197
+ * If the obj has a group, checks the subscription status for the authenticated user
198
+ */
199
+ useEffect(() => {
200
+ var _a;
201
+ if (((_a = scUserContext === null || scUserContext === void 0 ? void 0 : scUserContext.user) === null || _a === void 0 ? void 0 : _a.id) && (feedObject === null || feedObject === void 0 ? void 0 : feedObject.group)) {
202
+ setStatus(scGroupsManager.subscriptionStatus(feedObject === null || feedObject === void 0 ? void 0 : feedObject.group));
203
+ }
204
+ }, [(_a = scUserContext === null || scUserContext === void 0 ? void 0 : scUserContext.user) === null || _a === void 0 ? void 0 : _a.id, scGroupsManager.subscriptionStatus, feedObject === null || feedObject === void 0 ? void 0 : feedObject.group]);
194
205
  /**
195
206
  * Open expanded activities
196
207
  */
@@ -348,6 +359,12 @@ export default function FeedObject(inProps) {
348
359
  autoHideDuration: 3000
349
360
  });
350
361
  }
362
+ else if ((feedObject === null || feedObject === void 0 ? void 0 : feedObject.group) && status !== SCGroupSubscriptionStatusType.SUBSCRIBED) {
363
+ enqueueSnackbar(React.createElement(FormattedMessage, { id: "ui.common.group.actions.unsubscribed", defaultMessage: "ui.common.group.actions.unsubscribed" }), {
364
+ variant: 'warning',
365
+ autoHideDuration: 3000
366
+ });
367
+ }
351
368
  else {
352
369
  setIsReplying(true);
353
370
  performReply(comment)
@@ -445,8 +462,8 @@ export default function FeedObject(inProps) {
445
462
  obj.location && (React.createElement(React.Fragment, null,
446
463
  React.createElement(Bullet, null),
447
464
  React.createElement(Box, { className: classes.location },
448
- React.createElement(Icon, null, "add_location_alt"), (_a = obj.location) === null || _a === void 0 ? void 0 :
449
- _a.location))),
465
+ React.createElement(Icon, null, "add_location_alt"), (_b = obj.location) === null || _b === void 0 ? void 0 :
466
+ _b.location))),
450
467
  React.createElement(Bullet, null),
451
468
  React.createElement(Box, { className: classes.tag }, obj.addressing.length > 0 ? (React.createElement(Tags, { tags: obj.addressing, TagChipProps: { disposable: false, clickable: false } })) : obj.group ? (React.createElement(Tooltip, { title: `${intl.formatMessage(messages.visibleToGroup, { group: obj.group.name })}` },
452
469
  React.createElement(Icon, { color: "disabled", fontSize: "small" }, "groups"))) : (React.createElement(Tooltip, { title: `${intl.formatMessage(messages.visibleToAll)}` },
@@ -39,6 +39,7 @@ const Root = styled(NotificationItem, {
39
39
  * @param props
40
40
  */
41
41
  export default function PrivateMessageNotification(props) {
42
+ var _a, _b, _c, _d, _e;
42
43
  // PROPS
43
44
  const { notificationObject, id = `n_${props.notificationObject['sid']}`, className, template = SCNotificationObjectTemplateType.DETAIL } = props, rest = __rest(props, ["notificationObject", "id", "className", "template"]);
44
45
  // CONTEXT
@@ -89,7 +90,9 @@ export default function PrivateMessageNotification(props) {
89
90
  React.createElement(FormattedMessage, { id: 'ui.userToastNotifications.privateMessage.sentMessage', defaultMessage: 'ui.userToastNotifications.privateMessage.sentMessage' }),
90
91
  ":",
91
92
  React.createElement(Box, { className: classes.messageWrap },
92
- React.createElement(Link, { to: scRoutingContext.url(SCRoutes.USER_PRIVATE_MESSAGES_ROUTE_NAME, notificationObject.message.sender), className: classes.message },
93
+ React.createElement(Link, { to: ((_a = notificationObject.message) === null || _a === void 0 ? void 0 : _a.group)
94
+ ? scRoutingContext.url(SCRoutes.GROUP_MESSAGES_ROUTE_NAME, notificationObject.message.group)
95
+ : scRoutingContext.url(SCRoutes.USER_PRIVATE_MESSAGES_ROUTE_NAME, notificationObject.message.sender), className: classes.message },
93
96
  React.createElement(Typography, { variant: "body2", dangerouslySetInnerHTML: { __html: notificationObject.message.message } }))))),
94
97
  isSnippetTemplate && (React.createElement(Box, null,
95
98
  React.createElement(Typography, { component: "div", color: "inherit" },
@@ -97,13 +100,17 @@ export default function PrivateMessageNotification(props) {
97
100
  to: scRoutingContext.url(SCRoutes.USER_PROFILE_ROUTE_NAME, notificationObject.message.sender)
98
101
  }), { onClick: notificationObject.message.sender.deleted ? () => setOpenAlert(true) : null, className: classes.username }), notificationObject.message.sender.username),
99
102
  ' ',
100
- React.createElement(Link, { to: scRoutingContext.url(SCRoutes.USER_PRIVATE_MESSAGES_ROUTE_NAME, notificationObject.message.sender), className: classes.messageLabel }, intl.formatMessage(messages.receivePrivateMessage, {
103
+ React.createElement(Link, { to: ((_b = notificationObject.message) === null || _b === void 0 ? void 0 : _b.group)
104
+ ? scRoutingContext.url(SCRoutes.GROUP_MESSAGES_ROUTE_NAME, notificationObject.message.group)
105
+ : scRoutingContext.url(SCRoutes.USER_PRIVATE_MESSAGES_ROUTE_NAME, notificationObject.message.sender), className: classes.messageLabel }, intl.formatMessage(messages.receivePrivateMessage, {
101
106
  total: 1,
102
107
  b: (...chunks) => React.createElement("strong", null, chunks)
103
108
  })))))), footer: isToastTemplate && (React.createElement(Stack, { direction: "row", justifyContent: "space-between", alignItems: "center", spacing: 2 },
104
109
  React.createElement(DateTimeAgo, { date: notificationObject.active_at }),
105
110
  React.createElement(Typography, { color: "primary" },
106
- React.createElement(Link, { to: scRoutingContext.url(SCRoutes.USER_PRIVATE_MESSAGES_ROUTE_NAME, notificationObject.message.sender) }, scUserContext.user && follower ? (React.createElement(FormattedMessage, { id: "ui.userToastNotifications.replyMessage", defaultMessage: 'ui.userToastNotifications.replyMessage' })) : (React.createElement(FormattedMessage, { id: "ui.userToastNotifications.viewMessage", defaultMessage: 'ui.userToastNotifications.viewMessage' })))))) }, rest)));
111
+ React.createElement(Link, { to: ((_c = notificationObject.message) === null || _c === void 0 ? void 0 : _c.group)
112
+ ? scRoutingContext.url(SCRoutes.GROUP_MESSAGES_ROUTE_NAME, notificationObject.message.group)
113
+ : scRoutingContext.url(SCRoutes.USER_PRIVATE_MESSAGES_ROUTE_NAME, notificationObject.message.sender) }, scUserContext.user && follower ? (React.createElement(FormattedMessage, { id: "ui.userToastNotifications.replyMessage", defaultMessage: 'ui.userToastNotifications.replyMessage' })) : (React.createElement(FormattedMessage, { id: "ui.userToastNotifications.viewMessage", defaultMessage: 'ui.userToastNotifications.viewMessage' })))))) }, rest)));
107
114
  }
108
115
  return (React.createElement(React.Fragment, null,
109
116
  React.createElement(Root, Object.assign({ id: id, className: classNames(classes.root, className, `${PREFIX}-${template}`), template: template, isNew: notificationObject.is_new, disableTypography: true, actions: React.createElement(Stack, { direction: "row", justifyContent: "space-between", alignItems: "center", spacing: 2 },
@@ -112,8 +119,12 @@ export default function PrivateMessageNotification(props) {
112
119
  ? null
113
120
  : scUserContext.user
114
121
  ? follower === null || manager.isLoading(notificationObject.message.sender)
115
- : null, to: scRoutingContext.url(SCRoutes.USER_PRIVATE_MESSAGES_ROUTE_NAME, notificationObject.message.sender) }, scUserContext.user && follower ? (React.createElement(FormattedMessage, { id: "ui.notification.privateMessage.btnReplyLabel", defaultMessage: "ui.notification.privateMessage.btnReplyLabel" })) : (React.createElement(FormattedMessage, { id: "ui.notification.privateMessage.btnViewLabel", defaultMessage: "ui.notification.privateMessage.btnViewLabel" })))), primary: React.createElement(Box, { className: classes.messageWrap },
116
- React.createElement(Link, { to: scRoutingContext.url(SCRoutes.USER_PRIVATE_MESSAGES_ROUTE_NAME, notificationObject.message.sender), className: classes.message },
122
+ : null, to: ((_d = notificationObject.message) === null || _d === void 0 ? void 0 : _d.group)
123
+ ? scRoutingContext.url(SCRoutes.GROUP_MESSAGES_ROUTE_NAME, notificationObject.message.group)
124
+ : scRoutingContext.url(SCRoutes.USER_PRIVATE_MESSAGES_ROUTE_NAME, notificationObject.message.sender) }, scUserContext.user && follower ? (React.createElement(FormattedMessage, { id: "ui.notification.privateMessage.btnReplyLabel", defaultMessage: "ui.notification.privateMessage.btnReplyLabel" })) : (React.createElement(FormattedMessage, { id: "ui.notification.privateMessage.btnViewLabel", defaultMessage: "ui.notification.privateMessage.btnViewLabel" })))), primary: React.createElement(Box, { className: classes.messageWrap },
125
+ React.createElement(Link, { to: ((_e = notificationObject.message) === null || _e === void 0 ? void 0 : _e.group)
126
+ ? scRoutingContext.url(SCRoutes.GROUP_MESSAGES_ROUTE_NAME, notificationObject.message.group)
127
+ : scRoutingContext.url(SCRoutes.USER_PRIVATE_MESSAGES_ROUTE_NAME, notificationObject.message.sender), className: classes.message },
117
128
  React.createElement(Typography, { variant: "body2", dangerouslySetInnerHTML: { __html: notificationObject.message.message } }))) }, rest)),
118
129
  openAlert && React.createElement(UserDeletedSnackBar, { open: openAlert, handleClose: () => setOpenAlert(false) })));
119
130
  }
@@ -1,8 +1,9 @@
1
1
  import { __rest } from "tslib";
2
- import React, { useMemo, useRef, useState } from 'react';
2
+ import React, { useEffect, useMemo, useRef, useState } from 'react';
3
3
  import { styled } from '@mui/material/styles';
4
4
  import { LoadingButton } from '@mui/lab';
5
5
  import classNames from 'classnames';
6
+ import { SCGroupSubscriptionStatusType } from '@selfcommunity/types';
6
7
  import { useThemeProps } from '@mui/system';
7
8
  import Icon from '@mui/material/Icon';
8
9
  import { IconButton, Paper, Popper, Tooltip, useMediaQuery, useTheme } from '@mui/material';
@@ -52,6 +53,7 @@ const PopperRoot = styled(Popper, {
52
53
  * @param inProps
53
54
  */
54
55
  export default function VoteButton(inProps) {
56
+ var _a;
55
57
  // PROPS
56
58
  const props = useThemeProps({
57
59
  props: inProps,
@@ -60,11 +62,13 @@ export default function VoteButton(inProps) {
60
62
  const { className, contributionId, contributionType, contribution = null, onVote } = props, rest = __rest(props, ["className", "contributionId", "contributionType", "contribution", "onVote"]);
61
63
  // STATE
62
64
  const [anchorEl, setAnchorEl] = useState(null);
65
+ const [status, setStatus] = useState(null);
63
66
  // REF
64
67
  const timeoutRef = useRef(null);
65
68
  // CONTEXT
66
69
  const scContext = useSCContext();
67
70
  const scUserContext = useSCUser();
71
+ const scGroupsManager = scUserContext.managers.groups;
68
72
  const { enqueueSnackbar } = useSnackbar();
69
73
  // HANDLERS
70
74
  const handleMouseEnter = (event) => {
@@ -79,6 +83,15 @@ export default function VoteButton(inProps) {
79
83
  timeoutRef.current && clearTimeout(timeoutRef.current);
80
84
  timeoutRef.current = null;
81
85
  };
86
+ /**
87
+ * If the obj has a group, checks the subscription status for the authenticated user
88
+ */
89
+ useEffect(() => {
90
+ var _a;
91
+ if (((_a = scUserContext === null || scUserContext === void 0 ? void 0 : scUserContext.user) === null || _a === void 0 ? void 0 : _a.id) && (contribution === null || contribution === void 0 ? void 0 : contribution.group)) {
92
+ setStatus(scGroupsManager.subscriptionStatus(contribution === null || contribution === void 0 ? void 0 : contribution.group));
93
+ }
94
+ }, [(_a = scUserContext === null || scUserContext === void 0 ? void 0 : scUserContext.user) === null || _a === void 0 ? void 0 : _a.id, scGroupsManager.subscriptionStatus, contribution === null || contribution === void 0 ? void 0 : contribution.group]);
82
95
  /**
83
96
  * Perform vote action
84
97
  * @param reaction
@@ -93,6 +106,12 @@ export default function VoteButton(inProps) {
93
106
  autoHideDuration: 3000
94
107
  });
95
108
  }
109
+ else if ((contribution === null || contribution === void 0 ? void 0 : contribution.group) && status !== SCGroupSubscriptionStatusType.SUBSCRIBED) {
110
+ enqueueSnackbar(React.createElement(FormattedMessage, { id: "ui.common.group.actions.unsubscribed", defaultMessage: "ui.common.group.actions.unsubscribed" }), {
111
+ variant: 'warning',
112
+ autoHideDuration: 3000
113
+ });
114
+ }
96
115
  else {
97
116
  handleVote(reaction);
98
117
  }