stream-chat 9.5.0 → 9.6.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/esm/index.js CHANGED
@@ -4631,7 +4631,8 @@ var AttachmentManager = class {
4631
4631
  if (!attachment.localMetadata?.file || !attachment.localMetadata.id) {
4632
4632
  this.client.notifications.addError({
4633
4633
  message: "File is required for upload attachment",
4634
- origin: { emitter: "AttachmentManager", context: { attachment } }
4634
+ origin: { emitter: "AttachmentManager", context: { attachment } },
4635
+ options: { type: "validation:attachment:file:missing" }
4635
4636
  });
4636
4637
  return;
4637
4638
  }
@@ -4681,8 +4682,17 @@ var AttachmentManager = class {
4681
4682
  if (localAttachment.localMetadata.uploadState === "blocked") {
4682
4683
  this.upsertAttachments([localAttachment]);
4683
4684
  this.client.notifications.addError({
4684
- message: "Error uploading attachment",
4685
- origin: { emitter: "AttachmentManager", context: { attachment } }
4685
+ message: `The attachment upload was blocked`,
4686
+ origin: {
4687
+ emitter: "AttachmentManager",
4688
+ context: { attachment, blockedAttachment: localAttachment }
4689
+ },
4690
+ options: {
4691
+ type: "validation:attachment:upload:blocked",
4692
+ metadata: {
4693
+ reason: localAttachment.localMetadata.uploadPermissionCheck?.reason
4694
+ }
4695
+ }
4686
4696
  });
4687
4697
  return localAttachment;
4688
4698
  }
@@ -4699,19 +4709,7 @@ var AttachmentManager = class {
4699
4709
  try {
4700
4710
  response = await this.doUploadRequest(localAttachment.localMetadata.file);
4701
4711
  } catch (error) {
4702
- let finalError = {
4703
- message: "Error uploading attachment",
4704
- name: "Error"
4705
- };
4706
- if (typeof error.message === "string") {
4707
- finalError = error;
4708
- } else if (typeof error === "object") {
4709
- finalError = Object.assign(finalError, error);
4710
- }
4711
- this.client.notifications.addError({
4712
- message: finalError.message,
4713
- origin: { emitter: "AttachmentManager", context: { attachment } }
4714
- });
4712
+ const reason = error instanceof Error ? error.message : "unknown error";
4715
4713
  const failedAttachment = {
4716
4714
  ...attachment,
4717
4715
  localMetadata: {
@@ -4719,6 +4717,18 @@ var AttachmentManager = class {
4719
4717
  uploadState: "failed"
4720
4718
  }
4721
4719
  };
4720
+ this.client.notifications.addError({
4721
+ message: "Error uploading attachment",
4722
+ origin: {
4723
+ emitter: "AttachmentManager",
4724
+ context: { attachment, failedAttachment }
4725
+ },
4726
+ options: {
4727
+ type: "api:attachment:upload:failed",
4728
+ metadata: { reason },
4729
+ originalError: error instanceof Error ? error : void 0
4730
+ }
4731
+ });
4722
4732
  this.updateAttachment(failedAttachment);
4723
4733
  return failedAttachment;
4724
4734
  }
@@ -6411,15 +6421,14 @@ var pollStateChangeValidators = {
6411
6421
  return { max_votes_allowed: "Type a number from 2 to 10" };
6412
6422
  return { max_votes_allowed: void 0 };
6413
6423
  },
6414
- options: ({ value }) => {
6424
+ options: ({ value: options }) => {
6415
6425
  const errors = {};
6416
6426
  const seenOptions = /* @__PURE__ */ new Set();
6417
- value.forEach((option) => {
6418
- const trimmedText = option.text.trim();
6419
- if (seenOptions.has(trimmedText)) {
6427
+ options.forEach((option) => {
6428
+ if (seenOptions.has(option.text) && option.text.length) {
6420
6429
  errors[option.id] = "Option already exists";
6421
6430
  } else {
6422
- seenOptions.add(trimmedText);
6431
+ seenOptions.add(option.text);
6423
6432
  }
6424
6433
  });
6425
6434
  return Object.keys(errors).length > 0 ? { options: errors } : { options: void 0 };
@@ -6772,13 +6781,13 @@ var PollComposer = class {
6772
6781
  }
6773
6782
  get canCreatePoll() {
6774
6783
  const { data, errors } = this.state.getLatestValue();
6775
- const hasAtLeastOneOption = data.options.filter((o) => !!o.text).length > 0;
6784
+ const hasAtLeastOneNonEmptyOption = data.options.filter((o) => !!o.text.trim()).length > 0;
6776
6785
  const hasName = !!data.name;
6777
6786
  const maxVotesAllowedNumber = parseInt(
6778
6787
  data.max_votes_allowed?.match(VALID_MAX_VOTES_VALUE_REGEX)?.[0] || ""
6779
6788
  );
6780
6789
  const validMaxVotesAllowed = data.max_votes_allowed === "" || !!maxVotesAllowedNumber && (2 <= maxVotesAllowedNumber || maxVotesAllowedNumber <= 10);
6781
- return hasAtLeastOneOption && hasName && validMaxVotesAllowed && Object.values(errors).filter((errorText) => !!errorText).length === 0;
6790
+ return hasAtLeastOneNonEmptyOption && hasName && validMaxVotesAllowed && Object.values(errors).filter((errorText) => !!errorText).length === 0;
6782
6791
  }
6783
6792
  };
6784
6793
 
@@ -6868,8 +6877,7 @@ var createCompositionDataCleanupMiddleware = (composer) => ({
6868
6877
  localMessage: formatMessage({
6869
6878
  ...composer.editedMessage,
6870
6879
  ...state.localMessage,
6871
- ...common,
6872
- user: composer.client.user
6880
+ ...common
6873
6881
  }),
6874
6882
  message: {
6875
6883
  ...editedMessagePayloadToBeSent,
@@ -7115,6 +7123,9 @@ var createMessageComposerStateCompositionMiddleware = (composer) => ({
7115
7123
  if (composer.pollId) {
7116
7124
  payload.poll_id = composer.pollId;
7117
7125
  }
7126
+ if (composer.showReplyInChannel) {
7127
+ payload.show_in_channel = true;
7128
+ }
7118
7129
  return next({
7119
7130
  ...state,
7120
7131
  localMessage: {
@@ -7144,6 +7155,9 @@ var createDraftMessageComposerStateCompositionMiddleware = (composer) => ({
7144
7155
  if (composer.pollId) {
7145
7156
  payload.poll_id = composer.pollId;
7146
7157
  }
7158
+ if (composer.showReplyInChannel) {
7159
+ payload.show_in_channel = true;
7160
+ }
7147
7161
  return next({
7148
7162
  ...state,
7149
7163
  draft: {
@@ -7155,6 +7169,31 @@ var createDraftMessageComposerStateCompositionMiddleware = (composer) => ({
7155
7169
  }
7156
7170
  });
7157
7171
 
7172
+ // src/messageComposer/middleware/messageComposer/userDataInjection.ts
7173
+ var createUserDataInjectionMiddleware = (composer) => ({
7174
+ id: "stream-io/message-composer-middleware/user-data-injection",
7175
+ handlers: {
7176
+ compose: ({
7177
+ state,
7178
+ next,
7179
+ forward
7180
+ }) => {
7181
+ if (!composer.client.user) {
7182
+ return forward();
7183
+ }
7184
+ const { channel_mutes, devices, mutes, ...messageUser } = composer.client.user;
7185
+ return next({
7186
+ ...state,
7187
+ localMessage: {
7188
+ ...state.localMessage,
7189
+ user: messageUser,
7190
+ user_id: messageUser.id
7191
+ }
7192
+ });
7193
+ }
7194
+ }
7195
+ });
7196
+
7158
7197
  // src/messageComposer/middleware/messageComposer/pollOnly.ts
7159
7198
  var pollLocalMessageNullifiedFields = {
7160
7199
  attachments: [],
@@ -7196,6 +7235,7 @@ var MessageComposerMiddlewareExecutor = class extends MiddlewareExecutor {
7196
7235
  constructor({ composer }) {
7197
7236
  super();
7198
7237
  this.use([
7238
+ createUserDataInjectionMiddleware(composer),
7199
7239
  createPollOnlyCompositionMiddleware(composer),
7200
7240
  createTextComposerCompositionMiddleware(composer),
7201
7241
  createAttachmentsCompositionMiddleware(composer),
@@ -8770,10 +8810,11 @@ var initEditingAuditState = (composition) => {
8770
8810
  var initState5 = (composition) => {
8771
8811
  if (!composition) {
8772
8812
  return {
8813
+ draftId: null,
8773
8814
  id: MessageComposer.generateId(),
8774
- quotedMessage: null,
8775
8815
  pollId: null,
8776
- draftId: null
8816
+ quotedMessage: null,
8817
+ showReplyInChannel: false
8777
8818
  };
8778
8819
  }
8779
8820
  const quotedMessage = composition.quoted_message;
@@ -8790,8 +8831,9 @@ var initState5 = (composition) => {
8790
8831
  return {
8791
8832
  draftId,
8792
8833
  id,
8834
+ pollId: message.poll_id ?? null,
8793
8835
  quotedMessage: quotedMessage ? formatMessage(quotedMessage) : null,
8794
- pollId: message.poll_id ?? null
8836
+ showReplyInChannel: false
8795
8837
  };
8796
8838
  };
8797
8839
  var noop4 = () => void 0;
@@ -8986,6 +9028,9 @@ var _MessageComposer = class _MessageComposer extends WithSubscriptions {
8986
9028
  this.setQuotedMessage = (quotedMessage) => {
8987
9029
  this.state.partialNext({ quotedMessage });
8988
9030
  };
9031
+ this.toggleShowReplyInChannel = () => {
9032
+ this.state.partialNext({ showReplyInChannel: !this.showReplyInChannel });
9033
+ };
8989
9034
  this.clear = () => {
8990
9035
  this.initState();
8991
9036
  };
@@ -9059,15 +9104,21 @@ var _MessageComposer = class _MessageComposer extends WithSubscriptions {
9059
9104
  const composition = await this.pollComposer.compose();
9060
9105
  if (!composition || !composition.data.id) return;
9061
9106
  try {
9062
- const { poll } = await this.client.createPoll(composition.data);
9063
- this.state.partialNext({ pollId: poll.id });
9064
- this.pollComposer.initState();
9107
+ const poll = await this.client.polls.createPoll(composition.data);
9108
+ this.state.partialNext({ pollId: poll?.id });
9065
9109
  } catch (error) {
9066
- this.client.notifications.add({
9110
+ this.client.notifications.addError({
9067
9111
  message: "Failed to create the poll",
9068
9112
  origin: {
9069
9113
  emitter: "MessageComposer",
9070
9114
  context: { composer: this }
9115
+ },
9116
+ options: {
9117
+ type: "api:poll:create:failed",
9118
+ metadata: {
9119
+ reason: error.message
9120
+ },
9121
+ originalError: error instanceof Error ? error : void 0
9071
9122
  }
9072
9123
  });
9073
9124
  throw error;
@@ -9172,6 +9223,9 @@ var _MessageComposer = class _MessageComposer extends WithSubscriptions {
9172
9223
  get pollId() {
9173
9224
  return this.state.getLatestValue().pollId;
9174
9225
  }
9226
+ get showReplyInChannel() {
9227
+ return this.state.getLatestValue().showReplyInChannel;
9228
+ }
9175
9229
  get hasSendableData() {
9176
9230
  return !!(!this.attachmentManager.uploadsInProgressCount && (!this.textComposer.textIsEmpty || this.attachmentManager.successfulUploadsCount > 0) || this.pollId);
9177
9231
  }
@@ -12760,7 +12814,11 @@ var PollManager = class extends WithSubscriptions {
12760
12814
  };
12761
12815
  this.createPoll = async (poll) => {
12762
12816
  const { poll: createdPoll } = await this.client.createPoll(poll);
12763
- return new Poll({ client: this.client, poll: createdPoll });
12817
+ if (!createdPoll.vote_counts_by_option) {
12818
+ createdPoll.vote_counts_by_option = {};
12819
+ }
12820
+ this.setOrOverwriteInCache(createdPoll);
12821
+ return this.fromState(createdPoll.id);
12764
12822
  };
12765
12823
  this.getPoll = async (id) => {
12766
12824
  const cachedPoll = this.fromState(id);
@@ -13298,21 +13356,23 @@ var ChannelManager = class extends WithSubscriptions {
13298
13356
  }
13299
13357
  };
13300
13358
 
13301
- // src/notifications/NotificationManager.ts
13302
- var DURATIONS = {
13303
- error: 1e4,
13304
- warning: 5e3,
13305
- info: 3e3,
13306
- success: 3e3
13359
+ // src/notifications/configuration.ts
13360
+ var DURATION_MS = 3e3;
13361
+ var DEFAULT_NOTIFICATION_MANAGER_CONFIG = {
13362
+ durations: {
13363
+ error: DURATION_MS,
13364
+ info: DURATION_MS,
13365
+ success: DURATION_MS,
13366
+ warning: DURATION_MS
13367
+ }
13307
13368
  };
13369
+
13370
+ // src/notifications/NotificationManager.ts
13308
13371
  var NotificationManager = class {
13309
13372
  constructor(config = {}) {
13310
13373
  this.timeouts = /* @__PURE__ */ new Map();
13311
13374
  this.store = new StateStore({ notifications: [] });
13312
- this.config = {
13313
- ...config,
13314
- durations: config.durations || DURATIONS
13315
- };
13375
+ this.config = mergeWith(DEFAULT_NOTIFICATION_MANAGER_CONFIG, config);
13316
13376
  }
13317
13377
  get notifications() {
13318
13378
  return this.store.getLatestValue().notifications;
@@ -13332,21 +13392,24 @@ var NotificationManager = class {
13332
13392
  add({ message, origin, options = {} }) {
13333
13393
  const id = generateUUIDv4();
13334
13394
  const now = Date.now();
13395
+ const severity = options.severity || "info";
13396
+ const duration = options.duration ?? this.config.durations[severity];
13335
13397
  const notification = {
13336
13398
  id,
13337
13399
  message,
13338
13400
  origin,
13339
- severity: options.severity || "info",
13401
+ type: options?.type,
13402
+ severity,
13340
13403
  createdAt: now,
13341
- expiresAt: options.duration ? now + options.duration : void 0,
13342
- autoClose: options.autoClose ?? true,
13404
+ expiresAt: now + duration,
13343
13405
  actions: options.actions,
13344
- metadata: options.metadata
13406
+ metadata: options.metadata,
13407
+ originalError: options.originalError
13345
13408
  };
13346
13409
  this.store.partialNext({
13347
13410
  notifications: [...this.store.getLatestValue().notifications, notification]
13348
13411
  });
13349
- if (notification.autoClose && notification.expiresAt) {
13412
+ if (notification.expiresAt) {
13350
13413
  const timeout = setTimeout(() => {
13351
13414
  this.remove(id);
13352
13415
  }, options.duration || this.config.durations[notification.severity]);
@@ -15712,7 +15775,7 @@ var StreamChat = class _StreamChat {
15712
15775
  data
15713
15776
  );
15714
15777
  }
15715
- DBDeleteChannelType(channelType) {
15778
+ deleteChannelType(channelType) {
15716
15779
  return this.delete(
15717
15780
  this.baseURL + `/channeltypes/${encodeURIComponent(channelType)}`
15718
15781
  );
@@ -16055,7 +16118,7 @@ var StreamChat = class _StreamChat {
16055
16118
  if (this.userAgent) {
16056
16119
  return this.userAgent;
16057
16120
  }
16058
- const version = "9.5.0";
16121
+ const version = "9.6.0";
16059
16122
  const clientBundle = "browser-esm";
16060
16123
  let userAgentString = "";
16061
16124
  if (this.sdkIdentifier) {
@@ -18132,6 +18195,7 @@ export {
18132
18195
  MiddlewareExecutor,
18133
18196
  MinPriority,
18134
18197
  Moderation,
18198
+ NotificationManager,
18135
18199
  OfflineDBSyncManager,
18136
18200
  OfflineError,
18137
18201
  Permission,