@selfcommunity/react-core 0.4.55 → 0.5.0-alpha.0

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 (76) hide show
  1. package/lib/cjs/components/provider/SCAlertMessagesProvider/index.js +3 -4
  2. package/lib/cjs/components/provider/SCContextProvider/index.js +6 -5
  3. package/lib/cjs/components/provider/SCLocaleProvider/index.js +4 -6
  4. package/lib/cjs/components/provider/SCNotificationProvider/index.js +3 -2
  5. package/lib/cjs/components/provider/SCPreferencesProvider/index.js +18 -3
  6. package/lib/cjs/components/provider/SCRoutingProvider/index.js +3 -2
  7. package/lib/cjs/components/provider/SCThemeProvider/index.js +4 -5
  8. package/lib/cjs/components/provider/SCUserProvider/index.js +9 -2
  9. package/lib/cjs/components/provider/SCVoteProvider/index.js +3 -3
  10. package/lib/cjs/components/router/index.js +3 -2
  11. package/lib/cjs/constants/Cache.d.ts +11 -0
  12. package/lib/cjs/constants/Cache.js +15 -2
  13. package/lib/cjs/constants/Integrations.d.ts +5 -0
  14. package/lib/cjs/constants/Integrations.js +6 -1
  15. package/lib/cjs/constants/Preferences.d.ts +3 -0
  16. package/lib/cjs/constants/Preferences.js +8 -2
  17. package/lib/cjs/constants/Routes.d.ts +5 -0
  18. package/lib/cjs/constants/Routes.js +11 -1
  19. package/lib/cjs/hooks/useSCFetchEvent.d.ts +22 -0
  20. package/lib/cjs/hooks/useSCFetchEvent.js +87 -0
  21. package/lib/cjs/hooks/useSCFetchEvents.d.ts +22 -0
  22. package/lib/cjs/hooks/useSCFetchEvents.js +83 -0
  23. package/lib/cjs/hooks/useSCSubscribedEventsManager.d.ts +38 -0
  24. package/lib/cjs/hooks/useSCSubscribedEventsManager.js +297 -0
  25. package/lib/cjs/hooks/useSCWebPushMessaging.js +3 -4
  26. package/lib/cjs/index.d.ts +8 -3
  27. package/lib/cjs/index.js +13 -3
  28. package/lib/cjs/types/context.d.ts +71 -2
  29. package/lib/cjs/types/index.d.ts +2 -2
  30. package/lib/cjs/utils/errors.d.ts +2 -0
  31. package/lib/cjs/utils/errors.js +4 -0
  32. package/lib/cjs/utils/event.d.ts +8 -0
  33. package/lib/cjs/utils/event.js +29 -0
  34. package/lib/cjs/utils/user.d.ts +7 -0
  35. package/lib/cjs/utils/user.js +11 -1
  36. package/lib/cjs/utils/validator.d.ts +30 -1
  37. package/lib/cjs/utils/validator.js +52 -1
  38. package/lib/esm/components/provider/SCAlertMessagesProvider/index.js +3 -3
  39. package/lib/esm/components/provider/SCContextProvider/index.js +6 -5
  40. package/lib/esm/components/provider/SCLocaleProvider/index.js +4 -5
  41. package/lib/esm/components/provider/SCNotificationProvider/index.js +3 -2
  42. package/lib/esm/components/provider/SCPreferencesProvider/index.js +18 -2
  43. package/lib/esm/components/provider/SCRoutingProvider/index.js +3 -2
  44. package/lib/esm/components/provider/SCThemeProvider/index.js +4 -5
  45. package/lib/esm/components/provider/SCUserProvider/index.js +9 -2
  46. package/lib/esm/components/provider/SCVoteProvider/index.js +3 -2
  47. package/lib/esm/components/router/index.js +3 -2
  48. package/lib/esm/constants/Cache.d.ts +11 -0
  49. package/lib/esm/constants/Cache.js +11 -0
  50. package/lib/esm/constants/Integrations.d.ts +5 -0
  51. package/lib/esm/constants/Integrations.js +5 -0
  52. package/lib/esm/constants/Preferences.d.ts +3 -0
  53. package/lib/esm/constants/Preferences.js +6 -0
  54. package/lib/esm/constants/Routes.d.ts +5 -0
  55. package/lib/esm/constants/Routes.js +10 -0
  56. package/lib/esm/hooks/useSCFetchEvent.d.ts +22 -0
  57. package/lib/esm/hooks/useSCFetchEvent.js +84 -0
  58. package/lib/esm/hooks/useSCFetchEvents.d.ts +22 -0
  59. package/lib/esm/hooks/useSCFetchEvents.js +81 -0
  60. package/lib/esm/hooks/useSCSubscribedEventsManager.d.ts +38 -0
  61. package/lib/esm/hooks/useSCSubscribedEventsManager.js +293 -0
  62. package/lib/esm/hooks/useSCWebPushMessaging.js +3 -4
  63. package/lib/esm/index.d.ts +8 -3
  64. package/lib/esm/index.js +7 -2
  65. package/lib/esm/types/context.d.ts +71 -2
  66. package/lib/esm/types/index.d.ts +2 -2
  67. package/lib/esm/utils/errors.d.ts +2 -0
  68. package/lib/esm/utils/errors.js +4 -0
  69. package/lib/esm/utils/event.d.ts +8 -0
  70. package/lib/esm/utils/event.js +25 -0
  71. package/lib/esm/utils/user.d.ts +7 -0
  72. package/lib/esm/utils/user.js +9 -0
  73. package/lib/esm/utils/validator.d.ts +30 -1
  74. package/lib/esm/utils/validator.js +49 -0
  75. package/lib/umd/react-core.js +1 -1
  76. package/package.json +6 -6
