@twilio/conversations 2.1.0 → 3.0.0-canary.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -3
- package/builds/browser.js +2346 -1627
- package/builds/browser.js.map +1 -1
- package/builds/lib.d.ts +510 -305
- package/builds/lib.js +2346 -1627
- package/builds/lib.js.map +1 -1
- package/builds/twilio-conversations.js +3373 -3347
- package/builds/twilio-conversations.min.js +2 -2
- package/dist/client.js +402 -281
- package/dist/client.js.map +1 -1
- package/dist/command-executor.js.map +1 -1
- package/dist/configuration.js +2 -2
- package/dist/configuration.js.map +1 -1
- package/dist/conversation.js +406 -374
- package/dist/conversation.js.map +1 -1
- package/dist/data/conversations.js +9 -10
- package/dist/data/conversations.js.map +1 -1
- package/dist/data/messages.js +46 -26
- package/dist/data/messages.js.map +1 -1
- package/dist/data/participants.js +19 -10
- package/dist/data/participants.js.map +1 -1
- package/dist/data/users.js +2 -2
- package/dist/data/users.js.map +1 -1
- package/dist/media.js +36 -25
- package/dist/media.js.map +1 -1
- package/dist/message-builder.js +24 -18
- package/dist/message-builder.js.map +1 -1
- package/dist/message.js +46 -19
- package/dist/message.js.map +1 -1
- package/dist/packages/conversations/package.json.js +1 -1
- package/dist/participant.js.map +1 -1
- package/dist/push-notification.js.map +1 -1
- package/dist/services/typing-indicator.js +1 -1
- package/dist/services/typing-indicator.js.map +1 -1
- package/dist/unsent-message.js +13 -3
- package/dist/unsent-message.js.map +1 -1
- package/package.json +10 -8
- package/CHANGELOG.md +0 -420
- package/docs/assets/css/main.css +0 -2660
- package/docs/assets/images/icons.png +0 -0
- package/docs/assets/images/icons@2x.png +0 -0
- package/docs/assets/images/widgets.png +0 -0
- package/docs/assets/images/widgets@2x.png +0 -0
- package/docs/assets/js/main.js +0 -248
- package/docs/assets/js/search.js +0 -1
- package/docs/classes/AggregatedDeliveryReceipt.html +0 -3184
- package/docs/classes/Client.html +0 -4073
- package/docs/classes/Conversation.html +0 -4325
- package/docs/classes/DetailedDeliveryReceipt.html +0 -3163
- package/docs/classes/Media.html +0 -3193
- package/docs/classes/Message.html +0 -3677
- package/docs/classes/MessageBuilder.html +0 -3254
- package/docs/classes/Participant.html +0 -3444
- package/docs/classes/PushNotification.html +0 -3130
- package/docs/classes/RestPaginator.html +0 -3160
- package/docs/classes/UnsentMessage.html +0 -3042
- package/docs/classes/User.html +0 -3349
- package/docs/index.html +0 -3512
- package/docs/interfaces/ClientOptions.html +0 -3034
- package/docs/interfaces/ConversationBindings.html +0 -3001
- package/docs/interfaces/ConversationEmailBinding.html +0 -3001
- package/docs/interfaces/ConversationLimits.html +0 -3098
- package/docs/interfaces/ConversationState.html +0 -3050
- package/docs/interfaces/CreateConversationOptions.html +0 -3066
- package/docs/interfaces/LastMessage.html +0 -3050
- package/docs/interfaces/Paginator.html +0 -3141
- package/docs/interfaces/ParticipantBindings.html +0 -3001
- package/docs/interfaces/ParticipantEmailBinding.html +0 -3001
- package/docs/interfaces/PushNotificationData.html +0 -3066
- package/docs/interfaces/SendEmailOptions.html +0 -3034
- package/docs/interfaces/SendMediaOptions.html +0 -3068
- package/docs/modules.html +0 -3513
package/dist/conversation.js
CHANGED
@@ -146,7 +146,9 @@ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'defau
|
|
146
146
|
|
147
147
|
var isEqual__default = /*#__PURE__*/_interopDefaultLegacy(isEqual);
|
148
148
|
|
149
|
-
|
149
|
+
/**
|
150
|
+
* Map of the fields that will be processed with update messages.
|
151
|
+
*/
|
150
152
|
const fieldMappings = {
|
151
153
|
lastMessage: "lastMessage",
|
152
154
|
attributes: "attributes",
|
@@ -162,255 +164,150 @@ const fieldMappings = {
|
|
162
164
|
state: "state",
|
163
165
|
bindings: "bindings",
|
164
166
|
};
|
165
|
-
function parseTime(timeString) {
|
166
|
-
try {
|
167
|
-
return new Date(timeString);
|
168
|
-
}
|
169
|
-
catch (e) {
|
170
|
-
return null;
|
171
|
-
}
|
172
|
-
}
|
173
167
|
/**
|
174
|
-
* A conversation represents communication between multiple Conversations
|
168
|
+
* A conversation represents communication between multiple Conversations
|
169
|
+
* clients.
|
175
170
|
*/
|
176
171
|
class Conversation extends replayEventEmitter.ReplayEventEmitter {
|
177
172
|
/**
|
173
|
+
* @param descriptor Conversation descriptor.
|
174
|
+
* @param sid Conversation SID.
|
175
|
+
* @param links Conversation links for REST requests.
|
176
|
+
* @param configuration Client configuration.
|
177
|
+
* @param services Conversation services.
|
178
178
|
* @internal
|
179
179
|
*/
|
180
180
|
constructor(descriptor, sid, links, configuration, services) {
|
181
|
-
var _a;
|
181
|
+
var _a, _b;
|
182
182
|
super();
|
183
183
|
this.sid = sid;
|
184
|
-
this.
|
185
|
-
this.
|
186
|
-
this.
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
const dateUpdated = parseTime(descriptor.dateUpdated);
|
191
|
-
const friendlyName = descriptor.friendlyName || null;
|
192
|
-
const lastReadMessageIndex = Number.isInteger(descriptor.lastConsumedMessageIndex)
|
193
|
-
? descriptor.lastConsumedMessageIndex
|
194
|
-
: null;
|
195
|
-
const uniqueName = descriptor.uniqueName || null;
|
196
|
-
try {
|
197
|
-
JSON.stringify(attributes);
|
198
|
-
}
|
199
|
-
catch (e) {
|
200
|
-
throw new Error("Attributes must be a valid JSON object.");
|
201
|
-
}
|
202
|
-
this.entityName = descriptor.channel;
|
203
|
-
this.channelState = {
|
204
|
-
uniqueName,
|
184
|
+
this._links = links;
|
185
|
+
this._configuration = configuration;
|
186
|
+
this._services = services;
|
187
|
+
this._entityName = descriptor.channel;
|
188
|
+
this._internalState = {
|
189
|
+
uniqueName: descriptor.uniqueName || null,
|
205
190
|
status: "notParticipating",
|
206
|
-
attributes,
|
207
|
-
createdBy,
|
208
|
-
dateCreated,
|
209
|
-
dateUpdated,
|
210
|
-
friendlyName,
|
211
|
-
lastReadMessageIndex
|
212
|
-
|
191
|
+
attributes: (_a = descriptor.attributes) !== null && _a !== void 0 ? _a : {},
|
192
|
+
createdBy: descriptor.createdBy,
|
193
|
+
dateCreated: index.parseTime(descriptor.dateCreated),
|
194
|
+
dateUpdated: index.parseTime(descriptor.dateUpdated),
|
195
|
+
friendlyName: descriptor.friendlyName || null,
|
196
|
+
lastReadMessageIndex: Number.isInteger(descriptor.lastConsumedMessageIndex)
|
197
|
+
? descriptor.lastConsumedMessageIndex
|
198
|
+
: null,
|
199
|
+
bindings: (_b = descriptor.bindings) !== null && _b !== void 0 ? _b : {},
|
213
200
|
};
|
214
201
|
if (descriptor.notificationLevel) {
|
215
|
-
this.
|
202
|
+
this._internalState.notificationLevel = descriptor.notificationLevel;
|
216
203
|
}
|
217
204
|
const participantsLinks = {
|
218
|
-
participants: this.
|
205
|
+
participants: this._links.participants,
|
219
206
|
};
|
220
|
-
this.
|
221
|
-
this.
|
222
|
-
this.
|
223
|
-
this.
|
224
|
-
this.
|
225
|
-
this.
|
226
|
-
this.
|
227
|
-
this.
|
228
|
-
this.
|
207
|
+
this._participants = new Map();
|
208
|
+
this._participantsEntity = new participants.Participants(this, this._participants, participantsLinks, this._configuration, this._services);
|
209
|
+
this._participantsEntity.on("participantJoined", (participant) => this.emit("participantJoined", participant));
|
210
|
+
this._participantsEntity.on("participantLeft", (participant) => this.emit("participantLeft", participant));
|
211
|
+
this._participantsEntity.on("participantUpdated", (args) => this.emit("participantUpdated", args));
|
212
|
+
this._messagesEntity = new messages.Messages(this, configuration, services);
|
213
|
+
this._messagesEntity.on("messageAdded", (message) => this._onMessageAdded(message));
|
214
|
+
this._messagesEntity.on("messageUpdated", (args) => this.emit("messageUpdated", args));
|
215
|
+
this._messagesEntity.on("messageRemoved", (message) => this.emit("messageRemoved", message));
|
229
216
|
}
|
230
217
|
/**
|
231
218
|
* Unique name of the conversation.
|
232
219
|
*/
|
233
220
|
get uniqueName() {
|
234
|
-
return this.
|
221
|
+
return this._internalState.uniqueName;
|
235
222
|
}
|
236
223
|
/**
|
237
224
|
* Status of the conversation.
|
238
225
|
*/
|
239
226
|
get status() {
|
240
|
-
return this.
|
227
|
+
return this._internalState.status;
|
241
228
|
}
|
242
229
|
/**
|
243
230
|
* Name of the conversation.
|
244
231
|
*/
|
245
232
|
get friendlyName() {
|
246
|
-
return this.
|
233
|
+
return this._internalState.friendlyName;
|
247
234
|
}
|
248
235
|
/**
|
249
236
|
* Date this conversation was last updated on.
|
250
237
|
*/
|
251
238
|
get dateUpdated() {
|
252
|
-
return this.
|
239
|
+
return this._internalState.dateUpdated;
|
253
240
|
}
|
254
241
|
/**
|
255
242
|
* Date this conversation was created on.
|
256
243
|
*/
|
257
244
|
get dateCreated() {
|
258
|
-
return this.
|
245
|
+
return this._internalState.dateCreated;
|
259
246
|
}
|
260
247
|
/**
|
261
248
|
* Identity of the user that created this conversation.
|
262
249
|
*/
|
263
250
|
get createdBy() {
|
264
251
|
var _a;
|
265
|
-
return (_a = this.
|
252
|
+
return (_a = this._internalState.createdBy) !== null && _a !== void 0 ? _a : "";
|
266
253
|
}
|
267
254
|
/**
|
268
255
|
* Custom attributes of the conversation.
|
269
256
|
*/
|
270
257
|
get attributes() {
|
271
|
-
return this.
|
258
|
+
return this._internalState.attributes;
|
272
259
|
}
|
273
260
|
/**
|
274
261
|
* Index of the last message the user has read in this conversation.
|
275
262
|
*/
|
276
263
|
get lastReadMessageIndex() {
|
277
|
-
return this.
|
264
|
+
return this._internalState.lastReadMessageIndex;
|
278
265
|
}
|
279
266
|
/**
|
280
267
|
* Last message sent to this conversation.
|
281
268
|
*/
|
282
269
|
get lastMessage() {
|
283
270
|
var _a;
|
284
|
-
return (_a = this.
|
271
|
+
return (_a = this._internalState.lastMessage) !== null && _a !== void 0 ? _a : undefined;
|
285
272
|
}
|
286
273
|
/**
|
287
274
|
* User notification level for this conversation.
|
288
275
|
*/
|
289
276
|
get notificationLevel() {
|
290
277
|
var _a;
|
291
|
-
return (_a = this.
|
278
|
+
return (_a = this._internalState.notificationLevel) !== null && _a !== void 0 ? _a : "default";
|
292
279
|
}
|
280
|
+
/**
|
281
|
+
* Conversation bindings. Undocumented feature (for now).
|
282
|
+
* @internal
|
283
|
+
*/
|
293
284
|
get bindings() {
|
294
|
-
return this.
|
285
|
+
return this._internalState.bindings;
|
295
286
|
}
|
296
287
|
/**
|
297
288
|
* Current conversation limits.
|
298
289
|
*/
|
299
290
|
get limits() {
|
300
|
-
return this.
|
291
|
+
return this._configuration.limits;
|
301
292
|
}
|
302
293
|
/**
|
303
294
|
* State of the conversation.
|
304
295
|
*/
|
305
296
|
get state() {
|
306
|
-
return this.
|
307
|
-
}
|
308
|
-
/**
|
309
|
-
* Load and subscribe to this conversation and do not subscribe to its participants and messages.
|
310
|
-
* This or _subscribeStreams will need to be called before any events on conversation will fire.
|
311
|
-
* @internal
|
312
|
-
*/
|
313
|
-
_subscribe() {
|
314
|
-
var _a;
|
315
|
-
return (this.entityPromise =
|
316
|
-
(_a = this.entityPromise) !== null && _a !== void 0 ? _a : this.services.syncClient
|
317
|
-
.document({ id: this.entityName, mode: "open_existing" })
|
318
|
-
.then((entity) => {
|
319
|
-
this.entity = entity;
|
320
|
-
this.entity.on("updated", (args) => {
|
321
|
-
this._update(args.data);
|
322
|
-
});
|
323
|
-
this.entity.on("removed", () => this.emit("removed", this));
|
324
|
-
this._update(this.entity.data);
|
325
|
-
return entity;
|
326
|
-
})
|
327
|
-
.catch((err) => {
|
328
|
-
this.entity = null;
|
329
|
-
this.entityPromise = null;
|
330
|
-
if (this.services.syncClient.connectionState != "disconnected") {
|
331
|
-
log.error("Failed to get conversation object", err);
|
332
|
-
}
|
333
|
-
log.debug("ERROR: Failed to get conversation object", err);
|
334
|
-
throw err;
|
335
|
-
}));
|
297
|
+
return this._internalState.state;
|
336
298
|
}
|
337
299
|
/**
|
338
|
-
*
|
339
|
-
* This or _subscribe will need to be called before any events on the conversation will fire.
|
340
|
-
* This will need to be called before any events on participants or messages will fire
|
300
|
+
* Source of the conversation update.
|
341
301
|
* @internal
|
342
302
|
*/
|
343
|
-
|
344
|
-
|
345
|
-
try {
|
346
|
-
await this._subscribe();
|
347
|
-
log.trace("_subscribeStreams, this.entity.data=", (_a = this.entity) === null || _a === void 0 ? void 0 : _a.data);
|
348
|
-
const messagesObjectName = ((_b = this.entity) === null || _b === void 0 ? void 0 : _b.data)
|
349
|
-
.messages;
|
350
|
-
const rosterObjectName = ((_c = this.entity) === null || _c === void 0 ? void 0 : _c.data)
|
351
|
-
.roster;
|
352
|
-
await Promise.all([
|
353
|
-
this.messagesEntity.subscribe(messagesObjectName),
|
354
|
-
this.participantsEntity.subscribe(rosterObjectName),
|
355
|
-
]);
|
356
|
-
}
|
357
|
-
catch (err) {
|
358
|
-
if (this.services.syncClient.connectionState !== "disconnected") {
|
359
|
-
log.error("Failed to subscribe on conversation objects", this.sid, err);
|
360
|
-
}
|
361
|
-
log.debug("ERROR: Failed to subscribe on conversation objects", this.sid, err);
|
362
|
-
throw err;
|
363
|
-
}
|
303
|
+
get _statusSource() {
|
304
|
+
return this._dataSource;
|
364
305
|
}
|
365
306
|
/**
|
366
|
-
*
|
367
|
-
* @
|
307
|
+
* Preprocess the update object.
|
308
|
+
* @param update The update object received from Sync.
|
309
|
+
* @param conversationSid The SID of the conversation in question.
|
368
310
|
*/
|
369
|
-
async _unsubscribe() {
|
370
|
-
if (this.entity) {
|
371
|
-
await this.entity.close();
|
372
|
-
this.entity = null;
|
373
|
-
this.entityPromise = null;
|
374
|
-
}
|
375
|
-
return Promise.all([
|
376
|
-
this.participantsEntity.unsubscribe(),
|
377
|
-
this.messagesEntity.unsubscribe(),
|
378
|
-
]);
|
379
|
-
}
|
380
|
-
/**
|
381
|
-
* Set conversation status.
|
382
|
-
* @internal
|
383
|
-
*/
|
384
|
-
_setStatus(status, source) {
|
385
|
-
this.statusSource = source;
|
386
|
-
if (this.channelState.status === status) {
|
387
|
-
return;
|
388
|
-
}
|
389
|
-
this.channelState.status = status;
|
390
|
-
if (status === "joined") {
|
391
|
-
this._subscribeStreams().catch((err) => {
|
392
|
-
log.debug("ERROR while setting conversation status " + status, err);
|
393
|
-
if (this.services.syncClient.connectionState !== "disconnected") {
|
394
|
-
throw err;
|
395
|
-
}
|
396
|
-
});
|
397
|
-
}
|
398
|
-
else if (this.entityPromise) {
|
399
|
-
this._unsubscribe().catch((err) => {
|
400
|
-
log.debug("ERROR while setting conversation status " + status, err);
|
401
|
-
if (this.services.syncClient.connectionState !== "disconnected") {
|
402
|
-
throw err;
|
403
|
-
}
|
404
|
-
});
|
405
|
-
}
|
406
|
-
}
|
407
|
-
/**
|
408
|
-
* Get the source of the conversation update.
|
409
|
-
* @internal
|
410
|
-
*/
|
411
|
-
_statusSource() {
|
412
|
-
return this.statusSource;
|
413
|
-
}
|
414
311
|
static preprocessUpdate(update, conversationSid) {
|
415
312
|
try {
|
416
313
|
if (typeof update.attributes === "string") {
|
@@ -421,27 +318,23 @@ class Conversation extends replayEventEmitter.ReplayEventEmitter {
|
|
421
318
|
}
|
422
319
|
}
|
423
320
|
catch (e) {
|
424
|
-
|
321
|
+
Conversation._logger.warn("Retrieved malformed attributes from the server for conversation: " +
|
425
322
|
conversationSid);
|
426
323
|
update.attributes = {};
|
427
324
|
}
|
428
325
|
try {
|
429
|
-
|
430
|
-
update.dateCreated = new Date(update.dateCreated);
|
431
|
-
}
|
326
|
+
update.dateCreated && (update.dateCreated = new Date(update.dateCreated));
|
432
327
|
}
|
433
328
|
catch (e) {
|
434
|
-
|
329
|
+
Conversation._logger.warn("Retrieved malformed dateCreated from the server for conversation: " +
|
435
330
|
conversationSid);
|
436
331
|
delete update.dateCreated;
|
437
332
|
}
|
438
333
|
try {
|
439
|
-
|
440
|
-
update.dateUpdated = new Date(update.dateUpdated);
|
441
|
-
}
|
334
|
+
update.dateUpdated && (update.dateUpdated = new Date(update.dateUpdated));
|
442
335
|
}
|
443
336
|
catch (e) {
|
444
|
-
|
337
|
+
Conversation._logger.warn("Retrieved malformed dateUpdated from the server for conversation: " +
|
445
338
|
conversationSid);
|
446
339
|
delete update.dateUpdated;
|
447
340
|
}
|
@@ -451,158 +344,44 @@ class Conversation extends replayEventEmitter.ReplayEventEmitter {
|
|
451
344
|
}
|
452
345
|
}
|
453
346
|
catch (e) {
|
454
|
-
|
347
|
+
Conversation._logger.warn("Retrieved malformed lastMessage.timestamp from the server for conversation: " +
|
455
348
|
conversationSid);
|
456
349
|
delete update.lastMessage.timestamp;
|
457
350
|
}
|
458
351
|
}
|
459
|
-
/**
|
460
|
-
* Update the local conversation object with new values.
|
461
|
-
* @internal
|
462
|
-
*/
|
463
|
-
_update(update) {
|
464
|
-
var _a, _b, _c, _d, _e;
|
465
|
-
log.trace("_update", update);
|
466
|
-
Conversation.preprocessUpdate(update, this.sid);
|
467
|
-
const updateReasons = new Set();
|
468
|
-
for (const key of Object.keys(update)) {
|
469
|
-
const localKey = fieldMappings[key];
|
470
|
-
if (!localKey) {
|
471
|
-
continue;
|
472
|
-
}
|
473
|
-
switch (localKey) {
|
474
|
-
case fieldMappings.status:
|
475
|
-
if (!update.status ||
|
476
|
-
update.status === "unknown" ||
|
477
|
-
this.channelState.status === update.status) {
|
478
|
-
break;
|
479
|
-
}
|
480
|
-
this.channelState.status = update.status;
|
481
|
-
updateReasons.add(localKey);
|
482
|
-
break;
|
483
|
-
case fieldMappings.attributes:
|
484
|
-
if (isEqual__default['default'](this.channelState.attributes, update.attributes)) {
|
485
|
-
break;
|
486
|
-
}
|
487
|
-
this.channelState.attributes = update.attributes;
|
488
|
-
updateReasons.add(localKey);
|
489
|
-
break;
|
490
|
-
case fieldMappings.lastConsumedMessageIndex:
|
491
|
-
if (update.lastConsumedMessageIndex === undefined ||
|
492
|
-
update.lastConsumedMessageIndex ===
|
493
|
-
this.channelState.lastReadMessageIndex) {
|
494
|
-
break;
|
495
|
-
}
|
496
|
-
this.channelState.lastReadMessageIndex =
|
497
|
-
update.lastConsumedMessageIndex;
|
498
|
-
updateReasons.add("lastReadMessageIndex");
|
499
|
-
break;
|
500
|
-
case fieldMappings.lastMessage:
|
501
|
-
if (this.channelState.lastMessage && !update.lastMessage) {
|
502
|
-
delete this.channelState.lastMessage;
|
503
|
-
updateReasons.add(localKey);
|
504
|
-
break;
|
505
|
-
}
|
506
|
-
this.channelState.lastMessage = this.channelState.lastMessage || {};
|
507
|
-
if (((_a = update.lastMessage) === null || _a === void 0 ? void 0 : _a.index) !== undefined &&
|
508
|
-
update.lastMessage.index !== this.channelState.lastMessage.index) {
|
509
|
-
this.channelState.lastMessage.index = update.lastMessage.index;
|
510
|
-
updateReasons.add(localKey);
|
511
|
-
}
|
512
|
-
if (((_b = update.lastMessage) === null || _b === void 0 ? void 0 : _b.timestamp) !== undefined &&
|
513
|
-
((_d = (_c = this.channelState.lastMessage) === null || _c === void 0 ? void 0 : _c.dateCreated) === null || _d === void 0 ? void 0 : _d.getTime()) !==
|
514
|
-
update.lastMessage.timestamp.getTime()) {
|
515
|
-
this.channelState.lastMessage.dateCreated =
|
516
|
-
update.lastMessage.timestamp;
|
517
|
-
updateReasons.add(localKey);
|
518
|
-
}
|
519
|
-
if (isEqual__default['default'](this.channelState.lastMessage, {})) {
|
520
|
-
delete this.channelState.lastMessage;
|
521
|
-
}
|
522
|
-
break;
|
523
|
-
case fieldMappings.state:
|
524
|
-
const state = update.state || undefined;
|
525
|
-
if (state !== undefined) {
|
526
|
-
state.dateUpdated = new Date(state.dateUpdated);
|
527
|
-
}
|
528
|
-
if (isEqual__default['default'](this.channelState.state, state)) {
|
529
|
-
break;
|
530
|
-
}
|
531
|
-
this.channelState.state = state;
|
532
|
-
updateReasons.add(localKey);
|
533
|
-
break;
|
534
|
-
case fieldMappings.bindings:
|
535
|
-
if (isEqual__default['default'](this.channelState.bindings, update.bindings)) {
|
536
|
-
break;
|
537
|
-
}
|
538
|
-
this.channelState.bindings = update.bindings;
|
539
|
-
updateReasons.add(localKey);
|
540
|
-
break;
|
541
|
-
default:
|
542
|
-
const isDate = update[key] instanceof Date;
|
543
|
-
const keysMatchAsDates = isDate &&
|
544
|
-
((_e = this.channelState[localKey]) === null || _e === void 0 ? void 0 : _e.getTime()) === update[key].getTime();
|
545
|
-
const keysMatchAsNonDates = !isDate && this[localKey] === update[key];
|
546
|
-
if (keysMatchAsDates || keysMatchAsNonDates) {
|
547
|
-
break;
|
548
|
-
}
|
549
|
-
this.channelState[localKey] = update[key];
|
550
|
-
updateReasons.add(localKey);
|
551
|
-
}
|
552
|
-
}
|
553
|
-
if (updateReasons.size > 0) {
|
554
|
-
this.emit("updated", {
|
555
|
-
conversation: this,
|
556
|
-
updateReasons: [...updateReasons],
|
557
|
-
});
|
558
|
-
}
|
559
|
-
}
|
560
|
-
/**
|
561
|
-
* @internal
|
562
|
-
*/
|
563
|
-
_onMessageAdded(message) {
|
564
|
-
for (const participant of this.participants.values()) {
|
565
|
-
if (participant.identity === message.author) {
|
566
|
-
participant._endTyping();
|
567
|
-
break;
|
568
|
-
}
|
569
|
-
}
|
570
|
-
this.emit("messageAdded", message);
|
571
|
-
}
|
572
|
-
async _setLastReadMessageIndex(index) {
|
573
|
-
const result = await this.services.commandExecutor.mutateResource("post", `${this.configuration.links.myConversations}/${this.sid}`, {
|
574
|
-
last_read_message_index: index,
|
575
|
-
});
|
576
|
-
return result.unread_messages_count;
|
577
|
-
}
|
578
352
|
/**
|
579
353
|
* Add a participant to the conversation by its identity.
|
580
354
|
* @param identity Identity of the Client to add.
|
581
355
|
* @param attributes Attributes to be attached to the participant.
|
356
|
+
* @returns The added participant.
|
582
357
|
*/
|
583
358
|
async add(identity, attributes) {
|
584
|
-
return this.
|
359
|
+
return this._participantsEntity.add(identity, attributes !== null && attributes !== void 0 ? attributes : {});
|
585
360
|
}
|
586
361
|
/**
|
587
362
|
* Add a non-chat participant to the conversation.
|
588
363
|
* @param proxyAddress Proxy (Twilio) address of the participant.
|
589
364
|
* @param address User address of the participant.
|
590
365
|
* @param attributes Attributes to be attached to the participant.
|
591
|
-
* @param bindingOptions Options for adding email participants - name and
|
366
|
+
* @param bindingOptions Options for adding email participants - name and
|
367
|
+
* CC/To level.
|
368
|
+
* @returns The added participant.
|
592
369
|
*/
|
593
370
|
async addNonChatParticipant(proxyAddress, address, attributes = {}, bindingOptions = {}) {
|
594
|
-
return this.
|
371
|
+
return this._participantsEntity.addNonChatParticipant(proxyAddress, address, attributes !== null && attributes !== void 0 ? attributes : {}, bindingOptions !== null && bindingOptions !== void 0 ? bindingOptions : {});
|
595
372
|
}
|
596
373
|
/**
|
597
|
-
* Advance the conversation's last read message index to the current read
|
598
|
-
* Rejects if the user is not a participant of the conversation.
|
599
|
-
*
|
374
|
+
* Advance the conversation's last read message index to the current read
|
375
|
+
* horizon. Rejects if the user is not a participant of the conversation. Last
|
376
|
+
* read message index is updated only if the new index value is higher than
|
377
|
+
* the previous.
|
600
378
|
* @param index Message index to advance to.
|
601
379
|
* @return Resulting unread messages count in the conversation.
|
602
380
|
*/
|
603
381
|
async advanceLastReadMessageIndex(index) {
|
382
|
+
var _a;
|
604
383
|
await this._subscribeStreams();
|
605
|
-
if (index < (this.lastReadMessageIndex
|
384
|
+
if (index < ((_a = this.lastReadMessageIndex) !== null && _a !== void 0 ? _a : 0)) {
|
606
385
|
return await this._setLastReadMessageIndex(this.lastReadMessageIndex);
|
607
386
|
}
|
608
387
|
return await this._setLastReadMessageIndex(index);
|
@@ -611,7 +390,7 @@ class Conversation extends replayEventEmitter.ReplayEventEmitter {
|
|
611
390
|
* Delete the conversation and unsubscribe from its events.
|
612
391
|
*/
|
613
392
|
async delete() {
|
614
|
-
await this.
|
393
|
+
await this._services.commandExecutor.mutateResource("delete", this._links.self);
|
615
394
|
return this;
|
616
395
|
}
|
617
396
|
/**
|
@@ -623,39 +402,43 @@ class Conversation extends replayEventEmitter.ReplayEventEmitter {
|
|
623
402
|
}
|
624
403
|
/**
|
625
404
|
* Returns messages from the conversation using the paginator interface.
|
626
|
-
* @param pageSize Number of messages to return in a single chunk. Default is
|
627
|
-
*
|
628
|
-
* @param
|
629
|
-
*
|
405
|
+
* @param pageSize Number of messages to return in a single chunk. Default is
|
406
|
+
* 30.
|
407
|
+
* @param anchor Index of the newest message to fetch. Default is from the
|
408
|
+
* end.
|
409
|
+
* @param direction Query direction. By default, it queries backwards
|
410
|
+
* from newer to older. The `"forward"` value will query in the opposite
|
411
|
+
* direction.
|
630
412
|
* @return A page of messages.
|
631
413
|
*/
|
632
414
|
async getMessages(pageSize, anchor, direction) {
|
633
415
|
await this._subscribeStreams();
|
634
|
-
return this.
|
416
|
+
return this._messagesEntity.getMessages(pageSize, anchor, direction);
|
635
417
|
}
|
636
418
|
/**
|
637
419
|
* Get a list of all the participants who are joined to this conversation.
|
638
420
|
*/
|
639
421
|
async getParticipants() {
|
640
422
|
await this._subscribeStreams();
|
641
|
-
return this.
|
423
|
+
return this._participantsEntity.getParticipants();
|
642
424
|
}
|
643
425
|
/**
|
644
426
|
* Get conversation participants count.
|
645
427
|
*
|
646
|
-
* This method is semi-realtime. This means that this data will be eventually
|
647
|
-
* but will also be possibly incorrect for a few seconds. The
|
648
|
-
* provide real time events for counter values
|
428
|
+
* This method is semi-realtime. This means that this data will be eventually
|
429
|
+
* correct, but will also be possibly incorrect for a few seconds. The
|
430
|
+
* Conversations system does not provide real time events for counter values
|
431
|
+
* changes.
|
649
432
|
*
|
650
|
-
* This is useful for any UI badges, but it is not recommended to build any
|
651
|
-
* logic based on these counters being accurate in real time.
|
433
|
+
* This is useful for any UI badges, but it is not recommended to build any
|
434
|
+
* core application logic based on these counters being accurate in real time.
|
652
435
|
*/
|
653
436
|
async getParticipantsCount() {
|
654
437
|
var _a;
|
655
|
-
const url = new index.UriBuilder(this.
|
438
|
+
const url = new index.UriBuilder(this._configuration.links.conversations)
|
656
439
|
.path(this.sid)
|
657
440
|
.build();
|
658
|
-
const response = await this.
|
441
|
+
const response = await this._services.network.get(url);
|
659
442
|
return (_a = response.body.participants_count) !== null && _a !== void 0 ? _a : 0;
|
660
443
|
}
|
661
444
|
/**
|
@@ -663,53 +446,55 @@ class Conversation extends replayEventEmitter.ReplayEventEmitter {
|
|
663
446
|
* @param participantSid Participant SID.
|
664
447
|
*/
|
665
448
|
async getParticipantBySid(participantSid) {
|
666
|
-
return this.
|
449
|
+
return this._participantsEntity.getParticipantBySid(participantSid);
|
667
450
|
}
|
668
451
|
/**
|
669
452
|
* Get a participant by its identity.
|
670
453
|
* @param identity Participant identity.
|
671
454
|
*/
|
672
455
|
async getParticipantByIdentity(identity = "") {
|
673
|
-
return this.
|
456
|
+
return this._participantsEntity.getParticipantByIdentity(identity !== null && identity !== void 0 ? identity : "");
|
674
457
|
}
|
675
458
|
/**
|
676
459
|
* Get the total message count in the conversation.
|
677
460
|
*
|
678
|
-
* This method is semi-realtime. This means that this data will be eventually
|
679
|
-
* but will also be possibly incorrect for a few seconds. The
|
680
|
-
* provide real time events for counter values
|
461
|
+
* This method is semi-realtime. This means that this data will be eventually
|
462
|
+
* correct, but will also be possibly incorrect for a few seconds. The
|
463
|
+
* Conversations system does not provide real time events for counter values
|
464
|
+
* changes.
|
681
465
|
*
|
682
|
-
* This is useful for any UI badges, but it is not recommended to build any
|
683
|
-
* logic based on these counters being accurate in real time.
|
466
|
+
* This is useful for any UI badges, but it is not recommended to build any
|
467
|
+
* core application logic based on these counters being accurate in real time.
|
684
468
|
*/
|
685
469
|
async getMessagesCount() {
|
686
470
|
var _a;
|
687
|
-
const url = new index.UriBuilder(this.
|
471
|
+
const url = new index.UriBuilder(this._configuration.links.conversations)
|
688
472
|
.path(this.sid)
|
689
473
|
.build();
|
690
|
-
const response = await this.
|
474
|
+
const response = await this._services.network.get(url);
|
691
475
|
return (_a = response.body.messages_count) !== null && _a !== void 0 ? _a : 0;
|
692
476
|
}
|
693
477
|
/**
|
694
|
-
* Get unread messages count for the user if they are a participant of this
|
695
|
-
* Rejects if the user is not a participant of the conversation.
|
478
|
+
* Get unread messages count for the user if they are a participant of this
|
479
|
+
* conversation. Rejects if the user is not a participant of the conversation.
|
696
480
|
*
|
697
481
|
* Use this method to obtain the number of unread messages together with
|
698
482
|
* {@link Conversation.updateLastReadMessageIndex} instead of relying on the
|
699
483
|
* message indices which may have gaps. See {@link Message.index} for details.
|
700
484
|
*
|
701
|
-
* This method is semi-realtime. This means that this data will be eventually
|
702
|
-
* but will also be possibly incorrect for a few seconds. The
|
703
|
-
* provide real time events for counter values
|
485
|
+
* This method is semi-realtime. This means that this data will be eventually
|
486
|
+
* correct, but will also be possibly incorrect for a few seconds. The
|
487
|
+
* Conversations system does not provide real time events for counter values
|
488
|
+
* changes.
|
704
489
|
*
|
705
|
-
* This is useful for any UI badges, but it is not recommended to build any
|
706
|
-
* logic based on these counters being accurate in real time.
|
490
|
+
* This is useful for any UI badges, but it is not recommended to build any
|
491
|
+
* core application logic based on these counters being accurate in real time.
|
707
492
|
*/
|
708
493
|
async getUnreadMessagesCount() {
|
709
|
-
const url = new index.UriBuilder(this.
|
494
|
+
const url = new index.UriBuilder(this._configuration.links.myConversations)
|
710
495
|
.path(this.sid)
|
711
496
|
.build();
|
712
|
-
const response = await this.
|
497
|
+
const response = await this._services.network.get(url);
|
713
498
|
if (response.body.conversation_sid !== this.sid) {
|
714
499
|
throw new Error("Conversation was not found in the user conversations list");
|
715
500
|
}
|
@@ -723,8 +508,8 @@ class Conversation extends replayEventEmitter.ReplayEventEmitter {
|
|
723
508
|
* Join the conversation and subscribe to its events.
|
724
509
|
*/
|
725
510
|
async join() {
|
726
|
-
await this.
|
727
|
-
identity: this.
|
511
|
+
await this._services.commandExecutor.mutateResource("post", this._links.participants, {
|
512
|
+
identity: this._configuration.userIdentity,
|
728
513
|
});
|
729
514
|
return this;
|
730
515
|
}
|
@@ -732,8 +517,8 @@ class Conversation extends replayEventEmitter.ReplayEventEmitter {
|
|
732
517
|
* Leave the conversation.
|
733
518
|
*/
|
734
519
|
async leave() {
|
735
|
-
if (this.
|
736
|
-
await this.
|
520
|
+
if (this._internalState.status === "joined") {
|
521
|
+
await this._services.commandExecutor.mutateResource("delete", `${this._links.participants}/${this._configuration.userIdentity}`);
|
737
522
|
}
|
738
523
|
return this;
|
739
524
|
}
|
@@ -745,12 +530,13 @@ class Conversation extends replayEventEmitter.ReplayEventEmitter {
|
|
745
530
|
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
746
531
|
// @ts-ignore TODO: fix validateTypesAsync typing
|
747
532
|
async removeParticipant(participant) {
|
748
|
-
await this.
|
533
|
+
await this._participantsEntity.remove(typeof participant === "string" ? participant : participant.sid);
|
749
534
|
}
|
750
535
|
/**
|
751
536
|
* Send a message to the conversation.
|
752
537
|
* @param message Message body for the text message,
|
753
|
-
* `FormData` or {@link SendMediaOptions} for media content. Sending FormData
|
538
|
+
* `FormData` or {@link SendMediaOptions} for media content. Sending FormData
|
539
|
+
* is supported only with the browser engine.
|
754
540
|
* @param messageAttributes Attributes for the message.
|
755
541
|
* @param emailOptions Email options for the message.
|
756
542
|
* @return Index of the new message.
|
@@ -758,22 +544,23 @@ class Conversation extends replayEventEmitter.ReplayEventEmitter {
|
|
758
544
|
async sendMessage(message, messageAttributes, emailOptions) {
|
759
545
|
var _a, _b;
|
760
546
|
if (typeof message === "string" || message === null) {
|
761
|
-
const response = await this.
|
547
|
+
const response = await this._messagesEntity.send(message, messageAttributes, emailOptions);
|
762
548
|
return (_a = index.parseToNumber(response.index)) !== null && _a !== void 0 ? _a : 0;
|
763
549
|
}
|
764
|
-
const response = await this.
|
550
|
+
const response = await this._messagesEntity.sendMedia(message, messageAttributes, emailOptions);
|
765
551
|
return (_b = index.parseToNumber(response.index)) !== null && _b !== void 0 ? _b : 0;
|
766
552
|
}
|
767
553
|
/**
|
768
554
|
* New interface to prepare for sending a message.
|
769
|
-
* Use instead of
|
555
|
+
* Use this instead of {@link Message.sendMessage}.
|
770
556
|
* @return A MessageBuilder to help set all message sending options.
|
771
557
|
*/
|
772
558
|
prepareMessage() {
|
773
|
-
return new messageBuilder.MessageBuilder(this.limits, this.
|
559
|
+
return new messageBuilder.MessageBuilder(this.limits, this._messagesEntity);
|
774
560
|
}
|
775
561
|
/**
|
776
|
-
* Set last read message index of the conversation to the index of the last
|
562
|
+
* Set last read message index of the conversation to the index of the last
|
563
|
+
* known message.
|
777
564
|
* @return Resulting unread messages count in the conversation.
|
778
565
|
*/
|
779
566
|
async setAllMessagesRead() {
|
@@ -782,7 +569,7 @@ class Conversation extends replayEventEmitter.ReplayEventEmitter {
|
|
782
569
|
if (messagesPage.items.length > 0) {
|
783
570
|
return this.advanceLastReadMessageIndex(messagesPage.items[0].index);
|
784
571
|
}
|
785
|
-
return
|
572
|
+
return 0;
|
786
573
|
}
|
787
574
|
/**
|
788
575
|
* Set all messages in the conversation unread.
|
@@ -797,23 +584,25 @@ class Conversation extends replayEventEmitter.ReplayEventEmitter {
|
|
797
584
|
* @param notificationLevel New user notification level.
|
798
585
|
*/
|
799
586
|
async setUserNotificationLevel(notificationLevel) {
|
800
|
-
await this.
|
587
|
+
await this._services.commandExecutor.mutateResource("post", `${this._configuration.links.myConversations}/${this.sid}`, {
|
801
588
|
notification_level: notificationLevel,
|
802
589
|
});
|
803
590
|
}
|
804
591
|
/**
|
805
|
-
* Send a notification to the server indicating that this client is currently
|
806
|
-
* Typing ended notification is sent after a
|
592
|
+
* Send a notification to the server indicating that this client is currently
|
593
|
+
* typing in this conversation. Typing ended notification is sent after a
|
594
|
+
* while automatically, but by calling this method again you ensure that
|
595
|
+
* typing ended is not received.
|
807
596
|
*/
|
808
597
|
typing() {
|
809
|
-
return this.
|
598
|
+
return this._services.typingIndicator.send(this.sid);
|
810
599
|
}
|
811
600
|
/**
|
812
601
|
* Update the attributes of the conversation.
|
813
602
|
* @param attributes New attributes.
|
814
603
|
*/
|
815
604
|
async updateAttributes(attributes) {
|
816
|
-
await this.
|
605
|
+
await this._services.commandExecutor.mutateResource("post", this._links.self, {
|
817
606
|
attributes: attributes !== undefined ? JSON.stringify(attributes) : undefined,
|
818
607
|
});
|
819
608
|
return this;
|
@@ -823,15 +612,15 @@ class Conversation extends replayEventEmitter.ReplayEventEmitter {
|
|
823
612
|
* @param friendlyName New friendly name.
|
824
613
|
*/
|
825
614
|
async updateFriendlyName(friendlyName) {
|
826
|
-
if (this.
|
827
|
-
await this.
|
615
|
+
if (this._internalState.friendlyName !== friendlyName) {
|
616
|
+
await this._services.commandExecutor.mutateResource("post", this._links.self, { friendly_name: friendlyName });
|
828
617
|
}
|
829
618
|
return this;
|
830
619
|
}
|
831
620
|
/**
|
832
621
|
* Set the last read message index to the current read horizon.
|
833
|
-
* @param index Message index to set as last read.
|
834
|
-
*
|
622
|
+
* @param index Message index to set as last read. If null is provided, then
|
623
|
+
* the behavior is identical to {@link Conversation.setAllMessagesUnread}.
|
835
624
|
* @returns Resulting unread messages count in the conversation.
|
836
625
|
*/
|
837
626
|
async updateLastReadMessageIndex(index) {
|
@@ -840,25 +629,251 @@ class Conversation extends replayEventEmitter.ReplayEventEmitter {
|
|
840
629
|
}
|
841
630
|
/**
|
842
631
|
* Update the unique name of the conversation.
|
843
|
-
* @param uniqueName New unique name for the conversation. Setting unique name
|
632
|
+
* @param uniqueName New unique name for the conversation. Setting unique name
|
633
|
+
* to null removes it.
|
844
634
|
*/
|
845
635
|
async updateUniqueName(uniqueName) {
|
846
|
-
if (this.
|
847
|
-
|
848
|
-
|
849
|
-
}
|
850
|
-
await this.services.commandExecutor.mutateResource("post", this.links.self, {
|
636
|
+
if (this._internalState.uniqueName !== uniqueName) {
|
637
|
+
uniqueName || (uniqueName = "");
|
638
|
+
await this._services.commandExecutor.mutateResource("post", this._links.self, {
|
851
639
|
unique_name: uniqueName,
|
852
640
|
});
|
853
641
|
}
|
854
642
|
return this;
|
855
643
|
}
|
644
|
+
/**
|
645
|
+
* Load and subscribe to this conversation and do not subscribe to its
|
646
|
+
* participants and messages. This or _subscribeStreams will need to be called
|
647
|
+
* before any events on conversation will fire.
|
648
|
+
* @internal
|
649
|
+
*/
|
650
|
+
async _subscribe() {
|
651
|
+
if (this._entityPromise) {
|
652
|
+
return this._entityPromise;
|
653
|
+
}
|
654
|
+
this._entityPromise = this._services.syncClient.document({
|
655
|
+
id: this._entityName,
|
656
|
+
mode: "open_existing",
|
657
|
+
});
|
658
|
+
try {
|
659
|
+
this._entity = await this._entityPromise;
|
660
|
+
this._entity.on("updated", (args) => this._update(args.data));
|
661
|
+
this._entity.on("removed", () => this.emit("removed", this));
|
662
|
+
this._update(this._entity.data);
|
663
|
+
return this._entity;
|
664
|
+
}
|
665
|
+
catch (err) {
|
666
|
+
this._entity = null;
|
667
|
+
this._entityPromise = null;
|
668
|
+
if (this._services.syncClient.connectionState != "disconnected") {
|
669
|
+
Conversation._logger.error("Failed to get conversation object", err);
|
670
|
+
}
|
671
|
+
Conversation._logger.debug("ERROR: Failed to get conversation object", err);
|
672
|
+
throw err;
|
673
|
+
}
|
674
|
+
}
|
675
|
+
/**
|
676
|
+
* Load the attributes of this conversation and instantiate its participants
|
677
|
+
* and messages. This or _subscribe will need to be called before any events
|
678
|
+
* on the conversation will fire. This will need to be called before any
|
679
|
+
* events on participants or messages will fire
|
680
|
+
* @internal
|
681
|
+
*/
|
682
|
+
async _subscribeStreams() {
|
683
|
+
var _a, _b;
|
684
|
+
try {
|
685
|
+
await this._subscribe();
|
686
|
+
Conversation._logger.trace("_subscribeStreams, this.entity.data=", (_a = this._entity) === null || _a === void 0 ? void 0 : _a.data);
|
687
|
+
const data = (_b = this._entity) === null || _b === void 0 ? void 0 : _b.data;
|
688
|
+
const messagesObjectName = data.messages;
|
689
|
+
const rosterObjectName = data.roster;
|
690
|
+
await Promise.all([
|
691
|
+
this._messagesEntity.subscribe(messagesObjectName),
|
692
|
+
this._participantsEntity.subscribe(rosterObjectName),
|
693
|
+
]);
|
694
|
+
}
|
695
|
+
catch (err) {
|
696
|
+
if (this._services.syncClient.connectionState !== "disconnected") {
|
697
|
+
Conversation._logger.error("Failed to subscribe on conversation objects", this.sid, err);
|
698
|
+
}
|
699
|
+
Conversation._logger.debug("ERROR: Failed to subscribe on conversation objects", this.sid, err);
|
700
|
+
throw err;
|
701
|
+
}
|
702
|
+
}
|
703
|
+
/**
|
704
|
+
* Stop listening for and firing events on this conversation.
|
705
|
+
* @internal
|
706
|
+
*/
|
707
|
+
async _unsubscribe() {
|
708
|
+
if (this._entity) {
|
709
|
+
await this._entity.close();
|
710
|
+
this._entity = null;
|
711
|
+
this._entityPromise = null;
|
712
|
+
}
|
713
|
+
return Promise.all([
|
714
|
+
this._participantsEntity.unsubscribe(),
|
715
|
+
this._messagesEntity.unsubscribe(),
|
716
|
+
]);
|
717
|
+
}
|
718
|
+
/**
|
719
|
+
* Set conversation status.
|
720
|
+
* @internal
|
721
|
+
*/
|
722
|
+
_setStatus(status, source) {
|
723
|
+
this._dataSource = source;
|
724
|
+
if (this._internalState.status === status) {
|
725
|
+
return;
|
726
|
+
}
|
727
|
+
this._internalState.status = status;
|
728
|
+
if (status === "joined") {
|
729
|
+
this._subscribeStreams().catch((err) => {
|
730
|
+
Conversation._logger.debug("ERROR while setting conversation status " + status, err);
|
731
|
+
if (this._services.syncClient.connectionState !== "disconnected") {
|
732
|
+
throw err;
|
733
|
+
}
|
734
|
+
});
|
735
|
+
return;
|
736
|
+
}
|
737
|
+
if (this._entityPromise) {
|
738
|
+
this._unsubscribe().catch((err) => {
|
739
|
+
Conversation._logger.debug("ERROR while setting conversation status " + status, err);
|
740
|
+
if (this._services.syncClient.connectionState !== "disconnected") {
|
741
|
+
throw err;
|
742
|
+
}
|
743
|
+
});
|
744
|
+
}
|
745
|
+
}
|
746
|
+
/**
|
747
|
+
* Update the local conversation object with new values.
|
748
|
+
* @internal
|
749
|
+
*/
|
750
|
+
_update(update) {
|
751
|
+
var _a, _b, _c, _d, _e;
|
752
|
+
Conversation._logger.trace("_update", update);
|
753
|
+
Conversation.preprocessUpdate(update, this.sid);
|
754
|
+
const updateReasons = new Set();
|
755
|
+
for (const key of Object.keys(update)) {
|
756
|
+
const localKey = fieldMappings[key];
|
757
|
+
if (!localKey) {
|
758
|
+
continue;
|
759
|
+
}
|
760
|
+
switch (localKey) {
|
761
|
+
case fieldMappings.status:
|
762
|
+
if (!update.status ||
|
763
|
+
update.status === "unknown" ||
|
764
|
+
this._internalState.status === update.status) {
|
765
|
+
break;
|
766
|
+
}
|
767
|
+
this._internalState.status = update.status;
|
768
|
+
updateReasons.add(localKey);
|
769
|
+
break;
|
770
|
+
case fieldMappings.attributes:
|
771
|
+
if (isEqual__default['default'](this._internalState.attributes, update.attributes)) {
|
772
|
+
break;
|
773
|
+
}
|
774
|
+
this._internalState.attributes = update.attributes;
|
775
|
+
updateReasons.add(localKey);
|
776
|
+
break;
|
777
|
+
case fieldMappings.lastConsumedMessageIndex:
|
778
|
+
if (update.lastConsumedMessageIndex === undefined ||
|
779
|
+
update.lastConsumedMessageIndex ===
|
780
|
+
this._internalState.lastReadMessageIndex) {
|
781
|
+
break;
|
782
|
+
}
|
783
|
+
this._internalState.lastReadMessageIndex =
|
784
|
+
update.lastConsumedMessageIndex;
|
785
|
+
updateReasons.add("lastReadMessageIndex");
|
786
|
+
break;
|
787
|
+
case fieldMappings.lastMessage:
|
788
|
+
if (this._internalState.lastMessage && !update.lastMessage) {
|
789
|
+
delete this._internalState.lastMessage;
|
790
|
+
updateReasons.add(localKey);
|
791
|
+
break;
|
792
|
+
}
|
793
|
+
this._internalState.lastMessage =
|
794
|
+
this._internalState.lastMessage || {};
|
795
|
+
if (((_a = update.lastMessage) === null || _a === void 0 ? void 0 : _a.index) !== undefined &&
|
796
|
+
update.lastMessage.index !== this._internalState.lastMessage.index) {
|
797
|
+
this._internalState.lastMessage.index = update.lastMessage.index;
|
798
|
+
updateReasons.add(localKey);
|
799
|
+
}
|
800
|
+
if (((_b = update.lastMessage) === null || _b === void 0 ? void 0 : _b.timestamp) !== undefined &&
|
801
|
+
((_d = (_c = this._internalState.lastMessage) === null || _c === void 0 ? void 0 : _c.dateCreated) === null || _d === void 0 ? void 0 : _d.getTime()) !==
|
802
|
+
update.lastMessage.timestamp.getTime()) {
|
803
|
+
this._internalState.lastMessage.dateCreated =
|
804
|
+
update.lastMessage.timestamp;
|
805
|
+
updateReasons.add(localKey);
|
806
|
+
}
|
807
|
+
if (isEqual__default['default'](this._internalState.lastMessage, {})) {
|
808
|
+
delete this._internalState.lastMessage;
|
809
|
+
}
|
810
|
+
break;
|
811
|
+
case fieldMappings.state:
|
812
|
+
const state = update.state || undefined;
|
813
|
+
if (state !== undefined) {
|
814
|
+
state.dateUpdated = new Date(state.dateUpdated);
|
815
|
+
}
|
816
|
+
if (isEqual__default['default'](this._internalState.state, state)) {
|
817
|
+
break;
|
818
|
+
}
|
819
|
+
this._internalState.state = state;
|
820
|
+
updateReasons.add(localKey);
|
821
|
+
break;
|
822
|
+
case fieldMappings.bindings:
|
823
|
+
if (isEqual__default['default'](this._internalState.bindings, update.bindings)) {
|
824
|
+
break;
|
825
|
+
}
|
826
|
+
this._internalState.bindings = update.bindings;
|
827
|
+
updateReasons.add(localKey);
|
828
|
+
break;
|
829
|
+
default:
|
830
|
+
const isDate = update[key] instanceof Date;
|
831
|
+
const keysMatchAsDates = isDate &&
|
832
|
+
((_e = this._internalState[localKey]) === null || _e === void 0 ? void 0 : _e.getTime()) === update[key].getTime();
|
833
|
+
const keysMatchAsNonDates = !isDate && this[localKey] === update[key];
|
834
|
+
if (keysMatchAsDates || keysMatchAsNonDates) {
|
835
|
+
break;
|
836
|
+
}
|
837
|
+
this._internalState[localKey] = update[key];
|
838
|
+
updateReasons.add(localKey);
|
839
|
+
}
|
840
|
+
}
|
841
|
+
if (updateReasons.size > 0) {
|
842
|
+
this.emit("updated", {
|
843
|
+
conversation: this,
|
844
|
+
updateReasons: [...updateReasons],
|
845
|
+
});
|
846
|
+
}
|
847
|
+
}
|
848
|
+
/**
|
849
|
+
* Handle onMessageAdded event.
|
850
|
+
*/
|
851
|
+
_onMessageAdded(message) {
|
852
|
+
for (const participant of this._participants.values()) {
|
853
|
+
if (participant.identity === message.author) {
|
854
|
+
participant._endTyping();
|
855
|
+
break;
|
856
|
+
}
|
857
|
+
}
|
858
|
+
this.emit("messageAdded", message);
|
859
|
+
}
|
860
|
+
/**
|
861
|
+
* Set last read message index.
|
862
|
+
* @param index New index to set.
|
863
|
+
*/
|
864
|
+
async _setLastReadMessageIndex(index) {
|
865
|
+
const result = await this._services.commandExecutor.mutateResource("post", `${this._configuration.links.myConversations}/${this.sid}`, {
|
866
|
+
last_read_message_index: index,
|
867
|
+
});
|
868
|
+
return result.unread_messages_count;
|
869
|
+
}
|
856
870
|
}
|
857
871
|
/**
|
858
872
|
* Fired when a participant has joined the conversation.
|
859
873
|
*
|
860
874
|
* Parameters:
|
861
|
-
* 1. {@link Participant} `participant` - participant that joined the
|
875
|
+
* 1. {@link Participant} `participant` - participant that joined the
|
876
|
+
* conversation
|
862
877
|
* @event
|
863
878
|
*/
|
864
879
|
Conversation.participantJoined = "participantJoined";
|
@@ -866,7 +881,8 @@ Conversation.participantJoined = "participantJoined";
|
|
866
881
|
* Fired when a participant has left the conversation.
|
867
882
|
*
|
868
883
|
* Parameters:
|
869
|
-
* 1. {@link Participant} `participant` - participant that left the
|
884
|
+
* 1. {@link Participant} `participant` - participant that left the
|
885
|
+
* conversation
|
870
886
|
* @event
|
871
887
|
*/
|
872
888
|
Conversation.participantLeft = "participantLeft";
|
@@ -874,9 +890,12 @@ Conversation.participantLeft = "participantLeft";
|
|
874
890
|
* Fired when data of a participant has been updated.
|
875
891
|
*
|
876
892
|
* Parameters:
|
877
|
-
* 1. object `data` - info object provided with the event. It has the
|
878
|
-
*
|
879
|
-
* * {@link
|
893
|
+
* 1. object `data` - info object provided with the event. It has the
|
894
|
+
* following properties:
|
895
|
+
* * {@link Participant} `participant` - participant that has received the
|
896
|
+
* update
|
897
|
+
* * {@link ParticipantUpdateReason}[] `updateReasons` - array of reasons
|
898
|
+
* for the update
|
880
899
|
* @event
|
881
900
|
*/
|
882
901
|
Conversation.participantUpdated = "participantUpdated";
|
@@ -900,9 +919,11 @@ Conversation.messageRemoved = "messageRemoved";
|
|
900
919
|
* Fired when data of a message has been updated.
|
901
920
|
*
|
902
921
|
* Parameters:
|
903
|
-
* 1. object `data` - info object provided with the event. It has the
|
922
|
+
* 1. object `data` - info object provided with the event. It has the
|
923
|
+
* following properties:
|
904
924
|
* * {@link Message} `message` - message that has received the update
|
905
|
-
* * {@link MessageUpdateReason}[] `updateReasons` - array of reasons for
|
925
|
+
* * {@link MessageUpdateReason}[] `updateReasons` - array of reasons for
|
926
|
+
* the update
|
906
927
|
* @event
|
907
928
|
*/
|
908
929
|
Conversation.messageUpdated = "messageUpdated";
|
@@ -910,7 +931,8 @@ Conversation.messageUpdated = "messageUpdated";
|
|
910
931
|
* Fired when a participant has stopped typing.
|
911
932
|
*
|
912
933
|
* Parameters:
|
913
|
-
* 1. {@link Participant} `participant` - the participant that has stopped
|
934
|
+
* 1. {@link Participant} `participant` - the participant that has stopped
|
935
|
+
* typing
|
914
936
|
* @event
|
915
937
|
*/
|
916
938
|
Conversation.typingEnded = "typingEnded";
|
@@ -918,7 +940,8 @@ Conversation.typingEnded = "typingEnded";
|
|
918
940
|
* Fired when a participant has started typing.
|
919
941
|
*
|
920
942
|
* Parameters:
|
921
|
-
* 1. {@link Participant} `participant` - the participant that has started
|
943
|
+
* 1. {@link Participant} `participant` - the participant that has started
|
944
|
+
* typing
|
922
945
|
* @event
|
923
946
|
*/
|
924
947
|
Conversation.typingStarted = "typingStarted";
|
@@ -926,20 +949,28 @@ Conversation.typingStarted = "typingStarted";
|
|
926
949
|
* Fired when the data of the conversation has been updated.
|
927
950
|
*
|
928
951
|
* Parameters:
|
929
|
-
* 1. object `data` - info object provided with the event. It has the
|
930
|
-
*
|
931
|
-
* * {@link
|
952
|
+
* 1. object `data` - info object provided with the event. It has the
|
953
|
+
* following properties:
|
954
|
+
* * {@link Conversation} `conversation` - conversation that has received
|
955
|
+
* the update
|
956
|
+
* * {@link ConversationUpdateReason}[] `updateReasons` - array of reasons
|
957
|
+
* for the update
|
932
958
|
* @event
|
933
959
|
*/
|
934
960
|
Conversation.updated = "updated";
|
935
961
|
/**
|
936
|
-
* Fired when the conversation was destroyed or the currently-logged-in user
|
962
|
+
* Fired when the conversation was destroyed or the currently-logged-in user
|
963
|
+
* has left private conversation.
|
937
964
|
*
|
938
965
|
* Parameters:
|
939
966
|
* 1. {@link Conversation} `conversation` - conversation that has been removed
|
940
967
|
* @event
|
941
968
|
*/
|
942
969
|
Conversation.removed = "removed";
|
970
|
+
/**
|
971
|
+
* Logger instance.
|
972
|
+
*/
|
973
|
+
Conversation._logger = logger.Logger.scope("Conversation");
|
943
974
|
tslib_es6.__decorate([
|
944
975
|
declarativeTypeValidator.validateTypesAsync(declarativeTypeValidator.nonEmptyString, attributes.optionalAttributesValidator),
|
945
976
|
tslib_es6.__metadata("design:type", Function),
|
@@ -985,9 +1016,10 @@ tslib_es6.__decorate([
|
|
985
1016
|
tslib_es6.__decorate([
|
986
1017
|
declarativeTypeValidator.validateTypesAsync([
|
987
1018
|
"string",
|
1019
|
+
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
1020
|
+
// @ts-ignore TODO: fix validateTypesAsync typing
|
1021
|
+
FormData,
|
988
1022
|
declarativeTypeValidator.literal(null),
|
989
|
-
// Wrapping it into a custom rule is necessary because the FormData class is not available on initialization.
|
990
|
-
declarativeTypeValidator.custom((value) => [value instanceof FormData, "an instance of FormData"]),
|
991
1023
|
declarativeTypeValidator.objectSchema("media options", {
|
992
1024
|
contentType: declarativeTypeValidator.nonEmptyString,
|
993
1025
|
media: declarativeTypeValidator.custom((value) => {
|
@@ -1027,7 +1059,7 @@ tslib_es6.__decorate([
|
|
1027
1059
|
tslib_es6.__metadata("design:returntype", Promise)
|
1028
1060
|
], Conversation.prototype, "updateAttributes", null);
|
1029
1061
|
tslib_es6.__decorate([
|
1030
|
-
declarativeTypeValidator.validateTypesAsync(
|
1062
|
+
declarativeTypeValidator.validateTypesAsync("string"),
|
1031
1063
|
tslib_es6.__metadata("design:type", Function),
|
1032
1064
|
tslib_es6.__metadata("design:paramtypes", [String]),
|
1033
1065
|
tslib_es6.__metadata("design:returntype", Promise)
|