@selfcommunity/react-ui 0.8.0-live.69 → 0.8.0-live.71

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.
Files changed (26) hide show
  1. package/lib/cjs/components/CreateLiveStreamButton/CreateLiveStreamButton.js +15 -4
  2. package/lib/cjs/components/CreateLiveStreamDialog/LiveStreamSelector/LiveStreamSelector.js +66 -12
  3. package/lib/cjs/components/EventForm/EventAddress.js +7 -2
  4. package/lib/cjs/components/EventForm/EventForm.js +19 -4
  5. package/lib/cjs/components/LiveStreamForm/LiveStreamForm.js +21 -6
  6. package/lib/cjs/components/Notification/LiveStream/LiveStream.js +12 -11
  7. package/lib/cjs/components/PlatformWidget/constants.d.ts +4 -0
  8. package/lib/cjs/components/PlatformWidget/constants.js +5 -1
  9. package/lib/cjs/components/UserLiveStreamWidget/Skeleton.js +1 -1
  10. package/lib/cjs/components/UserLiveStreamWidget/UserLiveStreamWidget.js +6 -2
  11. package/lib/cjs/constants/LiveStream.d.ts +1 -1
  12. package/lib/cjs/constants/LiveStream.js +1 -1
  13. package/lib/esm/components/CreateLiveStreamButton/CreateLiveStreamButton.js +16 -5
  14. package/lib/esm/components/CreateLiveStreamDialog/LiveStreamSelector/LiveStreamSelector.js +68 -15
  15. package/lib/esm/components/EventForm/EventAddress.js +10 -5
  16. package/lib/esm/components/EventForm/EventForm.js +20 -5
  17. package/lib/esm/components/LiveStreamForm/LiveStreamForm.js +22 -7
  18. package/lib/esm/components/Notification/LiveStream/LiveStream.js +12 -11
  19. package/lib/esm/components/PlatformWidget/constants.d.ts +4 -0
  20. package/lib/esm/components/PlatformWidget/constants.js +4 -0
  21. package/lib/esm/components/UserLiveStreamWidget/Skeleton.js +1 -1
  22. package/lib/esm/components/UserLiveStreamWidget/UserLiveStreamWidget.js +6 -2
  23. package/lib/esm/constants/LiveStream.d.ts +1 -1
  24. package/lib/esm/constants/LiveStream.js +1 -1
  25. package/lib/umd/react-ui.js +1 -1
  26. package/package.json +7 -7
@@ -9,6 +9,7 @@ const react_core_1 = require("@selfcommunity/react-core");
9
9
  const classnames_1 = tslib_1.__importDefault(require("classnames"));
10
10
  const react_1 = tslib_1.__importStar(require("react"));
11
11
  const react_intl_1 = require("react-intl");
12
+ const types_1 = require("@selfcommunity/types");
12
13
  const CreateLiveStreamDialog_1 = tslib_1.__importDefault(require("../CreateLiveStreamDialog"));
13
14
  const PREFIX = 'SCCreateLivestreamButton';
