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
package/dist/cjs/index.node.js
CHANGED
|
@@ -3381,12 +3381,18 @@ var _AttachmentManager = class _AttachmentManager {
|
|
|
3381
3381
|
* Method to perform the default upload behavior without checking for custom upload functions
|
|
3382
3382
|
* to prevent recursive calls
|
|
3383
3383
|
*/
|
|
3384
|
-
this.doDefaultUploadRequest = async (fileLike) => {
|
|
3384
|
+
this.doDefaultUploadRequest = async (fileLike, options) => {
|
|
3385
|
+
const progressHandler = options?.onProgress ? (progressEvent) => {
|
|
3386
|
+
const percent = progressEvent.lengthComputable && progressEvent.total ? Math.round(progressEvent.loaded * 100 / progressEvent.total) : void 0;
|
|
3387
|
+
options.onProgress?.(percent);
|
|
3388
|
+
} : void 0;
|
|
3385
3389
|
if (isFileReference(fileLike)) {
|
|
3386
3390
|
return this.channel[isImageFile(fileLike) ? "sendImage" : "sendFile"](
|
|
3387
3391
|
fileLike.uri,
|
|
3388
3392
|
fileLike.name,
|
|
3389
|
-
fileLike.type
|
|
3393
|
+
fileLike.type,
|
|
3394
|
+
void 0,
|
|
3395
|
+
progressHandler ? { onUploadProgress: progressHandler } : void 0
|
|
3390
3396
|
);
|
|
3391
3397
|
}
|
|
3392
3398
|
const file = isFile(fileLike) ? fileLike : createFileFromBlobs({
|
|
@@ -3394,18 +3400,24 @@ var _AttachmentManager = class _AttachmentManager {
|
|
|
3394
3400
|
fileName: generateFileName(fileLike.type),
|
|
3395
3401
|
mimeType: fileLike.type
|
|
3396
3402
|
});
|
|
3397
|
-
const { duration, ...result } = await this.channel[isImageFile(fileLike) ? "sendImage" : "sendFile"](
|
|
3403
|
+
const { duration, ...result } = await this.channel[isImageFile(fileLike) ? "sendImage" : "sendFile"](
|
|
3404
|
+
file,
|
|
3405
|
+
void 0,
|
|
3406
|
+
void 0,
|
|
3407
|
+
void 0,
|
|
3408
|
+
progressHandler ? { onUploadProgress: progressHandler } : void 0
|
|
3409
|
+
);
|
|
3398
3410
|
return result;
|
|
3399
3411
|
};
|
|
3400
3412
|
/**
|
|
3401
3413
|
* todo: docs how to customize the image and file upload by overriding do
|
|
3402
3414
|
*/
|
|
3403
|
-
this.doUploadRequest = async (fileLike) => {
|
|
3415
|
+
this.doUploadRequest = async (fileLike, options) => {
|
|
3404
3416
|
const customUploadFn = this.config.doUploadRequest;
|
|
3405
3417
|
if (customUploadFn) {
|
|
3406
|
-
return await customUploadFn(fileLike);
|
|
3418
|
+
return await customUploadFn(fileLike, options);
|
|
3407
3419
|
}
|
|
3408
|
-
return this.doDefaultUploadRequest(fileLike);
|
|
3420
|
+
return this.doDefaultUploadRequest(fileLike, options);
|
|
3409
3421
|
};
|
|
3410
3422
|
// @deprecated use attachmentManager.uploadFile(file)
|
|
3411
3423
|
this.uploadAttachment = async (attachment) => {
|
|
@@ -3429,25 +3441,41 @@ var _AttachmentManager = class _AttachmentManager {
|
|
|
3429
3441
|
});
|
|
3430
3442
|
return localAttachment;
|
|
3431
3443
|
}
|
|
3432
|
-
this.
|
|
3433
|
-
|
|
3434
|
-
|
|
3435
|
-
|
|
3436
|
-
|
|
3437
|
-
|
|
3438
|
-
}
|
|
3444
|
+
const shouldTrackProgress = this.config.trackUploadProgress;
|
|
3445
|
+
const uploadingAttachment = {
|
|
3446
|
+
...attachment,
|
|
3447
|
+
localMetadata: {
|
|
3448
|
+
...attachment.localMetadata,
|
|
3449
|
+
uploadState: "uploading",
|
|
3450
|
+
...shouldTrackProgress && { uploadProgress: 0 }
|
|
3439
3451
|
}
|
|
3440
|
-
|
|
3452
|
+
};
|
|
3453
|
+
this.upsertAttachments([uploadingAttachment]);
|
|
3454
|
+
const uploadOptions = shouldTrackProgress ? {
|
|
3455
|
+
onProgress: (percent) => {
|
|
3456
|
+
this.updateAttachment({
|
|
3457
|
+
...uploadingAttachment,
|
|
3458
|
+
localMetadata: {
|
|
3459
|
+
...uploadingAttachment.localMetadata,
|
|
3460
|
+
uploadProgress: percent
|
|
3461
|
+
}
|
|
3462
|
+
});
|
|
3463
|
+
}
|
|
3464
|
+
} : void 0;
|
|
3441
3465
|
let response;
|
|
3442
3466
|
try {
|
|
3443
|
-
response = await this.doUploadRequest(
|
|
3467
|
+
response = await this.doUploadRequest(
|
|
3468
|
+
localAttachment.localMetadata.file,
|
|
3469
|
+
uploadOptions
|
|
3470
|
+
);
|
|
3444
3471
|
} catch (error) {
|
|
3445
3472
|
const reason = error instanceof Error ? error.message : "unknown error";
|
|
3446
3473
|
const failedAttachment = {
|
|
3447
3474
|
...attachment,
|
|
3448
3475
|
localMetadata: {
|
|
3449
3476
|
...attachment.localMetadata,
|
|
3450
|
-
uploadState: "failed"
|
|
3477
|
+
uploadState: "failed",
|
|
3478
|
+
uploadProgress: void 0
|
|
3451
3479
|
}
|
|
3452
3480
|
};
|
|
3453
3481
|
this.client.notifications.addError({
|
|
@@ -3473,7 +3501,8 @@ var _AttachmentManager = class _AttachmentManager {
|
|
|
3473
3501
|
...attachment,
|
|
3474
3502
|
localMetadata: {
|
|
3475
3503
|
...attachment.localMetadata,
|
|
3476
|
-
uploadState: "finished"
|
|
3504
|
+
uploadState: "finished",
|
|
3505
|
+
uploadProgress: void 0
|
|
3477
3506
|
}
|
|
3478
3507
|
};
|
|
3479
3508
|
const previewUri = uploadedAttachment.localMetadata.previewUri;
|
|
@@ -3507,18 +3536,31 @@ var _AttachmentManager = class _AttachmentManager {
|
|
|
3507
3536
|
this.upsertAttachments([attachment]);
|
|
3508
3537
|
return preUpload.state.attachment;
|
|
3509
3538
|
}
|
|
3539
|
+
const shouldTrackProgress = this.config.trackUploadProgress;
|
|
3510
3540
|
attachment = {
|
|
3511
3541
|
...attachment,
|
|
3512
3542
|
localMetadata: {
|
|
3513
3543
|
...attachment.localMetadata,
|
|
3514
|
-
uploadState: "uploading"
|
|
3544
|
+
uploadState: "uploading",
|
|
3545
|
+
...shouldTrackProgress && { uploadProgress: 0 }
|
|
3515
3546
|
}
|
|
3516
3547
|
};
|
|
3517
3548
|
this.upsertAttachments([attachment]);
|
|
3549
|
+
const uploadOptions = shouldTrackProgress ? {
|
|
3550
|
+
onProgress: (percent) => {
|
|
3551
|
+
this.updateAttachment({
|
|
3552
|
+
...attachment,
|
|
3553
|
+
localMetadata: {
|
|
3554
|
+
...attachment.localMetadata,
|
|
3555
|
+
uploadProgress: percent
|
|
3556
|
+
}
|
|
3557
|
+
});
|
|
3558
|
+
}
|
|
3559
|
+
} : void 0;
|
|
3518
3560
|
let response;
|
|
3519
3561
|
let error;
|
|
3520
3562
|
try {
|
|
3521
|
-
response = await this.doUploadRequest(file);
|
|
3563
|
+
response = await this.doUploadRequest(file, uploadOptions);
|
|
3522
3564
|
} catch (err) {
|
|
3523
3565
|
error = err instanceof Error ? err : void 0;
|
|
3524
3566
|
}
|
|
@@ -3529,7 +3571,8 @@ var _AttachmentManager = class _AttachmentManager {
|
|
|
3529
3571
|
...attachment,
|
|
3530
3572
|
localMetadata: {
|
|
3531
3573
|
...attachment.localMetadata,
|
|
3532
|
-
uploadState: error ? "failed" : "finished"
|
|
3574
|
+
uploadState: error ? "failed" : "finished",
|
|
3575
|
+
uploadProgress: void 0
|
|
3533
3576
|
}
|
|
3534
3577
|
},
|
|
3535
3578
|
error,
|
|
@@ -3697,7 +3740,8 @@ var DEFAULT_ATTACHMENT_MANAGER_CONFIG = {
|
|
|
3697
3740
|
acceptedFiles: [],
|
|
3698
3741
|
// an empty array means all files are accepted
|
|
3699
3742
|
fileUploadFilter: () => true,
|
|
3700
|
-
maxNumberOfFilesPerMessage: API_MAX_FILES_ALLOWED_PER_MESSAGE
|
|
3743
|
+
maxNumberOfFilesPerMessage: API_MAX_FILES_ALLOWED_PER_MESSAGE,
|
|
3744
|
+
trackUploadProgress: true
|
|
3701
3745
|
};
|
|
3702
3746
|
var DEFAULT_TEXT_COMPOSER_CONFIG = {
|
|
3703
3747
|
enabled: true,
|
|
@@ -8156,22 +8200,44 @@ var Channel = class {
|
|
|
8156
8200
|
}
|
|
8157
8201
|
return await this._sendMessage(message, options);
|
|
8158
8202
|
}
|
|
8159
|
-
|
|
8203
|
+
/**
|
|
8204
|
+
* Upload a file to this channel’s file endpoint (multipart). Forwards to the client’s `sendFile` implementation.
|
|
8205
|
+
*
|
|
8206
|
+
* @param uri File source: URL string, `File`, `Buffer`, or readable stream (Node).
|
|
8207
|
+
* @param name File name sent in the multipart body.
|
|
8208
|
+
* @param contentType MIME type; defaults are applied when omitted.
|
|
8209
|
+
* @param user Optional user payload appended to the form as JSON.
|
|
8210
|
+
* @param axiosRequestConfig Optional Axios per-request config, merged after upload defaults (e.g. `onUploadProgress`, `signal` from `AbortController`).
|
|
8211
|
+
* @return Promise resolving to `{ file: string, ... }` with the CDN URL.
|
|
8212
|
+
*/
|
|
8213
|
+
sendFile(uri, name, contentType, user, axiosRequestConfig) {
|
|
8160
8214
|
return this.getClient().sendFile(
|
|
8161
8215
|
`${this._channelURL()}/file`,
|
|
8162
8216
|
uri,
|
|
8163
8217
|
name,
|
|
8164
8218
|
contentType,
|
|
8165
|
-
user
|
|
8219
|
+
user,
|
|
8220
|
+
axiosRequestConfig
|
|
8166
8221
|
);
|
|
8167
8222
|
}
|
|
8168
|
-
|
|
8223
|
+
/**
|
|
8224
|
+
* Upload an image to this channel’s image endpoint (multipart). Uses the same transport as `sendFile`.
|
|
8225
|
+
*
|
|
8226
|
+
* @param uri Image source: URL string, `File`, or readable stream (Node). For `Buffer` uploads, use `sendFile` toward the channel file endpoint instead.
|
|
8227
|
+
* @param name File name sent in the multipart body.
|
|
8228
|
+
* @param contentType MIME type.
|
|
8229
|
+
* @param user Optional user payload appended to the form as JSON.
|
|
8230
|
+
* @param axiosRequestConfig Optional Axios per-request config, merged after upload defaults (e.g. `onUploadProgress`, `signal`).
|
|
8231
|
+
* @return Promise resolving to `{ file: string, ... }` with the CDN URL.
|
|
8232
|
+
*/
|
|
8233
|
+
sendImage(uri, name, contentType, user, axiosRequestConfig) {
|
|
8169
8234
|
return this.getClient().sendFile(
|
|
8170
8235
|
`${this._channelURL()}/image`,
|
|
8171
8236
|
uri,
|
|
8172
8237
|
name,
|
|
8173
8238
|
contentType,
|
|
8174
|
-
user
|
|
8239
|
+
user,
|
|
8240
|
+
axiosRequestConfig
|
|
8175
8241
|
);
|
|
8176
8242
|
}
|
|
8177
8243
|
deleteFile(url) {
|
|
@@ -12734,6 +12800,29 @@ var _ReminderManager = class _ReminderManager extends WithSubscriptions {
|
|
|
12734
12800
|
_ReminderManager.isReminderWsEventPayload = (event) => !!event.reminder && (event.type.startsWith("reminder.") || event.type === "notification.reminder_due");
|
|
12735
12801
|
var ReminderManager = _ReminderManager;
|
|
12736
12802
|
|
|
12803
|
+
// src/offline-support/util.ts
|
|
12804
|
+
var isLocalUrl = (value) => !!value && !value.startsWith("http");
|
|
12805
|
+
var isAttachmentReplayable = (attachment) => {
|
|
12806
|
+
if (!attachment || typeof attachment !== "object") {
|
|
12807
|
+
return true;
|
|
12808
|
+
}
|
|
12809
|
+
return !isLocalUrl(attachment.asset_url) && !isLocalUrl(attachment.image_url);
|
|
12810
|
+
};
|
|
12811
|
+
var isMessageUpdateReplayable = (message) => !message.attachments?.some((attachment) => !isAttachmentReplayable(attachment));
|
|
12812
|
+
var getPendingTaskChannelData = (cid) => {
|
|
12813
|
+
if (!cid) {
|
|
12814
|
+
return {};
|
|
12815
|
+
}
|
|
12816
|
+
const separatorIndex = cid.indexOf(":");
|
|
12817
|
+
if (separatorIndex <= 0 || separatorIndex === cid.length - 1) {
|
|
12818
|
+
return {};
|
|
12819
|
+
}
|
|
12820
|
+
return {
|
|
12821
|
+
channelId: cid.slice(separatorIndex + 1),
|
|
12822
|
+
channelType: cid.slice(0, separatorIndex)
|
|
12823
|
+
};
|
|
12824
|
+
};
|
|
12825
|
+
|
|
12737
12826
|
// src/client.ts
|
|
12738
12827
|
function isString2(x) {
|
|
12739
12828
|
return typeof x === "string" || x instanceof String;
|
|
@@ -13689,7 +13778,7 @@ var StreamChat = class _StreamChat {
|
|
|
13689
13778
|
delete(url, params) {
|
|
13690
13779
|
return this.doAxiosRequest("delete", url, null, { params });
|
|
13691
13780
|
}
|
|
13692
|
-
sendFile(url, uri, name, contentType, user) {
|
|
13781
|
+
sendFile(url, uri, name, contentType, user, axiosRequestConfig) {
|
|
13693
13782
|
const data = addFileToFormData(uri, name, contentType || "multipart/form-data");
|
|
13694
13783
|
if (user != null) data.append("user", JSON.stringify(user));
|
|
13695
13784
|
return this.doAxiosRequest("postForm", url, data, {
|
|
@@ -13698,7 +13787,8 @@ var StreamChat = class _StreamChat {
|
|
|
13698
13787
|
config: {
|
|
13699
13788
|
timeout: 0,
|
|
13700
13789
|
maxContentLength: Infinity,
|
|
13701
|
-
maxBodyLength: Infinity
|
|
13790
|
+
maxBodyLength: Infinity,
|
|
13791
|
+
...axiosRequestConfig
|
|
13702
13792
|
}
|
|
13703
13793
|
});
|
|
13704
13794
|
}
|
|
@@ -14826,6 +14916,30 @@ var StreamChat = class _StreamChat {
|
|
|
14826
14916
|
* @return {{ message: LocalMessage | MessageResponse }} Response that includes the message
|
|
14827
14917
|
*/
|
|
14828
14918
|
async updateMessage(message, partialUserOrUserId, options) {
|
|
14919
|
+
if (!message.id) {
|
|
14920
|
+
throw Error("Please specify the message.id when calling updateMessage");
|
|
14921
|
+
}
|
|
14922
|
+
const messageId = message.id;
|
|
14923
|
+
try {
|
|
14924
|
+
if (this.offlineDb) {
|
|
14925
|
+
return await this.offlineDb.queueTask({
|
|
14926
|
+
task: {
|
|
14927
|
+
...getPendingTaskChannelData(message.cid),
|
|
14928
|
+
messageId,
|
|
14929
|
+
payload: [message, partialUserOrUserId, options],
|
|
14930
|
+
type: "update-message"
|
|
14931
|
+
}
|
|
14932
|
+
});
|
|
14933
|
+
}
|
|
14934
|
+
} catch (error) {
|
|
14935
|
+
this.logger("error", `offlineDb:updateMessage`, {
|
|
14936
|
+
tags: ["channel", "offlineDb"],
|
|
14937
|
+
error
|
|
14938
|
+
});
|
|
14939
|
+
}
|
|
14940
|
+
return await this._updateMessage(message, partialUserOrUserId, options);
|
|
14941
|
+
}
|
|
14942
|
+
async _updateMessage(message, partialUserOrUserId, options) {
|
|
14829
14943
|
if (!message.id) {
|
|
14830
14944
|
throw Error("Please specify the message.id when calling updateMessage");
|
|
14831
14945
|
}
|
|
@@ -15103,7 +15217,7 @@ var StreamChat = class _StreamChat {
|
|
|
15103
15217
|
if (this.userAgent) {
|
|
15104
15218
|
return this.userAgent;
|
|
15105
15219
|
}
|
|
15106
|
-
const version = "9.
|
|
15220
|
+
const version = "9.41.0";
|
|
15107
15221
|
const clientBundle = "node-cjs";
|
|
15108
15222
|
let userAgentString = "";
|
|
15109
15223
|
if (this.sdkIdentifier) {
|
|
@@ -16241,11 +16355,19 @@ var StreamChat = class _StreamChat {
|
|
|
16241
16355
|
* @param {string} [name] The name of the file
|
|
16242
16356
|
* @param {string} [contentType] The content type of the file
|
|
16243
16357
|
* @param {UserResponse} [user] Optional user information
|
|
16358
|
+
* @param {AxiosRequestConfig} [axiosRequestConfig] Optional axios config (e.g. onUploadProgress for progress tracking)
|
|
16244
16359
|
*
|
|
16245
16360
|
* @return {Promise<SendFileAPIResponse>} Response containing the file URL
|
|
16246
16361
|
*/
|
|
16247
|
-
uploadFile(uri, name, contentType, user) {
|
|
16248
|
-
return this.sendFile(
|
|
16362
|
+
uploadFile(uri, name, contentType, user, axiosRequestConfig) {
|
|
16363
|
+
return this.sendFile(
|
|
16364
|
+
`${this.baseURL}/uploads/file`,
|
|
16365
|
+
uri,
|
|
16366
|
+
name,
|
|
16367
|
+
contentType,
|
|
16368
|
+
user,
|
|
16369
|
+
axiosRequestConfig
|
|
16370
|
+
);
|
|
16249
16371
|
}
|
|
16250
16372
|
/**
|
|
16251
16373
|
* uploadImage - Uploads an image to the configured storage (defaults to Stream CDN)
|
|
@@ -16254,11 +16376,19 @@ var StreamChat = class _StreamChat {
|
|
|
16254
16376
|
* @param {string} [name] The name of the image
|
|
16255
16377
|
* @param {string} [contentType] The content type of the image
|
|
16256
16378
|
* @param {UserResponse} [user] Optional user information
|
|
16379
|
+
* @param {AxiosRequestConfig} [axiosRequestConfig] Optional axios config (e.g. onUploadProgress for progress tracking)
|
|
16257
16380
|
*
|
|
16258
16381
|
* @return {Promise<SendFileAPIResponse>} Response containing the image URL
|
|
16259
16382
|
*/
|
|
16260
|
-
uploadImage(uri, name, contentType, user) {
|
|
16261
|
-
return this.sendFile(
|
|
16383
|
+
uploadImage(uri, name, contentType, user, axiosRequestConfig) {
|
|
16384
|
+
return this.sendFile(
|
|
16385
|
+
`${this.baseURL}/uploads/image`,
|
|
16386
|
+
uri,
|
|
16387
|
+
name,
|
|
16388
|
+
contentType,
|
|
16389
|
+
user,
|
|
16390
|
+
axiosRequestConfig
|
|
16391
|
+
);
|
|
16262
16392
|
}
|
|
16263
16393
|
/**
|
|
16264
16394
|
* deleteFile - Deletes a file from the configured storage
|
|
@@ -17259,7 +17389,7 @@ var AbstractOfflineDB = class {
|
|
|
17259
17389
|
return await attemptTaskExecution();
|
|
17260
17390
|
} catch (e) {
|
|
17261
17391
|
if (!this.shouldSkipQueueingTask(e)) {
|
|
17262
|
-
await this.
|
|
17392
|
+
await this.handleAddPendingTask({ task });
|
|
17263
17393
|
}
|
|
17264
17394
|
throw e;
|
|
17265
17395
|
}
|
|
@@ -17272,19 +17402,92 @@ var AbstractOfflineDB = class {
|
|
|
17272
17402
|
* @param error
|
|
17273
17403
|
*/
|
|
17274
17404
|
this.shouldSkipQueueingTask = (error) => error?.response?.data?.code === 4 || error?.response?.data?.code === 17;
|
|
17405
|
+
this.mergeFailedMessageUpdateIntoPendingSendMessage = ({
|
|
17406
|
+
editedMessage,
|
|
17407
|
+
pendingMessage
|
|
17408
|
+
}) => {
|
|
17409
|
+
const normalizedEditedMessageSource = {
|
|
17410
|
+
...editedMessage
|
|
17411
|
+
};
|
|
17412
|
+
if (editedMessage.status === "failed") {
|
|
17413
|
+
delete normalizedEditedMessageSource.message_text_updated_at;
|
|
17414
|
+
}
|
|
17415
|
+
const normalizedEditedMessage = localMessageToNewMessagePayload(
|
|
17416
|
+
normalizedEditedMessageSource
|
|
17417
|
+
);
|
|
17418
|
+
const pendingMessageStatus = pendingMessage.status;
|
|
17419
|
+
return {
|
|
17420
|
+
...pendingMessage,
|
|
17421
|
+
...normalizedEditedMessage,
|
|
17422
|
+
...typeof pendingMessageStatus !== "undefined" ? { status: pendingMessageStatus } : {}
|
|
17423
|
+
};
|
|
17424
|
+
};
|
|
17425
|
+
this.isPendingSendMessageTask = (task) => task.type === "send-message";
|
|
17426
|
+
this.handleOfflineFailedUpdateMessagePendingTask = async (task) => {
|
|
17427
|
+
const [message] = task.payload;
|
|
17428
|
+
if (!message.id) {
|
|
17429
|
+
return;
|
|
17430
|
+
}
|
|
17431
|
+
const pendingTasks = await this.getPendingTasks({ messageId: message.id });
|
|
17432
|
+
const pendingSendMessageTask = pendingTasks.find(this.isPendingSendMessageTask);
|
|
17433
|
+
if (!pendingSendMessageTask) {
|
|
17434
|
+
return;
|
|
17435
|
+
}
|
|
17436
|
+
const updatedPendingSendMessage = this.mergeFailedMessageUpdateIntoPendingSendMessage(
|
|
17437
|
+
{
|
|
17438
|
+
editedMessage: message,
|
|
17439
|
+
pendingMessage: pendingSendMessageTask.payload[0]
|
|
17440
|
+
}
|
|
17441
|
+
);
|
|
17442
|
+
const updatedPendingTask = {
|
|
17443
|
+
...pendingSendMessageTask,
|
|
17444
|
+
payload: [updatedPendingSendMessage, pendingSendMessageTask.payload[1]]
|
|
17445
|
+
};
|
|
17446
|
+
if (pendingSendMessageTask.id) {
|
|
17447
|
+
await this.updatePendingTask({
|
|
17448
|
+
id: pendingSendMessageTask.id,
|
|
17449
|
+
task: updatedPendingTask
|
|
17450
|
+
});
|
|
17451
|
+
return;
|
|
17452
|
+
}
|
|
17453
|
+
await this.addPendingTask({
|
|
17454
|
+
...updatedPendingTask,
|
|
17455
|
+
id: void 0
|
|
17456
|
+
});
|
|
17457
|
+
};
|
|
17458
|
+
/**
|
|
17459
|
+
* Central ingress for persisting pending tasks. It either stores the task as-is
|
|
17460
|
+
* or rewrites an existing pending `send-message` task for offline edits of failed messages.
|
|
17461
|
+
*/
|
|
17462
|
+
this.handleAddPendingTask = async ({ task }) => {
|
|
17463
|
+
if (task.type === "update-message" && !isMessageUpdateReplayable(task.payload[0])) {
|
|
17464
|
+
return;
|
|
17465
|
+
}
|
|
17466
|
+
if (task.type === "update-message" && !this.client.wsConnection?.isHealthy && task.payload[0].status === "failed") {
|
|
17467
|
+
await this.handleOfflineFailedUpdateMessagePendingTask(task);
|
|
17468
|
+
return;
|
|
17469
|
+
}
|
|
17470
|
+
await this.addPendingTask(task);
|
|
17471
|
+
};
|
|
17275
17472
|
/**
|
|
17276
17473
|
* Executes a task from the list of supported pending tasks. Currently supported pending tasks
|
|
17277
17474
|
* are:
|
|
17475
|
+
* - Updating a message
|
|
17278
17476
|
* - Deleting a message
|
|
17279
17477
|
* - Sending a reaction
|
|
17280
17478
|
* - Removing a reaction
|
|
17281
17479
|
* - Sending a message
|
|
17480
|
+
* - Creating a draft
|
|
17481
|
+
* - Deleting a draft
|
|
17282
17482
|
* It will throw if we try to execute a pending task that is not supported.
|
|
17283
17483
|
* @param task - The task we want to execute
|
|
17284
17484
|
* @param isPendingTask - a control value telling us if it's an actual pending task being executed
|
|
17285
17485
|
* or delayed execution
|
|
17286
17486
|
*/
|
|
17287
17487
|
this.executeTask = async ({ task }, isPendingTask = false) => {
|
|
17488
|
+
if (task.type === "update-message") {
|
|
17489
|
+
return await this.client._updateMessage(...task.payload);
|
|
17490
|
+
}
|
|
17288
17491
|
if (task.type === "delete-message") {
|
|
17289
17492
|
return await this.client._deleteMessage(...task.payload);
|
|
17290
17493
|
}
|