stream-chat-react 13.2.0 → 13.2.2

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.
@@ -4249,7 +4249,7 @@ var ChannelListMessenger = (props) => {
4249
4249
  } = props;
4250
4250
  const { t } = useTranslationContext("ChannelListMessenger");
4251
4251
  if (error) {
4252
- return /* @__PURE__ */ import_react47.default.createElement(LoadingErrorIndicator2, null);
4252
+ return /* @__PURE__ */ import_react47.default.createElement(LoadingErrorIndicator2, { error });
4253
4253
  }
4254
4254
  if (loading) {
4255
4255
  return /* @__PURE__ */ import_react47.default.createElement(LoadingIndicator2, null);
@@ -17944,7 +17944,6 @@ var keepLineBreaksPlugin = () => transform2;
17944
17944
  // src/components/Message/renderText/renderText.tsx
17945
17945
  var import_react110 = __toESM(require("react"));
17946
17946
  var import_linkifyjs = require("linkifyjs");
17947
- var import_lodash13 = __toESM(require("lodash.uniqby"));
17948
17947
 
17949
17948
  // node_modules/ccount/index.js
17950
17949
  function ccount(value, character) {
@@ -21081,39 +21080,31 @@ var renderText = (text7, mentionedUsers, {
21081
21080
  let newText = text7;
21082
21081
  const markdownLinks = matchMarkdownLinks(newText);
21083
21082
  const codeBlocks = messageCodeBlocks(newText);
21084
- (0, import_lodash13.default)([...(0, import_linkifyjs.find)(newText, "email"), ...(0, import_linkifyjs.find)(newText, "url")], "value").forEach(
21085
- ({ href, type, value }) => {
21086
- const linkIsInBlock = codeBlocks.some((block) => block?.includes(value));
21087
- const noParsingNeeded = markdownLinks && markdownLinks.filter((text8) => {
21088
- const strippedHref = href?.replace(detectHttp, "");
21089
- const strippedText = text8?.replace(detectHttp, "");
21090
- if (!strippedHref || !strippedText) return false;
21091
- return strippedHref.includes(strippedText) || strippedText.includes(strippedHref);
21092
- });
21093
- if (noParsingNeeded.length > 0 || linkIsInBlock) return;
21094
- try {
21095
- if (type === "email" && mentionedUsers) {
21096
- const emailMatchesWithName = mentionedUsers.some((u2) => u2.name === value);
21097
- if (emailMatchesWithName) {
21098
- newText = newText.replace(
21099
- new RegExp(escapeRegExp(value), "g"),
21100
- (match, position3) => {
21101
- const isMention = newText.charAt(position3 - 1) === "@";
21102
- return isMention ? match : `[${match}](${encodeDecode(href)})`;
21103
- }
21104
- );
21105
- return;
21106
- }
21083
+ const links = [...(0, import_linkifyjs.find)(newText, "email"), ...(0, import_linkifyjs.find)(newText, "url")];
21084
+ for (let i = links.length - 1; i >= 0; i--) {
21085
+ const { end, href, start: start2, type, value } = links[i];
21086
+ const linkIsInBlock = codeBlocks.some((block) => block?.includes(value));
21087
+ const noParsingNeeded = markdownLinks && markdownLinks.filter((text8) => {
21088
+ const strippedHref = href?.replace(detectHttp, "");
21089
+ const strippedText = text8?.replace(detectHttp, "");
21090
+ if (!strippedHref || !strippedText) return false;
21091
+ return strippedHref.includes(strippedText) || strippedText.includes(strippedHref);
21092
+ });
21093
+ if (noParsingNeeded.length > 0 || linkIsInBlock) return;
21094
+ try {
21095
+ if (type === "email" && mentionedUsers) {
21096
+ const emailMatchesWithName = mentionedUsers.find((u2) => u2.name === value);
21097
+ if (emailMatchesWithName) {
21098
+ const isMention = newText.charAt(start2 - 1) === "@";
21099
+ newText = newText.slice(0, start2) + (isMention ? value : `[${value}](${encodeDecode(href)})`) + newText.slice(end);
21107
21100
  }
21101
+ } else {
21108
21102
  const displayLink = type === "email" ? value : formatUrlForDisplay(href);
21109
- newText = newText.replace(
21110
- new RegExp(escapeRegExp(value), "g"),
21111
- `[${displayLink}](${encodeDecode(href)})`
21112
- );
21113
- } catch (e) {
21103
+ newText = newText.slice(0, start2) + `[${displayLink}](${encodeDecode(href)})` + newText.slice(end);
21114
21104
  }
21105
+ } catch (e) {
21115
21106
  }
21116
- );
21107
+ }
21117
21108
  const remarkPlugins = [
21118
21109
  htmlToTextPlugin,
21119
21110
  keepLineBreaksPlugin,
@@ -21980,7 +21971,8 @@ var FormDialog = ({
21980
21971
  "button",
21981
21972
  {
21982
21973
  className: "str-chat__dialog__controls-button str-chat__dialog__controls-button--cancel",
21983
- onClick: close
21974
+ onClick: close,
21975
+ type: "button"
21984
21976
  },
21985
21977
  t("Cancel")
21986
21978
  ), /* @__PURE__ */ import_react127.default.createElement(
@@ -22267,7 +22259,7 @@ function useManagePollVotesRealtime(managedVoteType, cursorPaginatorState, optio
22267
22259
  }
22268
22260
 
22269
22261
  // src/components/InfiniteScrollPaginator/hooks/useCursorPaginator.ts
22270
- var import_lodash14 = __toESM(require("lodash.uniqby"));
22262
+ var import_lodash13 = __toESM(require("lodash.uniqby"));
22271
22263
  var import_react136 = require("react");
22272
22264
  var import_stream_chat3 = require("stream-chat");
22273
22265
  var useCursorPaginator = (paginationFn, loadFirstPage) => {
@@ -22289,7 +22281,7 @@ var useCursorPaginator = (paginationFn, loadFirstPage) => {
22289
22281
  cursorPaginatorState.next((prev) => ({
22290
22282
  ...prev,
22291
22283
  hasNextPage: !!next,
22292
- items: (0, import_lodash14.default)(prev.items.concat(items), "id"),
22284
+ items: (0, import_lodash13.default)(prev.items.concat(items), "id"),
22293
22285
  latestPageItems: items,
22294
22286
  next: next || null
22295
22287
  }));
@@ -22388,7 +22380,7 @@ var usePollOptionVotesPagination = ({
22388
22380
 
22389
22381
  // src/components/InfiniteScrollPaginator/InfiniteScrollPaginator.tsx
22390
22382
  var import_clsx31 = __toESM(require("clsx"));
22391
- var import_lodash15 = __toESM(require("lodash.debounce"));
22383
+ var import_lodash14 = __toESM(require("lodash.debounce"));
22392
22384
  var import_react139 = __toESM(require("react"));
22393
22385
  var mousewheelListener = (event) => {
22394
22386
  if (event instanceof WheelEvent && event.deltaY === 1) {
@@ -22410,7 +22402,7 @@ var InfiniteScrollPaginator = (props) => {
22410
22402
  const rootRef = (0, import_react139.useRef)(null);
22411
22403
  const childRef = (0, import_react139.useRef)(null);
22412
22404
  const scrollListener = (0, import_react139.useMemo)(
22413
- () => (0, import_lodash15.default)(() => {
22405
+ () => (0, import_lodash14.default)(() => {
22414
22406
  const root4 = rootRef.current;
22415
22407
  const child = childRef.current;
22416
22408
  if (!root4 || root4.offsetParent === null || !child) {
@@ -22500,7 +22492,7 @@ var import_react142 = __toESM(require("react"));
22500
22492
 
22501
22493
  // src/components/Poll/PollOptionSelector.tsx
22502
22494
  var import_clsx32 = __toESM(require("clsx"));
22503
- var import_lodash16 = __toESM(require("lodash.debounce"));
22495
+ var import_lodash15 = __toESM(require("lodash.debounce"));
22504
22496
  var import_react141 = __toESM(require("react"));
22505
22497
  var import_stream_chat4 = require("stream-chat");
22506
22498
  var AmountBar = ({ amount, className }) => /* @__PURE__ */ import_react141.default.createElement(
@@ -22548,7 +22540,7 @@ var PollOptionSelector = ({
22548
22540
  const canCastVote = channelCapabilities["cast-poll-vote"] && !is_closed;
22549
22541
  const winningOptionCount = maxVotedOptionIds[0] ? vote_counts_by_option[maxVotedOptionIds[0]] : 0;
22550
22542
  const toggleVote = (0, import_react141.useMemo)(
22551
- () => (0, import_lodash16.default)(() => {
22543
+ () => (0, import_lodash15.default)(() => {
22552
22544
  if (!canCastVote) return;
22553
22545
  const haveVotedForTheOption = !!ownVotesByOptionId[option.id];
22554
22546
  return haveVotedForTheOption ? poll.removeVote(ownVotesByOptionId[option.id].id, message.id) : poll.castVote(option.id, message.id);
@@ -22972,7 +22964,7 @@ var MultipleAnswersField = () => {
22972
22964
  );
22973
22965
  },
22974
22966
  placeholder: t("Maximum number of votes (from 2 to 10)"),
22975
- type: "number",
22967
+ type: "text",
22976
22968
  value: max_votes_allowed
22977
22969
  }
22978
22970
  ))
@@ -23205,7 +23197,8 @@ var OptionFieldSet = () => {
23205
23197
  });
23206
23198
  },
23207
23199
  onKeyUp: (event) => {
23208
- if (event.key === "Enter") {
23200
+ const isFocusedLastOptionField = i === options.length - 1;
23201
+ if (event.key === "Enter" && !isFocusedLastOptionField) {
23209
23202
  const nextInputId = options[i + 1].id;
23210
23203
  document.getElementById(nextInputId)?.focus();
23211
23204
  }
@@ -23237,7 +23230,8 @@ var PollCreationDialogControls = ({
23237
23230
  onClick: () => {
23238
23231
  messageComposer.pollComposer.initState();
23239
23232
  close();
23240
- }
23233
+ },
23234
+ type: "button"
23241
23235
  },
23242
23236
  t("Cancel")
23243
23237
  ), /* @__PURE__ */ import_react157.default.createElement(
@@ -28589,7 +28583,7 @@ var useUnreadMessagesNotificationVirtualized = ({
28589
28583
 
28590
28584
  // src/components/MessageList/VirtualizedMessageListComponents.tsx
28591
28585
  var import_clsx48 = __toESM(require("clsx"));
28592
- var import_lodash17 = __toESM(require("lodash.throttle"));
28586
+ var import_lodash16 = __toESM(require("lodash.throttle"));
28593
28587
  var import_react194 = __toESM(require("react"));
28594
28588
  var PREPEND_OFFSET = 10 ** 7;
28595
28589
  function calculateItemIndex(virtuosoIndex, numItemsPrepended) {
@@ -28598,7 +28592,7 @@ function calculateItemIndex(virtuosoIndex, numItemsPrepended) {
28598
28592
  function calculateFirstItemIndex(numItemsPrepended) {
28599
28593
  return PREPEND_OFFSET - numItemsPrepended;
28600
28594
  }
28601
- var makeItemsRenderedHandler = (renderedItemsActions, processedMessages) => (0, import_lodash17.default)((items) => {
28595
+ var makeItemsRenderedHandler = (renderedItemsActions, processedMessages) => (0, import_lodash16.default)((items) => {
28602
28596
  const renderedMessages = items.map((item) => {
28603
28597
  if (!item.originalIndex) return void 0;
28604
28598
  return processedMessages[calculateItemIndex(item.originalIndex, PREPEND_OFFSET)];
@@ -30835,9 +30829,9 @@ var import_fix_webm_duration = __toESM(require("fix-webm-duration"));
30835
30829
  var import_nanoid5 = require("nanoid");
30836
30830
 
30837
30831
  // src/utils/mergeDeep.ts
30838
- var import_lodash18 = __toESM(require("lodash.mergewith"));
30832
+ var import_lodash17 = __toESM(require("lodash.mergewith"));
30839
30833
  var overrideUndefinedOnly = (object, source) => object ?? source;
30840
- var mergeDeepUndefined = (target, source) => (0, import_lodash18.default)(target, source, overrideUndefinedOnly);
30834
+ var mergeDeepUndefined = (target, source) => (0, import_lodash17.default)(target, source, overrideUndefinedOnly);
30841
30835
 
30842
30836
  // src/components/MediaRecorder/classes/AmplitudeRecorder.ts
30843
30837
  var MAX_FREQUENCY_AMPLITUDE = 255;
@@ -32318,6 +32312,12 @@ var searchSourceStateSelector2 = (state) => ({
32318
32312
  var configStateSelector = (state) => ({
32319
32313
  enabled: state.text.enabled
32320
32314
  });
32315
+ var messageComposerStateSelector2 = (state) => ({
32316
+ quotedMessage: state.quotedMessage
32317
+ });
32318
+ var attachmentManagerStateSelector = (state) => ({
32319
+ attachments: state.attachments
32320
+ });
32321
32321
  var defaultShouldSubmit = (event) => event.key === "Enter" && !event.shiftKey && !event.nativeEvent.isComposing;
32322
32322
  var TextareaComposer = ({
32323
32323
  className,
@@ -32340,6 +32340,7 @@ var TextareaComposer = ({
32340
32340
  const {
32341
32341
  additionalTextareaProps,
32342
32342
  cooldownRemaining,
32343
+ focus,
32343
32344
  handleSubmit,
32344
32345
  maxRows: maxRowsContext,
32345
32346
  minRows: minRowsContext,
@@ -32358,6 +32359,14 @@ var TextareaComposer = ({
32358
32359
  textComposerStateSelector2
32359
32360
  );
32360
32361
  const { enabled } = useStateStore(messageComposer.configState, configStateSelector);
32362
+ const { quotedMessage } = useStateStore(
32363
+ messageComposer.state,
32364
+ messageComposerStateSelector2
32365
+ );
32366
+ const { attachments } = useStateStore(
32367
+ messageComposer.attachmentManager.state,
32368
+ attachmentManagerStateSelector
32369
+ );
32361
32370
  const { isLoadingItems } = useStateStore(suggestions?.searchSource.state, searchSourceStateSelector2) ?? {};
32362
32371
  const containerRef = (0, import_react246.useRef)(null);
32363
32372
  const [focusedItemIndex, setFocusedItemIndex] = (0, import_react246.useState)(0);
@@ -32471,6 +32480,16 @@ var TextareaComposer = ({
32471
32480
  setFocusedItemIndex(0);
32472
32481
  }
32473
32482
  }, [textComposer.suggestions]);
32483
+ (0, import_react246.useEffect)(() => {
32484
+ const textareaIsFocused = textareaRef.current?.matches(":focus");
32485
+ if (!textareaRef.current || textareaIsFocused || !focus) return;
32486
+ textareaRef.current.focus();
32487
+ }, [attachments, focus, quotedMessage, textareaRef]);
32488
+ (0, import_react246.useEffect)(() => {
32489
+ const textarea = textareaRef.current;
32490
+ if (!textarea) return;
32491
+ textarea.value = text7;
32492
+ }, [textareaRef, text7]);
32474
32493
  return /* @__PURE__ */ import_react246.default.createElement(
32475
32494
  "div",
32476
32495
  {
@@ -32509,8 +32528,7 @@ var TextareaComposer = ({
32509
32528
  placeholder: placeholder || t("Type your message"),
32510
32529
  ref: (ref) => {
32511
32530
  textareaRef.current = ref;
32512
- },
32513
- value: text7
32531
+ }
32514
32532
  }
32515
32533
  ),
32516
32534
  !isComposing && /* @__PURE__ */ import_react246.default.createElement(
@@ -32817,7 +32835,7 @@ var MessageInputProvider = (props) => {
32817
32835
  );
32818
32836
  (0, import_react252.useEffect)(() => {
32819
32837
  const threadId = messageComposer.threadId;
32820
- if (!threadId || !messageComposer.channel || !messageComposer.compositionIsEmpty)
32838
+ if (!threadId || !messageComposer.channel || !messageComposer.compositionIsEmpty || !messageComposer.config.drafts.enabled)
32821
32839
  return;
32822
32840
  messageComposer.channel.getDraft({ parent_id: threadId }).then(({ draft }) => {
32823
32841
  if (draft) {
@@ -32883,7 +32901,8 @@ var EditMessageForm = () => {
32883
32901
  {
32884
32902
  className: "str-chat__edit-message-cancel",
32885
32903
  "data-testid": "cancel-button",
32886
- onClick: cancel
32904
+ onClick: cancel,
32905
+ type: "button"
32887
32906
  },
32888
32907
  t("Cancel")
32889
32908
  ), /* @__PURE__ */ import_react253.default.createElement(EditMessageFormSendButton, null))
@@ -32910,6 +32929,7 @@ var EditMessageModal = ({
32910
32929
  MessageInput,
32911
32930
  {
32912
32931
  clearEditingState,
32932
+ focus: true,
32913
32933
  hideSendButton: true,
32914
32934
  Input: EditMessageInput,
32915
32935
  ...additionalMessageInputProps
@@ -32934,7 +32954,7 @@ var UploadFileInput = (0, import_react254.forwardRef)(function UploadFileInput2(
32934
32954
  ...props
32935
32955
  }, ref) {
32936
32956
  const { t } = useTranslationContext("UploadFileInput");
32937
- const { cooldownRemaining } = useMessageInputContext();
32957
+ const { cooldownRemaining, textareaRef } = useMessageInputContext();
32938
32958
  const messageComposer = useMessageComposer();
32939
32959
  const { attachmentManager } = messageComposer;
32940
32960
  const { isUploadEnabled } = useAttachmentManagerState();
@@ -32946,9 +32966,10 @@ var UploadFileInput = (0, import_react254.forwardRef)(function UploadFileInput2(
32946
32966
  const onFileChange = (0, import_react254.useCallback)(
32947
32967
  (files) => {
32948
32968
  attachmentManager.uploadFiles(files);
32969
+ textareaRef.current?.focus();
32949
32970
  onFileChangeCustom?.(files);
32950
32971
  },
32951
- [onFileChangeCustom, attachmentManager]
32972
+ [onFileChangeCustom, attachmentManager, textareaRef]
32952
32973
  );
32953
32974
  return /* @__PURE__ */ import_react254.default.createElement(
32954
32975
  FileInput,
@@ -33473,9 +33494,9 @@ var getAttachmentType = (attachment) => {
33473
33494
  // src/components/Channel/Channel.tsx
33474
33495
  var import_react266 = __toESM(require("react"));
33475
33496
  var import_clsx67 = __toESM(require("clsx"));
33476
- var import_lodash19 = __toESM(require("lodash.debounce"));
33477
- var import_lodash20 = __toESM(require("lodash.defaultsdeep"));
33478
- var import_lodash21 = __toESM(require("lodash.throttle"));
33497
+ var import_lodash18 = __toESM(require("lodash.debounce"));
33498
+ var import_lodash19 = __toESM(require("lodash.defaultsdeep"));
33499
+ var import_lodash20 = __toESM(require("lodash.throttle"));
33479
33500
  var import_stream_chat13 = require("stream-chat");
33480
33501
 
33481
33502
  // src/components/Channel/channelState.ts
@@ -34073,7 +34094,7 @@ var ChannelInner = (props) => {
34073
34094
  skipMessageDataMemoization
34074
34095
  } = props;
34075
34096
  const channelQueryOptions = (0, import_react266.useMemo)(
34076
- () => (0, import_lodash20.default)(propChannelQueryOptions, {
34097
+ () => (0, import_lodash19.default)(propChannelQueryOptions, {
34077
34098
  messages: { limit: DEFAULT_INITIAL_CHANNEL_PAGE_SIZE }
34078
34099
  }),
34079
34100
  [propChannelQueryOptions]
@@ -34108,7 +34129,7 @@ var ChannelInner = (props) => {
34108
34129
  null
34109
34130
  );
34110
34131
  const channelCapabilitiesArray = channel.data?.own_capabilities;
34111
- const throttledCopyStateFromChannel = (0, import_lodash21.default)(
34132
+ const throttledCopyStateFromChannel = (0, import_lodash20.default)(
34112
34133
  () => dispatch({ channel, type: "copyStateFromChannelOnEvent" }),
34113
34134
  500,
34114
34135
  {
@@ -34117,14 +34138,14 @@ var ChannelInner = (props) => {
34117
34138
  }
34118
34139
  );
34119
34140
  const setChannelUnreadUiState = (0, import_react266.useMemo)(
34120
- () => (0, import_lodash21.default)(_setChannelUnreadUiState, 200, {
34141
+ () => (0, import_lodash20.default)(_setChannelUnreadUiState, 200, {
34121
34142
  leading: true,
34122
34143
  trailing: false
34123
34144
  }),
34124
34145
  []
34125
34146
  );
34126
34147
  const markRead = (0, import_react266.useMemo)(
34127
- () => (0, import_lodash21.default)(
34148
+ () => (0, import_lodash20.default)(
34128
34149
  async (options) => {
34129
34150
  const { updateChannelUiUnreadState = true } = options ?? {};
34130
34151
  if (channel.disconnected || !channelConfig?.read_events) {
@@ -34139,7 +34160,7 @@ var ChannelInner = (props) => {
34139
34160
  );
34140
34161
  } else {
34141
34162
  const markReadResponse = await channel.markRead();
34142
- if (updateChannelUiUnreadState && markReadResponse) {
34163
+ if (updateChannelUiUnreadState && markReadResponse?.event) {
34143
34164
  _setChannelUnreadUiState({
34144
34165
  last_read: lastRead.current,
34145
34166
  last_read_message_id: markReadResponse.event.last_read_message_id,
@@ -34329,7 +34350,7 @@ var ChannelInner = (props) => {
34329
34350
  []
34330
34351
  );
34331
34352
  const loadMoreFinished = (0, import_react266.useCallback)(
34332
- (0, import_lodash19.default)(
34353
+ (0, import_lodash18.default)(
34333
34354
  (hasMore, messages) => {
34334
34355
  if (!isMounted.current) return;
34335
34356
  dispatch({ hasMore, messages, type: "loadMoreFinished" });
@@ -34650,7 +34671,7 @@ var ChannelInner = (props) => {
34650
34671
  dispatch({ type: "closeThread" });
34651
34672
  };
34652
34673
  const loadMoreThreadFinished = (0, import_react266.useCallback)(
34653
- (0, import_lodash19.default)(
34674
+ (0, import_lodash18.default)(
34654
34675
  (threadHasMore, threadMessages) => {
34655
34676
  dispatch({
34656
34677
  threadHasMore,
@@ -34980,7 +35001,7 @@ var useChat = ({
34980
35001
  };
34981
35002
  (0, import_react269.useEffect)(() => {
34982
35003
  if (!client) return;
34983
- const version = "13.2.0";
35004
+ const version = "13.2.2";
34984
35005
  const userAgent = client.getUserAgent();
34985
35006
  if (!userAgent.includes("stream-chat-react")) {
34986
35007
  client.setUserAgent(`stream-chat-react-${version}-${userAgent}`);