@@ -0,0 +1,22 @@
1
+ import { SCEventType } from '@selfcommunity/types';
2
+ import { CacheStrategies } from '@selfcommunity/utils';
3
+ /**
4
+ :::info
5
+ This custom hook is used to fetch events.
6
+ @param object.cacheStrategy
7
+
8
+ :::tip Context can be consumed in this way:
9
+
10
+ ```jsx
11
+ const {events, isLoading} = useSCFetchEvents();
12
+ ```
13
+ :::
14
+ * @param props
15
+ */
16
+ declare const useSCFetchEvents: (props?: {
17
+ cacheStrategy?: CacheStrategies;
18
+ }) => {
19
+ events: SCEventType[];
20
+ isLoading: boolean;
21
+ };
22
+ export default useSCFetchEvents;
@@ -0,0 +1,83 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ const react_1 = require("react");
5
+ const Errors_1 = require("../constants/Errors");
6
+ const api_services_1 = require("@selfcommunity/api-services");
7
+ const utils_1 = require("@selfcommunity/utils");
8
+ const Cache_1 = require("../constants/Cache");
9
+ const init = { events: [], isLoading: true };
10
+ // HYDRATE the cache
11
+ const hydrate = (ids) => {
12
+ if (!ids) {
13
+ return null;
14
+ }
15
+ const events = ids.map((id) => {
16
+ const __eventCacheKey = (0, Cache_1.getEventObjectCacheKey)(id);
17
+ return utils_1.LRUCache.get(__eventCacheKey);
18
+ });
19
+ if (events.filter((c) => !c).length > 0) {
20
+ // REVALIDATE CACHE
21
+ return null;
22
+ }
23
+ return events;
24
+ };
25
+ /**
26
+ :::info
27
+ This custom hook is used to fetch events.
28
+ @param object.cacheStrategy
29
+
30
+ :::tip Context can be consumed in this way:
31
+
32
+ ```jsx
33
+ const {events, isLoading} = useSCFetchEvents();
34
+ ```
35
+ :::
36
+ * @param props
37
+ */
38
+ const useSCFetchEvents = (props) => {
39
+ // PROPS
40
+ const { cacheStrategy = utils_1.CacheStrategies.CACHE_FIRST } = props || {};
41
+ // CACHE
42
+ const __eventsCacheKey = (0, Cache_1.getEventsObjectCacheKey)();
43
+ // STATE
44
+ const events = cacheStrategy !== utils_1.CacheStrategies.NETWORK_ONLY ? hydrate(utils_1.LRUCache.get(__eventsCacheKey, null)) : null;
45
+ const [data, setData] = (0, react_1.useState)(events !== null ? { events, isLoading: false } : init);
46
+ /**
47
+ * Fetch events
48
+ */
49
+ const fetchEvents = (next = api_services_1.Endpoints.GetUserEvents.url()) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
50
+ const response = yield api_services_1.http.request({
51
+ url: next,
52
+ method: api_services_1.Endpoints.GetUserEvents.method,
53
+ });
54
+ const data = response.data;
55
+ if (data.next) {
56
+ return data.results.concat(yield fetchEvents(data.next));
57
+ }
58
+ return data.results;
59
+ });
60
+ /**
61
+ * Get events
62
+ */
63
+ (0, react_1.useEffect)(() => {
64
+ if (cacheStrategy === utils_1.CacheStrategies.CACHE_FIRST && events) {
65
+ return;
66
+ }
67
+ fetchEvents()
68
+ .then((data) => {
69
+ setData({ events: data, isLoading: false });
70
+ utils_1.LRUCache.set(__eventsCacheKey, data.map((event) => {
71
+ const __eventCacheKey = (0, Cache_1.getEventObjectCacheKey)(event.id);
72
+ utils_1.LRUCache.set(__eventCacheKey, event);
73
+ return event.id;
74
+ }));
75
+ })
76
+ .catch((error) => {
77
+ console.log(error);
78
+ utils_1.Logger.error(Errors_1.SCOPE_SC_CORE, 'Unable to retrieve events');
79
+ });
80
+ }, []);
81
+ return data;
82
+ };
83
+ exports.default = useSCFetchEvents;
@@ -0,0 +1,38 @@
1
+ import { SCEventType, SCUserType } from '@selfcommunity/types';
2
+ /**
3
+ :::info
4
+ This custom hook is used to manage the events followed.
5
+ :::
6
+
7
+ :::tip How to use it:
8
+ Follow these steps:
9
+ ```jsx
10
+ 1. const scUserContext: SCUserContextType = useSCUser();
11
+ 2. const scSubscribedEventsManager: SCSubscribedEventsManagerType = scUserContext.manager.events;
12
+ 3. scSubscribedEventsManager.isSubscribed(event)
13
+ ```
14
+ :::
15
+ */
16
+ export default function useSCSubscribedEventsManager(user?: SCUserType): {
17
+ events: any[];
18
+ loading: any[];
19
+ isLoading: (v: number | {
20
+ id: number;
21
+ }) => boolean;
22
+ toggleEventAttendance?: undefined;
23
+ toggleEventNonattendance?: undefined;
24
+ subscriptionStatus?: undefined;
25
+ refresh?: undefined;
26
+ emptyCache?: undefined;
27
+ } | {
28
+ events: any[];
29
+ loading: any[];
30
+ isLoading: (v: number | {
31
+ id: number;
32
+ }) => boolean;
33
+ toggleEventAttendance: (event: SCEventType, userId?: number) => Promise<any>;
34
+ toggleEventNonattendance: (event: SCEventType) => Promise<any>;
35
+ subscriptionStatus: (event?: SCEventType) => string;
36
+ refresh: () => void;
37
+ emptyCache: () => void;
38
+ };
@@ -0,0 +1,297 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ const api_services_1 = require("@selfcommunity/api-services");
5
+ const types_1 = require("@selfcommunity/types");
6
+ const utils_1 = require("@selfcommunity/utils");
7
+ const pubsub_js_1 = tslib_1.__importDefault(require("pubsub-js"));
8
+ const react_1 = require("react");
9
+ const use_deep_compare_effect_1 = require("use-deep-compare-effect");
10
+ const SCPreferencesProvider_1 = require("../components/provider/SCPreferencesProvider");
11
+ const Errors_1 = require("../constants/Errors");
12
+ const Notification_1 = require("../constants/Notification");
13
+ const useSCCachingManager_1 = tslib_1.__importDefault(require("./useSCCachingManager"));
14
+ const event_1 = require("../utils/event");
15
+ /**
16
+ :::info
17
+ This custom hook is used to manage the events followed.
18
+ :::
19
+
20
+ :::tip How to use it:
21
+ Follow these steps:
22
+ ```jsx
23
+ 1. const scUserContext: SCUserContextType = useSCUser();
24
+ 2. const scSubscribedEventsManager: SCSubscribedEventsManagerType = scUserContext.manager.events;
25
+ 3. scSubscribedEventsManager.isSubscribed(event)
26
+ ```
27
+ :::
28
+ */
29
+ function useSCSubscribedEventsManager(user) {
30
+ const { cache, updateCache, emptyCache, data, setData, loading, setLoading, setUnLoading, isLoading } = (0, useSCCachingManager_1.default)();
31
+ const { features } = (0, SCPreferencesProvider_1.useSCPreferences)();
32
+ const authUserId = user ? user.id : null;
33
+ const eventsEnabled = (0, react_1.useMemo)(() => features && features.includes(types_1.SCFeatureName.EVENT) && features.includes(types_1.SCFeatureName.TAGGING), [features]);
34
+ const notificationInvitedToJoinEvent = (0, react_1.useRef)(null);
35
+ const notificationRequestedToJoinEvent = (0, react_1.useRef)(null);
36
+ const notificationAcceptedToJoinEvent = (0, react_1.useRef)(null);
37
+ const notificationAddedToEvent = (0, react_1.useRef)(null);
38
+ /**
39
+ * Subscribe to notification types user_follow, user_unfollow
40
+ */
41
+ (0, use_deep_compare_effect_1.useDeepCompareEffectNoCheck)(() => {
42
+ notificationInvitedToJoinEvent.current = pubsub_js_1.default.subscribe(`${types_1.SCNotificationTopicType.INTERACTION}.${types_1.SCNotificationTypologyType.USER_INVITED_TO_JOIN_EVENT}`, notificationSubscriber);
43
+ notificationRequestedToJoinEvent.current = pubsub_js_1.default.subscribe(`${types_1.SCNotificationTopicType.INTERACTION}.${types_1.SCNotificationTypologyType.USER_REQUESTED_TO_JOIN_EVENT}`, notificationSubscriber);
44
+ notificationAcceptedToJoinEvent.current = pubsub_js_1.default.subscribe(`${types_1.SCNotificationTopicType.INTERACTION}.${types_1.SCNotificationTypologyType.USER_ACCEPTED_TO_JOIN_EVENT}`, notificationSubscriber);
45
+ notificationAddedToEvent.current = pubsub_js_1.default.subscribe(`${types_1.SCNotificationTopicType.INTERACTION}.${types_1.SCNotificationTypologyType.USER_ADDED_TO_EVENT}`, notificationSubscriber);
46
+ return () => {
47
+ pubsub_js_1.default.unsubscribe(notificationInvitedToJoinEvent.current);
48
+ pubsub_js_1.default.unsubscribe(notificationRequestedToJoinEvent.current);
49
+ pubsub_js_1.default.unsubscribe(notificationAcceptedToJoinEvent.current);
50
+ pubsub_js_1.default.unsubscribe(notificationAddedToEvent.current);
51
+ };
52
+ }, [data]);
53
+ /**
54
+ * Notification subscriber handler
55
+ * @param msg
56
+ * @param dataMsg
57
+ */
58
+ const notificationSubscriber = (msg, dataMsg) => {
59
+ if (dataMsg.data.event !== undefined) {
60
+ let _status;
61
+ switch (Notification_1.SCNotificationMapping[dataMsg.data.activity_type]) {
62
+ case types_1.SCNotificationTypologyType.USER_INVITED_TO_JOIN_EVENT:
63
+ _status = types_1.SCEventSubscriptionStatusType.INVITED;
64
+ break;
65
+ case types_1.SCNotificationTypologyType.USER_REQUESTED_TO_JOIN_EVENT:
66
+ _status = types_1.SCEventSubscriptionStatusType.REQUESTED;
67
+ break;
68
+ case types_1.SCNotificationTypologyType.USER_ACCEPTED_TO_JOIN_EVENT:
69
+ _status = types_1.SCEventSubscriptionStatusType.SUBSCRIBED;
70
+ break;
71
+ case types_1.SCNotificationTypologyType.USER_ADDED_TO_EVENT:
72
+ _status = types_1.SCEventSubscriptionStatusType.SUBSCRIBED;
73
+ break;
74
+ }
75
+ updateCache([dataMsg.data.event.id]);
76
+ setData((prev) => getDataUpdated(prev, dataMsg.data.event.id, _status));
77
+ }
78
+ };
79
+ /**
80
+ * Memoized refresh all events
81
+ * It makes a single request to the server and retrieves
82
+ * all the events followed by the user in a single solution
83
+ * It might be useful for multi-tab sync
84
+ */
85
+ const refresh = (0, react_1.useMemo)(() => () => {
86
+ emptyCache();
87
+ if (user) {
88
+ // Only if user is authenticated
89
+ api_services_1.http
90
+ .request({
91
+ url: api_services_1.Endpoints.GetUserEvents.url(),
92
+ method: api_services_1.Endpoints.GetUserEvents.method,
93
+ })
94
+ .then((res) => {
95
+ if (res.status >= 300) {
96
+ return Promise.reject(res);
97
+ }
98
+ const eventsIds = res.data.results.map((e) => e.id);
99
+ updateCache(eventsIds);
100
+ setData(res.data.results.map((e) => ({ [e.id]: e.subscription_status })));
101
+ return Promise.resolve(res.data);
102
+ })
103
+ .catch((e) => {
104
+ utils_1.Logger.error(Errors_1.SCOPE_SC_CORE, 'Unable to refresh the authenticated user events.');
105
+ utils_1.Logger.error(Errors_1.SCOPE_SC_CORE, e);
106
+ });
107
+ }
108
+ }, [data, user, cache]);
109
+ /**
110
+ * Memoized toggleEventAttendance Event
111
+ * Toggle action
112
+ */
113
+ const toggleEventAttendance = (0, react_1.useMemo)(() => (event, userId) => {
114
+ setLoading(event.id);
115
+ if (userId) {
116
+ return api_services_1.http
117
+ .request({
118
+ url: api_services_1.Endpoints.InviteOrAcceptEventRequest.url({ id: event.id }),
119
+ method: api_services_1.Endpoints.InviteOrAcceptEventRequest.method,
120
+ data: { users: [userId] },
121
+ })
122
+ .then((res) => {
123
+ if (res.status >= 300) {
124
+ return Promise.reject(res);
125
+ }
126
+ updateCache([event.id]);
127
+ setData((prev) => getDataUpdated(prev, event.id, types_1.SCEventSubscriptionStatusType.SUBSCRIBED));
128
+ setUnLoading(event.id);
129
+ return Promise.resolve(res.data);
130
+ });
131
+ }
132
+ else {
133
+ const requestConfig = !event.subscription_status || event.subscription_status === types_1.SCEventSubscriptionStatusType.INVITED
134
+ ? {
135
+ url: api_services_1.Endpoints.SubscribeToEvent.url({ id: event.id }),
136
+ method: api_services_1.Endpoints.SubscribeToEvent.method,
137
+ }
138
+ : event.subscription_status === types_1.SCEventSubscriptionStatusType.GOING
139
+ ? {
140
+ url: api_services_1.Endpoints.RemoveGoingToEvent.url({ id: event.id }),
141
+ method: api_services_1.Endpoints.RemoveGoingToEvent.method,
142
+ }
143
+ : {
144
+ url: api_services_1.Endpoints.GoToEvent.url({ id: event.id }),
145
+ method: api_services_1.Endpoints.GoToEvent.method,
146
+ };
147
+ return api_services_1.http.request(requestConfig).then((res) => {
148
+ if (res.status >= 300) {
149
+ return Promise.reject(res);
150
+ }
151
+ updateCache([event.id]);
152
+ setData((prev) => getDataUpdated(prev, event.id, (0, event_1.getEventStatus)(event, true)));
153
+ setUnLoading(event.id);
154
+ return Promise.resolve(res.data);
155
+ });
156
+ }
157
+ }, [data, loading, cache]);
158
+ /**
159
+ * Memoized toggleEventNonattendance Event
160
+ * Toggle action
161
+ */
162
+ const toggleEventNonattendance = (0, react_1.useMemo)(() => (event) => {
163
+ if (event.subscription_status !== types_1.SCEventSubscriptionStatusType.REQUESTED) {
164
+ setLoading(event.id);
165
+ const requestConfig = event.subscription_status === types_1.SCEventSubscriptionStatusType.NOT_GOING
166
+ ? {
167
+ url: api_services_1.Endpoints.RemoveNotGoingToEvent.url({ id: event.id }),
168
+ method: api_services_1.Endpoints.RemoveNotGoingToEvent.method,
169
+ }
170
+ : {
171
+ url: api_services_1.Endpoints.NotGoingToEvent.url({ id: event.id }),
172
+ method: api_services_1.Endpoints.NotGoingToEvent.method,
173
+ };
174
+ return api_services_1.http.request(requestConfig).then((res) => {
175
+ if (res.status >= 300) {
176
+ return Promise.reject(res);
177
+ }
178
+ updateCache([event.id]);
179
+ setData((prev) => getDataUpdated(prev, event.id, (0, event_1.getEventStatus)(event, false)));
180
+ setUnLoading(event.id);
181
+ return Promise.resolve(res.data);
182
+ });
183
+ }
184
+ else {
185
+ setLoading(event.id);
186
+ return api_services_1.http
187
+ .request({ url: api_services_1.Endpoints.UnsubscribeFromEvent.url({ id: event.id }), method: api_services_1.Endpoints.UnsubscribeFromEvent.method })
188
+ .then((res) => {
189
+ if (res.status >= 300) {
190
+ return Promise.reject(res);
191
+ }
192
+ updateCache([event.id]);
193
+ setData((prev) => getDataUpdated(prev, event.id, null));
194
+ setUnLoading(event.id);
195
+ return Promise.resolve(res.data);
196
+ });
197
+ }
198
+ }, [data, loading, cache]);
199
+ /**
200
+ * Check the authenticated user subscription status to the event
201
+ * Update the events cached
202
+ * Update events subscription statuses
203
+ * @param event
204
+ */
205
+ const checkEventSubscriptionStatus = (event) => {
206
+ setLoading(event.id);
207
+ return api_services_1.http
208
+ .request({
209
+ url: api_services_1.Endpoints.GetEventSubscriptionStatus.url({ id: event.id }),
210
+ method: api_services_1.Endpoints.GetEventSubscriptionStatus.method,
211
+ })
212
+ .then((res) => {
213
+ if (res.status >= 300) {
214
+ return Promise.reject(res);
215
+ }
216
+ setData((prev) => getDataUpdated(prev, event.id, res.data.status));
217
+ updateCache([event.id]);
218
+ setUnLoading(event.id);
219
+ return Promise.resolve(res.data);
220
+ })
221
+ .catch((e) => {
222
+ setUnLoading(event.id);
223
+ return Promise.reject(e);
224
+ });
225
+ };
226
+ /**
227
+ * Get updated data
228
+ * @param data
229
+ * @param eventId
230
+ * @param subscriptionStatus
231
+ */
232
+ const getDataUpdated = (data, eventId, subscriptionStatus) => {
233
+ const _index = data.findIndex((k) => parseInt(Object.keys(k)[0]) === eventId);
234
+ let _data;
235
+ if (_index < 0) {
236
+ _data = [...data, ...[{ [eventId]: subscriptionStatus }]];
237
+ }
238
+ else {
239
+ _data = data.map((k, i) => {
240
+ if (parseInt(Object.keys(k)[0]) === eventId) {
241
+ return { [Object.keys(k)[0]]: subscriptionStatus };
242
+ }
243
+ return { [Object.keys(k)[0]]: data[i][Object.keys(k)[0]] };
244
+ });
245
+ }
246
+ return _data;
247
+ };
248
+ /**
249
+ * Return current event subscription status if exists,
250
+ * otherwise return null
251
+ */
252
+ const getCurrentEventCacheStatus = (0, react_1.useMemo)(() => (event) => {
253
+ const d = data.filter((k) => parseInt(Object.keys(k)[0]) === event.id);
254
+ return d.length ? d[0][event.id] : !data.length ? event.subscription_status : null;
255
+ }, [data]);
256
+ /**
257
+ * Bypass remote check if the event is subscribed
258
+ */
259
+ const getSubscriptionStatus = (0, react_1.useMemo)(() => (event) => {
260
+ updateCache([event.id]);
261
+ setData((prev) => getDataUpdated(prev, event.id, event.subscription_status));
262
+ return event.subscription_status;
263
+ }, [data, cache]);
264
+ /**
265
+ * Memoized subscriptionStatus
266
+ * If event is already in cache -> check if the event is in events,
267
+ * otherwise, check if user toggleEventAttendance the event
268
+ */
269
+ const subscriptionStatus = (0, react_1.useMemo)(() => (event) => {
270
+ // Cache is valid also for anonymous user
271
+ if (cache.includes(event === null || event === void 0 ? void 0 : event.id)) {
272
+ return getCurrentEventCacheStatus(event);
273
+ }
274
+ if (authUserId && event) {
275
+ if ('subscription_status' in event) {
276
+ return getSubscriptionStatus(event);
277
+ }
278
+ if (!isLoading(event)) {
279
+ checkEventSubscriptionStatus(event);
280
+ }
281
+ }
282
+ return null;
283
+ }, [loading, cache, authUserId]);
284
+ /**
285
+ * Empty cache on logout
286
+ */
287
+ (0, react_1.useEffect)(() => {
288
+ if (!authUserId) {
289
+ emptyCache();
290
+ }
291
+ }, [authUserId]);
292
+ if (!eventsEnabled || !user) {
293
+ return { events: data, loading, isLoading };
294
+ }
295
+ return { events: data, loading, isLoading, toggleEventAttendance, toggleEventNonattendance, subscriptionStatus, refresh, emptyCache };
296
+ }
297
+ exports.default = useSCSubscribedEventsManager;
@@ -2,7 +2,8 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.SUPPORTED_BROWSER_TYPES = exports.DEFAULT_BROWSER_TYPE = exports.EDGE_BROWSER_TYPE = exports.OPERA_BROWSER_TYPE = exports.FIREFOX_BROWSER_TYPE = exports.CHROME_BROWSER_TYPE = void 0;
4
4
  const tslib_1 = require("tslib");
