@kolektor/nucleus-notifications 0.0.12-pre.7931 → 0.1.0-pre.124
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 +7 -0
- package/esm2022/index.mjs +4 -0
- package/esm2022/kolektor-nucleus-notifications.mjs +5 -0
- package/esm2022/lib/models.mjs +23 -0
- package/esm2022/lib/nucleus-notifications.module.mjs +25 -0
- package/esm2022/lib/nucleus-notifications.service.mjs +359 -0
- package/{fesm2020 → fesm2022}/kolektor-nucleus-notifications.mjs +388 -389
- package/fesm2022/kolektor-nucleus-notifications.mjs.map +1 -0
- package/index.d.ts +3 -5
- package/lib/models.d.ts +65 -65
- package/lib/nucleus-notifications.module.d.ts +9 -9
- package/lib/nucleus-notifications.service.d.ts +56 -56
- package/package.json +25 -31
- package/esm2020/kolektor-nucleus-notifications.mjs +0 -5
- package/esm2020/lib/models.mjs +0 -23
- package/esm2020/lib/nucleus-notifications.module.mjs +0 -25
- package/esm2020/lib/nucleus-notifications.service.mjs +0 -356
- package/esm2020/public-api.mjs +0 -7
- package/fesm2015/kolektor-nucleus-notifications.mjs +0 -412
- package/fesm2015/kolektor-nucleus-notifications.mjs.map +0 -1
- package/fesm2020/kolektor-nucleus-notifications.mjs.map +0 -1
- package/public-api.d.ts +0 -3
|
@@ -6,401 +6,400 @@ import { PushNotifications } from '@capacitor/push-notifications';
|
|
|
6
6
|
import * as i3 from '@kolektor/nucleus-common';
|
|
7
7
|
import { Subject, of } from 'rxjs';
|
|
8
8
|
|
|
9
|
-
class Notification {
|
|
10
|
-
}
|
|
11
|
-
class Identity {
|
|
12
|
-
}
|
|
13
|
-
class Recipient {
|
|
14
|
-
}
|
|
15
|
-
class NotificationData {
|
|
16
|
-
}
|
|
17
|
-
class WebKey {
|
|
18
|
-
}
|
|
19
|
-
class Registration {
|
|
20
|
-
}
|
|
21
|
-
class RegistrationResult {
|
|
22
|
-
}
|
|
23
|
-
class PayloadData {
|
|
24
|
-
}
|
|
25
|
-
class NucleusNotificationsConfig {
|
|
26
|
-
}
|
|
27
|
-
class NotificationClick {
|
|
28
|
-
}
|
|
29
|
-
class UserChannelConfig {
|
|
9
|
+
class Notification {
|
|
10
|
+
}
|
|
11
|
+
class Identity {
|
|
12
|
+
}
|
|
13
|
+
class Recipient {
|
|
14
|
+
}
|
|
15
|
+
class NotificationData {
|
|
16
|
+
}
|
|
17
|
+
class WebKey {
|
|
18
|
+
}
|
|
19
|
+
class Registration {
|
|
20
|
+
}
|
|
21
|
+
class RegistrationResult {
|
|
22
|
+
}
|
|
23
|
+
class PayloadData {
|
|
24
|
+
}
|
|
25
|
+
class NucleusNotificationsConfig {
|
|
26
|
+
}
|
|
27
|
+
class NotificationClick {
|
|
28
|
+
}
|
|
29
|
+
class UserChannelConfig {
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
this.
|
|
36
|
-
this.
|
|
37
|
-
this.
|
|
38
|
-
this.registrationStorageKey = 'NucleusNotificationsRegistrationId';
|
|
39
|
-
this.notificationsStorageKey = 'NucleusNotificationsLocalCache';
|
|
40
|
-
this._isInitialized = false;
|
|
41
|
-
this._newNotifications = new Subject();
|
|
42
|
-
this._clicksSubject = new Subject();
|
|
43
|
-
this._stateChangesSubject = new Subject();
|
|
44
|
-
this.notifications = [];
|
|
45
|
-
let url = config.serverApiUrl;
|
|
46
|
-
if (!url.endsWith('/')) {
|
|
47
|
-
url += '/';
|
|
48
|
-
}
|
|
49
|
-
this.apiUrl = url;
|
|
50
|
-
}
|
|
51
|
-
get unreadCount() {
|
|
52
|
-
return this.notifications.filter(x => !x.isRead).length;
|
|
53
|
-
}
|
|
54
|
-
get newNotifications() {
|
|
55
|
-
return this._newNotifications.asObservable();
|
|
56
|
-
}
|
|
57
|
-
get clicks() {
|
|
58
|
-
return this._clicksSubject.asObservable();
|
|
59
|
-
}
|
|
60
|
-
get stateChanges() {
|
|
61
|
-
return this._stateChangesSubject.asObservable();
|
|
62
|
-
}
|
|
63
|
-
get isInitialized() {
|
|
64
|
-
return this._isInitialized;
|
|
65
|
-
}
|
|
66
|
-
async initialize() {
|
|
67
|
-
// make sure app service has finished initializing
|
|
68
|
-
await this.appService.init();
|
|
69
|
-
this.loadFromStorage();
|
|
70
|
-
if (this.appService.isNative) {
|
|
71
|
-
this._platform = this.appService.deviceInfo.platform;
|
|
72
|
-
await this.registerCapacitorEvents();
|
|
73
|
-
}
|
|
74
|
-
else if (this.swPush.isEnabled) {
|
|
75
|
-
this._platform = 'web';
|
|
76
|
-
this.registerWebPushEvents();
|
|
77
|
-
}
|
|
78
|
-
else {
|
|
79
|
-
console.warn('Nucleus.Notifications: There is no push capability, timer will be used to update notifications');
|
|
80
|
-
setInterval(() => {
|
|
81
|
-
console.log('Updating notifications...');
|
|
82
|
-
this.refresh(true);
|
|
83
|
-
}, 5 * 60 * 1000);
|
|
84
|
-
}
|
|
85
|
-
this._isInitialized = true;
|
|
86
|
-
this.refresh();
|
|
87
|
-
}
|
|
88
|
-
register() {
|
|
89
|
-
return new Promise((_resolve, _reject) => {
|
|
90
|
-
this.getRegistrationInfo().then((info) => {
|
|
91
|
-
this.http.post(this.apiUrl + 'registration', info).subscribe((regResult) => {
|
|
92
|
-
window.localStorage.setItem(this.registrationStorageKey, regResult.id);
|
|
93
|
-
_resolve(null);
|
|
94
|
-
}, error => {
|
|
95
|
-
console.log('Nucleus.Notifications: Failed to send notification registration to server.', error);
|
|
96
|
-
_reject(error);
|
|
97
|
-
});
|
|
98
|
-
}).catch((error) => _reject(error));
|
|
99
|
-
});
|
|
100
|
-
}
|
|
101
|
-
unregister() {
|
|
102
|
-
return new Promise((_resolve, _reject) => {
|
|
103
|
-
this.getRegistrationInfo().then((info) => {
|
|
104
|
-
this.http.request('DELETE', this.apiUrl + 'registration', { body: info }).subscribe(() => {
|
|
105
|
-
window.localStorage.removeItem(this.registrationStorageKey);
|
|
106
|
-
_resolve(null);
|
|
107
|
-
}, error => {
|
|
108
|
-
console.log('Nucleus.Notifications: Failed to remove registration from server.', error);
|
|
109
|
-
_reject(error);
|
|
110
|
-
});
|
|
111
|
-
}).catch((error) => _reject(error));
|
|
112
|
-
});
|
|
113
|
-
}
|
|
114
|
-
refresh(notifyAboutNew = false) {
|
|
115
|
-
this.http.get(this.apiUrl + 'notifications').subscribe(res => {
|
|
116
|
-
this.updateNotifications(res, notifyAboutNew);
|
|
117
|
-
});
|
|
118
|
-
}
|
|
119
|
-
getNotification(id) {
|
|
120
|
-
const localNotification = this.notifications.find(x => x.id === id);
|
|
121
|
-
if (localNotification) {
|
|
122
|
-
return of(localNotification);
|
|
123
|
-
}
|
|
124
|
-
return this.http.get(this.apiUrl + 'notifications/' + id);
|
|
125
|
-
}
|
|
126
|
-
readNotification(id) {
|
|
127
|
-
const n = this.notifications.find(x => x.id === id);
|
|
128
|
-
if (n && !n.isRead) {
|
|
129
|
-
n.isRead = true;
|
|
130
|
-
this.notifyStateChanged();
|
|
131
|
-
}
|
|
132
|
-
this.http.get(this.apiUrl + 'notifications/read/' + id).subscribe();
|
|
133
|
-
}
|
|
134
|
-
dismissNotification(id) {
|
|
135
|
-
this.deleteNotificaton(id);
|
|
136
|
-
this.http.delete(this.apiUrl + 'notifications/' + id).subscribe();
|
|
137
|
-
this.removeDeliveredNotification(id);
|
|
138
|
-
}
|
|
139
|
-
dismissAll() {
|
|
140
|
-
this.notifications.splice(0);
|
|
141
|
-
this.notifyStateChanged();
|
|
142
|
-
this.http.delete(this.apiUrl + 'notifications/all').subscribe();
|
|
143
|
-
if (this._platform === 'ios' || this._platform === 'android') {
|
|
144
|
-
PushNotifications.removeAllDeliveredNotifications();
|
|
145
|
-
}
|
|
146
|
-
else if (this._platform === 'web') {
|
|
147
|
-
// TODO: remove all web push notifications
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
readAll() {
|
|
151
|
-
for (const n of this.notifications) {
|
|
152
|
-
n.isRead = true;
|
|
153
|
-
}
|
|
154
|
-
this.notifyStateChanged();
|
|
155
|
-
this.http.get(this.apiUrl + 'notifications/read/all').subscribe();
|
|
156
|
-
}
|
|
157
|
-
getChannelConfig(senderId, channelId, language
|
|
158
|
-
return this.http.get(this.apiUrl + `settings/channel/${senderId}/${channelId}?language=${language}`);
|
|
159
|
-
}
|
|
160
|
-
getChannelConfigsForSender(senderId, channelIds, language
|
|
161
|
-
const idsStr = channelIds.map(x => senderId + ',' + x).join(';');
|
|
162
|
-
return this.getChannelConfigsInternal(idsStr, language);
|
|
163
|
-
}
|
|
164
|
-
getChannelConfigs(ids, language
|
|
165
|
-
const idsStr = ids.map(x => x.senderId + ',' + x.channelId).join(';');
|
|
166
|
-
return this.getChannelConfigsInternal(idsStr, language);
|
|
167
|
-
}
|
|
168
|
-
setChannelConfig(senderId, config) {
|
|
169
|
-
return this.http.post(`${this.apiUrl}settings/channel/${senderId}`, config);
|
|
170
|
-
}
|
|
171
|
-
setChannelConfigs(configs) {
|
|
172
|
-
return this.http.post(`${this.apiUrl}settings/channels`, configs);
|
|
173
|
-
}
|
|
174
|
-
getChannelConfigsInternal(ids, language) {
|
|
175
|
-
return this.http.get(`${this.apiUrl}settings/channels?ids=${ids}&language=${language}`);
|
|
176
|
-
}
|
|
177
|
-
updateNotifications(newNotifications, notifyAboutNew = false) {
|
|
178
|
-
let stateChanged = false;
|
|
179
|
-
for (const n of newNotifications) {
|
|
180
|
-
const existing = this.notifications.find(x => x.id === n.id);
|
|
181
|
-
if (existing) {
|
|
182
|
-
if (existing.isRead !== n.isRead) {
|
|
183
|
-
existing.isRead = n.isRead;
|
|
184
|
-
stateChanged = true;
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
else {
|
|
188
|
-
let i = 0;
|
|
189
|
-
while (i < this.notifications.length && n.dateCreated < this.notifications[i].dateCreated) {
|
|
190
|
-
i++;
|
|
191
|
-
}
|
|
192
|
-
this.notifications.splice(i, 0, n);
|
|
193
|
-
stateChanged = true;
|
|
194
|
-
if (notifyAboutNew) {
|
|
195
|
-
this._newNotifications.next(n);
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
const now = Date.now();
|
|
200
|
-
for (let i = this.notifications.length - 1; i >= 0; i--) {
|
|
201
|
-
const n = this.notifications[i];
|
|
202
|
-
if (new Date(n.expirationDate).getTime() < now || !newNotifications.find(x => x.id === n.id)) {
|
|
203
|
-
this.notifications.splice(i, 1);
|
|
204
|
-
stateChanged = true;
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
if (stateChanged) {
|
|
208
|
-
this.notifyStateChanged();
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
saveToStorage() {
|
|
212
|
-
const str = JSON.stringify(this.notifications);
|
|
213
|
-
window.localStorage.setItem(this.notificationsStorageKey, str);
|
|
214
|
-
}
|
|
215
|
-
loadFromStorage() {
|
|
216
|
-
try {
|
|
217
|
-
const str = window.localStorage.getItem(this.notificationsStorageKey);
|
|
218
|
-
if (str) {
|
|
219
|
-
const notifications = JSON.parse(str);
|
|
220
|
-
this.notifications = notifications.filter(x => !!x);
|
|
221
|
-
// precaution for notification.isRead of undefined error
|
|
222
|
-
this.notifyStateChanged(false);
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
catch { }
|
|
226
|
-
}
|
|
227
|
-
handleNotificationEvent(id, eventType) {
|
|
228
|
-
if (eventType.startsWith('new') || eventType === 'updated') { // we are handling new and newSilent
|
|
229
|
-
this.getNotification(id).subscribe(n => {
|
|
230
|
-
if (eventType.startsWith('new') && !n.isRead) {
|
|
231
|
-
this._newNotifications.next(n);
|
|
232
|
-
}
|
|
233
|
-
const existing = this.notifications.find(x => x.id === n.id);
|
|
234
|
-
if (existing) {
|
|
235
|
-
existing.isRead = n.isRead;
|
|
236
|
-
}
|
|
237
|
-
else {
|
|
238
|
-
this.notifications.splice(0, 0, n);
|
|
239
|
-
}
|
|
240
|
-
this.notifyStateChanged();
|
|
241
|
-
});
|
|
242
|
-
}
|
|
243
|
-
else if (eventType === 'deleted') {
|
|
244
|
-
this.deleteNotificaton(id);
|
|
245
|
-
}
|
|
246
|
-
else {
|
|
247
|
-
this.refresh();
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
deleteNotificaton(id) {
|
|
251
|
-
const i = this.notifications.findIndex(x => x.id === id);
|
|
252
|
-
if (i >= 0) {
|
|
253
|
-
this.notifications.splice(i, 1);
|
|
254
|
-
this.notifyStateChanged();
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
notifyStateChanged(persistState = true) {
|
|
258
|
-
if (persistState) {
|
|
259
|
-
this.saveToStorage();
|
|
260
|
-
}
|
|
261
|
-
this._stateChangesSubject.next();
|
|
262
|
-
}
|
|
263
|
-
handleNotificationAction(notificationAction) {
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
i0.ɵɵ
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
32
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
33
|
+
class NucleusNotificationsService {
|
|
34
|
+
constructor(http, swPush, appService, config) {
|
|
35
|
+
this.http = http;
|
|
36
|
+
this.swPush = swPush;
|
|
37
|
+
this.appService = appService;
|
|
38
|
+
this.registrationStorageKey = 'NucleusNotificationsRegistrationId';
|
|
39
|
+
this.notificationsStorageKey = 'NucleusNotificationsLocalCache';
|
|
40
|
+
this._isInitialized = false;
|
|
41
|
+
this._newNotifications = new Subject();
|
|
42
|
+
this._clicksSubject = new Subject();
|
|
43
|
+
this._stateChangesSubject = new Subject();
|
|
44
|
+
this.notifications = [];
|
|
45
|
+
let url = config.serverApiUrl;
|
|
46
|
+
if (!url.endsWith('/')) {
|
|
47
|
+
url += '/';
|
|
48
|
+
}
|
|
49
|
+
this.apiUrl = url;
|
|
50
|
+
}
|
|
51
|
+
get unreadCount() {
|
|
52
|
+
return this.notifications.filter(x => !x.isRead).length;
|
|
53
|
+
}
|
|
54
|
+
get newNotifications() {
|
|
55
|
+
return this._newNotifications.asObservable();
|
|
56
|
+
}
|
|
57
|
+
get clicks() {
|
|
58
|
+
return this._clicksSubject.asObservable();
|
|
59
|
+
}
|
|
60
|
+
get stateChanges() {
|
|
61
|
+
return this._stateChangesSubject.asObservable();
|
|
62
|
+
}
|
|
63
|
+
get isInitialized() {
|
|
64
|
+
return this._isInitialized;
|
|
65
|
+
}
|
|
66
|
+
async initialize() {
|
|
67
|
+
// make sure app service has finished initializing
|
|
68
|
+
await this.appService.init();
|
|
69
|
+
this.loadFromStorage();
|
|
70
|
+
if (this.appService.isNative) {
|
|
71
|
+
this._platform = this.appService.deviceInfo.platform;
|
|
72
|
+
await this.registerCapacitorEvents();
|
|
73
|
+
}
|
|
74
|
+
else if (this.swPush.isEnabled) {
|
|
75
|
+
this._platform = 'web';
|
|
76
|
+
this.registerWebPushEvents();
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
console.warn('Nucleus.Notifications: There is no push capability, timer will be used to update notifications');
|
|
80
|
+
setInterval(() => {
|
|
81
|
+
console.log('Updating notifications...');
|
|
82
|
+
this.refresh(true);
|
|
83
|
+
}, 5 * 60 * 1000);
|
|
84
|
+
}
|
|
85
|
+
this._isInitialized = true;
|
|
86
|
+
this.refresh();
|
|
87
|
+
}
|
|
88
|
+
register() {
|
|
89
|
+
return new Promise((_resolve, _reject) => {
|
|
90
|
+
this.getRegistrationInfo().then((info) => {
|
|
91
|
+
this.http.post(this.apiUrl + 'registration', info).subscribe((regResult) => {
|
|
92
|
+
window.localStorage.setItem(this.registrationStorageKey, regResult.id);
|
|
93
|
+
_resolve(null);
|
|
94
|
+
}, error => {
|
|
95
|
+
console.log('Nucleus.Notifications: Failed to send notification registration to server.', error);
|
|
96
|
+
_reject(error);
|
|
97
|
+
});
|
|
98
|
+
}).catch((error) => _reject(error));
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
unregister() {
|
|
102
|
+
return new Promise((_resolve, _reject) => {
|
|
103
|
+
this.getRegistrationInfo().then((info) => {
|
|
104
|
+
this.http.request('DELETE', this.apiUrl + 'registration', { body: info }).subscribe(() => {
|
|
105
|
+
window.localStorage.removeItem(this.registrationStorageKey);
|
|
106
|
+
_resolve(null);
|
|
107
|
+
}, error => {
|
|
108
|
+
console.log('Nucleus.Notifications: Failed to remove registration from server.', error);
|
|
109
|
+
_reject(error);
|
|
110
|
+
});
|
|
111
|
+
}).catch((error) => _reject(error));
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
refresh(notifyAboutNew = false) {
|
|
115
|
+
this.http.get(this.apiUrl + 'notifications').subscribe(res => {
|
|
116
|
+
this.updateNotifications(res, notifyAboutNew);
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
getNotification(id) {
|
|
120
|
+
const localNotification = this.notifications.find(x => x.id === id);
|
|
121
|
+
if (localNotification) {
|
|
122
|
+
return of(localNotification);
|
|
123
|
+
}
|
|
124
|
+
return this.http.get(this.apiUrl + 'notifications/' + id);
|
|
125
|
+
}
|
|
126
|
+
readNotification(id) {
|
|
127
|
+
const n = this.notifications.find(x => x.id === id);
|
|
128
|
+
if (n && !n.isRead) {
|
|
129
|
+
n.isRead = true;
|
|
130
|
+
this.notifyStateChanged();
|
|
131
|
+
}
|
|
132
|
+
this.http.get(this.apiUrl + 'notifications/read/' + id).subscribe();
|
|
133
|
+
}
|
|
134
|
+
dismissNotification(id) {
|
|
135
|
+
this.deleteNotificaton(id);
|
|
136
|
+
this.http.delete(this.apiUrl + 'notifications/' + id).subscribe();
|
|
137
|
+
this.removeDeliveredNotification(id);
|
|
138
|
+
}
|
|
139
|
+
dismissAll() {
|
|
140
|
+
this.notifications.splice(0);
|
|
141
|
+
this.notifyStateChanged();
|
|
142
|
+
this.http.delete(this.apiUrl + 'notifications/all').subscribe();
|
|
143
|
+
if (this._platform === 'ios' || this._platform === 'android') {
|
|
144
|
+
PushNotifications.removeAllDeliveredNotifications();
|
|
145
|
+
}
|
|
146
|
+
else if (this._platform === 'web') {
|
|
147
|
+
// TODO: remove all web push notifications
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
readAll() {
|
|
151
|
+
for (const n of this.notifications) {
|
|
152
|
+
n.isRead = true;
|
|
153
|
+
}
|
|
154
|
+
this.notifyStateChanged();
|
|
155
|
+
this.http.get(this.apiUrl + 'notifications/read/all').subscribe();
|
|
156
|
+
}
|
|
157
|
+
getChannelConfig(senderId, channelId, language) {
|
|
158
|
+
return this.http.get(this.apiUrl + `settings/channel/${senderId}/${channelId}?language=${language}`);
|
|
159
|
+
}
|
|
160
|
+
getChannelConfigsForSender(senderId, channelIds, language) {
|
|
161
|
+
const idsStr = channelIds.map(x => senderId + ',' + x).join(';');
|
|
162
|
+
return this.getChannelConfigsInternal(idsStr, language);
|
|
163
|
+
}
|
|
164
|
+
getChannelConfigs(ids, language) {
|
|
165
|
+
const idsStr = ids.map(x => x.senderId + ',' + x.channelId).join(';');
|
|
166
|
+
return this.getChannelConfigsInternal(idsStr, language);
|
|
167
|
+
}
|
|
168
|
+
setChannelConfig(senderId, config) {
|
|
169
|
+
return this.http.post(`${this.apiUrl}settings/channel/${senderId}`, config);
|
|
170
|
+
}
|
|
171
|
+
setChannelConfigs(configs) {
|
|
172
|
+
return this.http.post(`${this.apiUrl}settings/channels`, configs);
|
|
173
|
+
}
|
|
174
|
+
getChannelConfigsInternal(ids, language) {
|
|
175
|
+
return this.http.get(`${this.apiUrl}settings/channels?ids=${ids}&language=${language}`);
|
|
176
|
+
}
|
|
177
|
+
updateNotifications(newNotifications, notifyAboutNew = false) {
|
|
178
|
+
let stateChanged = false;
|
|
179
|
+
for (const n of newNotifications) {
|
|
180
|
+
const existing = this.notifications.find(x => x.id === n.id);
|
|
181
|
+
if (existing) {
|
|
182
|
+
if (existing.isRead !== n.isRead) {
|
|
183
|
+
existing.isRead = n.isRead;
|
|
184
|
+
stateChanged = true;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
else {
|
|
188
|
+
let i = 0;
|
|
189
|
+
while (i < this.notifications.length && n.dateCreated < this.notifications[i].dateCreated) {
|
|
190
|
+
i++;
|
|
191
|
+
}
|
|
192
|
+
this.notifications.splice(i, 0, n);
|
|
193
|
+
stateChanged = true;
|
|
194
|
+
if (notifyAboutNew) {
|
|
195
|
+
this._newNotifications.next(n);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
const now = Date.now();
|
|
200
|
+
for (let i = this.notifications.length - 1; i >= 0; i--) {
|
|
201
|
+
const n = this.notifications[i];
|
|
202
|
+
if (new Date(n.expirationDate).getTime() < now || !newNotifications.find(x => x.id === n.id)) {
|
|
203
|
+
this.notifications.splice(i, 1);
|
|
204
|
+
stateChanged = true;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
if (stateChanged) {
|
|
208
|
+
this.notifyStateChanged();
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
saveToStorage() {
|
|
212
|
+
const str = JSON.stringify(this.notifications);
|
|
213
|
+
window.localStorage.setItem(this.notificationsStorageKey, str);
|
|
214
|
+
}
|
|
215
|
+
loadFromStorage() {
|
|
216
|
+
try {
|
|
217
|
+
const str = window.localStorage.getItem(this.notificationsStorageKey);
|
|
218
|
+
if (str) {
|
|
219
|
+
const notifications = JSON.parse(str);
|
|
220
|
+
this.notifications = notifications.filter(x => !!x);
|
|
221
|
+
// precaution for notification.isRead of undefined error
|
|
222
|
+
this.notifyStateChanged(false);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
catch { /* empty */ }
|
|
226
|
+
}
|
|
227
|
+
handleNotificationEvent(id, eventType) {
|
|
228
|
+
if (eventType.startsWith('new') || eventType === 'updated') { // we are handling new and newSilent
|
|
229
|
+
this.getNotification(id).subscribe(n => {
|
|
230
|
+
if (eventType.startsWith('new') && !n.isRead) {
|
|
231
|
+
this._newNotifications.next(n);
|
|
232
|
+
}
|
|
233
|
+
const existing = this.notifications.find(x => x.id === n.id);
|
|
234
|
+
if (existing) {
|
|
235
|
+
existing.isRead = n.isRead;
|
|
236
|
+
}
|
|
237
|
+
else {
|
|
238
|
+
this.notifications.splice(0, 0, n);
|
|
239
|
+
}
|
|
240
|
+
this.notifyStateChanged();
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
else if (eventType === 'deleted') {
|
|
244
|
+
this.deleteNotificaton(id);
|
|
245
|
+
}
|
|
246
|
+
else {
|
|
247
|
+
this.refresh();
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
deleteNotificaton(id) {
|
|
251
|
+
const i = this.notifications.findIndex(x => x.id === id);
|
|
252
|
+
if (i >= 0) {
|
|
253
|
+
this.notifications.splice(i, 1);
|
|
254
|
+
this.notifyStateChanged();
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
notifyStateChanged(persistState = true) {
|
|
258
|
+
if (persistState) {
|
|
259
|
+
this.saveToStorage();
|
|
260
|
+
}
|
|
261
|
+
this._stateChangesSubject.next();
|
|
262
|
+
}
|
|
263
|
+
handleNotificationAction(notificationAction) {
|
|
264
|
+
if (!notificationAction) {
|
|
265
|
+
throw new Error('Notification action is empty!');
|
|
266
|
+
}
|
|
267
|
+
const arr = notificationAction.split(':');
|
|
268
|
+
const notificationClick = {
|
|
269
|
+
id: arr[0],
|
|
270
|
+
type: arr[1],
|
|
271
|
+
routerLink: arr[2]
|
|
272
|
+
};
|
|
273
|
+
const validNotificationClickTypes = ['default', 'deeplink'];
|
|
274
|
+
if (validNotificationClickTypes.includes(notificationClick.type)) {
|
|
275
|
+
this._clicksSubject.next(notificationClick);
|
|
276
|
+
}
|
|
277
|
+
else {
|
|
278
|
+
console.error(`Nucleus.Notifications: Unknown notification action: '${notificationAction}'.`);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
removeDeliveredNotification(id) {
|
|
282
|
+
if (this._platform === 'ios' || this._platform === 'android') {
|
|
283
|
+
PushNotifications.getDeliveredNotifications().then(list => {
|
|
284
|
+
const toRemove = list.notifications.filter(n => {
|
|
285
|
+
const data = this.getNotificationPayloadData(n);
|
|
286
|
+
return (data.notificationId === id);
|
|
287
|
+
});
|
|
288
|
+
// TODO: On Android this does not currently work because notificationID is not set.
|
|
289
|
+
// This my solve the issue: https://github.com/ionic-team/capacitor/pull/3523
|
|
290
|
+
PushNotifications.removeDeliveredNotifications({
|
|
291
|
+
notifications: toRemove
|
|
292
|
+
});
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
else if (this._platform === 'web') {
|
|
296
|
+
// TODO: remove web push notification
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
getNotificationPayloadData(pushNotification) {
|
|
300
|
+
return (this._platform === 'ios') ? pushNotification.data.data : pushNotification.data;
|
|
301
|
+
}
|
|
302
|
+
async registerCapacitorEvents() {
|
|
303
|
+
await PushNotifications.addListener('pushNotificationReceived', n => {
|
|
304
|
+
const data = this.getNotificationPayloadData(n);
|
|
305
|
+
console.log('Nucleus.Notifications: Received capacitor push event: ' + data.eventType, n);
|
|
306
|
+
this.handleNotificationEvent(data.notificationId, data.eventType);
|
|
307
|
+
});
|
|
308
|
+
await PushNotifications.addListener('pushNotificationActionPerformed', a => {
|
|
309
|
+
let action = a.notification.data.notificationAction;
|
|
310
|
+
if (this._platform === 'ios') {
|
|
311
|
+
action = a.notification.data.data.notificationAction;
|
|
312
|
+
}
|
|
313
|
+
console.log('Nucleus.Notifications: Received capacitor action event', action);
|
|
314
|
+
this.handleNotificationAction(action);
|
|
315
|
+
});
|
|
316
|
+
}
|
|
317
|
+
registerWebPushEvents() {
|
|
318
|
+
this.swPush.messages.subscribe((n) => {
|
|
319
|
+
const data = n.data;
|
|
320
|
+
console.log('Nucleus.Notifications: Received WebPush event: ' + data.eventType, n);
|
|
321
|
+
this.handleNotificationEvent(data.notificationId, data.eventType);
|
|
322
|
+
});
|
|
323
|
+
this.swPush.notificationClicks.subscribe((action) => {
|
|
324
|
+
console.log('Nucleus.Notifications: Received WebPush action event', action);
|
|
325
|
+
const tag = action.notification.tag;
|
|
326
|
+
this.handleNotificationAction(tag);
|
|
327
|
+
});
|
|
328
|
+
}
|
|
329
|
+
getRegistrationInfo() {
|
|
330
|
+
return new Promise((_resolve, _reject) => {
|
|
331
|
+
const registrationId = window.localStorage.getItem(this.registrationStorageKey);
|
|
332
|
+
if (this._platform === 'android' || this._platform === 'ios') {
|
|
333
|
+
// capacitor platform
|
|
334
|
+
const listener = PushNotifications.addListener('registration', token => {
|
|
335
|
+
listener.remove();
|
|
336
|
+
_resolve({ id: registrationId, token: token.value, platform: this._platform });
|
|
337
|
+
});
|
|
338
|
+
PushNotifications.register().catch(error => _reject('Could not register for notifications:' + error));
|
|
339
|
+
}
|
|
340
|
+
else if (this._platform === 'web') {
|
|
341
|
+
// Web Push API
|
|
342
|
+
this.http.get(this.apiUrl + 'registration/webkey').subscribe(key => {
|
|
343
|
+
this.getWebPushSubscription(key.publicKey).then(subscription => {
|
|
344
|
+
const t = JSON.stringify(subscription.toJSON());
|
|
345
|
+
_resolve({ id: registrationId, token: t, platform: 'web' });
|
|
346
|
+
});
|
|
347
|
+
}, error => _reject(error));
|
|
348
|
+
}
|
|
349
|
+
else {
|
|
350
|
+
_reject(`Nucleus.Notifications: Platform is not supported`);
|
|
351
|
+
}
|
|
352
|
+
});
|
|
353
|
+
}
|
|
354
|
+
getWebPushSubscription(publicKey) {
|
|
355
|
+
return new Promise((_resolve, _reject) => {
|
|
356
|
+
this.swPush.subscription.subscribe(subscription => {
|
|
357
|
+
if (subscription != null) {
|
|
358
|
+
_resolve(subscription);
|
|
359
|
+
}
|
|
360
|
+
else {
|
|
361
|
+
this.swPush.requestSubscription({ serverPublicKey: publicKey }).then(s => _resolve(s)).catch(e => _reject(e));
|
|
362
|
+
}
|
|
363
|
+
}, error => {
|
|
364
|
+
console.error('Nucleus.Notifications: Cannot get web push subscription', error);
|
|
365
|
+
_reject(error);
|
|
366
|
+
});
|
|
367
|
+
});
|
|
368
|
+
}
|
|
369
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NucleusNotificationsService, deps: [{ token: i1.HttpClient }, { token: i2.SwPush }, { token: i3.NucleusAppService }, { token: NucleusNotificationsConfig }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
370
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NucleusNotificationsService, providedIn: 'root' }); }
|
|
371
|
+
}
|
|
372
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NucleusNotificationsService, decorators: [{
|
|
373
|
+
type: Injectable,
|
|
374
|
+
args: [{
|
|
375
|
+
providedIn: 'root'
|
|
376
|
+
}]
|
|
374
377
|
}], ctorParameters: function () { return [{ type: i1.HttpClient }, { type: i2.SwPush }, { type: i3.NucleusAppService }, { type: NucleusNotificationsConfig }]; } });
|
|
375
378
|
|
|
376
|
-
class NucleusNotificationsModule {
|
|
377
|
-
static forRoot(config) {
|
|
378
|
-
return {
|
|
379
|
-
ngModule: NucleusNotificationsModule,
|
|
380
|
-
providers: [
|
|
381
|
-
{ provide: NucleusNotificationsConfig, useValue: config }
|
|
382
|
-
]
|
|
383
|
-
};
|
|
384
|
-
}
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
390
|
-
type: NgModule,
|
|
391
|
-
args: [{
|
|
392
|
-
declarations: [],
|
|
393
|
-
imports: [],
|
|
394
|
-
exports: []
|
|
395
|
-
}]
|
|
379
|
+
class NucleusNotificationsModule {
|
|
380
|
+
static forRoot(config) {
|
|
381
|
+
return {
|
|
382
|
+
ngModule: NucleusNotificationsModule,
|
|
383
|
+
providers: [
|
|
384
|
+
{ provide: NucleusNotificationsConfig, useValue: config }
|
|
385
|
+
]
|
|
386
|
+
};
|
|
387
|
+
}
|
|
388
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NucleusNotificationsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
389
|
+
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "16.2.12", ngImport: i0, type: NucleusNotificationsModule }); }
|
|
390
|
+
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NucleusNotificationsModule }); }
|
|
391
|
+
}
|
|
392
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NucleusNotificationsModule, decorators: [{
|
|
393
|
+
type: NgModule,
|
|
394
|
+
args: [{
|
|
395
|
+
declarations: [],
|
|
396
|
+
imports: [],
|
|
397
|
+
exports: []
|
|
398
|
+
}]
|
|
396
399
|
}] });
|
|
397
400
|
|
|
398
|
-
|
|
399
|
-
*
|
|
400
|
-
*/
|
|
401
|
-
|
|
402
|
-
/**
|
|
403
|
-
* Generated bundle index. Do not edit.
|
|
401
|
+
/**
|
|
402
|
+
* Generated bundle index. Do not edit.
|
|
404
403
|
*/
|
|
405
404
|
|
|
406
405
|
export { Identity, Notification, NotificationClick, NotificationData, NucleusNotificationsConfig, NucleusNotificationsModule, NucleusNotificationsService, PayloadData, Recipient, Registration, RegistrationResult, UserChannelConfig, WebKey };
|