14
15
  const classes = {
@@ -39,7 +40,6 @@ const Root = (0, styles_1.styled)(material_1.Button, {
39
40
  * @param inProps
40
41
  */
41
42
  function CreateLiveStreamButton(inProps) {
42
- var _a;
43
43
  //PROPS
44
44
  const props = (0, system_1.useThemeProps)({
45
45
  props: inProps,
@@ -48,11 +48,22 @@ function CreateLiveStreamButton(inProps) {
48
48
  const { className, CreateLiveStreamDialogComponentProps = {}, onSuccess, children } = props, rest = tslib_1.__rest(props, ["className", "CreateLiveStreamDialogComponentProps", "onSuccess", "children"]);
49
49
  // CONTEXT
50
50
  const scUserContext = (0, react_1.useContext)(react_core_1.SCUserContext);
51
+ const { preferences, features } = (0, react_core_1.useSCPreferences)();
51
52
  // STATE
52
53
  const [open, setOpen] = react_1.default.useState(false);
53
54
  // CONST
54
- const authUserId = scUserContext.user ? scUserContext.user.id : null;
55
- const canCreateLiveStream = (0, react_1.useMemo)(() => { var _a, _b; return (_b = (_a = scUserContext === null || scUserContext === void 0 ? void 0 : scUserContext.user) === null || _a === void 0 ? void 0 : _a.permission) === null || _b === void 0 ? void 0 : _b.create_live_stream; }, [(_a = scUserContext === null || scUserContext === void 0 ? void 0 : scUserContext.user) === null || _a === void 0 ? void 0 : _a.permission]);
55
+ const authUserId = (0, react_1.useMemo)(() => (scUserContext.user ? scUserContext.user.id : null), [scUserContext.user]);
56
+ const isStaff = (0, react_1.useMemo)(() => scUserContext.user && react_core_1.UserUtils.isStaff(scUserContext.user), [scUserContext.user]);
57
+ const isCommunityOwner = (0, react_1.useMemo)(() => authUserId === 1, [authUserId]);
58
+ const isFreeTrialTier = (0, react_1.useMemo)(() => preferences &&
59
+ react_core_1.SCPreferences.CONFIGURATIONS_SUBSCRIPTION_TIER in preferences &&
60
+ preferences[react_core_1.SCPreferences.CONFIGURATIONS_SUBSCRIPTION_TIER].value &&
61
+ preferences[react_core_1.SCPreferences.CONFIGURATIONS_SUBSCRIPTION_TIER].value === types_1.SCCommunitySubscriptionTier.FREE_TRIAL, [preferences]);
62
+ const liveStreamEnabled = (0, react_1.useMemo)(() => preferences &&
63
+ features &&
64
+ react_core_1.SCPreferences.CONFIGURATIONS_LIVE_STREAM_ENABLED in preferences &&
65
+ preferences[react_core_1.SCPreferences.CONFIGURATIONS_LIVE_STREAM_ENABLED].value, [preferences, features]);
66
+ const onlyStaffEnabled = (0, react_1.useMemo)(() => preferences[react_core_1.SCPreferences.CONFIGURATIONS_LIVE_STREAM_ONLY_STAFF_ENABLED].value, [preferences]);
56
67
  /**
57
68
  * Handle close
58
69
  */
@@ -69,7 +80,7 @@ function CreateLiveStreamButton(inProps) {
69
80
  /**
70
81
  * If there's no authUserId, component is hidden.
71
82
  */
72
- if (!canCreateLiveStream || !authUserId) {
83
+ if (!liveStreamEnabled || !authUserId || (onlyStaffEnabled && !isStaff) || (isFreeTrialTier && !isCommunityOwner)) {
73
84
  return null;
74
85
  }
75
86
  /**
@@ -16,6 +16,9 @@ const event_1 = tslib_1.__importDefault(require("../../../assets/liveStream/even
16
16
  const live_1 = tslib_1.__importDefault(require("../../../assets/liveStream/live"));
17
17
  const api_services_1 = require("@selfcommunity/api-services");
18
18
  const constants_1 = require("../../LiveStreamRoom/constants");
19
+ const react_core_1 = require("@selfcommunity/react-core");
20
+ const types_2 = require("@selfcommunity/types");
21
+ const constants_2 = require("../../PlatformWidget/constants");
19
22
  exports.PREFIX = 'SCLiveStreamSelector';
20
23
  const classes = {
21
24
  root: `${exports.PREFIX}-root`,
@@ -62,34 +65,63 @@ function LiveStreamSelector(inProps) {
62
65
  props: inProps,
63
66
  name: exports.PREFIX
64
67
  });
65
- const { className, liveSelected, onLiveSelected, onNext } = props, rest = tslib_1.__rest(props, ["className", "liveSelected", "onLiveSelected", "onNext"]);
68
+ const { className, liveSelected, onLiveSelected, onNext } = props;
66
69
  // CONTEXT
70
+ const scContext = (0, react_core_1.useSCContext)();
71
+ const scUserContext = (0, react_core_1.useSCUser)();
67
72
  const { enqueueSnackbar } = (0, notistack_1.useSnackbar)();
68
73
  // STATE
69
74
  const [selectedOption, setSelectedOption] = (0, react_1.useState)(liveSelected);
70
75
  const [timeRemaining, setTimeRemaining] = (0, react_1.useState)(null);
76
+ // HOOKS
77
+ const { preferences } = (0, react_core_1.useSCPreferences)();
78
+ const isCommunityOwner = (0, react_1.useMemo)(() => { var _a; return ((_a = scUserContext === null || scUserContext === void 0 ? void 0 : scUserContext.user) === null || _a === void 0 ? void 0 : _a.id) === 1; }, [scUserContext.user]);
79
+ const isFreeTrialTier = (0, react_1.useMemo)(() => preferences &&
80
+ react_core_1.SCPreferences.CONFIGURATIONS_SUBSCRIPTION_TIER in preferences &&
81
+ preferences[react_core_1.SCPreferences.CONFIGURATIONS_SUBSCRIPTION_TIER].value &&
82
+ preferences[react_core_1.SCPreferences.CONFIGURATIONS_SUBSCRIPTION_TIER].value !== types_2.SCCommunitySubscriptionTier.FREE_TRIAL, [preferences]);
83
+ const intl = (0, react_intl_1.useIntl)();
71
84
  const options = [
72
85
  {
73
- title: 'Schedule a live event',
86
+ title: intl.formatMessage({ id: 'ui.liveStreamForm.selector.scheduleLiveEvent', defaultMessage: 'ui.liveStreamForm.selector.scheduleLiveEvent' }),
74
87
  image: event_1.default,
75
88
  type: types_1.LiveStreamType.EVENT_LIVE,
76
89
  features: [
77
- 'Schedule a live room or stream in your event space',
78
- 'Allow your members to RSVP, add to calendar, and receive event reminders',
79
- 'Automatically post the event recording to your space',
80
- 'Allow your members to host the event'
90
+ intl.formatMessage({
91
+ id: 'ui.liveStreamForm.selector.scheduleLiveEventItem1',
92
+ defaultMessage: 'ui.liveStreamForm.selector.scheduleLiveEventItem1'
93
+ }),
94
+ intl.formatMessage({
95
+ id: 'ui.liveStreamForm.selector.scheduleLiveEventItem2',
96
+ defaultMessage: 'ui.liveStreamForm.selector.scheduleLiveEventItem2'
97
+ }),
98
+ intl.formatMessage({
99
+ id: 'ui.liveStreamForm.selector.scheduleLiveEventItem3',
100
+ defaultMessage: 'ui.liveStreamForm.selector.scheduleLiveEventItem3'
101
+ })
81
102
  ],
82
103
  icons: [(0, jsx_runtime_1.jsx)(Icon_1.default, { children: "chevron_right" }), (0, jsx_runtime_1.jsx)(Icon_1.default, { children: "chevron_right" }), (0, jsx_runtime_1.jsx)(Icon_1.default, { children: "chevron_right" }), (0, jsx_runtime_1.jsx)(Icon_1.default, { children: "chevron_right" })]
83
104
  },
84
105
  {
85
- title: 'Start a live stream',
106
+ title: intl.formatMessage({
107
+ id: 'ui.liveStreamForm.selector.scheduleLiveStream',
108
+ defaultMessage: 'ui.liveStreamForm.selector.scheduleLiveStream'
109
+ }),
86
110
  image: live_1.default,
87
111
  type: types_1.LiveStreamType.DIRECT_LIVE,
88
112
  features: [
89
- 'Best for webinars, Q&As, AMAs, and for presentations',
90
- 'Up to 100 people',
91
- 'Only co-hosts can talk to each other with audio/video',
92
- 'View-only participants can only chat or be promoted to the stage'
113
+ intl.formatMessage({
114
+ id: 'ui.liveStreamForm.selector.scheduleLiveStreamItem1',
115
+ defaultMessage: 'ui.liveStreamForm.selector.scheduleLiveStreamItem1'
116
+ }),
117
+ intl.formatMessage({
118
+ id: 'ui.liveStreamForm.selector.scheduleLiveStreamItem2',
119
+ defaultMessage: 'ui.liveStreamForm.selector.scheduleLiveStreamItem2'
120
+ }),
121
+ intl.formatMessage({
122
+ id: 'ui.liveStreamForm.selector.scheduleLiveStreamItem3',
123
+ defaultMessage: 'ui.liveStreamForm.selector.scheduleLiveStreamItem3'
124
+ })
93
125
  ],
94
126
  icons: [(0, jsx_runtime_1.jsx)(Icon_1.default, { children: "chevron_right" }), (0, jsx_runtime_1.jsx)(Icon_1.default, { children: "chevron_right" }), (0, jsx_runtime_1.jsx)(Icon_1.default, { children: "chevron_right" }), (0, jsx_runtime_1.jsx)(Icon_1.default, { children: "chevron_right" })]
95
127
  }
@@ -121,7 +153,29 @@ function LiveStreamSelector(inProps) {
121
153
  (0, react_1.useEffect)(() => {
122
154
  fetchLivestreamStatus();
123
155
  }, []);
124
- return ((0, jsx_runtime_1.jsxs)(Root, Object.assign({ className: (0, classnames_1.default)(classes.root, className), maxWidth: "lg", sx: { py: 4 } }, { children: [(0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "h4", component: "h1", align: "center", gutterBottom: true, sx: { mb: 4, fontWeight: 500 } }, { children: "How do you want to go live?" })), timeRemaining !== null && timeRemaining <= constants_1.WARNING_THRESHOLD_EXPIRING_SOON && ((0, jsx_runtime_1.jsx)(material_1.Box, Object.assign({ className: classes.warning }, { children: (0, jsx_runtime_1.jsx)(material_1.Alert, Object.assign({ variant: "filled", severity: "warning" }, { children: timeRemaining <= 1 ? ((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.liveStreamRoom.selector.warningMinutesExausted", defaultMessage: "ui.liveStreamRoom.selector.warningMinutesExausted" })) : timeRemaining <= constants_1.WARNING_THRESHOLD_EXPIRING_SOON ? ((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.liveStreamRoom.selector.warningRemainingMinutes", defaultMessage: "ui.liveStreamRoom.selector.warningRemainingMinutes", values: { minutes: timeRemaining } })) : null })) }))), (0, jsx_runtime_1.jsx)(material_1.Box, Object.assign({ className: classes.options }, { children: options.map((option, index) => ((0, jsx_runtime_1.jsxs)(OptionCard, Object.assign({ selected: selectedOption === option.type, onClick: () => handleOptionSelect(option.type), elevation: 0, role: "button", tabIndex: 0, onKeyDown: (e) => {
156
+ const warning = (0, react_1.useMemo)(() => {
157
+ let _message;
158
+ if (isFreeTrialTier && isCommunityOwner) {
159
+ _message = ((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.liveStreamForm.selector.warningSubscriptionRequired", defaultMessage: "ui.liveStreamForm.selector.warningSubscriptionRequired", values: {
160
+ // eslint-disable-next-line @typescript-eslint/ban-ts-ignore
161
+ // @ts-ignore
162
+ link: (...chunks) => (0, jsx_runtime_1.jsx)(react_core_1.Link, Object.assign({ to: constants_2.SELFCOMMUNITY_PRICING[scContext.settings.locale.default] }, { children: chunks }))
163
+ } }));
164
+ }
165
+ else if (timeRemaining !== null && timeRemaining <= constants_1.WARNING_THRESHOLD_EXPIRING_SOON) {
166
+ if (timeRemaining <= 1) {
167
+ _message = ((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.liveStreamForm.selector.warningMinutesExausted", defaultMessage: "ui.liveStreamForm.selector.warningMinutesExausted" }));
168
+ }
169
+ else if (timeRemaining <= constants_1.WARNING_THRESHOLD_EXPIRING_SOON) {
170
+ _message = ((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.liveStreamForm.selector.warningRemainingMinutes", defaultMessage: "ui.liveStreamForm.selector.warningRemainingMinutes", values: { minutes: timeRemaining } }));
171
+ }
172
+ }
173
+ if (_message) {
174
+ return ((0, jsx_runtime_1.jsx)(material_1.Box, Object.assign({ className: classes.warning }, { children: (0, jsx_runtime_1.jsx)(material_1.Alert, Object.assign({ variant: "filled", severity: "warning" }, { children: timeRemaining <= 1 ? ((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.liveStreamForm.selector.warningMinutesExausted", defaultMessage: "ui.liveStreamForm.selector.warningMinutesExausted" })) : timeRemaining <= constants_1.WARNING_THRESHOLD_EXPIRING_SOON ? ((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.liveStreamForm.selector.warningRemainingMinutes", defaultMessage: "ui.liveStreamForm.selector.warningRemainingMinutes", values: { minutes: timeRemaining } })) : null })) })));
175
+ }
176
+ return null;
177
+ }, [timeRemaining, isFreeTrialTier]);
178
+ return ((0, jsx_runtime_1.jsxs)(Root, Object.assign({ className: (0, classnames_1.default)(classes.root, className), maxWidth: "lg", sx: { py: 4 } }, { children: [(0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "h4", component: "h1", align: "center", gutterBottom: true, sx: { mb: 4, fontWeight: 500 } }, { children: "How do you want to go live?" })), warning, (0, jsx_runtime_1.jsx)(material_1.Box, Object.assign({ className: classes.options }, { children: options.map((option, index) => ((0, jsx_runtime_1.jsxs)(OptionCard, Object.assign({ selected: selectedOption === option.type, onClick: () => handleOptionSelect(option.type), elevation: 0, role: "button", tabIndex: 0, onKeyDown: (e) => {
125
179
  if (e.key === 'Enter' || e.key === ' ') {
126
180
  handleOptionSelect(index);
127
181
  e.preventDefault();
@@ -69,12 +69,17 @@ function EventAddress(inProps) {
69
69
  // CONTEXT
70
70
  const scContext = (0, react_core_1.useSCContext)();
71
71
  const scUserContext = (0, react_core_1.useSCUser)();
72
+ const { preferences } = (0, react_core_1.useSCPreferences)();
72
73
  const geocodingApiKey = (0, react_1.useMemo)(() => scContext.settings.integrations && scContext.settings.integrations.geocoding.apiKey, [scContext.settings.integrations]);
73
74
  const { isLoaded } = (0, api_1.useLoadScript)({
74
75
  googleMapsApiKey: scContext.settings.integrations.geocoding.apiKey,
75
76
  libraries: ['places', 'geocoding']
76
77
  });
77
- const canViewLiveTab = (0, react_1.useMemo)(() => { var _a, _b; return ((_b = (_a = scUserContext === null || scUserContext === void 0 ? void 0 : scUserContext.user) === null || _a === void 0 ? void 0 : _a.permission) === null || _b === void 0 ? void 0 : _b.create_live_stream) || event.live_stream; }, [(_a = scUserContext === null || scUserContext === void 0 ? void 0 : scUserContext.user) === null || _a === void 0 ? void 0 : _a.permission]);
78
+ const isFreeTrialTier = (0, react_1.useMemo)(() => preferences &&
79
+ react_core_1.SCPreferences.CONFIGURATIONS_SUBSCRIPTION_TIER in preferences &&
80
+ preferences[react_core_1.SCPreferences.CONFIGURATIONS_SUBSCRIPTION_TIER].value &&
81
+ preferences[react_core_1.SCPreferences.CONFIGURATIONS_SUBSCRIPTION_TIER].value === types_1.SCCommunitySubscriptionTier.FREE_TRIAL, [preferences]);
82
+ const canViewLiveTab = (0, react_1.useMemo)(() => { var _a, _b; return !isFreeTrialTier && (((_b = (_a = scUserContext === null || scUserContext === void 0 ? void 0 : scUserContext.user) === null || _a === void 0 ? void 0 : _a.permission) === null || _b === void 0 ? void 0 : _b.create_live_stream) || event.live_stream); }, [(_a = scUserContext === null || scUserContext === void 0 ? void 0 : scUserContext.user) === null || _a === void 0 ? void 0 : _a.permission, isFreeTrialTier]);
78
83
  // HANDLERS
79
84
  const handleChange = (_event, newValue) => {
80
85
  setLocation(newValue);
@@ -138,7 +143,7 @@ function EventAddress(inProps) {
138
143
  if (!geocodingApiKey && !isLoaded) {
139
144
  return (0, jsx_runtime_1.jsx)(HiddenPlaceholder_1.default, {});
140
145
  }
141
- return ((0, jsx_runtime_1.jsxs)(Root, Object.assign({ className: (0, classnames_1.default)(classes.root, className) }, { children: [(0, jsx_runtime_1.jsxs)(material_1.Tabs, Object.assign({ className: classes.tabs, value: location, onChange: handleChange, indicatorColor: "secondary", textColor: "secondary", variant: "fullWidth" }, { children: [(0, jsx_runtime_1.jsx)(material_1.Tab, { value: types_1.SCEventLocationType.PERSON, classes: { root: classes.tab }, icon: (0, jsx_runtime_1.jsx)(Icon_1.default, { children: "add_location_alt" }), iconPosition: "start", label: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.eventForm.address.live.label", defaultMessage: "ui.eventForm.address.live.label" }) }), (0, jsx_runtime_1.jsx)(material_1.Tab, { value: types_1.SCEventLocationType.ONLINE, classes: { root: classes.tab }, icon: (0, jsx_runtime_1.jsx)(Icon_1.default, { children: "play_circle_outline" }), iconPosition: "start", label: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.eventForm.address.online.label", defaultMessage: "ui.eventForm.address.online.label" }) }), canViewLiveTab && ((0, jsx_runtime_1.jsx)(material_1.Tab, { value: types_1.SCEventLocationType.LIVESTREAM, classes: { root: classes.tab }, icon: (0, jsx_runtime_1.jsx)(Icon_1.default, { children: "photo_camera" }), iconPosition: "start", label: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.eventForm.address.liveStream.label", defaultMessage: "ui.eventForm.address.liveStream.label" }) }))] })), (0, jsx_runtime_1.jsxs)(material_1.Box, Object.assign({ className: classes.tabContent }, { children: [location === types_1.SCEventLocationType.PERSON && ((0, jsx_runtime_1.jsx)(material_1.Autocomplete, { size: "small", value: geolocation, onChange: handleSelection, inputValue: inputValue, onInputChange: handleLocationChange, options: suggestions, getOptionLabel: (option) => option.description || geolocation.description, noOptionsText: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.eventForm.address.live.noResults", defaultMessage: "ui.eventForm.address.live.noResults" }), isOptionEqualToValue: (option, value) => option.description === value.description, renderInput: (params) => ((0, jsx_runtime_1.jsx)(material_1.TextField, Object.assign({}, params, { label: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.eventForm.address.live.placeholder", defaultMessage: "ui.eventForm.address.live.placeholder" }), variant: "outlined", fullWidth: true, InputProps: Object.assign(Object.assign({}, params.InputProps), { endAdornment: ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(material_1.InputAdornment, Object.assign({ position: "start" }, { children: (0, jsx_runtime_1.jsx)(Icon_1.default, { children: "add_location_alt" }) })), params.InputProps.endAdornment] })) }) }))) })), location === types_1.SCEventLocationType.ONLINE && ((0, jsx_runtime_1.jsx)(UrlTextField_1.default, { size: "small", fullWidth: true, type: "url", placeholder: `${intl.formatMessage(messages.virtualPlaceholder)}`, helperText: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.eventForm.address.online.help", defaultMessage: "ui.eventForm.address.online.help" }), InputProps: {
146
+ return ((0, jsx_runtime_1.jsxs)(Root, Object.assign({ className: (0, classnames_1.default)(classes.root, className) }, { children: [(0, jsx_runtime_1.jsxs)(material_1.Tabs, Object.assign({ className: classes.tabs, value: location, onChange: handleChange, indicatorColor: "secondary", textColor: "secondary", variant: "fullWidth" }, { children: [(0, jsx_runtime_1.jsx)(material_1.Tab, { value: types_1.SCEventLocationType.PERSON, classes: { root: classes.tab }, icon: (0, jsx_runtime_1.jsx)(Icon_1.default, { children: "add_location_alt" }), iconPosition: "start", label: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.eventForm.address.live.label", defaultMessage: "ui.eventForm.address.live.label" }) }), (0, jsx_runtime_1.jsx)(material_1.Tab, { value: types_1.SCEventLocationType.ONLINE, classes: { root: classes.tab }, icon: (0, jsx_runtime_1.jsx)(Icon_1.default, { children: "play_circle_outline" }), iconPosition: "start", label: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.eventForm.address.online.label", defaultMessage: "ui.eventForm.address.online.label" }) }), canViewLiveTab && ((0, jsx_runtime_1.jsx)(material_1.Tab, { value: types_1.SCEventLocationType.LIVESTREAM, classes: { root: classes.tab }, icon: (0, jsx_runtime_1.jsx)(Icon_1.default, { children: "photo_camera" }), iconPosition: "start", label: (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.eventForm.address.liveStream.label", defaultMessage: "ui.eventForm.address.liveStream.label" }) }) }))] })), (0, jsx_runtime_1.jsxs)(material_1.Box, Object.assign({ className: classes.tabContent }, { children: [location === types_1.SCEventLocationType.PERSON && ((0, jsx_runtime_1.jsx)(material_1.Autocomplete, { size: "small", value: geolocation, onChange: handleSelection, inputValue: inputValue, onInputChange: handleLocationChange, options: suggestions, getOptionLabel: (option) => option.description || geolocation.description, noOptionsText: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.eventForm.address.live.noResults", defaultMessage: "ui.eventForm.address.live.noResults" }), isOptionEqualToValue: (option, value) => option.description === value.description, renderInput: (params) => ((0, jsx_runtime_1.jsx)(material_1.TextField, Object.assign({}, params, { label: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.eventForm.address.live.placeholder", defaultMessage: "ui.eventForm.address.live.placeholder" }), variant: "outlined", fullWidth: true, InputProps: Object.assign(Object.assign({}, params.InputProps), { endAdornment: ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(material_1.InputAdornment, Object.assign({ position: "start" }, { children: (0, jsx_runtime_1.jsx)(Icon_1.default, { children: "add_location_alt" }) })), params.InputProps.endAdornment] })) }) }))) })), location === types_1.SCEventLocationType.ONLINE && ((0, jsx_runtime_1.jsx)(UrlTextField_1.default, { size: "small", fullWidth: true, type: "url", placeholder: `${intl.formatMessage(messages.virtualPlaceholder)}`, helperText: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.eventForm.address.online.help", defaultMessage: "ui.eventForm.address.online.help" }), InputProps: {
142
147
  endAdornment: (0, jsx_runtime_1.jsx)(Icon_1.default, { children: "play_circle_outline" })
143
148
  }, onChange: handleLinkChange })), canViewLiveTab && location === types_1.SCEventLocationType.LIVESTREAM && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(LiveStream_1.default, { template: liveStream_1.SCLiveStreamTemplateType.SNIPPET, liveStream: liveStream, actions: (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, {}) }), (0, jsx_runtime_1.jsx)(LiveStreamFormSettings_1.default, { settings: liveStream.settings || constants_2.LIVESTREAM_DEFAULT_SETTINGS, onChange: handleLiveStreamSettingsChange })] }))] }))] })));
144
149
  }
@@ -77,7 +77,8 @@ const classes = {
77
77
  actions: `${constants_1.PREFIX}-actions`,
78
78
  privacySection: `${constants_1.PREFIX}-privacy-section`,
79
79
  privacySectionInfo: `${constants_1.PREFIX}-privacy-section-info`,
80
- error: `${constants_1.PREFIX}-error`
80
+ error: `${constants_1.PREFIX}-error`,
81
+ genericError: `${constants_1.PREFIX}-generic-error`
81
82
  };
82
83
  const Root = (0, styles_1.styled)(material_1.Box, {
83
84
  name: constants_1.PREFIX,
@@ -154,6 +155,7 @@ function EventForm(inProps) {
154
155
  // STATE
155
156
  const [field, setField] = (0, react_1.useState)(initialFieldState);
156
157
  const [error, setError] = (0, react_1.useState)({});
158
+ const [genericError, setGenericError] = (0, react_1.useState)(null);
157
159
  // PREFERENCES
158
160
  const scPreferences = (0, react_core_1.useSCPreferences)();
159
161
  const privateEnabled = (0, react_1.useMemo)(() => scPreferences.preferences[react_core_1.SCPreferences.CONFIGURATIONS_EVENTS_PRIVATE_ENABLED].value, [scPreferences.preferences]);
@@ -197,6 +199,7 @@ function EventForm(inProps) {
197
199
  }, []);
198
200
  const handleSubmit = (0, react_1.useCallback)(() => {
199
201
  setField((prev) => (Object.assign(Object.assign({}, prev), { ['isSubmitting']: true })));
202
+ setGenericError(null);
200
203
  const formData = new FormData();
201
204
  if (field.imageOriginalFile) {
202
205
  formData.append('image_original', field.imageOriginalFile);
@@ -251,6 +254,15 @@ function EventForm(inProps) {
251
254
  else {
252
255
  setError(Object.assign(Object.assign({}, error), _error));
253
256
  }
257
+ if ('errorsError' in _error) {
258
+ setGenericError(intl.formatMessage({
259
+ id: 'ui.eventForm.liveStream.error.monthlyMinuteLimitReached',
260
+ defaultMessage: 'ui.eventForm.liveStream.error.monthlyMinuteLimitReached'
261
+ }));
262
+ }
263
+ else {
264
+ setGenericError(null);
265
+ }
254
266
  setField((prev) => (Object.assign(Object.assign({}, prev), { ['isSubmitting']: false })));
255
267
  utils_1.Logger.error(Errors_1.SCOPE_SC_UI, e);
256
268
  onError === null || onError === void 0 ? void 0 : onError(e);
@@ -263,7 +275,8 @@ function EventForm(inProps) {
263
275
  delete error[`${name}Error`];
264
276
  setError(error);
265
277
  }
266
- }, [error]);
278
+ setGenericError(null);
279
+ }, [error, setGenericError]);
267
280
  const handleChangeDateTime = (0, react_1.useCallback)((value, name) => {
268
281
  setField((prev) => (Object.assign(Object.assign({}, prev), { [name]: value })));
269
282
  if (error[`${name}Error`]) {
@@ -274,7 +287,8 @@ function EventForm(inProps) {
274
287
  delete error['endDateError'];
275
288
  setError(error);
276
289
  }
277
- }, [error]);
290
+ setGenericError(null);
291
+ }, [error, setGenericError]);
278
292
  const shouldDisabledDate = (0, react_1.useCallback)((date) => {
279
293
  let disabled = false;
280
294
  switch (field.recurring) {
@@ -350,11 +364,12 @@ function EventForm(inProps) {
350
364
  b: (chunks) => (0, jsx_runtime_1.jsx)("strong", { children: chunks })
351
365
  } })) }))] }))), (0, jsx_runtime_1.jsx)(material_1.TextField, { multiline: true, className: classes.description, placeholder: `${intl.formatMessage(messages.description)}`, margin: "normal", value: field.description, name: "description", onChange: handleChange, InputProps: {
352
366
  endAdornment: ((0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body2" }, { children: ((_b = field.description) === null || _b === void 0 ? void 0 : _b.length) ? Event_1.EVENT_DESCRIPTION_MAX_LENGTH - field.description.length : Event_1.EVENT_DESCRIPTION_MAX_LENGTH })))
353
- }, error: Boolean(((_c = field.description) === null || _c === void 0 ? void 0 : _c.length) > Event_1.EVENT_DESCRIPTION_MAX_LENGTH), helperText: ((_d = field.description) === null || _d === void 0 ? void 0 : _d.length) > Event_1.EVENT_DESCRIPTION_MAX_LENGTH ? ((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.eventForm.description.error.maxLength", defaultMessage: "ui.eventForm.description.error.maxLength" })) : null }), (0, jsx_runtime_1.jsx)(material_1.Box, Object.assign({ className: classes.actions }, { children: (0, jsx_runtime_1.jsx)(lab_1.LoadingButton, Object.assign({ loading: field.isSubmitting, disabled: !field.name ||
367
+ }, error: Boolean(((_c = field.description) === null || _c === void 0 ? void 0 : _c.length) > Event_1.EVENT_DESCRIPTION_MAX_LENGTH), helperText: ((_d = field.description) === null || _d === void 0 ? void 0 : _d.length) > Event_1.EVENT_DESCRIPTION_MAX_LENGTH ? ((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.eventForm.description.error.maxLength", defaultMessage: "ui.eventForm.description.error.maxLength" })) : null }), genericError && ((0, jsx_runtime_1.jsx)(material_1.Box, Object.assign({ className: classes.genericError }, { children: (0, jsx_runtime_1.jsx)(material_1.Alert, Object.assign({ variant: "filled", severity: "error" }, { children: genericError })) }))), (0, jsx_runtime_1.jsx)(material_1.Box, Object.assign({ className: classes.actions }, { children: (0, jsx_runtime_1.jsx)(lab_1.LoadingButton, Object.assign({ loading: field.isSubmitting, disabled: !field.name ||
354
368
  !field.startDate ||
355
369
  !field.startTime ||
356
370
  !field.endDate ||
357
371
  !field.endTime ||
372
+ Boolean(genericError) ||
358
373
  (field.location === types_1.SCEventLocationType.ONLINE && !field.link) ||
359
374
  (field.location === types_1.SCEventLocationType.PERSON && !field.geolocation) ||
360
375
  (field.recurring !== types_1.SCEventRecurrenceType.NEVER && !field.endDate && !field.endTime) ||
@@ -26,7 +26,8 @@ const classes = {
26
26
  description: `${constants_1.PREFIX}-description`,
27
27
  content: `${constants_1.PREFIX}-content`,
28
28
  actions: `${constants_1.PREFIX}-actions`,
29
- error: `${constants_1.PREFIX}-error`
29
+ error: `${constants_1.PREFIX}-error`,
30
+ genericError: `${constants_1.PREFIX}-generic-error`
30
31
  };
31
32
  const Root = (0, styles_1.styled)(material_1.Box, {
32
33
  name: constants_1.PREFIX,
@@ -96,6 +97,7 @@ function LiveStreamForm(inProps) {
96
97
  // STATE
97
98
  const [field, setField] = (0, react_1.useState)(initialFieldState);
98
99
  const [error, setError] = (0, react_1.useState)({});
100
+ const [genericError, setGenericError] = (0, react_1.useState)(null);
99
101
  // PREFERENCES
100
102
  const scPreferences = (0, react_core_1.useSCPreferences)();
101
103
  const _backgroundCover = Object.assign({}, (field.cover
@@ -115,6 +117,7 @@ function LiveStreamForm(inProps) {
115
117
  }, [error]);
116
118
  const handleSubmit = (0, react_1.useCallback)(() => {
117
119
  setField((prev) => (Object.assign(Object.assign({}, prev), { ['isSubmitting']: true })));
120
+ setGenericError(null);
118
121
  const formData = new FormData();
119
122
  if (field.coverFile) {
120
123
  formData.append('cover', field.coverFile);
@@ -141,11 +144,21 @@ function LiveStreamForm(inProps) {
141
144
  const _error = (0, api_services_1.formatHttpErrorCode)(e);
142
145
  // eslint-disable-next-line @typescript-eslint/ban-ts-ignore,@typescript-eslint/ban-ts-comment
143
146
  // @ts-ignore
144
- if (Object.values(_error)[0].error === 'unique') {
145
- setError(Object.assign(Object.assign({}, error), { ['titleError']: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.liveStreamForm.title.error.unique", defaultMessage: "ui.liveStreamForm.title.error.unique" }), ['slugError']: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.liveStreamForm.slug.error.unique", defaultMessage: "ui.liveStreamForm.slug.error.unique" }) }));
147
+ console.log(_error);
148
+ if ('errorsError' in _error) {
149
+ setGenericError(intl.formatMessage({
150
+ id: 'ui.liveStreamForm.error.monthlyMinuteLimitReached',
151
+ defaultMessage: 'ui.liveStreamForm.error.monthlyMinuteLimitReached'
152
+ }));
146
153
  }
147
154
  else {
148
- setError(Object.assign(Object.assign({}, error), _error));
155
+ setGenericError(null);
156
+ }
157
+ if ('titleError' in Object.values(_error)) {
158
+ setError(Object.assign(Object.assign({}, error), { ['titleError']: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.liveStreamForm.title.error.invalid", defaultMessage: "ui.liveStreamForm.title.error.invalid" }) }));
159
+ }
160
+ if ('slugError' in Object.values(_error)) {
161
+ setError(Object.assign(Object.assign({}, error), { ['slugError']: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.liveStreamForm.slug.error.invalid", defaultMessage: "ui.liveStreamForm.slug.error.invalid" }) }));
149
162
  }
150
163
  setField((prev) => (Object.assign(Object.assign({}, prev), { ['isSubmitting']: false })));
151
164
  utils_1.Logger.error(Errors_1.SCOPE_SC_UI, e);
@@ -159,7 +172,8 @@ function LiveStreamForm(inProps) {
159
172
  delete error[`${name}Error`];
160
173
  setError(error);
161
174
  }
162
- }, [error]);
175
+ setGenericError(null);
176
+ }, [error, setGenericError]);
163
177
  const handleChangeSettings = (0, react_1.useCallback)((data) => {
164
178
  setField((prev) => (Object.assign(Object.assign({}, prev), { settings: data })));
165
179
  }, [setField]);
@@ -172,8 +186,9 @@ function LiveStreamForm(inProps) {
172
186
  endAdornment: (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body2" }, { children: LiveStream_1.LIVE_STREAM_SLUG_MAX_LENGTH - field.title.length }))
173
187
  }, error: Boolean(field.slug.length > LiveStream_1.LIVE_STREAM_SLUG_MAX_LENGTH) || Boolean(error['slugError']), helperText: field.title.length > LiveStream_1.LIVE_STREAM_SLUG_MAX_LENGTH ? ((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.liveStreamForm.slug.error.maxLength", defaultMessage: "ui.liveStreamForm.slug.error.maxLength" })) : error['slugError'] ? (error['slugError']) : null }), (0, jsx_runtime_1.jsx)(material_1.TextField, { multiline: true, rows: 4, className: classes.description, placeholder: `${intl.formatMessage(messages.description)}`, margin: "normal", value: field.description, name: "description", onChange: handleChange, InputProps: {
174
188
  endAdornment: ((0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body2" }, { children: ((_a = field.description) === null || _a === void 0 ? void 0 : _a.length) ? LiveStream_1.LIVE_STREAM_DESCRIPTION_MAX_LENGTH - field.description.length : LiveStream_1.LIVE_STREAM_DESCRIPTION_MAX_LENGTH })))
175
- }, error: Boolean(((_b = field.description) === null || _b === void 0 ? void 0 : _b.length) > LiveStream_1.LIVE_STREAM_DESCRIPTION_MAX_LENGTH), helperText: ((_c = field.description) === null || _c === void 0 ? void 0 : _c.length) > LiveStream_1.LIVE_STREAM_DESCRIPTION_MAX_LENGTH ? ((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.liveStreamForm.description.error.maxLength", defaultMessage: "ui.liveStreamForm.description.error.maxLength" })) : null }), (0, jsx_runtime_1.jsx)(LiveStreamFormSettings_1.default, { settings: field.settings, onChange: handleChangeSettings }), (0, jsx_runtime_1.jsx)(material_1.Box, Object.assign({ className: classes.actions }, { children: (0, jsx_runtime_1.jsx)(lab_1.LoadingButton, Object.assign({ loading: field.isSubmitting, disabled: !field.title ||
189
+ }, error: Boolean(((_b = field.description) === null || _b === void 0 ? void 0 : _b.length) > LiveStream_1.LIVE_STREAM_DESCRIPTION_MAX_LENGTH), helperText: ((_c = field.description) === null || _c === void 0 ? void 0 : _c.length) > LiveStream_1.LIVE_STREAM_DESCRIPTION_MAX_LENGTH ? ((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.liveStreamForm.description.error.maxLength", defaultMessage: "ui.liveStreamForm.description.error.maxLength" })) : null }), (0, jsx_runtime_1.jsx)(LiveStreamFormSettings_1.default, { settings: field.settings, onChange: handleChangeSettings }), genericError && ((0, jsx_runtime_1.jsx)(material_1.Box, Object.assign({ className: classes.genericError }, { children: (0, jsx_runtime_1.jsx)(material_1.Alert, Object.assign({ variant: "filled", severity: "error" }, { children: genericError })) }))), (0, jsx_runtime_1.jsx)(material_1.Box, Object.assign({ className: classes.actions }, { children: (0, jsx_runtime_1.jsx)(lab_1.LoadingButton, Object.assign({ loading: field.isSubmitting, disabled: !field.title ||
176
190
  Object.keys(error).length !== 0 ||
191
+ Boolean(genericError) ||
177
192
  field.title.length > LiveStream_1.LIVE_STREAM_TITLE_MAX_LENGTH ||
178
193
  field.description.length > LiveStream_1.LIVE_STREAM_DESCRIPTION_MAX_LENGTH, variant: "contained", onClick: handleSubmit, color: "secondary" }, { children: liveStream ? ((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.liveStreamForm.button.edit", defaultMessage: "ui.liveStreamForm.button.edit" })) : ((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.liveStreamForm.button.create", defaultMessage: "ui.liveStreamForm.button.create" })) })) }))] }))] })));
179
194
  }
@@ -44,13 +44,14 @@ function LiveStreamNotification(props) {
44
44
  // CONST
45
45
  const isSnippetTemplate = template === types_1.SCNotificationObjectTemplateType.SNIPPET;
46
46
  const isToastTemplate = template === types_1.SCNotificationObjectTemplateType.TOAST;
47
+ const inProgress = Boolean(!notificationObject.live_stream.closed_at_by_host && (notificationObject.live_stream.last_started_at && !notificationObject.live_stream.last_finished_at));
47
48
  // RENDER
48
49
  if (isSnippetTemplate) {
49
- return ((0, jsx_runtime_1.jsx)(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, image: (0, jsx_runtime_1.jsx)(react_core_1.Link, Object.assign({}, (!notificationObject.user.deleted && {
50
- to: scRoutingContext.url(react_core_1.SCRoutes.USER_PROFILE_ROUTE_NAME, notificationObject.user)
51
- }), { onClick: notificationObject.user.deleted ? () => setOpenAlert(true) : null }, { children: (0, jsx_runtime_1.jsx)(UserAvatar_1.default, Object.assign({ hide: !notificationObject.user.community_badge, smaller: true }, { children: (0, jsx_runtime_1.jsx)(material_1.Avatar, { alt: notificationObject.user.username, variant: "circular", src: notificationObject.user.avatar, classes: { root: classes.avatar } }) })) })), primary: (0, jsx_runtime_1.jsxs)(material_1.Box, { children: [(0, jsx_runtime_1.jsx)(react_core_1.Link, Object.assign({}, (!notificationObject.user.deleted && {
52
- to: scRoutingContext.url(react_core_1.SCRoutes.USER_PROFILE_ROUTE_NAME, notificationObject.user)
53
- }), { onClick: notificationObject.user.deleted ? () => setOpenAlert(true) : null, className: classes.username }, { children: notificationObject.user.username })), ' ', (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: `ui.notification.${notificationObject.type}.title`, defaultMessage: `ui.notification.${notificationObject.type}.title`, values: {
50
+ return ((0, jsx_runtime_1.jsx)(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, image: (0, jsx_runtime_1.jsx)(react_core_1.Link, Object.assign({}, (!notificationObject.live_stream.host.deleted && {
51
+ to: scRoutingContext.url(react_core_1.SCRoutes.USER_PROFILE_ROUTE_NAME, notificationObject.live_stream.host)
52
+ }), { onClick: notificationObject.live_stream.host.deleted ? () => setOpenAlert(true) : null }, { children: (0, jsx_runtime_1.jsx)(UserAvatar_1.default, Object.assign({ hide: !notificationObject.live_stream.host.community_badge, smaller: true }, { children: (0, jsx_runtime_1.jsx)(material_1.Avatar, { alt: notificationObject.live_stream.host.username, variant: "circular", src: notificationObject.live_stream.host.avatar, classes: { root: classes.avatar } }) })) })), primary: (0, jsx_runtime_1.jsxs)(material_1.Box, { children: [(0, jsx_runtime_1.jsx)(react_core_1.Link, Object.assign({}, (!notificationObject.live_stream.host.deleted && {
53
+ to: scRoutingContext.url(react_core_1.SCRoutes.USER_PROFILE_ROUTE_NAME, notificationObject.live_stream.host)
54
+ }), { onClick: notificationObject.live_stream.host.deleted ? () => setOpenAlert(true) : null, className: classes.username }, { children: notificationObject.live_stream.host.username })), ' ', (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: `ui.notification.${notificationObject.type}.title`, defaultMessage: `ui.notification.${notificationObject.type}.title`, values: {
54
55
  // eslint-disable-next-line @typescript-eslint/ban-ts-ignore
55
56
  // @ts-ignore
56
57
  icon: (...chunks) => (0, jsx_runtime_1.jsx)(material_1.Icon, { children: chunks }),
@@ -58,15 +59,15 @@ function LiveStreamNotification(props) {
58
59
  link: (...chunks) => (0, jsx_runtime_1.jsx)(react_core_1.Link, Object.assign({ to: scRoutingContext.url(react_core_1.SCRoutes.LIVESTREAM_ROUTE_NAME, notificationObject.live_stream) }, { children: chunks }))
59
60
  } })] }), footer: isToastTemplate ? ((0, jsx_runtime_1.jsxs)(material_1.Stack, Object.assign({ direction: "row", justifyContent: "space-between", alignItems: "center", spacing: 2 }, { children: [(0, jsx_runtime_1.jsx)(DateTimeAgo_1.default, { date: notificationObject.active_at }), (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ color: "primary" }, { children: (0, jsx_runtime_1.jsx)(react_core_1.Link, Object.assign({ to: scRoutingContext.url(react_core_1.SCRoutes.LIVESTREAM_ROUTE_NAME, notificationObject.live_stream) }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.notification.live_stream_started.join", defaultMessage: "ui.notification.live_stream_started.join" }) })) }))] }))) : ((0, jsx_runtime_1.jsx)(DateTimeAgo_1.default, { date: notificationObject.active_at, className: classes.snippetTime })) }, rest)));
60
61
  }
61
- return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(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, image: (0, jsx_runtime_1.jsx)(react_core_1.Link, Object.assign({}, (!notificationObject.user.deleted && {
62
- to: scRoutingContext.url(react_core_1.SCRoutes.USER_PROFILE_ROUTE_NAME, notificationObject.user)
63
- }), { onClick: notificationObject.user.deleted ? () => setOpenAlert(true) : null }, { children: (0, jsx_runtime_1.jsx)(UserAvatar_1.default, Object.assign({ hide: !notificationObject.user.community_badge, smaller: true }, { children: (0, jsx_runtime_1.jsx)(material_1.Avatar, { className: classes.avatar, alt: notificationObject.user.username, variant: "circular", src: notificationObject.user.avatar }) })) })), primary: (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(react_core_1.Link, Object.assign({}, (!notificationObject.user.deleted && {
64
- to: scRoutingContext.url(react_core_1.SCRoutes.USER_PROFILE_ROUTE_NAME, notificationObject.user)
65
- }), { onClick: notificationObject.user.deleted ? () => setOpenAlert(true) : null, className: classes.username }, { children: notificationObject.user.username })), ' ', (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: `ui.notification.${notificationObject.type}`, defaultMessage: `ui.notification.${notificationObject.type}`, values: {
62
+ return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(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, image: (0, jsx_runtime_1.jsx)(react_core_1.Link, Object.assign({}, (!notificationObject.live_stream.host.deleted && {
63
+ to: scRoutingContext.url(react_core_1.SCRoutes.USER_PROFILE_ROUTE_NAME, notificationObject.live_stream.host)
64
+ }), { onClick: notificationObject.live_stream.host.deleted ? () => setOpenAlert(true) : null }, { children: (0, jsx_runtime_1.jsx)(UserAvatar_1.default, Object.assign({ hide: !notificationObject.live_stream.host.community_badge, smaller: true }, { children: (0, jsx_runtime_1.jsx)(material_1.Avatar, { className: classes.avatar, alt: notificationObject.live_stream.host.username, variant: "circular", src: notificationObject.live_stream.host.avatar }) })) })), primary: (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(react_core_1.Link, Object.assign({}, (!notificationObject.live_stream.host.deleted && {
65
+ to: scRoutingContext.url(react_core_1.SCRoutes.USER_PROFILE_ROUTE_NAME, notificationObject.live_stream.host)
66
+ }), { onClick: notificationObject.live_stream.host.deleted ? () => setOpenAlert(true) : null, className: classes.username }, { children: notificationObject.live_stream.host.username })), ' ', (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: `ui.notification.${notificationObject.type}`, defaultMessage: `ui.notification.${notificationObject.type}`, values: {
66
67
  // eslint-disable-next-line @typescript-eslint/ban-ts-ignore
67
68
  // @ts-ignore
68
69
  live: notificationObject.live_stream.title,
69
70
  link: (...chunks) => (0, jsx_runtime_1.jsx)(react_core_1.Link, Object.assign({ to: scRoutingContext.url(react_core_1.SCRoutes.LIVESTREAM_ROUTE_NAME, notificationObject.live_stream) }, { children: chunks }))
70
- } }), (0, jsx_runtime_1.jsx)(LiveStream_1.default, { liveStream: notificationObject.live_stream, actions: (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, {}), elevation: 0 })] }), actions: (0, jsx_runtime_1.jsxs)(material_1.Stack, Object.assign({ direction: "row", justifyContent: "space-between", alignItems: "center", spacing: 2 }, { children: [(0, jsx_runtime_1.jsx)(DateTimeAgo_1.default, { date: notificationObject.active_at, className: classes.activeAt }), (0, jsx_runtime_1.jsx)(lab_1.LoadingButton, Object.assign({ color: 'primary', variant: "outlined", size: "small", classes: { root: classes.seeButton }, component: react_core_1.Link, disabled: Boolean(notificationObject.live_stream.closed_at_by_host), to: scRoutingContext.url(react_core_1.SCRoutes.LIVESTREAM_ROUTE_NAME, notificationObject.live_stream) }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.notification.live_stream_started.join", defaultMessage: "ui.notification.live_stream_started.join" }) }))] })) }, rest)), openAlert && (0, jsx_runtime_1.jsx)(UserDeletedSnackBar_1.default, { open: openAlert, handleClose: () => setOpenAlert(false) })] }));
71
+ } }), (0, jsx_runtime_1.jsx)(LiveStream_1.default, { liveStream: notificationObject.live_stream, hideInProgress: !inProgress, actions: (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, {}), elevation: 0 })] }), actions: (0, jsx_runtime_1.jsxs)(material_1.Stack, Object.assign({ direction: "row", justifyContent: "space-between", alignItems: "center", spacing: 2 }, { children: [(0, jsx_runtime_1.jsx)(DateTimeAgo_1.default, { date: notificationObject.active_at, className: classes.activeAt }), (0, jsx_runtime_1.jsx)(lab_1.LoadingButton, Object.assign({ color: 'primary', variant: "outlined", size: "small", classes: { root: classes.seeButton }, component: react_core_1.Link, disabled: Boolean(notificationObject.live_stream.closed_at_by_host), to: scRoutingContext.url(react_core_1.SCRoutes.LIVESTREAM_ROUTE_NAME, notificationObject.live_stream) }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.notification.live_stream_started.join", defaultMessage: "ui.notification.live_stream_started.join" }) }))] })) }, rest)), openAlert && (0, jsx_runtime_1.jsx)(UserDeletedSnackBar_1.default, { open: openAlert, handleClose: () => setOpenAlert(false) })] }));
71
72
  }
72
73
  exports.default = LiveStreamNotification;
@@ -3,3 +3,7 @@ export declare const HUB_STAGE = "https://hub.stage.quentrix.com/";
3
3
  export declare const HUB_PROD = "https://hub.selfcommunity.com/";
4
4
  export declare const CONTACT_STAGE = "https://hub.stage.quentrix.com/dashboard/account/contact-us";
5
5
  export declare const CONTACT_PROD = "https://hub.selfcommunity.com/dashboard/account/contact-us";
6
+ export declare const SELFCOMMUNITY_PRICING: {
7
+ en: string;
8
+ it: string;
9
+ };
@@ -1,8 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.CONTACT_PROD = exports.CONTACT_STAGE = exports.HUB_PROD = exports.HUB_STAGE = exports.PREFIX = void 0;
3
+ exports.SELFCOMMUNITY_PRICING = exports.CONTACT_PROD = exports.CONTACT_STAGE = exports.HUB_PROD = exports.HUB_STAGE = exports.PREFIX = void 0;
4
4
  exports.PREFIX = 'SCPlatformWidget';
5
5
  exports.HUB_STAGE = 'https://hub.stage.quentrix.com/';
6
6
  exports.HUB_PROD = 'https://hub.selfcommunity.com/';
7
7
  exports.CONTACT_STAGE = 'https://hub.stage.quentrix.com/dashboard/account/contact-us';
8
8
  exports.CONTACT_PROD = 'https://hub.selfcommunity.com/dashboard/account/contact-us';
9
+ exports.SELFCOMMUNITY_PRICING = {
10
+ en: 'https://selfcommunity.com/community-software-pricing/',
11
+ it: 'https://selfcommunity.com/it/community-software-prezzi/'
12
+ };
@@ -23,6 +23,6 @@ const Root = (0, system_1.styled)(Widget_1.default, {
23
23
  overridesResolver: (_props, styles) => styles.skeletonRoot
24
24
  })(() => ({}));
25
25
  function UserLiveStreamWidgetSkeleton() {
26
- return ((0, jsx_runtime_1.jsxs)(Root, Object.assign({ className: classes.root }, { children: [(0, jsx_runtime_1.jsx)(material_1.CardContent, Object.assign({ className: classes.content }, { children: (0, jsx_runtime_1.jsx)(material_1.Stack, Object.assign({ className: classes.liveWrapper }, { children: [1, 2, 3, 4].map((_event, i, array) => ((0, jsx_runtime_1.jsxs)(react_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(Event_1.EventSkeleton, { elevation: 0, className: classes.event }), i < array.length - 1 && (0, jsx_runtime_1.jsx)(material_1.Divider, {})] }, i))) })) })), (0, jsx_runtime_1.jsx)(material_1.CardActions, Object.assign({ className: classes.actions }, { children: (0, jsx_runtime_1.jsx)(material_1.Skeleton, { animation: "wave", width: "52px", height: "20px" }) }))] })));
26
+ return ((0, jsx_runtime_1.jsxs)(Root, Object.assign({ className: classes.root }, { children: [(0, jsx_runtime_1.jsx)(material_1.CardContent, Object.assign({ className: classes.content }, { children: (0, jsx_runtime_1.jsx)(material_1.Stack, Object.assign({ className: classes.liveWrapper }, { children: [1, 2].map((_event, i, array) => ((0, jsx_runtime_1.jsxs)(react_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(Event_1.EventSkeleton, { elevation: 0, className: classes.event }), i < array.length - 1 && (0, jsx_runtime_1.jsx)(material_1.Divider, {})] }, i))) })) })), (0, jsx_runtime_1.jsx)(material_1.CardActions, Object.assign({ className: classes.actions }, { children: (0, jsx_runtime_1.jsx)(material_1.Skeleton, { animation: "wave", width: "52px", height: "20px" }) }))] })));
27
27
  }
28
28
  exports.default = UserLiveStreamWidgetSkeleton;
@@ -6,6 +6,7 @@ const material_1 = require("@mui/material");
6
6
  const system_1 = require("@mui/system");
7
7
  const api_services_1 = require("@selfcommunity/api-services");
8
8
  const react_core_1 = require("@selfcommunity/react-core");
9
+ const types_1 = require("@selfcommunity/types");
9
10
  const utils_1 = require("@selfcommunity/utils");
10
11
  const react_1 = require("react");
11
12
  const react_intl_1 = require("react-intl");
@@ -75,7 +76,10 @@ function UserLiveStreamWidget(inProps) {
75
76
  // MEMO
76
77
  const liveStreamEnabled = (0, react_1.useMemo)(() => react_core_1.SCPreferences.CONFIGURATIONS_LIVE_STREAM_ENABLED in scPreferencesContext.preferences &&
77
78
  scPreferencesContext.preferences[react_core_1.SCPreferences.CONFIGURATIONS_LIVE_STREAM_ENABLED].value, [scPreferencesContext.preferences]);
78
- console.log(liveStreamEnabled);
79
+ const isFreeTrialTier = (0, react_1.useMemo)(() => scPreferencesContext.preferences &&
80
+ react_core_1.SCPreferences.CONFIGURATIONS_SUBSCRIPTION_TIER in scPreferencesContext.preferences &&
81
+ scPreferencesContext.preferences[react_core_1.SCPreferences.CONFIGURATIONS_SUBSCRIPTION_TIER].value &&
82
+ scPreferencesContext.preferences[react_core_1.SCPreferences.CONFIGURATIONS_SUBSCRIPTION_TIER].value === types_1.SCCommunitySubscriptionTier.FREE_TRIAL, [scPreferencesContext.preferences]);
79
83
  const _initComponent = (0, react_1.useCallback)(() => {
80
84
  if (!state.initialized && !state.isLoadingNext) {
81
85
  dispatch({ type: widget_1.actionWidgetTypes.LOADING_NEXT });
@@ -121,7 +125,7 @@ function UserLiveStreamWidget(inProps) {
121
125
  return (0, jsx_runtime_1.jsx)(Skeleton_1.default, {});
122
126
  }
123
127
  // RENDER
124
- if (!scUser.user || (state === null || state === void 0 ? void 0 : state.count) === 0 || !liveStreamEnabled) {
128
+ if (!scUser.user || (state === null || state === void 0 ? void 0 : state.count) === 0 || !liveStreamEnabled || isFreeTrialTier) {
125
129
  return (0, jsx_runtime_1.jsx)(HiddenPlaceholder_1.default, {});
126
130
  }
127
131
  return ((0, jsx_runtime_1.jsxs)(Root, Object.assign({ className: classes.root }, rest, { children: [(0, jsx_runtime_1.jsxs)(material_1.CardContent, Object.assign({ className: classes.content }, { children: [(0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "h4" }, { children: (0, jsx_runtime_1.jsx)("b", { children: intl.formatMessage(messages.title, { user: scUser.username }) }) })), (0, jsx_runtime_1.jsx)(material_1.Stack, Object.assign({ className: classes.liveWrapper }, { children: state === null || state === void 0 ? void 0 : state.results.map((_live, i, array) => ((0, jsx_runtime_1.jsxs)(react_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(LiveStream_1.default, Object.assign({ liveStream: _live }, liveStreamComponentProps, { className: classes.live })), i < array.length - 1 && (0, jsx_runtime_1.jsx)(material_1.Divider, {})] }, i))) }))] })), state.count > state.visibleItems && ((0, jsx_runtime_1.jsx)(material_1.CardActions, Object.assign({ className: classes.actions }, { children: (0, jsx_runtime_1.jsx)(material_1.Button, Object.assign({ onClick: handleToggleDialogOpen, className: classes.actionButton }, { children: (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "caption" }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.userLiveStreamWidget.showAll", defaultMessage: "ui.userLiveStreamWidget.showAll" }) })) })) }))), openDialog && ((0, jsx_runtime_1.jsx)(DialogRoot, Object.assign({ className: classes.dialogRoot, title: intl.formatMessage(messages.title, { user: scUser.username }), onClose: handleToggleDialogOpen, open: openDialog }, dialogProps, { children: (0, jsx_runtime_1.jsx)(InfiniteScroll_1.default, Object.assign({ dataLength: state.results.length, next: handleNext, hasMoreNext: Boolean(state.next), loaderNext: (0, jsx_runtime_1.jsx)(LiveStream_1.LiveStreamSkeleton, Object.assign({ elevation: 0 }, liveStreamComponentProps)), className: classes.infiniteScroll, endMessage: (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ className: classes.endMessage }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.userLiveStreamWidget.noMoreResults", defaultMessage: "ui.userLiveStreamWidget.noMoreResults" }) })) }, { children: (0, jsx_runtime_1.jsx)(material_1.List, { children: state.results.map((live) => ((0, jsx_runtime_1.jsx)(material_1.ListItem, { children: (0, jsx_runtime_1.jsx)(LiveStream_1.default, Object.assign({ elevation: 0, liveStream: live }, liveStreamComponentProps)) }, live.id))) }) })) })))] })));
@@ -1,3 +1,3 @@
1
- export declare const LIVE_STREAM_TITLE_MAX_LENGTH = 50;
1
+ export declare const LIVE_STREAM_TITLE_MAX_LENGTH = 100;
2
2
  export declare const LIVE_STREAM_SLUG_MAX_LENGTH = 50;
3
3
  export declare const LIVE_STREAM_DESCRIPTION_MAX_LENGTH = 500;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.LIVE_STREAM_DESCRIPTION_MAX_LENGTH = exports.LIVE_STREAM_SLUG_MAX_LENGTH = exports.LIVE_STREAM_TITLE_MAX_LENGTH = void 0;
4
- exports.LIVE_STREAM_TITLE_MAX_LENGTH = 50;
4
+ exports.LIVE_STREAM_TITLE_MAX_LENGTH = 100;
5
5
  exports.LIVE_STREAM_SLUG_MAX_LENGTH = 50;
6
6
  exports.LIVE_STREAM_DESCRIPTION_MAX_LENGTH = 500;
@@ -3,10 +3,11 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { Button, Icon } from '@mui/material';
4
4
  import { styled } from '@mui/material/styles';
5
5
  import { useThemeProps } from '@mui/system';
6
- import { SCUserContext } from '@selfcommunity/react-core';
6
+ import { SCPreferences, SCUserContext, UserUtils, useSCPreferences } from '@selfcommunity/react-core';
7
7
  import classNames from 'classnames';
8
8
  import React, { useContext, useMemo } from 'react';
9
9
  import { FormattedMessage } from 'react-intl';
10
+ import { SCCommunitySubscriptionTier } from '@selfcommunity/types';
10
11
  import CreateLivestreamDialog from '../CreateLiveStreamDialog';
11
12
  const PREFIX = 'SCCreateLivestreamButton';
12
13
  const classes = {
@@ -37,7 +38,6 @@ const Root = styled(Button, {
37
38
  * @param inProps
38
39
  */
39
40
  export default function CreateLiveStreamButton(inProps) {
40
- var _a;
41
41
  //PROPS
42
42
  const props = useThemeProps({
43
43
  props: inProps,
@@ -46,11 +46,22 @@ export default function CreateLiveStreamButton(inProps) {
46
46
  const { className, CreateLiveStreamDialogComponentProps = {}, onSuccess, children } = props, rest = __rest(props, ["className", "CreateLiveStreamDialogComponentProps", "onSuccess", "children"]);
47
47
  // CONTEXT
48
48
  const scUserContext = useContext(SCUserContext);
49
+ const { preferences, features } = useSCPreferences();
49
50
  // STATE
50
51
  const [open, setOpen] = React.useState(false);
51
52
  // CONST
52
- const authUserId = scUserContext.user ? scUserContext.user.id : null;
53
- const canCreateLiveStream = useMemo(() => { var _a, _b; return (_b = (_a = scUserContext === null || scUserContext === void 0 ? void 0 : scUserContext.user) === null || _a === void 0 ? void 0 : _a.permission) === null || _b === void 0 ? void 0 : _b.create_live_stream; }, [(_a = scUserContext === null || scUserContext === void 0 ? void 0 : scUserContext.user) === null || _a === void 0 ? void 0 : _a.permission]);
53
+ const authUserId = useMemo(() => (scUserContext.user ? scUserContext.user.id : null), [scUserContext.user]);
54
+ const isStaff = useMemo(() => scUserContext.user && UserUtils.isStaff(scUserContext.user), [scUserContext.user]);
55
+ const isCommunityOwner = useMemo(() => authUserId === 1, [authUserId]);
56
+ const isFreeTrialTier = useMemo(() => preferences &&
57
+ SCPreferences.CONFIGURATIONS_SUBSCRIPTION_TIER in preferences &&
58
+ preferences[SCPreferences.CONFIGURATIONS_SUBSCRIPTION_TIER].value &&
59
+ preferences[SCPreferences.CONFIGURATIONS_SUBSCRIPTION_TIER].value === SCCommunitySubscriptionTier.FREE_TRIAL, [preferences]);
60
+ const liveStreamEnabled = useMemo(() => preferences &&
61
+ features &&
62
+ SCPreferences.CONFIGURATIONS_LIVE_STREAM_ENABLED in preferences &&
63
+ preferences[SCPreferences.CONFIGURATIONS_LIVE_STREAM_ENABLED].value, [preferences, features]);
64
+ const onlyStaffEnabled = useMemo(() => preferences[SCPreferences.CONFIGURATIONS_LIVE_STREAM_ONLY_STAFF_ENABLED].value, [preferences]);
54
65
  /**
55
66
  * Handle close
56
67
  */
@@ -67,7 +78,7 @@ export default function CreateLiveStreamButton(inProps) {
67
78
  /**
68
79
  * If there's no authUserId, component is hidden.
69
80
  */
70
- if (!canCreateLiveStream || !authUserId) {
81
+ if (!liveStreamEnabled || !authUserId || (onlyStaffEnabled && !isStaff) || (isFreeTrialTier && !isCommunityOwner)) {
71
82
  return null;
72
83
  }
73
84
  /**