5
- const react_1 = tslib_1.__importStar(require("react"));
5
+ const jsx_runtime_1 = require("react/jsx-runtime");
6
+ const react_1 = require("react");
6
7
  const SCContextProvider_1 = require("../components/provider/SCContextProvider");
7
8
  const SCUserProvider_1 = require("../components/provider/SCUserProvider");
8
9
  const utils_1 = require("@selfcommunity/utils");
@@ -60,9 +61,7 @@ function useSCWebPushMessaging() {
60
61
  const showCustomRequestNotificationSnackbar = () => {
61
62
  if (!js_cookie_1.default.get(Notifications_1.NOTIFICATIONS_WEB_PUSH_MESSAGING_DIALOG_COOKIE)) {
62
63
  enqueueSnackbar(intl.formatMessage({ id: 'ui.webPushNotification.requestPermission', defaultMessage: 'ui.webPushNotification.requestPermission' }), {
63
- action: (snackbarId) => (react_1.default.createElement(react_1.default.Fragment, null,
64
- react_1.default.createElement(Button_1.default, { size: "small", sx: { color: '#FFF' }, onClick: () => requestNotificationPermission(snackbarId) }, intl.formatMessage({ id: 'ui.webPushNotification.allow', defaultMessage: 'ui.webPushNotification.allow' })),
65
- react_1.default.createElement(Button_1.default, { size: "small", sx: { color: '#FFF' }, onClick: () => closeRequestNotificationSnackbar(snackbarId) }, intl.formatMessage({ id: 'ui.webPushNotification.block', defaultMessage: 'ui.webPushNotification.block' })))),
64
+ action: (snackbarId) => ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(Button_1.default, Object.assign({ size: "small", sx: { color: '#FFF' }, onClick: () => requestNotificationPermission(snackbarId) }, { children: intl.formatMessage({ id: 'ui.webPushNotification.allow', defaultMessage: 'ui.webPushNotification.allow' }) })), (0, jsx_runtime_1.jsx)(Button_1.default, Object.assign({ size: "small", sx: { color: '#FFF' }, onClick: () => closeRequestNotificationSnackbar(snackbarId) }, { children: intl.formatMessage({ id: 'ui.webPushNotification.block', defaultMessage: 'ui.webPushNotification.block' }) }))] })),
66
65
  variant: 'default',
67
66
  anchorOrigin: { horizontal: 'center', vertical: 'bottom' },
68
67
  preventDuplicate: true,
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Types
3
3
  */
4
- import { SCUserContextType, SCFollowedCategoriesManagerType, SCContextProviderType, SCContextType, SCSettingsType, SCSessionType, SCFollowedManagerType, SCFollowersManagerType, SCSettingsManagerType, SCConnectionsManagerType, SCSubscribedIncubatorsManagerType, SCLocaleType, SCNotificationContextType, SCPreferencesContextType, SCThemeContextType, SCRoutingContextType, SCLocaleContextType, SCAlertMessagesContextType, SCThemeAvatarVariableType, SCThemeCategoryIconVariableType, SCThemeCategoryVariableType, SCThemeVariablesType, SCThemeType, SCSubscribedGroupsManagerType } from './types';
4
+ import { SCUserContextType, SCFollowedCategoriesManagerType, SCContextProviderType, SCContextType, SCSettingsType, SCSessionType, SCFollowedManagerType, SCFollowersManagerType, SCSettingsManagerType, SCConnectionsManagerType, SCSubscribedIncubatorsManagerType, SCLocaleType, SCNotificationContextType, SCPreferencesContextType, SCThemeContextType, SCRoutingContextType, SCLocaleContextType, SCAlertMessagesContextType, SCThemeAvatarVariableType, SCThemeCategoryIconVariableType, SCThemeCategoryVariableType, SCThemeVariablesType, SCThemeType, SCSubscribedGroupsManagerType, SCSubscribedEventsManagerType } from './types';
5
5
  /**
6
6
  * ContextProvider component
7
7
  */
@@ -62,6 +62,8 @@ import useSCFetchUserBlockedBy from './hooks/useSCFetchUserBlockedBy';
62
62
  import useSCUserIsBlocked from './hooks/useSCUserIsBlocked';
63
63
  import useSCFetchGroup from './hooks/useSCFetchGroup';
64
64
  import useSCFetchGroups from './hooks/useSCFetchGroups';
65
+ import useSCFetchEvent from './hooks/useSCFetchEvent';
66
+ import useSCFetchEvents from './hooks/useSCFetchEvents';
65
67
  /**
66
68
  * Routing component
67
69
  */
@@ -72,13 +74,16 @@ import * as SCRoutes from './constants/Routes';
72
74
  * User, hooks (useIsComponentMountedRef)
73
75
  */
74
76
  import * as UserUtils from './utils/user';
77
+ import getTheme from './themes/theme';
75
78
  import { useIsComponentMountedRef, usePreviousValue, useIsomorphicLayoutEffect, useEffectOnce, useNoInitialEffect } from './utils/hooks';
79
+ import { getEventStatus } from './utils/event';
76
80
  /**
77
81
  * Constants:
78
- * Locale
82
+ * Locale, Preferences
79
83
  */
80
84
  import * as Locale from './constants/Locale';
85
+ import * as Preferences from './constants/Preferences';
81
86
  /**
82
87
  * List all exports
83
88
  */
84
- export { SCUserContextType, SCFollowedCategoriesManagerType, SCContextProviderType, SCContextType, SCSettingsType, SCSessionType, SCSettingsManagerType, SCFollowedManagerType, SCFollowersManagerType, SCConnectionsManagerType, SCSubscribedIncubatorsManagerType, SCLocaleType, SCNotificationContextType, SCPreferencesContextType, SCThemeContextType, SCRoutingContextType, SCLocaleContextType, SCAlertMessagesContextType, SCThemeAvatarVariableType, SCThemeCategoryIconVariableType, SCThemeCategoryVariableType, SCThemeVariablesType, SCThemeType, SCSubscribedGroupsManagerType, SCContext, SCUserContext, SCThemeContext, SCRoutingContext, SCLocaleContext, SCPreferencesContext, useSCContext, SCContextProvider, SCUserProvider, useSCUser, useSCPreferences, SCThemeProvider, useSCTheme, withSCTheme, SCRoutingProvider, useSCRouting, SCLocaleProvider, useSCLocale, withSCLocale, SCPreferencesProvider, SCPreferences, SCFeatures, SCNotification, SCNotificationProvider, SCNotificationContext, useSCNotification, SCAlertMessagesProvider, SCAlertMessagesContext, useSCAlertMessages, Link, SCRoutes, SCCache, UserUtils, Locale, useSCFetchUser, useSCFetchUserProviders, useSCFetchVote, useSCFetchFeedObject, useSCFetchCommentObject, useSCFetchCommentObjects, useSCFetchCustomAdv, useSCFetchTag, useSCFetchAddressingTagList, useSCFetchCategory, useSCFetchCategories, useSCFetchIncubator, useSCMediaClick, useSCFetchContributors, useSCFetchFeed, useIsComponentMountedRef, usePreviousValue, useIsomorphicLayoutEffect, useEffectOnce, useNoInitialEffect, useSCFetchPrivateMessageSnippets, useSCFetchBroadcastMessages, useSCFetchUserBlockedBy, useSCUserIsBlocked, useSCFetchGroup, useSCFetchGroups, };
89
+ export { SCUserContextType, SCFollowedCategoriesManagerType, SCContextProviderType, SCContextType, SCSettingsType, SCSessionType, SCSettingsManagerType, SCFollowedManagerType, SCFollowersManagerType, SCConnectionsManagerType, SCSubscribedIncubatorsManagerType, SCLocaleType, SCNotificationContextType, SCPreferencesContextType, SCThemeContextType, SCRoutingContextType, SCLocaleContextType, SCAlertMessagesContextType, SCThemeAvatarVariableType, SCThemeCategoryIconVariableType, SCThemeCategoryVariableType, SCThemeVariablesType, SCThemeType, SCSubscribedGroupsManagerType, SCSubscribedEventsManagerType, SCContext, SCUserContext, SCThemeContext, SCRoutingContext, SCLocaleContext, SCPreferencesContext, useSCContext, SCContextProvider, SCUserProvider, useSCUser, useSCPreferences, SCThemeProvider, useSCTheme, withSCTheme, getTheme, SCRoutingProvider, useSCRouting, SCLocaleProvider, useSCLocale, withSCLocale, SCPreferencesProvider, SCPreferences, SCFeatures, SCNotification, SCNotificationProvider, SCNotificationContext, useSCNotification, SCAlertMessagesProvider, SCAlertMessagesContext, useSCAlertMessages, Link, SCRoutes, SCCache, UserUtils, getEventStatus, Locale, Preferences, useSCFetchUser, useSCFetchUserProviders, useSCFetchVote, useSCFetchFeedObject, useSCFetchCommentObject, useSCFetchCommentObjects, useSCFetchCustomAdv, useSCFetchTag, useSCFetchAddressingTagList, useSCFetchCategory, useSCFetchCategories, useSCFetchIncubator, useSCMediaClick, useSCFetchContributors, useSCFetchFeed, useIsComponentMountedRef, usePreviousValue, useIsomorphicLayoutEffect, useEffectOnce, useNoInitialEffect, useSCFetchPrivateMessageSnippets, useSCFetchBroadcastMessages, useSCFetchUserBlockedBy, useSCUserIsBlocked, useSCFetchGroup, useSCFetchGroups, useSCFetchEvent, useSCFetchEvents, };
package/lib/cjs/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.useIsComponentMountedRef = exports.useSCFetchFeed = exports.useSCFetchContributors = exports.useSCMediaClick = exports.useSCFetchIncubator = exports.useSCFetchCategories = exports.useSCFetchCategory = exports.useSCFetchAddressingTagList = exports.useSCFetchTag = exports.useSCFetchCustomAdv = exports.useSCFetchCommentObjects = exports.useSCFetchCommentObject = exports.useSCFetchFeedObject = exports.useSCFetchVote = exports.useSCFetchUserProviders = exports.useSCFetchUser = exports.Locale = exports.UserUtils = exports.SCCache = exports.SCRoutes = exports.Link = exports.useSCAlertMessages = exports.SCAlertMessagesContext = exports.SCAlertMessagesProvider = exports.useSCNotification = exports.SCNotificationContext = exports.SCNotificationProvider = exports.SCNotification = exports.SCFeatures = exports.SCPreferences = exports.SCPreferencesProvider = exports.withSCLocale = exports.useSCLocale = exports.SCLocaleProvider = exports.useSCRouting = exports.SCRoutingProvider = exports.withSCTheme = exports.useSCTheme = exports.SCThemeProvider = exports.useSCPreferences = exports.useSCUser = exports.SCUserProvider = exports.SCContextProvider = exports.useSCContext = exports.SCPreferencesContext = exports.SCLocaleContext = exports.SCRoutingContext = exports.SCThemeContext = exports.SCUserContext = exports.SCContext = void 0;
4
- exports.useSCFetchGroups = exports.useSCFetchGroup = exports.useSCUserIsBlocked = exports.useSCFetchUserBlockedBy = exports.useSCFetchBroadcastMessages = exports.useSCFetchPrivateMessageSnippets = exports.useNoInitialEffect = exports.useEffectOnce = exports.useIsomorphicLayoutEffect = exports.usePreviousValue = void 0;
3
+ exports.useSCMediaClick = exports.useSCFetchIncubator = exports.useSCFetchCategories = exports.useSCFetchCategory = exports.useSCFetchAddressingTagList = exports.useSCFetchTag = exports.useSCFetchCustomAdv = exports.useSCFetchCommentObjects = exports.useSCFetchCommentObject = exports.useSCFetchFeedObject = exports.useSCFetchVote = exports.useSCFetchUserProviders = exports.useSCFetchUser = exports.Preferences = exports.Locale = exports.getEventStatus = exports.UserUtils = exports.SCCache = exports.SCRoutes = exports.Link = exports.useSCAlertMessages = exports.SCAlertMessagesContext = exports.SCAlertMessagesProvider = exports.useSCNotification = exports.SCNotificationContext = exports.SCNotificationProvider = exports.SCNotification = exports.SCFeatures = exports.SCPreferences = exports.SCPreferencesProvider = exports.withSCLocale = exports.useSCLocale = exports.SCLocaleProvider = exports.useSCRouting = exports.SCRoutingProvider = exports.getTheme = exports.withSCTheme = exports.useSCTheme = exports.SCThemeProvider = exports.useSCPreferences = exports.useSCUser = exports.SCUserProvider = exports.SCContextProvider = exports.useSCContext = exports.SCPreferencesContext = exports.SCLocaleContext = exports.SCRoutingContext = exports.SCThemeContext = exports.SCUserContext = exports.SCContext = void 0;
4
+ exports.useSCFetchEvents = exports.useSCFetchEvent = exports.useSCFetchGroups = exports.useSCFetchGroup = exports.useSCUserIsBlocked = exports.useSCFetchUserBlockedBy = exports.useSCFetchBroadcastMessages = exports.useSCFetchPrivateMessageSnippets = exports.useNoInitialEffect = exports.useEffectOnce = exports.useIsomorphicLayoutEffect = exports.usePreviousValue = exports.useIsComponentMountedRef = exports.useSCFetchFeed = exports.useSCFetchContributors = void 0;
5
5
  const tslib_1 = require("tslib");
6
6
  /**
7
7
  * ContextProvider component
@@ -114,6 +114,10 @@ const useSCFetchGroup_1 = tslib_1.__importDefault(require("./hooks/useSCFetchGro
114
114
  exports.useSCFetchGroup = useSCFetchGroup_1.default;
115
115
  const useSCFetchGroups_1 = tslib_1.__importDefault(require("./hooks/useSCFetchGroups"));
116
116
  exports.useSCFetchGroups = useSCFetchGroups_1.default;
117
+ const useSCFetchEvent_1 = tslib_1.__importDefault(require("./hooks/useSCFetchEvent"));
118
+ exports.useSCFetchEvent = useSCFetchEvent_1.default;
119
+ const useSCFetchEvents_1 = tslib_1.__importDefault(require("./hooks/useSCFetchEvents"));
120
+ exports.useSCFetchEvents = useSCFetchEvents_1.default;
117
121
  /**
118
122
  * Routing component
119
123
  */
@@ -127,15 +131,21 @@ exports.SCRoutes = SCRoutes;
127
131
  */
128
132
  const UserUtils = tslib_1.__importStar(require("./utils/user"));
129
133
  exports.UserUtils = UserUtils;
134
+ const theme_1 = tslib_1.__importDefault(require("./themes/theme"));
135
+ exports.getTheme = theme_1.default;
130
136
  const hooks_1 = require("./utils/hooks");
131
137
  Object.defineProperty(exports, "useIsComponentMountedRef", { enumerable: true, get: function () { return hooks_1.useIsComponentMountedRef; } });
132
138
  Object.defineProperty(exports, "usePreviousValue", { enumerable: true, get: function () { return hooks_1.usePreviousValue; } });
133
139
  Object.defineProperty(exports, "useIsomorphicLayoutEffect", { enumerable: true, get: function () { return hooks_1.useIsomorphicLayoutEffect; } });
134
140
  Object.defineProperty(exports, "useEffectOnce", { enumerable: true, get: function () { return hooks_1.useEffectOnce; } });
135
141
  Object.defineProperty(exports, "useNoInitialEffect", { enumerable: true, get: function () { return hooks_1.useNoInitialEffect; } });
142
+ const event_1 = require("./utils/event");
143
+ Object.defineProperty(exports, "getEventStatus", { enumerable: true, get: function () { return event_1.getEventStatus; } });
136
144
  /**
137
145
  * Constants:
138
- * Locale
146
+ * Locale, Preferences
139
147
  */
140
148
  const Locale = tslib_1.__importStar(require("./constants/Locale"));
141
149
  exports.Locale = Locale;
150
+ const Preferences = tslib_1.__importStar(require("./constants/Preferences"));
151
+ exports.Preferences = Preferences;
@@ -1,5 +1,5 @@
1
1
  import React, { ReactNode } from 'react';
2
- import { SCAuthTokenType, SCIncubatorType, SCCategoryType, SCUserType, SCUserSettingsType, SCReactionType, SCGroupType } from '@selfcommunity/types';
2
+ import { SCAuthTokenType, SCIncubatorType, SCCategoryType, SCUserType, SCUserSettingsType, SCReactionType, SCGroupType, SCEventType } from '@selfcommunity/types';
3
3
  import { SCThemeType } from './theme';
4
4
  /**
5
5
  * Interface SCSettingsType
@@ -37,6 +37,10 @@ export interface SCSettingsType {
37
37
  * Object conf of notification.
38
38
  */
39
39
  notifications?: SCNotificationsType;
40
+ /**
41
+ * Integrations conf
42
+ */
43
+ integrations?: SCIntegrationsType;
40
44
  /**
41
45
  * Callback to handle anonymous action
42
46
  * Ex. an anonymous user attempt to post a comment
@@ -143,6 +147,7 @@ export interface SCUserContextType {
143
147
  incubators?: SCSubscribedIncubatorsManagerType;
144
148
  blockedUsers?: SCBlockedUsersManagerType;
145
149
  groups?: SCSubscribedGroupsManagerType;
150
+ events?: SCSubscribedEventsManagerType;
146
151
  };
147
152
  }
148
153
  export interface SCSettingsManagerType {
@@ -249,6 +254,44 @@ export interface SCFollowedCategoriesManagerType {
249
254
  */
250
255
  emptyCache?: () => void;
251
256
  }
