stream-chat 9.39.0 → 9.41.0
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/dist/cjs/index.browser.js +236 -33
- package/dist/cjs/index.browser.js.map +3 -3
- package/dist/cjs/index.node.js +236 -33
- package/dist/cjs/index.node.js.map +3 -3
- package/dist/esm/index.mjs +236 -33
- package/dist/esm/index.mjs.map +3 -3
- package/dist/types/channel.d.ts +23 -2
- package/dist/types/client.d.ts +8 -3
- package/dist/types/messageComposer/attachmentManager.d.ts +3 -3
- package/dist/types/messageComposer/configuration/types.d.ts +11 -1
- package/dist/types/messageComposer/types.d.ts +2 -0
- package/dist/types/offline-support/offline_support_api.d.ts +22 -0
- package/dist/types/offline-support/types.d.ts +14 -0
- package/dist/types/offline-support/util.d.ts +11 -0
- package/package.json +1 -1
- package/src/channel.ts +25 -0
- package/src/client.ts +55 -2
- package/src/messageComposer/attachmentManager.ts +83 -16
- package/src/messageComposer/configuration/configuration.ts +1 -0
- package/src/messageComposer/configuration/types.ts +12 -0
- package/src/messageComposer/types.ts +2 -0
- package/src/offline-support/offline_support_api.ts +124 -3
- package/src/offline-support/types.ts +18 -0
- package/src/offline-support/util.ts +32 -0
|
@@ -3402,12 +3402,18 @@ var _AttachmentManager = class _AttachmentManager {
|
|
|
3402
3402
|
* Method to perform the default upload behavior without checking for custom upload functions
|
|
3403
3403
|
* to prevent recursive calls
|
|
3404
3404
|
*/
|
|
3405
|
-
this.doDefaultUploadRequest = async (fileLike) => {
|
|
3405
|
+
this.doDefaultUploadRequest = async (fileLike, options) => {
|
|
3406
|
+
const progressHandler = options?.onProgress ? (progressEvent) => {
|
|
3407
|
+
const percent = progressEvent.lengthComputable && progressEvent.total ? Math.round(progressEvent.loaded * 100 / progressEvent.total) : void 0;
|
|
3408
|
+
options.onProgress?.(percent);
|
|
3409
|
+
} : void 0;
|
|
3406
3410
|
if (isFileReference(fileLike)) {
|
|
3407
3411
|
return this.channel[isImageFile(fileLike) ? "sendImage" : "sendFile"](
|
|
3408
3412
|
fileLike.uri,
|
|
3409
3413
|
fileLike.name,
|
|
3410
|
-
fileLike.type
|
|
3414
|
+
fileLike.type,
|
|
3415
|
+
void 0,
|
|
3416
|
+
progressHandler ? { onUploadProgress: progressHandler } : void 0
|
|
3411
3417
|
);
|
|
3412
3418
|
}
|
|
3413
3419
|
const file = isFile(fileLike) ? fileLike : createFileFromBlobs({
|
|
@@ -3415,18 +3421,24 @@ var _AttachmentManager = class _AttachmentManager {
|
|
|
3415
3421
|
fileName: generateFileName(fileLike.type),
|
|
3416
3422
|
mimeType: fileLike.type
|
|
3417
3423
|
});
|
|
3418
|
-
const { duration, ...result } = await this.channel[isImageFile(fileLike) ? "sendImage" : "sendFile"](
|
|
3424
|
+
const { duration, ...result } = await this.channel[isImageFile(fileLike) ? "sendImage" : "sendFile"](
|
|
3425
|
+
file,
|
|
3426
|
+
void 0,
|
|
3427
|
+
void 0,
|
|
3428
|
+
void 0,
|
|
3429
|
+
progressHandler ? { onUploadProgress: progressHandler } : void 0
|
|
3430
|
+
);
|
|
3419
3431
|
return result;
|
|
3420
3432
|
};
|
|
3421
3433
|
/**
|
|
3422
3434
|
* todo: docs how to customize the image and file upload by overriding do
|
|
3423
3435
|
*/
|
|
3424
|
-
this.doUploadRequest = async (fileLike) => {
|
|
3436
|
+
this.doUploadRequest = async (fileLike, options) => {
|
|
3425
3437
|
const customUploadFn = this.config.doUploadRequest;
|
|
3426
3438
|
if (customUploadFn) {
|
|
3427
|
-
return await customUploadFn(fileLike);
|
|
3439
|
+
return await customUploadFn(fileLike, options);
|
|
3428
3440
|
}
|
|
3429
|
-
return this.doDefaultUploadRequest(fileLike);
|
|
3441
|
+
return this.doDefaultUploadRequest(fileLike, options);
|
|
3430
3442
|
};
|
|
3431
3443
|
// @deprecated use attachmentManager.uploadFile(file)
|
|
3432
3444
|
this.uploadAttachment = async (attachment) => {
|
|
@@ -3450,25 +3462,41 @@ var _AttachmentManager = class _AttachmentManager {
|
|
|
3450
3462
|
});
|
|
3451
3463
|
return localAttachment;
|
|
3452
3464
|
}
|
|
3453
|
-
this.
|
|
3454
|
-
|
|
3455
|
-
|
|
3456
|
-
|
|
3457
|
-
|
|
3458
|
-
|
|
3459
|
-
}
|
|
3465
|
+
const shouldTrackProgress = this.config.trackUploadProgress;
|
|
3466
|
+
const uploadingAttachment = {
|
|
3467
|
+
...attachment,
|
|
3468
|
+
localMetadata: {
|
|
3469
|
+
...attachment.localMetadata,
|
|
3470
|
+
uploadState: "uploading",
|
|
3471
|
+
...shouldTrackProgress && { uploadProgress: 0 }
|
|
3460
3472
|
}
|
|
3461
|
-
|
|
3473
|
+
};
|
|
3474
|
+
this.upsertAttachments([uploadingAttachment]);
|
|
3475
|
+
const uploadOptions = shouldTrackProgress ? {
|
|
3476
|
+
onProgress: (percent) => {
|
|
3477
|
+
this.updateAttachment({
|
|
3478
|
+
...uploadingAttachment,
|
|
3479
|
+
localMetadata: {
|
|
3480
|
+
...uploadingAttachment.localMetadata,
|
|
3481
|
+
uploadProgress: percent
|
|
3482
|
+
}
|
|
3483
|
+
});
|
|
3484
|
+
}
|
|
3485
|
+
} : void 0;
|
|
3462
3486
|
let response;
|
|
3463
3487
|
try {
|
|
3464
|
-
response = await this.doUploadRequest(
|
|
3488
|
+
response = await this.doUploadRequest(
|
|
3489
|
+
localAttachment.localMetadata.file,
|
|
3490
|
+
uploadOptions
|
|
3491
|
+
);
|
|
3465
3492
|
} catch (error) {
|
|
3466
3493
|
const reason = error instanceof Error ? error.message : "unknown error";
|
|
3467
3494
|
const failedAttachment = {
|
|
3468
3495
|
...attachment,
|
|
3469
3496
|
localMetadata: {
|
|
3470
3497
|
...attachment.localMetadata,
|
|
3471
|
-
uploadState: "failed"
|
|
3498
|
+
uploadState: "failed",
|
|
3499
|
+
uploadProgress: void 0
|
|
3472
3500
|
}
|
|
3473
3501
|
};
|
|
3474
3502
|
this.client.notifications.addError({
|
|
@@ -3494,7 +3522,8 @@ var _AttachmentManager = class _AttachmentManager {
|
|
|
3494
3522
|
...attachment,
|
|
3495
3523
|
localMetadata: {
|
|
3496
3524
|
...attachment.localMetadata,
|
|
3497
|
-
uploadState: "finished"
|
|
3525
|
+
uploadState: "finished",
|
|
3526
|
+
uploadProgress: void 0
|
|
3498
3527
|
}
|
|
3499
3528
|
};
|
|
3500
3529
|
const previewUri = uploadedAttachment.localMetadata.previewUri;
|
|
@@ -3528,18 +3557,31 @@ var _AttachmentManager = class _AttachmentManager {
|
|
|
3528
3557
|
this.upsertAttachments([attachment]);
|
|
3529
3558
|
return preUpload.state.attachment;
|
|
3530
3559
|
}
|
|
3560
|
+
const shouldTrackProgress = this.config.trackUploadProgress;
|
|
3531
3561
|
attachment = {
|
|
3532
3562
|
...attachment,
|
|
3533
3563
|
localMetadata: {
|
|
3534
3564
|
...attachment.localMetadata,
|
|
3535
|
-
uploadState: "uploading"
|
|
3565
|
+
uploadState: "uploading",
|
|
3566
|
+
...shouldTrackProgress && { uploadProgress: 0 }
|
|
3536
3567
|
}
|
|
3537
3568
|
};
|
|
3538
3569
|
this.upsertAttachments([attachment]);
|
|
3570
|
+
const uploadOptions = shouldTrackProgress ? {
|
|
3571
|
+
onProgress: (percent) => {
|
|
3572
|
+
this.updateAttachment({
|
|
3573
|
+
...attachment,
|
|
3574
|
+
localMetadata: {
|
|
3575
|
+
...attachment.localMetadata,
|
|
3576
|
+
uploadProgress: percent
|
|
3577
|
+
}
|
|
3578
|
+
});
|
|
3579
|
+
}
|
|
3580
|
+
} : void 0;
|
|
3539
3581
|
let response;
|
|
3540
3582
|
let error;
|
|
3541
3583
|
try {
|
|
3542
|
-
response = await this.doUploadRequest(file);
|
|
3584
|
+
response = await this.doUploadRequest(file, uploadOptions);
|
|
3543
3585
|
} catch (err) {
|
|
3544
3586
|
error = err instanceof Error ? err : void 0;
|
|
3545
3587
|
}
|
|
@@ -3550,7 +3592,8 @@ var _AttachmentManager = class _AttachmentManager {
|
|
|
3550
3592
|
...attachment,
|
|
3551
3593
|
localMetadata: {
|
|
3552
3594
|
...attachment.localMetadata,
|
|
3553
|
-
uploadState: error ? "failed" : "finished"
|
|
3595
|
+
uploadState: error ? "failed" : "finished",
|
|
3596
|
+
uploadProgress: void 0
|
|
3554
3597
|
}
|
|
3555
3598
|
},
|
|
3556
3599
|
error,
|
|
@@ -3718,7 +3761,8 @@ var DEFAULT_ATTACHMENT_MANAGER_CONFIG = {
|
|
|
3718
3761
|
acceptedFiles: [],
|
|
3719
3762
|
// an empty array means all files are accepted
|
|
3720
3763
|
fileUploadFilter: () => true,
|
|
3721
|
-
maxNumberOfFilesPerMessage: API_MAX_FILES_ALLOWED_PER_MESSAGE
|
|
3764
|
+
maxNumberOfFilesPerMessage: API_MAX_FILES_ALLOWED_PER_MESSAGE,
|
|
3765
|
+
trackUploadProgress: true
|
|
3722
3766
|
};
|
|
3723
3767
|
var DEFAULT_TEXT_COMPOSER_CONFIG = {
|
|
3724
3768
|
enabled: true,
|
|
@@ -8177,22 +8221,44 @@ var Channel = class {
|
|
|
8177
8221
|
}
|
|
8178
8222
|
return await this._sendMessage(message, options);
|
|
8179
8223
|
}
|
|
8180
|
-
|
|
8224
|
+
/**
|
|
8225
|
+
* Upload a file to this channel’s file endpoint (multipart). Forwards to the client’s `sendFile` implementation.
|
|
8226
|
+
*
|
|
8227
|
+
* @param uri File source: URL string, `File`, `Buffer`, or readable stream (Node).
|
|
8228
|
+
* @param name File name sent in the multipart body.
|
|
8229
|
+
* @param contentType MIME type; defaults are applied when omitted.
|
|
8230
|
+
* @param user Optional user payload appended to the form as JSON.
|
|
8231
|
+
* @param axiosRequestConfig Optional Axios per-request config, merged after upload defaults (e.g. `onUploadProgress`, `signal` from `AbortController`).
|
|
8232
|
+
* @return Promise resolving to `{ file: string, ... }` with the CDN URL.
|
|
8233
|
+
*/
|
|
8234
|
+
sendFile(uri, name, contentType, user, axiosRequestConfig) {
|
|
8181
8235
|
return this.getClient().sendFile(
|
|
8182
8236
|
`${this._channelURL()}/file`,
|
|
8183
8237
|
uri,
|
|
8184
8238
|
name,
|
|
8185
8239
|
contentType,
|
|
8186
|
-
user
|
|
8240
|
+
user,
|
|
8241
|
+
axiosRequestConfig
|
|
8187
8242
|
);
|
|
8188
8243
|
}
|
|
8189
|
-
|
|
8244
|
+
/**
|
|
8245
|
+
* Upload an image to this channel’s image endpoint (multipart). Uses the same transport as `sendFile`.
|
|
8246
|
+
*
|
|
8247
|
+
* @param uri Image source: URL string, `File`, or readable stream (Node). For `Buffer` uploads, use `sendFile` toward the channel file endpoint instead.
|
|
8248
|
+
* @param name File name sent in the multipart body.
|
|
8249
|
+
* @param contentType MIME type.
|
|
8250
|
+
* @param user Optional user payload appended to the form as JSON.
|
|
8251
|
+
* @param axiosRequestConfig Optional Axios per-request config, merged after upload defaults (e.g. `onUploadProgress`, `signal`).
|
|
8252
|
+
* @return Promise resolving to `{ file: string, ... }` with the CDN URL.
|
|
8253
|
+
*/
|
|
8254
|
+
sendImage(uri, name, contentType, user, axiosRequestConfig) {
|
|
8190
8255
|
return this.getClient().sendFile(
|
|
8191
8256
|
`${this._channelURL()}/image`,
|
|
8192
8257
|
uri,
|
|
8193
8258
|
name,
|
|
8194
8259
|
contentType,
|
|
8195
|
-
user
|
|
8260
|
+
user,
|
|
8261
|
+
axiosRequestConfig
|
|
8196
8262
|
);
|
|
8197
8263
|
}
|
|
8198
8264
|
deleteFile(url) {
|
|
@@ -12755,6 +12821,29 @@ var _ReminderManager = class _ReminderManager extends WithSubscriptions {
|
|
|
12755
12821
|
_ReminderManager.isReminderWsEventPayload = (event) => !!event.reminder && (event.type.startsWith("reminder.") || event.type === "notification.reminder_due");
|
|
12756
12822
|
var ReminderManager = _ReminderManager;
|
|
12757
12823
|
|
|
12824
|
+
// src/offline-support/util.ts
|
|
12825
|
+
var isLocalUrl = (value) => !!value && !value.startsWith("http");
|
|
12826
|
+
var isAttachmentReplayable = (attachment) => {
|
|
12827
|
+
if (!attachment || typeof attachment !== "object") {
|
|
12828
|
+
return true;
|
|
12829
|
+
}
|
|
12830
|
+
return !isLocalUrl(attachment.asset_url) && !isLocalUrl(attachment.image_url);
|
|
12831
|
+
};
|
|
12832
|
+
var isMessageUpdateReplayable = (message) => !message.attachments?.some((attachment) => !isAttachmentReplayable(attachment));
|
|
12833
|
+
var getPendingTaskChannelData = (cid) => {
|
|
12834
|
+
if (!cid) {
|
|
12835
|
+
return {};
|
|
12836
|
+
}
|
|
12837
|
+
const separatorIndex = cid.indexOf(":");
|
|
12838
|
+
if (separatorIndex <= 0 || separatorIndex === cid.length - 1) {
|
|
12839
|
+
return {};
|
|
12840
|
+
}
|
|
12841
|
+
return {
|
|
12842
|
+
channelId: cid.slice(separatorIndex + 1),
|
|
12843
|
+
channelType: cid.slice(0, separatorIndex)
|
|
12844
|
+
};
|
|
12845
|
+
};
|
|
12846
|
+
|
|
12758
12847
|
// src/client.ts
|
|
12759
12848
|
function isString2(x) {
|
|
12760
12849
|
return typeof x === "string" || x instanceof String;
|
|
@@ -13710,7 +13799,7 @@ var StreamChat = class _StreamChat {
|
|
|
13710
13799
|
delete(url, params) {
|
|
13711
13800
|
return this.doAxiosRequest("delete", url, null, { params });
|
|
13712
13801
|
}
|
|
13713
|
-
sendFile(url, uri, name, contentType, user) {
|
|
13802
|
+
sendFile(url, uri, name, contentType, user, axiosRequestConfig) {
|
|
13714
13803
|
const data = addFileToFormData(uri, name, contentType || "multipart/form-data");
|
|
13715
13804
|
if (user != null) data.append("user", JSON.stringify(user));
|
|
13716
13805
|
return this.doAxiosRequest("postForm", url, data, {
|
|
@@ -13719,7 +13808,8 @@ var StreamChat = class _StreamChat {
|
|
|
13719
13808
|
config: {
|
|
13720
13809
|
timeout: 0,
|
|
13721
13810
|
maxContentLength: Infinity,
|
|
13722
|
-
maxBodyLength: Infinity
|
|
13811
|
+
maxBodyLength: Infinity,
|
|
13812
|
+
...axiosRequestConfig
|
|
13723
13813
|
}
|
|
13724
13814
|
});
|
|
13725
13815
|
}
|
|
@@ -14847,6 +14937,30 @@ var StreamChat = class _StreamChat {
|
|
|
14847
14937
|
* @return {{ message: LocalMessage | MessageResponse }} Response that includes the message
|
|
14848
14938
|
*/
|
|
14849
14939
|
async updateMessage(message, partialUserOrUserId, options) {
|
|
14940
|
+
if (!message.id) {
|
|
14941
|
+
throw Error("Please specify the message.id when calling updateMessage");
|
|
14942
|
+
}
|
|
14943
|
+
const messageId = message.id;
|
|
14944
|
+
try {
|
|
14945
|
+
if (this.offlineDb) {
|
|
14946
|
+
return await this.offlineDb.queueTask({
|
|
14947
|
+
task: {
|
|
14948
|
+
...getPendingTaskChannelData(message.cid),
|
|
14949
|
+
messageId,
|
|
14950
|
+
payload: [message, partialUserOrUserId, options],
|
|
14951
|
+
type: "update-message"
|
|
14952
|
+
}
|
|
14953
|
+
});
|
|
14954
|
+
}
|
|
14955
|
+
} catch (error) {
|
|
14956
|
+
this.logger("error", `offlineDb:updateMessage`, {
|
|
14957
|
+
tags: ["channel", "offlineDb"],
|
|
14958
|
+
error
|
|
14959
|
+
});
|
|
14960
|
+
}
|
|
14961
|
+
return await this._updateMessage(message, partialUserOrUserId, options);
|
|
14962
|
+
}
|
|
14963
|
+
async _updateMessage(message, partialUserOrUserId, options) {
|
|
14850
14964
|
if (!message.id) {
|
|
14851
14965
|
throw Error("Please specify the message.id when calling updateMessage");
|
|
14852
14966
|
}
|
|
@@ -15124,7 +15238,7 @@ var StreamChat = class _StreamChat {
|
|
|
15124
15238
|
if (this.userAgent) {
|
|
15125
15239
|
return this.userAgent;
|
|
15126
15240
|
}
|
|
15127
|
-
const version = "9.
|
|
15241
|
+
const version = "9.41.0";
|
|
15128
15242
|
const clientBundle = "browser-cjs";
|
|
15129
15243
|
let userAgentString = "";
|
|
15130
15244
|
if (this.sdkIdentifier) {
|
|
@@ -16262,11 +16376,19 @@ var StreamChat = class _StreamChat {
|
|
|
16262
16376
|
* @param {string} [name] The name of the file
|
|
16263
16377
|
* @param {string} [contentType] The content type of the file
|
|
16264
16378
|
* @param {UserResponse} [user] Optional user information
|
|
16379
|
+
* @param {AxiosRequestConfig} [axiosRequestConfig] Optional axios config (e.g. onUploadProgress for progress tracking)
|
|
16265
16380
|
*
|
|
16266
16381
|
* @return {Promise<SendFileAPIResponse>} Response containing the file URL
|
|
16267
16382
|
*/
|
|
16268
|
-
uploadFile(uri, name, contentType, user) {
|
|
16269
|
-
return this.sendFile(
|
|
16383
|
+
uploadFile(uri, name, contentType, user, axiosRequestConfig) {
|
|
16384
|
+
return this.sendFile(
|
|
16385
|
+
`${this.baseURL}/uploads/file`,
|
|
16386
|
+
uri,
|
|
16387
|
+
name,
|
|
16388
|
+
contentType,
|
|
16389
|
+
user,
|
|
16390
|
+
axiosRequestConfig
|
|
16391
|
+
);
|
|
16270
16392
|
}
|
|
16271
16393
|
/**
|
|
16272
16394
|
* uploadImage - Uploads an image to the configured storage (defaults to Stream CDN)
|
|
@@ -16275,11 +16397,19 @@ var StreamChat = class _StreamChat {
|
|
|
16275
16397
|
* @param {string} [name] The name of the image
|
|
16276
16398
|
* @param {string} [contentType] The content type of the image
|
|
16277
16399
|
* @param {UserResponse} [user] Optional user information
|
|
16400
|
+
* @param {AxiosRequestConfig} [axiosRequestConfig] Optional axios config (e.g. onUploadProgress for progress tracking)
|
|
16278
16401
|
*
|
|
16279
16402
|
* @return {Promise<SendFileAPIResponse>} Response containing the image URL
|
|
16280
16403
|
*/
|
|
16281
|
-
uploadImage(uri, name, contentType, user) {
|
|
16282
|
-
return this.sendFile(
|
|
16404
|
+
uploadImage(uri, name, contentType, user, axiosRequestConfig) {
|
|
16405
|
+
return this.sendFile(
|
|
16406
|
+
`${this.baseURL}/uploads/image`,
|
|
16407
|
+
uri,
|
|
16408
|
+
name,
|
|
16409
|
+
contentType,
|
|
16410
|
+
user,
|
|
16411
|
+
axiosRequestConfig
|
|
16412
|
+
);
|
|
16283
16413
|
}
|
|
16284
16414
|
/**
|
|
16285
16415
|
* deleteFile - Deletes a file from the configured storage
|
|
@@ -17280,7 +17410,7 @@ var AbstractOfflineDB = class {
|
|
|
17280
17410
|
return await attemptTaskExecution();
|
|
17281
17411
|
} catch (e) {
|
|
17282
17412
|
if (!this.shouldSkipQueueingTask(e)) {
|
|
17283
|
-
await this.
|
|
17413
|
+
await this.handleAddPendingTask({ task });
|
|
17284
17414
|
}
|
|
17285
17415
|
throw e;
|
|
17286
17416
|
}
|
|
@@ -17293,19 +17423,92 @@ var AbstractOfflineDB = class {
|
|
|
17293
17423
|
* @param error
|
|
17294
17424
|
*/
|
|
17295
17425
|
this.shouldSkipQueueingTask = (error) => error?.response?.data?.code === 4 || error?.response?.data?.code === 17;
|
|
17426
|
+
this.mergeFailedMessageUpdateIntoPendingSendMessage = ({
|
|
17427
|
+
editedMessage,
|
|
17428
|
+
pendingMessage
|
|
17429
|
+
}) => {
|
|
17430
|
+
const normalizedEditedMessageSource = {
|
|
17431
|
+
...editedMessage
|
|
17432
|
+
};
|
|
17433
|
+
if (editedMessage.status === "failed") {
|
|
17434
|
+
delete normalizedEditedMessageSource.message_text_updated_at;
|
|
17435
|
+
}
|
|
17436
|
+
const normalizedEditedMessage = localMessageToNewMessagePayload(
|
|
17437
|
+
normalizedEditedMessageSource
|
|
17438
|
+
);
|
|
17439
|
+
const pendingMessageStatus = pendingMessage.status;
|
|
17440
|
+
return {
|
|
17441
|
+
...pendingMessage,
|
|
17442
|
+
...normalizedEditedMessage,
|
|
17443
|
+
...typeof pendingMessageStatus !== "undefined" ? { status: pendingMessageStatus } : {}
|
|
17444
|
+
};
|
|
17445
|
+
};
|
|
17446
|
+
this.isPendingSendMessageTask = (task) => task.type === "send-message";
|
|
17447
|
+
this.handleOfflineFailedUpdateMessagePendingTask = async (task) => {
|
|
17448
|
+
const [message] = task.payload;
|
|
17449
|
+
if (!message.id) {
|
|
17450
|
+
return;
|
|
17451
|
+
}
|
|
17452
|
+
const pendingTasks = await this.getPendingTasks({ messageId: message.id });
|
|
17453
|
+
const pendingSendMessageTask = pendingTasks.find(this.isPendingSendMessageTask);
|
|
17454
|
+
if (!pendingSendMessageTask) {
|
|
17455
|
+
return;
|
|
17456
|
+
}
|
|
17457
|
+
const updatedPendingSendMessage = this.mergeFailedMessageUpdateIntoPendingSendMessage(
|
|
17458
|
+
{
|
|
17459
|
+
editedMessage: message,
|
|
17460
|
+
pendingMessage: pendingSendMessageTask.payload[0]
|
|
17461
|
+
}
|
|
17462
|
+
);
|
|
17463
|
+
const updatedPendingTask = {
|
|
17464
|
+
...pendingSendMessageTask,
|
|
17465
|
+
payload: [updatedPendingSendMessage, pendingSendMessageTask.payload[1]]
|
|
17466
|
+
};
|
|
17467
|
+
if (pendingSendMessageTask.id) {
|
|
17468
|
+
await this.updatePendingTask({
|
|
17469
|
+
id: pendingSendMessageTask.id,
|
|
17470
|
+
task: updatedPendingTask
|
|
17471
|
+
});
|
|
17472
|
+
return;
|
|
17473
|
+
}
|
|
17474
|
+
await this.addPendingTask({
|
|
17475
|
+
...updatedPendingTask,
|
|
17476
|
+
id: void 0
|
|
17477
|
+
});
|
|
17478
|
+
};
|
|
17479
|
+
/**
|
|
17480
|
+
* Central ingress for persisting pending tasks. It either stores the task as-is
|
|
17481
|
+
* or rewrites an existing pending `send-message` task for offline edits of failed messages.
|
|
17482
|
+
*/
|
|
17483
|
+
this.handleAddPendingTask = async ({ task }) => {
|
|
17484
|
+
if (task.type === "update-message" && !isMessageUpdateReplayable(task.payload[0])) {
|
|
17485
|
+
return;
|
|
17486
|
+
}
|
|
17487
|
+
if (task.type === "update-message" && !this.client.wsConnection?.isHealthy && task.payload[0].status === "failed") {
|
|
17488
|
+
await this.handleOfflineFailedUpdateMessagePendingTask(task);
|
|
17489
|
+
return;
|
|
17490
|
+
}
|
|
17491
|
+
await this.addPendingTask(task);
|
|
17492
|
+
};
|
|
17296
17493
|
/**
|
|
17297
17494
|
* Executes a task from the list of supported pending tasks. Currently supported pending tasks
|
|
17298
17495
|
* are:
|
|
17496
|
+
* - Updating a message
|
|
17299
17497
|
* - Deleting a message
|
|
17300
17498
|
* - Sending a reaction
|
|
17301
17499
|
* - Removing a reaction
|
|
17302
17500
|
* - Sending a message
|
|
17501
|
+
* - Creating a draft
|
|
17502
|
+
* - Deleting a draft
|
|
17303
17503
|
* It will throw if we try to execute a pending task that is not supported.
|
|
17304
17504
|
* @param task - The task we want to execute
|
|
17305
17505
|
* @param isPendingTask - a control value telling us if it's an actual pending task being executed
|
|
17306
17506
|
* or delayed execution
|
|
17307
17507
|
*/
|
|
17308
17508
|
this.executeTask = async ({ task }, isPendingTask = false) => {
|
|
17509
|
+
if (task.type === "update-message") {
|
|
17510
|
+
return await this.client._updateMessage(...task.payload);
|
|
17511
|
+
}
|
|
17309
17512
|
if (task.type === "delete-message") {
|
|
17310
17513
|
return await this.client._deleteMessage(...task.payload);
|
|
17311
17514
|
}
|