@dcl/hooks 1.1.0 → 1.1.1-20260130165526.commit-e8ee72c

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 (35) hide show
  1. package/README.md +120 -0
  2. package/esm/clients/index.d.ts +2 -0
  3. package/esm/clients/index.js +2 -0
  4. package/esm/clients/index.js.map +1 -0
  5. package/esm/clients/notifications/createNotificationsClient.d.ts +15 -0
  6. package/esm/clients/notifications/createNotificationsClient.js +55 -0
  7. package/esm/clients/notifications/createNotificationsClient.js.map +1 -0
  8. package/esm/clients/notifications/index.d.ts +2 -0
  9. package/esm/clients/notifications/index.js +2 -0
  10. package/esm/clients/notifications/index.js.map +1 -0
  11. package/esm/hooks/index.d.ts +2 -0
  12. package/esm/hooks/index.js +1 -0
  13. package/esm/hooks/index.js.map +1 -1
  14. package/esm/hooks/useNotifications/index.d.ts +3 -0
  15. package/esm/hooks/useNotifications/index.js +3 -0
  16. package/esm/hooks/useNotifications/index.js.map +1 -0
  17. package/esm/hooks/useNotifications/useNotifications.d.ts +12 -0
  18. package/esm/hooks/useNotifications/useNotifications.js +214 -0
  19. package/esm/hooks/useNotifications/useNotifications.js.map +1 -0
  20. package/esm/hooks/useNotifications/useNotifications.type.d.ts +47 -0
  21. package/esm/hooks/useNotifications/useNotifications.type.js +7 -0
  22. package/esm/hooks/useNotifications/useNotifications.type.js.map +1 -0
  23. package/esm/hooks/useTranslation/useTranslation.js +25 -3
  24. package/esm/hooks/useTranslation/useTranslation.js.map +1 -1
  25. package/esm/hooks/useTranslation/useTranslation.type.d.ts +3 -1
  26. package/esm/index.d.ts +2 -0
  27. package/esm/index.js +2 -0
  28. package/esm/index.js.map +1 -1
  29. package/esm/utils/index.d.ts +1 -0
  30. package/esm/utils/index.js +2 -0
  31. package/esm/utils/index.js.map +1 -0
  32. package/esm/utils/storage.d.ts +39 -0
  33. package/esm/utils/storage.js +65 -0
  34. package/esm/utils/storage.js.map +1 -0
  35. package/package.json +4 -2
package/README.md CHANGED
@@ -21,6 +21,7 @@ npm install @dcl/hooks
21
21
  - `useAsyncMemo`: Async version of useMemo
22
22
  - `useInfiniteScroll`: Infinite scroll functionality for loading more content
23
23
  - `useTranslation`: Simple and lightweight translation management
24
+ - `useNotifications`: Notification polling and modal state management
24
25
 
25
26
  ## Examples
26
27
 
@@ -505,6 +506,31 @@ function MyComponent() {
505
506
  }
506
507
  ```
507
508
 
509
+ Nested translations (dot notation):
510
+
511
+ ```typescript
512
+ const translations = {
513
+ en: {
514
+ components: {
515
+ blog: {
516
+ related_post: {
517
+ title: 'Related posts'
518
+ }
519
+ }
520
+ }
521
+ }
522
+ }
523
+
524
+ function MyComponent() {
525
+ const { t } = useTranslation({
526
+ locale: 'en',
527
+ translations
528
+ })
529
+
530
+ return <p>{t('components.blog.related_post.title')}</p>
531
+ }
532
+ ```
533
+
508
534
  Using the `intl` object for advanced formatting:
509
535
 
510
536
  ```typescript
@@ -678,6 +704,100 @@ function MyComponent() {
678
704
  }
