stream-chat 9.51.0 → 9.52.1
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 +418 -215
- package/dist/cjs/index.browser.js.map +4 -4
- package/dist/cjs/index.node.js +427 -216
- package/dist/cjs/index.node.js.map +4 -4
- package/dist/esm/index.mjs +416 -213
- package/dist/esm/index.mjs.map +4 -4
- package/dist/types/channel.d.ts +5 -3
- package/dist/types/client.d.ts +10 -0
- package/dist/types/index.d.ts +7 -0
- package/dist/types/messageComposer/attachmentIdentity.d.ts +4 -0
- package/dist/types/messageComposer/attachmentManager.d.ts +8 -0
- package/dist/types/messageComposer/messageComposer.d.ts +13 -0
- package/dist/types/messageComposer/middleware/attachmentManager/postUpload/attachmentEnrichment.d.ts +20 -1
- package/dist/types/messageComposer/middleware/messageComposer/MessageComposerMiddlewareExecutor.d.ts +6 -1
- package/dist/types/messageComposer/middleware/messageComposer/attachments.d.ts +24 -0
- package/dist/types/messageComposer/middleware/messageComposer/types.d.ts +22 -1
- package/dist/types/messageComposer/types.d.ts +5 -0
- package/dist/types/middleware.d.ts +8 -0
- package/dist/types/uploadManager.d.ts +30 -0
- package/dist/types/utils.d.ts +29 -6
- package/package.json +1 -1
- package/src/channel.ts +42 -26
- package/src/client.ts +27 -14
- package/src/index.ts +12 -0
- package/src/messageComposer/attachmentIdentity.ts +27 -0
- package/src/messageComposer/attachmentManager.ts +61 -12
- package/src/messageComposer/messageComposer.ts +43 -8
- package/src/messageComposer/middleware/attachmentManager/postUpload/AttachmentPostUploadMiddlewareExecutor.ts +1 -1
- package/src/messageComposer/middleware/attachmentManager/postUpload/attachmentEnrichment.ts +58 -33
- package/src/messageComposer/middleware/attachmentManager/postUpload/uploadErrorHandler.ts +4 -0
- package/src/messageComposer/middleware/messageComposer/MessageComposerMiddlewareExecutor.ts +9 -0
- package/src/messageComposer/middleware/messageComposer/attachments.ts +109 -0
- package/src/messageComposer/middleware/messageComposer/types.ts +22 -1
- package/src/messageComposer/types.ts +5 -0
- package/src/messageDelivery/MessageDeliveryReporter.ts +5 -4
- package/src/middleware.ts +11 -0
- package/src/offline-support/offline_support_api.ts +4 -0
- package/src/uploadManager.ts +45 -0
- package/src/utils.ts +102 -7
package/dist/cjs/index.node.js
CHANGED
|
@@ -158,6 +158,7 @@ __export(index_exports, {
|
|
|
158
158
|
createMessageComposerStateCompositionMiddleware: () => createMessageComposerStateCompositionMiddleware,
|
|
159
159
|
createPollComposerStateMiddleware: () => createPollComposerStateMiddleware,
|
|
160
160
|
createPostUploadAttachmentEnrichmentMiddleware: () => createPostUploadAttachmentEnrichmentMiddleware,
|
|
161
|
+
createSendWithPendingUploadsAttachmentsMiddleware: () => createSendWithPendingUploadsAttachmentsMiddleware,
|
|
161
162
|
createSharedLocationCompositionMiddleware: () => createSharedLocationCompositionMiddleware,
|
|
162
163
|
createTextComposerCompositionMiddleware: () => createTextComposerCompositionMiddleware,
|
|
163
164
|
createTextComposerPreValidationMiddleware: () => createTextComposerPreValidationMiddleware,
|
|
@@ -186,6 +187,7 @@ __export(index_exports, {
|
|
|
186
187
|
getTokenizedSuggestionDisplayName: () => getTokenizedSuggestionDisplayName,
|
|
187
188
|
getTriggerCharWithToken: () => getTriggerCharWithToken,
|
|
188
189
|
gunzipPayload: () => gunzipPayload,
|
|
190
|
+
hasPending: () => hasPending,
|
|
189
191
|
insertItemWithTrigger: () => insertItemWithTrigger,
|
|
190
192
|
isAudioAttachment: () => isAudioAttachment,
|
|
191
193
|
isBlobButNotFile: () => isBlobButNotFile,
|
|
@@ -193,6 +195,7 @@ __export(index_exports, {
|
|
|
193
195
|
isFileAttachment: () => isFileAttachment,
|
|
194
196
|
isFileList: () => isFileList,
|
|
195
197
|
isFileReference: () => isFileReference,
|
|
198
|
+
isFinishedUpload: () => isFinishedUpload,
|
|
196
199
|
isGiphyAttachment: () => isGiphyAttachment,
|
|
197
200
|
isImageAttachment: () => isImageAttachment,
|
|
198
201
|
isImageFile: () => isImageFile,
|
|
@@ -205,9 +208,11 @@ __export(index_exports, {
|
|
|
205
208
|
isLocalVoiceRecordingAttachment: () => isLocalVoiceRecordingAttachment,
|
|
206
209
|
isOwnUser: () => isOwnUser,
|
|
207
210
|
isPatch: () => isPatch,
|
|
211
|
+
isPendingUpload: () => isPendingUpload,
|
|
208
212
|
isScrapedContent: () => isScrapedContent,
|
|
209
213
|
isSharedLocationResponse: () => isSharedLocationResponse,
|
|
210
214
|
isTargetedOptionTextUpdate: () => isTargetedOptionTextUpdate,
|
|
215
|
+
isUploadCancellation: () => isUploadCancellation,
|
|
211
216
|
isUploadedAttachment: () => isUploadedAttachment,
|
|
212
217
|
isVideoAttachment: () => isVideoAttachment,
|
|
213
218
|
isVoiceRecordingAttachment: () => isVoiceRecordingAttachment,
|
|
@@ -227,12 +232,15 @@ __export(index_exports, {
|
|
|
227
232
|
readFileAsArrayBuffer: () => readFileAsArrayBuffer,
|
|
228
233
|
removeDiacritics: () => removeDiacritics,
|
|
229
234
|
replaceWordWithEntity: () => replaceWordWithEntity,
|
|
235
|
+
settled: () => settled,
|
|
230
236
|
stripCommandFromText: () => stripCommandFromText,
|
|
231
237
|
stripMentionTokens: () => stripMentionTokens,
|
|
232
238
|
textIsEmpty: () => textIsEmpty,
|
|
233
239
|
timeLeftMs: () => timeLeftMs,
|
|
234
240
|
verifyAndParseWebhook: () => verifyAndParseWebhook,
|
|
235
|
-
verifySignature: () => verifySignature
|
|
241
|
+
verifySignature: () => verifySignature,
|
|
242
|
+
withCancellation: () => withCancellation,
|
|
243
|
+
withoutConcurrency: () => withoutConcurrency
|
|
236
244
|
});
|
|
237
245
|
module.exports = __toCommonJS(index_exports);
|
|
238
246
|
|
|
@@ -499,7 +507,7 @@ var ChannelBatchUpdater = class {
|
|
|
499
507
|
};
|
|
500
508
|
|
|
501
509
|
// src/client.ts
|
|
502
|
-
var
|
|
510
|
+
var import_axios4 = __toESM(require("axios"));
|
|
503
511
|
var import_https = __toESM(require("https"));
|
|
504
512
|
|
|
505
513
|
// src/utils.ts
|
|
@@ -548,6 +556,22 @@ function logChatPromiseExecution(promise, name) {
|
|
|
548
556
|
console.warn(`failed to do ${name}, ran into error: `, error);
|
|
549
557
|
});
|
|
550
558
|
}
|
|
559
|
+
var noopLogger = () => null;
|
|
560
|
+
var logError = (logger, error, event) => {
|
|
561
|
+
const message = "Unhandled error in event listener";
|
|
562
|
+
logger("error", message, { error, event });
|
|
563
|
+
if (logger === noopLogger) console.error(message, error, event);
|
|
564
|
+
};
|
|
565
|
+
var invokeEventListener = (listener, event, logger) => {
|
|
566
|
+
try {
|
|
567
|
+
const result = listener(event);
|
|
568
|
+
if (result && typeof result.then === "function") {
|
|
569
|
+
Promise.resolve(result).catch((error) => logError(logger, error, event));
|
|
570
|
+
}
|
|
571
|
+
} catch (error) {
|
|
572
|
+
logError(logger, error, event);
|
|
573
|
+
}
|
|
574
|
+
};
|
|
551
575
|
var sleep = (m) => new Promise((r) => setTimeout(r, m));
|
|
552
576
|
function isFunction(value) {
|
|
553
577
|
return typeof value === "function" || value instanceof Function || Object.prototype.toString.call(value) === "[object Function]";
|
|
@@ -595,7 +619,6 @@ var channelHasReadEvents = (channel) => {
|
|
|
595
619
|
return !(Array.isArray(ownCapabilities) && !ownCapabilities.includes("read-events"));
|
|
596
620
|
};
|
|
597
621
|
var channelTracksReadLocally = (channel) => !channelHasReadEvents(channel) && !!channel?.getClient().options.isLocalUnreadCountEnabled;
|
|
598
|
-
var userHasReadReceipts = (client) => client.user?.privacy_settings?.read_receipts?.enabled ?? true;
|
|
599
622
|
function addFileToFormData(uri, name, contentType) {
|
|
600
623
|
const data = new import_form_data.default();
|
|
601
624
|
if (isReadableStream(uri) || isBuffer(uri) || isFileWebAPI(uri) || isBlobWebAPI(uri)) {
|
|
@@ -759,6 +782,38 @@ function unformatMessage(message) {
|
|
|
759
782
|
quoted_message: toMessageResponseBase(message.quoted_message)
|
|
760
783
|
};
|
|
761
784
|
}
|
|
785
|
+
var isRemoteUrl = (url) => !!url && /^https?:\/\//i.test(url.trim());
|
|
786
|
+
var sanitizeOutgoingAttachments = ({
|
|
787
|
+
client,
|
|
788
|
+
message
|
|
789
|
+
}) => {
|
|
790
|
+
const attachments = message.attachments;
|
|
791
|
+
if (!attachments?.length) return message;
|
|
792
|
+
const unresolved = [];
|
|
793
|
+
let changed = false;
|
|
794
|
+
const sanitized = attachments.reduce((acc, attachment) => {
|
|
795
|
+
const { localMetadata, ...rest } = attachment;
|
|
796
|
+
if (!localMetadata) {
|
|
797
|
+
acc.push(attachment);
|
|
798
|
+
return acc;
|
|
799
|
+
}
|
|
800
|
+
changed = true;
|
|
801
|
+
const hasRemoteSource = isRemoteUrl(rest.asset_url) || isRemoteUrl(rest.image_url) || isRemoteUrl(rest.og_scrape_url) || isRemoteUrl(rest.title_link);
|
|
802
|
+
if (hasRemoteSource) {
|
|
803
|
+
acc.push(rest);
|
|
804
|
+
} else {
|
|
805
|
+
unresolved.push(rest);
|
|
806
|
+
}
|
|
807
|
+
return acc;
|
|
808
|
+
}, []);
|
|
809
|
+
if (unresolved.length) {
|
|
810
|
+
const text = `Dropped ${unresolved.length} attachment(s) whose upload never completed. Composing with pending uploads requires awaiting them before sending.`;
|
|
811
|
+
const extraData = { attachments: unresolved, message, tags: ["attachments"] };
|
|
812
|
+
client.logger("warn", text, extraData);
|
|
813
|
+
console.warn(text, extraData);
|
|
814
|
+
}
|
|
815
|
+
return changed ? { ...message, attachments: sanitized } : message;
|
|
816
|
+
};
|
|
762
817
|
var localMessageToNewMessagePayload = (localMessage) => {
|
|
763
818
|
const {
|
|
764
819
|
// Remove all timestamp fields and client-specific fields.
|
|
@@ -2531,6 +2586,12 @@ var CooldownTimer = class extends WithSubscriptions {
|
|
|
2531
2586
|
var isScrapedContent = (attachment) => !!attachment?.og_scrape_url || !!attachment?.title_link;
|
|
2532
2587
|
var isLocalAttachment = (attachment) => !!attachment?.localMetadata?.id;
|
|
2533
2588
|
var isLocalUploadAttachment = (attachment) => !!attachment?.localMetadata?.uploadState;
|
|
2589
|
+
var PENDING_UPLOAD_STATES = [
|
|
2590
|
+
"pending",
|
|
2591
|
+
"uploading"
|
|
2592
|
+
];
|
|
2593
|
+
var isPendingUpload = (attachment) => isLocalUploadAttachment(attachment) && PENDING_UPLOAD_STATES.includes(attachment.localMetadata.uploadState);
|
|
2594
|
+
var isFinishedUpload = (attachment) => isLocalUploadAttachment(attachment) && attachment.localMetadata.uploadState === "finished";
|
|
2534
2595
|
var isFileAttachment = (attachment, supportedVideoFormat = []) => attachment.type === "file" || !!(attachment.mime_type && supportedVideoFormat.indexOf(attachment.mime_type) === -1 && attachment.type !== "video");
|
|
2535
2596
|
var isLocalFileAttachment = (attachment) => isFileAttachment(attachment) && isLocalAttachment(attachment);
|
|
2536
2597
|
var isImageAttachment = (attachment) => attachment.type === "image" && !isScrapedContent(attachment);
|
|
@@ -2606,7 +2667,7 @@ var ensureIsLocalAttachment = (attachment) => {
|
|
|
2606
2667
|
};
|
|
2607
2668
|
|
|
2608
2669
|
// src/messageComposer/middleware/attachmentManager/postUpload/attachmentEnrichment.ts
|
|
2609
|
-
var createPostUploadAttachmentEnrichmentMiddleware = () => ({
|
|
2670
|
+
var createPostUploadAttachmentEnrichmentMiddleware = (composer) => ({
|
|
2610
2671
|
id: "stream-io/attachment-manager-middleware/post-upload-enrichment",
|
|
2611
2672
|
handlers: {
|
|
2612
2673
|
postProcess: ({
|
|
@@ -2619,9 +2680,10 @@ var createPostUploadAttachmentEnrichmentMiddleware = () => ({
|
|
|
2619
2680
|
if (error) return forward();
|
|
2620
2681
|
if (!attachment || !response) return discard();
|
|
2621
2682
|
const enrichedAttachment = { ...attachment };
|
|
2622
|
-
const previewUri = attachment.localMetadata
|
|
2623
|
-
|
|
2624
|
-
|
|
2683
|
+
const { id, previewUri } = attachment.localMetadata;
|
|
2684
|
+
const attachmentIsStillInComposer = !composer || !!composer.attachmentManager.attachmentsById[id];
|
|
2685
|
+
if (previewUri && attachmentIsStillInComposer) {
|
|
2686
|
+
if (previewUri.startsWith("blob:")) URL.revokeObjectURL?.(previewUri);
|
|
2625
2687
|
delete enrichedAttachment.localMetadata.previewUri;
|
|
2626
2688
|
}
|
|
2627
2689
|
if (isLocalImageAttachment(attachment)) {
|
|
@@ -2644,6 +2706,12 @@ var createPostUploadAttachmentEnrichmentMiddleware = () => ({
|
|
|
2644
2706
|
var withoutConcurrency = createRunner(wrapWithContinuationTracking);
|
|
2645
2707
|
var withCancellation = createRunner(wrapWithCancellation);
|
|
2646
2708
|
var pendingPromises = /* @__PURE__ */ new Map();
|
|
2709
|
+
function hasPending(tag) {
|
|
2710
|
+
return pendingPromises.has(tag);
|
|
2711
|
+
}
|
|
2712
|
+
async function settled(tag) {
|
|
2713
|
+
await pendingPromises.get(tag)?.promise;
|
|
2714
|
+
}
|
|
2647
2715
|
function createRunner(wrapper) {
|
|
2648
2716
|
return function run(tag, cb) {
|
|
2649
2717
|
const { cb: wrapped, onContinued } = wrapper(tag, cb);
|
|
@@ -2686,6 +2754,16 @@ var MiddlewareExecutor = class {
|
|
|
2686
2754
|
this.middleware = [];
|
|
2687
2755
|
this.id = generateUUIDv4();
|
|
2688
2756
|
}
|
|
2757
|
+
/**
|
|
2758
|
+
* The middleware currently installed, in execution order.
|
|
2759
|
+
*
|
|
2760
|
+
* Read-only: use `use` / `insert` / `replace` / `setOrder` / `remove` to change the chain. It
|
|
2761
|
+
* exists so components can ask what the chain is capable of - a middleware may declare
|
|
2762
|
+
* behaviour its host has to account for, and the host has no other way to find out.
|
|
2763
|
+
*/
|
|
2764
|
+
get installedMiddleware() {
|
|
2765
|
+
return this.middleware;
|
|
2766
|
+
}
|
|
2689
2767
|
use(middleware) {
|
|
2690
2768
|
this.middleware = this.middleware.concat(middleware);
|
|
2691
2769
|
return this;
|
|
@@ -2789,6 +2867,142 @@ var MiddlewareExecutor = class {
|
|
|
2789
2867
|
}
|
|
2790
2868
|
};
|
|
2791
2869
|
|
|
2870
|
+
// src/uploadManager.ts
|
|
2871
|
+
var import_axios = __toESM(require("axios"));
|
|
2872
|
+
var isUploadCancellation = (error) => import_axios.default.isCancel(error) || error instanceof Error && error.name === "AbortError";
|
|
2873
|
+
var initState = () => ({ uploads: {} });
|
|
2874
|
+
var upsertById = (uploads, record) => ({
|
|
2875
|
+
...uploads,
|
|
2876
|
+
[record.id]: { ...uploads[record.id], ...record }
|
|
2877
|
+
});
|
|
2878
|
+
var updateById = (uploads, record) => {
|
|
2879
|
+
if (!(record.id in uploads)) return null;
|
|
2880
|
+
const current = uploads[record.id];
|
|
2881
|
+
return { ...uploads, [record.id]: { ...current, ...record } };
|
|
2882
|
+
};
|
|
2883
|
+
var UploadManager = class {
|
|
2884
|
+
constructor(client) {
|
|
2885
|
+
this.client = client;
|
|
2886
|
+
this.inFlightUploads = /* @__PURE__ */ new Map();
|
|
2887
|
+
this.getUpload = (id) => this.uploads[id];
|
|
2888
|
+
/**
|
|
2889
|
+
* Clears all upload records.
|
|
2890
|
+
* Invoked when the user disconnects so a later session does not inherit stale upload state.
|
|
2891
|
+
* Aborts every in-flight upload request via its `UploadRequestOptions.abortSignal`.
|
|
2892
|
+
*/
|
|
2893
|
+
this.reset = () => {
|
|
2894
|
+
for (const { abortController } of this.inFlightUploads.values()) {
|
|
2895
|
+
abortController.abort();
|
|
2896
|
+
}
|
|
2897
|
+
this.inFlightUploads.clear();
|
|
2898
|
+
this.state.next(initState());
|
|
2899
|
+
};
|
|
2900
|
+
/**
|
|
2901
|
+
* Removes the upload record for `id` if present.
|
|
2902
|
+
* If an upload is still in progress, aborts its `UploadRequestOptions.abortSignal`.
|
|
2903
|
+
*/
|
|
2904
|
+
this.deleteUploadRecord = (id) => {
|
|
2905
|
+
const flight = this.inFlightUploads.get(id);
|
|
2906
|
+
if (flight) {
|
|
2907
|
+
this.inFlightUploads.delete(id);
|
|
2908
|
+
flight.abortController.abort();
|
|
2909
|
+
}
|
|
2910
|
+
this.state.next((current) => {
|
|
2911
|
+
if (!(id in current.uploads)) return current;
|
|
2912
|
+
const uploads = { ...current.uploads };
|
|
2913
|
+
delete uploads[id];
|
|
2914
|
+
return { ...current, uploads };
|
|
2915
|
+
});
|
|
2916
|
+
};
|
|
2917
|
+
/**
|
|
2918
|
+
* Starts an upload for `id`, or returns the existing in-flight promise if one is already running.
|
|
2919
|
+
* Uses {@link StreamChat.channel}(`channelCid`) → `messageComposer.attachmentManager.doUploadRequest`.
|
|
2920
|
+
* Resolves with that result; rejects if the upload rejects (the record is removed from state either way).
|
|
2921
|
+
*/
|
|
2922
|
+
this.upload = ({
|
|
2923
|
+
id,
|
|
2924
|
+
channelCid,
|
|
2925
|
+
file
|
|
2926
|
+
}) => {
|
|
2927
|
+
const existing = this.inFlightUploads.get(id);
|
|
2928
|
+
if (existing) return existing.promise;
|
|
2929
|
+
let resolvePromise;
|
|
2930
|
+
let rejectPromise;
|
|
2931
|
+
const promise = new Promise((resolve, reject) => {
|
|
2932
|
+
resolvePromise = resolve;
|
|
2933
|
+
rejectPromise = reject;
|
|
2934
|
+
});
|
|
2935
|
+
const abortController = new AbortController();
|
|
2936
|
+
this.inFlightUploads.set(id, { promise, abortController });
|
|
2937
|
+
void (async () => {
|
|
2938
|
+
const attachmentManager = this.resolveAttachmentManager(channelCid);
|
|
2939
|
+
const trackProgress = attachmentManager.config.trackUploadProgress;
|
|
2940
|
+
try {
|
|
2941
|
+
this.upsertUpload({
|
|
2942
|
+
uploadConfirmationPending: false,
|
|
2943
|
+
id,
|
|
2944
|
+
uploadProgress: trackProgress ? 0 : void 0
|
|
2945
|
+
});
|
|
2946
|
+
const onProgress = trackProgress ? (progress) => {
|
|
2947
|
+
this.updateUpload({
|
|
2948
|
+
id,
|
|
2949
|
+
uploadProgress: progress,
|
|
2950
|
+
// Only a number says anything about the flush, so a report without one leaves
|
|
2951
|
+
// the flag alone: `undefined` means the transport cannot measure this upload,
|
|
2952
|
+
// not that bytes were un-sent. Lowering it there would drop a UI that had
|
|
2953
|
+
// already gone indeterminate back to a determinate one with nothing to show.
|
|
2954
|
+
//
|
|
2955
|
+
// The record is removed in the `finally` below, so a record that still exists
|
|
2956
|
+
// while reporting 100% can only mean "flushed, awaiting the response".
|
|
2957
|
+
...typeof progress === "number" ? { uploadConfirmationPending: progress >= 100 } : {}
|
|
2958
|
+
});
|
|
2959
|
+
} : void 0;
|
|
2960
|
+
const uploadRequestOptions = {
|
|
2961
|
+
abortSignal: abortController.signal,
|
|
2962
|
+
...onProgress ? { onProgress } : {}
|
|
2963
|
+
};
|
|
2964
|
+
const response = await attachmentManager.doUploadRequest(
|
|
2965
|
+
file,
|
|
2966
|
+
uploadRequestOptions
|
|
2967
|
+
);
|
|
2968
|
+
resolvePromise(response);
|
|
2969
|
+
} catch (error) {
|
|
2970
|
+
rejectPromise(error);
|
|
2971
|
+
} finally {
|
|
2972
|
+
this.inFlightUploads.delete(id);
|
|
2973
|
+
this.deleteUploadRecord(id);
|
|
2974
|
+
}
|
|
2975
|
+
})();
|
|
2976
|
+
return promise;
|
|
2977
|
+
};
|
|
2978
|
+
this.upsertUpload = (record) => {
|
|
2979
|
+
this.state.partialNext({
|
|
2980
|
+
uploads: upsertById(this.uploads, record)
|
|
2981
|
+
});
|
|
2982
|
+
};
|
|
2983
|
+
this.updateUpload = (record) => {
|
|
2984
|
+
this.state.next((current) => {
|
|
2985
|
+
const nextUploads = updateById(current.uploads, record);
|
|
2986
|
+
if (!nextUploads) return current;
|
|
2987
|
+
return { ...current, uploads: nextUploads };
|
|
2988
|
+
});
|
|
2989
|
+
};
|
|
2990
|
+
this.state = new StateStore(initState());
|
|
2991
|
+
}
|
|
2992
|
+
resolveAttachmentManager(channelCid) {
|
|
2993
|
+
const colon = channelCid.indexOf(":");
|
|
2994
|
+
if (colon <= 0 || colon === channelCid.length - 1) {
|
|
2995
|
+
throw new Error(`Invalid channelCid: ${channelCid}`);
|
|
2996
|
+
}
|
|
2997
|
+
const channelType = channelCid.slice(0, colon);
|
|
2998
|
+
const channelId = channelCid.slice(colon + 1);
|
|
2999
|
+
return this.client.channel(channelType, channelId).messageComposer.attachmentManager;
|
|
3000
|
+
}
|
|
3001
|
+
get uploads() {
|
|
3002
|
+
return this.state.getLatestValue().uploads;
|
|
3003
|
+
}
|
|
3004
|
+
};
|
|
3005
|
+
|
|
2792
3006
|
// src/messageComposer/middleware/attachmentManager/postUpload/uploadErrorHandler.ts
|
|
2793
3007
|
var createUploadErrorHandlerMiddleware = (composer) => ({
|
|
2794
3008
|
id: "stream-io/attachment-manager-middleware/upload-error",
|
|
@@ -2801,6 +3015,7 @@ var createUploadErrorHandlerMiddleware = (composer) => ({
|
|
|
2801
3015
|
const { attachment, error } = state;
|
|
2802
3016
|
if (!error) return forward();
|
|
2803
3017
|
if (!attachment) return discard();
|
|
3018
|
+
if (isUploadCancellation(error)) return forward();
|
|
2804
3019
|
const reason = error instanceof Error ? error.message : "unknown error";
|
|
2805
3020
|
composer.client.notifications.addError({
|
|
2806
3021
|
message: "Error uploading attachment",
|
|
@@ -2825,7 +3040,7 @@ var AttachmentPostUploadMiddlewareExecutor = class extends MiddlewareExecutor {
|
|
|
2825
3040
|
super();
|
|
2826
3041
|
this.use([
|
|
2827
3042
|
createUploadErrorHandlerMiddleware(composer),
|
|
2828
|
-
createPostUploadAttachmentEnrichmentMiddleware()
|
|
3043
|
+
createPostUploadAttachmentEnrichmentMiddleware(composer)
|
|
2829
3044
|
]);
|
|
2830
3045
|
}
|
|
2831
3046
|
};
|
|
@@ -3273,7 +3488,7 @@ function mergeWithDiff(target, source, customizer) {
|
|
|
3273
3488
|
}
|
|
3274
3489
|
|
|
3275
3490
|
// src/messageComposer/attachmentManager.ts
|
|
3276
|
-
var
|
|
3491
|
+
var initState2 = ({
|
|
3277
3492
|
message
|
|
3278
3493
|
}) => ({
|
|
3279
3494
|
attachments: (message?.attachments ?? [])?.filter(({ og_scrape_url }) => !og_scrape_url).map((att) => {
|
|
@@ -3301,13 +3516,14 @@ var _AttachmentManager = class _AttachmentManager {
|
|
|
3301
3516
|
...attachment,
|
|
3302
3517
|
localMetadata: {
|
|
3303
3518
|
...attachment.localMetadata,
|
|
3519
|
+
uploadConfirmationPending: false,
|
|
3304
3520
|
uploadProgress: void 0,
|
|
3305
3521
|
uploadState: "failed"
|
|
3306
3522
|
}
|
|
3307
3523
|
};
|
|
3308
3524
|
};
|
|
3309
3525
|
this.initState = ({ message } = {}) => {
|
|
3310
|
-
this.state.next(
|
|
3526
|
+
this.state.next(initState2({ message }));
|
|
3311
3527
|
};
|
|
3312
3528
|
this.getSnapshot = () => {
|
|
3313
3529
|
const state = this.state.getLatestValue();
|
|
@@ -3384,8 +3600,22 @@ var _AttachmentManager = class _AttachmentManager {
|
|
|
3384
3600
|
this.state.partialNext({ attachments });
|
|
3385
3601
|
}
|
|
3386
3602
|
};
|
|
3603
|
+
/**
|
|
3604
|
+
* Releases a local preview URL the SDK minted, if it minted one.
|
|
3605
|
+
*
|
|
3606
|
+
* Only `blob:` URLs are ours to revoke: `toLocalUploadAttachment` puts a
|
|
3607
|
+
* `URL.createObjectURL` result in `previewUri` for a `File`, but for a React Native
|
|
3608
|
+
* `FileReference` it stores the caller's own native file URI, which must be left alone.
|
|
3609
|
+
*/
|
|
3610
|
+
this.revokePreviewUri = (attachment) => {
|
|
3611
|
+
const previewUri = attachment.localMetadata?.previewUri;
|
|
3612
|
+
if (previewUri?.startsWith("blob:")) URL.revokeObjectURL?.(previewUri);
|
|
3613
|
+
};
|
|
3387
3614
|
this.removeAttachments = (localAttachmentIds) => {
|
|
3388
3615
|
if (!localAttachmentIds.length) return;
|
|
3616
|
+
const removedAttachments = this.attachments.filter(
|
|
3617
|
+
(attachment) => localAttachmentIds.includes(attachment.localMetadata?.id)
|
|
3618
|
+
);
|
|
3389
3619
|
this.state.partialNext({
|
|
3390
3620
|
attachments: this.attachments.filter(
|
|
3391
3621
|
(attachment) => !localAttachmentIds.includes(attachment.localMetadata?.id)
|
|
@@ -3394,6 +3624,7 @@ var _AttachmentManager = class _AttachmentManager {
|
|
|
3394
3624
|
for (const id of localAttachmentIds) {
|
|
3395
3625
|
this.client.uploadManager.deleteUploadRecord(id);
|
|
3396
3626
|
}
|
|
3627
|
+
removedAttachments.forEach(this.revokePreviewUri);
|
|
3397
3628
|
};
|
|
3398
3629
|
this.getUploadConfigCheck = async (fileLike) => {
|
|
3399
3630
|
const client = this.channel.getClient();
|
|
@@ -3545,21 +3776,27 @@ var _AttachmentManager = class _AttachmentManager {
|
|
|
3545
3776
|
localMetadata: {
|
|
3546
3777
|
...attachment.localMetadata,
|
|
3547
3778
|
uploadState: "failed",
|
|
3548
|
-
uploadProgress: void 0
|
|
3779
|
+
uploadProgress: void 0,
|
|
3780
|
+
// `false`, not `undefined`: these updates go through `updateAttachment`, which merges
|
|
3781
|
+
// via `mergeWith` — and that skips `undefined` source values, so `undefined` would
|
|
3782
|
+
// leave a stale `true` in place.
|
|
3783
|
+
uploadConfirmationPending: false
|
|
3549
3784
|
}
|
|
3550
3785
|
};
|
|
3551
|
-
|
|
3552
|
-
|
|
3553
|
-
|
|
3554
|
-
|
|
3555
|
-
|
|
3556
|
-
|
|
3557
|
-
|
|
3558
|
-
|
|
3559
|
-
|
|
3560
|
-
|
|
3561
|
-
|
|
3562
|
-
|
|
3786
|
+
if (!isUploadCancellation(error)) {
|
|
3787
|
+
this.client.notifications.addError({
|
|
3788
|
+
message: "Error uploading attachment",
|
|
3789
|
+
origin: {
|
|
3790
|
+
emitter: "AttachmentManager",
|
|
3791
|
+
context: { attachment, failedAttachment }
|
|
3792
|
+
},
|
|
3793
|
+
options: {
|
|
3794
|
+
type: "api:attachment:upload:failed",
|
|
3795
|
+
metadata: { reason },
|
|
3796
|
+
originalError: error instanceof Error ? error : void 0
|
|
3797
|
+
}
|
|
3798
|
+
});
|
|
3799
|
+
}
|
|
3563
3800
|
this.updateAttachment(failedAttachment);
|
|
3564
3801
|
return failedAttachment;
|
|
3565
3802
|
}
|
|
@@ -3572,7 +3809,9 @@ var _AttachmentManager = class _AttachmentManager {
|
|
|
3572
3809
|
localMetadata: {
|
|
3573
3810
|
...attachment.localMetadata,
|
|
3574
3811
|
uploadState: "finished",
|
|
3575
|
-
uploadProgress: void 0
|
|
3812
|
+
uploadProgress: void 0,
|
|
3813
|
+
// See the note in the failure branch: `undefined` cannot clear through `mergeWith`.
|
|
3814
|
+
uploadConfirmationPending: false
|
|
3576
3815
|
}
|
|
3577
3816
|
};
|
|
3578
3817
|
const previewUri = uploadedAttachment.localMetadata.previewUri;
|
|
@@ -3621,7 +3860,9 @@ var _AttachmentManager = class _AttachmentManager {
|
|
|
3621
3860
|
localMetadata: {
|
|
3622
3861
|
...attachment.localMetadata,
|
|
3623
3862
|
uploadState: error ? "failed" : "finished",
|
|
3624
|
-
uploadProgress: void 0
|
|
3863
|
+
uploadProgress: void 0,
|
|
3864
|
+
// See the note in `uploadAttachment`: `undefined` cannot clear through `mergeWith`.
|
|
3865
|
+
uploadConfirmationPending: false
|
|
3625
3866
|
}
|
|
3626
3867
|
},
|
|
3627
3868
|
error,
|
|
@@ -3646,7 +3887,7 @@ var _AttachmentManager = class _AttachmentManager {
|
|
|
3646
3887
|
);
|
|
3647
3888
|
};
|
|
3648
3889
|
this.composer = composer;
|
|
3649
|
-
this.state = new StateStore(
|
|
3890
|
+
this.state = new StateStore(initState2({ message }));
|
|
3650
3891
|
this.attachmentsByIdGetterCache = { attachmentsById: {}, attachments: [] };
|
|
3651
3892
|
this.preUploadMiddlewareExecutor = new AttachmentPreUploadMiddlewareExecutor({
|
|
3652
3893
|
composer
|
|
@@ -3751,7 +3992,8 @@ var _AttachmentManager = class _AttachmentManager {
|
|
|
3751
3992
|
localMetadata: {
|
|
3752
3993
|
...attachment.localMetadata,
|
|
3753
3994
|
uploadState: "uploading",
|
|
3754
|
-
uploadProgress: this.config.trackUploadProgress ? 0 : void 0
|
|
3995
|
+
uploadProgress: this.config.trackUploadProgress ? 0 : void 0,
|
|
3996
|
+
uploadConfirmationPending: false
|
|
3755
3997
|
}
|
|
3756
3998
|
}
|
|
3757
3999
|
]);
|
|
@@ -3764,7 +4006,8 @@ var _AttachmentManager = class _AttachmentManager {
|
|
|
3764
4006
|
localMetadata: {
|
|
3765
4007
|
...attachment.localMetadata,
|
|
3766
4008
|
uploadState: "uploading",
|
|
3767
|
-
uploadProgress: nextUpload.uploadProgress
|
|
4009
|
+
uploadProgress: nextUpload.uploadProgress,
|
|
4010
|
+
uploadConfirmationPending: nextUpload.uploadConfirmationPending
|
|
3768
4011
|
}
|
|
3769
4012
|
});
|
|
3770
4013
|
}
|
|
@@ -3818,6 +4061,50 @@ var localAttachmentToAttachment = (localAttachment) => {
|
|
|
3818
4061
|
const { localMetadata, ...attachment } = localAttachment;
|
|
3819
4062
|
return attachment;
|
|
3820
4063
|
};
|
|
4064
|
+
var composeWithPendingUploads = ({
|
|
4065
|
+
composer,
|
|
4066
|
+
state
|
|
4067
|
+
}) => {
|
|
4068
|
+
const composerIsKeptAsDraft = !!composer.pollId;
|
|
4069
|
+
const relevantAttachments = composer.attachmentManager.attachments.filter(
|
|
4070
|
+
(attachment) => isFinishedUpload(attachment) || !composerIsKeptAsDraft && isPendingUpload(attachment)
|
|
4071
|
+
);
|
|
4072
|
+
const localAttachments = (state.localMessage.attachments ?? []).concat(
|
|
4073
|
+
relevantAttachments.map(
|
|
4074
|
+
(attachment) => isPendingUpload(attachment) ? attachment : localAttachmentToAttachment(attachment)
|
|
4075
|
+
)
|
|
4076
|
+
);
|
|
4077
|
+
const messageAttachments = (state.message.attachments ?? []).concat(
|
|
4078
|
+
relevantAttachments.filter(isFinishedUpload).map(localAttachmentToAttachment)
|
|
4079
|
+
);
|
|
4080
|
+
if (!localAttachments.length && !messageAttachments.length) return state;
|
|
4081
|
+
return {
|
|
4082
|
+
...state,
|
|
4083
|
+
localMessage: localAttachments.length ? {
|
|
4084
|
+
...state.localMessage,
|
|
4085
|
+
attachments: localAttachments
|
|
4086
|
+
} : state.localMessage,
|
|
4087
|
+
message: messageAttachments.length ? {
|
|
4088
|
+
...state.message,
|
|
4089
|
+
attachments: messageAttachments
|
|
4090
|
+
} : state.message
|
|
4091
|
+
};
|
|
4092
|
+
};
|
|
4093
|
+
var createSendWithPendingUploadsAttachmentsMiddleware = (composer) => ({
|
|
4094
|
+
allowsPendingUploads: true,
|
|
4095
|
+
id: "stream-io/message-composer-middleware/attachments",
|
|
4096
|
+
handlers: {
|
|
4097
|
+
compose: ({
|
|
4098
|
+
state,
|
|
4099
|
+
next,
|
|
4100
|
+
forward
|
|
4101
|
+
}) => {
|
|
4102
|
+
const { attachmentManager } = composer;
|
|
4103
|
+
if (!attachmentManager) return forward();
|
|
4104
|
+
return next(composeWithPendingUploads({ composer, state }));
|
|
4105
|
+
}
|
|
4106
|
+
}
|
|
4107
|
+
});
|
|
3821
4108
|
var createAttachmentsCompositionMiddleware = (composer) => ({
|
|
3822
4109
|
id: "stream-io/message-composer-middleware/attachments",
|
|
3823
4110
|
handlers: {
|
|
@@ -4034,7 +4321,7 @@ var getInitialMentions = (message) => {
|
|
|
4034
4321
|
};
|
|
4035
4322
|
var isSameMentionEntity = (first, second) => first.id === second.id && first.mentionType === second.mentionType;
|
|
4036
4323
|
var getMentionsFromState = (state) => state.mentions ?? state.mentionedUsers.map(userResponseToMentionEntity);
|
|
4037
|
-
var
|
|
4324
|
+
var initState3 = ({
|
|
4038
4325
|
composer,
|
|
4039
4326
|
message
|
|
4040
4327
|
}) => {
|
|
@@ -4063,7 +4350,7 @@ var initState2 = ({
|
|
|
4063
4350
|
var TextComposer = class {
|
|
4064
4351
|
constructor({ composer, message }) {
|
|
4065
4352
|
this.initState = ({ message } = {}) => {
|
|
4066
|
-
this.state.next(
|
|
4353
|
+
this.state.next(initState3({ composer: this.composer, message }));
|
|
4067
4354
|
};
|
|
4068
4355
|
this.getSnapshot = (state = this.state.getLatestValue()) => state;
|
|
4069
4356
|
this.restoreSnapshot = (snapshot) => {
|
|
@@ -4256,7 +4543,7 @@ var TextComposer = class {
|
|
|
4256
4543
|
this.commitState(output.state);
|
|
4257
4544
|
};
|
|
4258
4545
|
this.composer = composer;
|
|
4259
|
-
this.state = new StateStore(
|
|
4546
|
+
this.state = new StateStore(initState3({ composer, message }));
|
|
4260
4547
|
this.middlewareExecutor = new TextComposerMiddlewareExecutor({ composer });
|
|
4261
4548
|
}
|
|
4262
4549
|
get channel() {
|
|
@@ -5958,6 +6245,13 @@ var MessageComposerMiddlewareExecutor = class extends MiddlewareExecutor {
|
|
|
5958
6245
|
createCompositionDataCleanupMiddleware(composer)
|
|
5959
6246
|
]);
|
|
5960
6247
|
}
|
|
6248
|
+
/**
|
|
6249
|
+
* Narrows the base accessor to the composition middleware type, so callers can read the
|
|
6250
|
+
* declarations it carries (`allowsPendingUploads`) without casting.
|
|
6251
|
+
*/
|
|
6252
|
+
get installedMiddleware() {
|
|
6253
|
+
return super.installedMiddleware;
|
|
6254
|
+
}
|
|
5961
6255
|
};
|
|
5962
6256
|
var MessageDraftComposerMiddlewareExecutor = class extends MiddlewareExecutor {
|
|
5963
6257
|
constructor({ composer }) {
|
|
@@ -7072,7 +7366,7 @@ var DEFAULT_COMPOSER_CONFIG = {
|
|
|
7072
7366
|
};
|
|
7073
7367
|
|
|
7074
7368
|
// src/messageComposer/CustomDataManager.ts
|
|
7075
|
-
var
|
|
7369
|
+
var initState4 = (options) => {
|
|
7076
7370
|
if (!options)
|
|
7077
7371
|
return { message: {}, custom: {} };
|
|
7078
7372
|
return { message: {}, custom: {} };
|
|
@@ -7081,14 +7375,14 @@ var CustomDataManager = class {
|
|
|
7081
7375
|
constructor({ composer, message }) {
|
|
7082
7376
|
this.isMessageDataEqual = (nextState, previousState) => JSON.stringify(nextState.message) === JSON.stringify(previousState?.message);
|
|
7083
7377
|
this.initState = ({ message } = {}) => {
|
|
7084
|
-
this.state.next(
|
|
7378
|
+
this.state.next(initState4({ composer: this.composer, message }));
|
|
7085
7379
|
};
|
|
7086
7380
|
this.getSnapshot = () => this.state.getLatestValue();
|
|
7087
7381
|
this.restoreSnapshot = (snapshot) => {
|
|
7088
7382
|
this.state.next(snapshot);
|
|
7089
7383
|
};
|
|
7090
7384
|
this.composer = composer;
|
|
7091
|
-
this.state = new StateStore(
|
|
7385
|
+
this.state = new StateStore(initState4({ composer, message }));
|
|
7092
7386
|
}
|
|
7093
7387
|
get customMessageData() {
|
|
7094
7388
|
return this.state.getLatestValue().message;
|
|
@@ -7124,7 +7418,7 @@ var LinkPreviewStatus = /* @__PURE__ */ ((LinkPreviewStatus2) => {
|
|
|
7124
7418
|
return LinkPreviewStatus2;
|
|
7125
7419
|
})(LinkPreviewStatus || {});
|
|
7126
7420
|
var linkPreviewArrayToMap = (linkPreviews) => new Map(linkPreviews.map((linkPreview) => [linkPreview.og_scrape_url, linkPreview]));
|
|
7127
|
-
var
|
|
7421
|
+
var initState5 = ({
|
|
7128
7422
|
message
|
|
7129
7423
|
}) => message ? {
|
|
7130
7424
|
previews: message.attachments?.reduce((acc, attachment) => {
|
|
@@ -7143,7 +7437,7 @@ var _LinkPreviewsManager = class _LinkPreviewsManager {
|
|
|
7143
7437
|
this.shouldDiscardEnrichQueries = false;
|
|
7144
7438
|
this.initState = ({ message } = {}) => {
|
|
7145
7439
|
this.cancelURLEnrichment();
|
|
7146
|
-
this.state.next(
|
|
7440
|
+
this.state.next(initState5({ message: this.enabled ? message : void 0 }));
|
|
7147
7441
|
};
|
|
7148
7442
|
this.getSnapshot = () => this.state.getLatestValue();
|
|
7149
7443
|
this.restoreSnapshot = (snapshot) => {
|
|
@@ -7246,7 +7540,7 @@ var _LinkPreviewsManager = class _LinkPreviewsManager {
|
|
|
7246
7540
|
};
|
|
7247
7541
|
this.composer = composer;
|
|
7248
7542
|
this.state = new StateStore(
|
|
7249
|
-
|
|
7543
|
+
initState5({ message: this.enabled ? message : void 0 })
|
|
7250
7544
|
);
|
|
7251
7545
|
this.findAndEnrichUrls = debounce(
|
|
7252
7546
|
this._findAndEnrichUrls.bind(this),
|
|
@@ -7334,7 +7628,7 @@ var LinkPreviewsManager = _LinkPreviewsManager;
|
|
|
7334
7628
|
|
|
7335
7629
|
// src/messageComposer/LocationComposer.ts
|
|
7336
7630
|
var MIN_LIVE_LOCATION_SHARE_DURATION = 60 * 1e3;
|
|
7337
|
-
var
|
|
7631
|
+
var initState6 = ({
|
|
7338
7632
|
message
|
|
7339
7633
|
}) => ({
|
|
7340
7634
|
location: message?.shared_location ?? null
|
|
@@ -7342,7 +7636,7 @@ var initState5 = ({
|
|
|
7342
7636
|
var LocationComposer = class {
|
|
7343
7637
|
constructor({ composer, message }) {
|
|
7344
7638
|
this.initState = ({ message } = {}) => {
|
|
7345
|
-
this.state.next(
|
|
7639
|
+
this.state.next(initState6({ message }));
|
|
7346
7640
|
};
|
|
7347
7641
|
this.getSnapshot = () => this.state.getLatestValue();
|
|
7348
7642
|
this.restoreSnapshot = (snapshot) => {
|
|
@@ -7360,7 +7654,7 @@ var LocationComposer = class {
|
|
|
7360
7654
|
});
|
|
7361
7655
|
};
|
|
7362
7656
|
this.composer = composer;
|
|
7363
|
-
this.state = new StateStore(
|
|
7657
|
+
this.state = new StateStore(initState6({ message }));
|
|
7364
7658
|
this._deviceId = this.config.getDeviceId();
|
|
7365
7659
|
}
|
|
7366
7660
|
get config() {
|
|
@@ -8081,7 +8375,7 @@ var initEditingAuditState = (composition) => {
|
|
|
8081
8375
|
}
|
|
8082
8376
|
};
|
|
8083
8377
|
};
|
|
8084
|
-
var
|
|
8378
|
+
var initState7 = (composition) => {
|
|
8085
8379
|
if (!composition) {
|
|
8086
8380
|
return {
|
|
8087
8381
|
draftId: null,
|
|
@@ -8168,7 +8462,7 @@ var _MessageComposer = class _MessageComposer extends WithSubscriptions {
|
|
|
8168
8462
|
this.textComposer.initState({ message });
|
|
8169
8463
|
this.pollComposer.initState();
|
|
8170
8464
|
this.customDataManager.initState({ message });
|
|
8171
|
-
this.state.next(
|
|
8465
|
+
this.state.next(initState7(composition));
|
|
8172
8466
|
};
|
|
8173
8467
|
this.initStateFromChannelResponse = (channelApiResponse) => {
|
|
8174
8468
|
if (this.channel.cid !== channelApiResponse.channel.cid) {
|
|
@@ -8634,7 +8928,7 @@ var _MessageComposer = class _MessageComposer extends WithSubscriptions {
|
|
|
8634
8928
|
this.editingAuditState = new StateStore(
|
|
8635
8929
|
this.initEditingAuditState(composition)
|
|
8636
8930
|
);
|
|
8637
|
-
this.state = new StateStore(
|
|
8931
|
+
this.state = new StateStore(initState7(composition));
|
|
8638
8932
|
this.compositionMiddlewareExecutor = new MessageComposerMiddlewareExecutor({
|
|
8639
8933
|
composer: this
|
|
8640
8934
|
});
|
|
@@ -8713,8 +9007,32 @@ var _MessageComposer = class _MessageComposer extends WithSubscriptions {
|
|
|
8713
9007
|
const currentCommand = this.textComposer.command;
|
|
8714
9008
|
return !currentCommand || this.validateCommandSendability(currentCommand).ready;
|
|
8715
9009
|
}
|
|
9010
|
+
/**
|
|
9011
|
+
* Whether the installed composition middleware composes messages whose uploads are still in
|
|
9012
|
+
* flight — see `MessageCompositionMiddleware.allowsPendingUploads`.
|
|
9013
|
+
*
|
|
9014
|
+
* Derived from the chain rather than from config, so there is exactly one switch: the UI SDK
|
|
9015
|
+
* that implements the rest of the flow installs the middleware, and everything that has to
|
|
9016
|
+
* follow from that (starting with {@link hasSendableData}) follows on its own.
|
|
9017
|
+
*
|
|
9018
|
+
* **Temporary API.** In v10 sending with pending uploads becomes part of the composer
|
|
9019
|
+
* configuration (`MessageComposerConfig`, set through `updateConfig`), and this getter,
|
|
9020
|
+
* together with the middleware declaration it reads, is replaced by that config field.
|
|
9021
|
+
*/
|
|
9022
|
+
get allowsPendingUploads() {
|
|
9023
|
+
return this.compositionMiddlewareExecutor.installedMiddleware.some(
|
|
9024
|
+
(middleware) => middleware.allowsPendingUploads
|
|
9025
|
+
);
|
|
9026
|
+
}
|
|
8716
9027
|
get hasSendableData() {
|
|
8717
|
-
|
|
9028
|
+
if (!this.isCommandSendable) return false;
|
|
9029
|
+
if (this.allowsPendingUploads) {
|
|
9030
|
+
const hasSendableAttachment = this.attachmentManager.attachments.some(
|
|
9031
|
+
(attachment) => isFinishedUpload(attachment) || isPendingUpload(attachment)
|
|
9032
|
+
);
|
|
9033
|
+
return !!(!this.textComposer.textIsEmpty || hasSendableAttachment || this.pollId || this.locationComposer.validLocation);
|
|
9034
|
+
}
|
|
9035
|
+
return !!(!this.attachmentManager.uploadsInProgressCount && (!this.textComposer.textIsEmpty || this.attachmentManager.successfulUploadsCount > 0) || this.pollId || !!this.locationComposer.validLocation);
|
|
8718
9036
|
}
|
|
8719
9037
|
get compositionIsEmpty() {
|
|
8720
9038
|
return !this.quotedMessage && this.contentIsEmpty;
|
|
@@ -8853,7 +9171,6 @@ var MessageDeliveryReporter = class _MessageDeliveryReporter {
|
|
|
8853
9171
|
* @param options
|
|
8854
9172
|
*/
|
|
8855
9173
|
this.markRead = async (collection, options) => {
|
|
8856
|
-
if (!userHasReadReceipts(this.client)) return null;
|
|
8857
9174
|
let result = null;
|
|
8858
9175
|
if (isChannel(collection)) {
|
|
8859
9176
|
result = await collection.markAsReadRequest(options);
|
|
@@ -8863,7 +9180,7 @@ var MessageDeliveryReporter = class _MessageDeliveryReporter {
|
|
|
8863
9180
|
thread_id: collection.id
|
|
8864
9181
|
});
|
|
8865
9182
|
}
|
|
8866
|
-
this.removeCandidateFor(collection);
|
|
9183
|
+
if (result) this.removeCandidateFor(collection);
|
|
8867
9184
|
return result;
|
|
8868
9185
|
};
|
|
8869
9186
|
/**
|
|
@@ -9248,18 +9565,14 @@ var Channel = class {
|
|
|
9248
9565
|
return await this.query(defaultOptions, "latest");
|
|
9249
9566
|
};
|
|
9250
9567
|
this._callChannelListeners = (event) => {
|
|
9251
|
-
const
|
|
9252
|
-
|
|
9253
|
-
|
|
9254
|
-
|
|
9255
|
-
}
|
|
9256
|
-
if (channel.listeners[event.type]) {
|
|
9257
|
-
listeners.push(...channel.listeners[event.type]);
|
|
9258
|
-
}
|
|
9568
|
+
const listeners = [
|
|
9569
|
+
...this.listeners.all ?? [],
|
|
9570
|
+
...this.listeners[event.type] ?? []
|
|
9571
|
+
];
|
|
9572
|
+
const { logger } = this._client;
|
|
9259
9573
|
for (const listener of listeners) {
|
|
9260
|
-
if (typeof listener
|
|
9261
|
-
|
|
9262
|
-
}
|
|
9574
|
+
if (typeof listener === "string") continue;
|
|
9575
|
+
invokeEventListener(listener, event, logger);
|
|
9263
9576
|
}
|
|
9264
9577
|
};
|
|
9265
9578
|
/**
|
|
@@ -9341,14 +9654,16 @@ var Channel = class {
|
|
|
9341
9654
|
*
|
|
9342
9655
|
* @return {Promise<SendMessageAPIResponse>} The Server Response
|
|
9343
9656
|
*/
|
|
9344
|
-
async _sendMessage(
|
|
9345
|
-
|
|
9346
|
-
|
|
9347
|
-
|
|
9348
|
-
|
|
9349
|
-
|
|
9350
|
-
|
|
9351
|
-
|
|
9657
|
+
async _sendMessage(rawMessage, options) {
|
|
9658
|
+
const client = this.getClient();
|
|
9659
|
+
const message = sanitizeOutgoingAttachments({
|
|
9660
|
+
client,
|
|
9661
|
+
message: rawMessage
|
|
9662
|
+
});
|
|
9663
|
+
return await client.post(this._channelURL() + "/message", {
|
|
9664
|
+
message,
|
|
9665
|
+
...options
|
|
9666
|
+
});
|
|
9352
9667
|
}
|
|
9353
9668
|
async sendMessage(message, options) {
|
|
9354
9669
|
try {
|
|
@@ -10171,14 +10486,15 @@ var Channel = class {
|
|
|
10171
10486
|
return await this.getClient().messageDeliveryReporter.markRead(this, data);
|
|
10172
10487
|
}
|
|
10173
10488
|
/**
|
|
10174
|
-
* markReadRequest - Send the mark read event for this user, only works if the `read_events` setting is
|
|
10489
|
+
* markReadRequest - Send the mark read event for this user, only works if the `read_events` setting is
|
|
10490
|
+
* enabled and the user holds the `read-events` capability on this channel
|
|
10175
10491
|
*
|
|
10176
10492
|
* @param {MarkReadOptions} data
|
|
10177
10493
|
* @return {Promise<EventAPIResponse | null>} Description
|
|
10178
10494
|
*/
|
|
10179
10495
|
async markAsReadRequest(data = {}) {
|
|
10180
10496
|
this._checkInitialized();
|
|
10181
|
-
if (!this.
|
|
10497
|
+
if (!this.getClient()._isUsingServerAuth() && (!this.getConfig()?.read_events || !channelHasReadEvents(this))) {
|
|
10182
10498
|
return null;
|
|
10183
10499
|
}
|
|
10184
10500
|
return await this.getClient().post(this._channelURL() + "/read", {
|
|
@@ -10186,14 +10502,15 @@ var Channel = class {
|
|
|
10186
10502
|
});
|
|
10187
10503
|
}
|
|
10188
10504
|
/**
|
|
10189
|
-
* markUnread - Mark the channel as unread from messageID, only works if the `read_events` setting is
|
|
10505
|
+
* markUnread - Mark the channel as unread from messageID, only works if the `read_events` setting is
|
|
10506
|
+
* enabled and the user holds the `read-events` capability on this channel
|
|
10190
10507
|
*
|
|
10191
10508
|
* @param {MarkUnreadOptions} data
|
|
10192
10509
|
* @return {APIResponse} An API response
|
|
10193
10510
|
*/
|
|
10194
10511
|
async markUnread(data) {
|
|
10195
10512
|
this._checkInitialized();
|
|
10196
|
-
if (!this.
|
|
10513
|
+
if (!this.getClient()._isUsingServerAuth() && (!this.getConfig()?.read_events || !channelHasReadEvents(this))) {
|
|
10197
10514
|
return Promise.resolve(null);
|
|
10198
10515
|
}
|
|
10199
10516
|
return await this.getClient().post(this._channelURL() + "/unread", {
|
|
@@ -10799,6 +11116,7 @@ var Channel = class {
|
|
|
10799
11116
|
// delivery-report network sync below is skipped for it.
|
|
10800
11117
|
case "message.read_locally":
|
|
10801
11118
|
case "message.read":
|
|
11119
|
+
if (event.thread) break;
|
|
10802
11120
|
if (event.user?.id && event.created_at) {
|
|
10803
11121
|
const previousReadState = channelState.read[event.user.id];
|
|
10804
11122
|
channelState.read[event.user.id] = {
|
|
@@ -11248,7 +11566,7 @@ var ClientState = class {
|
|
|
11248
11566
|
var import_isomorphic_ws = __toESM(require("isomorphic-ws"));
|
|
11249
11567
|
|
|
11250
11568
|
// src/insights.ts
|
|
11251
|
-
var
|
|
11569
|
+
var import_axios2 = __toESM(require("axios"));
|
|
11252
11570
|
var InsightMetrics = class {
|
|
11253
11571
|
constructor() {
|
|
11254
11572
|
this.connectionStartTimestamp = null;
|
|
@@ -11261,7 +11579,7 @@ var postInsights = async (insightType, insights) => {
|
|
|
11261
11579
|
const maxAttempts = 3;
|
|
11262
11580
|
for (let i = 0; i < maxAttempts; i++) {
|
|
11263
11581
|
try {
|
|
11264
|
-
await
|
|
11582
|
+
await import_axios2.default.post(
|
|
11265
11583
|
`https://chat-insights.getstream.io/insights/${insightType}`,
|
|
11266
11584
|
insights
|
|
11267
11585
|
);
|
|
@@ -11769,131 +12087,6 @@ var StableWSConnection = class {
|
|
|
11769
12087
|
}
|
|
11770
12088
|
};
|
|
11771
12089
|
|
|
11772
|
-
// src/uploadManager.ts
|
|
11773
|
-
var initState7 = () => ({ uploads: {} });
|
|
11774
|
-
var upsertById = (uploads, record) => ({
|
|
11775
|
-
...uploads,
|
|
11776
|
-
[record.id]: { ...uploads[record.id], ...record }
|
|
11777
|
-
});
|
|
11778
|
-
var updateById = (uploads, record) => {
|
|
11779
|
-
if (!(record.id in uploads)) return null;
|
|
11780
|
-
const current = uploads[record.id];
|
|
11781
|
-
return { ...uploads, [record.id]: { ...current, ...record } };
|
|
11782
|
-
};
|
|
11783
|
-
var UploadManager = class {
|
|
11784
|
-
constructor(client) {
|
|
11785
|
-
this.client = client;
|
|
11786
|
-
this.inFlightUploads = /* @__PURE__ */ new Map();
|
|
11787
|
-
this.getUpload = (id) => this.uploads[id];
|
|
11788
|
-
/**
|
|
11789
|
-
* Clears all upload records.
|
|
11790
|
-
* Invoked when the user disconnects so a later session does not inherit stale upload state.
|
|
11791
|
-
* Aborts every in-flight upload request via its `UploadRequestOptions.abortSignal`.
|
|
11792
|
-
*/
|
|
11793
|
-
this.reset = () => {
|
|
11794
|
-
for (const { abortController } of this.inFlightUploads.values()) {
|
|
11795
|
-
abortController.abort();
|
|
11796
|
-
}
|
|
11797
|
-
this.inFlightUploads.clear();
|
|
11798
|
-
this.state.next(initState7());
|
|
11799
|
-
};
|
|
11800
|
-
/**
|
|
11801
|
-
* Removes the upload record for `id` if present.
|
|
11802
|
-
* If an upload is still in progress, aborts its `UploadRequestOptions.abortSignal`.
|
|
11803
|
-
*/
|
|
11804
|
-
this.deleteUploadRecord = (id) => {
|
|
11805
|
-
const flight = this.inFlightUploads.get(id);
|
|
11806
|
-
if (flight) {
|
|
11807
|
-
this.inFlightUploads.delete(id);
|
|
11808
|
-
flight.abortController.abort();
|
|
11809
|
-
}
|
|
11810
|
-
this.state.next((current) => {
|
|
11811
|
-
if (!(id in current.uploads)) return current;
|
|
11812
|
-
const uploads = { ...current.uploads };
|
|
11813
|
-
delete uploads[id];
|
|
11814
|
-
return { ...current, uploads };
|
|
11815
|
-
});
|
|
11816
|
-
};
|
|
11817
|
-
/**
|
|
11818
|
-
* Starts an upload for `id`, or returns the existing in-flight promise if one is already running.
|
|
11819
|
-
* Uses {@link StreamChat.channel}(`channelCid`) → `messageComposer.attachmentManager.doUploadRequest`.
|
|
11820
|
-
* Resolves with that result; rejects if the upload rejects (the record is removed from state either way).
|
|
11821
|
-
*/
|
|
11822
|
-
this.upload = ({
|
|
11823
|
-
id,
|
|
11824
|
-
channelCid,
|
|
11825
|
-
file
|
|
11826
|
-
}) => {
|
|
11827
|
-
const existing = this.inFlightUploads.get(id);
|
|
11828
|
-
if (existing) return existing.promise;
|
|
11829
|
-
let resolvePromise;
|
|
11830
|
-
let rejectPromise;
|
|
11831
|
-
const promise = new Promise((resolve, reject) => {
|
|
11832
|
-
resolvePromise = resolve;
|
|
11833
|
-
rejectPromise = reject;
|
|
11834
|
-
});
|
|
11835
|
-
const abortController = new AbortController();
|
|
11836
|
-
this.inFlightUploads.set(id, { promise, abortController });
|
|
11837
|
-
void (async () => {
|
|
11838
|
-
const attachmentManager = this.resolveAttachmentManager(channelCid);
|
|
11839
|
-
const trackProgress = attachmentManager.config.trackUploadProgress;
|
|
11840
|
-
try {
|
|
11841
|
-
this.upsertUpload({
|
|
11842
|
-
id,
|
|
11843
|
-
uploadProgress: trackProgress ? 0 : void 0
|
|
11844
|
-
});
|
|
11845
|
-
const onProgress = trackProgress ? (progress) => {
|
|
11846
|
-
this.updateUpload({
|
|
11847
|
-
id,
|
|
11848
|
-
uploadProgress: progress
|
|
11849
|
-
});
|
|
11850
|
-
} : void 0;
|
|
11851
|
-
const uploadRequestOptions = {
|
|
11852
|
-
abortSignal: abortController.signal,
|
|
11853
|
-
...onProgress ? { onProgress } : {}
|
|
11854
|
-
};
|
|
11855
|
-
const response = await attachmentManager.doUploadRequest(
|
|
11856
|
-
file,
|
|
11857
|
-
uploadRequestOptions
|
|
11858
|
-
);
|
|
11859
|
-
resolvePromise(response);
|
|
11860
|
-
} catch (error) {
|
|
11861
|
-
rejectPromise(error);
|
|
11862
|
-
} finally {
|
|
11863
|
-
this.inFlightUploads.delete(id);
|
|
11864
|
-
this.deleteUploadRecord(id);
|
|
11865
|
-
}
|
|
11866
|
-
})();
|
|
11867
|
-
return promise;
|
|
11868
|
-
};
|
|
11869
|
-
this.upsertUpload = (record) => {
|
|
11870
|
-
this.state.partialNext({
|
|
11871
|
-
uploads: upsertById(this.uploads, record)
|
|
11872
|
-
});
|
|
11873
|
-
};
|
|
11874
|
-
this.updateUpload = (record) => {
|
|
11875
|
-
this.state.next((current) => {
|
|
11876
|
-
const nextUploads = updateById(current.uploads, record);
|
|
11877
|
-
if (!nextUploads) return current;
|
|
11878
|
-
return { ...current, uploads: nextUploads };
|
|
11879
|
-
});
|
|
11880
|
-
};
|
|
11881
|
-
this.state = new StateStore(initState7());
|
|
11882
|
-
}
|
|
11883
|
-
resolveAttachmentManager(channelCid) {
|
|
11884
|
-
const colon = channelCid.indexOf(":");
|
|
11885
|
-
if (colon <= 0 || colon === channelCid.length - 1) {
|
|
11886
|
-
throw new Error(`Invalid channelCid: ${channelCid}`);
|
|
11887
|
-
}
|
|
11888
|
-
const channelType = channelCid.slice(0, colon);
|
|
11889
|
-
const channelId = channelCid.slice(colon + 1);
|
|
11890
|
-
return this.client.channel(channelType, channelId).messageComposer.attachmentManager;
|
|
11891
|
-
}
|
|
11892
|
-
get uploads() {
|
|
11893
|
-
return this.state.getLatestValue().uploads;
|
|
11894
|
-
}
|
|
11895
|
-
};
|
|
11896
|
-
|
|
11897
12090
|
// src/signing.ts
|
|
11898
12091
|
var import_jsonwebtoken = __toESM(require("jsonwebtoken"));
|
|
11899
12092
|
var import_crypto = __toESM(require("crypto"));
|
|
@@ -12152,7 +12345,7 @@ var TokenManager = class {
|
|
|
12152
12345
|
};
|
|
12153
12346
|
|
|
12154
12347
|
// src/connection_fallback.ts
|
|
12155
|
-
var
|
|
12348
|
+
var import_axios3 = __toESM(require("axios"));
|
|
12156
12349
|
var WSConnectionFallback = class {
|
|
12157
12350
|
constructor({ client }) {
|
|
12158
12351
|
/** @private */
|
|
@@ -12171,7 +12364,7 @@ var WSConnectionFallback = class {
|
|
|
12171
12364
|
/** @private */
|
|
12172
12365
|
this._req = async (params, config, retry) => {
|
|
12173
12366
|
if (!this.cancelToken && !params.close) {
|
|
12174
|
-
this.cancelToken =
|
|
12367
|
+
this.cancelToken = import_axios3.default.CancelToken.source();
|
|
12175
12368
|
}
|
|
12176
12369
|
try {
|
|
12177
12370
|
const res = await this.client.doAxiosRequest(
|
|
@@ -12207,7 +12400,7 @@ var WSConnectionFallback = class {
|
|
|
12207
12400
|
}
|
|
12208
12401
|
}
|
|
12209
12402
|
} catch (error) {
|
|
12210
|
-
if (
|
|
12403
|
+
if (import_axios3.default.isCancel(error)) {
|
|
12211
12404
|
this._log(`_poll() - axios canceled request`);
|
|
12212
12405
|
return;
|
|
12213
12406
|
}
|
|
@@ -14630,7 +14823,7 @@ var StreamChat = class _StreamChat {
|
|
|
14630
14823
|
return this.handleResponse(response);
|
|
14631
14824
|
} catch (e) {
|
|
14632
14825
|
e.client_request_id = requestConfig.headers?.["x-client-request-id"];
|
|
14633
|
-
if (
|
|
14826
|
+
if (import_axios4.default.isCancel(e)) throw e;
|
|
14634
14827
|
this._logApiError(type, url, e);
|
|
14635
14828
|
this.consecutiveFailures += 1;
|
|
14636
14829
|
if (e.response) {
|
|
@@ -14779,16 +14972,12 @@ var StreamChat = class _StreamChat {
|
|
|
14779
14972
|
}
|
|
14780
14973
|
};
|
|
14781
14974
|
this._callClientListeners = (event) => {
|
|
14782
|
-
const
|
|
14783
|
-
|
|
14784
|
-
|
|
14785
|
-
|
|
14786
|
-
}
|
|
14787
|
-
if (client.listeners[event.type]) {
|
|
14788
|
-
listeners.push(...client.listeners[event.type]);
|
|
14789
|
-
}
|
|
14975
|
+
const listeners = [
|
|
14976
|
+
...this.listeners.all ?? [],
|
|
14977
|
+
...this.listeners[event.type] ?? []
|
|
14978
|
+
];
|
|
14790
14979
|
for (const listener of listeners) {
|
|
14791
|
-
listener
|
|
14980
|
+
invokeEventListener(listener, event, this.logger);
|
|
14792
14981
|
}
|
|
14793
14982
|
};
|
|
14794
14983
|
this.recoverState = async () => {
|
|
@@ -14942,7 +15131,7 @@ var StreamChat = class _StreamChat {
|
|
|
14942
15131
|
return this.userAgent;
|
|
14943
15132
|
}
|
|
14944
15133
|
if (!this.cachedUserAgent) {
|
|
14945
|
-
const version = "9.
|
|
15134
|
+
const version = "9.52.1";
|
|
14946
15135
|
const { name: sdkName, version: sdkVersion } = this.sdkIdentifier ?? {};
|
|
14947
15136
|
const { name: appName, version: appVersion } = this.appIdentifier ?? {};
|
|
14948
15137
|
const { os, model: deviceModel } = this.deviceIdentifier ?? {};
|
|
@@ -15010,7 +15199,7 @@ var StreamChat = class _StreamChat {
|
|
|
15010
15199
|
keepAliveMsecs: 3e3
|
|
15011
15200
|
});
|
|
15012
15201
|
}
|
|
15013
|
-
this.axiosInstance =
|
|
15202
|
+
this.axiosInstance = import_axios4.default.create(this.options);
|
|
15014
15203
|
this.setBaseURL(this.options.baseURL || "https://chat.stream-io-api.com");
|
|
15015
15204
|
if (typeof process !== "undefined" && "env" in process && process.env.STREAM_LOCAL_TEST_RUN) {
|
|
15016
15205
|
this.setBaseURL("http://localhost:3030");
|
|
@@ -15031,7 +15220,7 @@ var StreamChat = class _StreamChat {
|
|
|
15031
15220
|
this.defaultWSTimeoutWithFallback = 6 * 1e3;
|
|
15032
15221
|
this.defaultWSTimeout = 15 * 1e3;
|
|
15033
15222
|
this.axiosInstance.defaults.paramsSerializer = axiosParamsSerializer;
|
|
15034
|
-
this.logger = isFunction(inputOptions.logger) ? inputOptions.logger :
|
|
15223
|
+
this.logger = isFunction(inputOptions.logger) ? inputOptions.logger : noopLogger;
|
|
15035
15224
|
this.recoverStateOnReconnect = this.options.recoverStateOnReconnect;
|
|
15036
15225
|
this.threads = new ThreadManager({ client: this });
|
|
15037
15226
|
this.polls = new PollManager({ client: this });
|
|
@@ -16362,6 +16551,11 @@ var StreamChat = class _StreamChat {
|
|
|
16362
16551
|
}
|
|
16363
16552
|
/**
|
|
16364
16553
|
* unflagMessage - unflag a message
|
|
16554
|
+
*
|
|
16555
|
+
* @deprecated The `/moderation/unflag` endpoint is deprecated and is a no-op on
|
|
16556
|
+
* the backend - calling this resolves successfully but does not remove the flag.
|
|
16557
|
+
* Use `client.moderation.submitAction()` against the review queue item instead.
|
|
16558
|
+
*
|
|
16365
16559
|
* @param {string} targetMessageID
|
|
16366
16560
|
* @param {string} [options.user_id] currentUserID, only used with serverside auth
|
|
16367
16561
|
* @returns {Promise<APIResponse>}
|
|
@@ -16374,6 +16568,11 @@ var StreamChat = class _StreamChat {
|
|
|
16374
16568
|
}
|
|
16375
16569
|
/**
|
|
16376
16570
|
* unflagUser - unflag a user
|
|
16571
|
+
*
|
|
16572
|
+
* @deprecated The `/moderation/unflag` endpoint is deprecated and is a no-op on
|
|
16573
|
+
* the backend - calling this resolves successfully but does not remove the flag.
|
|
16574
|
+
* Use `client.moderation.submitAction()` against the review queue item instead.
|
|
16575
|
+
*
|
|
16377
16576
|
* @param {string} targetID
|
|
16378
16577
|
* @param {string} [options.user_id] currentUserID, only used with serverside auth
|
|
16379
16578
|
* @returns {Promise<APIResponse>}
|
|
@@ -16658,7 +16857,10 @@ var StreamChat = class _StreamChat {
|
|
|
16658
16857
|
if (!message.id) {
|
|
16659
16858
|
throw Error("Please specify the message.id when calling updateMessage");
|
|
16660
16859
|
}
|
|
16661
|
-
const payload =
|
|
16860
|
+
const payload = sanitizeOutgoingAttachments({
|
|
16861
|
+
client: this,
|
|
16862
|
+
message: toUpdatedMessagePayload(message)
|
|
16863
|
+
});
|
|
16662
16864
|
if (typeof partialUserOrUserId === "string") {
|
|
16663
16865
|
payload.user_id = partialUserOrUserId;
|
|
16664
16866
|
} else if (typeof partialUserOrUserId?.id === "string") {
|
|
@@ -18474,7 +18676,7 @@ var OfflineError = class extends Error {
|
|
|
18474
18676
|
};
|
|
18475
18677
|
|
|
18476
18678
|
// src/offline-support/offline_sync_manager.ts
|
|
18477
|
-
var
|
|
18679
|
+
var import_axios5 = require("axios");
|
|
18478
18680
|
var OfflineDBSyncManager = class {
|
|
18479
18681
|
constructor({
|
|
18480
18682
|
client,
|
|
@@ -18622,7 +18824,7 @@ var OfflineDBSyncManager = class {
|
|
|
18622
18824
|
});
|
|
18623
18825
|
} catch (e) {
|
|
18624
18826
|
console.log("An error has occurred while syncing the DB.", e);
|
|
18625
|
-
if ((0,
|
|
18827
|
+
if ((0, import_axios5.isAxiosError)(e) && e.code === "ECONNABORTED") {
|
|
18626
18828
|
return;
|
|
18627
18829
|
}
|
|
18628
18830
|
const error = e;
|
|
@@ -19131,6 +19333,7 @@ var AbstractOfflineDB = class {
|
|
|
19131
19333
|
return this.handleMessageUpdatedEvent({ event, execute });
|
|
19132
19334
|
}
|
|
19133
19335
|
if (type === "message.read" || type === "notification.mark_read") {
|
|
19336
|
+
if (event.thread) return [];
|
|
19134
19337
|
return this.handleRead({ event, unreadMessages: 0, execute });
|
|
19135
19338
|
}
|
|
19136
19339
|
if (type === "message.read_locally") {
|
|
@@ -19698,6 +19901,7 @@ var LiveLocationManager = _LiveLocationManager;
|
|
|
19698
19901
|
createMessageComposerStateCompositionMiddleware,
|
|
19699
19902
|
createPollComposerStateMiddleware,
|
|
19700
19903
|
createPostUploadAttachmentEnrichmentMiddleware,
|
|
19904
|
+
createSendWithPendingUploadsAttachmentsMiddleware,
|
|
19701
19905
|
createSharedLocationCompositionMiddleware,
|
|
19702
19906
|
createTextComposerCompositionMiddleware,
|
|
19703
19907
|
createTextComposerPreValidationMiddleware,
|
|
@@ -19726,6 +19930,7 @@ var LiveLocationManager = _LiveLocationManager;
|
|
|
19726
19930
|
getTokenizedSuggestionDisplayName,
|
|
19727
19931
|
getTriggerCharWithToken,
|
|
19728
19932
|
gunzipPayload,
|
|
19933
|
+
hasPending,
|
|
19729
19934
|
insertItemWithTrigger,
|
|
19730
19935
|
isAudioAttachment,
|
|
19731
19936
|
isBlobButNotFile,
|
|
@@ -19733,6 +19938,7 @@ var LiveLocationManager = _LiveLocationManager;
|
|
|
19733
19938
|
isFileAttachment,
|
|
19734
19939
|
isFileList,
|
|
19735
19940
|
isFileReference,
|
|
19941
|
+
isFinishedUpload,
|
|
19736
19942
|
isGiphyAttachment,
|
|
19737
19943
|
isImageAttachment,
|
|
19738
19944
|
isImageFile,
|
|
@@ -19745,9 +19951,11 @@ var LiveLocationManager = _LiveLocationManager;
|
|
|
19745
19951
|
isLocalVoiceRecordingAttachment,
|
|
19746
19952
|
isOwnUser,
|
|
19747
19953
|
isPatch,
|
|
19954
|
+
isPendingUpload,
|
|
19748
19955
|
isScrapedContent,
|
|
19749
19956
|
isSharedLocationResponse,
|
|
19750
19957
|
isTargetedOptionTextUpdate,
|
|
19958
|
+
isUploadCancellation,
|
|
19751
19959
|
isUploadedAttachment,
|
|
19752
19960
|
isVideoAttachment,
|
|
19753
19961
|
isVoiceRecordingAttachment,
|
|
@@ -19767,11 +19975,14 @@ var LiveLocationManager = _LiveLocationManager;
|
|
|
19767
19975
|
readFileAsArrayBuffer,
|
|
19768
19976
|
removeDiacritics,
|
|
19769
19977
|
replaceWordWithEntity,
|
|
19978
|
+
settled,
|
|
19770
19979
|
stripCommandFromText,
|
|
19771
19980
|
stripMentionTokens,
|
|
19772
19981
|
textIsEmpty,
|
|
19773
19982
|
timeLeftMs,
|
|
19774
19983
|
verifyAndParseWebhook,
|
|
19775
|
-
verifySignature
|
|
19984
|
+
verifySignature,
|
|
19985
|
+
withCancellation,
|
|
19986
|
+
withoutConcurrency
|
|
19776
19987
|
});
|
|
19777
19988
|
//# sourceMappingURL=index.node.js.map
|