@notificationapi/react 1.1.4 → 1.3.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.
- package/README.md +19 -1
- package/dist/assets/PreferenceInput.js +46 -38
- package/dist/assets/channelUtils.js +24 -21
- package/dist/assets/createSvgIcon.js +10 -9
- package/dist/components/Notifications/interface.d.ts +2 -1
- package/dist/components/Notifications/interface.js +4 -4
- package/dist/components/Preferences/channelUtils.js +4 -3
- package/dist/components/Provider/index.d.ts +1 -0
- package/dist/components/Provider/index.js +447 -243
- package/dist/main.d.ts +1 -0
- package/dist/main.js +8 -6
- package/dist/utils/debug.d.ts +26 -0
- package/dist/utils/debug.js +61 -0
- package/package.json +7 -3
|
@@ -1,25 +1,26 @@
|
|
|
1
|
-
import { jsx as
|
|
2
|
-
import {
|
|
3
|
-
import { NotificationAPIContext as
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
import { jsx as te } from "react/jsx-runtime";
|
|
2
|
+
import { useMemo as B, useState as b, useCallback as N, useRef as R, useEffect as y, useContext as oe } from "react";
|
|
3
|
+
import { NotificationAPIContext as V } from "./context.js";
|
|
4
|
+
import { createDebugLogger as ie, formatApiCall as k } from "../../utils/debug.js";
|
|
5
|
+
const ne = async (i, e, g, s, c, p, w) => {
|
|
6
|
+
const h = re(s, c, p), f = await fetch(
|
|
7
|
+
`https://${e}/${s}/users/${encodeURIComponent(
|
|
8
|
+
c
|
|
9
|
+
)}/${g}`,
|
|
9
10
|
{
|
|
10
|
-
method:
|
|
11
|
-
body: JSON.stringify(
|
|
11
|
+
method: i,
|
|
12
|
+
body: JSON.stringify(w),
|
|
12
13
|
headers: {
|
|
13
|
-
Authorization: `Basic ${
|
|
14
|
+
Authorization: `Basic ${h}`
|
|
14
15
|
}
|
|
15
16
|
}
|
|
16
17
|
);
|
|
17
18
|
try {
|
|
18
|
-
return await
|
|
19
|
+
return await f.json();
|
|
19
20
|
} catch {
|
|
20
21
|
return;
|
|
21
22
|
}
|
|
22
|
-
},
|
|
23
|
+
}, re = (i, e, g) => btoa(g ? i + ":" + e + ":" + g : i + ":" + e), K = {
|
|
23
24
|
host: "api.notificationapi.com",
|
|
24
25
|
websocketHost: "ws.notificationapi.com",
|
|
25
26
|
userId: "",
|
|
@@ -32,79 +33,79 @@ const Z = async (e, c, i, a, f, b, h) => {
|
|
|
32
33
|
onNewInAppNotifications: void 0,
|
|
33
34
|
keepWebSocketAliveForSeconds: 86400
|
|
34
35
|
// 24 hours
|
|
35
|
-
},
|
|
36
|
-
config:
|
|
37
|
-
init: function(
|
|
38
|
-
return this.config = { ...
|
|
36
|
+
}, a = {
|
|
37
|
+
config: K,
|
|
38
|
+
init: function(i) {
|
|
39
|
+
return this.config = { ...K, ...i }, {
|
|
39
40
|
...this
|
|
40
41
|
};
|
|
41
42
|
},
|
|
42
43
|
rest: {
|
|
43
|
-
generic: function(
|
|
44
|
-
return
|
|
44
|
+
generic: function(i, e, g) {
|
|
45
|
+
return ne(
|
|
46
|
+
i,
|
|
47
|
+
a.config.host,
|
|
45
48
|
e,
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
o.config.hashedUserId,
|
|
51
|
-
i
|
|
49
|
+
a.config.clientId,
|
|
50
|
+
a.config.userId,
|
|
51
|
+
a.config.hashedUserId,
|
|
52
|
+
g
|
|
52
53
|
);
|
|
53
54
|
},
|
|
54
55
|
// The functions below are nice wrappers over the generic
|
|
55
56
|
// rest api function above. They must follow REST API naming:
|
|
56
57
|
// Method + Resource, representing the end-point.
|
|
57
|
-
getNotifications: function(
|
|
58
|
-
return
|
|
58
|
+
getNotifications: function(i, e) {
|
|
59
|
+
return a.rest.generic(
|
|
59
60
|
"GET",
|
|
60
|
-
`notifications/INAPP_WEB?count=${
|
|
61
|
+
`notifications/INAPP_WEB?count=${e}&before=${i}`
|
|
61
62
|
);
|
|
62
63
|
},
|
|
63
|
-
patchNotifications: function(
|
|
64
|
-
return
|
|
64
|
+
patchNotifications: function(i) {
|
|
65
|
+
return a.rest.generic(
|
|
65
66
|
"PATCH",
|
|
66
67
|
"notifications/INAPP_WEB",
|
|
67
|
-
|
|
68
|
+
i
|
|
68
69
|
);
|
|
69
70
|
},
|
|
70
71
|
getPreferences: function() {
|
|
71
|
-
return
|
|
72
|
+
return a.rest.generic("GET", "preferences");
|
|
72
73
|
},
|
|
73
|
-
postPreferences: function(
|
|
74
|
-
return
|
|
74
|
+
postPreferences: function(i) {
|
|
75
|
+
return a.rest.generic(
|
|
75
76
|
"POST",
|
|
76
77
|
"preferences",
|
|
77
|
-
|
|
78
|
+
i
|
|
78
79
|
);
|
|
79
80
|
},
|
|
80
|
-
postUser: function(
|
|
81
|
-
return
|
|
81
|
+
postUser: function(i) {
|
|
82
|
+
return a.rest.generic("POST", "", i);
|
|
82
83
|
},
|
|
83
84
|
getUserAccountMetadata: function() {
|
|
84
|
-
return
|
|
85
|
+
return a.rest.generic("GET", "account_metadata");
|
|
85
86
|
}
|
|
86
87
|
},
|
|
87
88
|
websocket: {
|
|
88
89
|
object: void 0,
|
|
89
90
|
connect: function() {
|
|
90
|
-
let
|
|
91
|
-
return
|
|
92
|
-
const
|
|
93
|
-
if (!(!
|
|
94
|
-
const
|
|
95
|
-
|
|
96
|
-
|
|
91
|
+
let i = `wss://${a.config.websocketHost}?userId=${encodeURIComponent(a.config.userId)}&envId=${a.config.clientId}`;
|
|
92
|
+
return a.config.hashedUserId && (i += `&userIdHash=${encodeURIComponent(a.config.hashedUserId)}`), a.websocket.object = new WebSocket(i), a.websocket.object.onmessage = (e) => {
|
|
93
|
+
const g = JSON.parse(e.data);
|
|
94
|
+
if (!(!g || !g.route) && g.route === "inapp_web/new_notifications") {
|
|
95
|
+
const s = g;
|
|
96
|
+
a.config.onNewInAppNotifications && a.config.onNewInAppNotifications(
|
|
97
|
+
s.payload.notifications
|
|
97
98
|
);
|
|
98
99
|
}
|
|
99
|
-
},
|
|
100
|
+
}, a.websocket.object;
|
|
100
101
|
},
|
|
101
|
-
disconnect: function(
|
|
102
|
-
var
|
|
103
|
-
|
|
102
|
+
disconnect: function(i) {
|
|
103
|
+
var e;
|
|
104
|
+
a.websocket.object && ((e = a.websocket.object) == null || e.close(), i && i(a.websocket.object));
|
|
104
105
|
}
|
|
105
106
|
},
|
|
106
107
|
openWebSocket: function() {
|
|
107
|
-
return
|
|
108
|
+
return a.websocket.connect(() => {
|
|
108
109
|
setTimeout(
|
|
109
110
|
() => {
|
|
110
111
|
this.websocket.disconnect(() => {
|
|
@@ -118,45 +119,55 @@ const Z = async (e, c, i, a, f, b, h) => {
|
|
|
118
119
|
// These functions are developer friendly wrappers over the rest APIs
|
|
119
120
|
// They may or may not do additional tasks.
|
|
120
121
|
// e.g. identify simply maps to postUsers
|
|
121
|
-
getInAppNotifications: async (
|
|
122
|
-
const
|
|
123
|
-
let
|
|
124
|
-
for (;
|
|
125
|
-
const
|
|
126
|
-
|
|
127
|
-
|
|
122
|
+
getInAppNotifications: async (i) => {
|
|
123
|
+
const e = i.maxCountNeeded || a.config.getInAppDefaultCount, g = i.oldestNeeded || a.config.getInAppDefaultOldest;
|
|
124
|
+
let s = [], c = i.before, p = !0, w = !0;
|
|
125
|
+
for (; w; ) {
|
|
126
|
+
const h = (await a.rest.getNotifications(
|
|
127
|
+
c,
|
|
128
|
+
e
|
|
128
129
|
)).notifications.filter(
|
|
129
|
-
(
|
|
130
|
+
(f) => !s.find((I) => I.id === f.id)
|
|
130
131
|
);
|
|
131
|
-
|
|
132
|
-
(
|
|
133
|
-
|
|
134
|
-
),
|
|
132
|
+
c = h.reduce(
|
|
133
|
+
(f, I) => f < I.date ? f : I.date,
|
|
134
|
+
i.before
|
|
135
|
+
), s = [...s, ...h], p = h.length > 0, w = !0, (!p || s.length >= e || c < g) && (w = !1);
|
|
135
136
|
}
|
|
136
137
|
return {
|
|
137
|
-
items:
|
|
138
|
-
hasMore:
|
|
139
|
-
oldestReceived:
|
|
138
|
+
items: s,
|
|
139
|
+
hasMore: p,
|
|
140
|
+
oldestReceived: c
|
|
140
141
|
};
|
|
141
142
|
},
|
|
142
|
-
updateInAppNotifications: async (
|
|
143
|
-
const
|
|
144
|
-
trackingIds:
|
|
143
|
+
updateInAppNotifications: async (i) => {
|
|
144
|
+
const e = {
|
|
145
|
+
trackingIds: i.ids
|
|
145
146
|
};
|
|
146
|
-
return
|
|
147
|
+
return i.archived === !0 ? e.archived = (/* @__PURE__ */ new Date()).toISOString() : i.archived === !1 && (e.archived = null), i.clicked === !0 ? e.clicked = (/* @__PURE__ */ new Date()).toISOString() : i.clicked === !1 && (e.clicked = null), i.opened === !0 ? e.opened = (/* @__PURE__ */ new Date()).toISOString() : i.opened === !1 && (e.opened = null), a.rest.patchNotifications(e);
|
|
147
148
|
},
|
|
148
|
-
getPreferences: async () =>
|
|
149
|
-
updateDeliveryOption: async (
|
|
150
|
-
identify: async (
|
|
151
|
-
if (
|
|
149
|
+
getPreferences: async () => a.rest.getPreferences(),
|
|
150
|
+
updateDeliveryOption: async (i) => a.rest.postPreferences([i]),
|
|
151
|
+
identify: async (i) => {
|
|
152
|
+
if (i.id && i.id !== a.config.userId)
|
|
152
153
|
throw new Error(
|
|
153
154
|
"The id in the parameters does not match the initialized userId."
|
|
154
155
|
);
|
|
155
|
-
return
|
|
156
|
+
return a.rest.postUser(i);
|
|
156
157
|
},
|
|
157
|
-
getUserAccountMetadata: async () =>
|
|
158
|
-
},
|
|
159
|
-
const
|
|
158
|
+
getUserAccountMetadata: async () => a.rest.getUserAccountMetadata()
|
|
159
|
+
}, G = typeof window < "u", se = (i) => {
|
|
160
|
+
const e = B(
|
|
161
|
+
() => ie(i.debug || !1),
|
|
162
|
+
[i.debug]
|
|
163
|
+
);
|
|
164
|
+
e.log("NotificationAPI Provider initializing", {
|
|
165
|
+
clientId: i.clientId,
|
|
166
|
+
userId: "userId" in i ? i.userId : i.user.id,
|
|
167
|
+
debug: i.debug || !1,
|
|
168
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
169
|
+
});
|
|
170
|
+
const s = {
|
|
160
171
|
...{
|
|
161
172
|
apiURL: "api.notificationapi.com",
|
|
162
173
|
wsURL: "ws.notificationapi.com",
|
|
@@ -167,153 +178,313 @@ const Z = async (e, c, i, a, f, b, h) => {
|
|
|
167
178
|
webPushOptInMessage: "AUTOMATIC",
|
|
168
179
|
customServiceWorkerPath: "/notificationapi-service-worker.js"
|
|
169
180
|
},
|
|
170
|
-
...
|
|
171
|
-
user: "userId" in
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
return !p && !D;
|
|
181
|
-
}), n = Array.isArray(n) ? n : [], [
|
|
182
|
-
...t.filter((d) => !n.find((D) => D.id === d.id)),
|
|
183
|
-
...n
|
|
184
|
-
]));
|
|
185
|
-
}, []), u = X(() => {
|
|
186
|
-
const t = e.client ? e.client : o.init({
|
|
187
|
-
clientId: i.clientId,
|
|
188
|
-
userId: i.user.id,
|
|
189
|
-
hashedUserId: i.hashedUserId,
|
|
190
|
-
onNewInAppNotifications: (s) => {
|
|
191
|
-
W(), P(s);
|
|
192
|
-
},
|
|
193
|
-
host: i.apiURL,
|
|
194
|
-
websocketHost: i.wsURL
|
|
195
|
-
});
|
|
196
|
-
return t.identify({
|
|
197
|
-
email: i.user.email,
|
|
198
|
-
number: i.user.number
|
|
199
|
-
}), t;
|
|
181
|
+
...i,
|
|
182
|
+
user: "userId" in i ? { id: i.userId } : i.user
|
|
183
|
+
};
|
|
184
|
+
e.log("Configuration loaded", s);
|
|
185
|
+
const [c, p] = b(), [w, h] = b(), [f, I] = b(), [E, C] = b(!1), [O, F] = b((/* @__PURE__ */ new Date()).toISOString()), [M, x] = b(!0), [P, m] = b(s.webPushOptInMessage), [S, J] = b(!1), q = N(() => {
|
|
186
|
+
s.playSoundOnNewNotification && (e.log("Playing notification sound", {
|
|
187
|
+
soundPath: s.newNotificationSoundPath
|
|
188
|
+
}), new Audio(s.newNotificationSoundPath).play().catch((n) => {
|
|
189
|
+
e.error("Failed to play new notification sound", n), console.log("Failed to play new notification sound:", n);
|
|
190
|
+
}));
|
|
200
191
|
}, [
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
192
|
+
s.newNotificationSoundPath,
|
|
193
|
+
s.playSoundOnNewNotification,
|
|
194
|
+
e
|
|
195
|
+
]), A = N(
|
|
196
|
+
(t) => {
|
|
197
|
+
e.group("Adding notifications to state"), e.log("Received notifications", {
|
|
198
|
+
count: (t == null ? void 0 : t.length) || 0,
|
|
199
|
+
notifications: t
|
|
200
|
+
});
|
|
201
|
+
const n = (/* @__PURE__ */ new Date()).toISOString();
|
|
202
|
+
p((o) => {
|
|
203
|
+
const r = (o == null ? void 0 : o.length) || 0;
|
|
204
|
+
e.log("Current notifications count", r), t = Array.isArray(t) ? t : [], t = t.filter((u) => {
|
|
205
|
+
const v = u.expDate && new Date(u.expDate).toISOString() > n, T = new Date(u.date).getTime() > new Date(n).getTime() + 1e3, z = !v && !T;
|
|
206
|
+
return z || e.log("Filtering out notification", {
|
|
207
|
+
id: u.id,
|
|
208
|
+
reason: v ? "expired" : "future",
|
|
209
|
+
expDate: u.expDate,
|
|
210
|
+
date: u.date
|
|
211
|
+
}), z;
|
|
212
|
+
}), o = Array.isArray(o) ? o : [];
|
|
213
|
+
const d = [
|
|
214
|
+
...t.filter((u) => {
|
|
215
|
+
const v = o.find((T) => T.id === u.id);
|
|
216
|
+
return v && e.log("Filtering out duplicate notification", { id: u.id }), !v;
|
|
217
|
+
}),
|
|
218
|
+
...o
|
|
219
|
+
];
|
|
220
|
+
return e.log("State updated", {
|
|
221
|
+
previousCount: r,
|
|
222
|
+
newCount: d.length,
|
|
223
|
+
addedCount: t.length
|
|
224
|
+
}), e.groupEnd(), d;
|
|
225
|
+
});
|
|
215
226
|
},
|
|
216
|
-
[
|
|
217
|
-
),
|
|
227
|
+
[e]
|
|
228
|
+
), l = B(() => {
|
|
229
|
+
e.group("Initializing NotificationAPI client");
|
|
230
|
+
const t = {
|
|
231
|
+
clientId: s.clientId,
|
|
232
|
+
userId: s.user.id,
|
|
233
|
+
hashedUserId: s.hashedUserId,
|
|
234
|
+
host: s.apiURL,
|
|
235
|
+
websocketHost: s.wsURL
|
|
236
|
+
};
|
|
237
|
+
e.log("Client configuration", t);
|
|
238
|
+
const n = i.client ? i.client : a.init({
|
|
239
|
+
...t,
|
|
240
|
+
onNewInAppNotifications: (r) => {
|
|
241
|
+
e.log("Received new in-app notifications via WebSocket", {
|
|
242
|
+
count: (r == null ? void 0 : r.length) || 0,
|
|
243
|
+
notifications: r
|
|
244
|
+
}), q(), A(r);
|
|
245
|
+
}
|
|
246
|
+
}), o = {
|
|
247
|
+
email: s.user.email,
|
|
248
|
+
number: s.user.number
|
|
249
|
+
};
|
|
250
|
+
return e.log("Identifying user", o), n.identify(o), e.groupEnd(), n;
|
|
251
|
+
}, [
|
|
252
|
+
s.clientId,
|
|
253
|
+
s.user.id,
|
|
254
|
+
s.user.email,
|
|
255
|
+
s.user.number,
|
|
256
|
+
s.hashedUserId,
|
|
257
|
+
A,
|
|
258
|
+
q,
|
|
259
|
+
i.client,
|
|
260
|
+
s.apiURL,
|
|
261
|
+
s.wsURL,
|
|
262
|
+
e
|
|
263
|
+
]), $ = N(
|
|
264
|
+
async (t, n) => {
|
|
265
|
+
var o;
|
|
266
|
+
e.group("Fetching notifications"), e.log(
|
|
267
|
+
"Fetch parameters",
|
|
268
|
+
k("GET", "/notifications", { date: t, count: n })
|
|
269
|
+
);
|
|
270
|
+
try {
|
|
271
|
+
const r = await l.rest.getNotifications(t, n);
|
|
272
|
+
e.log("Fetch successful", {
|
|
273
|
+
notificationsCount: ((o = r.notifications) == null ? void 0 : o.length) || 0,
|
|
274
|
+
oldestReceived: r.oldestReceived,
|
|
275
|
+
couldLoadMore: r.couldLoadMore
|
|
276
|
+
}), F(r.oldestReceived), x(r.couldLoadMore), A(r.notifications), e.groupEnd();
|
|
277
|
+
} catch (r) {
|
|
278
|
+
throw e.error("Failed to fetch notifications", r, { date: t, count: n }), e.groupEnd(), r;
|
|
279
|
+
}
|
|
280
|
+
},
|
|
281
|
+
[A, l.rest, e]
|
|
282
|
+
), U = R(M), D = R(E), j = R(O);
|
|
218
283
|
y(() => {
|
|
219
|
-
|
|
220
|
-
}, [
|
|
221
|
-
const
|
|
284
|
+
U.current = M, D.current = E, j.current = O;
|
|
285
|
+
}, [M, E, O]);
|
|
286
|
+
const L = N(
|
|
222
287
|
async (t) => {
|
|
223
|
-
if (
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
288
|
+
if (e.group(`Loading notifications (${t ? "initial" : "more"})`), e.log("Load conditions", {
|
|
289
|
+
initial: t,
|
|
290
|
+
hasMore: U.current,
|
|
291
|
+
loading: D.current
|
|
292
|
+
}), !t && (!U.current || D.current)) {
|
|
293
|
+
e.log("Skipping load - conditions not met"), e.groupEnd();
|
|
294
|
+
return;
|
|
295
|
+
}
|
|
296
|
+
C(!0), e.log("Loading started");
|
|
297
|
+
try {
|
|
298
|
+
await $(
|
|
299
|
+
t ? (/* @__PURE__ */ new Date()).toISOString() : j.current,
|
|
300
|
+
t ? s.initialLoadMaxCount : 1e3
|
|
301
|
+
), e.log("Loading completed successfully");
|
|
302
|
+
} catch (n) {
|
|
303
|
+
throw e.error("Loading failed", n), n;
|
|
304
|
+
} finally {
|
|
305
|
+
C(!1), e.groupEnd();
|
|
233
306
|
}
|
|
234
307
|
},
|
|
235
|
-
[
|
|
236
|
-
),
|
|
237
|
-
if (!
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
308
|
+
[s.initialLoadMaxCount, $, e]
|
|
309
|
+
), Q = async (t) => {
|
|
310
|
+
if (e.group("Marking notifications as clicked"), e.log("Requested IDs", t), !c) {
|
|
311
|
+
e.warn("No notifications available"), e.groupEnd();
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
const n = (/* @__PURE__ */ new Date()).toISOString(), o = c.filter((r) => t.includes(r.id) && !r.clicked).map((r) => r.id);
|
|
315
|
+
if (e.log("Filtered IDs for update", {
|
|
316
|
+
requestedCount: t.length,
|
|
317
|
+
actualCount: o.length,
|
|
318
|
+
ids: o
|
|
319
|
+
}), o.length === 0) {
|
|
320
|
+
e.log("No notifications to update"), e.groupEnd();
|
|
321
|
+
return;
|
|
322
|
+
}
|
|
323
|
+
try {
|
|
324
|
+
e.log(
|
|
325
|
+
"Updating notifications via API",
|
|
326
|
+
k("PUT", "/notifications/clicked", { ids: o })
|
|
327
|
+
), l.updateInAppNotifications({ ids: o, clicked: !0 }), p((r) => {
|
|
328
|
+
if (!r) return [];
|
|
329
|
+
const d = [...r];
|
|
330
|
+
return d.filter((u) => o.includes(u.id)).forEach((u) => {
|
|
331
|
+
u.clicked = n;
|
|
332
|
+
}), e.log("Local state updated", { updatedCount: o.length }), d;
|
|
333
|
+
}), e.groupEnd();
|
|
334
|
+
} catch (r) {
|
|
335
|
+
throw e.error("Failed to mark notifications as clicked", r, { ids: o }), e.groupEnd(), r;
|
|
336
|
+
}
|
|
337
|
+
}, X = async () => {
|
|
338
|
+
if (e.group("Marking notifications as opened"), !c) {
|
|
339
|
+
e.warn("No notifications available"), e.groupEnd();
|
|
340
|
+
return;
|
|
341
|
+
}
|
|
342
|
+
const t = (/* @__PURE__ */ new Date()).toISOString(), n = c.filter((o) => !o.opened || !o.seen).map((o) => o.id);
|
|
343
|
+
if (e.log("Notifications to mark as opened", { count: n.length, ids: n }), n.length === 0) {
|
|
344
|
+
e.log("All notifications already opened"), e.groupEnd();
|
|
345
|
+
return;
|
|
346
|
+
}
|
|
347
|
+
try {
|
|
348
|
+
e.log(
|
|
349
|
+
"Updating notifications via API",
|
|
350
|
+
k("PUT", "/notifications/opened", { ids: n })
|
|
351
|
+
), l.updateInAppNotifications({
|
|
352
|
+
ids: n,
|
|
353
|
+
opened: !0
|
|
354
|
+
}), p((o) => {
|
|
355
|
+
if (!o) return [];
|
|
356
|
+
const r = [...o];
|
|
357
|
+
return r.filter((d) => n.includes(d.id)).forEach((d) => {
|
|
358
|
+
d.opened = t, d.seen = !0;
|
|
359
|
+
}), e.log("Local state updated", { updatedCount: n.length }), r;
|
|
360
|
+
}), e.groupEnd();
|
|
361
|
+
} catch (o) {
|
|
362
|
+
throw e.error("Failed to mark notifications as opened", o, { ids: n }), e.groupEnd(), o;
|
|
363
|
+
}
|
|
364
|
+
}, Y = async (t) => {
|
|
365
|
+
if (e.group("Marking notifications as unarchived"), e.log("Requested operation", { ids: t }), !c) {
|
|
366
|
+
e.warn("No notifications available"), e.groupEnd();
|
|
367
|
+
return;
|
|
368
|
+
}
|
|
369
|
+
const n = c.filter((o) => o.archived && (t === "ALL" || t.includes(o.id))).map((o) => o.id);
|
|
370
|
+
if (e.log("Filtered notifications for unarchiving", {
|
|
371
|
+
count: n.length,
|
|
372
|
+
ids: n
|
|
373
|
+
}), n.length === 0) {
|
|
374
|
+
e.log("No archived notifications to unarchive"), e.groupEnd();
|
|
375
|
+
return;
|
|
376
|
+
}
|
|
377
|
+
try {
|
|
378
|
+
e.log(
|
|
379
|
+
"Updating notifications via API",
|
|
380
|
+
k("PUT", "/notifications/unarchived", { ids: n })
|
|
381
|
+
), l.updateInAppNotifications({
|
|
382
|
+
ids: n,
|
|
383
|
+
archived: !1
|
|
384
|
+
}), p((o) => {
|
|
385
|
+
if (!o) return [];
|
|
386
|
+
const r = [...o];
|
|
387
|
+
return r.filter((d) => n.includes(d.id)).forEach((d) => {
|
|
388
|
+
d.archived = void 0;
|
|
389
|
+
}), e.log("Local state updated", { unarchivedCount: n.length }), r;
|
|
390
|
+
}), e.groupEnd();
|
|
391
|
+
} catch (o) {
|
|
392
|
+
throw e.error("Failed to unarchive notifications", o, { ids: n }), e.groupEnd(), o;
|
|
393
|
+
}
|
|
394
|
+
}, Z = async (t) => {
|
|
395
|
+
if (e.group("Marking notifications as archived"), e.log("Requested operation", { ids: t }), !c) {
|
|
396
|
+
e.warn("No notifications available"), e.groupEnd();
|
|
397
|
+
return;
|
|
398
|
+
}
|
|
399
|
+
const n = (/* @__PURE__ */ new Date()).toISOString(), o = c.filter((r) => !r.archived && (t === "ALL" || t.includes(r.id))).map((r) => r.id);
|
|
400
|
+
if (e.log("Filtered notifications for archiving", {
|
|
401
|
+
count: o.length,
|
|
402
|
+
ids: o
|
|
403
|
+
}), o.length === 0) {
|
|
404
|
+
e.log("No unarchived notifications to archive"), e.groupEnd();
|
|
405
|
+
return;
|
|
406
|
+
}
|
|
407
|
+
try {
|
|
408
|
+
e.log(
|
|
409
|
+
"Updating notifications via API",
|
|
410
|
+
k("PUT", "/notifications/archived", { ids: o })
|
|
411
|
+
), l.updateInAppNotifications({ ids: o, archived: !0 }), p((r) => {
|
|
412
|
+
if (!r) return [];
|
|
413
|
+
const d = [...r];
|
|
414
|
+
return d.filter((u) => o.includes(u.id)).forEach((u) => {
|
|
415
|
+
u.archived = n;
|
|
416
|
+
}), e.log("Local state updated", { archivedCount: o.length }), d;
|
|
417
|
+
}), e.groupEnd();
|
|
418
|
+
} catch (r) {
|
|
419
|
+
throw e.error("Failed to archive notifications", r, { ids: o }), e.groupEnd(), r;
|
|
420
|
+
}
|
|
421
|
+
}, _ = (t, n, o, r) => (e.log("Updating single delivery preference", {
|
|
422
|
+
notificationId: t,
|
|
423
|
+
channel: n,
|
|
424
|
+
delivery: o,
|
|
425
|
+
subNotificationId: r
|
|
426
|
+
}), H([
|
|
283
427
|
{
|
|
284
428
|
notificationId: t,
|
|
285
|
-
channel:
|
|
286
|
-
delivery:
|
|
429
|
+
channel: n,
|
|
430
|
+
delivery: o,
|
|
287
431
|
subNotificationId: r
|
|
288
432
|
}
|
|
289
|
-
]),
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
433
|
+
])), H = (t) => {
|
|
434
|
+
e.group("Updating delivery preferences"), e.log("Preference updates", { count: t.length, params: t });
|
|
435
|
+
try {
|
|
436
|
+
l.rest.postPreferences(t).then(() => {
|
|
437
|
+
e.log(
|
|
438
|
+
"Preferences updated successfully, fetching latest preferences"
|
|
439
|
+
), l.getPreferences().then((n) => {
|
|
440
|
+
var o, r, d;
|
|
441
|
+
e.log("Latest preferences fetched", {
|
|
442
|
+
preferencesCount: ((o = n.preferences) == null ? void 0 : o.length) || 0,
|
|
443
|
+
notificationsCount: ((r = n.notifications) == null ? void 0 : r.length) || 0,
|
|
444
|
+
subNotificationsCount: ((d = n.subNotifications) == null ? void 0 : d.length) || 0
|
|
445
|
+
}), h(n), e.groupEnd();
|
|
446
|
+
}).catch((n) => {
|
|
447
|
+
e.error("Failed to fetch updated preferences", n), e.groupEnd();
|
|
448
|
+
});
|
|
449
|
+
}).catch((n) => {
|
|
450
|
+
e.error("Failed to update preferences", n, { params: t }), e.groupEnd();
|
|
293
451
|
});
|
|
294
|
-
})
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
452
|
+
} catch (n) {
|
|
453
|
+
throw e.error("Error in updateDeliveries", n, { params: t }), e.groupEnd(), n;
|
|
454
|
+
}
|
|
455
|
+
}, W = N(() => {
|
|
456
|
+
e.group("Requesting web push permission"), e.log("Service worker support check", {
|
|
457
|
+
supported: "serviceWorker" in navigator,
|
|
458
|
+
customServiceWorkerPath: s.customServiceWorkerPath
|
|
459
|
+
}), "serviceWorker" in navigator ? (e.log("Registering service worker"), navigator.serviceWorker.register(s.customServiceWorkerPath).then(async (t) => {
|
|
460
|
+
e.log("Service worker registered successfully"), m(!1), ce().then(async (n) => {
|
|
461
|
+
e.log("Notification permission result", { permission: n }), n === "granted" ? (e.log("Permission granted, subscribing to push manager"), await t.pushManager.subscribe({
|
|
299
462
|
userVisibleOnly: !0,
|
|
300
|
-
applicationServerKey:
|
|
301
|
-
}).then(async (
|
|
463
|
+
applicationServerKey: f == null ? void 0 : f.userAccountMetadata.environmentVapidPublicKey
|
|
464
|
+
}).then(async (o) => {
|
|
465
|
+
e.log("Push subscription successful");
|
|
302
466
|
const r = {
|
|
303
467
|
webPushTokens: [
|
|
304
468
|
{
|
|
305
469
|
sub: {
|
|
306
|
-
endpoint:
|
|
307
|
-
keys:
|
|
470
|
+
endpoint: o.toJSON().endpoint,
|
|
471
|
+
keys: o.toJSON().keys
|
|
308
472
|
}
|
|
309
473
|
}
|
|
310
474
|
]
|
|
311
475
|
};
|
|
312
|
-
await
|
|
313
|
-
}) :
|
|
476
|
+
e.log("Identifying user with web push tokens"), await l.identify(r), localStorage.setItem("hideWebPushOptInMessage", "true"), e.log("Web push setup completed successfully"), e.groupEnd();
|
|
477
|
+
})) : n === "denied" && (e.warn("Permission for notifications was denied"), console.log("Permission for notifications was denied"), e.groupEnd());
|
|
314
478
|
});
|
|
315
479
|
}).catch((t) => {
|
|
316
|
-
|
|
480
|
+
e.error(
|
|
481
|
+
"Service worker registration or push subscription failed",
|
|
482
|
+
t,
|
|
483
|
+
{
|
|
484
|
+
errorCode: t.code,
|
|
485
|
+
customServiceWorkerPath: s.customServiceWorkerPath
|
|
486
|
+
}
|
|
487
|
+
), t.code === 18 ? console.error(
|
|
317
488
|
"NotificationAPI guide: Probably you are not setup the service worker correctly. Please check the documentation at https://docs.notificationapi.com/guides/web-push#step-by-step-implementation Step 3: Service Worker Setup."
|
|
318
489
|
) : t.code === 19 ? console.error(
|
|
319
490
|
"The operation is aborted. This can happen if the user denies the permission request."
|
|
@@ -323,62 +494,95 @@ const Z = async (e, c, i, a, f, b, h) => {
|
|
|
323
494
|
"The operation is not allowed. This can happen if the user has blocked notifications for the site. Please check your browser site settings Notifications part."
|
|
324
495
|
) : t.code === 22 ? console.error(
|
|
325
496
|
"The operation is not supported. This can occur if the browser does not support the required features."
|
|
326
|
-
) : console.error(t);
|
|
327
|
-
});
|
|
497
|
+
) : console.error(t), e.groupEnd();
|
|
498
|
+
})) : (e.warn("Service worker not supported in this browser"), e.groupEnd());
|
|
328
499
|
}, [
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
500
|
+
l,
|
|
501
|
+
s.customServiceWorkerPath,
|
|
502
|
+
f == null ? void 0 : f.userAccountMetadata.environmentVapidPublicKey,
|
|
503
|
+
e
|
|
332
504
|
]);
|
|
333
505
|
y(() => {
|
|
334
|
-
|
|
335
|
-
|
|
506
|
+
e.group("Provider initialization effect"), e.log("Resetting state and loading initial data"), p([]), C(!1), h(void 0), F((/* @__PURE__ */ new Date()).toISOString()), x(!0), L(!0), e.log("Opening WebSocket connection"), l.openWebSocket(), e.log("Fetching user preferences"), l.getPreferences().then((t) => {
|
|
507
|
+
var n, o, r;
|
|
508
|
+
e.log("Initial preferences loaded", {
|
|
509
|
+
preferencesCount: ((n = t.preferences) == null ? void 0 : n.length) || 0,
|
|
510
|
+
notificationsCount: ((o = t.notifications) == null ? void 0 : o.length) || 0,
|
|
511
|
+
subNotificationsCount: ((r = t.subNotifications) == null ? void 0 : r.length) || 0
|
|
512
|
+
}), h(t), e.groupEnd();
|
|
513
|
+
}).catch((t) => {
|
|
514
|
+
e.error("Failed to fetch initial preferences", t), e.groupEnd();
|
|
336
515
|
});
|
|
337
|
-
}, [
|
|
338
|
-
|
|
339
|
-
|
|
516
|
+
}, [l, L, W, e]), y(() => {
|
|
517
|
+
e.group("Fetching user account metadata"), l.getUserAccountMetadata().then((t) => {
|
|
518
|
+
e.log("User account metadata loaded", {
|
|
519
|
+
hasWebPushEnabled: t.userAccountMetadata.hasWebPushEnabled,
|
|
520
|
+
environmentVapidPublicKey: t.userAccountMetadata.environmentVapidPublicKey ? "present" : "missing"
|
|
521
|
+
}), I(t), G && "Notification" in window && typeof Notification.requestPermission == "function" ? (e.log("Browser notification support detected", {
|
|
522
|
+
permission: Notification.permission
|
|
523
|
+
}), Notification.permission !== "default" && (e.log(
|
|
524
|
+
"Setting webPushOptInMessage to false (permission already set)"
|
|
525
|
+
), m(!1))) : (e.log(
|
|
526
|
+
"Browser notification not supported, using server setting",
|
|
527
|
+
{
|
|
528
|
+
hasWebPushEnabled: t.userAccountMetadata.hasWebPushEnabled
|
|
529
|
+
}
|
|
530
|
+
), m(t.userAccountMetadata.hasWebPushEnabled)), e.groupEnd();
|
|
531
|
+
}).catch((t) => {
|
|
532
|
+
e.error("Failed to fetch user account metadata", t), e.groupEnd();
|
|
340
533
|
});
|
|
341
|
-
}, [
|
|
342
|
-
|
|
343
|
-
localStorage.getItem("hideWebPushOptInMessage")
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
534
|
+
}, [l, e]), y(() => {
|
|
535
|
+
if (e.group("Handling webPushOptInMessage state"), e.log("webPushOptInMessage value", P), P === "AUTOMATIC") {
|
|
536
|
+
const t = localStorage.getItem("hideWebPushOptInMessage") === "true";
|
|
537
|
+
e.log("Automatic mode - checking localStorage", {
|
|
538
|
+
hideMessage: t,
|
|
539
|
+
shouldShow: !t
|
|
540
|
+
}), m(!t);
|
|
541
|
+
}
|
|
542
|
+
e.groupEnd();
|
|
543
|
+
}, [P, e]), y(() => {
|
|
544
|
+
e.group("Handling webPushOptIn state"), e.log("webPushOptIn state", S), S && (e.log("User opted in for web push, requesting permission"), W()), e.groupEnd();
|
|
545
|
+
}, [S, W, e]);
|
|
546
|
+
const ee = {
|
|
547
|
+
notifications: c,
|
|
548
|
+
preferences: w,
|
|
549
|
+
userAccountMetaData: f,
|
|
550
|
+
webPushOptInMessage: P,
|
|
551
|
+
loadNotifications: L,
|
|
552
|
+
markAsOpened: X,
|
|
553
|
+
markAsArchived: Z,
|
|
554
|
+
markAsUnarchived: Y,
|
|
555
|
+
markAsClicked: Q,
|
|
358
556
|
updateDelivery: _,
|
|
359
|
-
updateDeliveries:
|
|
360
|
-
getClient: () =>
|
|
361
|
-
setWebPushOptInMessage:
|
|
557
|
+
updateDeliveries: H,
|
|
558
|
+
getClient: () => l,
|
|
559
|
+
setWebPushOptInMessage: m,
|
|
362
560
|
setWebPushOptIn: J
|
|
363
561
|
};
|
|
364
|
-
return
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
562
|
+
return e.log("NotificationAPI Provider rendering", {
|
|
563
|
+
notificationsCount: (c == null ? void 0 : c.length) || 0,
|
|
564
|
+
hasPreferences: !!w,
|
|
565
|
+
hasUserAccountMetaData: !!f,
|
|
566
|
+
webPushOptInMessage: P,
|
|
567
|
+
webPushOptIn: S
|
|
568
|
+
}), /* @__PURE__ */ te(V.Provider, { value: ee, children: i.children });
|
|
569
|
+
}, ae = () => {
|
|
570
|
+
const i = oe(V);
|
|
571
|
+
if (!i)
|
|
368
572
|
throw new Error("useMyContext must be used within a MyProvider");
|
|
369
|
-
return
|
|
573
|
+
return i;
|
|
370
574
|
};
|
|
371
|
-
|
|
372
|
-
const
|
|
373
|
-
if (
|
|
575
|
+
se.useNotificationAPIContext = ae;
|
|
576
|
+
const ce = async () => {
|
|
577
|
+
if (G && "Notification" in window && typeof Notification.requestPermission == "function")
|
|
374
578
|
try {
|
|
375
579
|
return await Notification.requestPermission();
|
|
376
|
-
} catch (
|
|
377
|
-
return console.error("Error requesting notification permission:",
|
|
580
|
+
} catch (i) {
|
|
581
|
+
return console.error("Error requesting notification permission:", i), "default";
|
|
378
582
|
}
|
|
379
583
|
else
|
|
380
584
|
return console.warn("Web Push Notifications are not supported in this browser."), "default";
|
|
381
585
|
};
|
|
382
586
|
export {
|
|
383
|
-
|
|
587
|
+
se as NotificationAPIProvider
|
|
384
588
|
};
|