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