stream-chat 9.29.0 → 9.30.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 +515 -377
- package/dist/cjs/index.browser.js.map +3 -3
- package/dist/cjs/index.node.js +515 -377
- package/dist/cjs/index.node.js.map +3 -3
- package/dist/esm/index.mjs +515 -377
- package/dist/esm/index.mjs.map +3 -3
- package/dist/types/CooldownTimer.d.ts +45 -0
- package/dist/types/channel.d.ts +2 -0
- package/dist/types/channel_state.d.ts +1 -1
- package/dist/types/index.d.ts +1 -0
- package/dist/types/insights.d.ts +2 -2
- package/dist/types/messageComposer/fileUtils.d.ts +1 -1
- package/dist/types/messageComposer/messageComposer.d.ts +3 -3
- package/dist/types/messageComposer/middleware/textComposer/commands.d.ts +2 -2
- package/dist/types/messageComposer/types.d.ts +8 -0
- package/dist/types/utils.d.ts +5 -5
- package/package.json +1 -1
- package/src/CooldownTimer.ts +196 -0
- package/src/channel.ts +10 -0
- package/src/client.ts +1 -1
- package/src/index.ts +1 -0
- package/src/messageComposer/attachmentManager.ts +18 -13
- package/src/messageComposer/middleware/attachmentManager/postUpload/attachmentEnrichment.ts +5 -4
- package/src/messageComposer/types.ts +8 -0
|
@@ -2132,6 +2132,399 @@ var ChannelState = class {
|
|
|
2132
2132
|
}
|
|
2133
2133
|
};
|
|
2134
2134
|
|
|
2135
|
+
// src/store.ts
|
|
2136
|
+
var isPatch = (value) => typeof value === "function";
|
|
2137
|
+
var noop = () => {
|
|
2138
|
+
};
|
|
2139
|
+
var StateStore = class {
|
|
2140
|
+
constructor(value) {
|
|
2141
|
+
this.value = value;
|
|
2142
|
+
this.handlers = /* @__PURE__ */ new Set();
|
|
2143
|
+
this.preprocessors = /* @__PURE__ */ new Set();
|
|
2144
|
+
this.partialNext = (partial) => this.next((current) => ({ ...current, ...partial }));
|
|
2145
|
+
this.subscribeWithSelector = (selector, handler) => {
|
|
2146
|
+
let previouslySelectedValues;
|
|
2147
|
+
const wrappedHandler = (nextValue) => {
|
|
2148
|
+
const newlySelectedValues = selector(nextValue);
|
|
2149
|
+
let hasUpdatedValues = typeof previouslySelectedValues === "undefined";
|
|
2150
|
+
for (const key in previouslySelectedValues) {
|
|
2151
|
+
if (previouslySelectedValues[key] === newlySelectedValues[key]) continue;
|
|
2152
|
+
hasUpdatedValues = true;
|
|
2153
|
+
break;
|
|
2154
|
+
}
|
|
2155
|
+
if (!hasUpdatedValues) return;
|
|
2156
|
+
const previouslySelectedValuesCopy = previouslySelectedValues;
|
|
2157
|
+
previouslySelectedValues = newlySelectedValues;
|
|
2158
|
+
handler(newlySelectedValues, previouslySelectedValuesCopy);
|
|
2159
|
+
};
|
|
2160
|
+
return this.subscribe(wrappedHandler);
|
|
2161
|
+
};
|
|
2162
|
+
}
|
|
2163
|
+
/**
|
|
2164
|
+
* Allows merging two stores only if their keys differ otherwise there's no way to ensure the data type stability.
|
|
2165
|
+
* @experimental
|
|
2166
|
+
* This method is experimental and may change in future versions.
|
|
2167
|
+
*/
|
|
2168
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2169
|
+
merge(stateStore) {
|
|
2170
|
+
return new MergedStateStore({
|
|
2171
|
+
original: this,
|
|
2172
|
+
merged: stateStore
|
|
2173
|
+
});
|
|
2174
|
+
}
|
|
2175
|
+
next(newValueOrPatch) {
|
|
2176
|
+
const newValue = isPatch(newValueOrPatch) ? newValueOrPatch(this.value) : newValueOrPatch;
|
|
2177
|
+
if (newValue === this.value) return;
|
|
2178
|
+
this.preprocessors.forEach((preprocessor) => preprocessor(newValue, this.value));
|
|
2179
|
+
const oldValue = this.value;
|
|
2180
|
+
this.value = newValue;
|
|
2181
|
+
this.handlers.forEach((handler) => handler(this.value, oldValue));
|
|
2182
|
+
}
|
|
2183
|
+
getLatestValue() {
|
|
2184
|
+
return this.value;
|
|
2185
|
+
}
|
|
2186
|
+
subscribe(handler) {
|
|
2187
|
+
handler(this.value, void 0);
|
|
2188
|
+
this.handlers.add(handler);
|
|
2189
|
+
return () => {
|
|
2190
|
+
this.handlers.delete(handler);
|
|
2191
|
+
};
|
|
2192
|
+
}
|
|
2193
|
+
/**
|
|
2194
|
+
* Registers a preprocessor function that will be called before the state is updated.
|
|
2195
|
+
*
|
|
2196
|
+
* Preprocessors are invoked with the new and previous values whenever `next` or `partialNext` methods
|
|
2197
|
+
* are called, allowing you to mutate or react to the new value before it is set. Preprocessors run in the
|
|
2198
|
+
* order they were registered.
|
|
2199
|
+
*
|
|
2200
|
+
* @example
|
|
2201
|
+
* ```ts
|
|
2202
|
+
* const store = new StateStore<{ count: number; isMaxValue: bool; }>({ count: 0, isMaxValue: false });
|
|
2203
|
+
*
|
|
2204
|
+
* store.addPreprocessor((nextValue, prevValue) => {
|
|
2205
|
+
* if (nextValue.count > 10) {
|
|
2206
|
+
* nextValue.count = 10; // Clamp the value to a maximum of 10
|
|
2207
|
+
* }
|
|
2208
|
+
*
|
|
2209
|
+
* if (nextValue.count === 10) {
|
|
2210
|
+
* nextValue.isMaxValue = true; // Set isMaxValue to true if count is 10
|
|
2211
|
+
* } else {
|
|
2212
|
+
* nextValue.isMaxValue = false; // Reset isMaxValue otherwise
|
|
2213
|
+
* }
|
|
2214
|
+
* });
|
|
2215
|
+
*
|
|
2216
|
+
* store.partialNext({ count: 15 });
|
|
2217
|
+
*
|
|
2218
|
+
* store.getLatestValue(); // { count: 10, isMaxValue: true }
|
|
2219
|
+
*
|
|
2220
|
+
* store.partialNext({ count: 5 });
|
|
2221
|
+
*
|
|
2222
|
+
* store.getLatestValue(); // { count: 5, isMaxValue: false }
|
|
2223
|
+
* ```
|
|
2224
|
+
*
|
|
2225
|
+
* @param preprocessor - The function to be called with the next and previous values before the state is updated.
|
|
2226
|
+
* @returns A `RemovePreprocessor` function that removes the preprocessor when called.
|
|
2227
|
+
*/
|
|
2228
|
+
addPreprocessor(preprocessor) {
|
|
2229
|
+
this.preprocessors.add(preprocessor);
|
|
2230
|
+
return () => {
|
|
2231
|
+
this.preprocessors.delete(preprocessor);
|
|
2232
|
+
};
|
|
2233
|
+
}
|
|
2234
|
+
};
|
|
2235
|
+
var MergedStateStore = class _MergedStateStore extends StateStore {
|
|
2236
|
+
constructor({ original, merged }) {
|
|
2237
|
+
const originalValue = original.getLatestValue();
|
|
2238
|
+
const mergedValue = merged.getLatestValue();
|
|
2239
|
+
super({
|
|
2240
|
+
...originalValue,
|
|
2241
|
+
...mergedValue
|
|
2242
|
+
});
|
|
2243
|
+
// override original methods and "disable" them
|
|
2244
|
+
this.next = () => {
|
|
2245
|
+
console.warn(
|
|
2246
|
+
`${_MergedStateStore.name}.next is disabled, call original.next or merged.next instead`
|
|
2247
|
+
);
|
|
2248
|
+
};
|
|
2249
|
+
this.partialNext = () => {
|
|
2250
|
+
console.warn(
|
|
2251
|
+
`${_MergedStateStore.name}.partialNext is disabled, call original.partialNext or merged.partialNext instead`
|
|
2252
|
+
);
|
|
2253
|
+
};
|
|
2254
|
+
this.cachedOriginalValue = originalValue;
|
|
2255
|
+
this.cachedMergedValue = mergedValue;
|
|
2256
|
+
this.original = original;
|
|
2257
|
+
this.merged = merged;
|
|
2258
|
+
}
|
|
2259
|
+
/**
|
|
2260
|
+
* Subscribes to changes in the merged state store.
|
|
2261
|
+
*
|
|
2262
|
+
* This method extends the base subscribe functionality to handle the merged nature of this store:
|
|
2263
|
+
* 1. The first subscriber triggers registration of helper subscribers that listen to both source stores
|
|
2264
|
+
* 2. Changes from either source store are propagated to this merged store
|
|
2265
|
+
* 3. Source store values are cached to prevent unnecessary updates
|
|
2266
|
+
*
|
|
2267
|
+
* When the first subscriber is added, the method sets up listeners on both original and merged stores.
|
|
2268
|
+
* These listeners update the combined store value whenever either source store changes.
|
|
2269
|
+
* All subscriptions (helpers and the actual handler) are tracked so they can be properly cleaned up.
|
|
2270
|
+
*
|
|
2271
|
+
* @param handler - The callback function that will be executed when the state changes
|
|
2272
|
+
* @returns An unsubscribe function that, when called, removes the subscription and any helper subscriptions
|
|
2273
|
+
*/
|
|
2274
|
+
subscribe(handler) {
|
|
2275
|
+
const unsubscribeFunctions = [];
|
|
2276
|
+
if (!this.handlers.size) {
|
|
2277
|
+
const base = (nextValue) => {
|
|
2278
|
+
super.next((currentValue) => ({
|
|
2279
|
+
...currentValue,
|
|
2280
|
+
...nextValue
|
|
2281
|
+
}));
|
|
2282
|
+
};
|
|
2283
|
+
unsubscribeFunctions.push(
|
|
2284
|
+
this.original.subscribe((nextValue) => {
|
|
2285
|
+
if (nextValue === this.cachedOriginalValue) return;
|
|
2286
|
+
this.cachedOriginalValue = nextValue;
|
|
2287
|
+
base(nextValue);
|
|
2288
|
+
}),
|
|
2289
|
+
this.merged.subscribe((nextValue) => {
|
|
2290
|
+
if (nextValue === this.cachedMergedValue) return;
|
|
2291
|
+
this.cachedMergedValue = nextValue;
|
|
2292
|
+
base(nextValue);
|
|
2293
|
+
})
|
|
2294
|
+
);
|
|
2295
|
+
}
|
|
2296
|
+
unsubscribeFunctions.push(super.subscribe(handler));
|
|
2297
|
+
return () => {
|
|
2298
|
+
unsubscribeFunctions.forEach((unsubscribe) => unsubscribe());
|
|
2299
|
+
};
|
|
2300
|
+
}
|
|
2301
|
+
/**
|
|
2302
|
+
* Retrieves the latest combined state from both original and merged stores.
|
|
2303
|
+
*
|
|
2304
|
+
* This method extends the base getLatestValue functionality to ensure the merged store
|
|
2305
|
+
* remains in sync with its source stores even when there are no active subscribers.
|
|
2306
|
+
*
|
|
2307
|
+
* When there are no handlers registered, the method:
|
|
2308
|
+
* 1. Fetches the latest values from both source stores
|
|
2309
|
+
* 2. Compares them with the cached values to detect changes
|
|
2310
|
+
* 3. If changes are detected, updates the internal value and caches
|
|
2311
|
+
* the new source values to maintain consistency
|
|
2312
|
+
*
|
|
2313
|
+
* This approach ensures that calling getLatestValue() always returns the most
|
|
2314
|
+
* up-to-date combined state, even if the merged store hasn't been actively
|
|
2315
|
+
* receiving updates through subscriptions.
|
|
2316
|
+
*
|
|
2317
|
+
* @returns The latest combined state from both original and merged stores
|
|
2318
|
+
*/
|
|
2319
|
+
getLatestValue() {
|
|
2320
|
+
if (!this.handlers.size) {
|
|
2321
|
+
const originalValue = this.original.getLatestValue();
|
|
2322
|
+
const mergedValue = this.merged.getLatestValue();
|
|
2323
|
+
if (originalValue !== this.cachedOriginalValue || mergedValue !== this.cachedMergedValue) {
|
|
2324
|
+
this.value = {
|
|
2325
|
+
...originalValue,
|
|
2326
|
+
...mergedValue
|
|
2327
|
+
};
|
|
2328
|
+
this.cachedMergedValue = mergedValue;
|
|
2329
|
+
this.cachedOriginalValue = originalValue;
|
|
2330
|
+
}
|
|
2331
|
+
}
|
|
2332
|
+
return super.getLatestValue();
|
|
2333
|
+
}
|
|
2334
|
+
addPreprocessor() {
|
|
2335
|
+
console.warn(
|
|
2336
|
+
`${_MergedStateStore.name}.addPreprocessor is disabled, call original.addPreprocessor or merged.addPreprocessor instead`
|
|
2337
|
+
);
|
|
2338
|
+
return noop;
|
|
2339
|
+
}
|
|
2340
|
+
};
|
|
2341
|
+
|
|
2342
|
+
// src/utils/WithSubscriptions.ts
|
|
2343
|
+
var _WithSubscriptions = class _WithSubscriptions {
|
|
2344
|
+
constructor() {
|
|
2345
|
+
this.unsubscribeFunctions = /* @__PURE__ */ new Set();
|
|
2346
|
+
this.refCount = 0;
|
|
2347
|
+
}
|
|
2348
|
+
/**
|
|
2349
|
+
* Returns a boolean, provides information of whether `registerSubscriptions`
|
|
2350
|
+
* method has already been called for this instance.
|
|
2351
|
+
*/
|
|
2352
|
+
get hasSubscriptions() {
|
|
2353
|
+
return this.unsubscribeFunctions.size > 0;
|
|
2354
|
+
}
|
|
2355
|
+
addUnsubscribeFunction(unsubscribeFunction) {
|
|
2356
|
+
this.unsubscribeFunctions.add(unsubscribeFunction);
|
|
2357
|
+
}
|
|
2358
|
+
/**
|
|
2359
|
+
* Increments `refCount` by one and returns new value.
|
|
2360
|
+
*/
|
|
2361
|
+
incrementRefCount() {
|
|
2362
|
+
return ++this.refCount;
|
|
2363
|
+
}
|
|
2364
|
+
/**
|
|
2365
|
+
* If you re-declare `unregisterSubscriptions` method within your class
|
|
2366
|
+
* make sure to run the original too.
|
|
2367
|
+
*
|
|
2368
|
+
* @example
|
|
2369
|
+
* ```ts
|
|
2370
|
+
* class T extends WithSubscriptions {
|
|
2371
|
+
* ...
|
|
2372
|
+
* public unregisterSubscriptions = () => {
|
|
2373
|
+
* this.customThing();
|
|
2374
|
+
* return super.unregisterSubscriptions();
|
|
2375
|
+
* }
|
|
2376
|
+
* }
|
|
2377
|
+
* ```
|
|
2378
|
+
*/
|
|
2379
|
+
unregisterSubscriptions() {
|
|
2380
|
+
if (this.refCount > 1) {
|
|
2381
|
+
this.refCount--;
|
|
2382
|
+
return _WithSubscriptions.symbol;
|
|
2383
|
+
}
|
|
2384
|
+
this.unsubscribeFunctions.forEach((unsubscribe) => unsubscribe());
|
|
2385
|
+
this.unsubscribeFunctions.clear();
|
|
2386
|
+
this.refCount = 0;
|
|
2387
|
+
return _WithSubscriptions.symbol;
|
|
2388
|
+
}
|
|
2389
|
+
};
|
|
2390
|
+
/**
|
|
2391
|
+
* Workaround for the missing TS keyword - ensures that inheritants
|
|
2392
|
+
* overriding `unregisterSubscriptions` call the base method and return
|
|
2393
|
+
* its unique symbol value.
|
|
2394
|
+
*/
|
|
2395
|
+
_WithSubscriptions.symbol = Symbol(_WithSubscriptions.name);
|
|
2396
|
+
var WithSubscriptions = _WithSubscriptions;
|
|
2397
|
+
|
|
2398
|
+
// src/CooldownTimer.ts
|
|
2399
|
+
var toDateOrUndefined = (value) => {
|
|
2400
|
+
if (value instanceof Date) return value;
|
|
2401
|
+
if (typeof value === "string" || typeof value === "number") {
|
|
2402
|
+
const parsed = new Date(value);
|
|
2403
|
+
if (!Number.isNaN(parsed.getTime())) return parsed;
|
|
2404
|
+
}
|
|
2405
|
+
return void 0;
|
|
2406
|
+
};
|
|
2407
|
+
var CooldownTimer = class extends WithSubscriptions {
|
|
2408
|
+
constructor({ channel }) {
|
|
2409
|
+
super();
|
|
2410
|
+
this.timeout = null;
|
|
2411
|
+
this.registerSubscriptions = () => {
|
|
2412
|
+
this.incrementRefCount();
|
|
2413
|
+
if (this.hasSubscriptions) return;
|
|
2414
|
+
this.addUnsubscribeFunction(
|
|
2415
|
+
this.channel.on("message.new", (event) => {
|
|
2416
|
+
const isOwnMessage = event.message?.user?.id && event.message.user.id === this.getOwnUserId();
|
|
2417
|
+
if (!isOwnMessage) return;
|
|
2418
|
+
this.setOwnLatestMessageDate(toDateOrUndefined(event.message?.created_at));
|
|
2419
|
+
}).unsubscribe
|
|
2420
|
+
);
|
|
2421
|
+
this.addUnsubscribeFunction(
|
|
2422
|
+
this.channel.on("channel.updated", (event) => {
|
|
2423
|
+
const cooldownChanged = event.channel?.cooldown !== this.cooldownConfigSeconds;
|
|
2424
|
+
if (!cooldownChanged) return;
|
|
2425
|
+
this.refresh();
|
|
2426
|
+
}).unsubscribe
|
|
2427
|
+
);
|
|
2428
|
+
};
|
|
2429
|
+
this.setCooldownRemaining = (cooldownRemaining) => {
|
|
2430
|
+
this.state.partialNext({ cooldownRemaining });
|
|
2431
|
+
};
|
|
2432
|
+
this.clearTimeout = () => {
|
|
2433
|
+
if (!this.timeout) return;
|
|
2434
|
+
clearTimeout(this.timeout);
|
|
2435
|
+
this.timeout = null;
|
|
2436
|
+
};
|
|
2437
|
+
this.refresh = () => {
|
|
2438
|
+
const { cooldown: cooldownConfigSeconds = 0, own_capabilities } = this.channel.data ?? {};
|
|
2439
|
+
const canSkipCooldown = (own_capabilities ?? []).includes("skip-slow-mode");
|
|
2440
|
+
const ownLatestMessageDate = this.findOwnLatestMessageDate({
|
|
2441
|
+
messages: this.channel.state.latestMessages
|
|
2442
|
+
});
|
|
2443
|
+
if (cooldownConfigSeconds !== this.cooldownConfigSeconds || ownLatestMessageDate?.getTime() !== this.ownLatestMessageDate?.getTime() || canSkipCooldown !== this.canSkipCooldown) {
|
|
2444
|
+
this.state.partialNext({
|
|
2445
|
+
cooldownConfigSeconds,
|
|
2446
|
+
ownLatestMessageDate,
|
|
2447
|
+
canSkipCooldown
|
|
2448
|
+
});
|
|
2449
|
+
}
|
|
2450
|
+
if (this.canSkipCooldown || this.cooldownConfigSeconds === 0) {
|
|
2451
|
+
this.clearTimeout();
|
|
2452
|
+
if (this.cooldownRemaining !== 0) {
|
|
2453
|
+
this.setCooldownRemaining(0);
|
|
2454
|
+
}
|
|
2455
|
+
return;
|
|
2456
|
+
}
|
|
2457
|
+
this.recalculate();
|
|
2458
|
+
};
|
|
2459
|
+
/**
|
|
2460
|
+
* Updates the known latest own message date and recomputes remaining time.
|
|
2461
|
+
* Prefer calling this when you already know the message date (e.g. from an event).
|
|
2462
|
+
*/
|
|
2463
|
+
this.setOwnLatestMessageDate = (date) => {
|
|
2464
|
+
this.state.partialNext({ ownLatestMessageDate: date });
|
|
2465
|
+
this.recalculate();
|
|
2466
|
+
};
|
|
2467
|
+
this.recalculate = () => {
|
|
2468
|
+
this.clearTimeout();
|
|
2469
|
+
const { cooldownConfigSeconds, ownLatestMessageDate, canSkipCooldown } = this.state.getLatestValue();
|
|
2470
|
+
const timeSinceOwnLastMessage = ownLatestMessageDate != null ? (
|
|
2471
|
+
// prevent negative values
|
|
2472
|
+
Math.max(0, (Date.now() - ownLatestMessageDate.getTime()) / 1e3)
|
|
2473
|
+
) : void 0;
|
|
2474
|
+
const remaining = !canSkipCooldown && typeof timeSinceOwnLastMessage !== "undefined" && cooldownConfigSeconds > timeSinceOwnLastMessage ? Math.round(cooldownConfigSeconds - timeSinceOwnLastMessage) : 0;
|
|
2475
|
+
if (remaining !== this.cooldownRemaining) {
|
|
2476
|
+
this.setCooldownRemaining(remaining);
|
|
2477
|
+
}
|
|
2478
|
+
if (remaining <= 0) return;
|
|
2479
|
+
this.timeout = setTimeout(() => {
|
|
2480
|
+
this.recalculate();
|
|
2481
|
+
}, 1e3);
|
|
2482
|
+
};
|
|
2483
|
+
this.channel = channel;
|
|
2484
|
+
this.state = new StateStore({
|
|
2485
|
+
cooldownConfigSeconds: 0,
|
|
2486
|
+
cooldownRemaining: 0,
|
|
2487
|
+
ownLatestMessageDate: void 0,
|
|
2488
|
+
canSkipCooldown: false
|
|
2489
|
+
});
|
|
2490
|
+
this.refresh();
|
|
2491
|
+
}
|
|
2492
|
+
get cooldownConfigSeconds() {
|
|
2493
|
+
return this.state.getLatestValue().cooldownConfigSeconds;
|
|
2494
|
+
}
|
|
2495
|
+
get cooldownRemaining() {
|
|
2496
|
+
return this.state.getLatestValue().cooldownRemaining;
|
|
2497
|
+
}
|
|
2498
|
+
get canSkipCooldown() {
|
|
2499
|
+
return this.state.getLatestValue().canSkipCooldown;
|
|
2500
|
+
}
|
|
2501
|
+
get ownLatestMessageDate() {
|
|
2502
|
+
return this.state.getLatestValue().ownLatestMessageDate;
|
|
2503
|
+
}
|
|
2504
|
+
getOwnUserId() {
|
|
2505
|
+
const client = this.channel.getClient();
|
|
2506
|
+
return client.userID ?? client.user?.id;
|
|
2507
|
+
}
|
|
2508
|
+
findOwnLatestMessageDate({
|
|
2509
|
+
messages
|
|
2510
|
+
}) {
|
|
2511
|
+
const ownUserId = this.getOwnUserId();
|
|
2512
|
+
if (!ownUserId) return void 0;
|
|
2513
|
+
let latest;
|
|
2514
|
+
for (let i = messages.length - 1; i >= 0; i -= 1) {
|
|
2515
|
+
const message = messages[i];
|
|
2516
|
+
if (message.user?.id !== ownUserId) continue;
|
|
2517
|
+
const createdAt = toDateOrUndefined(message.created_at);
|
|
2518
|
+
if (!createdAt) continue;
|
|
2519
|
+
if (!latest || createdAt.getTime() > latest.getTime()) {
|
|
2520
|
+
latest = createdAt;
|
|
2521
|
+
}
|
|
2522
|
+
if (latest.getTime() > createdAt.getTime()) break;
|
|
2523
|
+
}
|
|
2524
|
+
return latest;
|
|
2525
|
+
}
|
|
2526
|
+
};
|
|
2527
|
+
|
|
2135
2528
|
// src/messageComposer/attachmentIdentity.ts
|
|
2136
2529
|
var isScrapedContent = (attachment) => !!attachment?.og_scrape_url || !!attachment?.title_link;
|
|
2137
2530
|
var isLocalAttachment = (attachment) => !!attachment?.localMetadata?.id;
|
|
@@ -2223,11 +2616,12 @@ var createPostUploadAttachmentEnrichmentMiddleware = () => ({
|
|
|
2223
2616
|
if (error) return forward();
|
|
2224
2617
|
if (!attachment || !response) return discard();
|
|
2225
2618
|
const enrichedAttachment = { ...attachment };
|
|
2619
|
+
const previewUri = attachment.localMetadata.previewUri;
|
|
2620
|
+
if (previewUri) {
|
|
2621
|
+
if (previewUri.startsWith("blob:")) URL.revokeObjectURL(previewUri);
|
|
2622
|
+
delete enrichedAttachment.localMetadata.previewUri;
|
|
2623
|
+
}
|
|
2226
2624
|
if (isLocalImageAttachment(attachment)) {
|
|
2227
|
-
if (attachment.localMetadata.previewUri) {
|
|
2228
|
-
URL.revokeObjectURL(attachment.localMetadata.previewUri);
|
|
2229
|
-
delete enrichedAttachment.localMetadata.previewUri;
|
|
2230
|
-
}
|
|
2231
2625
|
enrichedAttachment.image_url = response.file;
|
|
2232
2626
|
} else {
|
|
2233
2627
|
enrichedAttachment.asset_url = response.file;
|
|
@@ -2392,321 +2786,114 @@ var MiddlewareExecutor = class {
|
|
|
2392
2786
|
}
|
|
2393
2787
|
};
|
|
2394
2788
|
|
|
2395
|
-
// src/messageComposer/middleware/attachmentManager/postUpload/uploadErrorHandler.ts
|
|
2396
|
-
var createUploadErrorHandlerMiddleware = (composer) => ({
|
|
2397
|
-
id: "stream-io/attachment-manager-middleware/upload-error",
|
|
2398
|
-
handlers: {
|
|
2399
|
-
postProcess: ({
|
|
2400
|
-
state,
|
|
2401
|
-
discard,
|
|
2402
|
-
forward
|
|
2403
|
-
}) => {
|
|
2404
|
-
const { attachment, error } = state;
|
|
2405
|
-
if (!error) return forward();
|
|
2406
|
-
if (!attachment) return discard();
|
|
2407
|
-
const reason = error instanceof Error ? error.message : "unknown error";
|
|
2408
|
-
composer.client.notifications.addError({
|
|
2409
|
-
message: "Error uploading attachment",
|
|
2410
|
-
origin: {
|
|
2411
|
-
emitter: "AttachmentManager",
|
|
2412
|
-
context: { attachment }
|
|
2413
|
-
},
|
|
2414
|
-
options: {
|
|
2415
|
-
type: "api:attachment:upload:failed",
|
|
2416
|
-
metadata: { reason },
|
|
2417
|
-
originalError: error
|
|
2418
|
-
}
|
|
2419
|
-
});
|
|
2420
|
-
return forward();
|
|
2421
|
-
}
|
|
2422
|
-
}
|
|
2423
|
-
});
|
|
2424
|
-
|
|
2425
|
-
// src/messageComposer/middleware/attachmentManager/postUpload/AttachmentPostUploadMiddlewareExecutor.ts
|
|
2426
|
-
var AttachmentPostUploadMiddlewareExecutor = class extends MiddlewareExecutor {
|
|
2427
|
-
constructor({ composer }) {
|
|
2428
|
-
super();
|
|
2429
|
-
this.use([
|
|
2430
|
-
createUploadErrorHandlerMiddleware(composer),
|
|
2431
|
-
createPostUploadAttachmentEnrichmentMiddleware()
|
|
2432
|
-
]);
|
|
2433
|
-
}
|
|
2434
|
-
};
|
|
2435
|
-
|
|
2436
|
-
// src/messageComposer/middleware/attachmentManager/preUpload/serverUploadConfigCheck.ts
|
|
2437
|
-
var createUploadConfigCheckMiddleware = (composer) => ({
|
|
2438
|
-
id: "stream-io/attachment-manager-middleware/file-upload-config-check",
|
|
2439
|
-
handlers: {
|
|
2440
|
-
prepare: async ({
|
|
2441
|
-
state,
|
|
2442
|
-
next,
|
|
2443
|
-
discard
|
|
2444
|
-
}) => {
|
|
2445
|
-
const { attachmentManager } = composer;
|
|
2446
|
-
if (!attachmentManager || !state.attachment) return discard();
|
|
2447
|
-
const uploadPermissionCheck = await attachmentManager.getUploadConfigCheck(
|
|
2448
|
-
state.attachment.localMetadata.file
|
|
2449
|
-
);
|
|
2450
|
-
const attachment = {
|
|
2451
|
-
...state.attachment,
|
|
2452
|
-
localMetadata: {
|
|
2453
|
-
...state.attachment.localMetadata,
|
|
2454
|
-
uploadPermissionCheck,
|
|
2455
|
-
uploadState: uploadPermissionCheck.uploadBlocked ? "blocked" : "pending"
|
|
2456
|
-
}
|
|
2457
|
-
};
|
|
2458
|
-
return next({
|
|
2459
|
-
...state,
|
|
2460
|
-
attachment
|
|
2461
|
-
});
|
|
2462
|
-
}
|
|
2463
|
-
}
|
|
2464
|
-
});
|
|
2465
|
-
|
|
2466
|
-
// src/messageComposer/middleware/attachmentManager/preUpload/blockedUploadNotification.ts
|
|
2467
|
-
var createBlockedAttachmentUploadNotificationMiddleware = (composer) => ({
|
|
2468
|
-
id: "stream-io/attachment-manager-middleware/blocked-upload-notification",
|
|
2469
|
-
handlers: {
|
|
2470
|
-
prepare: ({
|
|
2471
|
-
state: { attachment },
|
|
2472
|
-
forward
|
|
2473
|
-
}) => {
|
|
2474
|
-
if (!attachment) return forward();
|
|
2475
|
-
if (attachment.localMetadata.uploadPermissionCheck?.uploadBlocked) {
|
|
2476
|
-
composer.client.notifications.addError({
|
|
2477
|
-
message: `The attachment upload was blocked`,
|
|
2478
|
-
origin: {
|
|
2479
|
-
emitter: "AttachmentManager",
|
|
2480
|
-
context: { blockedAttachment: attachment }
|
|
2481
|
-
},
|
|
2482
|
-
options: {
|
|
2483
|
-
type: "validation:attachment:upload:blocked",
|
|
2484
|
-
metadata: {
|
|
2485
|
-
reason: attachment.localMetadata.uploadPermissionCheck?.reason
|
|
2486
|
-
}
|
|
2487
|
-
}
|
|
2488
|
-
});
|
|
2489
|
-
}
|
|
2490
|
-
return forward();
|
|
2491
|
-
}
|
|
2492
|
-
}
|
|
2493
|
-
});
|
|
2494
|
-
|
|
2495
|
-
// src/messageComposer/middleware/attachmentManager/preUpload/AttachmentPreUploadMiddlewareExecutor.ts
|
|
2496
|
-
var AttachmentPreUploadMiddlewareExecutor = class extends MiddlewareExecutor {
|
|
2497
|
-
constructor({ composer }) {
|
|
2498
|
-
super();
|
|
2499
|
-
this.use([
|
|
2500
|
-
createUploadConfigCheckMiddleware(composer),
|
|
2501
|
-
createBlockedAttachmentUploadNotificationMiddleware(composer)
|
|
2502
|
-
]);
|
|
2503
|
-
}
|
|
2504
|
-
};
|
|
2505
|
-
|
|
2506
|
-
// src/store.ts
|
|
2507
|
-
var isPatch = (value) => typeof value === "function";
|
|
2508
|
-
var noop = () => {
|
|
2509
|
-
};
|
|
2510
|
-
var StateStore = class {
|
|
2511
|
-
constructor(value) {
|
|
2512
|
-
this.value = value;
|
|
2513
|
-
this.handlers = /* @__PURE__ */ new Set();
|
|
2514
|
-
this.preprocessors = /* @__PURE__ */ new Set();
|
|
2515
|
-
this.partialNext = (partial) => this.next((current) => ({ ...current, ...partial }));
|
|
2516
|
-
this.subscribeWithSelector = (selector, handler) => {
|
|
2517
|
-
let previouslySelectedValues;
|
|
2518
|
-
const wrappedHandler = (nextValue) => {
|
|
2519
|
-
const newlySelectedValues = selector(nextValue);
|
|
2520
|
-
let hasUpdatedValues = typeof previouslySelectedValues === "undefined";
|
|
2521
|
-
for (const key in previouslySelectedValues) {
|
|
2522
|
-
if (previouslySelectedValues[key] === newlySelectedValues[key]) continue;
|
|
2523
|
-
hasUpdatedValues = true;
|
|
2524
|
-
break;
|
|
2525
|
-
}
|
|
2526
|
-
if (!hasUpdatedValues) return;
|
|
2527
|
-
const previouslySelectedValuesCopy = previouslySelectedValues;
|
|
2528
|
-
previouslySelectedValues = newlySelectedValues;
|
|
2529
|
-
handler(newlySelectedValues, previouslySelectedValuesCopy);
|
|
2530
|
-
};
|
|
2531
|
-
return this.subscribe(wrappedHandler);
|
|
2532
|
-
};
|
|
2533
|
-
}
|
|
2534
|
-
/**
|
|
2535
|
-
* Allows merging two stores only if their keys differ otherwise there's no way to ensure the data type stability.
|
|
2536
|
-
* @experimental
|
|
2537
|
-
* This method is experimental and may change in future versions.
|
|
2538
|
-
*/
|
|
2539
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2540
|
-
merge(stateStore) {
|
|
2541
|
-
return new MergedStateStore({
|
|
2542
|
-
original: this,
|
|
2543
|
-
merged: stateStore
|
|
2544
|
-
});
|
|
2545
|
-
}
|
|
2546
|
-
next(newValueOrPatch) {
|
|
2547
|
-
const newValue = isPatch(newValueOrPatch) ? newValueOrPatch(this.value) : newValueOrPatch;
|
|
2548
|
-
if (newValue === this.value) return;
|
|
2549
|
-
this.preprocessors.forEach((preprocessor) => preprocessor(newValue, this.value));
|
|
2550
|
-
const oldValue = this.value;
|
|
2551
|
-
this.value = newValue;
|
|
2552
|
-
this.handlers.forEach((handler) => handler(this.value, oldValue));
|
|
2553
|
-
}
|
|
2554
|
-
getLatestValue() {
|
|
2555
|
-
return this.value;
|
|
2556
|
-
}
|
|
2557
|
-
subscribe(handler) {
|
|
2558
|
-
handler(this.value, void 0);
|
|
2559
|
-
this.handlers.add(handler);
|
|
2560
|
-
return () => {
|
|
2561
|
-
this.handlers.delete(handler);
|
|
2562
|
-
};
|
|
2563
|
-
}
|
|
2564
|
-
/**
|
|
2565
|
-
* Registers a preprocessor function that will be called before the state is updated.
|
|
2566
|
-
*
|
|
2567
|
-
* Preprocessors are invoked with the new and previous values whenever `next` or `partialNext` methods
|
|
2568
|
-
* are called, allowing you to mutate or react to the new value before it is set. Preprocessors run in the
|
|
2569
|
-
* order they were registered.
|
|
2570
|
-
*
|
|
2571
|
-
* @example
|
|
2572
|
-
* ```ts
|
|
2573
|
-
* const store = new StateStore<{ count: number; isMaxValue: bool; }>({ count: 0, isMaxValue: false });
|
|
2574
|
-
*
|
|
2575
|
-
* store.addPreprocessor((nextValue, prevValue) => {
|
|
2576
|
-
* if (nextValue.count > 10) {
|
|
2577
|
-
* nextValue.count = 10; // Clamp the value to a maximum of 10
|
|
2578
|
-
* }
|
|
2579
|
-
*
|
|
2580
|
-
* if (nextValue.count === 10) {
|
|
2581
|
-
* nextValue.isMaxValue = true; // Set isMaxValue to true if count is 10
|
|
2582
|
-
* } else {
|
|
2583
|
-
* nextValue.isMaxValue = false; // Reset isMaxValue otherwise
|
|
2584
|
-
* }
|
|
2585
|
-
* });
|
|
2586
|
-
*
|
|
2587
|
-
* store.partialNext({ count: 15 });
|
|
2588
|
-
*
|
|
2589
|
-
* store.getLatestValue(); // { count: 10, isMaxValue: true }
|
|
2590
|
-
*
|
|
2591
|
-
* store.partialNext({ count: 5 });
|
|
2592
|
-
*
|
|
2593
|
-
* store.getLatestValue(); // { count: 5, isMaxValue: false }
|
|
2594
|
-
* ```
|
|
2595
|
-
*
|
|
2596
|
-
* @param preprocessor - The function to be called with the next and previous values before the state is updated.
|
|
2597
|
-
* @returns A `RemovePreprocessor` function that removes the preprocessor when called.
|
|
2598
|
-
*/
|
|
2599
|
-
addPreprocessor(preprocessor) {
|
|
2600
|
-
this.preprocessors.add(preprocessor);
|
|
2601
|
-
return () => {
|
|
2602
|
-
this.preprocessors.delete(preprocessor);
|
|
2603
|
-
};
|
|
2789
|
+
// src/messageComposer/middleware/attachmentManager/postUpload/uploadErrorHandler.ts
|
|
2790
|
+
var createUploadErrorHandlerMiddleware = (composer) => ({
|
|
2791
|
+
id: "stream-io/attachment-manager-middleware/upload-error",
|
|
2792
|
+
handlers: {
|
|
2793
|
+
postProcess: ({
|
|
2794
|
+
state,
|
|
2795
|
+
discard,
|
|
2796
|
+
forward
|
|
2797
|
+
}) => {
|
|
2798
|
+
const { attachment, error } = state;
|
|
2799
|
+
if (!error) return forward();
|
|
2800
|
+
if (!attachment) return discard();
|
|
2801
|
+
const reason = error instanceof Error ? error.message : "unknown error";
|
|
2802
|
+
composer.client.notifications.addError({
|
|
2803
|
+
message: "Error uploading attachment",
|
|
2804
|
+
origin: {
|
|
2805
|
+
emitter: "AttachmentManager",
|
|
2806
|
+
context: { attachment }
|
|
2807
|
+
},
|
|
2808
|
+
options: {
|
|
2809
|
+
type: "api:attachment:upload:failed",
|
|
2810
|
+
metadata: { reason },
|
|
2811
|
+
originalError: error
|
|
2812
|
+
}
|
|
2813
|
+
});
|
|
2814
|
+
return forward();
|
|
2815
|
+
}
|
|
2816
|
+
}
|
|
2817
|
+
});
|
|
2818
|
+
|
|
2819
|
+
// src/messageComposer/middleware/attachmentManager/postUpload/AttachmentPostUploadMiddlewareExecutor.ts
|
|
2820
|
+
var AttachmentPostUploadMiddlewareExecutor = class extends MiddlewareExecutor {
|
|
2821
|
+
constructor({ composer }) {
|
|
2822
|
+
super();
|
|
2823
|
+
this.use([
|
|
2824
|
+
createUploadErrorHandlerMiddleware(composer),
|
|
2825
|
+
createPostUploadAttachmentEnrichmentMiddleware()
|
|
2826
|
+
]);
|
|
2604
2827
|
}
|
|
2605
2828
|
};
|
|
2606
|
-
|
|
2607
|
-
|
|
2608
|
-
|
|
2609
|
-
|
|
2610
|
-
|
|
2611
|
-
|
|
2612
|
-
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
this.partialNext = () => {
|
|
2621
|
-
console.warn(
|
|
2622
|
-
`${_MergedStateStore.name}.partialNext is disabled, call original.partialNext or merged.partialNext instead`
|
|
2829
|
+
|
|
2830
|
+
// src/messageComposer/middleware/attachmentManager/preUpload/serverUploadConfigCheck.ts
|
|
2831
|
+
var createUploadConfigCheckMiddleware = (composer) => ({
|
|
2832
|
+
id: "stream-io/attachment-manager-middleware/file-upload-config-check",
|
|
2833
|
+
handlers: {
|
|
2834
|
+
prepare: async ({
|
|
2835
|
+
state,
|
|
2836
|
+
next,
|
|
2837
|
+
discard
|
|
2838
|
+
}) => {
|
|
2839
|
+
const { attachmentManager } = composer;
|
|
2840
|
+
if (!attachmentManager || !state.attachment) return discard();
|
|
2841
|
+
const uploadPermissionCheck = await attachmentManager.getUploadConfigCheck(
|
|
2842
|
+
state.attachment.localMetadata.file
|
|
2623
2843
|
);
|
|
2624
|
-
|
|
2625
|
-
|
|
2626
|
-
|
|
2627
|
-
|
|
2628
|
-
|
|
2629
|
-
|
|
2630
|
-
|
|
2631
|
-
* Subscribes to changes in the merged state store.
|
|
2632
|
-
*
|
|
2633
|
-
* This method extends the base subscribe functionality to handle the merged nature of this store:
|
|
2634
|
-
* 1. The first subscriber triggers registration of helper subscribers that listen to both source stores
|
|
2635
|
-
* 2. Changes from either source store are propagated to this merged store
|
|
2636
|
-
* 3. Source store values are cached to prevent unnecessary updates
|
|
2637
|
-
*
|
|
2638
|
-
* When the first subscriber is added, the method sets up listeners on both original and merged stores.
|
|
2639
|
-
* These listeners update the combined store value whenever either source store changes.
|
|
2640
|
-
* All subscriptions (helpers and the actual handler) are tracked so they can be properly cleaned up.
|
|
2641
|
-
*
|
|
2642
|
-
* @param handler - The callback function that will be executed when the state changes
|
|
2643
|
-
* @returns An unsubscribe function that, when called, removes the subscription and any helper subscriptions
|
|
2644
|
-
*/
|
|
2645
|
-
subscribe(handler) {
|
|
2646
|
-
const unsubscribeFunctions = [];
|
|
2647
|
-
if (!this.handlers.size) {
|
|
2648
|
-
const base = (nextValue) => {
|
|
2649
|
-
super.next((currentValue) => ({
|
|
2650
|
-
...currentValue,
|
|
2651
|
-
...nextValue
|
|
2652
|
-
}));
|
|
2844
|
+
const attachment = {
|
|
2845
|
+
...state.attachment,
|
|
2846
|
+
localMetadata: {
|
|
2847
|
+
...state.attachment.localMetadata,
|
|
2848
|
+
uploadPermissionCheck,
|
|
2849
|
+
uploadState: uploadPermissionCheck.uploadBlocked ? "blocked" : "pending"
|
|
2850
|
+
}
|
|
2653
2851
|
};
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
|
|
2658
|
-
base(nextValue);
|
|
2659
|
-
}),
|
|
2660
|
-
this.merged.subscribe((nextValue) => {
|
|
2661
|
-
if (nextValue === this.cachedMergedValue) return;
|
|
2662
|
-
this.cachedMergedValue = nextValue;
|
|
2663
|
-
base(nextValue);
|
|
2664
|
-
})
|
|
2665
|
-
);
|
|
2852
|
+
return next({
|
|
2853
|
+
...state,
|
|
2854
|
+
attachment
|
|
2855
|
+
});
|
|
2666
2856
|
}
|
|
2667
|
-
unsubscribeFunctions.push(super.subscribe(handler));
|
|
2668
|
-
return () => {
|
|
2669
|
-
unsubscribeFunctions.forEach((unsubscribe) => unsubscribe());
|
|
2670
|
-
};
|
|
2671
2857
|
}
|
|
2672
|
-
|
|
2673
|
-
|
|
2674
|
-
|
|
2675
|
-
|
|
2676
|
-
|
|
2677
|
-
|
|
2678
|
-
|
|
2679
|
-
|
|
2680
|
-
|
|
2681
|
-
|
|
2682
|
-
|
|
2683
|
-
|
|
2684
|
-
|
|
2685
|
-
|
|
2686
|
-
|
|
2687
|
-
|
|
2688
|
-
|
|
2689
|
-
|
|
2690
|
-
|
|
2691
|
-
|
|
2692
|
-
|
|
2693
|
-
|
|
2694
|
-
|
|
2695
|
-
|
|
2696
|
-
|
|
2697
|
-
...mergedValue
|
|
2698
|
-
};
|
|
2699
|
-
this.cachedMergedValue = mergedValue;
|
|
2700
|
-
this.cachedOriginalValue = originalValue;
|
|
2858
|
+
});
|
|
2859
|
+
|
|
2860
|
+
// src/messageComposer/middleware/attachmentManager/preUpload/blockedUploadNotification.ts
|
|
2861
|
+
var createBlockedAttachmentUploadNotificationMiddleware = (composer) => ({
|
|
2862
|
+
id: "stream-io/attachment-manager-middleware/blocked-upload-notification",
|
|
2863
|
+
handlers: {
|
|
2864
|
+
prepare: ({
|
|
2865
|
+
state: { attachment },
|
|
2866
|
+
forward
|
|
2867
|
+
}) => {
|
|
2868
|
+
if (!attachment) return forward();
|
|
2869
|
+
if (attachment.localMetadata.uploadPermissionCheck?.uploadBlocked) {
|
|
2870
|
+
composer.client.notifications.addError({
|
|
2871
|
+
message: `The attachment upload was blocked`,
|
|
2872
|
+
origin: {
|
|
2873
|
+
emitter: "AttachmentManager",
|
|
2874
|
+
context: { blockedAttachment: attachment }
|
|
2875
|
+
},
|
|
2876
|
+
options: {
|
|
2877
|
+
type: "validation:attachment:upload:blocked",
|
|
2878
|
+
metadata: {
|
|
2879
|
+
reason: attachment.localMetadata.uploadPermissionCheck?.reason
|
|
2880
|
+
}
|
|
2881
|
+
}
|
|
2882
|
+
});
|
|
2701
2883
|
}
|
|
2884
|
+
return forward();
|
|
2702
2885
|
}
|
|
2703
|
-
return super.getLatestValue();
|
|
2704
2886
|
}
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
|
|
2887
|
+
});
|
|
2888
|
+
|
|
2889
|
+
// src/messageComposer/middleware/attachmentManager/preUpload/AttachmentPreUploadMiddlewareExecutor.ts
|
|
2890
|
+
var AttachmentPreUploadMiddlewareExecutor = class extends MiddlewareExecutor {
|
|
2891
|
+
constructor({ composer }) {
|
|
2892
|
+
super();
|
|
2893
|
+
this.use([
|
|
2894
|
+
createUploadConfigCheckMiddleware(composer),
|
|
2895
|
+
createBlockedAttachmentUploadNotificationMiddleware(composer)
|
|
2896
|
+
]);
|
|
2710
2897
|
}
|
|
2711
2898
|
};
|
|
2712
2899
|
|
|
@@ -3336,11 +3523,12 @@ var _AttachmentManager = class _AttachmentManager {
|
|
|
3336
3523
|
uploadState: "finished"
|
|
3337
3524
|
}
|
|
3338
3525
|
};
|
|
3526
|
+
const previewUri = uploadedAttachment.localMetadata.previewUri;
|
|
3527
|
+
if (previewUri) {
|
|
3528
|
+
if (previewUri.startsWith("blob:")) URL.revokeObjectURL(previewUri);
|
|
3529
|
+
delete uploadedAttachment.localMetadata.previewUri;
|
|
3530
|
+
}
|
|
3339
3531
|
if (isLocalImageAttachment(uploadedAttachment)) {
|
|
3340
|
-
if (uploadedAttachment.localMetadata.previewUri) {
|
|
3341
|
-
URL.revokeObjectURL(uploadedAttachment.localMetadata.previewUri);
|
|
3342
|
-
delete uploadedAttachment.localMetadata.previewUri;
|
|
3343
|
-
}
|
|
3344
3532
|
uploadedAttachment.image_url = response.file;
|
|
3345
3533
|
} else {
|
|
3346
3534
|
uploadedAttachment.asset_url = response.file;
|
|
@@ -3521,12 +3709,10 @@ _AttachmentManager.toLocalUploadAttachment = (fileLike) => {
|
|
|
3521
3709
|
type: getAttachmentTypeFromMimeType(file.type)
|
|
3522
3710
|
};
|
|
3523
3711
|
localAttachment[isImageFile(file) ? "fallback" : "title"] = file.name;
|
|
3524
|
-
|
|
3525
|
-
|
|
3526
|
-
|
|
3527
|
-
|
|
3528
|
-
localAttachment.original_width = fileLike.width;
|
|
3529
|
-
}
|
|
3712
|
+
localAttachment.localMetadata.previewUri = isFileReference(fileLike) ? fileLike.uri : URL.createObjectURL?.(fileLike);
|
|
3713
|
+
if (isFileReference(fileLike) && fileLike.height && fileLike.width && isImageFile(file)) {
|
|
3714
|
+
localAttachment.original_height = fileLike.height;
|
|
3715
|
+
localAttachment.original_width = fileLike.width;
|
|
3530
3716
|
}
|
|
3531
3717
|
if (isFileReference(fileLike) && fileLike.thumb_url) {
|
|
3532
3718
|
localAttachment.thumb_url = fileLike.thumb_url;
|
|
@@ -6342,62 +6528,6 @@ var TextComposer = class {
|
|
|
6342
6528
|
// --- END TEXT PROCESSING ----
|
|
6343
6529
|
};
|
|
6344
6530
|
|
|
6345
|
-
// src/utils/WithSubscriptions.ts
|
|
6346
|
-
var _WithSubscriptions = class _WithSubscriptions {
|
|
6347
|
-
constructor() {
|
|
6348
|
-
this.unsubscribeFunctions = /* @__PURE__ */ new Set();
|
|
6349
|
-
this.refCount = 0;
|
|
6350
|
-
}
|
|
6351
|
-
/**
|
|
6352
|
-
* Returns a boolean, provides information of whether `registerSubscriptions`
|
|
6353
|
-
* method has already been called for this instance.
|
|
6354
|
-
*/
|
|
6355
|
-
get hasSubscriptions() {
|
|
6356
|
-
return this.unsubscribeFunctions.size > 0;
|
|
6357
|
-
}
|
|
6358
|
-
addUnsubscribeFunction(unsubscribeFunction) {
|
|
6359
|
-
this.unsubscribeFunctions.add(unsubscribeFunction);
|
|
6360
|
-
}
|
|
6361
|
-
/**
|
|
6362
|
-
* Increments `refCount` by one and returns new value.
|
|
6363
|
-
*/
|
|
6364
|
-
incrementRefCount() {
|
|
6365
|
-
return ++this.refCount;
|
|
6366
|
-
}
|
|
6367
|
-
/**
|
|
6368
|
-
* If you re-declare `unregisterSubscriptions` method within your class
|
|
6369
|
-
* make sure to run the original too.
|
|
6370
|
-
*
|
|
6371
|
-
* @example
|
|
6372
|
-
* ```ts
|
|
6373
|
-
* class T extends WithSubscriptions {
|
|
6374
|
-
* ...
|
|
6375
|
-
* public unregisterSubscriptions = () => {
|
|
6376
|
-
* this.customThing();
|
|
6377
|
-
* return super.unregisterSubscriptions();
|
|
6378
|
-
* }
|
|
6379
|
-
* }
|
|
6380
|
-
* ```
|
|
6381
|
-
*/
|
|
6382
|
-
unregisterSubscriptions() {
|
|
6383
|
-
if (this.refCount > 1) {
|
|
6384
|
-
this.refCount--;
|
|
6385
|
-
return _WithSubscriptions.symbol;
|
|
6386
|
-
}
|
|
6387
|
-
this.unsubscribeFunctions.forEach((unsubscribe) => unsubscribe());
|
|
6388
|
-
this.unsubscribeFunctions.clear();
|
|
6389
|
-
this.refCount = 0;
|
|
6390
|
-
return _WithSubscriptions.symbol;
|
|
6391
|
-
}
|
|
6392
|
-
};
|
|
6393
|
-
/**
|
|
6394
|
-
* Workaround for the missing TS keyword - ensures that inheritants
|
|
6395
|
-
* overriding `unregisterSubscriptions` call the base method and return
|
|
6396
|
-
* its unique symbol value.
|
|
6397
|
-
*/
|
|
6398
|
-
_WithSubscriptions.symbol = Symbol(_WithSubscriptions.name);
|
|
6399
|
-
var WithSubscriptions = _WithSubscriptions;
|
|
6400
|
-
|
|
6401
6531
|
// src/thread.ts
|
|
6402
6532
|
var DEFAULT_PAGE_LIMIT = 50;
|
|
6403
6533
|
var DEFAULT_SORT = [{ created_at: -1 }];
|
|
@@ -7984,6 +8114,7 @@ var Channel = class {
|
|
|
7984
8114
|
return msg && { timestampMs, msgId: msg.id };
|
|
7985
8115
|
}
|
|
7986
8116
|
});
|
|
8117
|
+
this.cooldownTimer = new CooldownTimer({ channel: this });
|
|
7987
8118
|
}
|
|
7988
8119
|
/**
|
|
7989
8120
|
* getClient - Get the chat client for this channel. If client.disconnect() was called, this function will error
|
|
@@ -9119,6 +9250,7 @@ var Channel = class {
|
|
|
9119
9250
|
].sort().join();
|
|
9120
9251
|
this.data = state.channel;
|
|
9121
9252
|
this.offlineMode = false;
|
|
9253
|
+
this.cooldownTimer.refresh();
|
|
9122
9254
|
if (areCapabilitiesChanged) {
|
|
9123
9255
|
this.getClient().dispatchEvent({
|
|
9124
9256
|
type: "capabilities.changed",
|
|
@@ -9500,6 +9632,9 @@ var Channel = class {
|
|
|
9500
9632
|
channelState.addPinnedMessage(event.message);
|
|
9501
9633
|
}
|
|
9502
9634
|
const preventUnreadCountUpdate = ownMessage || isThreadMessage;
|
|
9635
|
+
if (ownMessage) {
|
|
9636
|
+
this.cooldownTimer.refresh();
|
|
9637
|
+
}
|
|
9503
9638
|
if (preventUnreadCountUpdate) break;
|
|
9504
9639
|
if (event.user?.id) {
|
|
9505
9640
|
for (const userId in channelState.read) {
|
|
@@ -9634,6 +9769,7 @@ var Channel = class {
|
|
|
9634
9769
|
own_capabilities: event.channel?.own_capabilities ?? channel.data?.own_capabilities
|
|
9635
9770
|
};
|
|
9636
9771
|
channel.data = newChannelData;
|
|
9772
|
+
this.cooldownTimer.refresh();
|
|
9637
9773
|
}
|
|
9638
9774
|
break;
|
|
9639
9775
|
case "reaction.new":
|
|
@@ -9818,6 +9954,7 @@ var Channel = class {
|
|
|
9818
9954
|
}
|
|
9819
9955
|
);
|
|
9820
9956
|
this.disconnected = true;
|
|
9957
|
+
this.cooldownTimer.clearTimeout();
|
|
9821
9958
|
this.state.setIsUpToDate(false);
|
|
9822
9959
|
}
|
|
9823
9960
|
};
|
|
@@ -13954,6 +14091,7 @@ var StreamChat = class _StreamChat {
|
|
|
13954
14091
|
this.reminders.hydrateState(channelState.messages);
|
|
13955
14092
|
}
|
|
13956
14093
|
c.messageComposer.initStateFromChannelResponse(channelState);
|
|
14094
|
+
c.cooldownTimer.refresh();
|
|
13957
14095
|
channels.push(c);
|
|
13958
14096
|
}
|
|
13959
14097
|
this.syncDeliveredCandidates(channels);
|
|
@@ -14949,7 +15087,7 @@ var StreamChat = class _StreamChat {
|
|
|
14949
15087
|
if (this.userAgent) {
|
|
14950
15088
|
return this.userAgent;
|
|
14951
15089
|
}
|
|
14952
|
-
const version = "9.
|
|
15090
|
+
const version = "9.30.0";
|
|
14953
15091
|
const clientBundle = "browser-cjs";
|
|
14954
15092
|
let userAgentString = "";
|
|
14955
15093
|
if (this.sdkIdentifier) {
|