679
705
  ```
680
706
 
707
+ ### useNotifications
708
+
709
+ The `useNotifications` hook manages notification polling, modal state, and onboarding flow. It uses Decentraland's notifications API by default.
710
+
711
+ Basic usage:
712
+
713
+ ```typescript
714
+ import { useNotifications } from '@dcl/hooks'
715
+ import type { AuthIdentity } from 'decentraland-crypto-fetch'
716
+
717
+ function NotificationsComponent() {
718
+ const identity: AuthIdentity = useAuthIdentity() // From your auth context
719
+
720
+ const {
721
+ notifications,
722
+ isLoading,
723
+ isModalOpen,
724
+ isNotificationsOnboarding,
725
+ handleNotificationsOpen,
726
+ handleOnBegin
727
+ } = useNotifications({
728
+ identity,
729
+ isNotificationsEnabled: !!identity,
730
+ notificationsUrl: 'https://notifications.decentraland.org' // or .zone for dev
731
+ })
732
+
733
+ if (isNotificationsOnboarding) {
734
+ return (
735
+ <div>
736
+ <h2>Welcome to Notifications!</h2>
737
+ <button onClick={handleOnBegin}>Get Started</button>
738
+ </div>
739
+ )
740
+ }
741
+
742
+ return (
743
+ <div>
744
+ <button onClick={handleNotificationsOpen}>
745
+ Notifications ({notifications.filter(n => !n.read).length})
746
+ </button>
747
+
748
+ {isModalOpen && (
749
+ <ul>
750
+ {notifications.map(notification => (
751
+ <li key={notification.id}>
752
+ {notification.type} - {notification.read ? 'Read' : 'Unread'}
753
+ </li>
754
+ ))}
755
+ </ul>
756
+ )}
757
+ </div>
758
+ )
759
+ }
760
+ ```
761
+
762
+ With custom polling interval:
763
+
764
+ ```typescript
765
+ const { notifications } = useNotifications({
766
+ identity,
767
+ isNotificationsEnabled: !!identity,
768
+ notificationsUrl: 'https://notifications.decentraland.org',
769
+ queryIntervalMs: 30000 // Poll every 30 seconds (default: 60000)
770
+ })
771
+ ```
772
+
773
+ With notification type filtering:
774
+
775
+ ```typescript
776
+ const { notifications } = useNotifications({
777
+ identity,
778
+ isNotificationsEnabled: !!identity,
779
+ notificationsUrl: 'https://notifications.decentraland.org',
780
+ availableNotificationTypes: ['bid', 'sale', 'royalties']
781
+ })
782
+ ```
783
+
784
+ With error handling:
785
+
786
+ `onError` is called when fetching fails, marking as read fails, or when
787
+ `notificationsUrl` is missing.
788
+
789
+ ```typescript
790
+ const { notifications } = useNotifications({
791
+ identity,
792
+ isNotificationsEnabled: !!identity,
793
+ notificationsUrl: 'https://notifications.decentraland.org',
794
+ onError: (error) => {
795
+ console.error('Notification error:', error)
796
+ Sentry.captureException(error)
797
+ }
798
+ })
799
+ ```
800
+
681
801
  ## License
682
802
 
683
803
  This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
@@ -0,0 +1,2 @@
1
+ export { createNotificationsClient } from "./notifications";
2
+ export type { NotificationsClientOptions } from "./notifications";
@@ -0,0 +1,2 @@
1
+ export { createNotificationsClient } from "./notifications";
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/clients/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAA"}
@@ -0,0 +1,15 @@
1
+ import type { NotificationsClient } from "../../hooks/useNotifications";
2
+ type NotificationsClientOptions = {
3
+ url: string;
4
+ limit?: number;
5
+ };
6
+ /**
7
+ * Creates a Decentraland notifications client.
8
+ *
9
+ * @param identity - The AuthIdentity for signing requests
10
+ * @param options - Configuration with required url
11
+ * @returns A NotificationsClient instance
12
+ */
13
+ declare const createNotificationsClient: (identity: unknown, options: NotificationsClientOptions) => NotificationsClient;
14
+ export { createNotificationsClient };
15
+ export type { NotificationsClientOptions };
@@ -0,0 +1,55 @@
1
+ import { signedFetchFactory, } from "decentraland-crypto-fetch";
2
+ const DEFAULT_NOTIFICATIONS_LIMIT = 50;
3
+ const parseNotification = (notification) => ({
4
+ ...notification,
5
+ timestamp: Number(notification.timestamp),
6
+ });
7
+ /**
8
+ * Creates a Decentraland notifications client.
9
+ *
10
+ * @param identity - The AuthIdentity for signing requests
11
+ * @param options - Configuration with required url
12
+ * @returns A NotificationsClient instance
13
+ */
14
+ const createNotificationsClient = (identity, options) => {
15
+ const authIdentity = identity;
16
+ const { url: baseUrl, limit = DEFAULT_NOTIFICATIONS_LIMIT } = options;
17
+ const signedFetch = signedFetchFactory();
18
+ const getNotifications = async () => {
19
+ const params = new URLSearchParams();
20
+ params.append("limit", String(limit));
21
+ const url = `${baseUrl}/notifications?${params.toString()}`;
22
+ const response = await signedFetch(url, {
23
+ identity: authIdentity,
24
+ headers: {
25
+ "Content-Type": "application/json",
26
+ },
27
+ });
28
+ if (!response.ok) {
29
+ throw new Error(`Failed to fetch notifications: ${response.status}`);
30
+ }
31
+ const data = await response.json();
32
+ const notifications = data.notifications ?? [];
33
+ return notifications.map(parseNotification);
34
+ };
35
+ const markNotificationsAsRead = async (ids) => {
36
+ const url = `${baseUrl}/notifications/read`;
37
+ const response = await signedFetch(url, {
38
+ method: "PUT",
39
+ identity: authIdentity,
40
+ body: JSON.stringify({ notificationIds: ids }),
41
+ headers: {
42
+ "Content-Type": "application/json",
43
+ },
44
+ });
45
+ if (!response.ok) {
46
+ throw new Error(`Failed to mark notifications as read: ${response.status}`);
47
+ }
48
+ };
49
+ return {
50
+ getNotifications,
51
+ markNotificationsAsRead,
52
+ };
53
+ };
54
+ export { createNotificationsClient };
55
+ //# sourceMappingURL=createNotificationsClient.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createNotificationsClient.js","sourceRoot":"","sources":["../../../src/clients/notifications/createNotificationsClient.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,kBAAkB,GACnB,MAAM,2BAA2B,CAAA;AAMlC,MAAM,2BAA2B,GAAG,EAAE,CAAA;AAWtC,MAAM,iBAAiB,GAAG,CACxB,YAAkC,EAChB,EAAE,CAAC,CAAC;IACtB,GAAG,YAAY;IACf,SAAS,EAAE,MAAM,CAAC,YAAY,CAAC,SAAS,CAAC;CAC1C,CAAC,CAAA;AAEF;;;;;;GAMG;AACH,MAAM,yBAAyB,GAAG,CAChC,QAAiB,EACjB,OAAmC,EACd,EAAE;IACvB,MAAM,YAAY,GAAG,QAAwB,CAAA;IAC7C,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,GAAG,2BAA2B,EAAE,GAAG,OAAO,CAAA;IACrE,MAAM,WAAW,GAAG,kBAAkB,EAAE,CAAA;IAExC,MAAM,gBAAgB,GAAG,KAAK,IAAiC,EAAE;QAC/D,MAAM,MAAM,GAAG,IAAI,eAAe,EAAE,CAAA;QACpC,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAA;QAErC,MAAM,GAAG,GAAG,GAAG,OAAO,kBAAkB,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAA;QAC3D,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAC,GAAG,EAAE;YACtC,QAAQ,EAAE,YAAY;YACtB,OAAO,EAAE;gBACP,cAAc,EAAE,kBAAkB;aACnC;SACF,CAAC,CAAA;QAEF,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,kCAAkC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAA;QACtE,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAA;QAClC,MAAM,aAAa,GAA2B,IAAI,CAAC,aAAa,IAAI,EAAE,CAAA;QAEtE,OAAO,aAAa,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAA;IAC7C,CAAC,CAAA;IAED,MAAM,uBAAuB,GAAG,KAAK,EAAE,GAAa,EAAiB,EAAE;QACrE,MAAM,GAAG,GAAG,GAAG,OAAO,qBAAqB,CAAA;QAC3C,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAC,GAAG,EAAE;YACtC,MAAM,EAAE,KAAK;YACb,QAAQ,EAAE,YAAY;YACtB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,eAAe,EAAE,GAAG,EAAE,CAAC;YAC9C,OAAO,EAAE;gBACP,cAAc,EAAE,kBAAkB;aACnC;SACF,CAAC,CAAA;QAEF,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CACb,yCAAyC,QAAQ,CAAC,MAAM,EAAE,CAC3D,CAAA;QACH,CAAC;IACH,CAAC,CAAA;IAED,OAAO;QACL,gBAAgB;QAChB,uBAAuB;KACxB,CAAA;AACH,CAAC,CAAA;AAED,OAAO,EAAE,yBAAyB,EAAE,CAAA"}
@@ -0,0 +1,2 @@
1
+ export { createNotificationsClient } from "./createNotificationsClient";
2
+ export type { NotificationsClientOptions } from "./createNotificationsClient";
@@ -0,0 +1,2 @@
1
+ export { createNotificationsClient } from "./createNotificationsClient";
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/clients/notifications/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAA"}
@@ -2,6 +2,7 @@ export type { AdvancedNavigatorUAData } from "./useAdvancedUserAgentData";
2
2
  export type { AsyncMemoResult, AsyncMemoResultState } from "./useAsyncMemo";
3
3
  export type { AsyncStateResult, AsyncStateResultState } from "./useAsyncState";
4
4
  export type { UseInfiniteScrollOptions } from "./useInfiniteScroll";
5
+ export type { NotificationItem, NotificationsClient, NotificationsState, NotificationsUIState, UseNotificationsOptions, UseNotificationsResult, } from "./useNotifications";
5
6
  export type { Translations, LanguageTranslations, TranslationState, TranslationOptions, TranslationResult, } from "./useTranslation";
6
7
  export { useAdvancedUserAgentData } from "./useAdvancedUserAgentData";
7
8
  export { useAnalytics } from "./useAnalytics";
@@ -11,6 +12,7 @@ export { useAsyncState, createAsyncStateState } from "./useAsyncState";
11
12
  export { useAsyncTask } from "./useAsyncTask";
12
13
  export { useAsyncTasks } from "./useAsyncTasks";
13
14
  export { useInfiniteScroll } from "./useInfiniteScroll";
15
+ export { checkIsOnboarding, setOnboardingDone, useNotifications, } from "./useNotifications";
14
16
  export { usePageTracking } from "./usePageTracking";
15
17
  export { usePatchState } from "./usePatchState";
16
18
  export { useTranslation } from "./useTranslation";
@@ -7,6 +7,7 @@ export { useAsyncState, createAsyncStateState } from "./useAsyncState";
7
7
  export { useAsyncTask } from "./useAsyncTask";
8
8
  export { useAsyncTasks } from "./useAsyncTasks";
9
9
  export { useInfiniteScroll } from "./useInfiniteScroll";
10
+ export { checkIsOnboarding, setOnboardingDone, useNotifications, } from "./useNotifications";
10
11
  export { usePageTracking } from "./usePageTracking";
11
12
  export { usePatchState } from "./usePatchState";
12
13
  export { useTranslation } from "./useTranslation";
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAaA,QAAQ;AACR,OAAO,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAA;AACrE,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AACjD,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAA;AACnE,OAAO,EAAE,aAAa,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAA;AACtE,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAC/C,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAqBA,QAAQ;AACR,OAAO,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAA;AACrE,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AACjD,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAA;AACnE,OAAO,EAAE,aAAa,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAA;AACtE,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAC/C,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AACvD,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA"}
@@ -0,0 +1,3 @@
1
+ export { checkIsOnboarding, setOnboardingDone, useNotifications, } from "./useNotifications";
2
+ export { NotificationActiveTab } from "./useNotifications.type";
3
+ export type { NotificationItem, NotificationsClient, NotificationsState, NotificationsUIState, UseNotificationsOptions, UseNotificationsResult, } from "./useNotifications.type";
@@ -0,0 +1,3 @@
1
+ export { checkIsOnboarding, setOnboardingDone, useNotifications, } from "./useNotifications";
2
+ export { NotificationActiveTab } from "./useNotifications.type";
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/hooks/useNotifications/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAA"}
@@ -0,0 +1,12 @@
1
+ import { UseNotificationsOptions, UseNotificationsResult } from "./useNotifications.type";
2
+ declare const checkIsOnboarding: () => boolean;
3
+ declare const setOnboardingDone: () => void;
4
+ /**
5
+ * Hook to manage notification polling and modal state.
6
+ * Uses Decentraland's notifications API.
7
+ *
8
+ * @param options - Configuration options for notifications polling and UI state.
9
+ * @returns Notifications state, modal state, and handlers.
10
+ */
11
+ declare const useNotifications: (options: UseNotificationsOptions) => UseNotificationsResult;
12
+ export { checkIsOnboarding, setOnboardingDone, useNotifications };
@@ -0,0 +1,214 @@
1
+ import { useCallback, useEffect, useMemo, useRef, useState } from "react";
2
+ import { NotificationActiveTab, } from "./useNotifications.type";
3
+ import { createNotificationsClient } from "../../clients/notifications";
4
+ import { getStorageItem, setStorageItem } from "../../utils/storage";
5
+ const DEFAULT_QUERY_INTERVAL_MS = 60000;
6
+ const ONBOARDING_KEY = "dcl_notifications_onboarding";
7
+ const checkIsOnboarding = () => {
8
+ const value = getStorageItem(ONBOARDING_KEY, null);
9
+ if (value === null) {
10
+ setStorageItem(ONBOARDING_KEY, true);
11
+ return true;
12
+ }
13
+ return value;
14
+ };
15
+ const setOnboardingDone = () => {
16
+ setStorageItem(ONBOARDING_KEY, false);
17
+ };
18
+ /**
19
+ * Hook to manage notification polling and modal state.
20
+ * Uses Decentraland's notifications API.
21
+ *
22
+ * @param options - Configuration options for notifications polling and UI state.
23
+ * @returns Notifications state, modal state, and handlers.
24
+ */
25
+ const useNotifications = (options) => {
26
+ const { identity, isNotificationsEnabled, notificationsUrl, availableNotificationTypes, queryIntervalMs = DEFAULT_QUERY_INTERVAL_MS, initialActiveTab = NotificationActiveTab.NEWEST, onError, renderProfile, } = options;
27
+ const [notificationsState, setNotificationsState] = useState({
28
+ isLoading: false,
29
+ notifications: [],
30
+ });
31
+ const [uiState, setUiState] = useState(() => ({
32
+ activeTab: initialActiveTab,
33
+ isOnboarding: checkIsOnboarding(),
34
+ isOpen: false,
35
+ }));
36
+ const [notificationsClient, setNotificationsClient] = useState(null);
37
+ const notificationsRef = useRef([]);
38
+ const notificationsClientRef = useRef(null);
39
+ useEffect(() => {
40
+ notificationsRef.current = notificationsState.notifications;
41
+ }, [notificationsState.notifications]);
42
+ useEffect(() => {
43
+ notificationsClientRef.current = notificationsClient;
44
+ }, [notificationsClient]);
45
+ const availableNotifications = useMemo(() => {
46
+ if (!availableNotificationTypes) {
47
+ return null;
48
+ }
49
+ return new Set(availableNotificationTypes);
50
+ }, [availableNotificationTypes]);
51
+ const fetchAndUpdateNotifications = useCallback((client) => {
52
+ return Promise.resolve()
53
+ .then(() => client.getNotifications())
54
+ .then((notificationsFetched) => {
55
+ const filteredNotifications = availableNotifications
56
+ ? notificationsFetched.filter((notification) => availableNotifications.has(notification.type))
57
+ : notificationsFetched;
58
+ const hasReadNotifications = filteredNotifications.some((notification) => notification.read);
59
+ setNotificationsState((prevState) => ({
60
+ ...prevState,
61
+ isLoading: false,
62
+ notifications: filteredNotifications,
63
+ }));
64
+ if (hasReadNotifications) {
65
+ setOnboardingDone();
66
+ setUiState((prevState) => prevState.isOnboarding
67
+ ? { ...prevState, isOnboarding: false }
68
+ : prevState);
69
+ }
70
+ })
71
+ .catch((error) => {
72
+ const normalizedError = error instanceof Error ? error : new Error("Unknown error");
73
+ console.error("Error fetching notifications:", normalizedError);
74
+ if (onError) {
75
+ onError(normalizedError);
76
+ }
77
+ setNotificationsState((prevState) => ({
78
+ ...prevState,
79
+ isLoading: false,
80
+ }));
81
+ });
82
+ }, [availableNotifications, onError]);
83
+ useEffect(() => {
84
+ if (!identity) {
85
+ setNotificationsClient(null);
86
+ return;
87
+ }
88
+ if (!notificationsUrl) {
89
+ const normalizedError = new Error("notificationsUrl is required");
90
+ console.error("Notifications URL missing:", normalizedError);
91
+ if (onError) {
92
+ onError(normalizedError);
93
+ }
94
+ setNotificationsClient(null);
95
+ return;
96
+ }
97
+ const client = createNotificationsClient(identity, {
98
+ url: notificationsUrl,
99
+ });
100
+ setNotificationsClient(client);
101
+ if (!isNotificationsEnabled) {
102
+ return;
103
+ }
104
+ let cancelled = false;
105
+ setNotificationsState((prevState) => ({
106
+ ...prevState,
107
+ isLoading: true,
108
+ }));
109
+ const pollNotifications = () => {
110
+ if (cancelled) {
111
+ return;
112
+ }
113
+ fetchAndUpdateNotifications(client);
114
+ };
115
+ pollNotifications();
116
+ const intervalId = setInterval(pollNotifications, queryIntervalMs);
117
+ return () => {
118
+ cancelled = true;
119
+ clearInterval(intervalId);
120
+ };
121
+ }, [
122
+ identity,
123
+ isNotificationsEnabled,
124
+ notificationsUrl,
125
+ onError,
126
+ fetchAndUpdateNotifications,
127
+ queryIntervalMs,
128
+ ]);
129
+ useEffect(() => {
130
+ const isClosing = !uiState.isOpen;
131
+ if (!isClosing) {
132
+ return;
133
+ }
134
+ const currentNotifications = notificationsRef.current;
135
+ const currentClient = notificationsClientRef.current;
136
+ if (!currentClient) {
137
+ return;
138
+ }
139
+ const unreadNotificationsIds = currentNotifications
140
+ .filter((notification) => !notification.read)
141
+ .map((notification) => notification.id);
142
+ if (unreadNotificationsIds.length === 0) {
143
+ return;
144
+ }
145
+ let cancelled = false;
146
+ Promise.resolve()
147
+ .then(() => currentClient.markNotificationsAsRead(unreadNotificationsIds))
148
+ .then(() => {
149
+ if (cancelled) {
150
+ return;
151
+ }
152
+ setNotificationsState((prevState) => ({
153
+ ...prevState,
154
+ notifications: prevState.notifications.map((notification) => ({
155
+ ...notification,
156
+ read: unreadNotificationsIds.includes(notification.id)
157
+ ? true
158
+ : notification.read,
159
+ })),
160
+ }));
161
+ })
162
+ .catch((error) => {
163
+ if (cancelled) {
164
+ return;
165
+ }
166
+ const normalizedError = error instanceof Error ? error : new Error("Unknown error");
167
+ console.error("Error marking notifications as read:", normalizedError);
168
+ if (onError) {
169
+ onError(normalizedError);
170
+ }
171
+ });
172
+ return () => {
173
+ cancelled = true;
174
+ };
175
+ }, [uiState.isOpen, onError]);
176
+ const handleOnBegin = useCallback(() => {
177
+ setOnboardingDone();
178
+ setUiState((prevState) => ({
179
+ ...prevState,
180
+ isOnboarding: false,
181
+ }));
182
+ }, []);
183
+ const handleNotificationsOpen = useCallback(() => {
184
+ setUiState((prevState) => ({
185
+ ...prevState,
186
+ isOpen: !prevState.isOpen,
187
+ }));
188
+ }, []);
189
+ const handleOnChangeModalTab = useCallback((tab) => {
190
+ setUiState((prevState) => ({
191
+ ...prevState,
192
+ activeTab: tab,
193
+ }));
194
+ }, []);
195
+ const handleRenderProfile = useCallback((address) => {
196
+ if (!renderProfile) {
197
+ return null;
198
+ }
199
+ return renderProfile(address);
200
+ }, [renderProfile]);
201
+ return {
202
+ notifications: notificationsState.notifications,
203
+ isLoading: notificationsState.isLoading,
204
+ isModalOpen: uiState.isOpen,
205
+ modalActiveTab: uiState.activeTab,
206
+ isNotificationsOnboarding: uiState.isOnboarding,
207
+ handleOnBegin,
208
+ handleNotificationsOpen,
209
+ handleOnChangeModalTab,
210
+ handleRenderProfile,
211
+ };
212
+ };
213
+ export { checkIsOnboarding, setOnboardingDone, useNotifications };
214
+ //# sourceMappingURL=useNotifications.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useNotifications.js","sourceRoot":"","sources":["../../../src/hooks/useNotifications/useNotifications.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ import type { ReactNode } from "react";
2
+ declare enum NotificationActiveTab {
3
+ NEWEST = "newest",
4
+ READ = "read"
5
+ }
6
+ type NotificationItem = {
7
+ id: string;
8
+ type: string;
9
+ read: boolean;
10
+ [key: string]: unknown;
11
+ };
12
+ type NotificationsClient = {
13
+ getNotifications: () => Promise<NotificationItem[]>;
14
+ markNotificationsAsRead: (ids: string[]) => Promise<void>;
15
+ };
16
+ type NotificationsState = {
17
+ isLoading: boolean;
18
+ notifications: NotificationItem[];
19
+ };
20
+ type NotificationsUIState = {
21
+ activeTab: string;
22
+ isOnboarding: boolean;
23
+ isOpen: boolean;
24
+ };
25
+ type UseNotificationsOptions = {
26
+ identity?: unknown;
27
+ isNotificationsEnabled: boolean;
28
+ notificationsUrl: string;
29
+ availableNotificationTypes?: string[];
30
+ queryIntervalMs?: number;
31
+ initialActiveTab?: string;
32
+ onError?: (error: Error) => void;
33
+ renderProfile?: (address: string) => ReactNode;
34
+ };
35
+ type UseNotificationsResult = {
36
+ notifications: NotificationItem[];
37
+ isLoading: boolean;
38
+ isModalOpen: boolean;
39
+ modalActiveTab: string;
40
+ isNotificationsOnboarding: boolean;
41
+ handleOnBegin: () => void;
42
+ handleNotificationsOpen: () => void;
43
+ handleOnChangeModalTab: (tab: string) => void;
44
+ handleRenderProfile: (address: string) => ReactNode;
45
+ };
46
+ export { NotificationActiveTab };
47
+ export type { NotificationItem, NotificationsClient, NotificationsState, NotificationsUIState, UseNotificationsOptions, UseNotificationsResult, };
@@ -0,0 +1,7 @@
1
+ var NotificationActiveTab;
2
+ (function (NotificationActiveTab) {
3
+ NotificationActiveTab["NEWEST"] = "newest";
4
+ NotificationActiveTab["READ"] = "read";
5
+ })(NotificationActiveTab || (NotificationActiveTab = {}));
6
+ export { NotificationActiveTab };
7
+ //# sourceMappingURL=useNotifications.type.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useNotifications.type.js","sourceRoot":"","sources":["../../../src/hooks/useNotifications/useNotifications.type.ts"],"names":[],"mappings":"AAEA,IAAK,qBAGJ;AAHD,WAAK,qBAAqB;IACxB,0CAAiB,CAAA;IACjB,sCAAa,CAAA;AACf,CAAC,EAHI,qBAAqB,KAArB,qBAAqB,QAGzB;AAgDD,OAAO,EAAE,qBAAqB,EAAE,CAAA"}
@@ -3,6 +3,21 @@ import { createIntl, createIntlCache } from "@formatjs/intl";
3
3
  import { TranslationContext } from "../../contexts/translation/TranslationContext";
4
4
  // Create a cache for @formatjs/intl to improve performance
5
5
  const cache = createIntlCache();
6
+ const flattenTranslations = (translations, parentKey = "", result = {}) => {
7
+ Object.entries(translations).forEach(([key, value]) => {
8
+ const translationKey = parentKey ? `${parentKey}.${key}` : key;
9
+ if (typeof value === "string") {
10
+ result[translationKey] = value;
11
+ return;
12
+ }
13
+ if (value && typeof value === "object" && !Array.isArray(value)) {
14
+ flattenTranslations(value, translationKey, result);
15
+ return;
16
+ }
17
+ console.error(`Invalid translation value for key "${translationKey}". Expected string or nested object.`);
18
+ });
19
+ return result;
20
+ };
6
21
  /**
7
22
  * Hook to manage translations in a React application using @formatjs/intl
8
23
  *
@@ -97,11 +112,18 @@ const useTranslation = (options) => {
97
112
  translations: validatedOptions.translations,
98
113
  error: null,
99
114
  });
115
+ const flattenedTranslations = useMemo(() => {
116
+ const locales = {};
117
+ Object.entries(state.translations).forEach(([locale, translations]) => {
118
+ locales[locale] = flattenTranslations(translations);
119
+ });
120
+ return locales;
121
+ }, [state.translations]);
100
122
  // Create intl instance with current locale and translations
101
123
  const intl = useMemo(() => {
102
- const currentTranslations = state.translations[state.locale];
124
+ const currentTranslations = flattenedTranslations[state.locale];
103
125
  const fallbackTranslations = validatedOptions.fallbackLocale &&
104
- state.translations[validatedOptions.fallbackLocale];
126
+ flattenedTranslations[validatedOptions.fallbackLocale];
105
127
  if (!currentTranslations && fallbackTranslations) {
106
128
  console.error(`No translations found for locale "${state.locale}". Using fallback locale "${validatedOptions.fallbackLocale}".`);
107
129
  return createIntl({
@@ -129,7 +151,7 @@ const useTranslation = (options) => {
129
151
  locale: state.locale,
130
152
  messages,
131
153
  }, cache);
132
- }, [state.locale, state.translations, validatedOptions.fallbackLocale]);
154
+ }, [state.locale, flattenedTranslations, validatedOptions.fallbackLocale]);
133
155
  // Simplified t() function using intl.formatMessage
134
156
  const t = useCallback((key, values) => {
135
157
  return intl.formatMessage({ id: key }, values);
@@ -1 +1 @@
1
- {"version":3,"file":"useTranslation.js","sourceRoot":"","sources":["../../../src/hooks/useTranslation/useTranslation.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"useTranslation.js","sourceRoot":"","sources":["../../../src/hooks/useTranslation/useTranslation.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,7 @@
1
1
  import type { IntlShape } from "@formatjs/intl";
2
- type Translations = Record<string, string>;
2
+ interface Translations {
3
+ [key: string]: string | Translations;
4
+ }
3
5
  type LanguageTranslations = Record<string, Translations>;
4
6
  type TranslationState<L extends string = string> = {
5
7
  locale: L;
package/esm/index.d.ts CHANGED
@@ -1,2 +1,4 @@
1
+ export * from "./clients";
1
2
  export * from "./contexts";
2
3
  export * from "./hooks";
4
+ export * from "./utils";
package/esm/index.js CHANGED
@@ -1,3 +1,5 @@
1
+ export * from "./clients";
1
2
  export * from "./contexts";
2
3
  export * from "./hooks";
4
+ export * from "./utils";
3
5
  //# sourceMappingURL=index.js.map
package/esm/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAA;AAC1B,cAAc,SAAS,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAA;AACzB,cAAc,YAAY,CAAA;AAC1B,cAAc,SAAS,CAAA;AACvB,cAAc,SAAS,CAAA"}
@@ -0,0 +1 @@
1
+ export { getStorageItem, removeStorageItem, setStorageItem } from "./storage";
@@ -0,0 +1,2 @@
1
+ export { getStorageItem, removeStorageItem, setStorageItem } from "./storage";
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Retrieves and parses a JSON value from localStorage.
3
+ * Returns the fallback value if the key doesn't exist, parsing fails,
4
+ * or localStorage throws an error.
5
+ *
6
+ * @template T - The expected type of the stored value
7
+ * @param key - The localStorage key to retrieve
8
+ * @param fallback - The value to return if retrieval fails
9
+ * @returns The parsed value or the fallback
10
+ *
11
+ * @example
12
+ * const isEnabled = getStorageItem<boolean>('feature_enabled', false)
13
+ * const user = getStorageItem<User | null>('current_user', null)
14
+ */
15
+ declare const getStorageItem: <T>(key: string, fallback: T) => T;
16
+ /**
17
+ * Stores a value in localStorage as JSON.
18
+ * Silently fails if localStorage throws an error.
19
+ *
20
+ * @template T - The type of the value to store
21
+ * @param key - The localStorage key
22
+ * @param value - The value to store (will be JSON stringified)
23
+ *
24
+ * @example
25
+ * setStorageItem('feature_enabled', true)
26
+ * setStorageItem('current_user', { id: 1, name: 'John' })
27
+ */
28
+ declare const setStorageItem: <T>(key: string, value: T) => void;
29
+ /**
30
+ * Removes a key from localStorage.
31
+ * Silently fails if localStorage throws an error.
32
+ *
33
+ * @param key - The localStorage key to remove
34
+ *
35
+ * @example
36
+ * removeStorageItem('current_user')
37
+ */
38
+ declare const removeStorageItem: (key: string) => void;
39
+ export { getStorageItem, removeStorageItem, setStorageItem };
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Retrieves and parses a JSON value from localStorage.
3
+ * Returns the fallback value if the key doesn't exist, parsing fails,
4
+ * or localStorage throws an error.
5
+ *
6
+ * @template T - The expected type of the stored value
7
+ * @param key - The localStorage key to retrieve
8
+ * @param fallback - The value to return if retrieval fails
9
+ * @returns The parsed value or the fallback
10
+ *
11
+ * @example
12
+ * const isEnabled = getStorageItem<boolean>('feature_enabled', false)
13
+ * const user = getStorageItem<User | null>('current_user', null)
14
+ */
15
+ const getStorageItem = (key, fallback) => {
16
+ try {
17
+ const value = localStorage.getItem(key);
18
+ if (value === null) {
19
+ return fallback;
20
+ }
21
+ return JSON.parse(value);
22
+ }
23
+ catch {
24
+ return fallback;
25
+ }
26
+ };
27
+ /**
28
+ * Stores a value in localStorage as JSON.
29
+ * Silently fails if localStorage throws an error.
30
+ *
31
+ * @template T - The type of the value to store
32
+ * @param key - The localStorage key
33
+ * @param value - The value to store (will be JSON stringified)
34
+ *
35
+ * @example
36
+ * setStorageItem('feature_enabled', true)
37
+ * setStorageItem('current_user', { id: 1, name: 'John' })
38
+ */
39
+ const setStorageItem = (key, value) => {
40
+ try {
41
+ localStorage.setItem(key, JSON.stringify(value));
42
+ }
43
+ catch {
44
+ // Ignore storage errors
45
+ }
46
+ };
47
+ /**
48
+ * Removes a key from localStorage.
49
+ * Silently fails if localStorage throws an error.
50
+ *
51
+ * @param key - The localStorage key to remove
52
+ *
53
+ * @example
54
+ * removeStorageItem('current_user')
55
+ */
56
+ const removeStorageItem = (key) => {
57
+ try {
58
+ localStorage.removeItem(key);
59
+ }
60
+ catch {
61
+ // Ignore storage errors
62
+ }
63
+ };
64
+ export { getStorageItem, removeStorageItem, setStorageItem };
65
+ //# sourceMappingURL=storage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage.js","sourceRoot":"","sources":["../../src/utils/storage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,MAAM,cAAc,GAAG,CAAI,GAAW,EAAE,QAAW,EAAK,EAAE;IACxD,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;QACvC,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YACnB,OAAO,QAAQ,CAAA;QACjB,CAAC;QACD,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAM,CAAA;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,QAAQ,CAAA;IACjB,CAAC;AACH,CAAC,CAAA;AAED;;;;;;;;;;;GAWG;AACH,MAAM,cAAc,GAAG,CAAI,GAAW,EAAE,KAAQ,EAAQ,EAAE;IACxD,IAAI,CAAC;QACH,YAAY,CAAC,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAA;IAClD,CAAC;IAAC,MAAM,CAAC;QACP,wBAAwB;IAC1B,CAAC;AACH,CAAC,CAAA;AAED;;;;;;;;GAQG;AACH,MAAM,iBAAiB,GAAG,CAAC,GAAW,EAAQ,EAAE;IAC9C,IAAI,CAAC;QACH,YAAY,CAAC,UAAU,CAAC,GAAG,CAAC,CAAA;IAC9B,CAAC;IAAC,MAAM,CAAC;QACP,wBAAwB;IAC1B,CAAC;AACH,CAAC,CAAA;AAED,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,cAAc,EAAE,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dcl/hooks",
3
- "version": "1.1.0",
3
+ "version": "1.1.1-20260130165526.commit-e8ee72c",
4
4
  "type": "module",
5
5
  "main": "esm/index.js",
6
6
  "module": "esm/index.js",
@@ -19,6 +19,7 @@
19
19
  "test:coverage": "npm run test -- --coverage"
20
20
  },
21
21
  "peerDependencies": {
22
+ "decentraland-crypto-fetch": "^2.0.1",
22
23
  "react": "^18.0.0"
23
24
  },
24
25
  "devDependencies": {
@@ -30,6 +31,7 @@
30
31
  "@types/ua-parser-js": "^0.7.39",
31
32
  "@typescript-eslint/eslint-plugin": "^7.15.0",
32
33
  "@typescript-eslint/parser": "^7.15.0",
34
+ "decentraland-crypto-fetch": "^2.0.1",
33
35
  "eslint": "^8.57.0",
34
36
  "eslint-config-prettier": "^9.1.0",
35
37
  "eslint-import-resolver-jest": "^3.0.2",
@@ -78,5 +80,5 @@
78
80
  "<rootDir>/test/setup.ts"
79
81
  ]
80
82
  },
81
- "commit": "7c01c67ea4f59e6cd131b191224dc86e24b568c5"
83
+ "commit": "e8ee72cf8c4f5342c8da501151fad8310c495ad5"
82
84
  }