@knocklabs/client 0.8.14 → 0.8.16

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.
Files changed (76) hide show
  1. package/README.md +22 -13
  2. package/dist/cjs/api.js +33 -56
  3. package/dist/cjs/api.js.map +1 -1
  4. package/dist/cjs/clients/feed/feed.js +492 -624
  5. package/dist/cjs/clients/feed/feed.js.map +1 -1
  6. package/dist/cjs/clients/feed/index.js +1 -10
  7. package/dist/cjs/clients/feed/index.js.map +1 -1
  8. package/dist/cjs/clients/feed/interfaces.js.map +1 -1
  9. package/dist/cjs/clients/feed/store.js +4 -15
  10. package/dist/cjs/clients/feed/store.js.map +1 -1
  11. package/dist/cjs/clients/feed/types.js.map +1 -1
  12. package/dist/cjs/clients/feed/utils.js +0 -5
  13. package/dist/cjs/clients/feed/utils.js.map +1 -1
  14. package/dist/cjs/clients/preferences/index.js +216 -249
  15. package/dist/cjs/clients/preferences/index.js.map +1 -1
  16. package/dist/cjs/clients/preferences/interfaces.js.map +1 -1
  17. package/dist/cjs/clients/users/index.js +185 -0
  18. package/dist/cjs/clients/users/index.js.map +1 -0
  19. package/dist/cjs/clients/users/interfaces.js +6 -0
  20. package/dist/cjs/clients/users/interfaces.js.map +1 -0
  21. package/dist/cjs/index.js +15 -21
  22. package/dist/cjs/index.js.map +1 -1
  23. package/dist/cjs/interfaces.js.map +1 -1
  24. package/dist/cjs/knock.js +11 -21
  25. package/dist/cjs/knock.js.map +1 -1
  26. package/dist/cjs/networkStatus.js +3 -6
  27. package/dist/cjs/networkStatus.js.map +1 -1
  28. package/dist/esm/api.js +9 -21
  29. package/dist/esm/api.js.map +1 -1
  30. package/dist/esm/clients/feed/feed.js +69 -149
  31. package/dist/esm/clients/feed/feed.js.map +1 -1
  32. package/dist/esm/clients/feed/index.js +0 -5
  33. package/dist/esm/clients/feed/index.js.map +1 -1
  34. package/dist/esm/clients/feed/interfaces.js.map +1 -1
  35. package/dist/esm/clients/feed/store.js +2 -8
  36. package/dist/esm/clients/feed/store.js.map +1 -1
  37. package/dist/esm/clients/feed/types.js.map +1 -1
  38. package/dist/esm/clients/feed/utils.js +0 -1
  39. package/dist/esm/clients/feed/utils.js.map +1 -1
  40. package/dist/esm/clients/preferences/index.js +35 -25
  41. package/dist/esm/clients/preferences/index.js.map +1 -1
  42. package/dist/esm/clients/preferences/interfaces.js.map +1 -1
  43. package/dist/esm/clients/users/index.js +84 -0
  44. package/dist/esm/clients/users/index.js.map +1 -0
  45. package/dist/esm/clients/users/interfaces.js +2 -0
  46. package/dist/esm/clients/users/interfaces.js.map +1 -0
  47. package/dist/esm/index.js +1 -0
  48. package/dist/esm/index.js.map +1 -1
  49. package/dist/esm/interfaces.js.map +1 -1
  50. package/dist/esm/knock.js +10 -22
  51. package/dist/esm/knock.js.map +1 -1
  52. package/dist/esm/networkStatus.js +3 -5
  53. package/dist/esm/networkStatus.js.map +1 -1
  54. package/dist/types/api.d.ts +1 -1
  55. package/dist/types/api.d.ts.map +1 -1
  56. package/dist/types/clients/feed/feed.d.ts +1 -1
  57. package/dist/types/clients/feed/feed.d.ts.map +1 -1
  58. package/dist/types/clients/feed/interfaces.d.ts +2 -1
  59. package/dist/types/clients/feed/interfaces.d.ts.map +1 -1
  60. package/dist/types/clients/feed/types.d.ts +10 -10
  61. package/dist/types/clients/feed/types.d.ts.map +1 -1
  62. package/dist/types/clients/preferences/index.d.ts +27 -0
  63. package/dist/types/clients/preferences/index.d.ts.map +1 -1
  64. package/dist/types/clients/preferences/interfaces.d.ts +7 -4
  65. package/dist/types/clients/preferences/interfaces.d.ts.map +1 -1
  66. package/dist/types/clients/users/index.d.ts +16 -0
  67. package/dist/types/clients/users/index.d.ts.map +1 -0
  68. package/dist/types/clients/users/interfaces.d.ts +8 -0
  69. package/dist/types/clients/users/interfaces.d.ts.map +1 -0
  70. package/dist/types/index.d.ts +1 -0
  71. package/dist/types/index.d.ts.map +1 -1
  72. package/dist/types/interfaces.d.ts +6 -2
  73. package/dist/types/interfaces.d.ts.map +1 -1
  74. package/dist/types/knock.d.ts +2 -0
  75. package/dist/types/knock.d.ts.map +1 -1
  76. package/package.json +15 -10
@@ -1,42 +1,27 @@
1
1
  "use strict";
2
2
 
3
3
  var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
-
5
4
  Object.defineProperty(exports, "__esModule", {
6
5
  value: true
7
6
  });
8
7
  exports["default"] = void 0;
9
-
10
8
  var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
11
-
12
9
  var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
13
-
14
10
  var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
15
-
16
11
  var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
17
-
18
12
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
19
-
20
13
  var _eventemitter = require("eventemitter2");
21
-
22
14
  var _store = _interopRequireDefault(require("./store"));
23
-
24
15
  var _networkStatus = require("../../networkStatus");
