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