@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.
- package/README.md +22 -13
- package/dist/cjs/api.js +33 -56
- package/dist/cjs/api.js.map +1 -1
- package/dist/cjs/clients/feed/feed.js +492 -624
- package/dist/cjs/clients/feed/feed.js.map +1 -1
- package/dist/cjs/clients/feed/index.js +1 -10
- package/dist/cjs/clients/feed/index.js.map +1 -1
- package/dist/cjs/clients/feed/interfaces.js.map +1 -1
- package/dist/cjs/clients/feed/store.js +4 -15
- package/dist/cjs/clients/feed/store.js.map +1 -1
- package/dist/cjs/clients/feed/types.js.map +1 -1
- package/dist/cjs/clients/feed/utils.js +0 -5
- package/dist/cjs/clients/feed/utils.js.map +1 -1
- package/dist/cjs/clients/preferences/index.js +216 -249
- package/dist/cjs/clients/preferences/index.js.map +1 -1
- package/dist/cjs/clients/preferences/interfaces.js.map +1 -1
- package/dist/cjs/clients/users/index.js +185 -0
- package/dist/cjs/clients/users/index.js.map +1 -0
- package/dist/cjs/clients/users/interfaces.js +6 -0
- package/dist/cjs/clients/users/interfaces.js.map +1 -0
- package/dist/cjs/index.js +15 -21
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/interfaces.js.map +1 -1
- package/dist/cjs/knock.js +11 -21
- package/dist/cjs/knock.js.map +1 -1
- package/dist/cjs/networkStatus.js +3 -6
- package/dist/cjs/networkStatus.js.map +1 -1
- package/dist/esm/api.js +9 -21
- package/dist/esm/api.js.map +1 -1
- package/dist/esm/clients/feed/feed.js +69 -149
- package/dist/esm/clients/feed/feed.js.map +1 -1
- package/dist/esm/clients/feed/index.js +0 -5
- package/dist/esm/clients/feed/index.js.map +1 -1
- package/dist/esm/clients/feed/interfaces.js.map +1 -1
- package/dist/esm/clients/feed/store.js +2 -8
- package/dist/esm/clients/feed/store.js.map +1 -1
- package/dist/esm/clients/feed/types.js.map +1 -1
- package/dist/esm/clients/feed/utils.js +0 -1
- package/dist/esm/clients/feed/utils.js.map +1 -1
- package/dist/esm/clients/preferences/index.js +35 -25
- package/dist/esm/clients/preferences/index.js.map +1 -1
- package/dist/esm/clients/preferences/interfaces.js.map +1 -1
- package/dist/esm/clients/users/index.js +84 -0
- package/dist/esm/clients/users/index.js.map +1 -0
- package/dist/esm/clients/users/interfaces.js +2 -0
- package/dist/esm/clients/users/interfaces.js.map +1 -0
- package/dist/esm/index.js +1 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/interfaces.js.map +1 -1
- package/dist/esm/knock.js +10 -22
- package/dist/esm/knock.js.map +1 -1
- package/dist/esm/networkStatus.js +3 -5
- package/dist/esm/networkStatus.js.map +1 -1
- package/dist/types/api.d.ts +1 -1
- package/dist/types/api.d.ts.map +1 -1
- package/dist/types/clients/feed/feed.d.ts +1 -1
- 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/types.d.ts +10 -10
- package/dist/types/clients/feed/types.d.ts.map +1 -1
- package/dist/types/clients/preferences/index.d.ts +27 -0
- package/dist/types/clients/preferences/index.d.ts.map +1 -1
- package/dist/types/clients/preferences/interfaces.d.ts +7 -4
- package/dist/types/clients/preferences/interfaces.d.ts.map +1 -1
- package/dist/types/clients/users/index.d.ts +16 -0
- package/dist/types/clients/users/index.d.ts.map +1 -0
- package/dist/types/clients/users/interfaces.d.ts +8 -0
- package/dist/types/clients/users/interfaces.d.ts.map +1 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/interfaces.d.ts +6 -2
- package/dist/types/interfaces.d.ts.map +1 -1
- package/dist/types/knock.d.ts +2 -0
- package/dist/types/knock.d.ts.map +1 -1
- package/package.json +15 -10
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
|
|
2
2
|
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
3
|
-
|
|
4
|
-
function
|
|
5
|
-
|
|
6
|
-
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) { _defineProperty(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; }
|
|
7
|
-
|
|
3
|
+
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; }
|
|
4
|
+
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) { _defineProperty(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; }
|
|
8
5
|
import { EventEmitter2 as EventEmitter } from "eventemitter2";
|
|
9
6
|
import createStore from "./store";
|
|
10
7
|
import { isRequestInFlight, NetworkStatus } from "../../networkStatus";
|
|
@@ -12,27 +9,18 @@ import { isRequestInFlight, NetworkStatus } from "../../networkStatus";
|
|
|
12
9
|
var feedClientDefaults = {
|
|
13
10
|
archived: "exclude"
|
|
14
11
|
};
|
|
15
|
-
|
|
16
12
|
class Feed {
|
|
17
|
-
// The raw store instance, used for binding in React and other environments
|
|
18
13
|
constructor(knock, feedId, options) {
|
|
19
14
|
this.knock = knock;
|
|
20
15
|
this.feedId = feedId;
|
|
21
|
-
|
|
22
16
|
_defineProperty(this, "apiClient", void 0);
|
|
23
|
-
|
|
24
17
|
_defineProperty(this, "userFeedId", void 0);
|
|
25
|
-
|
|
26
18
|
_defineProperty(this, "channel", void 0);
|
|
27
|
-
|
|
28
19
|
_defineProperty(this, "broadcaster", void 0);
|
|
29
|
-
|
|
30
20
|
_defineProperty(this, "defaultOptions", void 0);
|
|
31
|
-
|
|
32
21
|
_defineProperty(this, "broadcastChannel", void 0);
|
|
33
|
-
|
|
22
|
+
// The raw store instance, used for binding in React and other environments
|
|
34
23
|
_defineProperty(this, "store", void 0);
|
|
35
|
-
|
|
36
24
|
this.apiClient = knock.client();
|
|
37
25
|
this.feedId = feedId;
|
|
38
26
|
this.userFeedId = this.buildUserFeedId();
|
|
@@ -41,55 +29,52 @@ class Feed {
|
|
|
41
29
|
wildcard: true,
|
|
42
30
|
delimiter: "."
|
|
43
31
|
});
|
|
44
|
-
this.defaultOptions = _objectSpread(_objectSpread({}, feedClientDefaults), options);
|
|
32
|
+
this.defaultOptions = _objectSpread(_objectSpread({}, feedClientDefaults), options);
|
|
45
33
|
|
|
34
|
+
// In server environments we might not have a socket connection
|
|
46
35
|
if (this.apiClient.socket) {
|
|
47
36
|
this.channel = this.apiClient.socket.channel("feeds:".concat(this.userFeedId), this.defaultOptions);
|
|
48
37
|
this.channel.on("new-message", resp => this.onNewMessageReceived(resp));
|
|
49
|
-
}
|
|
50
|
-
// Note: here we ensure `self` is available (it's not in server rendered envs)
|
|
51
|
-
|
|
38
|
+
}
|
|
52
39
|
|
|
40
|
+
// Attempt to bind to listen to other events from this feed in different tabs
|
|
41
|
+
// Note: here we ensure `self` is available (it's not in server rendered envs)
|
|
53
42
|
this.broadcastChannel = typeof self !== "undefined" && "BroadcastChannel" in self ? new BroadcastChannel("knock:feed:".concat(this.userFeedId)) : null;
|
|
54
43
|
}
|
|
44
|
+
|
|
55
45
|
/**
|
|
56
46
|
* Cleans up a feed instance by destroying the store and disconnecting
|
|
57
47
|
* an open socket connection.
|
|
58
48
|
*/
|
|
59
|
-
|
|
60
|
-
|
|
61
49
|
teardown() {
|
|
62
50
|
if (this.channel) {
|
|
63
51
|
this.channel.leave();
|
|
64
52
|
this.channel.off("new-message");
|
|
65
53
|
}
|
|
66
|
-
|
|
67
54
|
this.broadcaster.removeAllListeners();
|
|
68
55
|
this.store.destroy();
|
|
69
|
-
|
|
70
56
|
if (this.broadcastChannel) {
|
|
71
57
|
this.broadcastChannel.close();
|
|
72
58
|
}
|
|
73
59
|
}
|
|
60
|
+
|
|
74
61
|
/*
|
|
75
62
|
Initializes a real-time connection to Knock, connecting the websocket for the
|
|
76
63
|
current ApiClient instance if the socket is not already connected.
|
|
77
64
|
*/
|
|
78
|
-
|
|
79
|
-
|
|
80
65
|
listenForUpdates() {
|
|
81
66
|
// Connect the socket only if we don't already have a connection
|
|
82
67
|
if (this.apiClient.socket && !this.apiClient.socket.isConnected()) {
|
|
83
68
|
this.apiClient.socket.connect();
|
|
84
|
-
}
|
|
85
|
-
|
|
69
|
+
}
|
|
86
70
|
|
|
71
|
+
// Only join the channel if we're not already in a joining state
|
|
87
72
|
if (this.channel && ["closed", "errored"].includes(this.channel.state)) {
|
|
88
73
|
this.channel.join();
|
|
89
|
-
}
|
|
90
|
-
// channel (iff it's enabled and exists)
|
|
91
|
-
|
|
74
|
+
}
|
|
92
75
|
|
|
76
|
+
// Opt into receiving updates from _other tabs for the same user / feed_ via the broadcast
|
|
77
|
+
// channel (iff it's enabled and exists)
|
|
93
78
|
if (this.broadcastChannel && this.defaultOptions.__experimentalCrossBrowserUpdates === true) {
|
|
94
79
|
this.broadcastChannel.onmessage = e => {
|
|
95
80
|
switch (e.data.type) {
|
|
@@ -107,45 +92,35 @@ class Feed {
|
|
|
107
92
|
// maybe do this optimistically without the fetch.
|
|
108
93
|
return this.fetch();
|
|
109
94
|
break;
|
|
110
|
-
|
|
111
95
|
default:
|
|
112
96
|
return null;
|
|
113
97
|
}
|
|
114
98
|
};
|
|
115
99
|
}
|
|
116
100
|
}
|
|
117
|
-
/* Binds a handler to be invoked when event occurs */
|
|
118
|
-
|
|
119
101
|
|
|
102
|
+
/* Binds a handler to be invoked when event occurs */
|
|
120
103
|
on(eventName, callback) {
|
|
121
104
|
this.broadcaster.on(eventName, callback);
|
|
122
105
|
}
|
|
123
|
-
|
|
124
106
|
off(eventName, callback) {
|
|
125
107
|
this.broadcaster.off(eventName, callback);
|
|
126
108
|
}
|
|
127
|
-
|
|
128
109
|
getState() {
|
|
129
110
|
return this.store.getState();
|
|
130
111
|
}
|
|
131
|
-
|
|
132
112
|
markAsSeen(itemOrItems) {
|
|
133
113
|
var _this = this;
|
|
134
|
-
|
|
135
114
|
return _asyncToGenerator(function* () {
|
|
136
115
|
var now = new Date().toISOString();
|
|
137
|
-
|
|
138
116
|
_this.optimisticallyPerformStatusUpdate(itemOrItems, "seen", {
|
|
139
117
|
seen_at: now
|
|
140
118
|
}, "unseen_count");
|
|
141
|
-
|
|
142
119
|
return _this.makeStatusUpdate(itemOrItems, "seen");
|
|
143
120
|
})();
|
|
144
121
|
}
|
|
145
|
-
|
|
146
122
|
markAllAsSeen() {
|
|
147
123
|
var _this2 = this;
|
|
148
|
-
|
|
149
124
|
return _asyncToGenerator(function* () {
|
|
150
125
|
// To mark all of the messages as seen we:
|
|
151
126
|
// 1. Optimistically update *everything* we have in the store
|
|
@@ -166,10 +141,11 @@ class Feed {
|
|
|
166
141
|
metadata,
|
|
167
142
|
items
|
|
168
143
|
} = getState();
|
|
169
|
-
var isViewingOnlyUnseen = _this2.defaultOptions.status === "unseen";
|
|
144
|
+
var isViewingOnlyUnseen = _this2.defaultOptions.status === "unseen";
|
|
145
|
+
|
|
146
|
+
// If we're looking at the unseen view, then we want to remove all of the items optimistically
|
|
170
147
|
// from the store given that nothing should be visible. We do this by resetting the store state
|
|
171
148
|
// and setting the current metadata counts to 0
|
|
172
|
-
|
|
173
149
|
if (isViewingOnlyUnseen) {
|
|
174
150
|
setState(store => store.resetStore(_objectSpread(_objectSpread({}, metadata), {}, {
|
|
175
151
|
total_count: 0,
|
|
@@ -185,52 +161,40 @@ class Feed {
|
|
|
185
161
|
};
|
|
186
162
|
var itemIds = items.map(item => item.id);
|
|
187
163
|
setState(store => store.setItemAttrs(itemIds, attrs));
|
|
188
|
-
}
|
|
189
|
-
|
|
164
|
+
}
|
|
190
165
|
|
|
166
|
+
// Issue the API request to the bulk status change API
|
|
191
167
|
var result = yield _this2.makeBulkStatusUpdate("seen");
|
|
192
|
-
|
|
193
168
|
_this2.broadcaster.emit("items:all_seen", {
|
|
194
169
|
items
|
|
195
170
|
});
|
|
196
|
-
|
|
197
171
|
_this2.broadcastOverChannel("items:all_seen", {
|
|
198
172
|
items
|
|
199
173
|
});
|
|
200
|
-
|
|
201
174
|
return result;
|
|
202
175
|
})();
|
|
203
176
|
}
|
|
204
|
-
|
|
205
177
|
markAsUnseen(itemOrItems) {
|
|
206
178
|
var _this3 = this;
|
|
207
|
-
|
|
208
179
|
return _asyncToGenerator(function* () {
|
|
209
180
|
_this3.optimisticallyPerformStatusUpdate(itemOrItems, "unseen", {
|
|
210
181
|
seen_at: null
|
|
211
182
|
}, "unseen_count");
|
|
212
|
-
|
|
213
183
|
return _this3.makeStatusUpdate(itemOrItems, "unseen");
|
|
214
184
|
})();
|
|
215
185
|
}
|
|
216
|
-
|
|
217
186
|
markAsRead(itemOrItems) {
|
|
218
187
|
var _this4 = this;
|
|
219
|
-
|
|
220
188
|
return _asyncToGenerator(function* () {
|
|
221
189
|
var now = new Date().toISOString();
|
|
222
|
-
|
|
223
190
|
_this4.optimisticallyPerformStatusUpdate(itemOrItems, "read", {
|
|
224
191
|
read_at: now
|
|
225
192
|
}, "unread_count");
|
|
226
|
-
|
|
227
193
|
return _this4.makeStatusUpdate(itemOrItems, "read");
|
|
228
194
|
})();
|
|
229
195
|
}
|
|
230
|
-
|
|
231
196
|
markAllAsRead() {
|
|
232
197
|
var _this5 = this;
|
|
233
|
-
|
|
234
198
|
return _asyncToGenerator(function* () {
|
|
235
199
|
// To mark all of the messages as read we:
|
|
236
200
|
// 1. Optimistically update *everything* we have in the store
|
|
@@ -251,10 +215,11 @@ class Feed {
|
|
|
251
215
|
metadata,
|
|
252
216
|
items
|
|
253
217
|
} = getState();
|
|
254
|
-
var isViewingOnlyUnread = _this5.defaultOptions.status === "unread";
|
|
218
|
+
var isViewingOnlyUnread = _this5.defaultOptions.status === "unread";
|
|
219
|
+
|
|
220
|
+
// If we're looking at the unread view, then we want to remove all of the items optimistically
|
|
255
221
|
// from the store given that nothing should be visible. We do this by resetting the store state
|
|
256
222
|
// and setting the current metadata counts to 0
|
|
257
|
-
|
|
258
223
|
if (isViewingOnlyUnread) {
|
|
259
224
|
setState(store => store.resetStore(_objectSpread(_objectSpread({}, metadata), {}, {
|
|
260
225
|
total_count: 0,
|
|
@@ -270,60 +235,48 @@ class Feed {
|
|
|
270
235
|
};
|
|
271
236
|
var itemIds = items.map(item => item.id);
|
|
272
237
|
setState(store => store.setItemAttrs(itemIds, attrs));
|
|
273
|
-
}
|
|
274
|
-
|
|
238
|
+
}
|
|
275
239
|
|
|
240
|
+
// Issue the API request to the bulk status change API
|
|
276
241
|
var result = yield _this5.makeBulkStatusUpdate("read");
|
|
277
|
-
|
|
278
242
|
_this5.broadcaster.emit("items:all_read", {
|
|
279
243
|
items
|
|
280
244
|
});
|
|
281
|
-
|
|
282
245
|
_this5.broadcastOverChannel("items:all_read", {
|
|
283
246
|
items
|
|
284
247
|
});
|
|
285
|
-
|
|
286
248
|
return result;
|
|
287
249
|
})();
|
|
288
250
|
}
|
|
289
|
-
|
|
290
251
|
markAsUnread(itemOrItems) {
|
|
291
252
|
var _this6 = this;
|
|
292
|
-
|
|
293
253
|
return _asyncToGenerator(function* () {
|
|
294
254
|
_this6.optimisticallyPerformStatusUpdate(itemOrItems, "unread", {
|
|
295
255
|
read_at: null
|
|
296
256
|
}, "unread_count");
|
|
297
|
-
|
|
298
257
|
return _this6.makeStatusUpdate(itemOrItems, "unread");
|
|
299
258
|
})();
|
|
300
259
|
}
|
|
301
|
-
|
|
302
260
|
markAsInteracted(itemOrItems) {
|
|
303
261
|
var _this7 = this;
|
|
304
|
-
|
|
305
262
|
return _asyncToGenerator(function* () {
|
|
306
263
|
var now = new Date().toISOString();
|
|
307
|
-
|
|
308
264
|
_this7.optimisticallyPerformStatusUpdate(itemOrItems, "interacted", {
|
|
309
265
|
read_at: now,
|
|
310
266
|
interacted_at: now
|
|
311
267
|
}, "unread_count");
|
|
312
|
-
|
|
313
268
|
return _this7.makeStatusUpdate(itemOrItems, "interacted");
|
|
314
269
|
})();
|
|
315
270
|
}
|
|
271
|
+
|
|
316
272
|
/*
|
|
317
273
|
Marking one or more items as archived should:
|
|
318
274
|
- Decrement the badge count for any unread / unseen items
|
|
319
275
|
- Remove the item from the feed list when the `archived` flag is "exclude" (default)
|
|
320
276
|
TODO: how do we handle rollbacks?
|
|
321
277
|
*/
|
|
322
|
-
|
|
323
|
-
|
|
324
278
|
markAsArchived(itemOrItems) {
|
|
325
279
|
var _this8 = this;
|
|
326
|
-
|
|
327
280
|
return _asyncToGenerator(function* () {
|
|
328
281
|
var {
|
|
329
282
|
getState,
|
|
@@ -333,6 +286,7 @@ class Feed {
|
|
|
333
286
|
var shouldOptimisticallyRemoveItems = _this8.defaultOptions.archived === "exclude";
|
|
334
287
|
var normalizedItems = Array.isArray(itemOrItems) ? itemOrItems : [itemOrItems];
|
|
335
288
|
var itemIds = normalizedItems.map(item => item.id);
|
|
289
|
+
|
|
336
290
|
/*
|
|
337
291
|
In the code here we want to optimistically update counts and items
|
|
338
292
|
that are persisted such that we can display updates immediately on the feed
|
|
@@ -356,15 +310,16 @@ class Feed {
|
|
|
356
310
|
// If any of the items are unseen or unread, then capture as we'll want to decrement
|
|
357
311
|
// the counts for these in the metadata we have
|
|
358
312
|
var unseenCount = normalizedItems.filter(i => !i.seen_at).length;
|
|
359
|
-
var unreadCount = normalizedItems.filter(i => !i.read_at).length;
|
|
313
|
+
var unreadCount = normalizedItems.filter(i => !i.read_at).length;
|
|
360
314
|
|
|
315
|
+
// Build the new metadata
|
|
361
316
|
var updatedMetadata = _objectSpread(_objectSpread({}, state.metadata), {}, {
|
|
362
317
|
total_count: state.metadata.total_count - normalizedItems.length,
|
|
363
318
|
unseen_count: state.metadata.unseen_count - unseenCount,
|
|
364
319
|
unread_count: state.metadata.unread_count - unreadCount
|
|
365
|
-
});
|
|
366
|
-
|
|
320
|
+
});
|
|
367
321
|
|
|
322
|
+
// Remove the archiving entries
|
|
368
323
|
var entriesToSet = state.items.filter(item => !itemIds.includes(item.id));
|
|
369
324
|
setState(state => state.setResult({
|
|
370
325
|
entries: entriesToSet,
|
|
@@ -377,14 +332,11 @@ class Feed {
|
|
|
377
332
|
archived_at: new Date().toISOString()
|
|
378
333
|
});
|
|
379
334
|
}
|
|
380
|
-
|
|
381
335
|
return _this8.makeStatusUpdate(itemOrItems, "archived");
|
|
382
336
|
})();
|
|
383
337
|
}
|
|
384
|
-
|
|
385
338
|
markAllAsArchived() {
|
|
386
339
|
var _this9 = this;
|
|
387
|
-
|
|
388
340
|
return _asyncToGenerator(function* () {
|
|
389
341
|
// Note: there is the potential for a race condition here because the bulk
|
|
390
342
|
// update is an async method, so if a new message comes in during this window before
|
|
@@ -395,11 +347,11 @@ class Feed {
|
|
|
395
347
|
} = _this9.store;
|
|
396
348
|
var {
|
|
397
349
|
items
|
|
398
|
-
} = getState();
|
|
399
|
-
// will want to optimistically remove all of the items from the feed as they are now all excluded
|
|
350
|
+
} = getState();
|
|
400
351
|
|
|
352
|
+
// Here if we're looking at a feed that excludes all of the archived items by default then we
|
|
353
|
+
// will want to optimistically remove all of the items from the feed as they are now all excluded
|
|
401
354
|
var shouldOptimisticallyRemoveItems = _this9.defaultOptions.archived === "exclude";
|
|
402
|
-
|
|
403
355
|
if (shouldOptimisticallyRemoveItems) {
|
|
404
356
|
// Reset the store to clear out all of items and reset the badge count
|
|
405
357
|
setState(store => store.resetStore());
|
|
@@ -411,41 +363,33 @@ class Feed {
|
|
|
411
363
|
archived_at: new Date().toISOString()
|
|
412
364
|
});
|
|
413
365
|
});
|
|
414
|
-
}
|
|
415
|
-
|
|
366
|
+
}
|
|
416
367
|
|
|
368
|
+
// Issue the API request to the bulk status change API
|
|
417
369
|
var result = yield _this9.makeBulkStatusUpdate("archive");
|
|
418
|
-
|
|
419
370
|
_this9.broadcaster.emit("items:all_archived", {
|
|
420
371
|
items
|
|
421
372
|
});
|
|
422
|
-
|
|
423
373
|
_this9.broadcastOverChannel("items:all_archived", {
|
|
424
374
|
items
|
|
425
375
|
});
|
|
426
|
-
|
|
427
376
|
return result;
|
|
428
377
|
})();
|
|
429
378
|
}
|
|
430
|
-
|
|
431
379
|
markAsUnarchived(itemOrItems) {
|
|
432
380
|
var _this10 = this;
|
|
433
|
-
|
|
434
381
|
return _asyncToGenerator(function* () {
|
|
435
382
|
_this10.optimisticallyPerformStatusUpdate(itemOrItems, "unarchived", {
|
|
436
383
|
archived_at: null
|
|
437
384
|
});
|
|
438
|
-
|
|
439
385
|
return _this10.makeStatusUpdate(itemOrItems, "unarchived");
|
|
440
386
|
})();
|
|
441
387
|
}
|
|
442
|
-
/* Fetches the feed content, appending it to the store */
|
|
443
|
-
|
|
444
388
|
|
|
389
|
+
/* Fetches the feed content, appending it to the store */
|
|
445
390
|
fetch() {
|
|
446
391
|
var _arguments = arguments,
|
|
447
|
-
|
|
448
|
-
|
|
392
|
+
_this11 = this;
|
|
449
393
|
return _asyncToGenerator(function* () {
|
|
450
394
|
var options = _arguments.length > 0 && _arguments[0] !== undefined ? _arguments[0] : {};
|
|
451
395
|
var {
|
|
@@ -454,32 +398,31 @@ class Feed {
|
|
|
454
398
|
} = _this11.store;
|
|
455
399
|
var {
|
|
456
400
|
networkStatus
|
|
457
|
-
} = getState();
|
|
401
|
+
} = getState();
|
|
458
402
|
|
|
403
|
+
// If there's an existing request in flight, then do nothing
|
|
459
404
|
if (isRequestInFlight(networkStatus)) {
|
|
460
405
|
return;
|
|
461
|
-
}
|
|
462
|
-
|
|
406
|
+
}
|
|
463
407
|
|
|
408
|
+
// Set the loading type based on the request type it is
|
|
464
409
|
setState(store => {
|
|
465
410
|
var _options$__loadingTyp;
|
|
466
|
-
|
|
467
411
|
return store.setNetworkStatus((_options$__loadingTyp = options.__loadingType) !== null && _options$__loadingTyp !== void 0 ? _options$__loadingTyp : NetworkStatus.loading);
|
|
468
|
-
});
|
|
412
|
+
});
|
|
469
413
|
|
|
414
|
+
// Always include the default params, if they have been set
|
|
470
415
|
var queryParams = _objectSpread(_objectSpread(_objectSpread({}, _this11.defaultOptions), options), {}, {
|
|
471
416
|
// Unset options that should not be sent to the API
|
|
472
417
|
__loadingType: undefined,
|
|
473
418
|
__fetchSource: undefined,
|
|
474
419
|
__experimentalCrossBrowserUpdates: undefined
|
|
475
420
|
});
|
|
476
|
-
|
|
477
421
|
var result = yield _this11.apiClient.makeRequest({
|
|
478
422
|
method: "GET",
|
|
479
423
|
url: "/v1/users/".concat(_this11.knock.userId, "/feeds/").concat(_this11.feedId),
|
|
480
424
|
params: queryParams
|
|
481
425
|
});
|
|
482
|
-
|
|
483
426
|
if (result.statusCode === "error" || !result.body) {
|
|
484
427
|
setState(store => store.setNetworkStatus(NetworkStatus.error));
|
|
485
428
|
return {
|
|
@@ -487,13 +430,11 @@ class Feed {
|
|
|
487
430
|
data: result.error || result.body
|
|
488
431
|
};
|
|
489
432
|
}
|
|
490
|
-
|
|
491
433
|
var response = {
|
|
492
434
|
entries: result.body.entries,
|
|
493
435
|
meta: result.body.meta,
|
|
494
436
|
page_info: result.body.page_info
|
|
495
437
|
};
|
|
496
|
-
|
|
497
438
|
if (options.before) {
|
|
498
439
|
var opts = {
|
|
499
440
|
shouldSetPage: false,
|
|
@@ -508,31 +449,27 @@ class Feed {
|
|
|
508
449
|
setState(state => state.setResult(response, _opts));
|
|
509
450
|
} else {
|
|
510
451
|
setState(state => state.setResult(response));
|
|
511
|
-
}
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
_this11.broadcast("messages.new", response); // Broadcast the appropriate event type depending on the fetch source
|
|
452
|
+
}
|
|
515
453
|
|
|
454
|
+
// Legacy `messages.new` event, should be removed in a future version
|
|
455
|
+
_this11.broadcast("messages.new", response);
|
|
516
456
|
|
|
457
|
+
// Broadcast the appropriate event type depending on the fetch source
|
|
517
458
|
var feedEventType = options.__fetchSource === "socket" ? "items.received.realtime" : "items.received.page";
|
|
518
459
|
var eventPayload = {
|
|
519
460
|
items: response.entries,
|
|
520
461
|
metadata: response.meta,
|
|
521
462
|
event: feedEventType
|
|
522
463
|
};
|
|
523
|
-
|
|
524
464
|
_this11.broadcast(eventPayload.event, eventPayload);
|
|
525
|
-
|
|
526
465
|
return {
|
|
527
466
|
data: response,
|
|
528
467
|
status: result.statusCode
|
|
529
468
|
};
|
|
530
469
|
})();
|
|
531
470
|
}
|
|
532
|
-
|
|
533
471
|
fetchNextPage() {
|
|
534
472
|
var _this12 = this;
|
|
535
|
-
|
|
536
473
|
return _asyncToGenerator(function* () {
|
|
537
474
|
// Attempts to fetch the next page of results (if we have any)
|
|
538
475
|
var {
|
|
@@ -541,27 +478,23 @@ class Feed {
|
|
|
541
478
|
var {
|
|
542
479
|
pageInfo
|
|
543
480
|
} = getState();
|
|
544
|
-
|
|
545
481
|
if (!pageInfo.after) {
|
|
546
482
|
// Nothing more to fetch
|
|
547
483
|
return;
|
|
548
484
|
}
|
|
549
|
-
|
|
550
485
|
_this12.fetch({
|
|
551
486
|
after: pageInfo.after,
|
|
552
487
|
__loadingType: NetworkStatus.fetchMore
|
|
553
488
|
});
|
|
554
489
|
})();
|
|
555
490
|
}
|
|
556
|
-
|
|
557
491
|
broadcast(eventName, data) {
|
|
558
492
|
this.broadcaster.emit(eventName, data);
|
|
559
|
-
}
|
|
560
|
-
|
|
493
|
+
}
|
|
561
494
|
|
|
495
|
+
// Invoked when a new real-time message comes in from the socket
|
|
562
496
|
onNewMessageReceived(_ref) {
|
|
563
497
|
var _this13 = this;
|
|
564
|
-
|
|
565
498
|
return _asyncToGenerator(function* () {
|
|
566
499
|
var {
|
|
567
500
|
metadata
|
|
@@ -574,21 +507,19 @@ class Feed {
|
|
|
574
507
|
var {
|
|
575
508
|
items
|
|
576
509
|
} = getState();
|
|
577
|
-
var currentHead = items[0];
|
|
578
|
-
|
|
579
|
-
setState(state => state.setMetadata(metadata));
|
|
580
|
-
|
|
510
|
+
var currentHead = items[0];
|
|
511
|
+
// Optimistically set the badge counts
|
|
512
|
+
setState(state => state.setMetadata(metadata));
|
|
513
|
+
// Fetch the items before the current head (if it exists)
|
|
581
514
|
_this13.fetch({
|
|
582
515
|
before: currentHead === null || currentHead === void 0 ? void 0 : currentHead.__cursor,
|
|
583
516
|
__fetchSource: "socket"
|
|
584
517
|
});
|
|
585
518
|
})();
|
|
586
519
|
}
|
|
587
|
-
|
|
588
520
|
buildUserFeedId() {
|
|
589
521
|
return "".concat(this.feedId, ":").concat(this.knock.userId);
|
|
590
522
|
}
|
|
591
|
-
|
|
592
523
|
optimisticallyPerformStatusUpdate(itemOrItems, type, attrs, badgeCountAttr) {
|
|
593
524
|
var {
|
|
594
525
|
getState,
|
|
@@ -596,47 +527,42 @@ class Feed {
|
|
|
596
527
|
} = this.store;
|
|
597
528
|
var normalizedItems = Array.isArray(itemOrItems) ? itemOrItems : [itemOrItems];
|
|
598
529
|
var itemIds = normalizedItems.map(item => item.id);
|
|
599
|
-
|
|
600
530
|
if (badgeCountAttr) {
|
|
601
531
|
var {
|
|
602
532
|
metadata
|
|
603
|
-
} = getState();
|
|
604
|
-
// badge count total to avoid updating the badge count unnecessarily.
|
|
533
|
+
} = getState();
|
|
605
534
|
|
|
535
|
+
// We only want to update the counts of items that have not already been counted towards the
|
|
536
|
+
// badge count total to avoid updating the badge count unnecessarily.
|
|
606
537
|
var itemsToUpdate = normalizedItems.filter(item => {
|
|
607
538
|
switch (type) {
|
|
608
539
|
case "seen":
|
|
609
540
|
return item.seen_at === null;
|
|
610
|
-
|
|
611
541
|
case "unseen":
|
|
612
542
|
return item.seen_at !== null;
|
|
613
|
-
|
|
614
543
|
case "read":
|
|
615
544
|
case "interacted":
|
|
616
545
|
return item.read_at === null;
|
|
617
|
-
|
|
618
546
|
case "unread":
|
|
619
547
|
return item.read_at !== null;
|
|
620
|
-
|
|
621
548
|
default:
|
|
622
549
|
return true;
|
|
623
550
|
}
|
|
624
|
-
});
|
|
625
|
-
// adding or removing from the badge count
|
|
551
|
+
});
|
|
626
552
|
|
|
553
|
+
// Tnis is a hack to determine the direction of whether we're
|
|
554
|
+
// adding or removing from the badge count
|
|
627
555
|
var direction = type.startsWith("un") ? itemsToUpdate.length : -itemsToUpdate.length;
|
|
628
556
|
setState(store => store.setMetadata(_objectSpread(_objectSpread({}, metadata), {}, {
|
|
629
557
|
[badgeCountAttr]: Math.max(0, metadata[badgeCountAttr] + direction)
|
|
630
558
|
})));
|
|
631
|
-
}
|
|
632
|
-
|
|
559
|
+
}
|
|
633
560
|
|
|
561
|
+
// Update the items with the given attributes
|
|
634
562
|
setState(store => store.setItemAttrs(itemIds, attrs));
|
|
635
563
|
}
|
|
636
|
-
|
|
637
564
|
makeStatusUpdate(itemOrItems, type) {
|
|
638
565
|
var _this14 = this;
|
|
639
|
-
|
|
640
566
|
return _asyncToGenerator(function* () {
|
|
641
567
|
// Always treat items as a batch to use the corresponding batch endpoint
|
|
642
568
|
var items = Array.isArray(itemOrItems) ? itemOrItems : [itemOrItems];
|
|
@@ -647,24 +573,21 @@ class Feed {
|
|
|
647
573
|
data: {
|
|
648
574
|
message_ids: itemIds
|
|
649
575
|
}
|
|
650
|
-
});
|
|
651
|
-
// Note: we do this after the update to ensure that the server event actually completed
|
|
576
|
+
});
|
|
652
577
|
|
|
578
|
+
// Emit the event that these items had their statuses changed
|
|
579
|
+
// Note: we do this after the update to ensure that the server event actually completed
|
|
653
580
|
_this14.broadcaster.emit("items:".concat(type), {
|
|
654
581
|
items
|
|
655
582
|
});
|
|
656
|
-
|
|
657
583
|
_this14.broadcastOverChannel("items:".concat(type), {
|
|
658
584
|
items
|
|
659
585
|
});
|
|
660
|
-
|
|
661
586
|
return result;
|
|
662
587
|
})();
|
|
663
588
|
}
|
|
664
|
-
|
|
665
589
|
makeBulkStatusUpdate(type) {
|
|
666
590
|
var _this15 = this;
|
|
667
|
-
|
|
668
591
|
return _asyncToGenerator(function* () {
|
|
669
592
|
// The base scope for the call should take into account all of the options currently
|
|
670
593
|
// set on the feed, as well as being scoped for the current user. We do this so that
|
|
@@ -684,15 +607,14 @@ class Feed {
|
|
|
684
607
|
});
|
|
685
608
|
})();
|
|
686
609
|
}
|
|
687
|
-
|
|
688
610
|
broadcastOverChannel(type, payload) {
|
|
689
611
|
// The broadcastChannel may not be available in non-browser environments
|
|
690
612
|
if (!this.broadcastChannel) {
|
|
691
613
|
return;
|
|
692
|
-
}
|
|
693
|
-
// don't get any `An object could not be cloned` errors when trying to broadcast
|
|
694
|
-
|
|
614
|
+
}
|
|
695
615
|
|
|
616
|
+
// Here we stringify our payload and try and send as JSON such that we
|
|
617
|
+
// don't get any `An object could not be cloned` errors when trying to broadcast
|
|
696
618
|
try {
|
|
697
619
|
var stringifiedPayload = JSON.parse(JSON.stringify(payload));
|
|
698
620
|
this.broadcastChannel.postMessage({
|
|
@@ -703,8 +625,6 @@ class Feed {
|
|
|
703
625
|
console.warn("Could not broadcast ".concat(type, ", got error: ").concat(e));
|
|
704
626
|
}
|
|
705
627
|
}
|
|
706
|
-
|
|
707
628
|
}
|
|
708
|
-
|
|
709
629
|
export default Feed;
|
|
710
630
|
//# sourceMappingURL=feed.js.map
|