stream-chat 9.6.1 → 9.8.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.cjs +532 -57
- package/dist/cjs/index.browser.cjs.map +4 -4
- package/dist/cjs/index.node.cjs +538 -57
- package/dist/cjs/index.node.cjs.map +4 -4
- package/dist/esm/index.js +532 -57
- package/dist/esm/index.js.map +4 -4
- package/dist/types/channel.d.ts +36 -4
- package/dist/types/client.d.ts +38 -0
- package/dist/types/messageComposer/messageComposer.d.ts +4 -1
- package/dist/types/messageComposer/middleware/messageComposer/commandInjection.d.ts +4 -0
- package/dist/types/messageComposer/middleware/messageComposer/index.d.ts +1 -0
- package/dist/types/messageComposer/middleware/textComposer/activeCommandGuard.d.ts +4 -0
- package/dist/types/messageComposer/middleware/textComposer/commandStringExtraction.d.ts +5 -0
- package/dist/types/messageComposer/middleware/textComposer/commands.d.ts +5 -5
- package/dist/types/messageComposer/middleware/textComposer/index.d.ts +2 -0
- package/dist/types/messageComposer/middleware/textComposer/mentions.d.ts +1 -2
- package/dist/types/messageComposer/middleware/textComposer/textMiddlewareUtils.d.ts +6 -0
- package/dist/types/messageComposer/middleware/textComposer/types.d.ts +3 -2
- package/dist/types/messageComposer/textComposer.d.ts +6 -3
- package/dist/types/offline-support/offline_support_api.d.ts +39 -0
- package/dist/types/offline-support/types.d.ts +36 -2
- package/dist/types/pagination/BasePaginator.d.ts +1 -1
- package/dist/types/pagination/ReminderPaginator.d.ts +6 -2
- package/dist/types/reminders/ReminderManager.d.ts +3 -3
- package/dist/types/search/BaseSearchSource.d.ts +37 -31
- package/dist/types/search/ChannelSearchSource.d.ts +1 -1
- package/dist/types/search/MessageSearchSource.d.ts +1 -1
- package/dist/types/search/UserSearchSource.d.ts +1 -1
- package/dist/types/search/index.d.ts +1 -0
- package/dist/types/search/types.d.ts +20 -0
- package/dist/types/types.d.ts +6 -2
- package/dist/types/utils.d.ts +11 -2
- package/package.json +1 -1
- package/src/channel.ts +85 -10
- package/src/client.ts +61 -3
- package/src/messageComposer/messageComposer.ts +120 -14
- package/src/messageComposer/middleware/messageComposer/commandInjection.ts +72 -0
- package/src/messageComposer/middleware/messageComposer/index.ts +1 -0
- package/src/messageComposer/middleware/textComposer/activeCommandGuard.ts +20 -0
- package/src/messageComposer/middleware/textComposer/commandStringExtraction.ts +56 -0
- package/src/messageComposer/middleware/textComposer/commands.ts +28 -11
- package/src/messageComposer/middleware/textComposer/index.ts +2 -0
- package/src/messageComposer/middleware/textComposer/mentions.ts +1 -2
- package/src/messageComposer/middleware/textComposer/textMiddlewareUtils.ts +14 -0
- package/src/messageComposer/middleware/textComposer/types.ts +3 -2
- package/src/messageComposer/textComposer.ts +23 -3
- package/src/offline-support/offline_support_api.ts +79 -0
- package/src/offline-support/types.ts +41 -1
- package/src/pagination/BasePaginator.ts +1 -1
- package/src/pagination/ReminderPaginator.ts +20 -2
- package/src/reminders/ReminderManager.ts +16 -2
- package/src/search/BaseSearchSource.ts +123 -52
- package/src/search/ChannelSearchSource.ts +1 -1
- package/src/search/MessageSearchSource.ts +1 -1
- package/src/search/UserSearchSource.ts +1 -1
- package/src/search/index.ts +1 -0
- package/src/search/types.ts +20 -0
- package/src/types.ts +9 -2
- package/src/utils.ts +31 -2
|
@@ -161,6 +161,7 @@ __export(index_exports, {
|
|
|
161
161
|
AttachmentManager: () => AttachmentManager,
|
|
162
162
|
BasePaginator: () => BasePaginator,
|
|
163
163
|
BaseSearchSource: () => BaseSearchSource,
|
|
164
|
+
BaseSearchSourceSync: () => BaseSearchSourceSync,
|
|
164
165
|
BuiltinPermissions: () => BuiltinPermissions,
|
|
165
166
|
BuiltinRoles: () => BuiltinRoles,
|
|
166
167
|
Campaign: () => Campaign,
|
|
@@ -238,12 +239,16 @@ __export(index_exports, {
|
|
|
238
239
|
calculateLevenshtein: () => calculateLevenshtein,
|
|
239
240
|
channelManagerEventToHandlerMapping: () => channelManagerEventToHandlerMapping,
|
|
240
241
|
chatCodes: () => chatCodes,
|
|
242
|
+
createActiveCommandGuardMiddleware: () => createActiveCommandGuardMiddleware,
|
|
241
243
|
createAttachmentsCompositionMiddleware: () => createAttachmentsCompositionMiddleware,
|
|
244
|
+
createCommandInjectionMiddleware: () => createCommandInjectionMiddleware,
|
|
245
|
+
createCommandStringExtractionMiddleware: () => createCommandStringExtractionMiddleware,
|
|
242
246
|
createCommandsMiddleware: () => createCommandsMiddleware,
|
|
243
247
|
createCompositionDataCleanupMiddleware: () => createCompositionDataCleanupMiddleware,
|
|
244
248
|
createCompositionValidationMiddleware: () => createCompositionValidationMiddleware,
|
|
245
249
|
createCustomDataCompositionMiddleware: () => createCustomDataCompositionMiddleware,
|
|
246
250
|
createDraftAttachmentsCompositionMiddleware: () => createDraftAttachmentsCompositionMiddleware,
|
|
251
|
+
createDraftCommandInjectionMiddleware: () => createDraftCommandInjectionMiddleware,
|
|
247
252
|
createDraftCompositionValidationMiddleware: () => createDraftCompositionValidationMiddleware,
|
|
248
253
|
createDraftCustomDataCompositionMiddleware: () => createDraftCustomDataCompositionMiddleware,
|
|
249
254
|
createDraftLinkPreviewsCompositionMiddleware: () => createDraftLinkPreviewsCompositionMiddleware,
|
|
@@ -267,6 +272,7 @@ __export(index_exports, {
|
|
|
267
272
|
formatMessage: () => formatMessage,
|
|
268
273
|
generateFileName: () => generateFileName,
|
|
269
274
|
getAttachmentTypeFromMimeType: () => getAttachmentTypeFromMimeType,
|
|
275
|
+
getCompleteCommandInString: () => getCompleteCommandInString,
|
|
270
276
|
getExtensionFromMimeType: () => getExtensionFromMimeType,
|
|
271
277
|
getTokenizedSuggestionDisplayName: () => getTokenizedSuggestionDisplayName,
|
|
272
278
|
getTriggerCharWithToken: () => getTriggerCharWithToken,
|
|
@@ -2757,6 +2763,23 @@ function formatMessage(message) {
|
|
|
2757
2763
|
quoted_message: toLocalMessageBase(message.quoted_message)
|
|
2758
2764
|
};
|
|
2759
2765
|
}
|
|
2766
|
+
function unformatMessage(message) {
|
|
2767
|
+
const toMessageResponseBase = (msg) => {
|
|
2768
|
+
if (!msg) return null;
|
|
2769
|
+
const newDateString = (/* @__PURE__ */ new Date()).toISOString();
|
|
2770
|
+
return {
|
|
2771
|
+
...msg,
|
|
2772
|
+
created_at: message.created_at ? message.created_at.toISOString() : newDateString,
|
|
2773
|
+
deleted_at: message.deleted_at ? message.deleted_at.toISOString() : void 0,
|
|
2774
|
+
pinned_at: message.pinned_at ? message.pinned_at.toISOString() : void 0,
|
|
2775
|
+
updated_at: message.updated_at ? message.updated_at.toISOString() : newDateString
|
|
2776
|
+
};
|
|
2777
|
+
};
|
|
2778
|
+
return {
|
|
2779
|
+
...toMessageResponseBase(message),
|
|
2780
|
+
quoted_message: toMessageResponseBase(message.quoted_message)
|
|
2781
|
+
};
|
|
2782
|
+
}
|
|
2760
2783
|
var localMessageToNewMessagePayload = (localMessage) => {
|
|
2761
2784
|
const {
|
|
2762
2785
|
// Remove all timestamp fields and client-specific fields.
|
|
@@ -6291,16 +6314,83 @@ var MessageDraftComposerMiddlewareExecutor = class extends MiddlewareExecutor {
|
|
|
6291
6314
|
}
|
|
6292
6315
|
};
|
|
6293
6316
|
|
|
6317
|
+
// src/messageComposer/middleware/messageComposer/commandInjection.ts
|
|
6318
|
+
var createCommandInjectionMiddleware = (composer) => ({
|
|
6319
|
+
handlers: {
|
|
6320
|
+
compose: ({
|
|
6321
|
+
forward,
|
|
6322
|
+
next,
|
|
6323
|
+
state
|
|
6324
|
+
}) => {
|
|
6325
|
+
const command = composer.textComposer.command;
|
|
6326
|
+
if (!command) {
|
|
6327
|
+
return forward();
|
|
6328
|
+
}
|
|
6329
|
+
const { text } = state.localMessage;
|
|
6330
|
+
const injection = `/${command?.name}`;
|
|
6331
|
+
const enrichedText = `${injection} ${text}`;
|
|
6332
|
+
return next({
|
|
6333
|
+
...state,
|
|
6334
|
+
localMessage: {
|
|
6335
|
+
...state.localMessage,
|
|
6336
|
+
text: enrichedText
|
|
6337
|
+
},
|
|
6338
|
+
message: {
|
|
6339
|
+
...state.message,
|
|
6340
|
+
text: enrichedText
|
|
6341
|
+
}
|
|
6342
|
+
});
|
|
6343
|
+
}
|
|
6344
|
+
},
|
|
6345
|
+
id: "stream-io/message-composer-middleware/command-string-injection"
|
|
6346
|
+
});
|
|
6347
|
+
var createDraftCommandInjectionMiddleware = (composer) => ({
|
|
6348
|
+
handlers: {
|
|
6349
|
+
compose: ({
|
|
6350
|
+
forward,
|
|
6351
|
+
next,
|
|
6352
|
+
state
|
|
6353
|
+
}) => {
|
|
6354
|
+
const command = composer.textComposer.command;
|
|
6355
|
+
if (!command) {
|
|
6356
|
+
return forward();
|
|
6357
|
+
}
|
|
6358
|
+
const { text } = state.draft;
|
|
6359
|
+
const injection = `/${command?.name}`;
|
|
6360
|
+
const enrichedText = `${injection} ${text}`;
|
|
6361
|
+
return next({
|
|
6362
|
+
...state,
|
|
6363
|
+
draft: {
|
|
6364
|
+
...state.draft,
|
|
6365
|
+
text: enrichedText
|
|
6366
|
+
}
|
|
6367
|
+
});
|
|
6368
|
+
}
|
|
6369
|
+
},
|
|
6370
|
+
id: "stream-io/message-composer-middleware/draft-command-string-injection"
|
|
6371
|
+
});
|
|
6372
|
+
|
|
6373
|
+
// src/messageComposer/middleware/textComposer/activeCommandGuard.ts
|
|
6374
|
+
var createActiveCommandGuardMiddleware = () => ({
|
|
6375
|
+
handlers: {
|
|
6376
|
+
onChange: ({ complete, forward, state }) => {
|
|
6377
|
+
if (state.command) {
|
|
6378
|
+
return complete(state);
|
|
6379
|
+
}
|
|
6380
|
+
return forward();
|
|
6381
|
+
},
|
|
6382
|
+
onSuggestionItemSelect: ({ forward }) => forward()
|
|
6383
|
+
},
|
|
6384
|
+
id: "stream-io/text-composer/active-command-guard"
|
|
6385
|
+
});
|
|
6386
|
+
|
|
6294
6387
|
// src/search/BaseSearchSource.ts
|
|
6295
6388
|
var DEFAULT_SEARCH_SOURCE_OPTIONS = {
|
|
6296
6389
|
debounceMs: 300,
|
|
6297
6390
|
pageSize: 10
|
|
6298
6391
|
};
|
|
6299
|
-
var
|
|
6392
|
+
var BaseSearchSourceBase = class {
|
|
6300
6393
|
constructor(options) {
|
|
6301
|
-
this.setDebounceOptions = ({ debounceMs }) => {
|
|
6302
|
-
this.searchDebounced = debounce(this.executeQuery.bind(this), debounceMs);
|
|
6303
|
-
};
|
|
6304
6394
|
this.activate = () => {
|
|
6305
6395
|
if (this.isActive) return;
|
|
6306
6396
|
this.state.partialNext({ isActive: true });
|
|
@@ -6314,11 +6404,9 @@ var BaseSearchSource = class {
|
|
|
6314
6404
|
const searchString = newSearchString ?? this.searchQuery;
|
|
6315
6405
|
return !!(this.isActive && !this.isLoading && (this.hasNext || hasNewSearchQuery) && searchString);
|
|
6316
6406
|
};
|
|
6317
|
-
|
|
6318
|
-
const { debounceMs, pageSize } = { ...DEFAULT_SEARCH_SOURCE_OPTIONS, ...options };
|
|
6407
|
+
const { pageSize } = { ...DEFAULT_SEARCH_SOURCE_OPTIONS, ...options };
|
|
6319
6408
|
this.pageSize = pageSize;
|
|
6320
6409
|
this.state = new StateStore(this.initialState);
|
|
6321
|
-
this.setDebounceOptions({ debounceMs });
|
|
6322
6410
|
}
|
|
6323
6411
|
get lastQueryError() {
|
|
6324
6412
|
return this.state.getLatestValue().lastQueryError;
|
|
@@ -6378,8 +6466,7 @@ var BaseSearchSource = class {
|
|
|
6378
6466
|
items: isFirstPage ? stateUpdate.items : [...this.items ?? [], ...stateUpdate.items || []]
|
|
6379
6467
|
};
|
|
6380
6468
|
}
|
|
6381
|
-
|
|
6382
|
-
if (!this.canExecuteQuery(newSearchString)) return;
|
|
6469
|
+
prepareStateForQuery(newSearchString) {
|
|
6383
6470
|
const hasNewSearchQuery = typeof newSearchString !== "undefined";
|
|
6384
6471
|
const searchString = newSearchString ?? this.searchQuery;
|
|
6385
6472
|
if (hasNewSearchQuery) {
|
|
@@ -6387,18 +6474,47 @@ var BaseSearchSource = class {
|
|
|
6387
6474
|
} else {
|
|
6388
6475
|
this.state.partialNext({ isLoading: true });
|
|
6389
6476
|
}
|
|
6477
|
+
return { searchString, hasNewSearchQuery };
|
|
6478
|
+
}
|
|
6479
|
+
updatePaginationStateFromQuery(result) {
|
|
6480
|
+
const { items, next } = result;
|
|
6390
6481
|
const stateUpdate = {};
|
|
6482
|
+
if (next || next === null) {
|
|
6483
|
+
stateUpdate.next = next;
|
|
6484
|
+
stateUpdate.hasNext = !!next;
|
|
6485
|
+
} else {
|
|
6486
|
+
stateUpdate.offset = (this.offset ?? 0) + items.length;
|
|
6487
|
+
stateUpdate.hasNext = items.length === this.pageSize;
|
|
6488
|
+
}
|
|
6489
|
+
return stateUpdate;
|
|
6490
|
+
}
|
|
6491
|
+
resetState() {
|
|
6492
|
+
this.state.next(this.initialState);
|
|
6493
|
+
}
|
|
6494
|
+
resetStateAndActivate() {
|
|
6495
|
+
this.resetState();
|
|
6496
|
+
this.activate();
|
|
6497
|
+
}
|
|
6498
|
+
};
|
|
6499
|
+
var BaseSearchSource = class extends BaseSearchSourceBase {
|
|
6500
|
+
constructor(options) {
|
|
6501
|
+
const { debounceMs } = { ...DEFAULT_SEARCH_SOURCE_OPTIONS, ...options };
|
|
6502
|
+
super(options);
|
|
6503
|
+
this.setDebounceOptions = ({ debounceMs }) => {
|
|
6504
|
+
this.searchDebounced = debounce(this.executeQuery.bind(this), debounceMs);
|
|
6505
|
+
};
|
|
6506
|
+
this.search = (searchQuery) => this.searchDebounced(searchQuery);
|
|
6507
|
+
this.setDebounceOptions({ debounceMs });
|
|
6508
|
+
}
|
|
6509
|
+
async executeQuery(newSearchString) {
|
|
6510
|
+
if (!this.canExecuteQuery(newSearchString)) return;
|
|
6511
|
+
const { hasNewSearchQuery, searchString } = this.prepareStateForQuery(newSearchString);
|
|
6512
|
+
let stateUpdate = {};
|
|
6391
6513
|
try {
|
|
6392
6514
|
const results = await this.query(searchString);
|
|
6393
6515
|
if (!results) return;
|
|
6394
|
-
const { items
|
|
6395
|
-
|
|
6396
|
-
stateUpdate.next = next;
|
|
6397
|
-
stateUpdate.hasNext = !!next;
|
|
6398
|
-
} else {
|
|
6399
|
-
stateUpdate.offset = (this.offset ?? 0) + items.length;
|
|
6400
|
-
stateUpdate.hasNext = items.length === this.pageSize;
|
|
6401
|
-
}
|
|
6516
|
+
const { items } = results;
|
|
6517
|
+
stateUpdate = this.updatePaginationStateFromQuery(results);
|
|
6402
6518
|
stateUpdate.items = await this.filterQueryResults(items);
|
|
6403
6519
|
} catch (e) {
|
|
6404
6520
|
stateUpdate.lastQueryError = e;
|
|
@@ -6409,12 +6525,35 @@ var BaseSearchSource = class {
|
|
|
6409
6525
|
cancelScheduledQuery() {
|
|
6410
6526
|
this.searchDebounced.cancel();
|
|
6411
6527
|
}
|
|
6412
|
-
|
|
6413
|
-
|
|
6528
|
+
};
|
|
6529
|
+
var BaseSearchSourceSync = class extends BaseSearchSourceBase {
|
|
6530
|
+
constructor(options) {
|
|
6531
|
+
const { debounceMs } = { ...DEFAULT_SEARCH_SOURCE_OPTIONS, ...options };
|
|
6532
|
+
super(options);
|
|
6533
|
+
this.setDebounceOptions = ({ debounceMs }) => {
|
|
6534
|
+
this.searchDebounced = debounce(this.executeQuery.bind(this), debounceMs);
|
|
6535
|
+
};
|
|
6536
|
+
this.search = (searchQuery) => this.searchDebounced(searchQuery);
|
|
6537
|
+
this.setDebounceOptions({ debounceMs });
|
|
6414
6538
|
}
|
|
6415
|
-
|
|
6416
|
-
this.
|
|
6417
|
-
this.
|
|
6539
|
+
executeQuery(newSearchString) {
|
|
6540
|
+
if (!this.canExecuteQuery(newSearchString)) return;
|
|
6541
|
+
const { hasNewSearchQuery, searchString } = this.prepareStateForQuery(newSearchString);
|
|
6542
|
+
let stateUpdate = {};
|
|
6543
|
+
try {
|
|
6544
|
+
const results = this.query(searchString);
|
|
6545
|
+
if (!results) return;
|
|
6546
|
+
const { items } = results;
|
|
6547
|
+
stateUpdate = this.updatePaginationStateFromQuery(results);
|
|
6548
|
+
stateUpdate.items = this.filterQueryResults(items);
|
|
6549
|
+
} catch (e) {
|
|
6550
|
+
stateUpdate.lastQueryError = e;
|
|
6551
|
+
} finally {
|
|
6552
|
+
this.state.next(this.getStateAfterQuery(stateUpdate, hasNewSearchQuery));
|
|
6553
|
+
}
|
|
6554
|
+
}
|
|
6555
|
+
cancelScheduledQuery() {
|
|
6556
|
+
this.searchDebounced.cancel();
|
|
6418
6557
|
}
|
|
6419
6558
|
};
|
|
6420
6559
|
|
|
@@ -6648,6 +6787,11 @@ var getTriggerCharWithToken = ({
|
|
|
6648
6787
|
);
|
|
6649
6788
|
return match && match[match.length - 1].trim();
|
|
6650
6789
|
};
|
|
6790
|
+
var getCompleteCommandInString = (text) => {
|
|
6791
|
+
const match = text.match(/^\/(\S+)\s+.*/);
|
|
6792
|
+
const commandName = match && match[1];
|
|
6793
|
+
return commandName;
|
|
6794
|
+
};
|
|
6651
6795
|
var insertItemWithTrigger = ({
|
|
6652
6796
|
insertText,
|
|
6653
6797
|
selection,
|
|
@@ -6697,7 +6841,7 @@ var getTokenizedSuggestionDisplayName = ({
|
|
|
6697
6841
|
});
|
|
6698
6842
|
|
|
6699
6843
|
// src/messageComposer/middleware/textComposer/commands.ts
|
|
6700
|
-
var CommandSearchSource = class extends
|
|
6844
|
+
var CommandSearchSource = class extends BaseSearchSourceSync {
|
|
6701
6845
|
constructor(channel, options) {
|
|
6702
6846
|
super(options);
|
|
6703
6847
|
this.type = "commands";
|
|
@@ -6741,10 +6885,10 @@ var CommandSearchSource = class extends BaseSearchSource {
|
|
|
6741
6885
|
}
|
|
6742
6886
|
return 0;
|
|
6743
6887
|
});
|
|
6744
|
-
return
|
|
6888
|
+
return {
|
|
6745
6889
|
items: selectedCommands.map((c) => ({ ...c, id: c.name })),
|
|
6746
6890
|
next: null
|
|
6747
|
-
}
|
|
6891
|
+
};
|
|
6748
6892
|
}
|
|
6749
6893
|
filterQueryResults(items) {
|
|
6750
6894
|
return items;
|
|
@@ -6764,9 +6908,21 @@ var createCommandsMiddleware = (channel, options) => {
|
|
|
6764
6908
|
handlers: {
|
|
6765
6909
|
onChange: ({ state, next, complete, forward }) => {
|
|
6766
6910
|
if (!state.selection) return forward();
|
|
6911
|
+
const finalText = state.text.slice(0, state.selection.end);
|
|
6912
|
+
const commandName = getCompleteCommandInString(finalText);
|
|
6913
|
+
if (commandName) {
|
|
6914
|
+
const command = searchSource?.query(commandName).items[0];
|
|
6915
|
+
if (command) {
|
|
6916
|
+
return next({
|
|
6917
|
+
...state,
|
|
6918
|
+
command,
|
|
6919
|
+
suggestions: void 0
|
|
6920
|
+
});
|
|
6921
|
+
}
|
|
6922
|
+
}
|
|
6767
6923
|
const triggerWithToken = getTriggerCharWithToken({
|
|
6768
6924
|
trigger: finalOptions.trigger,
|
|
6769
|
-
text:
|
|
6925
|
+
text: finalText,
|
|
6770
6926
|
acceptTrailingSpaces: false,
|
|
6771
6927
|
isCommand: true
|
|
6772
6928
|
});
|
|
@@ -6785,6 +6941,7 @@ var createCommandsMiddleware = (channel, options) => {
|
|
|
6785
6941
|
}
|
|
6786
6942
|
return complete({
|
|
6787
6943
|
...state,
|
|
6944
|
+
command: null,
|
|
6788
6945
|
suggestions: {
|
|
6789
6946
|
query: triggerWithToken.slice(1),
|
|
6790
6947
|
searchSource,
|
|
@@ -6792,12 +6949,12 @@ var createCommandsMiddleware = (channel, options) => {
|
|
|
6792
6949
|
}
|
|
6793
6950
|
});
|
|
6794
6951
|
},
|
|
6795
|
-
onSuggestionItemSelect: ({ state,
|
|
6952
|
+
onSuggestionItemSelect: ({ state, next, forward }) => {
|
|
6796
6953
|
const { selectedSuggestion } = state.change ?? {};
|
|
6797
6954
|
if (!selectedSuggestion || state.suggestions?.trigger !== finalOptions.trigger)
|
|
6798
6955
|
return forward();
|
|
6799
6956
|
searchSource.resetStateAndActivate();
|
|
6800
|
-
return
|
|
6957
|
+
return next({
|
|
6801
6958
|
...state,
|
|
6802
6959
|
...insertItemWithTrigger({
|
|
6803
6960
|
insertText: `/${selectedSuggestion.name} `,
|
|
@@ -6805,6 +6962,7 @@ var createCommandsMiddleware = (channel, options) => {
|
|
|
6805
6962
|
text: state.text,
|
|
6806
6963
|
trigger: finalOptions.trigger
|
|
6807
6964
|
}),
|
|
6965
|
+
command: selectedSuggestion,
|
|
6808
6966
|
suggestions: void 0
|
|
6809
6967
|
});
|
|
6810
6968
|
}
|
|
@@ -6812,6 +6970,45 @@ var createCommandsMiddleware = (channel, options) => {
|
|
|
6812
6970
|
};
|
|
6813
6971
|
};
|
|
6814
6972
|
|
|
6973
|
+
// src/messageComposer/middleware/textComposer/commandStringExtraction.ts
|
|
6974
|
+
var stripCommandFromText = (text, commandName) => text.replace(new RegExp(`^${escapeRegExp(`/${commandName}`)}\\s*`), "");
|
|
6975
|
+
var createCommandStringExtractionMiddleware = () => ({
|
|
6976
|
+
handlers: {
|
|
6977
|
+
onChange: ({ complete, forward, state }) => {
|
|
6978
|
+
const { command } = state;
|
|
6979
|
+
if (!command?.name) {
|
|
6980
|
+
return forward();
|
|
6981
|
+
}
|
|
6982
|
+
const newText = stripCommandFromText(state.text, command.name);
|
|
6983
|
+
return complete({
|
|
6984
|
+
...state,
|
|
6985
|
+
selection: {
|
|
6986
|
+
end: newText.length,
|
|
6987
|
+
start: newText.length
|
|
6988
|
+
},
|
|
6989
|
+
text: newText
|
|
6990
|
+
});
|
|
6991
|
+
},
|
|
6992
|
+
onSuggestionItemSelect: ({ next, forward, state }) => {
|
|
6993
|
+
const { command } = state;
|
|
6994
|
+
if (!command) {
|
|
6995
|
+
return forward();
|
|
6996
|
+
}
|
|
6997
|
+
const triggerWithCommand = `/${command?.name} `;
|
|
6998
|
+
const newText = state.text.slice(triggerWithCommand.length);
|
|
6999
|
+
return next({
|
|
7000
|
+
...state,
|
|
7001
|
+
selection: {
|
|
7002
|
+
end: newText.length,
|
|
7003
|
+
start: newText.length
|
|
7004
|
+
},
|
|
7005
|
+
text: newText
|
|
7006
|
+
});
|
|
7007
|
+
}
|
|
7008
|
+
},
|
|
7009
|
+
id: "stream-io/text-composer/command-string-extraction"
|
|
7010
|
+
});
|
|
7011
|
+
|
|
6815
7012
|
// src/messageComposer/middleware/textComposer/mentions.ts
|
|
6816
7013
|
var accentsMap = {
|
|
6817
7014
|
a: "\xE1|\xE0|\xE3|\xE2|\xC0|\xC1|\xC3|\xC2",
|
|
@@ -7144,6 +7341,7 @@ var initState4 = ({
|
|
|
7144
7341
|
if (!message) {
|
|
7145
7342
|
const text2 = composer.config.text.defaultValue ?? "";
|
|
7146
7343
|
return {
|
|
7344
|
+
command: null,
|
|
7147
7345
|
mentionedUsers: [],
|
|
7148
7346
|
text: text2,
|
|
7149
7347
|
selection: { start: text2.length, end: text2.length }
|
|
@@ -7182,6 +7380,10 @@ var TextComposer = class {
|
|
|
7182
7380
|
mentionedUsers.splice(existingUserIndex, 1);
|
|
7183
7381
|
this.state.partialNext({ mentionedUsers });
|
|
7184
7382
|
};
|
|
7383
|
+
this.setCommand = (command) => {
|
|
7384
|
+
if (command?.name === this.command?.name) return;
|
|
7385
|
+
this.state.partialNext({ command });
|
|
7386
|
+
};
|
|
7185
7387
|
this.setText = (text) => {
|
|
7186
7388
|
if (!this.enabled || text === this.text) return;
|
|
7187
7389
|
this.state.partialNext({ text });
|
|
@@ -7191,7 +7393,10 @@ var TextComposer = class {
|
|
|
7191
7393
|
if (!this.enabled || !selectionChanged) return;
|
|
7192
7394
|
this.state.partialNext({ selection });
|
|
7193
7395
|
};
|
|
7194
|
-
this.insertText = ({
|
|
7396
|
+
this.insertText = async ({
|
|
7397
|
+
text,
|
|
7398
|
+
selection
|
|
7399
|
+
}) => {
|
|
7195
7400
|
if (!this.enabled) return;
|
|
7196
7401
|
const finalSelection = selection ?? this.selection;
|
|
7197
7402
|
const { maxLengthOnEdit } = this.composer.config.text ?? {};
|
|
@@ -7207,7 +7412,7 @@ var TextComposer = class {
|
|
|
7207
7412
|
);
|
|
7208
7413
|
const expectedCursorPosition = currentText.slice(0, finalSelection.start).length + text.length;
|
|
7209
7414
|
const cursorPosition = expectedCursorPosition >= finalText.length ? finalText.length : currentText.slice(0, expectedCursorPosition).length;
|
|
7210
|
-
this.
|
|
7415
|
+
await this.handleChange({
|
|
7211
7416
|
text: finalText,
|
|
7212
7417
|
selection: {
|
|
7213
7418
|
start: cursorPosition,
|
|
@@ -7327,6 +7532,9 @@ var TextComposer = class {
|
|
|
7327
7532
|
this.composer.updateConfig({ text: { publishTypingEvents } });
|
|
7328
7533
|
}
|
|
7329
7534
|
// --- START STATE API ---
|
|
7535
|
+
get command() {
|
|
7536
|
+
return this.state.getLatestValue().command;
|
|
7537
|
+
}
|
|
7330
7538
|
get mentionedUsers() {
|
|
7331
7539
|
return this.state.getLatestValue().mentionedUsers;
|
|
7332
7540
|
}
|
|
@@ -7345,6 +7553,9 @@ var TextComposer = class {
|
|
|
7345
7553
|
setMentionedUsers(users) {
|
|
7346
7554
|
this.state.partialNext({ mentionedUsers: users });
|
|
7347
7555
|
}
|
|
7556
|
+
clearCommand() {
|
|
7557
|
+
this.state.partialNext({ command: null });
|
|
7558
|
+
}
|
|
7348
7559
|
// --- END TEXT PROCESSING ----
|
|
7349
7560
|
};
|
|
7350
7561
|
|
|
@@ -7902,7 +8113,33 @@ var _MessageComposer = class _MessageComposer extends WithSubscriptions {
|
|
|
7902
8113
|
this.editedMessage = message;
|
|
7903
8114
|
}
|
|
7904
8115
|
};
|
|
8116
|
+
this.initStateFromChannelResponse = (channelApiResponse) => {
|
|
8117
|
+
if (this.channel.cid !== channelApiResponse.channel.cid) {
|
|
8118
|
+
return;
|
|
8119
|
+
}
|
|
8120
|
+
if (channelApiResponse.draft) {
|
|
8121
|
+
this.initState({ composition: channelApiResponse.draft });
|
|
8122
|
+
} else if (this.state.getLatestValue().draftId) {
|
|
8123
|
+
this.clear();
|
|
8124
|
+
this.client.offlineDb?.executeQuerySafely(
|
|
8125
|
+
(db) => db.deleteDraft({
|
|
8126
|
+
cid: this.channel.cid,
|
|
8127
|
+
parent_id: void 0
|
|
8128
|
+
// makes sure that we don't delete thread drafts while upserting channels
|
|
8129
|
+
}),
|
|
8130
|
+
{ method: "deleteDraft" }
|
|
8131
|
+
);
|
|
8132
|
+
}
|
|
8133
|
+
};
|
|
7905
8134
|
this.initEditingAuditState = (composition) => initEditingAuditState(composition);
|
|
8135
|
+
this.registerDraftEventSubscriptions = () => {
|
|
8136
|
+
const unsubscribeDraftUpdated = this.subscribeDraftUpdated();
|
|
8137
|
+
const unsubscribeDraftDeleted = this.subscribeDraftDeleted();
|
|
8138
|
+
return () => {
|
|
8139
|
+
unsubscribeDraftUpdated();
|
|
8140
|
+
unsubscribeDraftDeleted();
|
|
8141
|
+
};
|
|
8142
|
+
};
|
|
7906
8143
|
this.registerSubscriptions = () => {
|
|
7907
8144
|
if (!this.hasSubscriptions) {
|
|
7908
8145
|
this.addUnsubscribeFunction(this.subscribeMessageComposerSetupStateChange());
|
|
@@ -7967,13 +8204,13 @@ var _MessageComposer = class _MessageComposer extends WithSubscriptions {
|
|
|
7967
8204
|
}).unsubscribe;
|
|
7968
8205
|
this.subscribeDraftUpdated = () => this.client.on("draft.updated", (event) => {
|
|
7969
8206
|
const draft = event.draft;
|
|
7970
|
-
if (!draft ||
|
|
8207
|
+
if (!draft || (draft.parent_id ?? null) !== (this.threadId ?? null) || draft.channel_cid !== this.channel.cid)
|
|
7971
8208
|
return;
|
|
7972
8209
|
this.initState({ composition: draft });
|
|
7973
8210
|
}).unsubscribe;
|
|
7974
8211
|
this.subscribeDraftDeleted = () => this.client.on("draft.deleted", (event) => {
|
|
7975
8212
|
const draft = event.draft;
|
|
7976
|
-
if (!draft ||
|
|
8213
|
+
if (!draft || (draft.parent_id ?? null) !== (this.threadId ?? null) || draft.channel_cid !== this.channel.cid) {
|
|
7977
8214
|
return;
|
|
7978
8215
|
}
|
|
7979
8216
|
this.logDraftUpdateTimestamp();
|
|
@@ -8037,7 +8274,7 @@ var _MessageComposer = class _MessageComposer extends WithSubscriptions {
|
|
|
8037
8274
|
}
|
|
8038
8275
|
});
|
|
8039
8276
|
this.subscribeMessageComposerConfigStateChanged = () => {
|
|
8040
|
-
let
|
|
8277
|
+
let draftUnsubscribeFunction;
|
|
8041
8278
|
const unsubscribe = this.configState.subscribeWithSelector(
|
|
8042
8279
|
(currentValue) => ({
|
|
8043
8280
|
textDefaultValue: currentValue.text.defaultValue,
|
|
@@ -8050,19 +8287,16 @@ var _MessageComposer = class _MessageComposer extends WithSubscriptions {
|
|
|
8050
8287
|
selection: { start: 0, end: 0 }
|
|
8051
8288
|
});
|
|
8052
8289
|
}
|
|
8053
|
-
if (draftsEnabled && !
|
|
8054
|
-
|
|
8055
|
-
|
|
8056
|
-
|
|
8057
|
-
|
|
8058
|
-
} else if (!draftsEnabled && draftUnsubscribeFunctions) {
|
|
8059
|
-
draftUnsubscribeFunctions.forEach((fn) => fn());
|
|
8060
|
-
draftUnsubscribeFunctions = null;
|
|
8290
|
+
if (draftsEnabled && !draftUnsubscribeFunction) {
|
|
8291
|
+
draftUnsubscribeFunction = this.registerDraftEventSubscriptions();
|
|
8292
|
+
} else if (!draftsEnabled && draftUnsubscribeFunction) {
|
|
8293
|
+
draftUnsubscribeFunction();
|
|
8294
|
+
draftUnsubscribeFunction = null;
|
|
8061
8295
|
}
|
|
8062
8296
|
}
|
|
8063
8297
|
);
|
|
8064
8298
|
return () => {
|
|
8065
|
-
|
|
8299
|
+
draftUnsubscribeFunction?.();
|
|
8066
8300
|
unsubscribe();
|
|
8067
8301
|
};
|
|
8068
8302
|
};
|
|
@@ -8132,14 +8366,78 @@ var _MessageComposer = class _MessageComposer extends WithSubscriptions {
|
|
|
8132
8366
|
if (!composition) return;
|
|
8133
8367
|
const { draft } = composition;
|
|
8134
8368
|
this.state.partialNext({ draftId: draft.id });
|
|
8369
|
+
if (this.client.offlineDb) {
|
|
8370
|
+
try {
|
|
8371
|
+
const optimisticDraftResponse = {
|
|
8372
|
+
channel_cid: this.channel.cid,
|
|
8373
|
+
created_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
8374
|
+
message: draft,
|
|
8375
|
+
parent_id: draft.parent_id,
|
|
8376
|
+
quoted_message: this.quotedMessage ? unformatMessage(this.quotedMessage) : void 0
|
|
8377
|
+
};
|
|
8378
|
+
await this.client.offlineDb.upsertDraft({ draft: optimisticDraftResponse });
|
|
8379
|
+
} catch (error) {
|
|
8380
|
+
this.client.logger("error", `offlineDb:upsertDraft`, {
|
|
8381
|
+
tags: ["channel", "offlineDb"],
|
|
8382
|
+
error
|
|
8383
|
+
});
|
|
8384
|
+
}
|
|
8385
|
+
}
|
|
8135
8386
|
this.logDraftUpdateTimestamp();
|
|
8136
8387
|
await this.channel.createDraft(draft);
|
|
8137
8388
|
};
|
|
8138
8389
|
this.deleteDraft = async () => {
|
|
8139
8390
|
if (this.editedMessage || !this.config.drafts.enabled || !this.draftId) return;
|
|
8140
8391
|
this.state.partialNext({ draftId: null });
|
|
8392
|
+
const parentId = this.threadId ?? void 0;
|
|
8393
|
+
if (this.client.offlineDb) {
|
|
8394
|
+
try {
|
|
8395
|
+
await this.client.offlineDb.deleteDraft({
|
|
8396
|
+
cid: this.channel.cid,
|
|
8397
|
+
parent_id: parentId
|
|
8398
|
+
});
|
|
8399
|
+
} catch (error) {
|
|
8400
|
+
this.client.logger("error", `offlineDb:deleteDraft`, {
|
|
8401
|
+
tags: ["channel", "offlineDb"],
|
|
8402
|
+
error
|
|
8403
|
+
});
|
|
8404
|
+
}
|
|
8405
|
+
}
|
|
8141
8406
|
this.logDraftUpdateTimestamp();
|
|
8142
|
-
await this.channel.deleteDraft({ parent_id:
|
|
8407
|
+
await this.channel.deleteDraft({ parent_id: parentId });
|
|
8408
|
+
};
|
|
8409
|
+
this.getDraft = async () => {
|
|
8410
|
+
if (this.editedMessage || !this.config.drafts.enabled || !this.client.userID) return;
|
|
8411
|
+
const draftFromOfflineDB = await this.client.offlineDb?.getDraft({
|
|
8412
|
+
cid: this.channel.cid,
|
|
8413
|
+
userId: this.client.userID,
|
|
8414
|
+
parent_id: this.threadId ?? void 0
|
|
8415
|
+
});
|
|
8416
|
+
if (draftFromOfflineDB) {
|
|
8417
|
+
this.initState({ composition: draftFromOfflineDB });
|
|
8418
|
+
}
|
|
8419
|
+
try {
|
|
8420
|
+
const response = await this.channel.getDraft({
|
|
8421
|
+
parent_id: this.threadId ?? void 0
|
|
8422
|
+
});
|
|
8423
|
+
const { draft } = response;
|
|
8424
|
+
if (!draft) return;
|
|
8425
|
+
this.client.offlineDb?.executeQuerySafely(
|
|
8426
|
+
(db) => db.upsertDraft({
|
|
8427
|
+
draft
|
|
8428
|
+
}),
|
|
8429
|
+
{ method: "upsertDraft" }
|
|
8430
|
+
);
|
|
8431
|
+
this.initState({ composition: draft });
|
|
8432
|
+
} catch (error) {
|
|
8433
|
+
this.client.notifications.add({
|
|
8434
|
+
message: "Failed to get the draft",
|
|
8435
|
+
origin: {
|
|
8436
|
+
emitter: "MessageComposer",
|
|
8437
|
+
context: { composer: this }
|
|
8438
|
+
}
|
|
8439
|
+
});
|
|
8440
|
+
}
|
|
8143
8441
|
};
|
|
8144
8442
|
this.createPoll = async () => {
|
|
8145
8443
|
const composition = await this.pollComposer.compose();
|
|
@@ -8268,6 +8566,9 @@ var _MessageComposer = class _MessageComposer extends WithSubscriptions {
|
|
|
8268
8566
|
return this.state.getLatestValue().showReplyInChannel;
|
|
8269
8567
|
}
|
|
8270
8568
|
get hasSendableData() {
|
|
8569
|
+
if (this.client.offlineDb) {
|
|
8570
|
+
return !this.compositionIsEmpty;
|
|
8571
|
+
}
|
|
8271
8572
|
return !!(!this.attachmentManager.uploadsInProgressCount && (!this.textComposer.textIsEmpty || this.attachmentManager.successfulUploadsCount > 0) || this.pollId);
|
|
8272
8573
|
}
|
|
8273
8574
|
get compositionIsEmpty() {
|
|
@@ -8583,6 +8884,17 @@ var Channel = class {
|
|
|
8583
8884
|
updates
|
|
8584
8885
|
);
|
|
8585
8886
|
}
|
|
8887
|
+
/**
|
|
8888
|
+
* sendReaction - Sends a reaction to a message. If offline support is enabled, it will make sure
|
|
8889
|
+
* that sending the reaction is queued up if it fails due to bad internet conditions and executed
|
|
8890
|
+
* later.
|
|
8891
|
+
*
|
|
8892
|
+
* @param {string} messageID the message id
|
|
8893
|
+
* @param {Reaction} reaction the reaction object for instance {type: 'love'}
|
|
8894
|
+
* @param {{ enforce_unique?: boolean, skip_push?: boolean }} [options] Option object, {enforce_unique: true, skip_push: true} to override any existing reaction or skip sending push notifications
|
|
8895
|
+
*
|
|
8896
|
+
* @return {Promise<ReactionAPIResponse>} The Server Response
|
|
8897
|
+
*/
|
|
8586
8898
|
async sendReaction(messageID, reaction, options) {
|
|
8587
8899
|
if (!messageID) {
|
|
8588
8900
|
throw Error(`Message id is missing`);
|
|
@@ -9435,9 +9747,7 @@ var Channel = class {
|
|
|
9435
9747
|
};
|
|
9436
9748
|
this.getClient().polls.hydratePollCache(state.messages, true);
|
|
9437
9749
|
this.getClient().reminders.hydrateState(state.messages);
|
|
9438
|
-
|
|
9439
|
-
this.messageComposer.initState({ composition: state.draft });
|
|
9440
|
-
}
|
|
9750
|
+
this.messageComposer.initStateFromChannelResponse(state);
|
|
9441
9751
|
const areCapabilitiesChanged = [...state.channel.own_capabilities || []].sort().join() !== [
|
|
9442
9752
|
...this.data && Array.isArray(this.data?.own_capabilities) ? this.data.own_capabilities : []
|
|
9443
9753
|
].sort().join();
|
|
@@ -9564,13 +9874,11 @@ var Channel = class {
|
|
|
9564
9874
|
/**
|
|
9565
9875
|
* createDraft - Creates or updates a draft message in a channel
|
|
9566
9876
|
*
|
|
9567
|
-
* @param {string} channelType The channel type
|
|
9568
|
-
* @param {string} channelID The channel ID
|
|
9569
9877
|
* @param {DraftMessagePayload} message The draft message to create or update
|
|
9570
9878
|
*
|
|
9571
9879
|
* @return {Promise<CreateDraftResponse>} Response containing the created draft
|
|
9572
9880
|
*/
|
|
9573
|
-
async
|
|
9881
|
+
async _createDraft(message) {
|
|
9574
9882
|
return await this.getClient().post(
|
|
9575
9883
|
this._channelURL() + "/draft",
|
|
9576
9884
|
{
|
|
@@ -9579,18 +9887,82 @@ var Channel = class {
|
|
|
9579
9887
|
);
|
|
9580
9888
|
}
|
|
9581
9889
|
/**
|
|
9582
|
-
*
|
|
9890
|
+
* createDraft - Creates or updates a draft message in a channel. If offline support is
|
|
9891
|
+
* enabled, it will make sure that creating the draft is queued up if it fails due to
|
|
9892
|
+
* bad internet conditions and executed later.
|
|
9893
|
+
*
|
|
9894
|
+
* @param {DraftMessagePayload} message The draft message to create or update
|
|
9895
|
+
*
|
|
9896
|
+
* @return {Promise<CreateDraftResponse>} Response containing the created draft
|
|
9897
|
+
*/
|
|
9898
|
+
async createDraft(message) {
|
|
9899
|
+
try {
|
|
9900
|
+
const offlineDb = this.getClient().offlineDb;
|
|
9901
|
+
if (offlineDb) {
|
|
9902
|
+
return await offlineDb.queueTask({
|
|
9903
|
+
task: {
|
|
9904
|
+
channelId: this.id,
|
|
9905
|
+
channelType: this.type,
|
|
9906
|
+
threadId: message.parent_id,
|
|
9907
|
+
payload: [message],
|
|
9908
|
+
type: "create-draft"
|
|
9909
|
+
}
|
|
9910
|
+
});
|
|
9911
|
+
}
|
|
9912
|
+
} catch (error) {
|
|
9913
|
+
this._client.logger("error", `offlineDb:create-draft`, {
|
|
9914
|
+
tags: ["channel", "offlineDb"],
|
|
9915
|
+
error
|
|
9916
|
+
});
|
|
9917
|
+
}
|
|
9918
|
+
return this._createDraft(message);
|
|
9919
|
+
}
|
|
9920
|
+
/**
|
|
9921
|
+
* deleteDraft - Deletes a draft message from a channel or a thread.
|
|
9583
9922
|
*
|
|
9584
9923
|
* @param {Object} options
|
|
9585
9924
|
* @param {string} options.parent_id Optional parent message ID for drafts in threads
|
|
9586
9925
|
*
|
|
9587
9926
|
* @return {Promise<APIResponse>} API response
|
|
9588
9927
|
*/
|
|
9589
|
-
async
|
|
9928
|
+
async _deleteDraft({ parent_id } = {}) {
|
|
9590
9929
|
return await this.getClient().delete(this._channelURL() + "/draft", {
|
|
9591
9930
|
parent_id
|
|
9592
9931
|
});
|
|
9593
9932
|
}
|
|
9933
|
+
/**
|
|
9934
|
+
* deleteDraft - Deletes a draft message from a channel or a thread. If offline support is
|
|
9935
|
+
* enabled, it will make sure that deleting the draft is queued up if it fails due to
|
|
9936
|
+
* bad internet conditions and executed later.
|
|
9937
|
+
*
|
|
9938
|
+
* @param {Object} options
|
|
9939
|
+
* @param {string} options.parent_id Optional parent message ID for drafts in threads
|
|
9940
|
+
*
|
|
9941
|
+
* @return {Promise<APIResponse>} API response
|
|
9942
|
+
*/
|
|
9943
|
+
async deleteDraft(options = {}) {
|
|
9944
|
+
const { parent_id } = options;
|
|
9945
|
+
try {
|
|
9946
|
+
const offlineDb = this.getClient().offlineDb;
|
|
9947
|
+
if (offlineDb) {
|
|
9948
|
+
return await offlineDb.queueTask({
|
|
9949
|
+
task: {
|
|
9950
|
+
channelId: this.id,
|
|
9951
|
+
channelType: this.type,
|
|
9952
|
+
threadId: parent_id,
|
|
9953
|
+
payload: [options],
|
|
9954
|
+
type: "delete-draft"
|
|
9955
|
+
}
|
|
9956
|
+
});
|
|
9957
|
+
}
|
|
9958
|
+
} catch (error) {
|
|
9959
|
+
this._client.logger("error", `offlineDb:delete-draft`, {
|
|
9960
|
+
tags: ["channel", "offlineDb"],
|
|
9961
|
+
error
|
|
9962
|
+
});
|
|
9963
|
+
}
|
|
9964
|
+
return this._deleteDraft(options);
|
|
9965
|
+
}
|
|
9594
9966
|
/**
|
|
9595
9967
|
* getDraft - Retrieves a draft message from a channel
|
|
9596
9968
|
*
|
|
@@ -12744,6 +13116,20 @@ var ReminderPaginator = class extends BasePaginator {
|
|
|
12744
13116
|
this.filterQueryResults = (items) => items;
|
|
12745
13117
|
this.client = client;
|
|
12746
13118
|
}
|
|
13119
|
+
get filters() {
|
|
13120
|
+
return this._filters;
|
|
13121
|
+
}
|
|
13122
|
+
get sort() {
|
|
13123
|
+
return this._sort;
|
|
13124
|
+
}
|
|
13125
|
+
set filters(filters) {
|
|
13126
|
+
this._filters = filters;
|
|
13127
|
+
this.resetState();
|
|
13128
|
+
}
|
|
13129
|
+
set sort(sort) {
|
|
13130
|
+
this._sort = sort;
|
|
13131
|
+
this.resetState();
|
|
13132
|
+
}
|
|
12747
13133
|
};
|
|
12748
13134
|
|
|
12749
13135
|
// src/reminders/ReminderManager.ts
|
|
@@ -12758,7 +13144,8 @@ var DEFAULT_REMINDER_MANAGER_CONFIG = {
|
|
|
12758
13144
|
2 * oneHour2,
|
|
12759
13145
|
8 * oneHour2,
|
|
12760
13146
|
oneDay2
|
|
12761
|
-
]
|
|
13147
|
+
],
|
|
13148
|
+
stopTimerRefreshBoundaryMs: DEFAULT_STOP_REFRESH_BOUNDARY_MS
|
|
12762
13149
|
};
|
|
12763
13150
|
var isReminderExistsError = (error) => error.message.match("already has reminder created for this message_id");
|
|
12764
13151
|
var isReminderDoesNotExistError = (error) => error.message.match("reminder does not exist");
|
|
@@ -12909,13 +13296,19 @@ var _ReminderManager = class _ReminderManager extends WithSubscriptions {
|
|
|
12909
13296
|
};
|
|
12910
13297
|
this.client = client;
|
|
12911
13298
|
this.configState = new StateStore({
|
|
12912
|
-
scheduledOffsetsMs: config?.scheduledOffsetsMs ?? DEFAULT_REMINDER_MANAGER_CONFIG.scheduledOffsetsMs
|
|
13299
|
+
scheduledOffsetsMs: config?.scheduledOffsetsMs ?? DEFAULT_REMINDER_MANAGER_CONFIG.scheduledOffsetsMs,
|
|
13300
|
+
stopTimerRefreshBoundaryMs: config?.stopTimerRefreshBoundaryMs ?? DEFAULT_REMINDER_MANAGER_CONFIG.stopTimerRefreshBoundaryMs
|
|
12913
13301
|
});
|
|
12914
13302
|
this.state = new StateStore({ reminders: /* @__PURE__ */ new Map() });
|
|
12915
13303
|
this.paginator = new ReminderPaginator(client);
|
|
12916
13304
|
}
|
|
12917
13305
|
// Config API START //
|
|
12918
13306
|
updateConfig(config) {
|
|
13307
|
+
if (typeof config.stopTimerRefreshBoundaryMs === "number" && config.stopTimerRefreshBoundaryMs !== this.stopTimerRefreshBoundaryMs) {
|
|
13308
|
+
this.reminders.forEach((reminder) => {
|
|
13309
|
+
reminder.timer.stopRefreshBoundaryMs = config?.stopTimerRefreshBoundaryMs;
|
|
13310
|
+
});
|
|
13311
|
+
}
|
|
12919
13312
|
this.configState.partialNext(config);
|
|
12920
13313
|
}
|
|
12921
13314
|
get stopTimerRefreshBoundaryMs() {
|
|
@@ -14240,9 +14633,7 @@ var StreamChat = class _StreamChat {
|
|
|
14240
14633
|
this.polls.hydratePollCache(channelState.messages, true);
|
|
14241
14634
|
this.reminders.hydrateState(channelState.messages);
|
|
14242
14635
|
}
|
|
14243
|
-
|
|
14244
|
-
c.messageComposer.initState({ composition: channelState.draft });
|
|
14245
|
-
}
|
|
14636
|
+
c.messageComposer.initStateFromChannelResponse(channelState);
|
|
14246
14637
|
channels.push(c);
|
|
14247
14638
|
}
|
|
14248
14639
|
return channels;
|
|
@@ -15159,7 +15550,7 @@ var StreamChat = class _StreamChat {
|
|
|
15159
15550
|
if (this.userAgent) {
|
|
15160
15551
|
return this.userAgent;
|
|
15161
15552
|
}
|
|
15162
|
-
const version = "9.
|
|
15553
|
+
const version = "9.8.0";
|
|
15163
15554
|
const clientBundle = "browser-cjs";
|
|
15164
15555
|
let userAgentString = "";
|
|
15165
15556
|
if (this.sdkIdentifier) {
|
|
@@ -16248,6 +16639,52 @@ var StreamChat = class _StreamChat {
|
|
|
16248
16639
|
...rest
|
|
16249
16640
|
});
|
|
16250
16641
|
}
|
|
16642
|
+
/**
|
|
16643
|
+
* uploadFile - Uploads a file to the configured storage (defaults to Stream CDN)
|
|
16644
|
+
*
|
|
16645
|
+
* @param {string|NodeJS.ReadableStream|Buffer|File} uri The file to upload
|
|
16646
|
+
* @param {string} [name] The name of the file
|
|
16647
|
+
* @param {string} [contentType] The content type of the file
|
|
16648
|
+
* @param {UserResponse} [user] Optional user information
|
|
16649
|
+
*
|
|
16650
|
+
* @return {Promise<SendFileAPIResponse>} Response containing the file URL
|
|
16651
|
+
*/
|
|
16652
|
+
uploadFile(uri, name, contentType, user) {
|
|
16653
|
+
return this.sendFile(`${this.baseURL}/uploads/file`, uri, name, contentType, user);
|
|
16654
|
+
}
|
|
16655
|
+
/**
|
|
16656
|
+
* uploadImage - Uploads an image to the configured storage (defaults to Stream CDN)
|
|
16657
|
+
*
|
|
16658
|
+
* @param {string|NodeJS.ReadableStream|File} uri The image to upload
|
|
16659
|
+
* @param {string} [name] The name of the image
|
|
16660
|
+
* @param {string} [contentType] The content type of the image
|
|
16661
|
+
* @param {UserResponse} [user] Optional user information
|
|
16662
|
+
*
|
|
16663
|
+
* @return {Promise<SendFileAPIResponse>} Response containing the image URL
|
|
16664
|
+
*/
|
|
16665
|
+
uploadImage(uri, name, contentType, user) {
|
|
16666
|
+
return this.sendFile(`${this.baseURL}/uploads/image`, uri, name, contentType, user);
|
|
16667
|
+
}
|
|
16668
|
+
/**
|
|
16669
|
+
* deleteFile - Deletes a file from the configured storage
|
|
16670
|
+
*
|
|
16671
|
+
* @param {string} url The URL of the file to delete
|
|
16672
|
+
*
|
|
16673
|
+
* @return {Promise<APIResponse>} The server response
|
|
16674
|
+
*/
|
|
16675
|
+
deleteFile(url) {
|
|
16676
|
+
return this.delete(`${this.baseURL}/uploads/file`, { url });
|
|
16677
|
+
}
|
|
16678
|
+
/**
|
|
16679
|
+
* deleteImage - Deletes an image from the configured storage
|
|
16680
|
+
*
|
|
16681
|
+
* @param {string} url The URL of the image to delete
|
|
16682
|
+
*
|
|
16683
|
+
* @return {Promise<APIResponse>} The server response
|
|
16684
|
+
*/
|
|
16685
|
+
deleteImage(url) {
|
|
16686
|
+
return this.delete(`${this.baseURL}/uploads/image`, { url });
|
|
16687
|
+
}
|
|
16251
16688
|
};
|
|
16252
16689
|
|
|
16253
16690
|
// src/events.ts
|
|
@@ -16956,6 +17393,35 @@ var AbstractOfflineDB = class {
|
|
|
16956
17393
|
(executeOverride) => reactionMethod({ message, reaction, execute: executeOverride })
|
|
16957
17394
|
);
|
|
16958
17395
|
};
|
|
17396
|
+
/**
|
|
17397
|
+
* A utility handler for all draft events:
|
|
17398
|
+
* - draft.updated -> updateDraft
|
|
17399
|
+
* - draft.deleted -> deleteDraft
|
|
17400
|
+
* @param event - the WS event we are trying to process
|
|
17401
|
+
* @param execute - whether to immediately execute the operation.
|
|
17402
|
+
*/
|
|
17403
|
+
this.handleDraftEvent = async ({
|
|
17404
|
+
event,
|
|
17405
|
+
execute = true
|
|
17406
|
+
}) => {
|
|
17407
|
+
const { cid, draft, type } = event;
|
|
17408
|
+
if (!draft) return [];
|
|
17409
|
+
if (type === "draft.updated") {
|
|
17410
|
+
return await this.upsertDraft({
|
|
17411
|
+
draft,
|
|
17412
|
+
execute
|
|
17413
|
+
});
|
|
17414
|
+
}
|
|
17415
|
+
if (type === "draft.deleted") {
|
|
17416
|
+
if (!cid) return [];
|
|
17417
|
+
return await this.deleteDraft({
|
|
17418
|
+
cid,
|
|
17419
|
+
parent_id: draft.parent_id,
|
|
17420
|
+
execute
|
|
17421
|
+
});
|
|
17422
|
+
}
|
|
17423
|
+
return [];
|
|
17424
|
+
};
|
|
16959
17425
|
/**
|
|
16960
17426
|
* A generic event handler that decides which DB API to invoke based on
|
|
16961
17427
|
* event.type for all events we are currently handling. It is used to both
|
|
@@ -16992,6 +17458,9 @@ var AbstractOfflineDB = class {
|
|
|
16992
17458
|
if (type === "channel.hidden" || type === "channel.visible") {
|
|
16993
17459
|
return await this.handleChannelVisibilityEvent({ event, execute });
|
|
16994
17460
|
}
|
|
17461
|
+
if (type === "draft.updated" || type === "draft.deleted") {
|
|
17462
|
+
return await this.handleDraftEvent({ event, execute });
|
|
17463
|
+
}
|
|
16995
17464
|
if ((type === "channel.updated" || type === "notification.message_new" || type === "notification.added_to_channel") && channel) {
|
|
16996
17465
|
return await this.upsertChannelData({ channel, execute });
|
|
16997
17466
|
}
|
|
@@ -17066,6 +17535,12 @@ var AbstractOfflineDB = class {
|
|
|
17066
17535
|
if (task.type === "delete-reaction") {
|
|
17067
17536
|
return await channel._deleteReaction(...task.payload);
|
|
17068
17537
|
}
|
|
17538
|
+
if (task.type === "create-draft") {
|
|
17539
|
+
return await channel._createDraft(...task.payload);
|
|
17540
|
+
}
|
|
17541
|
+
if (task.type === "delete-draft") {
|
|
17542
|
+
return await channel._deleteDraft(...task.payload);
|
|
17543
|
+
}
|
|
17069
17544
|
if (task.type === "send-message") {
|
|
17070
17545
|
const newMessageResponse = await channel._sendMessage(...task.payload);
|
|
17071
17546
|
const newMessage = newMessageResponse?.message;
|