@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
@@ -130,6 +130,9 @@ export const CONFIGURATIONS_CUSTOM_NAVBAR_ITEM_IMAGE = `${SCPreferenceSection.CO
130
130
  export const CONFIGURATIONS_GROUPS_ONLY_STAFF_ENABLED = `${SCPreferenceSection.CONFIGURATIONS}.${SCPreferenceName.GROUPS_ONLY_STAFF_ENABLED}`;
131
131
  export const CONFIGURATIONS_GROUPS_VISIBILITY_ENABLED = `${SCPreferenceSection.CONFIGURATIONS}.${SCPreferenceName.GROUPS_VISIBILITY_ENABLED}`;
132
132
  export const CONFIGURATIONS_GROUPS_PRIVATE_ENABLED = `${SCPreferenceSection.CONFIGURATIONS}.${SCPreferenceName.GROUPS_PRIVATE_ENABLED}`;
133
+ export const CONFIGURATIONS_EVENTS_ONLY_STAFF_ENABLED = `${SCPreferenceSection.CONFIGURATIONS}.${SCPreferenceName.EVENTS_ONLY_STAFF_ENABLED}`;
134
+ export const CONFIGURATIONS_EVENTS_VISIBILITY_ENABLED = `${SCPreferenceSection.CONFIGURATIONS}.${SCPreferenceName.EVENTS_VISIBILITY_ENABLED}`;
135
+ export const CONFIGURATIONS_EVENTS_PRIVATE_ENABLED = `${SCPreferenceSection.CONFIGURATIONS}.${SCPreferenceName.EVENTS_PRIVATE_ENABLED}`;
133
136
  /**
134
137
  * PROVIDERS
135
138
  */
@@ -266,6 +269,9 @@ export const DATA_TYPES = {
266
269
  [CONFIGURATIONS_CUSTOM_NAVBAR_ITEM_TEXT]: stringType,
267
270
  [CONFIGURATIONS_CUSTOM_NAVBAR_ITEM_URL]: stringType,
268
271
  [CONFIGURATIONS_CUSTOM_NAVBAR_ITEM_IMAGE]: stringType,
272
+ [CONFIGURATIONS_EVENTS_ONLY_STAFF_ENABLED]: booleanType,
273
+ [CONFIGURATIONS_EVENTS_VISIBILITY_ENABLED]: booleanType,
274
+ [CONFIGURATIONS_EVENTS_PRIVATE_ENABLED]: booleanType,
269
275
  [CONFIGURATIONS_GROUPS_ONLY_STAFF_ENABLED]: booleanType,
270
276
  [CONFIGURATIONS_GROUPS_VISIBILITY_ENABLED]: booleanType,
271
277
  [CONFIGURATIONS_GROUPS_PRIVATE_ENABLED]: booleanType,
@@ -36,6 +36,11 @@ export declare const GROUP_MEMBERS_ROUTE_NAME = "group_members";
36
36
  export declare const GROUP_MESSAGES_ROUTE_NAME = "group_messages";
37
37
  export declare const GROUPS_ROUTE_NAME = "groups";
38
38
  export declare const GROUPS_SUBSCRIBED_ROUTE_NAME = "groups_subscribed";
39
+ export declare const EVENT_ROUTE_NAME = "event";
40
+ export declare const EVENTS_ROUTE_NAME = "events";
41
+ export declare const EVENTS_SUGGESTED_ROUTE_NAME = "events_suggested";
42
+ export declare const EVENTS_SUBSCRIBED_ROUTE_NAME = "events_subscribed";
43
+ export declare const EVENTS_HIGHLIGHT_ROUTE_NAME = "events_highlight";
39
44
  /**
40
45
  * Default Routes
41
46
  * @type {{[p: string]: string, '[POST_ROUTE_NAME]': string, '[INCUBATOR_ROUTE_NAME]': string, '[LOYALTY_ROUTE_NAME]': string, '[USER_NOTIFICATION_ROUTE_NAME]': string, '[USER_PRIVATE_MESSAGES_ROUTE_NAME]': string, '[COMMENT_ROUTE_NAME]': string, '[DISCUSSION_ROUTE_NAME]': string, '[CATEGORIES_ROUTE_NAME]': string, '[USER_PROFILE_ROUTE_NAME]': string, '[CATEGORY_ROUTE_NAME]': string, '[USER_PROFILE_SETTINGS_ROUTE_NAME]': string, '[STATUS_ROUTE_NAME]': string}}
@@ -36,6 +36,11 @@ export const GROUP_MEMBERS_ROUTE_NAME = 'group_members';
36
36
  export const GROUP_MESSAGES_ROUTE_NAME = 'group_messages';
37
37
  export const GROUPS_ROUTE_NAME = 'groups';
38
38
  export const GROUPS_SUBSCRIBED_ROUTE_NAME = 'groups_subscribed';
39
+ export const EVENT_ROUTE_NAME = 'event';
40
+ export const EVENTS_ROUTE_NAME = 'events';
41
+ export const EVENTS_SUGGESTED_ROUTE_NAME = 'events_suggested';
42
+ export const EVENTS_SUBSCRIBED_ROUTE_NAME = 'events_subscribed';
43
+ export const EVENTS_HIGHLIGHT_ROUTE_NAME = 'events_highlight';
39
44
  /**
40
45
  * Default Routes
41
46
  * @type {{[p: string]: string, '[POST_ROUTE_NAME]': string, '[INCUBATOR_ROUTE_NAME]': string, '[LOYALTY_ROUTE_NAME]': string, '[USER_NOTIFICATION_ROUTE_NAME]': string, '[USER_PRIVATE_MESSAGES_ROUTE_NAME]': string, '[COMMENT_ROUTE_NAME]': string, '[DISCUSSION_ROUTE_NAME]': string, '[CATEGORIES_ROUTE_NAME]': string, '[USER_PROFILE_ROUTE_NAME]': string, '[CATEGORY_ROUTE_NAME]': string, '[USER_PROFILE_SETTINGS_ROUTE_NAME]': string, '[STATUS_ROUTE_NAME]': string}}
@@ -74,4 +79,9 @@ export const defaultRoutes = {
74
79
  [GROUP_MESSAGES_ROUTE_NAME]: '/group/:id/:slug/messages/',
75
80
  [GROUPS_ROUTE_NAME]: '/groups/',
76
81
  [GROUPS_SUBSCRIBED_ROUTE_NAME]: '/groups/subscribed/',
82
+ [EVENTS_ROUTE_NAME]: '/events/',
83
+ [EVENTS_SUGGESTED_ROUTE_NAME]: '/events/suggested',
84
+ [EVENT_ROUTE_NAME]: '/event/:id/:slug/',
85
+ [EVENTS_SUBSCRIBED_ROUTE_NAME]: '/events/subscribed/',
86
+ [EVENTS_HIGHLIGHT_ROUTE_NAME]: '/events/highlight/',
77
87
  };
@@ -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 an event object.
6
+ :::
7
+ * @param object
8
+ * @param object.id
9
+ * @param object.event
10
+ * @param object.autosubscribe
11
+ * @param object.cacheStrategy
12
+ */
13
+ export default function useSCFetchEvent({ id, event, autoSubscribe, cacheStrategy, }: {
14
+ id?: number | string;
15
+ event?: SCEventType;
16
+ autoSubscribe?: boolean;
17
+ cacheStrategy?: CacheStrategies;
18
+ }): {
19
+ scEvent: SCEventType;
20
+ setSCEvent: (event: SCEventType) => void;
21
+ error: string;
22
+ };
@@ -0,0 +1,84 @@
1
+ import { useEffect, useMemo, useState } from 'react';
2
+ import { SCOPE_SC_CORE } from '../constants/Errors';
3
+ import { SCEventPrivacyType, SCEventSubscriptionStatusType } from '@selfcommunity/types';
4
+ import { Endpoints, EventService, http } from '@selfcommunity/api-services';
5
+ import { CacheStrategies, Logger, LRUCache, objectWithoutProperties } from '@selfcommunity/utils';
6
+ import { getEventObjectCacheKey } from '../constants/Cache';
7
+ import { useDeepCompareEffectNoCheck } from 'use-deep-compare-effect';
8
+ import { useSCUser } from '../components/provider/SCUserProvider';
9
+ /**
10
+ :::info
11
+ This custom hook is used to fetch an event object.
12
+ :::
13
+ * @param object
14
+ * @param object.id
15
+ * @param object.event
16
+ * @param object.autosubscribe
17
+ * @param object.cacheStrategy
18
+ */
19
+ export default function useSCFetchEvent({ id = null, event = null, autoSubscribe = true, cacheStrategy = CacheStrategies.CACHE_FIRST, }) {
20
+ const __eventId = event ? event.id : id;
21
+ // CONTEXT
22
+ const scUserContext = useSCUser();
23
+ const authUserId = scUserContext.user ? scUserContext.user.id : null;
24
+ // CACHE
25
+ const __eventCacheKey = getEventObjectCacheKey(__eventId);
26
+ const __event = authUserId ? event : objectWithoutProperties(event, ['subscription_status']);
27
+ const [scEvent, setScEvent] = useState(cacheStrategy !== CacheStrategies.NETWORK_ONLY ? LRUCache.get(__eventCacheKey, __event) : null);
28
+ const [error, setError] = useState(null);
29
+ const setSCEvent = (event) => {
30
+ const _e = authUserId ? event : objectWithoutProperties(event, ['subscription_status']);
31
+ setScEvent(_e);
32
+ LRUCache.set(__eventCacheKey, _e);
33
+ };
34
+ /**
35
+ * Memoized fetchTag
36
+ */
37
+ const fetchEvent = useMemo(() => () => {
38
+ return http
39
+ .request({
40
+ url: Endpoints.GetEventInfo.url({ id: __eventId }),
41
+ method: Endpoints.GetEventInfo.method,
42
+ })
43
+ .then((res) => {
44
+ if (res.status >= 300) {
45
+ return Promise.reject(res);
46
+ }
47
+ return Promise.resolve(res.data);
48
+ });
49
+ }, [__eventId]);
50
+ /**
51
+ * If id attempt to get the event by id
52
+ */
53
+ useEffect(() => {
54
+ if (__eventId && scUserContext.user !== undefined && (!scEvent || (scEvent && __eventId !== scEvent.id))) {
55
+ fetchEvent()
56
+ .then((event) => {
57
+ if (autoSubscribe &&
58
+ authUserId !== null &&
59
+ ((event.privacy === SCEventPrivacyType.PUBLIC && !event.subscription_status) || event.subscription_status === SCEventSubscriptionStatusType.INVITED)) {
60
+ // Auto subscribe to the event
61
+ EventService.subscribeToEvent(event.id).then(() => {
62
+ const updatedEvent = Object.assign(Object.assign({}, event), { subscription_status: SCEventSubscriptionStatusType.SUBSCRIBED });
63
+ setSCEvent(updatedEvent);
64
+ });
65
+ }
66
+ else {
67
+ setSCEvent(event);
68
+ }
69
+ })
70
+ .catch((err) => {
71
+ LRUCache.delete(__eventCacheKey);
72
+ setError(`Event with id ${id} not found`);
73
+ Logger.error(SCOPE_SC_CORE, `Event with id ${id} not found`);
74
+ Logger.error(SCOPE_SC_CORE, err.message);
75
+ });
76
+ }
77
+ }, [__eventId, authUserId, scUserContext.user]);
78
+ useDeepCompareEffectNoCheck(() => {
79
+ if (event) {
80
+ setSCEvent(event);
81
+ }
82
+ }, [event, authUserId]);
83
+ return { scEvent, setSCEvent, error };
84
+ }
@@ -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,81 @@
1
+ import { __awaiter } from "tslib";
2
+ import { useEffect, useState } from 'react';
3
+ import { SCOPE_SC_CORE } from '../constants/Errors';
4
+ import { Endpoints, http } from '@selfcommunity/api-services';
5
+ import { CacheStrategies, Logger, LRUCache } from '@selfcommunity/utils';
6
+ import { getEventObjectCacheKey, getEventsObjectCacheKey } from '../constants/Cache';
7
+ const init = { events: [], isLoading: true };
8
+ // HYDRATE the cache
9
+ const hydrate = (ids) => {
10
+ if (!ids) {
11
+ return null;
12
+ }
13
+ const events = ids.map((id) => {
14
+ const __eventCacheKey = getEventObjectCacheKey(id);
15
+ return LRUCache.get(__eventCacheKey);
16
+ });
17
+ if (events.filter((c) => !c).length > 0) {
18
+ // REVALIDATE CACHE
19
+ return null;
20
+ }
21
+ return events;
22
+ };
23
+ /**
24
+ :::info
25
+ This custom hook is used to fetch events.
26
+ @param object.cacheStrategy
27
+
28
+ :::tip Context can be consumed in this way:
29
+
30
+ ```jsx
31
+ const {events, isLoading} = useSCFetchEvents();
32
+ ```
33
+ :::
34
+ * @param props
35
+ */
36
+ const useSCFetchEvents = (props) => {
37
+ // PROPS
38
+ const { cacheStrategy = CacheStrategies.CACHE_FIRST } = props || {};
39
+ // CACHE
40
+ const __eventsCacheKey = getEventsObjectCacheKey();
41
+ // STATE
42
+ const events = cacheStrategy !== CacheStrategies.NETWORK_ONLY ? hydrate(LRUCache.get(__eventsCacheKey, null)) : null;
43
+ const [data, setData] = useState(events !== null ? { events, isLoading: false } : init);
44
+ /**
45
+ * Fetch events
46
+ */
47
+ const fetchEvents = (next = Endpoints.GetUserEvents.url()) => __awaiter(void 0, void 0, void 0, function* () {
48
+ const response = yield http.request({
49
+ url: next,
50
+ method: Endpoints.GetUserEvents.method,
51
+ });
52
+ const data = response.data;
53
+ if (data.next) {
54
+ return data.results.concat(yield fetchEvents(data.next));
55
+ }
56
+ return data.results;
57
+ });
58
+ /**
59
+ * Get events
60
+ */
61
+ useEffect(() => {
62
+ if (cacheStrategy === CacheStrategies.CACHE_FIRST && events) {
63
+ return;
64
+ }
65
+ fetchEvents()
66
+ .then((data) => {
67
+ setData({ events: data, isLoading: false });
68
+ LRUCache.set(__eventsCacheKey, data.map((event) => {
69
+ const __eventCacheKey = getEventObjectCacheKey(event.id);
70
+ LRUCache.set(__eventCacheKey, event);
71
+ return event.id;
72
+ }));
73
+ })
74
+ .catch((error) => {
75
+ console.log(error);
76
+ Logger.error(SCOPE_SC_CORE, 'Unable to retrieve events');
77
+ });
78
+ }, []);
79
+ return data;
80
+ };
81
+ export 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,293 @@
1
+ import { Endpoints, http } from '@selfcommunity/api-services';
2
+ import { SCEventSubscriptionStatusType, SCFeatureName, SCNotificationTopicType, SCNotificationTypologyType, } from '@selfcommunity/types';
3
+ import { Logger } from '@selfcommunity/utils';
4
+ import PubSub from 'pubsub-js';
5
+ import { useEffect, useMemo, useRef } from 'react';
6
+ import { useDeepCompareEffectNoCheck } from 'use-deep-compare-effect';
7
+ import { useSCPreferences } from '../components/provider/SCPreferencesProvider';
8
+ import { SCOPE_SC_CORE } from '../constants/Errors';
9
+ import { SCNotificationMapping } from '../constants/Notification';
10
+ import useSCCachingManager from './useSCCachingManager';
11
+ import { getEventStatus } from '../utils/event';
12
+ /**
13
+ :::info
14
+ This custom hook is used to manage the events followed.
15
+ :::
16
+
17
+ :::tip How to use it:
18
+ Follow these steps:
19
+ ```jsx
20
+ 1. const scUserContext: SCUserContextType = useSCUser();
21
+ 2. const scSubscribedEventsManager: SCSubscribedEventsManagerType = scUserContext.manager.events;
22
+ 3. scSubscribedEventsManager.isSubscribed(event)
23
+ ```
24
+ :::
25
+ */
26
+ export default function useSCSubscribedEventsManager(user) {
27
+ const { cache, updateCache, emptyCache, data, setData, loading, setLoading, setUnLoading, isLoading } = useSCCachingManager();
28
+ const { features } = useSCPreferences();
29
+ const authUserId = user ? user.id : null;
30
+ const eventsEnabled = useMemo(() => features && features.includes(SCFeatureName.EVENT) && features.includes(SCFeatureName.TAGGING), [features]);
31
+ const notificationInvitedToJoinEvent = useRef(null);
32
+ const notificationRequestedToJoinEvent = useRef(null);
33
+ const notificationAcceptedToJoinEvent = useRef(null);
34
+ const notificationAddedToEvent = useRef(null);
35
+ /**
36
+ * Subscribe to notification types user_follow, user_unfollow
37
+ */
38
+ useDeepCompareEffectNoCheck(() => {
39
+ notificationInvitedToJoinEvent.current = PubSub.subscribe(`${SCNotificationTopicType.INTERACTION}.${SCNotificationTypologyType.USER_INVITED_TO_JOIN_EVENT}`, notificationSubscriber);
40
+ notificationRequestedToJoinEvent.current = PubSub.subscribe(`${SCNotificationTopicType.INTERACTION}.${SCNotificationTypologyType.USER_REQUESTED_TO_JOIN_EVENT}`, notificationSubscriber);
41
+ notificationAcceptedToJoinEvent.current = PubSub.subscribe(`${SCNotificationTopicType.INTERACTION}.${SCNotificationTypologyType.USER_ACCEPTED_TO_JOIN_EVENT}`, notificationSubscriber);
42
+ notificationAddedToEvent.current = PubSub.subscribe(`${SCNotificationTopicType.INTERACTION}.${SCNotificationTypologyType.USER_ADDED_TO_EVENT}`, notificationSubscriber);
43
+ return () => {
44
+ PubSub.unsubscribe(notificationInvitedToJoinEvent.current);
45
+ PubSub.unsubscribe(notificationRequestedToJoinEvent.current);
46
+ PubSub.unsubscribe(notificationAcceptedToJoinEvent.current);
47
+ PubSub.unsubscribe(notificationAddedToEvent.current);
48
+ };
49
+ }, [data]);
50
+ /**
51
+ * Notification subscriber handler
52
+ * @param msg
53
+ * @param dataMsg
54
+ */
55
+ const notificationSubscriber = (msg, dataMsg) => {
56
+ if (dataMsg.data.event !== undefined) {
57
+ let _status;
58
+ switch (SCNotificationMapping[dataMsg.data.activity_type]) {
59
+ case SCNotificationTypologyType.USER_INVITED_TO_JOIN_EVENT:
60
+ _status = SCEventSubscriptionStatusType.INVITED;
61
+ break;
62
+ case SCNotificationTypologyType.USER_REQUESTED_TO_JOIN_EVENT:
63
+ _status = SCEventSubscriptionStatusType.REQUESTED;
64
+ break;
65
+ case SCNotificationTypologyType.USER_ACCEPTED_TO_JOIN_EVENT:
66
+ _status = SCEventSubscriptionStatusType.SUBSCRIBED;
67
+ break;
68
+ case SCNotificationTypologyType.USER_ADDED_TO_EVENT:
69
+ _status = SCEventSubscriptionStatusType.SUBSCRIBED;
70
+ break;
71
+ }
72
+ updateCache([dataMsg.data.event.id]);
73
+ setData((prev) => getDataUpdated(prev, dataMsg.data.event.id, _status));
74
+ }
75
+ };
76
+ /**
77
+ * Memoized refresh all events
78
+ * It makes a single request to the server and retrieves
79
+ * all the events followed by the user in a single solution
80
+ * It might be useful for multi-tab sync
81
+ */
82
+ const refresh = useMemo(() => () => {
83
+ emptyCache();
84
+ if (user) {
85
+ // Only if user is authenticated
86
+ http
87
+ .request({
88
+ url: Endpoints.GetUserEvents.url(),
89
+ method: Endpoints.GetUserEvents.method,
90
+ })
91
+ .then((res) => {
92
+ if (res.status >= 300) {
93
+ return Promise.reject(res);
94
+ }
95
+ const eventsIds = res.data.results.map((e) => e.id);
96
+ updateCache(eventsIds);
97
+ setData(res.data.results.map((e) => ({ [e.id]: e.subscription_status })));
98
+ return Promise.resolve(res.data);
99
+ })
100
+ .catch((e) => {
101
+ Logger.error(SCOPE_SC_CORE, 'Unable to refresh the authenticated user events.');
102
+ Logger.error(SCOPE_SC_CORE, e);
103
+ });
104
+ }
105
+ }, [data, user, cache]);
106
+ /**
107
+ * Memoized toggleEventAttendance Event
108
+ * Toggle action
109
+ */
110
+ const toggleEventAttendance = useMemo(() => (event, userId) => {
111
+ setLoading(event.id);
112
+ if (userId) {
113
+ return http
114
+ .request({
115
+ url: Endpoints.InviteOrAcceptEventRequest.url({ id: event.id }),
116
+ method: Endpoints.InviteOrAcceptEventRequest.method,
117
+ data: { users: [userId] },
118
+ })
119
+ .then((res) => {
120
+ if (res.status >= 300) {
121
+ return Promise.reject(res);
122
+ }
123
+ updateCache([event.id]);
124
+ setData((prev) => getDataUpdated(prev, event.id, SCEventSubscriptionStatusType.SUBSCRIBED));
125
+ setUnLoading(event.id);
126
+ return Promise.resolve(res.data);
127
+ });
128
+ }
129
+ else {
130
+ const requestConfig = !event.subscription_status || event.subscription_status === SCEventSubscriptionStatusType.INVITED
131
+ ? {
132
+ url: Endpoints.SubscribeToEvent.url({ id: event.id }),
133
+ method: Endpoints.SubscribeToEvent.method,
134
+ }
135
+ : event.subscription_status === SCEventSubscriptionStatusType.GOING
136
+ ? {
137
+ url: Endpoints.RemoveGoingToEvent.url({ id: event.id }),
138
+ method: Endpoints.RemoveGoingToEvent.method,
139
+ }
140
+ : {
141
+ url: Endpoints.GoToEvent.url({ id: event.id }),
142
+ method: Endpoints.GoToEvent.method,
143
+ };
144
+ return http.request(requestConfig).then((res) => {
145
+ if (res.status >= 300) {
146
+ return Promise.reject(res);
147
+ }
148
+ updateCache([event.id]);
149
+ setData((prev) => getDataUpdated(prev, event.id, getEventStatus(event, true)));
150
+ setUnLoading(event.id);
151
+ return Promise.resolve(res.data);
152
+ });
153
+ }
154
+ }, [data, loading, cache]);
155
+ /**
156
+ * Memoized toggleEventNonattendance Event
157
+ * Toggle action
158
+ */
159
+ const toggleEventNonattendance = useMemo(() => (event) => {
160
+ if (event.subscription_status !== SCEventSubscriptionStatusType.REQUESTED) {
161
+ setLoading(event.id);
162
+ const requestConfig = event.subscription_status === SCEventSubscriptionStatusType.NOT_GOING
163
+ ? {
164
+ url: Endpoints.RemoveNotGoingToEvent.url({ id: event.id }),
165
+ method: Endpoints.RemoveNotGoingToEvent.method,
166
+ }
167
+ : {
168
+ url: Endpoints.NotGoingToEvent.url({ id: event.id }),
169
+ method: Endpoints.NotGoingToEvent.method,
170
+ };
171
+ return http.request(requestConfig).then((res) => {
172
+ if (res.status >= 300) {
173
+ return Promise.reject(res);
174
+ }
175
+ updateCache([event.id]);
176
+ setData((prev) => getDataUpdated(prev, event.id, getEventStatus(event, false)));
177
+ setUnLoading(event.id);
178
+ return Promise.resolve(res.data);
179
+ });
180
+ }
181
+ else {
182
+ setLoading(event.id);
183
+ return http
184
+ .request({ url: Endpoints.UnsubscribeFromEvent.url({ id: event.id }), method: Endpoints.UnsubscribeFromEvent.method })
185
+ .then((res) => {
186
+ if (res.status >= 300) {
187
+ return Promise.reject(res);
188
+ }
189
+ updateCache([event.id]);
190
+ setData((prev) => getDataUpdated(prev, event.id, null));
191
+ setUnLoading(event.id);
192
+ return Promise.resolve(res.data);
193
+ });
194
+ }
195
+ }, [data, loading, cache]);
196
+ /**
197
+ * Check the authenticated user subscription status to the event
198
+ * Update the events cached
199
+ * Update events subscription statuses
200
+ * @param event
201
+ */
202
+ const checkEventSubscriptionStatus = (event) => {
203
+ setLoading(event.id);
204
+ return http
205
+ .request({
206
+ url: Endpoints.GetEventSubscriptionStatus.url({ id: event.id }),
207
+ method: Endpoints.GetEventSubscriptionStatus.method,
208
+ })
209
+ .then((res) => {
210
+ if (res.status >= 300) {
211
+ return Promise.reject(res);
212
+ }
213
+ setData((prev) => getDataUpdated(prev, event.id, res.data.status));
214
+ updateCache([event.id]);
215
+ setUnLoading(event.id);
216
+ return Promise.resolve(res.data);
217
+ })
218
+ .catch((e) => {
219
+ setUnLoading(event.id);
220
+ return Promise.reject(e);
221
+ });
222
+ };
223
+ /**
224
+ * Get updated data
225
+ * @param data
226
+ * @param eventId
227
+ * @param subscriptionStatus
228
+ */
229
+ const getDataUpdated = (data, eventId, subscriptionStatus) => {
230
+ const _index = data.findIndex((k) => parseInt(Object.keys(k)[0]) === eventId);
231
+ let _data;
232
+ if (_index < 0) {
233
+ _data = [...data, ...[{ [eventId]: subscriptionStatus }]];
234
+ }
235
+ else {
236
+ _data = data.map((k, i) => {
237
+ if (parseInt(Object.keys(k)[0]) === eventId) {
238
+ return { [Object.keys(k)[0]]: subscriptionStatus };
239
+ }
240
+ return { [Object.keys(k)[0]]: data[i][Object.keys(k)[0]] };
241
+ });
242
+ }
243
+ return _data;
244
+ };
245
+ /**
246
+ * Return current event subscription status if exists,
247
+ * otherwise return null
248
+ */
249
+ const getCurrentEventCacheStatus = useMemo(() => (event) => {
250
+ const d = data.filter((k) => parseInt(Object.keys(k)[0]) === event.id);
251
+ return d.length ? d[0][event.id] : !data.length ? event.subscription_status : null;
252
+ }, [data]);
253
+ /**
254
+ * Bypass remote check if the event is subscribed
255
+ */
256
+ const getSubscriptionStatus = useMemo(() => (event) => {
257
+ updateCache([event.id]);
258
+ setData((prev) => getDataUpdated(prev, event.id, event.subscription_status));
259
+ return event.subscription_status;
260
+ }, [data, cache]);
261
+ /**
262
+ * Memoized subscriptionStatus
263
+ * If event is already in cache -> check if the event is in events,
264
+ * otherwise, check if user toggleEventAttendance the event
265
+ */
266
+ const subscriptionStatus = useMemo(() => (event) => {
267
+ // Cache is valid also for anonymous user
268
+ if (cache.includes(event === null || event === void 0 ? void 0 : event.id)) {
269
+ return getCurrentEventCacheStatus(event);
270
+ }
271
+ if (authUserId && event) {
272
+ if ('subscription_status' in event) {
273
+ return getSubscriptionStatus(event);
274
+ }
275
+ if (!isLoading(event)) {
276
+ checkEventSubscriptionStatus(event);
277
+ }
278
+ }
279
+ return null;
280
+ }, [loading, cache, authUserId]);
281
+ /**
282
+ * Empty cache on logout
283
+ */
284
+ useEffect(() => {
285
+ if (!authUserId) {
286
+ emptyCache();
287
+ }
288
+ }, [authUserId]);
289
+ if (!eventsEnabled || !user) {
290
+ return { events: data, loading, isLoading };
291
+ }
292
+ return { events: data, loading, isLoading, toggleEventAttendance, toggleEventNonattendance, subscriptionStatus, refresh, emptyCache };
293
+ }
@@ -1,4 +1,5 @@
1
- import React, { useContext, useEffect, useRef, useState } from 'react';
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useContext, useEffect, useRef, useState } from 'react';
2
3
  import { useSCContext } from '../components/provider/SCContextProvider';
3
4
  import { useSCUser } from '../components/provider/SCUserProvider';
4
5
  import { Logger } from '@selfcommunity/utils';
@@ -56,9 +57,7 @@ export default function useSCWebPushMessaging() {
56
57
  const showCustomRequestNotificationSnackbar = () => {
57
58
  if (!Cookies.get(NOTIFICATIONS_WEB_PUSH_MESSAGING_DIALOG_COOKIE)) {
58
59
  enqueueSnackbar(intl.formatMessage({ id: 'ui.webPushNotification.requestPermission', defaultMessage: 'ui.webPushNotification.requestPermission' }), {
59
- action: (snackbarId) => (React.createElement(React.Fragment, null,
60
- React.createElement(Button, { size: "small", sx: { color: '#FFF' }, onClick: () => requestNotificationPermission(snackbarId) }, intl.formatMessage({ id: 'ui.webPushNotification.allow', defaultMessage: 'ui.webPushNotification.allow' })),
61
- React.createElement(Button, { size: "small", sx: { color: '#FFF' }, onClick: () => closeRequestNotificationSnackbar(snackbarId) }, intl.formatMessage({ id: 'ui.webPushNotification.block', defaultMessage: 'ui.webPushNotification.block' })))),
60
+ action: (snackbarId) => (_jsxs(_Fragment, { children: [_jsx(Button, Object.assign({ size: "small", sx: { color: '#FFF' }, onClick: () => requestNotificationPermission(snackbarId) }, { children: intl.formatMessage({ id: 'ui.webPushNotification.allow', defaultMessage: 'ui.webPushNotification.allow' }) })), _jsx(Button, Object.assign({ size: "small", sx: { color: '#FFF' }, onClick: () => closeRequestNotificationSnackbar(snackbarId) }, { children: intl.formatMessage({ id: 'ui.webPushNotification.block', defaultMessage: 'ui.webPushNotification.block' }) }))] })),
62
61
  variant: 'default',
63
62
  anchorOrigin: { horizontal: 'center', vertical: 'bottom' },
64
63
  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, };