257
+ export interface SCSubscribedEventsManagerType {
258
+ /**
259
+ * List of all events ids followed by the authenticated user
260
+ */
261
+ events: number[];
262
+ /**
263
+ * List of all events in loading state
264
+ */
265
+ loading: number[];
266
+ /**
267
+ * List of current events in loading state
268
+ */
269
+ isLoading: (event: SCEventType) => boolean;
270
+ /**
271
+ * Handle user subscription to an event
272
+ */
273
+ subscribe?: (event: SCEventType, userId?: number) => Promise<any>;
274
+ /**
275
+ * Handle user going to an event
276
+ */
277
+ toggleEventAttendance?: (event: SCEventType, userId?: number) => Promise<any>;
278
+ /**
279
+ * Handle user not going to an event
280
+ */
281
+ toggleEventNonattendance?: (event: SCEventType, userId?: number) => Promise<any>;
282
+ /**
283
+ * Handles a user subscription status to an event, caching data
284
+ */
285
+ subscriptionStatus?: (event: SCEventType) => string;
286
+ /**
287
+ * Refresh groups
288
+ */
289
+ refresh?: () => void;
290
+ /**
291
+ * Empty cache to revalidate all groups
292
+ */
293
+ emptyCache?: () => void;
294
+ }
252
295
  export interface SCSubscribedGroupsManagerType {
253
296
  /**
254
297
  * List of all groups ids followed by the authenticated user
@@ -444,6 +487,18 @@ export interface SCPreferencesContextType {
444
487
  * List of all community enabled features
445
488
  */
446
489
  features: string[];
490
+ /**
491
+ * Set prefrerences
492
+ */
493
+ setPreferences: (preferences: Record<string, any>) => void;
494
+ /**
495
+ * Set features
496
+ */
497
+ setFeatures: (features: string[]) => void;
498
+ /**
499
+ * Force refresh
500
+ */
501
+ refresh: () => void;
447
502
  }
448
503
  /**
449
504
  * Interface SCVoteContextType
@@ -628,9 +683,13 @@ export interface SCIntegrationsType {
628
683
  * OpenAI
629
684
  */
630
685
  openai?: SCIntegrationsOpenAIType;
686
+ /**
687
+ * Geocoding
688
+ */
689
+ geocoding?: SCGeocodingType;
631
690
  }
632
691
  /**
633
- * Interface SCNotificationsWebSocketType
692
+ * Interface SCIntegrationsOpenAIType
634
693
  */
635
694
  export interface SCIntegrationsOpenAIType {
636
695
  /**
@@ -639,3 +698,13 @@ export interface SCIntegrationsOpenAIType {
639
698
  */
640
699
  secretKey: string | null;
641
700
  }
701
+ /**
702
+ * Interface SCGeocodingType
703
+ */
704
+ export interface SCGeocodingType {
705
+ /**
706
+ * Set secretKey geocoding service
707
+ * Default: null
708
+ */
709
+ apiKey: string | null;
710
+ }