-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsirenProvider.tsx
More file actions
178 lines (151 loc) · 4.95 KB
/
sirenProvider.tsx
File metadata and controls
178 lines (151 loc) · 4.95 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
import React, { createContext, useContext, useEffect, useState } from 'react';
import PubSub from 'pubsub-js';
import { Siren } from '@sirenapp/js-sdk';
import type {
InitConfigType,
NotificationDataType,
NotificationsApiResponse,
UnviewedCountApiResponse
} from '@sirenapp/js-sdk/dist/esm/types';
import type { SirenProviderConfigProps } from '../types';
import { generateUniqueId, isNonEmptyArray, logger } from '../utils/commonUtils';
import {
events,
eventTypes,
EventType
} from '../utils/constants';
import { useSiren } from '../utils';
type SirenContextProp = {
siren: Siren | null;
id: string;
};
interface SirenProvider {
config: SirenProviderConfigProps;
children: React.ReactNode;
}
export const SirenContext = createContext<SirenContextProp>({
siren: null,
id: ''
});
/**
* Use `useSirenContext` hook to access Siren notifications context within your component.
*
* @example
* const {
* siren,
* } = useSirenContext();
*
* @returns {SirenContextProp} The Siren notifications context.
*/
export const useSirenContext = (): SirenContextProp => useContext(SirenContext);
/**
* Provides a React context for Siren notifications, making Siren SDK functionality
* available throughout your React application.
*
* `SirenProvider` initializes the Siren SDK with given configuration and manages the state for siren.
*
* @component
* @example
* const config = {
* userToken: "user_token_here",
* recipientId: "recipient_id_here"
* };
*
* <SirenProvider config={config}>
* <YourComponent />
* </SirenProvider>
*
* @param {Object} props - Props for configuring the SirenProvider.
* @param {SirenProviderConfig} props.config - Configuration for initializing the Siren SDK.
* @param {React.ReactNode} props.children - Child components that will have access to the Siren context.
*/
const SirenProvider: React.FC<SirenProvider> = ({ config, children }) => {
const { markAllAsViewed } = useSiren();
const [id] = useState(generateUniqueId());
const [siren, setSiren] = useState<Siren | null>(null);
useEffect(() => {
if (config?.recipientId && config?.userToken) {
stopRealTimeFetch();
sendResetDataEvents();
initialize();
}
}, [config]);
const stopRealTimeFetch = (): void => {
siren?.stopRealTimeFetch(EventType.NOTIFICATION);
siren?.stopRealTimeFetch(EventType.UNVIEWED_COUNT);
};
const sendResetDataEvents = () => {
const updateCountPayload = {
action: eventTypes.RESET_NOTIFICATIONS_COUNT
};
const updateNotificationPayload = {
action: eventTypes.RESET_NOTIFICATIONS
};
PubSub.publish(`${events.NOTIFICATION_COUNT_EVENT}${id}`, JSON.stringify(updateCountPayload));
PubSub.publish(
`${events.NOTIFICATION_LIST_EVENT}${id}`,
JSON.stringify(updateNotificationPayload)
);
};
const onNewNotificationEvent = (responseData: NotificationDataType[]) => {
logger.info(`new notifications : ${JSON.stringify(responseData)}`);
markAllAsViewed(responseData[0].createdAt);
const payload = { newNotifications: responseData, action: eventTypes.NEW_NOTIFICATIONS };
PubSub.publish(`${events.NOTIFICATION_LIST_EVENT}${id}`, JSON.stringify(payload));
};
const onTotalUnviewedCountEvent = (response: UnviewedCountApiResponse) => {
const totalUnviewed = response.data?.totalUnviewed;
const payload = {
unviewedCount: totalUnviewed,
action: eventTypes.UPDATE_NOTIFICATIONS_COUNT
};
PubSub.publish(`${events.NOTIFICATION_COUNT_EVENT}${id}`, JSON.stringify(payload));
};
const handleNotificationEvent = (response: NotificationsApiResponse) => {
const responseData = response?.data;
if (Array.isArray(responseData) && isNonEmptyArray(responseData))
onNewNotificationEvent(responseData);
};
const handleUnviewedCountEvent = (response: UnviewedCountApiResponse) => {
const responseData = response?.data;
if (responseData && 'totalUnviewed' in responseData) onTotalUnviewedCountEvent(response);
};
const onEventReceive = (
response: NotificationsApiResponse | UnviewedCountApiResponse = {},
eventType: EventType
) => {
switch (eventType) {
case EventType.NOTIFICATION:
handleNotificationEvent(response as NotificationsApiResponse);
break;
case EventType.UNVIEWED_COUNT:
handleUnviewedCountEvent(response as UnviewedCountApiResponse);
break;
}
};
const actionCallbacks = { onEventReceive };
const getDataParams = () => {
return {
token: config.userToken,
recipientId: config.recipientId,
actionCallbacks: actionCallbacks
};
};
// Function to initialize the Siren SDK and fetch notifications
const initialize = (): void => {
const dataParams: InitConfigType = getDataParams();
const siren = new Siren(dataParams);
setSiren(siren);
};
return (
<SirenContext.Provider
value={{
id,
siren
}}
>
{children}
</SirenContext.Provider>
);
};
export default SirenProvider;