@notificationapi/react 1.0.2 → 1.1.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/dist/assets/DefaultPropsProvider.js +61 -0
- package/dist/assets/Inbox.js +359 -349
- package/dist/assets/Notification.js +7 -2
- package/dist/components/Notifications/Inbox.d.ts +1 -0
- package/dist/components/Notifications/Notification.d.ts +1 -0
- package/dist/components/Notifications/NotificationFeed.d.ts +1 -0
- package/dist/components/Notifications/NotificationFeed.js +24 -22
- package/dist/components/Notifications/NotificationLauncher.js +36 -30
- package/dist/components/Notifications/NotificationPopup.d.ts +6 -0
- package/dist/components/Notifications/NotificationPopup.js +53 -45
- package/dist/components/Provider/index.d.ts +3 -3
- package/dist/components/Provider/index.js +84 -80
- package/package.json +6 -2
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { jsx as Q } from "react/jsx-runtime";
|
|
2
|
-
import { useState as I, useCallback as m, useMemo as X, useRef as
|
|
2
|
+
import { useState as I, useCallback as m, useMemo as X, useRef as U, useEffect as P, useContext as Y } from "react";
|
|
3
3
|
import { NotificationAPIContext as H } from "./context.js";
|
|
4
|
-
const Z = async (e, c,
|
|
5
|
-
const l = ee(a, f,
|
|
4
|
+
const Z = async (e, c, i, a, f, b, h) => {
|
|
5
|
+
const l = ee(a, f, b), g = await fetch(
|
|
6
6
|
`https://${c}/${a}/users/${encodeURIComponent(
|
|
7
7
|
f
|
|
8
|
-
)}/${
|
|
8
|
+
)}/${i}`,
|
|
9
9
|
{
|
|
10
10
|
method: e,
|
|
11
11
|
body: JSON.stringify(h),
|
|
@@ -19,7 +19,7 @@ const Z = async (e, c, o, a, f, N, h) => {
|
|
|
19
19
|
} catch {
|
|
20
20
|
return;
|
|
21
21
|
}
|
|
22
|
-
}, ee = (e, c,
|
|
22
|
+
}, ee = (e, c, i) => btoa(i ? e + ":" + c + ":" + i : e + ":" + c), q = {
|
|
23
23
|
host: "api.notificationapi.com",
|
|
24
24
|
websocketHost: "ws.notificationapi.com",
|
|
25
25
|
userId: "",
|
|
@@ -32,7 +32,7 @@ const Z = async (e, c, o, a, f, N, h) => {
|
|
|
32
32
|
onNewInAppNotifications: void 0,
|
|
33
33
|
keepWebSocketAliveForSeconds: 86400
|
|
34
34
|
// 24 hours
|
|
35
|
-
},
|
|
35
|
+
}, o = {
|
|
36
36
|
config: q,
|
|
37
37
|
init: function(e) {
|
|
38
38
|
return this.config = { ...q, ...e }, {
|
|
@@ -40,71 +40,71 @@ const Z = async (e, c, o, a, f, N, h) => {
|
|
|
40
40
|
};
|
|
41
41
|
},
|
|
42
42
|
rest: {
|
|
43
|
-
generic: function(e, c,
|
|
43
|
+
generic: function(e, c, i) {
|
|
44
44
|
return Z(
|
|
45
45
|
e,
|
|
46
|
-
|
|
46
|
+
o.config.host,
|
|
47
47
|
c,
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
48
|
+
o.config.clientId,
|
|
49
|
+
o.config.userId,
|
|
50
|
+
o.config.hashedUserId,
|
|
51
|
+
i
|
|
52
52
|
);
|
|
53
53
|
},
|
|
54
54
|
// The functions below are nice wrappers over the generic
|
|
55
55
|
// rest api function above. They must follow REST API naming:
|
|
56
56
|
// Method + Resource, representing the end-point.
|
|
57
57
|
getNotifications: function(e, c) {
|
|
58
|
-
return
|
|
58
|
+
return o.rest.generic(
|
|
59
59
|
"GET",
|
|
60
60
|
`notifications/INAPP_WEB?count=${c}&before=${e}`
|
|
61
61
|
);
|
|
62
62
|
},
|
|
63
63
|
patchNotifications: function(e) {
|
|
64
|
-
return
|
|
64
|
+
return o.rest.generic(
|
|
65
65
|
"PATCH",
|
|
66
66
|
"notifications/INAPP_WEB",
|
|
67
67
|
e
|
|
68
68
|
);
|
|
69
69
|
},
|
|
70
70
|
getPreferences: function() {
|
|
71
|
-
return
|
|
71
|
+
return o.rest.generic("GET", "preferences");
|
|
72
72
|
},
|
|
73
73
|
postPreferences: function(e) {
|
|
74
|
-
return
|
|
74
|
+
return o.rest.generic(
|
|
75
75
|
"POST",
|
|
76
76
|
"preferences",
|
|
77
77
|
e
|
|
78
78
|
);
|
|
79
79
|
},
|
|
80
80
|
postUser: function(e) {
|
|
81
|
-
return
|
|
81
|
+
return o.rest.generic("POST", "", e);
|
|
82
82
|
},
|
|
83
83
|
getUserAccountMetadata: function() {
|
|
84
|
-
return
|
|
84
|
+
return o.rest.generic("GET", "account_metadata");
|
|
85
85
|
}
|
|
86
86
|
},
|
|
87
87
|
websocket: {
|
|
88
88
|
object: void 0,
|
|
89
89
|
connect: function() {
|
|
90
|
-
let e = `wss://${
|
|
91
|
-
return
|
|
92
|
-
const
|
|
93
|
-
if (!(!
|
|
94
|
-
const a =
|
|
95
|
-
|
|
90
|
+
let e = `wss://${o.config.websocketHost}?userId=${encodeURIComponent(o.config.userId)}&envId=${o.config.clientId}`;
|
|
91
|
+
return o.config.hashedUserId && (e += `&userIdHash=${encodeURIComponent(o.config.hashedUserId)}`), o.websocket.object = new WebSocket(e), o.websocket.object.onmessage = (c) => {
|
|
92
|
+
const i = JSON.parse(c.data);
|
|
93
|
+
if (!(!i || !i.route) && i.route === "inapp_web/new_notifications") {
|
|
94
|
+
const a = i;
|
|
95
|
+
o.config.onNewInAppNotifications && o.config.onNewInAppNotifications(
|
|
96
96
|
a.payload.notifications
|
|
97
97
|
);
|
|
98
98
|
}
|
|
99
|
-
},
|
|
99
|
+
}, o.websocket.object;
|
|
100
100
|
},
|
|
101
101
|
disconnect: function(e) {
|
|
102
102
|
var c;
|
|
103
|
-
|
|
103
|
+
o.websocket.object && ((c = o.websocket.object) == null || c.close(), e && e(o.websocket.object));
|
|
104
104
|
}
|
|
105
105
|
},
|
|
106
106
|
openWebSocket: function() {
|
|
107
|
-
return
|
|
107
|
+
return o.websocket.connect(() => {
|
|
108
108
|
setTimeout(
|
|
109
109
|
() => {
|
|
110
110
|
this.websocket.disconnect(() => {
|
|
@@ -119,10 +119,10 @@ const Z = async (e, c, o, a, f, N, h) => {
|
|
|
119
119
|
// They may or may not do additional tasks.
|
|
120
120
|
// e.g. identify simply maps to postUsers
|
|
121
121
|
getInAppNotifications: async (e) => {
|
|
122
|
-
const c = e.maxCountNeeded ||
|
|
123
|
-
let a = [], f = e.before,
|
|
122
|
+
const c = e.maxCountNeeded || o.config.getInAppDefaultCount, i = e.oldestNeeded || o.config.getInAppDefaultOldest;
|
|
123
|
+
let a = [], f = e.before, b = !0, h = !0;
|
|
124
124
|
for (; h; ) {
|
|
125
|
-
const l = (await
|
|
125
|
+
const l = (await o.rest.getNotifications(
|
|
126
126
|
f,
|
|
127
127
|
c
|
|
128
128
|
)).notifications.filter(
|
|
@@ -131,11 +131,11 @@ const Z = async (e, c, o, a, f, N, h) => {
|
|
|
131
131
|
f = l.reduce(
|
|
132
132
|
(g, w) => g < w.date ? g : w.date,
|
|
133
133
|
e.before
|
|
134
|
-
), a = [...a, ...l],
|
|
134
|
+
), a = [...a, ...l], b = l.length > 0, h = !0, (!b || a.length >= c || f < i) && (h = !1);
|
|
135
135
|
}
|
|
136
136
|
return {
|
|
137
137
|
items: a,
|
|
138
|
-
hasMore:
|
|
138
|
+
hasMore: b,
|
|
139
139
|
oldestReceived: f
|
|
140
140
|
};
|
|
141
141
|
},
|
|
@@ -143,23 +143,23 @@ const Z = async (e, c, o, a, f, N, h) => {
|
|
|
143
143
|
const c = {
|
|
144
144
|
trackingIds: e.ids
|
|
145
145
|
};
|
|
146
|
-
return e.archived === !0 ? c.archived = (/* @__PURE__ */ new Date()).toISOString() : e.archived === !1 && (c.archived = null), e.clicked === !0 ? c.clicked = (/* @__PURE__ */ new Date()).toISOString() : e.clicked === !1 && (c.clicked = null), e.opened === !0 ? c.opened = (/* @__PURE__ */ new Date()).toISOString() : e.opened === !1 && (c.opened = null),
|
|
146
|
+
return e.archived === !0 ? c.archived = (/* @__PURE__ */ new Date()).toISOString() : e.archived === !1 && (c.archived = null), e.clicked === !0 ? c.clicked = (/* @__PURE__ */ new Date()).toISOString() : e.clicked === !1 && (c.clicked = null), e.opened === !0 ? c.opened = (/* @__PURE__ */ new Date()).toISOString() : e.opened === !1 && (c.opened = null), o.rest.patchNotifications(c);
|
|
147
147
|
},
|
|
148
|
-
getPreferences: async () =>
|
|
149
|
-
updateDeliveryOption: async (e) =>
|
|
148
|
+
getPreferences: async () => o.rest.getPreferences(),
|
|
149
|
+
updateDeliveryOption: async (e) => o.rest.postPreferences([e]),
|
|
150
150
|
identify: async (e) => {
|
|
151
|
-
if (e.id && e.id !==
|
|
151
|
+
if (e.id && e.id !== o.config.userId)
|
|
152
152
|
throw new Error(
|
|
153
153
|
"The id in the parameters does not match the initialized userId."
|
|
154
154
|
);
|
|
155
|
-
return
|
|
155
|
+
return o.rest.postUser(e);
|
|
156
156
|
},
|
|
157
|
-
getUserAccountMetadata: async () =>
|
|
157
|
+
getUserAccountMetadata: async () => o.rest.getUserAccountMetadata()
|
|
158
158
|
}, F = typeof window < "u", te = (e) => {
|
|
159
|
-
const
|
|
159
|
+
const i = {
|
|
160
160
|
...{
|
|
161
|
-
apiURL: "
|
|
162
|
-
wsURL: "
|
|
161
|
+
apiURL: "api.notificationapi.com",
|
|
162
|
+
wsURL: "ws.notificationapi.com",
|
|
163
163
|
initialLoadMaxCount: 1e3,
|
|
164
164
|
initialLoadMaxAge: new Date((/* @__PURE__ */ new Date()).setMonth((/* @__PURE__ */ new Date()).getMonth() - 3)),
|
|
165
165
|
playSoundOnNewNotification: !1,
|
|
@@ -169,11 +169,11 @@ const Z = async (e, c, o, a, f, N, h) => {
|
|
|
169
169
|
},
|
|
170
170
|
...e,
|
|
171
171
|
user: "userId" in e ? { id: e.userId } : e.user
|
|
172
|
-
}, [a, f] = I(), [
|
|
173
|
-
|
|
172
|
+
}, [a, f] = I(), [b, h] = I(), [l, g] = I(), [w, S] = I(!1), [k, T] = I((/* @__PURE__ */ new Date()).toISOString()), [A, C] = I(!0), [v, N] = I(i.webPushOptInMessage), [L, J] = I(!1), W = m(() => {
|
|
173
|
+
i.playSoundOnNewNotification && new Audio(i.newNotificationSoundPath).play().catch((s) => {
|
|
174
174
|
console.log("Failed to play new notification sound:", s);
|
|
175
175
|
});
|
|
176
|
-
}, [
|
|
176
|
+
}, [i.newNotificationSoundPath, i.playSoundOnNewNotification]), y = m((t) => {
|
|
177
177
|
const s = (/* @__PURE__ */ new Date()).toISOString();
|
|
178
178
|
f((n) => (t = Array.isArray(t) ? t : [], t = t.filter((d) => {
|
|
179
179
|
const p = d.expDate && new Date(d.expDate * 1e3).toISOString() < s, D = new Date(d.date).getTime() > new Date(s).getTime() + 1e3;
|
|
@@ -183,52 +183,56 @@ const Z = async (e, c, o, a, f, N, h) => {
|
|
|
183
183
|
...n
|
|
184
184
|
]));
|
|
185
185
|
}, []), u = X(() => {
|
|
186
|
-
const t = e.client ? e.client :
|
|
187
|
-
clientId:
|
|
188
|
-
userId:
|
|
189
|
-
hashedUserId:
|
|
186
|
+
const t = e.client ? e.client : o.init({
|
|
187
|
+
clientId: i.clientId,
|
|
188
|
+
userId: i.user.id,
|
|
189
|
+
hashedUserId: i.hashedUserId,
|
|
190
190
|
onNewInAppNotifications: (s) => {
|
|
191
|
-
|
|
192
|
-
}
|
|
191
|
+
W(), y(s);
|
|
192
|
+
},
|
|
193
|
+
host: i.apiURL,
|
|
194
|
+
websocketHost: i.wsURL
|
|
193
195
|
});
|
|
194
196
|
return t.identify({
|
|
195
|
-
email:
|
|
196
|
-
number:
|
|
197
|
+
email: i.user.email,
|
|
198
|
+
number: i.user.number
|
|
197
199
|
}), t;
|
|
198
200
|
}, [
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
201
|
+
i.clientId,
|
|
202
|
+
i.user.id,
|
|
203
|
+
i.user.email,
|
|
204
|
+
i.user.number,
|
|
205
|
+
i.hashedUserId,
|
|
204
206
|
y,
|
|
205
|
-
|
|
206
|
-
e.client
|
|
207
|
-
|
|
207
|
+
W,
|
|
208
|
+
e.client,
|
|
209
|
+
i.apiURL,
|
|
210
|
+
i.wsURL
|
|
211
|
+
]), x = m(
|
|
208
212
|
async (t, s) => {
|
|
209
213
|
const n = await u.rest.getNotifications(t, s);
|
|
210
|
-
|
|
214
|
+
T(n.oldestReceived), C(n.couldLoadMore), y(n.notifications);
|
|
211
215
|
},
|
|
212
216
|
[y, u.rest]
|
|
213
|
-
),
|
|
217
|
+
), E = U(A), R = U(w), $ = U(k);
|
|
214
218
|
P(() => {
|
|
215
|
-
|
|
219
|
+
E.current = A, R.current = w, $.current = k;
|
|
216
220
|
}, [A, w, k]);
|
|
217
221
|
const O = m(
|
|
218
222
|
async (t) => {
|
|
219
|
-
if (!(!t && (!
|
|
223
|
+
if (!(!t && (!E.current || R.current))) {
|
|
220
224
|
S(!0);
|
|
221
225
|
try {
|
|
222
|
-
await
|
|
226
|
+
await x(
|
|
223
227
|
t ? (/* @__PURE__ */ new Date()).toISOString() : $.current,
|
|
224
|
-
t ?
|
|
228
|
+
t ? i.initialLoadMaxCount : 1e3
|
|
225
229
|
);
|
|
226
230
|
} finally {
|
|
227
231
|
S(!1);
|
|
228
232
|
}
|
|
229
233
|
}
|
|
230
234
|
},
|
|
231
|
-
[
|
|
235
|
+
[i.initialLoadMaxCount, x]
|
|
232
236
|
), B = async (t) => {
|
|
233
237
|
if (!a) return;
|
|
234
238
|
const s = (/* @__PURE__ */ new Date()).toISOString(), n = a.filter((r) => t.includes(r.id) && !r.clicked).map((r) => r.id);
|
|
@@ -289,8 +293,8 @@ const Z = async (e, c, o, a, f, N, h) => {
|
|
|
289
293
|
});
|
|
290
294
|
});
|
|
291
295
|
}, M = m(() => {
|
|
292
|
-
"serviceWorker" in navigator && navigator.serviceWorker.register(
|
|
293
|
-
|
|
296
|
+
"serviceWorker" in navigator && navigator.serviceWorker.register(i.customServiceWorkerPath).then(async (t) => {
|
|
297
|
+
N(!1), ne().then(async (s) => {
|
|
294
298
|
s === "granted" ? await t.pushManager.subscribe({
|
|
295
299
|
userVisibleOnly: !0,
|
|
296
300
|
applicationServerKey: l == null ? void 0 : l.userAccountMetadata.environmentVapidPublicKey
|
|
@@ -323,25 +327,25 @@ const Z = async (e, c, o, a, f, N, h) => {
|
|
|
323
327
|
});
|
|
324
328
|
}, [
|
|
325
329
|
u,
|
|
326
|
-
|
|
330
|
+
i.customServiceWorkerPath,
|
|
327
331
|
l == null ? void 0 : l.userAccountMetadata.environmentVapidPublicKey
|
|
328
332
|
]);
|
|
329
333
|
P(() => {
|
|
330
|
-
f([]), S(!1), h(void 0),
|
|
334
|
+
f([]), S(!1), h(void 0), T((/* @__PURE__ */ new Date()).toISOString()), C(!0), O(!0), u.openWebSocket(), u.getPreferences().then((t) => {
|
|
331
335
|
h(t);
|
|
332
336
|
});
|
|
333
337
|
}, [u, O, M]), P(() => {
|
|
334
|
-
F && "Notification" in window && typeof Notification.requestPermission == "function" && Notification.permission !== "default" &&
|
|
338
|
+
F && "Notification" in window && typeof Notification.requestPermission == "function" && Notification.permission !== "default" && N(!1), v === "AUTOMATIC" && (N(
|
|
335
339
|
localStorage.getItem("hideWebPushOptInMessage") !== "true"
|
|
336
340
|
), u.getUserAccountMetadata().then((t) => {
|
|
337
|
-
g(t),
|
|
341
|
+
g(t), N(t.userAccountMetadata.hasWebPushEnabled);
|
|
338
342
|
}));
|
|
339
343
|
}, [u, v]), P(() => {
|
|
340
|
-
|
|
341
|
-
}, [
|
|
344
|
+
L && M();
|
|
345
|
+
}, [L, M]);
|
|
342
346
|
const z = {
|
|
343
347
|
notifications: a,
|
|
344
|
-
preferences:
|
|
348
|
+
preferences: b,
|
|
345
349
|
userAccountMetaData: l,
|
|
346
350
|
webPushOptInMessage: v,
|
|
347
351
|
loadNotifications: O,
|
|
@@ -352,18 +356,18 @@ const Z = async (e, c, o, a, f, N, h) => {
|
|
|
352
356
|
updateDelivery: _,
|
|
353
357
|
updateDeliveries: j,
|
|
354
358
|
getClient: () => u,
|
|
355
|
-
setWebPushOptInMessage:
|
|
359
|
+
setWebPushOptInMessage: N,
|
|
356
360
|
setWebPushOptIn: J
|
|
357
361
|
};
|
|
358
362
|
return /* @__PURE__ */ Q(H.Provider, { value: z, children: e.children });
|
|
359
|
-
},
|
|
363
|
+
}, ie = () => {
|
|
360
364
|
const e = Y(H);
|
|
361
365
|
if (!e)
|
|
362
366
|
throw new Error("useMyContext must be used within a MyProvider");
|
|
363
367
|
return e;
|
|
364
368
|
};
|
|
365
|
-
te.useNotificationAPIContext =
|
|
366
|
-
const
|
|
369
|
+
te.useNotificationAPIContext = ie;
|
|
370
|
+
const ne = async () => {
|
|
367
371
|
if (F && "Notification" in window && typeof Notification.requestPermission == "function")
|
|
368
372
|
try {
|
|
369
373
|
return await Notification.requestPermission();
|
package/package.json
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@notificationapi/react",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "1.0
|
|
4
|
+
"version": "1.1.0",
|
|
5
5
|
"type": "module",
|
|
6
|
+
"overrides": {
|
|
7
|
+
"esbuild": "^0.25.0",
|
|
8
|
+
"vue-template-compiler": "^2.7.16"
|
|
9
|
+
},
|
|
6
10
|
"browserslist": [
|
|
7
11
|
"last 2 versions",
|
|
8
12
|
"last 2 ChromeAndroid versions",
|
|
@@ -59,7 +63,7 @@
|
|
|
59
63
|
"@fontsource/roboto": "^5.1.1",
|
|
60
64
|
"@mui/icons-material": "^6.3.1",
|
|
61
65
|
"@mui/material": "^6.3.1",
|
|
62
|
-
"@notificationapi/core": "^0.0.
|
|
66
|
+
"@notificationapi/core": "^0.0.15",
|
|
63
67
|
"javascript-time-ago": "^2.5.10",
|
|
64
68
|
"liquidjs": "^10.14.0",
|
|
65
69
|
"rc-virtual-list": "^3.11.5",
|