25
-
26
- function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
27
-
28
- function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
29
-
16
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
17
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2["default"])(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
30
18
  // Default options to apply
31
19
  var feedClientDefaults = {
32
20
  archived: "exclude"
33
21
  };
34
-
35
22
  var Feed = /*#__PURE__*/function () {
36
- // The raw store instance, used for binding in React and other environments
37
23
  function Feed(knock, feedId, options) {
38
24
  var _this = this;
39
-
40
25
  (0, _classCallCheck2["default"])(this, Feed);
41
26
  this.knock = knock;
42
27
  this.feedId = feedId;
@@ -46,6 +31,7 @@ var Feed = /*#__PURE__*/function () {
46
31
  (0, _defineProperty2["default"])(this, "broadcaster", void 0);
47
32
  (0, _defineProperty2["default"])(this, "defaultOptions", void 0);
48
33
  (0, _defineProperty2["default"])(this, "broadcastChannel", void 0);
34
+ // The raw store instance, used for binding in React and other environments
49
35
  (0, _defineProperty2["default"])(this, "store", void 0);
50
36
  this.apiClient = knock.client();
51
37
  this.feedId = feedId;
@@ -55,25 +41,25 @@ var Feed = /*#__PURE__*/function () {
55
41
  wildcard: true,
56
42
  delimiter: "."
57
43
  });
58
- this.defaultOptions = _objectSpread(_objectSpread({}, feedClientDefaults), options); // In server environments we might not have a socket connection
44
+ this.defaultOptions = _objectSpread(_objectSpread({}, feedClientDefaults), options);
59
45
 
46
+ // In server environments we might not have a socket connection
60
47
  if (this.apiClient.socket) {
61
48
  this.channel = this.apiClient.socket.channel("feeds:".concat(this.userFeedId), this.defaultOptions);
62
49
  this.channel.on("new-message", function (resp) {
63
50
  return _this.onNewMessageReceived(resp);
64
51
  });
65
- } // Attempt to bind to listen to other events from this feed in different tabs
66
- // Note: here we ensure `self` is available (it's not in server rendered envs)
67
-
52
+ }
68
53
 
54
+ // Attempt to bind to listen to other events from this feed in different tabs
55
+ // Note: here we ensure `self` is available (it's not in server rendered envs)
69
56
  this.broadcastChannel = typeof self !== "undefined" && "BroadcastChannel" in self ? new BroadcastChannel("knock:feed:".concat(this.userFeedId)) : null;
70
57
  }
58
+
71
59
  /**
72
60
  * Cleans up a feed instance by destroying the store and disconnecting
73
61
  * an open socket connection.
74
62
  */
75
-
76
-
77
63
  (0, _createClass2["default"])(Feed, [{
78
64
  key: "teardown",
79
65
  value: function teardown() {
@@ -81,36 +67,33 @@ var Feed = /*#__PURE__*/function () {
81
67
  this.channel.leave();
82
68
  this.channel.off("new-message");
83
69
  }
84
-
85
70
  this.broadcaster.removeAllListeners();
86
71
  this.store.destroy();
87
-
88
72
  if (this.broadcastChannel) {
89
73
  this.broadcastChannel.close();
90
74
  }
91
75
  }
76
+
92
77
  /*
93
78
  Initializes a real-time connection to Knock, connecting the websocket for the
94
79
  current ApiClient instance if the socket is not already connected.
95
80
  */
96
-
97
81
  }, {
98
82
  key: "listenForUpdates",
99
83
  value: function listenForUpdates() {
100
84
  var _this2 = this;
101
-
102
85
  // Connect the socket only if we don't already have a connection
103
86
  if (this.apiClient.socket && !this.apiClient.socket.isConnected()) {
104
87
  this.apiClient.socket.connect();
105
- } // Only join the channel if we're not already in a joining state
106
-
88
+ }
107
89
 
90
+ // Only join the channel if we're not already in a joining state
108
91
  if (this.channel && ["closed", "errored"].includes(this.channel.state)) {
109
92
  this.channel.join();
110
- } // Opt into receiving updates from _other tabs for the same user / feed_ via the broadcast
111
- // channel (iff it's enabled and exists)
112
-
93
+ }
113
94
 
95
+ // Opt into receiving updates from _other tabs for the same user / feed_ via the broadcast
96
+ // channel (iff it's enabled and exists)
114
97
  if (this.broadcastChannel && this.defaultOptions.__experimentalCrossBrowserUpdates === true) {
115
98
  this.broadcastChannel.onmessage = function (e) {
116
99
  switch (e.data.type) {
@@ -128,15 +111,14 @@ var Feed = /*#__PURE__*/function () {
128
111
  // maybe do this optimistically without the fetch.
129
112
  return _this2.fetch();
130
113
  break;
131
-
132
114
  default:
133
115
  return null;
134
116
  }
135
117
  };
136
118
  }
137
119
  }
138
- /* Binds a handler to be invoked when event occurs */
139
120
 
121
+ /* Binds a handler to be invoked when event occurs */
140
122
  }, {
141
123
  key: "on",
142
124
  value: function on(eventName, callback) {
@@ -158,27 +140,22 @@ var Feed = /*#__PURE__*/function () {
158
140
  var _markAsSeen = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee(itemOrItems) {
159
141
  var now;
160
142
  return _regenerator["default"].wrap(function _callee$(_context) {
161
- while (1) {
162
- switch (_context.prev = _context.next) {
163
- case 0:
164
- now = new Date().toISOString();
165
- this.optimisticallyPerformStatusUpdate(itemOrItems, "seen", {
166
- seen_at: now
167
- }, "unseen_count");
168
- return _context.abrupt("return", this.makeStatusUpdate(itemOrItems, "seen"));
169
-
170
- case 3:
171
- case "end":
172
- return _context.stop();
173
- }
143
+ while (1) switch (_context.prev = _context.next) {
144
+ case 0:
145
+ now = new Date().toISOString();
146
+ this.optimisticallyPerformStatusUpdate(itemOrItems, "seen", {
147
+ seen_at: now
148
+ }, "unseen_count");
149
+ return _context.abrupt("return", this.makeStatusUpdate(itemOrItems, "seen"));
150
+ case 3:
151
+ case "end":
152
+ return _context.stop();
174
153
  }
175
154
  }, _callee, this);
176
155
  }));
177
-
178
156
  function markAsSeen(_x) {
179
157
  return _markAsSeen.apply(this, arguments);
180
158
  }
181
-
182
159
  return markAsSeen;
183
160
  }()
184
161
  }, {
@@ -186,79 +163,71 @@ var Feed = /*#__PURE__*/function () {
186
163
  value: function () {
187
164
  var _markAllAsSeen = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee2() {
188
165
  var _this$store, getState, setState, _getState, metadata, items, isViewingOnlyUnseen, attrs, itemIds, result;
189
-
190
166
  return _regenerator["default"].wrap(function _callee2$(_context2) {
191
- while (1) {
192
- switch (_context2.prev = _context2.next) {
193
- case 0:
194
- // To mark all of the messages as seen we:
195
- // 1. Optimistically update *everything* we have in the store
196
- // 2. We decrement the `unseen_count` to zero optimistically
197
- // 3. We issue the API call to the endpoint
198
- //
199
- // Note: there is the potential for a race condition here because the bulk
200
- // update is an async method, so if a new message comes in during this window before
201
- // the update has been processed we'll effectively reset the `unseen_count` to be what it was.
202
- //
203
- // Note: here we optimistically handle the case whereby the feed is scoped to show only `unseen`
204
- // items by removing everything from view.
205
- _this$store = this.store, getState = _this$store.getState, setState = _this$store.setState;
206
- _getState = getState(), metadata = _getState.metadata, items = _getState.items;
207
- isViewingOnlyUnseen = this.defaultOptions.status === "unseen"; // If we're looking at the unseen view, then we want to remove all of the items optimistically
208
- // from the store given that nothing should be visible. We do this by resetting the store state
209
- // and setting the current metadata counts to 0
210
-
211
- if (isViewingOnlyUnseen) {
212
- setState(function (store) {
213
- return store.resetStore(_objectSpread(_objectSpread({}, metadata), {}, {
214
- total_count: 0,
215
- unseen_count: 0
216
- }));
217
- });
218
- } else {
219
- // Otherwise we want to update the metadata and mark all of the items in the store as seen
220
- setState(function (store) {
221
- return store.setMetadata(_objectSpread(_objectSpread({}, metadata), {}, {
222
- unseen_count: 0
223
- }));
224
- });
225
- attrs = {
226
- seen_at: new Date().toISOString()
227
- };
228
- itemIds = items.map(function (item) {
229
- return item.id;
230
- });
231
- setState(function (store) {
232
- return store.setItemAttrs(itemIds, attrs);
233
- });
234
- } // Issue the API request to the bulk status change API
235
-
236
-
237
- _context2.next = 6;
238
- return this.makeBulkStatusUpdate("seen");
239
-
240
- case 6:
241
- result = _context2.sent;
242
- this.broadcaster.emit("items:all_seen", {
243
- items: items
167
+ while (1) switch (_context2.prev = _context2.next) {
168
+ case 0:
169
+ // To mark all of the messages as seen we:
170
+ // 1. Optimistically update *everything* we have in the store
171
+ // 2. We decrement the `unseen_count` to zero optimistically
172
+ // 3. We issue the API call to the endpoint
173
+ //
174
+ // Note: there is the potential for a race condition here because the bulk
175
+ // update is an async method, so if a new message comes in during this window before
176
+ // the update has been processed we'll effectively reset the `unseen_count` to be what it was.
177
+ //
178
+ // Note: here we optimistically handle the case whereby the feed is scoped to show only `unseen`
179
+ // items by removing everything from view.
180
+ _this$store = this.store, getState = _this$store.getState, setState = _this$store.setState;
181
+ _getState = getState(), metadata = _getState.metadata, items = _getState.items;
182
+ isViewingOnlyUnseen = this.defaultOptions.status === "unseen"; // If we're looking at the unseen view, then we want to remove all of the items optimistically
183
+ // from the store given that nothing should be visible. We do this by resetting the store state
184
+ // and setting the current metadata counts to 0
185
+ if (isViewingOnlyUnseen) {
186
+ setState(function (store) {
187
+ return store.resetStore(_objectSpread(_objectSpread({}, metadata), {}, {
188
+ total_count: 0,
189
+ unseen_count: 0
190
+ }));
244
191
  });
245
- this.broadcastOverChannel("items:all_seen", {
246
- items: items
192
+ } else {
193
+ // Otherwise we want to update the metadata and mark all of the items in the store as seen
194
+ setState(function (store) {
195
+ return store.setMetadata(_objectSpread(_objectSpread({}, metadata), {}, {
196
+ unseen_count: 0
197
+ }));
247
198
  });
248
- return _context2.abrupt("return", result);
249
-
250
- case 10:
251
- case "end":
252
- return _context2.stop();
253
- }
199
+ attrs = {
200
+ seen_at: new Date().toISOString()
201
+ };
202
+ itemIds = items.map(function (item) {
203
+ return item.id;
204
+ });
205
+ setState(function (store) {
206
+ return store.setItemAttrs(itemIds, attrs);
207
+ });
208
+ }
209
+
210
+ // Issue the API request to the bulk status change API
211
+ _context2.next = 6;
212
+ return this.makeBulkStatusUpdate("seen");
213
+ case 6:
214
+ result = _context2.sent;
215
+ this.broadcaster.emit("items:all_seen", {
216
+ items: items
217
+ });
218
+ this.broadcastOverChannel("items:all_seen", {
219
+ items: items
220
+ });
221
+ return _context2.abrupt("return", result);
222
+ case 10:
223
+ case "end":
224
+ return _context2.stop();
254
225
  }
255
226
  }, _callee2, this);
256
227
  }));
257
-
258
228
  function markAllAsSeen() {
259
229
  return _markAllAsSeen.apply(this, arguments);
260
230
  }
261
-
262
231
  return markAllAsSeen;
263
232
  }()
264
233
  }, {
@@ -266,26 +235,21 @@ var Feed = /*#__PURE__*/function () {
266
235
  value: function () {
267
236
  var _markAsUnseen = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee3(itemOrItems) {
268
237
  return _regenerator["default"].wrap(function _callee3$(_context3) {
269
- while (1) {
270
- switch (_context3.prev = _context3.next) {
271
- case 0:
272
- this.optimisticallyPerformStatusUpdate(itemOrItems, "unseen", {
273
- seen_at: null
274
- }, "unseen_count");
275
- return _context3.abrupt("return", this.makeStatusUpdate(itemOrItems, "unseen"));
276
-
277
- case 2:
278
- case "end":
279
- return _context3.stop();
280
- }
238
+ while (1) switch (_context3.prev = _context3.next) {
239
+ case 0:
240
+ this.optimisticallyPerformStatusUpdate(itemOrItems, "unseen", {
241
+ seen_at: null
242
+ }, "unseen_count");
243
+ return _context3.abrupt("return", this.makeStatusUpdate(itemOrItems, "unseen"));
244
+ case 2:
245
+ case "end":
246
+ return _context3.stop();
281
247
  }
282
248
  }, _callee3, this);
283
249
  }));
284
-
285
250
  function markAsUnseen(_x2) {
286
251
  return _markAsUnseen.apply(this, arguments);
287
252
  }
288
-
289
253
  return markAsUnseen;
290
254
  }()
291
255
  }, {
@@ -294,27 +258,22 @@ var Feed = /*#__PURE__*/function () {
294
258
  var _markAsRead = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee4(itemOrItems) {
295
259
  var now;
296
260
  return _regenerator["default"].wrap(function _callee4$(_context4) {
297
- while (1) {
298
- switch (_context4.prev = _context4.next) {
299
- case 0:
300
- now = new Date().toISOString();
301
- this.optimisticallyPerformStatusUpdate(itemOrItems, "read", {
302
- read_at: now
303
- }, "unread_count");
304
- return _context4.abrupt("return", this.makeStatusUpdate(itemOrItems, "read"));
305
-
306
- case 3:
307
- case "end":
308
- return _context4.stop();
309
- }
261
+ while (1) switch (_context4.prev = _context4.next) {
262
+ case 0:
263
+ now = new Date().toISOString();
264
+ this.optimisticallyPerformStatusUpdate(itemOrItems, "read", {
265
+ read_at: now
266
+ }, "unread_count");
267
+ return _context4.abrupt("return", this.makeStatusUpdate(itemOrItems, "read"));
268
+ case 3:
269
+ case "end":
270
+ return _context4.stop();
310
271
  }
311
272
  }, _callee4, this);
312
273
  }));
313
-
314
274
  function markAsRead(_x3) {
315
275
  return _markAsRead.apply(this, arguments);
316
276
  }
317
-
318
277
  return markAsRead;
319
278
  }()
320
279
  }, {
@@ -322,79 +281,71 @@ var Feed = /*#__PURE__*/function () {
322
281
  value: function () {
323
282
  var _markAllAsRead = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee5() {
324
283
  var _this$store2, getState, setState, _getState2, metadata, items, isViewingOnlyUnread, attrs, itemIds, result;
325
-
326
284
  return _regenerator["default"].wrap(function _callee5$(_context5) {
327
- while (1) {
328
- switch (_context5.prev = _context5.next) {
329
- case 0:
330
- // To mark all of the messages as read we:
331
- // 1. Optimistically update *everything* we have in the store
332
- // 2. We decrement the `unread_count` to zero optimistically
333
- // 3. We issue the API call to the endpoint
334
- //
335
- // Note: there is the potential for a race condition here because the bulk
336
- // update is an async method, so if a new message comes in during this window before
337
- // the update has been processed we'll effectively reset the `unread_count` to be what it was.
338
- //
339
- // Note: here we optimistically handle the case whereby the feed is scoped to show only `unread`
340
- // items by removing everything from view.
341
- _this$store2 = this.store, getState = _this$store2.getState, setState = _this$store2.setState;
342
- _getState2 = getState(), metadata = _getState2.metadata, items = _getState2.items;
343
- isViewingOnlyUnread = this.defaultOptions.status === "unread"; // If we're looking at the unread view, then we want to remove all of the items optimistically
344
- // from the store given that nothing should be visible. We do this by resetting the store state
345
- // and setting the current metadata counts to 0
346
-
347
- if (isViewingOnlyUnread) {
348
- setState(function (store) {
349
- return store.resetStore(_objectSpread(_objectSpread({}, metadata), {}, {
350
- total_count: 0,
351
- unread_count: 0
352
- }));
353
- });
354
- } else {
355
- // Otherwise we want to update the metadata and mark all of the items in the store as seen
356
- setState(function (store) {
357
- return store.setMetadata(_objectSpread(_objectSpread({}, metadata), {}, {
358
- unread_count: 0
359
- }));
360
- });
361
- attrs = {
362
- read_at: new Date().toISOString()
363
- };
364
- itemIds = items.map(function (item) {
365
- return item.id;
366
- });
367
- setState(function (store) {
368
- return store.setItemAttrs(itemIds, attrs);
369
- });
370
- } // Issue the API request to the bulk status change API
371
-
372
-
373
- _context5.next = 6;
374
- return this.makeBulkStatusUpdate("read");
375
-
376
- case 6:
377
- result = _context5.sent;
378
- this.broadcaster.emit("items:all_read", {
379
- items: items
285
+ while (1) switch (_context5.prev = _context5.next) {
286
+ case 0:
287
+ // To mark all of the messages as read we:
288
+ // 1. Optimistically update *everything* we have in the store
289
+ // 2. We decrement the `unread_count` to zero optimistically
290
+ // 3. We issue the API call to the endpoint
291
+ //
292
+ // Note: there is the potential for a race condition here because the bulk
293
+ // update is an async method, so if a new message comes in during this window before
294
+ // the update has been processed we'll effectively reset the `unread_count` to be what it was.
295
+ //
296
+ // Note: here we optimistically handle the case whereby the feed is scoped to show only `unread`
297
+ // items by removing everything from view.
298
+ _this$store2 = this.store, getState = _this$store2.getState, setState = _this$store2.setState;
299
+ _getState2 = getState(), metadata = _getState2.metadata, items = _getState2.items;
300
+ isViewingOnlyUnread = this.defaultOptions.status === "unread"; // If we're looking at the unread view, then we want to remove all of the items optimistically
301
+ // from the store given that nothing should be visible. We do this by resetting the store state
302
+ // and setting the current metadata counts to 0
303
+ if (isViewingOnlyUnread) {
304
+ setState(function (store) {
305
+ return store.resetStore(_objectSpread(_objectSpread({}, metadata), {}, {
306
+ total_count: 0,
307
+ unread_count: 0
308
+ }));
380
309
  });
381
- this.broadcastOverChannel("items:all_read", {
382
- items: items
310
+ } else {
311
+ // Otherwise we want to update the metadata and mark all of the items in the store as seen
312
+ setState(function (store) {
313
+ return store.setMetadata(_objectSpread(_objectSpread({}, metadata), {}, {
314
+ unread_count: 0
315
+ }));
383
316
  });
384
- return _context5.abrupt("return", result);
385
-
386
- case 10:
387
- case "end":
388
- return _context5.stop();
389
- }
317
+ attrs = {
318
+ read_at: new Date().toISOString()
319
+ };
320
+ itemIds = items.map(function (item) {
321
+ return item.id;
322
+ });
323
+ setState(function (store) {
324
+ return store.setItemAttrs(itemIds, attrs);
325
+ });
326
+ }
327
+
328
+ // Issue the API request to the bulk status change API
329
+ _context5.next = 6;
330
+ return this.makeBulkStatusUpdate("read");
331
+ case 6:
332
+ result = _context5.sent;
333
+ this.broadcaster.emit("items:all_read", {
334
+ items: items
335
+ });
336
+ this.broadcastOverChannel("items:all_read", {
337
+ items: items
338
+ });
339
+ return _context5.abrupt("return", result);
340
+ case 10:
341
+ case "end":
342
+ return _context5.stop();
390
343
  }
391
344
  }, _callee5, this);
392
345
  }));
393
-
394
346
  function markAllAsRead() {
395
347
  return _markAllAsRead.apply(this, arguments);
396
348
  }
397
-
398
349
  return markAllAsRead;
399
350
  }()
400
351
  }, {
@@ -402,26 +353,21 @@ var Feed = /*#__PURE__*/function () {
402
353
  value: function () {
403
354
  var _markAsUnread = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee6(itemOrItems) {
404
355
  return _regenerator["default"].wrap(function _callee6$(_context6) {
405
- while (1) {
406
- switch (_context6.prev = _context6.next) {
407
- case 0:
408
- this.optimisticallyPerformStatusUpdate(itemOrItems, "unread", {
409
- read_at: null
410
- }, "unread_count");
411
- return _context6.abrupt("return", this.makeStatusUpdate(itemOrItems, "unread"));
412
-
413
- case 2:
414
- case "end":
415
- return _context6.stop();
416
- }
356
+ while (1) switch (_context6.prev = _context6.next) {
357
+ case 0:
358
+ this.optimisticallyPerformStatusUpdate(itemOrItems, "unread", {
359
+ read_at: null
360
+ }, "unread_count");
361
+ return _context6.abrupt("return", this.makeStatusUpdate(itemOrItems, "unread"));
362
+ case 2:
363
+ case "end":
364
+ return _context6.stop();
417
365
  }
418
366
  }, _callee6, this);
419
367
  }));
420
-
421
368
  function markAsUnread(_x4) {
422
369
  return _markAsUnread.apply(this, arguments);
423
370
  }
424
-
425
371
  return markAsUnread;
426
372
  }()
427
373
  }, {
@@ -430,28 +376,23 @@ var Feed = /*#__PURE__*/function () {
430
376
  var _markAsInteracted = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee7(itemOrItems) {
431
377
  var now;
432
378
  return _regenerator["default"].wrap(function _callee7$(_context7) {
433
- while (1) {
434
- switch (_context7.prev = _context7.next) {
435
- case 0:
436
- now = new Date().toISOString();
437
- this.optimisticallyPerformStatusUpdate(itemOrItems, "interacted", {
438
- read_at: now,
439
- interacted_at: now
440
- }, "unread_count");
441
- return _context7.abrupt("return", this.makeStatusUpdate(itemOrItems, "interacted"));
442
-
443
- case 3:
444
- case "end":
445
- return _context7.stop();
446
- }
379
+ while (1) switch (_context7.prev = _context7.next) {
380
+ case 0:
381
+ now = new Date().toISOString();
382
+ this.optimisticallyPerformStatusUpdate(itemOrItems, "interacted", {
383
+ read_at: now,
384
+ interacted_at: now
385
+ }, "unread_count");
386
+ return _context7.abrupt("return", this.makeStatusUpdate(itemOrItems, "interacted"));
387
+ case 3:
388
+ case "end":
389
+ return _context7.stop();
447
390
  }
448
391
  }, _callee7, this);
449
392
  }));
450
-
451
393
  function markAsInteracted(_x5) {
452
394
  return _markAsInteracted.apply(this, arguments);
453
395
  }
454
-
455
396
  return markAsInteracted;
456
397
  }()
457
398
  /*
@@ -460,154 +401,134 @@ var Feed = /*#__PURE__*/function () {
460
401
  - Remove the item from the feed list when the `archived` flag is "exclude" (default)
461
402
  TODO: how do we handle rollbacks?
462
403
  */
463
-
464
404
  }, {
465
405
  key: "markAsArchived",
466
- value: function () {
406
+ value: (function () {
467
407
  var _markAsArchived = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee8(itemOrItems) {
468
408
  var _this$store3, getState, setState, state, shouldOptimisticallyRemoveItems, normalizedItems, itemIds, unseenCount, unreadCount, updatedMetadata, entriesToSet;
469
-
470
409
  return _regenerator["default"].wrap(function _callee8$(_context8) {
471
- while (1) {
472
- switch (_context8.prev = _context8.next) {
473
- case 0:
474
- _this$store3 = this.store, getState = _this$store3.getState, setState = _this$store3.setState;
475
- state = getState();
476
- shouldOptimisticallyRemoveItems = this.defaultOptions.archived === "exclude";
477
- normalizedItems = Array.isArray(itemOrItems) ? itemOrItems : [itemOrItems];
478
- itemIds = normalizedItems.map(function (item) {
479
- return item.id;
410
+ while (1) switch (_context8.prev = _context8.next) {
411
+ case 0:
412
+ _this$store3 = this.store, getState = _this$store3.getState, setState = _this$store3.setState;
413
+ state = getState();
414
+ shouldOptimisticallyRemoveItems = this.defaultOptions.archived === "exclude";
415
+ normalizedItems = Array.isArray(itemOrItems) ? itemOrItems : [itemOrItems];
416
+ itemIds = normalizedItems.map(function (item) {
417
+ return item.id;
418
+ });
419
+ /*
420
+ In the code here we want to optimistically update counts and items
421
+ that are persisted such that we can display updates immediately on the feed
422
+ without needing to make a network request.
423
+ Note: right now this does *not* take into account offline handling or any extensive retry
424
+ logic, so rollbacks aren't considered. That probably needs to be a future consideration for
425
+ this library.
426
+ Scenarios to consider:
427
+ ## Feed scope to archived *only*
428
+ - Counts should not be decremented
429
+ - Items should not be removed
430
+ ## Feed scoped to exclude archived items (the default)
431
+ - Counts should be decremented
432
+ - Items should be removed
433
+ ## Feed scoped to include archived items as well
434
+ - Counts should not be decremented
435
+ - Items should not be removed
436
+ */
437
+ if (shouldOptimisticallyRemoveItems) {
438
+ // If any of the items are unseen or unread, then capture as we'll want to decrement
439
+ // the counts for these in the metadata we have
440
+ unseenCount = normalizedItems.filter(function (i) {
441
+ return !i.seen_at;
442
+ }).length;
443
+ unreadCount = normalizedItems.filter(function (i) {
444
+ return !i.read_at;
445
+ }).length; // Build the new metadata
446
+ updatedMetadata = _objectSpread(_objectSpread({}, state.metadata), {}, {
447
+ total_count: state.metadata.total_count - normalizedItems.length,
448
+ unseen_count: state.metadata.unseen_count - unseenCount,
449
+ unread_count: state.metadata.unread_count - unreadCount
450
+ }); // Remove the archiving entries
451
+ entriesToSet = state.items.filter(function (item) {
452
+ return !itemIds.includes(item.id);
480
453
  });
481
- /*
482
- In the code here we want to optimistically update counts and items
483
- that are persisted such that we can display updates immediately on the feed
484
- without needing to make a network request.
485
- Note: right now this does *not* take into account offline handling or any extensive retry
486
- logic, so rollbacks aren't considered. That probably needs to be a future consideration for
487
- this library.
488
- Scenarios to consider:
489
- ## Feed scope to archived *only*
490
- - Counts should not be decremented
491
- - Items should not be removed
492
- ## Feed scoped to exclude archived items (the default)
493
- - Counts should be decremented
494
- - Items should be removed
495
- ## Feed scoped to include archived items as well
496
- - Counts should not be decremented
497
- - Items should not be removed
498
- */
499
-
500
- if (shouldOptimisticallyRemoveItems) {
501
- // If any of the items are unseen or unread, then capture as we'll want to decrement
502
- // the counts for these in the metadata we have
503
- unseenCount = normalizedItems.filter(function (i) {
504
- return !i.seen_at;
505
- }).length;
506
- unreadCount = normalizedItems.filter(function (i) {
507
- return !i.read_at;
508
- }).length; // Build the new metadata
509
-
510
- updatedMetadata = _objectSpread(_objectSpread({}, state.metadata), {}, {
511
- total_count: state.metadata.total_count - normalizedItems.length,
512
- unseen_count: state.metadata.unseen_count - unseenCount,
513
- unread_count: state.metadata.unread_count - unreadCount
514
- }); // Remove the archiving entries
515
-
516
- entriesToSet = state.items.filter(function (item) {
517
- return !itemIds.includes(item.id);
518
- });
519
- setState(function (state) {
520
- return state.setResult({
521
- entries: entriesToSet,
522
- meta: updatedMetadata,
523
- page_info: state.pageInfo
524
- });
525
- });
526
- } else {
527
- // Mark all the entries being updated as archived either way so the state is correct
528
- state.setItemAttrs(itemIds, {
529
- archived_at: new Date().toISOString()
454
+ setState(function (state) {
455
+ return state.setResult({
456
+ entries: entriesToSet,
457
+ meta: updatedMetadata,
458
+ page_info: state.pageInfo
530
459
  });
531
- }
532
-
533
- return _context8.abrupt("return", this.makeStatusUpdate(itemOrItems, "archived"));
534
-
535
- case 7:
536
- case "end":
537
- return _context8.stop();
538
- }
460
+ });
461
+ } else {
462
+ // Mark all the entries being updated as archived either way so the state is correct
463
+ state.setItemAttrs(itemIds, {
464
+ archived_at: new Date().toISOString()
465
+ });
466
+ }
467
+ return _context8.abrupt("return", this.makeStatusUpdate(itemOrItems, "archived"));
468
+ case 7:
469
+ case "end":
470
+ return _context8.stop();
539
471
  }
540
472
  }, _callee8, this);
541
473
  }));
542
-
543
474
  function markAsArchived(_x6) {
544
475
  return _markAsArchived.apply(this, arguments);
545
476
  }
546
-
547
477
  return markAsArchived;
548
- }()
478
+ }())
549
479
  }, {
550
480
  key: "markAllAsArchived",
551
481
  value: function () {
552
482
  var _markAllAsArchived = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee9() {
553
483
  var _this$store4, setState, getState, _getState3, items, shouldOptimisticallyRemoveItems, result;
554
-
555
484
  return _regenerator["default"].wrap(function _callee9$(_context9) {
556
- while (1) {
557
- switch (_context9.prev = _context9.next) {
558
- case 0:
559
- // Note: there is the potential for a race condition here because the bulk
560
- // update is an async method, so if a new message comes in during this window before
561
- // the update has been processed we'll effectively reset the `unseen_count` to be what it was.
562
- _this$store4 = this.store, setState = _this$store4.setState, getState = _this$store4.getState;
563
- _getState3 = getState(), items = _getState3.items; // Here if we're looking at a feed that excludes all of the archived items by default then we
564
- // will want to optimistically remove all of the items from the feed as they are now all excluded
565
-
566
- shouldOptimisticallyRemoveItems = this.defaultOptions.archived === "exclude";
567
-
568
- if (shouldOptimisticallyRemoveItems) {
569
- // Reset the store to clear out all of items and reset the badge count
570
- setState(function (store) {
571
- return store.resetStore();
485
+ while (1) switch (_context9.prev = _context9.next) {
486
+ case 0:
487
+ // Note: there is the potential for a race condition here because the bulk
488
+ // update is an async method, so if a new message comes in during this window before
489
+ // the update has been processed we'll effectively reset the `unseen_count` to be what it was.
490
+ _this$store4 = this.store, setState = _this$store4.setState, getState = _this$store4.getState;
491
+ _getState3 = getState(), items = _getState3.items; // Here if we're looking at a feed that excludes all of the archived items by default then we
492
+ // will want to optimistically remove all of the items from the feed as they are now all excluded
493
+ shouldOptimisticallyRemoveItems = this.defaultOptions.archived === "exclude";
494
+ if (shouldOptimisticallyRemoveItems) {
495
+ // Reset the store to clear out all of items and reset the badge count
496
+ setState(function (store) {
497
+ return store.resetStore();
498
+ });
499
+ } else {
500
+ // Mark all the entries being updated as archived either way so the state is correct
501
+ setState(function (store) {
502
+ var itemIds = items.map(function (i) {
503
+ return i.id;
572
504
  });
573
- } else {
574
- // Mark all the entries being updated as archived either way so the state is correct
575
- setState(function (store) {
576
- var itemIds = items.map(function (i) {
577
- return i.id;
578
- });
579
- store.setItemAttrs(itemIds, {
580
- archived_at: new Date().toISOString()
581
- });
505
+ store.setItemAttrs(itemIds, {
506
+ archived_at: new Date().toISOString()
582
507
  });
583
- } // Issue the API request to the bulk status change API
584
-
585
-
586
- _context9.next = 6;
587
- return this.makeBulkStatusUpdate("archive");
588
-
589
- case 6:
590
- result = _context9.sent;
591
- this.broadcaster.emit("items:all_archived", {
592
- items: items
593
- });
594
- this.broadcastOverChannel("items:all_archived", {
595
- items: items
596
508
  });
597
- return _context9.abrupt("return", result);
598
-
599
- case 10:
600
- case "end":
601
- return _context9.stop();
602
- }
509
+ }
510
+
511
+ // Issue the API request to the bulk status change API
512
+ _context9.next = 6;
513
+ return this.makeBulkStatusUpdate("archive");
514
+ case 6:
515
+ result = _context9.sent;
516
+ this.broadcaster.emit("items:all_archived", {
517
+ items: items
518
+ });
519
+ this.broadcastOverChannel("items:all_archived", {
520
+ items: items
521
+ });
522
+ return _context9.abrupt("return", result);
523
+ case 10:
524
+ case "end":
525
+ return _context9.stop();
603
526
  }
604
527
  }, _callee9, this);
605
528
  }));
606
-
607
529
  function markAllAsArchived() {
608
530
  return _markAllAsArchived.apply(this, arguments);
609
531
  }
610
-
611
532
  return markAllAsArchived;
612
533
  }()
613
534
  }, {
@@ -615,243 +536,208 @@ var Feed = /*#__PURE__*/function () {
615
536
  value: function () {
616
537
  var _markAsUnarchived = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee10(itemOrItems) {
617
538
  return _regenerator["default"].wrap(function _callee10$(_context10) {
618
- while (1) {
619
- switch (_context10.prev = _context10.next) {
620
- case 0:
621
- this.optimisticallyPerformStatusUpdate(itemOrItems, "unarchived", {
622
- archived_at: null
623
- });
624
- return _context10.abrupt("return", this.makeStatusUpdate(itemOrItems, "unarchived"));
625
-
626
- case 2:
627
- case "end":
628
- return _context10.stop();
629
- }
539
+ while (1) switch (_context10.prev = _context10.next) {
540
+ case 0:
541
+ this.optimisticallyPerformStatusUpdate(itemOrItems, "unarchived", {
542
+ archived_at: null
543
+ });
544
+ return _context10.abrupt("return", this.makeStatusUpdate(itemOrItems, "unarchived"));
545
+ case 2:
546
+ case "end":
547
+ return _context10.stop();
630
548
  }
631
549
  }, _callee10, this);
632
550
  }));
633
-
634
551
  function markAsUnarchived(_x7) {
635
552
  return _markAsUnarchived.apply(this, arguments);
636
553
  }
637
-
638
554
  return markAsUnarchived;
639
- }()
640
- /* Fetches the feed content, appending it to the store */
641
-
555
+ }() /* Fetches the feed content, appending it to the store */
642
556
  }, {
643
557
  key: "fetch",
644
- value: function () {
558
+ value: (function () {
645
559
  var _fetch = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee11() {
646
560
  var options,
647
- _this$store5,
648
- setState,
649
- getState,
650
- _getState4,
651
- networkStatus,
652
- queryParams,
653
- result,
654
- response,
655
- opts,
656
- _opts,
657
- feedEventType,
658
- eventPayload,
659
- _args11 = arguments;
660
-
561
+ _this$store5,
562
+ setState,
563
+ getState,
564
+ _getState4,
565
+ networkStatus,
566
+ queryParams,
567
+ result,
568
+ response,
569
+ opts,
570
+ _opts,
571
+ feedEventType,
572
+ eventPayload,
573
+ _args11 = arguments;
661
574
  return _regenerator["default"].wrap(function _callee11$(_context11) {
662
- while (1) {
663
- switch (_context11.prev = _context11.next) {
664
- case 0:
665
- options = _args11.length > 0 && _args11[0] !== undefined ? _args11[0] : {};
666
- _this$store5 = this.store, setState = _this$store5.setState, getState = _this$store5.getState;
667
- _getState4 = getState(), networkStatus = _getState4.networkStatus; // If there's an existing request in flight, then do nothing
668
-
669
- if (!(0, _networkStatus.isRequestInFlight)(networkStatus)) {
670
- _context11.next = 5;
671
- break;
672
- }
673
-
674
- return _context11.abrupt("return");
675
-
676
- case 5:
677
- // Set the loading type based on the request type it is
678
- setState(function (store) {
679
- var _options$__loadingTyp;
680
-
681
- return store.setNetworkStatus((_options$__loadingTyp = options.__loadingType) !== null && _options$__loadingTyp !== void 0 ? _options$__loadingTyp : _networkStatus.NetworkStatus.loading);
682
- }); // Always include the default params, if they have been set
683
-
684
- queryParams = _objectSpread(_objectSpread(_objectSpread({}, this.defaultOptions), options), {}, {
685
- // Unset options that should not be sent to the API
686
- __loadingType: undefined,
687
- __fetchSource: undefined,
688
- __experimentalCrossBrowserUpdates: undefined
689
- });
690
- _context11.next = 9;
691
- return this.apiClient.makeRequest({
692
- method: "GET",
693
- url: "/v1/users/".concat(this.knock.userId, "/feeds/").concat(this.feedId),
694
- params: queryParams
695
- });
696
-
697
- case 9:
698
- result = _context11.sent;
699
-
700
- if (!(result.statusCode === "error" || !result.body)) {
701
- _context11.next = 13;
702
- break;
703
- }
704
-
705
- setState(function (store) {
706
- return store.setNetworkStatus(_networkStatus.NetworkStatus.error);
707
- });
708
- return _context11.abrupt("return", {
709
- status: result.statusCode,
710
- data: result.error || result.body
711
- });
712
-
713
- case 13:
714
- response = {
715
- entries: result.body.entries,
716
- meta: result.body.meta,
717
- page_info: result.body.page_info
575
+ while (1) switch (_context11.prev = _context11.next) {
576
+ case 0:
577
+ options = _args11.length > 0 && _args11[0] !== undefined ? _args11[0] : {};
578
+ _this$store5 = this.store, setState = _this$store5.setState, getState = _this$store5.getState;
579
+ _getState4 = getState(), networkStatus = _getState4.networkStatus; // If there's an existing request in flight, then do nothing
580
+ if (!(0, _networkStatus.isRequestInFlight)(networkStatus)) {
581
+ _context11.next = 5;
582
+ break;
583
+ }
584
+ return _context11.abrupt("return");
585
+ case 5:
586
+ // Set the loading type based on the request type it is
587
+ setState(function (store) {
588
+ var _options$__loadingTyp;
589
+ return store.setNetworkStatus((_options$__loadingTyp = options.__loadingType) !== null && _options$__loadingTyp !== void 0 ? _options$__loadingTyp : _networkStatus.NetworkStatus.loading);
590
+ });
591
+
592
+ // Always include the default params, if they have been set
593
+ queryParams = _objectSpread(_objectSpread(_objectSpread({}, this.defaultOptions), options), {}, {
594
+ // Unset options that should not be sent to the API
595
+ __loadingType: undefined,
596
+ __fetchSource: undefined,
597
+ __experimentalCrossBrowserUpdates: undefined
598
+ });
599
+ _context11.next = 9;
600
+ return this.apiClient.makeRequest({
601
+ method: "GET",
602
+ url: "/v1/users/".concat(this.knock.userId, "/feeds/").concat(this.feedId),
603
+ params: queryParams
604
+ });
605
+ case 9:
606
+ result = _context11.sent;
607
+ if (!(result.statusCode === "error" || !result.body)) {
608
+ _context11.next = 13;
609
+ break;
610
+ }
611
+ setState(function (store) {
612
+ return store.setNetworkStatus(_networkStatus.NetworkStatus.error);
613
+ });
614
+ return _context11.abrupt("return", {
615
+ status: result.statusCode,
616
+ data: result.error || result.body
617
+ });
618
+ case 13:
619
+ response = {
620
+ entries: result.body.entries,
621
+ meta: result.body.meta,
622
+ page_info: result.body.page_info
623
+ };
624
+ if (options.before) {
625
+ opts = {
626
+ shouldSetPage: false,
627
+ shouldAppend: true
718
628
  };
719
-
720
- if (options.before) {
721
- opts = {
722
- shouldSetPage: false,
723
- shouldAppend: true
724
- };
725
- setState(function (state) {
726
- return state.setResult(response, opts);
727
- });
728
- } else if (options.after) {
729
- _opts = {
730
- shouldSetPage: true,
731
- shouldAppend: true
732
- };
733
- setState(function (state) {
734
- return state.setResult(response, _opts);
735
- });
736
- } else {
737
- setState(function (state) {
738
- return state.setResult(response);
739
- });
740
- } // Legacy `messages.new` event, should be removed in a future version
741
-
742
-
743
- this.broadcast("messages.new", response); // Broadcast the appropriate event type depending on the fetch source
744
-
745
- feedEventType = options.__fetchSource === "socket" ? "items.received.realtime" : "items.received.page";
746
- eventPayload = {
747
- items: response.entries,
748
- metadata: response.meta,
749
- event: feedEventType
629
+ setState(function (state) {
630
+ return state.setResult(response, opts);
631
+ });
632
+ } else if (options.after) {
633
+ _opts = {
634
+ shouldSetPage: true,
635
+ shouldAppend: true
750
636
  };
751
- this.broadcast(eventPayload.event, eventPayload);
752
- return _context11.abrupt("return", {
753
- data: response,
754
- status: result.statusCode
637
+ setState(function (state) {
638
+ return state.setResult(response, _opts);
755
639
  });
756
-
757
- case 20:
758
- case "end":
759
- return _context11.stop();
760
- }
640
+ } else {
641
+ setState(function (state) {
642
+ return state.setResult(response);
643
+ });
644
+ }
645
+
646
+ // Legacy `messages.new` event, should be removed in a future version
647
+ this.broadcast("messages.new", response);
648
+
649
+ // Broadcast the appropriate event type depending on the fetch source
650
+ feedEventType = options.__fetchSource === "socket" ? "items.received.realtime" : "items.received.page";
651
+ eventPayload = {
652
+ items: response.entries,
653
+ metadata: response.meta,
654
+ event: feedEventType
655
+ };
656
+ this.broadcast(eventPayload.event, eventPayload);
657
+ return _context11.abrupt("return", {
658
+ data: response,
659
+ status: result.statusCode
660
+ });
661
+ case 20:
662
+ case "end":
663
+ return _context11.stop();
761
664
  }
762
665
  }, _callee11, this);
763
666
  }));
764
-
765
667
  function fetch() {
766
668
  return _fetch.apply(this, arguments);
767
669
  }
768
-
769
670
  return fetch;
770
- }()
671
+ }())
771
672
  }, {
772
673
  key: "fetchNextPage",
773
674
  value: function () {
774
675
  var _fetchNextPage = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee12() {
775
676
  var getState, _getState5, pageInfo;
776
-
777
677
  return _regenerator["default"].wrap(function _callee12$(_context12) {
778
- while (1) {
779
- switch (_context12.prev = _context12.next) {
780
- case 0:
781
- // Attempts to fetch the next page of results (if we have any)
782
- getState = this.store.getState;
783
- _getState5 = getState(), pageInfo = _getState5.pageInfo;
784
-
785
- if (pageInfo.after) {
786
- _context12.next = 4;
787
- break;
788
- }
789
-
790
- return _context12.abrupt("return");
791
-
792
- case 4:
793
- this.fetch({
794
- after: pageInfo.after,
795
- __loadingType: _networkStatus.NetworkStatus.fetchMore
796
- });
797
-
798
- case 5:
799
- case "end":
800
- return _context12.stop();
801
- }
678
+ while (1) switch (_context12.prev = _context12.next) {
679
+ case 0:
680
+ // Attempts to fetch the next page of results (if we have any)
681
+ getState = this.store.getState;
682
+ _getState5 = getState(), pageInfo = _getState5.pageInfo;
683
+ if (pageInfo.after) {
684
+ _context12.next = 4;
685
+ break;
686
+ }
687
+ return _context12.abrupt("return");
688
+ case 4:
689
+ this.fetch({
690
+ after: pageInfo.after,
691
+ __loadingType: _networkStatus.NetworkStatus.fetchMore
692
+ });
693
+ case 5:
694
+ case "end":
695
+ return _context12.stop();
802
696
  }
803
697
  }, _callee12, this);
804
698
  }));
805
-
806
699
  function fetchNextPage() {
807
700
  return _fetchNextPage.apply(this, arguments);
808
701
  }
809
-
810
702
  return fetchNextPage;
811
703
  }()
812
704
  }, {
813
705
  key: "broadcast",
814
706
  value: function broadcast(eventName, data) {
815
707
  this.broadcaster.emit(eventName, data);
816
- } // Invoked when a new real-time message comes in from the socket
708
+ }
817
709
 
710
+ // Invoked when a new real-time message comes in from the socket
818
711
  }, {
819
712
  key: "onNewMessageReceived",
820
713
  value: function () {
821
714
  var _onNewMessageReceived = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee13(_ref) {
822
715
  var metadata, _this$store6, getState, setState, _getState6, items, currentHead;
823
-
824
716
  return _regenerator["default"].wrap(function _callee13$(_context13) {
825
- while (1) {
826
- switch (_context13.prev = _context13.next) {
827
- case 0:
828
- metadata = _ref.metadata;
829
- // Handle the new message coming in
830
- _this$store6 = this.store, getState = _this$store6.getState, setState = _this$store6.setState;
831
- _getState6 = getState(), items = _getState6.items;
832
- currentHead = items[0]; // Optimistically set the badge counts
833
-
834
- setState(function (state) {
835
- return state.setMetadata(metadata);
836
- }); // Fetch the items before the current head (if it exists)
837
-
838
- this.fetch({
839
- before: currentHead === null || currentHead === void 0 ? void 0 : currentHead.__cursor,
840
- __fetchSource: "socket"
841
- });
842
-
843
- case 6:
844
- case "end":
845
- return _context13.stop();
846
- }
717
+ while (1) switch (_context13.prev = _context13.next) {
718
+ case 0:
719
+ metadata = _ref.metadata;
720
+ // Handle the new message coming in
721
+ _this$store6 = this.store, getState = _this$store6.getState, setState = _this$store6.setState;
722
+ _getState6 = getState(), items = _getState6.items;
723
+ currentHead = items[0]; // Optimistically set the badge counts
724
+ setState(function (state) {
725
+ return state.setMetadata(metadata);
726
+ });
727
+ // Fetch the items before the current head (if it exists)
728
+ this.fetch({
729
+ before: currentHead === null || currentHead === void 0 ? void 0 : currentHead.__cursor,
730
+ __fetchSource: "socket"
731
+ });
732
+ case 6:
733
+ case "end":
734
+ return _context13.stop();
847
735
  }
848
736
  }, _callee13, this);
849
737
  }));
850
-
851
738
  function onNewMessageReceived(_x8) {
852
739
  return _onNewMessageReceived.apply(this, arguments);
853
740
  }
854
-
855
741
  return onNewMessageReceived;
856
742
  }()
857
743
  }, {
@@ -863,47 +749,43 @@ var Feed = /*#__PURE__*/function () {
863
749
  key: "optimisticallyPerformStatusUpdate",
864
750
  value: function optimisticallyPerformStatusUpdate(itemOrItems, type, attrs, badgeCountAttr) {
865
751
  var _this$store7 = this.store,
866
- getState = _this$store7.getState,
867
- setState = _this$store7.setState;
752
+ getState = _this$store7.getState,
753
+ setState = _this$store7.setState;
868
754
  var normalizedItems = Array.isArray(itemOrItems) ? itemOrItems : [itemOrItems];
869
755
  var itemIds = normalizedItems.map(function (item) {
870
756
  return item.id;
871
757
  });
872
-
873
758
  if (badgeCountAttr) {
874
759
  var _getState7 = getState(),
875
- metadata = _getState7.metadata; // We only want to update the counts of items that have not already been counted towards the
876
- // badge count total to avoid updating the badge count unnecessarily.
877
-
760
+ metadata = _getState7.metadata;
878
761
 
762
+ // We only want to update the counts of items that have not already been counted towards the
763
+ // badge count total to avoid updating the badge count unnecessarily.
879
764
  var itemsToUpdate = normalizedItems.filter(function (item) {
880
765
  switch (type) {
881
766
  case "seen":
882
767
  return item.seen_at === null;
883
-
884
768
  case "unseen":
885
769
  return item.seen_at !== null;
886
-
887
770
  case "read":
888
771
  case "interacted":
889
772
  return item.read_at === null;
890
-
891
773
  case "unread":
892
774
  return item.read_at !== null;
893
-
894
775
  default:
895
776
  return true;
896
777
  }
897
- }); // Tnis is a hack to determine the direction of whether we're
898
- // adding or removing from the badge count
778
+ });
899
779
 
780
+ // Tnis is a hack to determine the direction of whether we're
781
+ // adding or removing from the badge count
900
782
  var direction = type.startsWith("un") ? itemsToUpdate.length : -itemsToUpdate.length;
901
783
  setState(function (store) {
902
784
  return store.setMetadata(_objectSpread(_objectSpread({}, metadata), {}, (0, _defineProperty2["default"])({}, badgeCountAttr, Math.max(0, metadata[badgeCountAttr] + direction))));
903
785
  });
904
- } // Update the items with the given attributes
905
-
786
+ }
906
787
 
788
+ // Update the items with the given attributes
907
789
  setState(function (store) {
908
790
  return store.setItemAttrs(itemIds, attrs);
909
791
  });
@@ -914,47 +796,41 @@ var Feed = /*#__PURE__*/function () {
914
796
  var _makeStatusUpdate = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee14(itemOrItems, type) {
915
797
  var items, itemIds, result;
916
798
  return _regenerator["default"].wrap(function _callee14$(_context14) {
917
- while (1) {
918
- switch (_context14.prev = _context14.next) {
919
- case 0:
920
- // Always treat items as a batch to use the corresponding batch endpoint
921
- items = Array.isArray(itemOrItems) ? itemOrItems : [itemOrItems];
922
- itemIds = items.map(function (item) {
923
- return item.id;
924
- });
925
- _context14.next = 4;
926
- return this.apiClient.makeRequest({
927
- method: "POST",
928
- url: "/v1/messages/batch/".concat(type),
929
- data: {
930
- message_ids: itemIds
931
- }
932
- });
933
-
934
- case 4:
935
- result = _context14.sent;
936
- // Emit the event that these items had their statuses changed
937
- // Note: we do this after the update to ensure that the server event actually completed
938
- this.broadcaster.emit("items:".concat(type), {
939
- items: items
940
- });
941
- this.broadcastOverChannel("items:".concat(type), {
942
- items: items
943
- });
944
- return _context14.abrupt("return", result);
945
-
946
- case 8:
947
- case "end":
948
- return _context14.stop();
949
- }
799
+ while (1) switch (_context14.prev = _context14.next) {
800
+ case 0:
801
+ // Always treat items as a batch to use the corresponding batch endpoint
802
+ items = Array.isArray(itemOrItems) ? itemOrItems : [itemOrItems];
803
+ itemIds = items.map(function (item) {
804
+ return item.id;
805
+ });
806
+ _context14.next = 4;
807
+ return this.apiClient.makeRequest({
808
+ method: "POST",
809
+ url: "/v1/messages/batch/".concat(type),
810
+ data: {
811
+ message_ids: itemIds
812
+ }
813
+ });
814
+ case 4:
815
+ result = _context14.sent;
816
+ // Emit the event that these items had their statuses changed
817
+ // Note: we do this after the update to ensure that the server event actually completed
818
+ this.broadcaster.emit("items:".concat(type), {
819
+ items: items
820
+ });
821
+ this.broadcastOverChannel("items:".concat(type), {
822
+ items: items
823
+ });
824
+ return _context14.abrupt("return", result);
825
+ case 8:
826
+ case "end":
827
+ return _context14.stop();
950
828
  }
951
829
  }, _callee14, this);
952
830
  }));
953
-
954
831
  function makeStatusUpdate(_x9, _x10) {
955
832
  return _makeStatusUpdate.apply(this, arguments);
956
833
  }
957
-
958
834
  return makeStatusUpdate;
959
835
  }()
960
836
  }, {
@@ -963,42 +839,36 @@ var Feed = /*#__PURE__*/function () {
963
839
  var _makeBulkStatusUpdate = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee15(type) {
964
840
  var options;
965
841
  return _regenerator["default"].wrap(function _callee15$(_context15) {
966
- while (1) {
967
- switch (_context15.prev = _context15.next) {
968
- case 0:
969
- // The base scope for the call should take into account all of the options currently
970
- // set on the feed, as well as being scoped for the current user. We do this so that
971
- // we ONLY make changes to the messages that are currently in view on this feed, and not
972
- // all messages that exist.
973
- options = {
974
- user_ids: [this.knock.userId],
975
- engagement_status: this.defaultOptions.status !== "all" ? this.defaultOptions.status : undefined,
976
- archived: this.defaultOptions.archived,
977
- has_tenant: this.defaultOptions.has_tenant,
978
- tenants: this.defaultOptions.tenant ? [this.defaultOptions.tenant] : undefined
979
- };
980
- _context15.next = 3;
981
- return this.apiClient.makeRequest({
982
- method: "POST",
983
- url: "/v1/channels/".concat(this.feedId, "/messages/bulk/").concat(type),
984
- data: options
985
- });
986
-
987
- case 3:
988
- return _context15.abrupt("return", _context15.sent);
989
-
990
- case 4:
991
- case "end":
992
- return _context15.stop();
993
- }
842
+ while (1) switch (_context15.prev = _context15.next) {
843
+ case 0:
844
+ // The base scope for the call should take into account all of the options currently
845
+ // set on the feed, as well as being scoped for the current user. We do this so that
846
+ // we ONLY make changes to the messages that are currently in view on this feed, and not
847
+ // all messages that exist.
848
+ options = {
849
+ user_ids: [this.knock.userId],
850
+ engagement_status: this.defaultOptions.status !== "all" ? this.defaultOptions.status : undefined,
851
+ archived: this.defaultOptions.archived,
852
+ has_tenant: this.defaultOptions.has_tenant,
853
+ tenants: this.defaultOptions.tenant ? [this.defaultOptions.tenant] : undefined
854
+ };
855
+ _context15.next = 3;
856
+ return this.apiClient.makeRequest({
857
+ method: "POST",
858
+ url: "/v1/channels/".concat(this.feedId, "/messages/bulk/").concat(type),
859
+ data: options
860
+ });
861
+ case 3:
862
+ return _context15.abrupt("return", _context15.sent);
863
+ case 4:
864
+ case "end":
865
+ return _context15.stop();
994
866
  }
995
867
  }, _callee15, this);
996
868
  }));
997
-
998
869
  function makeBulkStatusUpdate(_x11) {
999
870
  return _makeBulkStatusUpdate.apply(this, arguments);
1000
871
  }
1001
-
1002
872
  return makeBulkStatusUpdate;
1003
873
  }()
1004
874
  }, {
@@ -1007,10 +877,10 @@ var Feed = /*#__PURE__*/function () {
1007
877
  // The broadcastChannel may not be available in non-browser environments
1008
878
  if (!this.broadcastChannel) {
1009
879
  return;
1010
- } // Here we stringify our payload and try and send as JSON such that we
1011
- // don't get any `An object could not be cloned` errors when trying to broadcast
1012
-
880
+ }
1013
881
 
882
+ // Here we stringify our payload and try and send as JSON such that we
883
+ // don't get any `An object could not be cloned` errors when trying to broadcast
1014
884
  try {
1015
885
  var stringifiedPayload = JSON.parse(JSON.stringify(payload));
1016
886
  this.broadcastChannel.postMessage({
@@ -1024,7 +894,5 @@ var Feed = /*#__PURE__*/function () {
1024
894
  }]);
1025
895
  return Feed;
1026
896
  }();
1027
-
1028
- var _default = Feed;
1029
- exports["default"] = _default;
897
+ var _default = exports["default"] = Feed;
1030
898
  //# sourceMappingURL=feed.js.map