@knocklabs/client 0.8.2 → 0.8.4
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/cjs/clients/feed/feed.js +421 -116
- package/dist/cjs/clients/feed/feed.js.map +1 -1
- package/dist/cjs/clients/feed/store.js +23 -16
- package/dist/cjs/clients/feed/store.js.map +1 -1
- package/dist/esm/clients/feed/feed.js +295 -59
- package/dist/esm/clients/feed/feed.js.map +1 -1
- package/dist/esm/clients/feed/store.js +20 -15
- package/dist/esm/clients/feed/store.js.map +1 -1
- package/dist/types/clients/feed/feed.d.ts +6 -0
- package/dist/types/clients/feed/feed.d.ts.map +1 -1
- package/dist/types/clients/feed/interfaces.d.ts +2 -1
- package/dist/types/clients/feed/interfaces.d.ts.map +1 -1
- package/dist/types/clients/feed/store.d.ts.map +1 -1
- package/dist/types/clients/feed/types.d.ts +3 -2
- package/dist/types/clients/feed/types.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -8,12 +8,7 @@ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { va
|
|
|
8
8
|
import { EventEmitter2 as EventEmitter } from "eventemitter2";
|
|
9
9
|
import createStore from "./store";
|
|
10
10
|
import { isRequestInFlight, NetworkStatus } from "../../networkStatus";
|
|
11
|
-
|
|
12
|
-
function invertStatus(status) {
|
|
13
|
-
return status.startsWith("un") ? status.substring(2, status.length) : "un".concat(status);
|
|
14
|
-
} // Default options to apply
|
|
15
|
-
|
|
16
|
-
|
|
11
|
+
// Default options to apply
|
|
17
12
|
var feedClientDefaults = {
|
|
18
13
|
archived: "exclude"
|
|
19
14
|
};
|
|
@@ -34,6 +29,8 @@ class Feed {
|
|
|
34
29
|
|
|
35
30
|
_defineProperty(this, "defaultOptions", void 0);
|
|
36
31
|
|
|
32
|
+
_defineProperty(this, "broadcastChannel", void 0);
|
|
33
|
+
|
|
37
34
|
_defineProperty(this, "store", void 0);
|
|
38
35
|
|
|
39
36
|
this.apiClient = knock.client();
|
|
@@ -46,7 +43,10 @@ class Feed {
|
|
|
46
43
|
});
|
|
47
44
|
this.defaultOptions = _objectSpread(_objectSpread({}, feedClientDefaults), options);
|
|
48
45
|
this.channel = this.apiClient.socket.channel("feeds:".concat(this.userFeedId), this.defaultOptions);
|
|
49
|
-
this.channel.on("new-message", resp => this.onNewMessageReceived(resp));
|
|
46
|
+
this.channel.on("new-message", resp => this.onNewMessageReceived(resp)); // Attempt to bind to listen to other events from this feed in different tabs
|
|
47
|
+
// Note: here we ensure `self` is available (it's not in server rendered envs)
|
|
48
|
+
|
|
49
|
+
this.broadcastChannel = self && "BroadcastChannel" in self ? new BroadcastChannel("knock:feed:".concat(this.userFeedId)) : null;
|
|
50
50
|
}
|
|
51
51
|
/**
|
|
52
52
|
* Cleans up a feed instance by destroying the store and disconnecting
|
|
@@ -59,6 +59,10 @@ class Feed {
|
|
|
59
59
|
this.broadcaster.removeAllListeners();
|
|
60
60
|
this.channel.off("new-message");
|
|
61
61
|
this.store.destroy();
|
|
62
|
+
|
|
63
|
+
if (this.broadcastChannel) {
|
|
64
|
+
this.broadcastChannel.close();
|
|
65
|
+
}
|
|
62
66
|
}
|
|
63
67
|
/*
|
|
64
68
|
Initializes a real-time connection to Knock, connecting the websocket for the
|
|
@@ -75,6 +79,32 @@ class Feed {
|
|
|
75
79
|
|
|
76
80
|
if (["closed", "errored"].includes(this.channel.state)) {
|
|
77
81
|
this.channel.join();
|
|
82
|
+
} // Opt into receiving updates from _other tabs for the same user / feed_ via the broadcast
|
|
83
|
+
// channel (iff it's enabled and exists)
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
if (this.broadcastChannel && this.defaultOptions.__experimentalCrossBrowserUpdates === true) {
|
|
87
|
+
this.broadcastChannel.onmessage = e => {
|
|
88
|
+
switch (e.data.type) {
|
|
89
|
+
case "items:archived":
|
|
90
|
+
case "items:unarchived":
|
|
91
|
+
case "items:seen":
|
|
92
|
+
case "items:unseen":
|
|
93
|
+
case "items:read":
|
|
94
|
+
case "items:unread":
|
|
95
|
+
case "items:all_read":
|
|
96
|
+
case "items:all_seen":
|
|
97
|
+
case "items:all_archived":
|
|
98
|
+
// When items are updated in any other tab, simply refetch to get the latest state
|
|
99
|
+
// to make sure that the state gets updated accordingly. In the future here we could
|
|
100
|
+
// maybe do this optimistically without the fetch.
|
|
101
|
+
return this.fetch();
|
|
102
|
+
break;
|
|
103
|
+
|
|
104
|
+
default:
|
|
105
|
+
return null;
|
|
106
|
+
}
|
|
107
|
+
};
|
|
78
108
|
}
|
|
79
109
|
}
|
|
80
110
|
/* Binds a handler to be invoked when event occurs */
|
|
@@ -106,41 +136,159 @@ class Feed {
|
|
|
106
136
|
})();
|
|
107
137
|
}
|
|
108
138
|
|
|
109
|
-
|
|
139
|
+
markAllAsSeen() {
|
|
110
140
|
var _this2 = this;
|
|
111
141
|
|
|
112
142
|
return _asyncToGenerator(function* () {
|
|
113
|
-
|
|
143
|
+
// To mark all of the messages as seen we:
|
|
144
|
+
// 1. Optimistically update *everything* we have in the store
|
|
145
|
+
// 2. We decrement the `unseen_count` to zero optimistically
|
|
146
|
+
// 3. We issue the API call to the endpoint
|
|
147
|
+
//
|
|
148
|
+
// Note: there is the potential for a race condition here because the bulk
|
|
149
|
+
// update is an async method, so if a new message comes in during this window before
|
|
150
|
+
// the update has been processed we'll effectively reset the `unseen_count` to be what it was.
|
|
151
|
+
//
|
|
152
|
+
// Note: here we optimistically handle the case whereby the feed is scoped to show only `unseen`
|
|
153
|
+
// items by removing everything from view.
|
|
154
|
+
var {
|
|
155
|
+
getState,
|
|
156
|
+
setState
|
|
157
|
+
} = _this2.store;
|
|
158
|
+
var {
|
|
159
|
+
metadata,
|
|
160
|
+
items
|
|
161
|
+
} = getState();
|
|
162
|
+
var isViewingOnlyUnseen = _this2.defaultOptions.status === "unseen"; // If we're looking at the unseen view, then we want to remove all of the items optimistically
|
|
163
|
+
// from the store given that nothing should be visible. We do this by resetting the store state
|
|
164
|
+
// and setting the current metadata counts to 0
|
|
165
|
+
|
|
166
|
+
if (isViewingOnlyUnseen) {
|
|
167
|
+
setState(store => store.resetStore(_objectSpread(_objectSpread({}, metadata), {}, {
|
|
168
|
+
total_count: 0,
|
|
169
|
+
unseen_count: 0
|
|
170
|
+
})));
|
|
171
|
+
} else {
|
|
172
|
+
// Otherwise we want to update the metadata and mark all of the items in the store as seen
|
|
173
|
+
setState(store => store.setMetadata(_objectSpread(_objectSpread({}, metadata), {}, {
|
|
174
|
+
unseen_count: 0
|
|
175
|
+
})));
|
|
176
|
+
var attrs = {
|
|
177
|
+
seen_at: new Date().toISOString()
|
|
178
|
+
};
|
|
179
|
+
var itemIds = items.map(item => item.id);
|
|
180
|
+
setState(store => store.setItemAttrs(itemIds, attrs));
|
|
181
|
+
} // Issue the API request to the bulk status change API
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
var result = yield _this2.makeBulkStatusUpdate("seen");
|
|
185
|
+
|
|
186
|
+
_this2.broadcaster.emit("items:all_seen", {
|
|
187
|
+
items
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
_this2.broadcastOverChannel("items:all_seen", {
|
|
191
|
+
items
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
return result;
|
|
195
|
+
})();
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
markAsUnseen(itemOrItems) {
|
|
199
|
+
var _this3 = this;
|
|
200
|
+
|
|
201
|
+
return _asyncToGenerator(function* () {
|
|
202
|
+
_this3.optimisticallyPerformStatusUpdate(itemOrItems, "unseen", {
|
|
114
203
|
seen_at: null
|
|
115
204
|
}, "unseen_count");
|
|
116
205
|
|
|
117
|
-
return
|
|
206
|
+
return _this3.makeStatusUpdate(itemOrItems, "unseen");
|
|
118
207
|
})();
|
|
119
208
|
}
|
|
120
209
|
|
|
121
210
|
markAsRead(itemOrItems) {
|
|
122
|
-
var
|
|
211
|
+
var _this4 = this;
|
|
123
212
|
|
|
124
213
|
return _asyncToGenerator(function* () {
|
|
125
214
|
var now = new Date().toISOString();
|
|
126
215
|
|
|
127
|
-
|
|
216
|
+
_this4.optimisticallyPerformStatusUpdate(itemOrItems, "read", {
|
|
128
217
|
read_at: now
|
|
129
218
|
}, "unread_count");
|
|
130
219
|
|
|
131
|
-
return
|
|
220
|
+
return _this4.makeStatusUpdate(itemOrItems, "read");
|
|
221
|
+
})();
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
markAllAsRead() {
|
|
225
|
+
var _this5 = this;
|
|
226
|
+
|
|
227
|
+
return _asyncToGenerator(function* () {
|
|
228
|
+
// To mark all of the messages as read we:
|
|
229
|
+
// 1. Optimistically update *everything* we have in the store
|
|
230
|
+
// 2. We decrement the `unread_count` to zero optimistically
|
|
231
|
+
// 3. We issue the API call to the endpoint
|
|
232
|
+
//
|
|
233
|
+
// Note: there is the potential for a race condition here because the bulk
|
|
234
|
+
// update is an async method, so if a new message comes in during this window before
|
|
235
|
+
// the update has been processed we'll effectively reset the `unread_count` to be what it was.
|
|
236
|
+
//
|
|
237
|
+
// Note: here we optimistically handle the case whereby the feed is scoped to show only `unread`
|
|
238
|
+
// items by removing everything from view.
|
|
239
|
+
var {
|
|
240
|
+
getState,
|
|
241
|
+
setState
|
|
242
|
+
} = _this5.store;
|
|
243
|
+
var {
|
|
244
|
+
metadata,
|
|
245
|
+
items
|
|
246
|
+
} = getState();
|
|
247
|
+
var isViewingOnlyUnread = _this5.defaultOptions.status === "unread"; // If we're looking at the unread view, then we want to remove all of the items optimistically
|
|
248
|
+
// from the store given that nothing should be visible. We do this by resetting the store state
|
|
249
|
+
// and setting the current metadata counts to 0
|
|
250
|
+
|
|
251
|
+
if (isViewingOnlyUnread) {
|
|
252
|
+
setState(store => store.resetStore(_objectSpread(_objectSpread({}, metadata), {}, {
|
|
253
|
+
total_count: 0,
|
|
254
|
+
unread_count: 0
|
|
255
|
+
})));
|
|
256
|
+
} else {
|
|
257
|
+
// Otherwise we want to update the metadata and mark all of the items in the store as seen
|
|
258
|
+
setState(store => store.setMetadata(_objectSpread(_objectSpread({}, metadata), {}, {
|
|
259
|
+
unread_count: 0
|
|
260
|
+
})));
|
|
261
|
+
var attrs = {
|
|
262
|
+
read_at: new Date().toISOString()
|
|
263
|
+
};
|
|
264
|
+
var itemIds = items.map(item => item.id);
|
|
265
|
+
setState(store => store.setItemAttrs(itemIds, attrs));
|
|
266
|
+
} // Issue the API request to the bulk status change API
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
var result = yield _this5.makeBulkStatusUpdate("read");
|
|
270
|
+
|
|
271
|
+
_this5.broadcaster.emit("items:all_read", {
|
|
272
|
+
items
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
_this5.broadcastOverChannel("items:all_read", {
|
|
276
|
+
items
|
|
277
|
+
});
|
|
278
|
+
|
|
279
|
+
return result;
|
|
132
280
|
})();
|
|
133
281
|
}
|
|
134
282
|
|
|
135
283
|
markAsUnread(itemOrItems) {
|
|
136
|
-
var
|
|
284
|
+
var _this6 = this;
|
|
137
285
|
|
|
138
286
|
return _asyncToGenerator(function* () {
|
|
139
|
-
|
|
287
|
+
_this6.optimisticallyPerformStatusUpdate(itemOrItems, "unread", {
|
|
140
288
|
read_at: null
|
|
141
289
|
}, "unread_count");
|
|
142
290
|
|
|
143
|
-
return
|
|
291
|
+
return _this6.makeStatusUpdate(itemOrItems, "unread");
|
|
144
292
|
})();
|
|
145
293
|
}
|
|
146
294
|
/*
|
|
@@ -152,19 +300,19 @@ class Feed {
|
|
|
152
300
|
|
|
153
301
|
|
|
154
302
|
markAsArchived(itemOrItems) {
|
|
155
|
-
var
|
|
303
|
+
var _this7 = this;
|
|
156
304
|
|
|
157
305
|
return _asyncToGenerator(function* () {
|
|
158
306
|
var {
|
|
159
307
|
getState,
|
|
160
308
|
setState
|
|
161
|
-
} =
|
|
309
|
+
} = _this7.store;
|
|
162
310
|
var state = getState();
|
|
163
|
-
var shouldOptimisticallyRemoveItems =
|
|
311
|
+
var shouldOptimisticallyRemoveItems = _this7.defaultOptions.archived === "exclude";
|
|
164
312
|
var normalizedItems = Array.isArray(itemOrItems) ? itemOrItems : [itemOrItems];
|
|
165
313
|
var itemIds = normalizedItems.map(item => item.id);
|
|
166
314
|
/*
|
|
167
|
-
In the
|
|
315
|
+
In the code here we want to optimistically update counts and items
|
|
168
316
|
that are persisted such that we can display updates immediately on the feed
|
|
169
317
|
without needing to make a network request.
|
|
170
318
|
Note: right now this does *not* take into account offline handling or any extensive retry
|
|
@@ -208,19 +356,65 @@ class Feed {
|
|
|
208
356
|
});
|
|
209
357
|
}
|
|
210
358
|
|
|
211
|
-
return
|
|
359
|
+
return _this7.makeStatusUpdate(itemOrItems, "archived");
|
|
360
|
+
})();
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
markAllAsArchived() {
|
|
364
|
+
var _this8 = this;
|
|
365
|
+
|
|
366
|
+
return _asyncToGenerator(function* () {
|
|
367
|
+
// Note: there is the potential for a race condition here because the bulk
|
|
368
|
+
// update is an async method, so if a new message comes in during this window before
|
|
369
|
+
// the update has been processed we'll effectively reset the `unseen_count` to be what it was.
|
|
370
|
+
var {
|
|
371
|
+
setState,
|
|
372
|
+
getState
|
|
373
|
+
} = _this8.store;
|
|
374
|
+
var {
|
|
375
|
+
items
|
|
376
|
+
} = getState(); // Here if we're looking at a feed that excludes all of the archived items by default then we
|
|
377
|
+
// will want to optimistically remove all of the items from the feed as they are now all excluded
|
|
378
|
+
|
|
379
|
+
var shouldOptimisticallyRemoveItems = _this8.defaultOptions.archived === "exclude";
|
|
380
|
+
|
|
381
|
+
if (shouldOptimisticallyRemoveItems) {
|
|
382
|
+
// Reset the store to clear out all of items and reset the badge count
|
|
383
|
+
setState(store => store.resetStore());
|
|
384
|
+
} else {
|
|
385
|
+
// Mark all the entries being updated as archived either way so the state is correct
|
|
386
|
+
setState(store => {
|
|
387
|
+
var itemIds = items.map(i => i.id);
|
|
388
|
+
store.setItemAttrs(itemIds, {
|
|
389
|
+
archived_at: new Date().toISOString()
|
|
390
|
+
});
|
|
391
|
+
});
|
|
392
|
+
} // Issue the API request to the bulk status change API
|
|
393
|
+
|
|
394
|
+
|
|
395
|
+
var result = yield _this8.makeBulkStatusUpdate("archive");
|
|
396
|
+
|
|
397
|
+
_this8.broadcaster.emit("items:all_archived", {
|
|
398
|
+
items
|
|
399
|
+
});
|
|
400
|
+
|
|
401
|
+
_this8.broadcastOverChannel("items:all_archived", {
|
|
402
|
+
items
|
|
403
|
+
});
|
|
404
|
+
|
|
405
|
+
return result;
|
|
212
406
|
})();
|
|
213
407
|
}
|
|
214
408
|
|
|
215
409
|
markAsUnarchived(itemOrItems) {
|
|
216
|
-
var
|
|
410
|
+
var _this9 = this;
|
|
217
411
|
|
|
218
412
|
return _asyncToGenerator(function* () {
|
|
219
|
-
|
|
413
|
+
_this9.optimisticallyPerformStatusUpdate(itemOrItems, "unarchived", {
|
|
220
414
|
archived_at: null
|
|
221
415
|
});
|
|
222
416
|
|
|
223
|
-
return
|
|
417
|
+
return _this9.makeStatusUpdate(itemOrItems, "unarchived");
|
|
224
418
|
})();
|
|
225
419
|
}
|
|
226
420
|
/* Fetches the feed content, appending it to the store */
|
|
@@ -228,14 +422,14 @@ class Feed {
|
|
|
228
422
|
|
|
229
423
|
fetch() {
|
|
230
424
|
var _arguments = arguments,
|
|
231
|
-
|
|
425
|
+
_this10 = this;
|
|
232
426
|
|
|
233
427
|
return _asyncToGenerator(function* () {
|
|
234
428
|
var options = _arguments.length > 0 && _arguments[0] !== undefined ? _arguments[0] : {};
|
|
235
429
|
var {
|
|
236
430
|
setState,
|
|
237
431
|
getState
|
|
238
|
-
} =
|
|
432
|
+
} = _this10.store;
|
|
239
433
|
var {
|
|
240
434
|
networkStatus
|
|
241
435
|
} = getState(); // If there's an existing request in flight, then do nothing
|
|
@@ -251,11 +445,16 @@ class Feed {
|
|
|
251
445
|
return store.setNetworkStatus((_options$__loadingTyp = options.__loadingType) !== null && _options$__loadingTyp !== void 0 ? _options$__loadingTyp : NetworkStatus.loading);
|
|
252
446
|
}); // Always include the default params, if they have been set
|
|
253
447
|
|
|
254
|
-
var queryParams = _objectSpread(_objectSpread({},
|
|
448
|
+
var queryParams = _objectSpread(_objectSpread(_objectSpread({}, _this10.defaultOptions), options), {}, {
|
|
449
|
+
// Unset options that should not be sent to the API
|
|
450
|
+
__loadingType: undefined,
|
|
451
|
+
__fetchSource: undefined,
|
|
452
|
+
__experimentalCrossBrowserUpdates: undefined
|
|
453
|
+
});
|
|
255
454
|
|
|
256
|
-
var result = yield
|
|
455
|
+
var result = yield _this10.apiClient.makeRequest({
|
|
257
456
|
method: "GET",
|
|
258
|
-
url: "/v1/users/".concat(
|
|
457
|
+
url: "/v1/users/".concat(_this10.knock.userId, "/feeds/").concat(_this10.feedId),
|
|
259
458
|
params: queryParams
|
|
260
459
|
});
|
|
261
460
|
|
|
@@ -290,7 +489,7 @@ class Feed {
|
|
|
290
489
|
} // Legacy `messages.new` event, should be removed in a future version
|
|
291
490
|
|
|
292
491
|
|
|
293
|
-
|
|
492
|
+
_this10.broadcast("messages.new", response); // Broadcast the appropriate event type depending on the fetch source
|
|
294
493
|
|
|
295
494
|
|
|
296
495
|
var feedEventType = options.__fetchSource === "socket" ? "items.received.realtime" : "items.received.page";
|
|
@@ -300,7 +499,7 @@ class Feed {
|
|
|
300
499
|
event: feedEventType
|
|
301
500
|
};
|
|
302
501
|
|
|
303
|
-
|
|
502
|
+
_this10.broadcast(eventPayload.event, eventPayload);
|
|
304
503
|
|
|
305
504
|
return {
|
|
306
505
|
data: response,
|
|
@@ -310,13 +509,13 @@ class Feed {
|
|
|
310
509
|
}
|
|
311
510
|
|
|
312
511
|
fetchNextPage() {
|
|
313
|
-
var
|
|
512
|
+
var _this11 = this;
|
|
314
513
|
|
|
315
514
|
return _asyncToGenerator(function* () {
|
|
316
515
|
// Attempts to fetch the next page of results (if we have any)
|
|
317
516
|
var {
|
|
318
517
|
getState
|
|
319
|
-
} =
|
|
518
|
+
} = _this11.store;
|
|
320
519
|
var {
|
|
321
520
|
pageInfo
|
|
322
521
|
} = getState();
|
|
@@ -326,7 +525,7 @@ class Feed {
|
|
|
326
525
|
return;
|
|
327
526
|
}
|
|
328
527
|
|
|
329
|
-
|
|
528
|
+
_this11.fetch({
|
|
330
529
|
after: pageInfo.after,
|
|
331
530
|
__loadingType: NetworkStatus.fetchMore
|
|
332
531
|
});
|
|
@@ -339,7 +538,7 @@ class Feed {
|
|
|
339
538
|
|
|
340
539
|
|
|
341
540
|
onNewMessageReceived(_ref) {
|
|
342
|
-
var
|
|
541
|
+
var _this12 = this;
|
|
343
542
|
|
|
344
543
|
return _asyncToGenerator(function* () {
|
|
345
544
|
var {
|
|
@@ -349,7 +548,7 @@ class Feed {
|
|
|
349
548
|
var {
|
|
350
549
|
getState,
|
|
351
550
|
setState
|
|
352
|
-
} =
|
|
551
|
+
} = _this12.store;
|
|
353
552
|
var {
|
|
354
553
|
items
|
|
355
554
|
} = getState();
|
|
@@ -357,7 +556,7 @@ class Feed {
|
|
|
357
556
|
|
|
358
557
|
setState(state => state.setMetadata(metadata)); // Fetch the items before the current head (if it exists)
|
|
359
558
|
|
|
360
|
-
|
|
559
|
+
_this12.fetch({
|
|
361
560
|
before: currentHead === null || currentHead === void 0 ? void 0 : currentHead.__cursor,
|
|
362
561
|
__fetchSource: "socket"
|
|
363
562
|
});
|
|
@@ -392,38 +591,75 @@ class Feed {
|
|
|
392
591
|
}
|
|
393
592
|
|
|
394
593
|
makeStatusUpdate(itemOrItems, type) {
|
|
395
|
-
var
|
|
594
|
+
var _this13 = this;
|
|
396
595
|
|
|
397
596
|
return _asyncToGenerator(function* () {
|
|
398
|
-
//
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
597
|
+
// Always treat items as a batch to use the corresponding batch endpoint
|
|
598
|
+
var items = Array.isArray(itemOrItems) ? itemOrItems : [itemOrItems];
|
|
599
|
+
var itemIds = items.map(item => item.id);
|
|
600
|
+
var result = yield _this13.apiClient.makeRequest({
|
|
601
|
+
method: "POST",
|
|
602
|
+
url: "/v1/messages/batch/".concat(type),
|
|
603
|
+
data: {
|
|
604
|
+
message_ids: itemIds
|
|
605
|
+
}
|
|
606
|
+
}); // Emit the event that these items had their statuses changed
|
|
607
|
+
// Note: we do this after the update to ensure that the server event actually completed
|
|
608
|
+
|
|
609
|
+
_this13.broadcaster.emit("items:".concat(type), {
|
|
610
|
+
items
|
|
611
|
+
});
|
|
409
612
|
|
|
613
|
+
_this13.broadcastOverChannel("items:".concat(type), {
|
|
614
|
+
items
|
|
615
|
+
});
|
|
410
616
|
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
url: "/v1/messages/".concat(itemOrItems.id, "/").concat(invertStatus(type))
|
|
415
|
-
});
|
|
416
|
-
} // If its a single then we can just call the regular endpoint
|
|
617
|
+
return result;
|
|
618
|
+
})();
|
|
619
|
+
}
|
|
417
620
|
|
|
621
|
+
makeBulkStatusUpdate(type) {
|
|
622
|
+
var _this14 = this;
|
|
418
623
|
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
624
|
+
return _asyncToGenerator(function* () {
|
|
625
|
+
// The base scope for the call should take into account all of the options currently
|
|
626
|
+
// set on the feed, as well as being scoped for the current user. We do this so that
|
|
627
|
+
// we ONLY make changes to the messages that are currently in view on this feed, and not
|
|
628
|
+
// all messages that exist.
|
|
629
|
+
var options = {
|
|
630
|
+
user_ids: [_this14.knock.userId],
|
|
631
|
+
engagement_status: _this14.defaultOptions.status !== "all" ? _this14.defaultOptions.status : undefined,
|
|
632
|
+
archived: _this14.defaultOptions.archived,
|
|
633
|
+
has_tenant: _this14.defaultOptions.has_tenant,
|
|
634
|
+
tenants: _this14.defaultOptions.tenant ? [_this14.defaultOptions.tenant] : undefined
|
|
635
|
+
};
|
|
636
|
+
return yield _this14.apiClient.makeRequest({
|
|
637
|
+
method: "POST",
|
|
638
|
+
url: "/v1/channels/".concat(_this14.feedId, "/messages/bulk/").concat(type),
|
|
639
|
+
data: options
|
|
422
640
|
});
|
|
423
|
-
return result;
|
|
424
641
|
})();
|
|
425
642
|
}
|
|
426
643
|
|
|
644
|
+
broadcastOverChannel(type, payload) {
|
|
645
|
+
// The broadcastChannel may not be available in non-browser environments
|
|
646
|
+
if (!this.broadcastChannel) {
|
|
647
|
+
return;
|
|
648
|
+
} // Here we stringify our payload and try and send as JSON such that we
|
|
649
|
+
// don't get any `An object could not be cloned` errors when trying to broadcast
|
|
650
|
+
|
|
651
|
+
|
|
652
|
+
try {
|
|
653
|
+
var stringifiedPayload = JSON.parse(JSON.stringify(payload));
|
|
654
|
+
this.broadcastChannel.postMessage({
|
|
655
|
+
type,
|
|
656
|
+
payload: stringifiedPayload
|
|
657
|
+
});
|
|
658
|
+
} catch (e) {
|
|
659
|
+
console.warn("Could not broadcast ".concat(type, ", got error: ").concat(e));
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
|
|
427
663
|
}
|
|
428
664
|
|
|
429
665
|
export default Feed;
|