stream-chat-react 12.9.0 → 12.11.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.
Files changed (207) hide show
  1. package/dist/components/Attachment/Attachment.js +2 -1
  2. package/dist/components/Attachment/AttachmentContainer.d.ts +1 -1
  3. package/dist/components/Attachment/AttachmentContainer.js +2 -2
  4. package/dist/components/Attachment/Card.js +3 -3
  5. package/dist/components/Attachment/VoiceRecording.d.ts +1 -1
  6. package/dist/components/Attachment/VoiceRecording.js +2 -2
  7. package/dist/components/Attachment/attachment-sizing.js +2 -1
  8. package/dist/components/Attachment/components/FileSizeIndicator.d.ts +1 -1
  9. package/dist/components/Attachment/components/FileSizeIndicator.js +1 -1
  10. package/dist/components/Attachment/components/WaveProgressBar.js +1 -1
  11. package/dist/components/Attachment/hooks/useAudioController.d.ts +1 -1
  12. package/dist/components/Attachment/hooks/useAudioController.js +4 -2
  13. package/dist/components/Attachment/utils.d.ts +1 -1
  14. package/dist/components/Attachment/utils.js +12 -3
  15. package/dist/components/AutoCompleteTextarea/List.js +3 -2
  16. package/dist/components/AutoCompleteTextarea/Textarea.js +3 -7
  17. package/dist/components/AutoCompleteTextarea/utils.js +3 -7
  18. package/dist/components/Avatar/ChannelAvatar.js +1 -1
  19. package/dist/components/Channel/Channel.d.ts +1 -1
  20. package/dist/components/Channel/Channel.js +30 -14
  21. package/dist/components/Channel/channelState.d.ts +1 -3
  22. package/dist/components/Channel/channelState.js +10 -4
  23. package/dist/components/Channel/hooks/useCreateChannelStateContext.js +5 -3
  24. package/dist/components/Channel/hooks/useIsMounted.d.ts +1 -1
  25. package/dist/components/Channel/hooks/useMentionsHandlers.js +5 -2
  26. package/dist/components/Channel/utils.js +2 -1
  27. package/dist/components/ChannelHeader/ChannelHeader.js +1 -1
  28. package/dist/components/ChannelList/ChannelList.js +13 -8
  29. package/dist/components/ChannelList/hooks/useChannelListShape.d.ts +2 -2
  30. package/dist/components/ChannelList/hooks/useChannelListShape.js +46 -19
  31. package/dist/components/ChannelList/hooks/useChannelUpdatedListener.js +2 -1
  32. package/dist/components/ChannelList/hooks/useMessageNewListener.js +3 -1
  33. package/dist/components/ChannelList/hooks/useMobileNavigation.d.ts +1 -1
  34. package/dist/components/ChannelList/hooks/usePaginatedChannels.js +5 -3
  35. package/dist/components/ChannelList/hooks/useSelectedChannelState.js +1 -1
  36. package/dist/components/ChannelPreview/ChannelPreview.js +2 -2
  37. package/dist/components/ChannelPreview/ChannelPreviewMessenger.js +1 -1
  38. package/dist/components/ChannelPreview/icons.js +0 -1
  39. package/dist/components/ChannelPreview/utils.js +3 -3
  40. package/dist/components/ChannelSearch/ChannelSearch.js +5 -3
  41. package/dist/components/ChannelSearch/SearchBar.d.ts +1 -1
  42. package/dist/components/ChannelSearch/SearchInput.d.ts +1 -1
  43. package/dist/components/ChannelSearch/SearchResults.js +1 -1
  44. package/dist/components/ChannelSearch/hooks/useChannelSearch.d.ts +4 -2
  45. package/dist/components/ChannelSearch/hooks/useChannelSearch.js +61 -36
  46. package/dist/components/ChannelSearch/index.d.ts +1 -1
  47. package/dist/components/Chat/hooks/useChat.js +4 -2
  48. package/dist/components/Chat/hooks/useCreateChatClient.js +3 -1
  49. package/dist/components/ChatAutoComplete/ChatAutoComplete.js +1 -1
  50. package/dist/components/ChatView/ChatView.js +0 -1
  51. package/dist/components/Dialog/PromptDialog.d.ts +1 -1
  52. package/dist/components/Dialog/PromptDialog.js +1 -1
  53. package/dist/components/EventComponent/EventComponent.js +1 -1
  54. package/dist/components/Gallery/BaseImage.d.ts +1 -3
  55. package/dist/components/Gallery/Gallery.js +10 -2
  56. package/dist/components/Gallery/Image.js +1 -1
  57. package/dist/components/Gallery/ModalGallery.js +4 -4
  58. package/dist/components/InfiniteScrollPaginator/InfiniteScroll.js +9 -6
  59. package/dist/components/InfiniteScrollPaginator/InfiniteScrollPaginator.js +1 -1
  60. package/dist/components/LoadMore/LoadMorePaginator.js +1 -1
  61. package/dist/components/MML/MML.js +1 -0
  62. package/dist/components/MediaRecorder/transcode/wav.js +6 -3
  63. package/dist/components/Message/FixedHeightMessage.js +6 -8
  64. package/dist/components/Message/Message.js +2 -1
  65. package/dist/components/Message/MessageEditedTimestamp.js +1 -1
  66. package/dist/components/Message/MessageSimple.js +2 -5
  67. package/dist/components/Message/MessageStatus.js +1 -1
  68. package/dist/components/Message/MessageText.js +7 -7
  69. package/dist/components/Message/QuotedMessage.js +2 -2
  70. package/dist/components/Message/Timestamp.js +9 -1
  71. package/dist/components/Message/hooks/useActionHandler.js +1 -1
  72. package/dist/components/Message/hooks/useFlagHandler.js +2 -1
  73. package/dist/components/Message/hooks/useMarkUnreadHandler.js +2 -1
  74. package/dist/components/Message/hooks/useMessageTextStreaming.d.ts +1 -1
  75. package/dist/components/Message/hooks/useMessageTextStreaming.js +1 -1
  76. package/dist/components/Message/hooks/useMuteHandler.js +7 -4
  77. package/dist/components/Message/hooks/usePinHandler.js +1 -1
  78. package/dist/components/Message/hooks/useReactionHandler.js +10 -5
  79. package/dist/components/Message/hooks/useRetryHandler.js +1 -1
  80. package/dist/components/Message/hooks/useUserRole.js +1 -1
  81. package/dist/components/Message/renderText/renderText.js +2 -2
  82. package/dist/components/Message/utils.js +3 -3
  83. package/dist/components/MessageActions/MessageActionsBox.js +7 -3
  84. package/dist/components/MessageActions/hooks/useMessageActionsBoxPopper.d.ts +1 -1
  85. package/dist/components/MessageInput/AttachmentPreviewList/AttachmentPreviewList.js +1 -1
  86. package/dist/components/MessageInput/AttachmentPreviewList/FileAttachmentPreview.js +4 -2
  87. package/dist/components/MessageInput/AttachmentPreviewList/UnsupportedAttachmentPreview.js +4 -2
  88. package/dist/components/MessageInput/AttachmentSelector.js +1 -1
  89. package/dist/components/MessageInput/DefaultTriggerProvider.js +1 -1
  90. package/dist/components/MessageInput/DropzoneProvider.js +1 -1
  91. package/dist/components/MessageInput/MessageInput.js +1 -1
  92. package/dist/components/MessageInput/MessageInputFlat.js +4 -3
  93. package/dist/components/MessageInput/QuotedMessagePreview.js +1 -1
  94. package/dist/components/MessageInput/hooks/useAttachments.js +12 -4
  95. package/dist/components/MessageInput/hooks/useLinkPreviews.js +3 -1
  96. package/dist/components/MessageInput/hooks/useMessageInputState.js +4 -3
  97. package/dist/components/MessageInput/hooks/useMessageInputText.d.ts +1 -1
  98. package/dist/components/MessageInput/hooks/useMessageInputText.js +5 -3
  99. package/dist/components/MessageInput/hooks/useSubmitHandler.js +5 -3
  100. package/dist/components/MessageInput/hooks/useTimeElapsed.js +1 -1
  101. package/dist/components/MessageInput/hooks/useUserTrigger.js +2 -2
  102. package/dist/components/MessageInput/hooks/utils.js +6 -2
  103. package/dist/components/MessageList/ConnectionStatus.js +1 -1
  104. package/dist/components/MessageList/MessageList.js +5 -6
  105. package/dist/components/MessageList/MessageListNotifications.js +3 -1
  106. package/dist/components/MessageList/VirtualizedMessageList.d.ts +1 -1
  107. package/dist/components/MessageList/VirtualizedMessageList.js +19 -12
  108. package/dist/components/MessageList/VirtualizedMessageListComponents.js +2 -2
  109. package/dist/components/MessageList/hooks/MessageList/useMessageListElements.js +1 -3
  110. package/dist/components/MessageList/hooks/MessageList/useMessageListScrollManager.js +3 -2
  111. package/dist/components/MessageList/hooks/MessageList/useScrollLocationLogic.js +3 -2
  112. package/dist/components/MessageList/hooks/MessageList/useUnreadMessagesNotification.js +6 -2
  113. package/dist/components/MessageList/hooks/VirtualizedMessageList/useMessageSetKey.js +1 -1
  114. package/dist/components/MessageList/hooks/VirtualizedMessageList/useNewMessageNotification.d.ts +1 -1
  115. package/dist/components/MessageList/hooks/VirtualizedMessageList/usePrependMessagesCount.js +4 -3
  116. package/dist/components/MessageList/hooks/VirtualizedMessageList/useScrollToBottomOnNewMessage.js +1 -1
  117. package/dist/components/MessageList/hooks/VirtualizedMessageList/useUnreadMessagesNotificationVirtualized.js +7 -3
  118. package/dist/components/MessageList/hooks/useMarkRead.d.ts +2 -4
  119. package/dist/components/MessageList/hooks/useMarkRead.js +14 -16
  120. package/dist/components/MessageList/utils.js +28 -11
  121. package/dist/components/Modal/Modal.d.ts +1 -1
  122. package/dist/components/Modal/Modal.js +1 -1
  123. package/dist/components/Modal/ModalHeader.js +1 -1
  124. package/dist/components/Poll/Poll.js +1 -1
  125. package/dist/components/Poll/PollActions/PollActions.js +6 -4
  126. package/dist/components/Poll/PollActions/PollAnswerList.js +1 -1
  127. package/dist/components/Poll/PollActions/PollResults/PollOptionVotesList.js +1 -1
  128. package/dist/components/Poll/PollActions/PollResults/PollOptionWithLatestVotes.js +4 -2
  129. package/dist/components/Poll/PollActions/PollResults/PollResults.js +2 -1
  130. package/dist/components/Poll/PollContent.js +1 -1
  131. package/dist/components/Poll/PollCreationDialog/OptionFieldSet.d.ts +1 -1
  132. package/dist/components/Poll/PollCreationDialog/OptionFieldSet.js +11 -4
  133. package/dist/components/Poll/PollCreationDialog/PollCreationDialog.js +13 -4
  134. package/dist/components/Poll/PollCreationDialog/PollCreationDialogControls.js +6 -3
  135. package/dist/components/Poll/PollOptionList.js +1 -1
  136. package/dist/components/Poll/PollOptionSelector.js +12 -5
  137. package/dist/components/Poll/hooks/useManagePollVotesRealtime.js +9 -4
  138. package/dist/components/Poll/hooks/usePollAnswerPagination.js +8 -2
  139. package/dist/components/Poll/hooks/usePollOptionVotesPagination.js +8 -2
  140. package/dist/components/ReactFileUtilities/FileIcon/mimeTypes.d.ts +1 -1
  141. package/dist/components/ReactFileUtilities/ImageDropzone.js +3 -1
  142. package/dist/components/ReactFileUtilities/UploadButton.js +1 -1
  143. package/dist/components/ReactFileUtilities/utils.js +3 -1
  144. package/dist/components/Reactions/ReactionSelector.js +3 -1
  145. package/dist/components/Reactions/ReactionSelectorWithButton.js +1 -1
  146. package/dist/components/Reactions/ReactionsList.d.ts +2 -2
  147. package/dist/components/Reactions/ReactionsList.js +7 -4
  148. package/dist/components/Reactions/ReactionsListModal.d.ts +1 -2
  149. package/dist/components/Reactions/ReactionsListModal.js +1 -1
  150. package/dist/components/Reactions/SpriteImage.js +6 -2
  151. package/dist/components/Reactions/hooks/useFetchReactions.js +1 -1
  152. package/dist/components/Reactions/hooks/useProcessReactions.js +1 -1
  153. package/dist/components/Reactions/index.d.ts +1 -0
  154. package/dist/components/Reactions/index.js +1 -0
  155. package/dist/components/Reactions/reactionOptions.js +20 -5
  156. package/dist/components/Thread/Thread.js +4 -3
  157. package/dist/components/Threads/ThreadContext.d.ts +1 -1
  158. package/dist/components/Threads/ThreadContext.js +1 -1
  159. package/dist/components/Threads/ThreadList/ThreadList.js +1 -1
  160. package/dist/components/Threads/ThreadList/ThreadListItem.d.ts +1 -1
  161. package/dist/components/Threads/ThreadList/ThreadListItem.js +1 -1
  162. package/dist/components/Threads/ThreadList/ThreadListItemUI.js +5 -3
  163. package/dist/components/Threads/icons.js +0 -1
  164. package/dist/components/Tooltip/Tooltip.d.ts +1 -1
  165. package/dist/components/Tooltip/Tooltip.js +1 -1
  166. package/dist/context/ComponentContext.d.ts +3 -1
  167. package/dist/context/ComponentContext.js +1 -1
  168. package/dist/context/DialogManagerContext.d.ts +1 -1
  169. package/dist/context/DialogManagerContext.js +1 -1
  170. package/dist/context/MessageBounceContext.js +2 -2
  171. package/dist/context/MessageContext.js +1 -1
  172. package/dist/context/VirtualizedMessageListContext.d.ts +13 -0
  173. package/dist/context/VirtualizedMessageListContext.js +7 -0
  174. package/dist/context/WithComponents.js +1 -1
  175. package/dist/css/v2/index.css +2 -2
  176. package/dist/css/v2/index.layout.css +2 -2
  177. package/dist/experimental/MessageActions/MessageActions.js +0 -1
  178. package/dist/experimental/MessageActions/defaults.js +31 -7
  179. package/dist/experimental/index.browser.cjs +103 -37
  180. package/dist/experimental/index.browser.cjs.map +2 -2
  181. package/dist/experimental/index.node.cjs +103 -37
  182. package/dist/experimental/index.node.cjs.map +2 -2
  183. package/dist/i18n/Streami18n.js +11 -2
  184. package/dist/i18n/utils.js +14 -1
  185. package/dist/index.browser.cjs +2329 -1145
  186. package/dist/index.browser.cjs.map +4 -4
  187. package/dist/index.node.cjs +2594 -1164
  188. package/dist/index.node.cjs.map +4 -4
  189. package/dist/plugins/Emojis/EmojiPicker.js +0 -1
  190. package/dist/plugins/Emojis/index.browser.cjs +3 -1
  191. package/dist/plugins/Emojis/index.browser.cjs.map +2 -2
  192. package/dist/plugins/Emojis/index.node.cjs +3 -1
  193. package/dist/plugins/Emojis/index.node.cjs.map +2 -2
  194. package/dist/plugins/encoders/mp3.browser.cjs +7 -4
  195. package/dist/plugins/encoders/mp3.browser.cjs.map +2 -2
  196. package/dist/plugins/encoders/mp3.node.cjs +7 -4
  197. package/dist/plugins/encoders/mp3.node.cjs.map +2 -2
  198. package/dist/scss/v2/ChannelSearch/ChannelSearch-layout.scss +1 -0
  199. package/dist/scss/v2/Message/Message-layout.scss +12 -5
  200. package/dist/scss/v2/Poll/Poll-layout.scss +1 -1
  201. package/dist/scss/v2/Search/Search-layout.scss +148 -0
  202. package/dist/scss/v2/Search/Search-theme.scss +222 -0
  203. package/dist/scss/v2/_icons.scss +2 -0
  204. package/dist/scss/v2/index.layout.scss +1 -0
  205. package/dist/scss/v2/index.scss +1 -0
  206. package/dist/store/hooks/useStateStore.js +35 -11
  207. package/package.json +32 -47
@@ -24,8 +24,9 @@ export const ATTACHMENT_GROUPS_ORDER = [
24
24
  */
25
25
  export const Attachment = (props) => {
26
26
  const { attachments } = props;
27
+ const groupedAttachments = useMemo(() => renderGroupedAttachments(props),
27
28
  // eslint-disable-next-line react-hooks/exhaustive-deps
28
- const groupedAttachments = useMemo(() => renderGroupedAttachments(props), [attachments]);
29
+ [attachments]);
29
30
  return (React.createElement("div", { className: 'str-chat__attachment-list' }, ATTACHMENT_GROUPS_ORDER.reduce((acc, groupName) => [...acc, ...groupedAttachments[groupName]], [])));
30
31
  };
31
32
  const renderGroupedAttachments = ({ attachments, ...rest }) => {
@@ -13,6 +13,6 @@ export declare const ImageContainer: <StreamChatGenerics extends DefaultStreamCh
13
13
  export declare const CardContainer: <StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics>(props: RenderAttachmentProps<StreamChatGenerics>) => React.JSX.Element;
14
14
  export declare const FileContainer: <StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics>({ attachment, File, }: RenderAttachmentProps<StreamChatGenerics>) => React.JSX.Element | null;
15
15
  export declare const AudioContainer: <StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics>({ attachment, Audio, }: RenderAttachmentProps<StreamChatGenerics>) => React.JSX.Element;
16
- export declare const VoiceRecordingContainer: <StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics>({ attachment, VoiceRecording, isQuoted, }: RenderAttachmentProps<StreamChatGenerics>) => React.JSX.Element;
16
+ export declare const VoiceRecordingContainer: <StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics>({ attachment, isQuoted, VoiceRecording, }: RenderAttachmentProps<StreamChatGenerics>) => React.JSX.Element;
17
17
  export declare const MediaContainer: <StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics>(props: RenderAttachmentProps<StreamChatGenerics>) => React.JSX.Element;
18
18
  export declare const UnsupportedAttachmentContainer: <StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics>({ attachment, UnsupportedAttachment, }: RenderAttachmentProps<StreamChatGenerics>) => React.JSX.Element;
@@ -123,7 +123,7 @@ export const FileContainer = ({ attachment, File = DefaultFile, }) => {
123
123
  export const AudioContainer = ({ attachment, Audio = DefaultAudio, }) => (React.createElement(AttachmentWithinContainer, { attachment: attachment, componentType: 'audio' },
124
124
  React.createElement("div", { className: 'str-chat__attachment' },
125
125
  React.createElement(Audio, { og: attachment }))));
126
- export const VoiceRecordingContainer = ({ attachment, VoiceRecording = DefaultVoiceRecording, isQuoted, }) => (React.createElement(AttachmentWithinContainer, { attachment: attachment, componentType: 'voiceRecording' },
126
+ export const VoiceRecordingContainer = ({ attachment, isQuoted, VoiceRecording = DefaultVoiceRecording, }) => (React.createElement(AttachmentWithinContainer, { attachment: attachment, componentType: 'voiceRecording' },
127
127
  React.createElement("div", { className: 'str-chat__attachment' },
128
128
  React.createElement(VoiceRecording, { attachment: attachment, isQuoted: isQuoted }))));
129
129
  export const MediaContainer = (props) => {
@@ -131,7 +131,7 @@ export const MediaContainer = (props) => {
131
131
  const componentType = 'media';
132
132
  const { shouldGenerateVideoThumbnail, videoAttachmentSizeHandler } = useChannelStateContext();
133
133
  const videoElement = useRef(null);
134
- const [attachmentConfiguration, setAttachmentConfiguration,] = useState();
134
+ const [attachmentConfiguration, setAttachmentConfiguration] = useState();
135
135
  useLayoutEffect(() => {
136
136
  if (videoElement.current && videoAttachmentSizeHandler) {
137
137
  const config = videoAttachmentSizeHandler(attachment, videoElement.current, shouldGenerateVideoThumbnail);
@@ -22,7 +22,7 @@ const UnableToRenderCard = ({ type }) => {
22
22
  React.createElement("div", { className: 'str-chat__message-attachment-card--content' },
23
23
  React.createElement("div", { className: 'str-chat__message-attachment-card--text' }, t('this content could not be displayed')))));
24
24
  };
25
- const SourceLink = ({ author_name, url }) => (React.createElement("div", { className: 'str-chat__message-attachment-card--source-link', "data-testid": 'card-source-link' },
25
+ const SourceLink = ({ author_name, url, }) => (React.createElement("div", { className: 'str-chat__message-attachment-card--source-link', "data-testid": 'card-source-link' },
26
26
  React.createElement(SafeAnchor, { className: 'str-chat__message-attachment-card--url', href: url, rel: 'noopener noreferrer', target: '_blank' }, author_name || getHostFromURL(url))));
27
27
  const CardHeader = (props) => {
28
28
  const { asset_url, dimensions, image, image_url, thumb_url, title, type } = props;
@@ -40,7 +40,7 @@ const CardContent = (props) => {
40
40
  const url = title_link || og_scrape_url;
41
41
  return (React.createElement("div", { className: 'str-chat__message-attachment-card--content' }, type === 'audio' ? (React.createElement(CardAudio, { og: props })) : (React.createElement("div", { className: 'str-chat__message-attachment-card--flex' },
42
42
  url && React.createElement(SourceLink, { author_name: author_name, url: url }),
43
- title && React.createElement("div", { className: 'str-chat__message-attachment-card--title' }, title),
43
+ title && (React.createElement("div", { className: 'str-chat__message-attachment-card--title' }, title)),
44
44
  text && React.createElement("div", { className: 'str-chat__message-attachment-card--text' }, text)))));
45
45
  };
46
46
  export const CardAudio = ({ og: { asset_url, author_name, mime_type, og_scrape_url, text, title, title_link }, }) => {
@@ -60,7 +60,7 @@ export const CardAudio = ({ og: { asset_url, author_name, mime_type, og_scrape_u
60
60
  React.createElement(ProgressBar, { onClick: seek, progress: progress })))),
61
61
  React.createElement("div", { className: 'str-chat__message-attachment-audio-widget--second-row' },
62
62
  url && React.createElement(SourceLink, { author_name: author_name, url: url }),
63
- title && React.createElement("div", { className: 'str-chat__message-attachment-audio-widget--title' }, title),
63
+ title && (React.createElement("div", { className: 'str-chat__message-attachment-audio-widget--title' }, title)),
64
64
  text && (React.createElement("div", { className: 'str-chat__message-attachment-audio-widget--description' }, text)))));
65
65
  };
66
66
  const UnMemoizedCard = (props) => {
@@ -5,7 +5,7 @@ export type VoiceRecordingPlayerProps<StreamChatGenerics extends DefaultStreamCh
5
5
  /** An array of fractional numeric values of playback speed to override the defaults (1.0, 1.5, 2.0) */
6
6
  playbackRates?: number[];
7
7
  };
8
- export declare const VoiceRecordingPlayer: ({ attachment, playbackRates }: VoiceRecordingPlayerProps) => React.JSX.Element | null;
8
+ export declare const VoiceRecordingPlayer: ({ attachment, playbackRates, }: VoiceRecordingPlayerProps) => React.JSX.Element | null;
9
9
  export type QuotedVoiceRecordingProps<StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics> = Pick<VoiceRecordingProps<StreamChatGenerics>, 'attachment'>;
10
10
  export declare const QuotedVoiceRecording: ({ attachment }: QuotedVoiceRecordingProps) => React.JSX.Element;
11
11
  export type VoiceRecordingProps<StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics> = {
@@ -1,11 +1,11 @@
1
1
  import React from 'react';
2
- import { FileSizeIndicator, PlaybackRateButton, PlayButton, WaveProgressBar } from './components';
2
+ import { FileSizeIndicator, PlaybackRateButton, PlayButton, WaveProgressBar, } from './components';
3
3
  import { useAudioController } from './hooks/useAudioController';
4
4
  import { displayDuration } from './utils';
5
5
  import { FileIcon } from '../ReactFileUtilities';
6
6
  import { useTranslationContext } from '../../context';
7
7
  const rootClassName = 'str-chat__message-attachment__voice-recording-widget';
8
- export const VoiceRecordingPlayer = ({ attachment, playbackRates }) => {
8
+ export const VoiceRecordingPlayer = ({ attachment, playbackRates, }) => {
9
9
  const { t } = useTranslationContext('VoiceRecordingPlayer');
10
10
  const { asset_url, duration = 0, mime_type, title = t('Voice message'), waveform_data, } = attachment;
11
11
  const { audioRef, increasePlaybackRate, isPlaying, playbackRate, progress, secondsElapsed, seek, togglePlay, } = useAudioController({
@@ -43,7 +43,8 @@ const getSizingRestrictions = (url, htmlElement) => {
43
43
  const originalWidth = Number(urlParams.get('ow')) || 1;
44
44
  const cssSizeRestriction = getCSSSizeRestrictions(htmlElement);
45
45
  let resizeDimensions;
46
- if ((cssSizeRestriction.maxHeight || cssSizeRestriction.height) && cssSizeRestriction.maxWidth) {
46
+ if ((cssSizeRestriction.maxHeight || cssSizeRestriction.height) &&
47
+ cssSizeRestriction.maxWidth) {
47
48
  resizeDimensions = getResizeDimensions(originalHeight, originalWidth,
48
49
  /* eslint-disable-next-line @typescript-eslint/no-non-null-assertion */
49
50
  cssSizeRestriction.maxHeight || cssSizeRestriction.height, cssSizeRestriction.maxWidth);
@@ -8,5 +8,5 @@ type FileSizeIndicatorProps = {
8
8
  */
9
9
  maximumFractionDigits?: number;
10
10
  };
11
- export declare const FileSizeIndicator: ({ fileSize, maximumFractionDigits }: FileSizeIndicatorProps) => React.JSX.Element | null;
11
+ export declare const FileSizeIndicator: ({ fileSize, maximumFractionDigits, }: FileSizeIndicatorProps) => React.JSX.Element | null;
12
12
  export {};
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
  import { prettifyFileSize } from '../../MessageInput/hooks/utils';
3
- export const FileSizeIndicator = ({ fileSize, maximumFractionDigits }) => {
3
+ export const FileSizeIndicator = ({ fileSize, maximumFractionDigits, }) => {
4
4
  if (!(fileSize && Number.isFinite(Number(fileSize))))
5
5
  return null;
6
6
  return (React.createElement("span", { className: 'str-chat__message-attachment-file--item-size', "data-testid": 'file-size-indicator' }, prettifyFileSize(fileSize, maximumFractionDigits)));
@@ -7,7 +7,7 @@ export const WaveProgressBar = ({ amplitudesCount = 40, progress = 0, relativeAm
7
7
  const isDragging = useRef(false);
8
8
  const [root, setRoot] = useState(null);
9
9
  const [trackAxisX, setTrackAxisX] = useState();
10
- const lastRootWidth = useRef();
10
+ const lastRootWidth = useRef(undefined);
11
11
  const handleDragStart = (e) => {
12
12
  e.preventDefault();
13
13
  if (!progressIndicator)
@@ -13,7 +13,7 @@ type AudioControllerParams = {
13
13
  playbackRates?: number[];
14
14
  };
15
15
  export declare const useAudioController: ({ durationSeconds, mimeType, playbackRates, }?: AudioControllerParams) => {
16
- audioRef: import("react").MutableRefObject<HTMLAudioElement | null>;
16
+ audioRef: import("react").RefObject<HTMLAudioElement | null>;
17
17
  canPlayRecord: boolean;
18
18
  increasePlaybackRate: () => void;
19
19
  isPlaying: boolean;
@@ -13,7 +13,7 @@ export const useAudioController = ({ durationSeconds, mimeType, playbackRates =
13
13
  const [canPlayRecord, setCanPlayRecord] = useState(true);
14
14
  const [secondsElapsed, setSecondsElapsed] = useState(0);
15
15
  const [playbackRateIndex, setPlaybackRateIndex] = useState(0);
16
- const playTimeout = useRef();
16
+ const playTimeout = useRef(undefined);
17
17
  const audioRef = useRef(null);
18
18
  const registerError = useCallback((e) => {
19
19
  logError(e);
@@ -116,7 +116,9 @@ export const useAudioController = ({ durationSeconds, mimeType, playbackRates =
116
116
  isPlaying,
117
117
  playbackError,
118
118
  playbackRate: playbackRates[playbackRateIndex],
119
- progress: audioRef.current && secondsElapsed ? (secondsElapsed / audioRef.current.duration) * 100 : 0,
119
+ progress: audioRef.current && secondsElapsed
120
+ ? (secondsElapsed / audioRef.current.duration) * 100
121
+ : 0,
120
122
  secondsElapsed,
121
123
  seek,
122
124
  togglePlay,
@@ -4,7 +4,7 @@ import type { ATTACHMENT_GROUPS_ORDER, AttachmentProps } from './Attachment';
4
4
  import type { DefaultStreamChatGenerics, UnknownType } from '../../types/types';
5
5
  import type { LocalAttachment, LocalAudioAttachment, LocalFileAttachment, LocalImageAttachment, LocalVideoAttachment, LocalVoiceRecordingAttachment, VoiceRecordingAttachment } from '../MessageInput';
6
6
  export declare const SUPPORTED_VIDEO_FORMATS: string[];
7
- export type AttachmentComponentType = typeof ATTACHMENT_GROUPS_ORDER[number];
7
+ export type AttachmentComponentType = (typeof ATTACHMENT_GROUPS_ORDER)[number];
8
8
  export type GroupedRenderedAttachment = Record<AttachmentComponentType, ReactNode[]>;
9
9
  export type GalleryAttachment<StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics> = {
10
10
  images: Attachment<StreamChatGenerics>[];
@@ -1,4 +1,9 @@
1
- export const SUPPORTED_VIDEO_FORMATS = ['video/mp4', 'video/ogg', 'video/webm', 'video/quicktime'];
1
+ export const SUPPORTED_VIDEO_FORMATS = [
2
+ 'video/mp4',
3
+ 'video/ogg',
4
+ 'video/webm',
5
+ 'video/quicktime',
6
+ ];
2
7
  export const isLocalAttachment = (attachment) => !!attachment.localMetadata?.id;
3
8
  export const isScrapedContent = (attachment) => attachment.og_scrape_url || attachment.title_link;
4
9
  export const isUploadedImage = (attachment) => attachment.type === 'image' && !isScrapedContent(attachment);
@@ -13,14 +18,18 @@ export const isFileAttachment = (attachment) => attachment.type === 'file' ||
13
18
  SUPPORTED_VIDEO_FORMATS.indexOf(attachment.mime_type) === -1 &&
14
19
  attachment.type !== 'video');
15
20
  export const isLocalFileAttachment = (attachment) => isFileAttachment(attachment) && isLocalAttachment(attachment);
16
- export const isMediaAttachment = (attachment) => (attachment.mime_type && SUPPORTED_VIDEO_FORMATS.indexOf(attachment.mime_type) !== -1) ||
21
+ export const isMediaAttachment = (attachment) => (attachment.mime_type &&
22
+ SUPPORTED_VIDEO_FORMATS.indexOf(attachment.mime_type) !== -1) ||
17
23
  attachment.type === 'video';
18
24
  export const isLocalMediaAttachment = (attachment) => isMediaAttachment(attachment) && isLocalAttachment(attachment);
19
25
  export const isSvgAttachment = (attachment) => {
20
26
  const filename = attachment.fallback || '';
21
27
  return filename.toLowerCase().endsWith('.svg');
22
28
  };
23
- export const divMod = (num, divisor) => [Math.floor(num / divisor), num % divisor];
29
+ export const divMod = (num, divisor) => [
30
+ Math.floor(num / divisor),
31
+ num % divisor,
32
+ ];
24
33
  export const displayDuration = (totalSeconds) => {
25
34
  if (!totalSeconds || totalSeconds < 0)
26
35
  return '00:00';
@@ -19,7 +19,7 @@ export const List = ({ className, component, currentTrigger, dropdownScroll, get
19
19
  }
20
20
  return item.key;
21
21
  };
22
- const findItemIndex = useCallback((item) => values.findIndex((value) => (value.id ? value.id === item.id : value.name === item.name)), [values]);
22
+ const findItemIndex = useCallback((item) => values.findIndex((value) => value.id ? value.id === item.id : value.name === item.name), [values]);
23
23
  const modifyText = (value) => {
24
24
  if (!value)
25
25
  return;
@@ -57,7 +57,8 @@ export const List = ({ className, component, currentTrigger, dropdownScroll, get
57
57
  return newIndex;
58
58
  });
59
59
  }
60
- if ((event.key === 'Enter' || event.key === 'Tab') && selectedItemIndex !== undefined) {
60
+ if ((event.key === 'Enter' || event.key === 'Tab') &&
61
+ selectedItemIndex !== undefined) {
61
62
  handleClick(event, values[selectedItemIndex]);
62
63
  }
63
64
  return null;
@@ -2,7 +2,6 @@ import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import Textarea from 'react-textarea-autosize';
4
4
  import getCaretCoordinates from 'textarea-caret';
5
- import { isValidElementType } from 'react-is';
6
5
  import clsx from 'clsx';
7
6
  import { List as DefaultSuggestionList } from './List';
8
7
  import { DEFAULT_CARET_POSITION, defaultScrollToItem, errorMessage, triggerPropsCheck, } from './utils';
@@ -112,7 +111,7 @@ export class ReactTextareaAutocomplete extends React.Component {
112
111
  };
113
112
  this._onSelect = (newToken) => {
114
113
  const { closeCommandsList, closeMentionsList, onChange, showCommandsList, showMentionsList, } = this.props;
115
- const { currentTrigger: stateTrigger, selectionEnd, value: textareaValue } = this.state;
114
+ const { currentTrigger: stateTrigger, selectionEnd, value: textareaValue, } = this.state;
116
115
  const currentTrigger = showCommandsList ? '/' : showMentionsList ? '@' : stateTrigger;
117
116
  if (!currentTrigger)
118
117
  return;
@@ -242,9 +241,6 @@ export class ReactTextareaAutocomplete extends React.Component {
242
241
  if (!Array.isArray(data)) {
243
242
  throw new Error('Trigger provider has to provide an array!');
244
243
  }
245
- if (!isValidElementType(component)) {
246
- throw new Error('Component should be defined!');
247
- }
248
244
  // throw away if we resolved old trigger
249
245
  if (currentTrigger !== this.state.currentTrigger)
250
246
  return;
@@ -317,7 +313,6 @@ export class ReactTextareaAutocomplete extends React.Component {
317
313
  'trigger',
318
314
  'value',
319
315
  ];
320
- // eslint-disable-next-line
321
316
  for (const prop in props) {
322
317
  if (notSafe.includes(prop))
323
318
  delete props[prop];
@@ -354,7 +349,8 @@ export class ReactTextareaAutocomplete extends React.Component {
354
349
  const regex = new RegExp(`(?!^|\\W)?[${triggerTokens}]${triggerNorWhitespace}\\s?${triggerNorWhitespace}$`, 'g');
355
350
  const tokenMatch = value.slice(0, selectionEnd).match(regex);
356
351
  lastToken = tokenMatch && tokenMatch[tokenMatch.length - 1].trim();
357
- currentTrigger = (lastToken && Object.keys(trigger).find((a) => a === lastToken[0])) || null;
352
+ currentTrigger =
353
+ (lastToken && Object.keys(trigger).find((a) => a === lastToken[0])) || null;
358
354
  }
359
355
  /*
360
356
  if we lost the trigger token or there is no following character we want to close
@@ -1,4 +1,3 @@
1
- import { isValidElementType } from 'react-is';
2
1
  export const DEFAULT_CARET_POSITION = 'next';
3
2
  export function defaultScrollToItem(container, item) {
4
3
  if (!item)
@@ -7,10 +6,10 @@ export function defaultScrollToItem(container, item) {
7
6
  const containerHight = parseInt(getComputedStyle(container).getPropertyValue('height'), 10) - itemHeight;
8
7
  const actualScrollTop = container.scrollTop;
9
8
  const itemOffsetTop = item.offsetTop;
10
- if (itemOffsetTop < actualScrollTop + containerHight && actualScrollTop < itemOffsetTop) {
9
+ if (itemOffsetTop < actualScrollTop + containerHight &&
10
+ actualScrollTop < itemOffsetTop) {
11
11
  return;
12
12
  }
13
- // eslint-disable-next-line
14
13
  container.scrollTop = itemOffsetTop;
15
14
  }
16
15
  export const errorMessage = (message) => console.error(`RTA: dataProvider fails: ${message}
@@ -26,10 +25,7 @@ export const triggerPropsCheck = ({ trigger }) => {
26
25
  }
27
26
  // $FlowFixMe
28
27
  const triggerSetting = settings;
29
- const { callback, component, dataProvider, output } = triggerSetting;
30
- if (!isValidElementType(component)) {
31
- return Error('Invalid prop trigger: component should be defined.');
32
- }
28
+ const { callback, dataProvider, output } = triggerSetting;
33
29
  if (!dataProvider || typeof dataProvider !== 'function') {
34
30
  return Error('Invalid prop trigger: dataProvider should be defined.');
35
31
  }
@@ -2,7 +2,7 @@ import React from 'react';
2
2
  import { Avatar, GroupAvatar } from './index';
3
3
  export const ChannelAvatar = ({ groupChannelDisplayInfo, image, name, user, ...sharedProps }) => {
4
4
  if (groupChannelDisplayInfo) {
5
- return React.createElement(GroupAvatar, { groupChannelDisplayInfo: groupChannelDisplayInfo, ...sharedProps });
5
+ return (React.createElement(GroupAvatar, { groupChannelDisplayInfo: groupChannelDisplayInfo, ...sharedProps }));
6
6
  }
7
7
  return React.createElement(Avatar, { image: image, name: name, user: user, ...sharedProps });
8
8
  };
@@ -6,7 +6,7 @@ import { ComponentContextValue, StreamMessage } from '../../context';
6
6
  import type { MessageInputProps } from '../MessageInput';
7
7
  import type { ChannelUnreadUiState, CustomTrigger, DefaultStreamChatGenerics, GiphyVersions, ImageAttachmentSizeHandler, SendMessageOptions, UpdateMessageOptions, VideoAttachmentSizeHandler } from '../../types/types';
8
8
  import type { URLEnrichmentConfig } from '../MessageInput/hooks/useLinkPreviews';
9
- type ChannelPropsForwardedToComponentContext<StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics> = Pick<ComponentContextValue<StreamChatGenerics>, 'Attachment' | 'AttachmentPreviewList' | 'AttachmentSelector' | 'AttachmentSelectorInitiationButtonContents' | 'AudioRecorder' | 'AutocompleteSuggestionItem' | 'AutocompleteSuggestionList' | 'Avatar' | 'BaseImage' | 'CooldownTimer' | 'CustomMessageActionsList' | 'DateSeparator' | 'EditMessageInput' | 'EmojiPicker' | 'emojiSearchIndex' | 'EmptyStateIndicator' | 'FileUploadIcon' | 'GiphyPreviewMessage' | 'HeaderComponent' | 'Input' | 'LinkPreviewList' | 'LoadingIndicator' | 'Message' | 'MessageActions' | 'MessageBouncePrompt' | 'MessageDeleted' | 'MessageListNotifications' | 'MessageListMainPanel' | 'MessageNotification' | 'MessageOptions' | 'MessageRepliesCountButton' | 'MessageStatus' | 'MessageSystem' | 'MessageTimestamp' | 'ModalGallery' | 'PinIndicator' | 'PollActions' | 'PollContent' | 'PollCreationDialog' | 'PollHeader' | 'PollOptionSelector' | 'QuotedMessage' | 'QuotedMessagePreview' | 'QuotedPoll' | 'reactionOptions' | 'ReactionSelector' | 'ReactionsList' | 'SendButton' | 'StartRecordingAudioButton' | 'ThreadHead' | 'ThreadHeader' | 'ThreadStart' | 'Timestamp' | 'TriggerProvider' | 'TypingIndicator' | 'UnreadMessagesNotification' | 'UnreadMessagesSeparator' | 'VirtualMessage' | 'StopAIGenerationButton' | 'StreamedMessageText'>;
9
+ type ChannelPropsForwardedToComponentContext<StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics> = Pick<ComponentContextValue<StreamChatGenerics>, 'Attachment' | 'AttachmentPreviewList' | 'AttachmentSelector' | 'AttachmentSelectorInitiationButtonContents' | 'AudioRecorder' | 'AutocompleteSuggestionItem' | 'AutocompleteSuggestionList' | 'Avatar' | 'BaseImage' | 'CooldownTimer' | 'CustomMessageActionsList' | 'DateSeparator' | 'EditMessageInput' | 'EmojiPicker' | 'emojiSearchIndex' | 'EmptyStateIndicator' | 'FileUploadIcon' | 'GiphyPreviewMessage' | 'HeaderComponent' | 'Input' | 'LinkPreviewList' | 'LoadingIndicator' | 'Message' | 'MessageActions' | 'MessageBouncePrompt' | 'MessageDeleted' | 'MessageListNotifications' | 'MessageListMainPanel' | 'MessageNotification' | 'MessageOptions' | 'MessageRepliesCountButton' | 'MessageStatus' | 'MessageSystem' | 'MessageTimestamp' | 'ModalGallery' | 'PinIndicator' | 'PollActions' | 'PollContent' | 'PollCreationDialog' | 'PollHeader' | 'PollOptionSelector' | 'QuotedMessage' | 'QuotedMessagePreview' | 'QuotedPoll' | 'reactionOptions' | 'ReactionSelector' | 'ReactionsList' | 'ReactionsListModal' | 'SendButton' | 'StartRecordingAudioButton' | 'ThreadHead' | 'ThreadHeader' | 'ThreadStart' | 'Timestamp' | 'TriggerProvider' | 'TypingIndicator' | 'UnreadMessagesNotification' | 'UnreadMessagesSeparator' | 'VirtualMessage' | 'StopAIGenerationButton' | 'StreamedMessageText'>;
10
10
  export type ChannelProps<StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, V extends CustomTrigger = CustomTrigger> = ChannelPropsForwardedToComponentContext<StreamChatGenerics> & {
11
11
  /** List of accepted file types */
12
12
  acceptedFiles?: string[];
@@ -4,7 +4,7 @@ import defaultsDeep from 'lodash.defaultsdeep';
4
4
  import throttle from 'lodash.throttle';
5
5
  import { nanoid } from 'nanoid';
6
6
  import clsx from 'clsx';
7
- import { channelReducer, initialState } from './channelState';
7
+ import { initialState, makeChannelReducer } from './channelState';
8
8
  import { useCreateChannelStateContext } from './hooks/useCreateChannelStateContext';
9
9
  import { useCreateTypingContext } from './hooks/useCreateTypingContext';
10
10
  import { useEditMessageHandler } from './hooks/useEditMessageHandler';
@@ -53,7 +53,7 @@ const ChannelInner = (props) => {
53
53
  const channelQueryOptions = useMemo(() => defaultsDeep(propChannelQueryOptions, {
54
54
  messages: { limit: DEFAULT_INITIAL_CHANNEL_PAGE_SIZE },
55
55
  }), [propChannelQueryOptions]);
56
- const { client, customClasses, latestMessageDatesByChannels, mutes, } = useChatContext('Channel');
56
+ const { client, customClasses, latestMessageDatesByChannels, mutes } = useChatContext('Channel');
57
57
  const { t } = useTranslationContext('Channel');
58
58
  const chatContainerClass = getChatContainerClass(customClasses?.chatContainer);
59
59
  const windowsEmojiClass = useImageFlagEmojisOnWindowsClass();
@@ -63,6 +63,7 @@ const ChannelInner = (props) => {
63
63
  const [quotedMessage, setQuotedMessage] = useState();
64
64
  const [channelUnreadUiState, _setChannelUnreadUiState] = useState();
65
65
  const notificationTimeouts = useRef([]);
66
+ const channelReducer = useMemo(() => makeChannelReducer(), []);
66
67
  const [state, dispatch] = useReducer(channelReducer,
67
68
  // channel.initialized === false if client.channel().query() was not called, e.g. ChannelList is not used
68
69
  // => Channel will call channel.watch() in useLayoutEffect => state.loading is used to signal the watch() call state
@@ -73,7 +74,7 @@ const ChannelInner = (props) => {
73
74
  });
74
75
  const isMounted = useIsMounted();
75
76
  const originalTitle = useRef('');
76
- const lastRead = useRef();
77
+ const lastRead = useRef(undefined);
77
78
  const online = useRef(true);
78
79
  const channelCapabilitiesArray = channel.data?.own_capabilities;
79
80
  const throttledCopyStateFromChannel = throttle(() => dispatch({ channel, type: 'copyStateFromChannelOnEvent' }), 500, {
@@ -114,7 +115,14 @@ const ChannelInner = (props) => {
114
115
  catch (e) {
115
116
  console.error(t('Failed to mark channel as read'));
116
117
  }
117
- }, 500, { leading: true, trailing: false }), [activeUnreadHandler, channel, channelConfig, doMarkReadRequest, setChannelUnreadUiState, t]);
118
+ }, 500, { leading: true, trailing: false }), [
119
+ activeUnreadHandler,
120
+ channel,
121
+ channelConfig,
122
+ doMarkReadRequest,
123
+ setChannelUnreadUiState,
124
+ t,
125
+ ]);
118
126
  const handleEvent = async (event) => {
119
127
  if (event.message) {
120
128
  dispatch({
@@ -134,7 +142,9 @@ const ChannelInner = (props) => {
134
142
  if (event.type === 'message.new') {
135
143
  const mainChannelUpdated = !event.message?.parent_id || event.message?.show_in_channel;
136
144
  if (mainChannelUpdated) {
137
- if (document.hidden && channelConfig?.read_events && !channel.muteStatus().muted) {
145
+ if (document.hidden &&
146
+ channelConfig?.read_events &&
147
+ !channel.muteStatus().muted) {
138
148
  const unread = channel.countUnread(lastRead.current);
139
149
  if (activeUnreadHandler) {
140
150
  activeUnreadHandler(unread, originalTitle.current);
@@ -282,11 +292,15 @@ const ChannelInner = (props) => {
282
292
  dispatch({ hasMore, messages, type: 'loadMoreFinished' });
283
293
  }, 2000, { leading: true, trailing: true }), []);
284
294
  const loadMore = async (limit = DEFAULT_NEXT_CHANNEL_PAGE_SIZE) => {
285
- if (!online.current || !window.navigator.onLine || !channel.state.messagePagination.hasPrev)
295
+ if (!online.current ||
296
+ !window.navigator.onLine ||
297
+ !channel.state.messagePagination.hasPrev)
286
298
  return 0;
287
299
  // prevent duplicate loading events...
288
300
  const oldestMessage = state?.messages?.[0];
289
- if (state.loadingMore || state.loadingMoreNewer || oldestMessage?.status !== 'received') {
301
+ if (state.loadingMore ||
302
+ state.loadingMoreNewer ||
303
+ oldestMessage?.status !== 'received') {
290
304
  return 0;
291
305
  }
292
306
  dispatch({ loadingMore: true, type: 'setLoadingMore' });
@@ -308,7 +322,9 @@ const ChannelInner = (props) => {
308
322
  return queryResponse.messages.length;
309
323
  };
310
324
  const loadMoreNewer = async (limit = DEFAULT_NEXT_CHANNEL_PAGE_SIZE) => {
311
- if (!online.current || !window.navigator.onLine || !channel.state.messagePagination.hasNext)
325
+ if (!online.current ||
326
+ !window.navigator.onLine ||
327
+ !channel.state.messagePagination.hasNext)
312
328
  return 0;
313
329
  const newestMessage = state?.messages?.[state?.messages?.length - 1];
314
330
  if (state.loadingMore || state.loadingMoreNewer)
@@ -538,9 +554,7 @@ const ChannelInner = (props) => {
538
554
  catch (error) {
539
555
  // error response isn't usable so needs to be stringified then parsed
540
556
  const stringError = JSON.stringify(error);
541
- const parsedError = (stringError
542
- ? JSON.parse(stringError)
543
- : {});
557
+ const parsedError = (stringError ? JSON.parse(stringError) : {});
544
558
  // Handle the case where the message already exists
545
559
  // (typically, when retrying to send a message).
546
560
  // If the message already exists, we can assume it was sent successfully,
@@ -564,7 +578,7 @@ const ChannelInner = (props) => {
564
578
  status: 'failed',
565
579
  });
566
580
  thread?.upsertReplyLocally({
567
- // @ts-expect-error
581
+ // @ts-expect-error message type mismatch
568
582
  message: {
569
583
  ...message,
570
584
  error: parsedError,
@@ -591,7 +605,7 @@ const ChannelInner = (props) => {
591
605
  user: client.user,
592
606
  };
593
607
  thread?.upsertReplyLocally({
594
- // @ts-expect-error
608
+ // @ts-expect-error message type mismatch
595
609
  message: messagePreview,
596
610
  });
597
611
  updateMessage(messagePreview);
@@ -732,7 +746,7 @@ const ChannelInner = (props) => {
732
746
  jumpToLatestMessage,
733
747
  setChannelUnreadUiState,
734
748
  ]);
735
- // @ts-expect-error
749
+ // @ts-expect-error message type mismatch
736
750
  const componentContextValue = useMemo(() => ({
737
751
  Attachment: props.Attachment,
738
752
  AttachmentPreviewList: props.AttachmentPreviewList,
@@ -780,6 +794,7 @@ const ChannelInner = (props) => {
780
794
  reactionOptions: props.reactionOptions,
781
795
  ReactionSelector: props.ReactionSelector,
782
796
  ReactionsList: props.ReactionsList,
797
+ ReactionsListModal: props.ReactionsListModal,
783
798
  SendButton: props.SendButton,
784
799
  StartRecordingAudioButton: props.StartRecordingAudioButton,
785
800
  StopAIGenerationButton: props.StopAIGenerationButton,
@@ -838,6 +853,7 @@ const ChannelInner = (props) => {
838
853
  props.QuotedPoll,
839
854
  props.ReactionSelector,
840
855
  props.ReactionsList,
856
+ props.ReactionsListModal,
841
857
  props.SendButton,
842
858
  props.StartRecordingAudioButton,
843
859
  props.ThreadHead,
@@ -1,4 +1,3 @@
1
- import type { Reducer } from 'react';
2
1
  import type { Channel, MessageResponse, ChannelState as StreamChannelState } from 'stream-chat';
3
2
  import type { ChannelState, StreamMessage } from '../../context/ChannelStateContext';
4
3
  import type { DefaultStreamChatGenerics } from '../../types/types';
@@ -61,8 +60,7 @@ export type ChannelStateReducerAction<StreamChatGenerics extends DefaultStreamCh
61
60
  } | {
62
61
  type: 'jumpToLatestMessage';
63
62
  };
64
- export type ChannelStateReducer<StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics> = Reducer<ChannelState<StreamChatGenerics>, ChannelStateReducerAction<StreamChatGenerics>>;
65
- export declare const channelReducer: <StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics>(state: ChannelState<StreamChatGenerics>, action: ChannelStateReducerAction<StreamChatGenerics>) => ChannelState<StreamChatGenerics>;
63
+ export declare const makeChannelReducer: <StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics>() => (state: ChannelState<StreamChatGenerics>, action: ChannelStateReducerAction<StreamChatGenerics>) => ChannelState<StreamChatGenerics>;
66
64
  export declare const initialState: {
67
65
  error: null;
68
66
  hasMore: boolean;
@@ -1,4 +1,4 @@
1
- export const channelReducer = (state, action) => {
1
+ export const makeChannelReducer = () => (state, action) => {
2
2
  switch (action.type) {
3
3
  case 'closeThread': {
4
4
  return {
@@ -103,7 +103,9 @@ export const channelReducer = (state, action) => {
103
103
  ...state,
104
104
  thread: message,
105
105
  threadHasMore: true,
106
- threadMessages: message.id ? { ...channel.state.threads }[message.id] || [] : [],
106
+ threadMessages: message.id
107
+ ? { ...channel.state.threads }[message.id] || []
108
+ : [],
107
109
  threadSuppressAutoscroll: false,
108
110
  };
109
111
  }
@@ -144,8 +146,12 @@ export const channelReducer = (state, action) => {
144
146
  return state;
145
147
  return {
146
148
  ...state,
147
- thread: message?.id === state.thread.id ? channel.state.formatMessage(message) : state.thread,
148
- threadMessages: state.thread?.id ? { ...channel.state.threads }[state.thread.id] || [] : [],
149
+ thread: message?.id === state.thread.id
150
+ ? channel.state.formatMessage(message)
151
+ : state.thread,
152
+ threadMessages: state.thread?.id
153
+ ? { ...channel.state.threads }[state.thread.id] || []
154
+ : [],
149
155
  };
150
156
  }
151
157
  default:
@@ -1,14 +1,16 @@
1
1
  import { useMemo } from 'react';
2
2
  import { isDate, isDayOrMoment } from '../../../i18n';
3
3
  export const useCreateChannelStateContext = (value) => {
4
- const { acceptedFiles, channel, channelCapabilitiesArray = [], channelConfig, debounceURLEnrichmentMs, dragAndDropWindow, enrichURLForPreview, giphyVersion, error, findURLFn, hasMore, hasMoreNewer, imageAttachmentSizeHandler, suppressAutoscroll, highlightedMessageId, loading, loadingMore, maxNumberOfFiles, members, messages = [], multipleUploads, mutes, notifications, onLinkPreviewDismissed, pinnedMessages, quotedMessage, read = {}, shouldGenerateVideoThumbnail, skipMessageDataMemoization, thread, threadHasMore, threadLoadingMore, threadMessages = [], channelUnreadUiState, videoAttachmentSizeHandler, watcherCount, watcher_count, watchers, } = value;
4
+ const { acceptedFiles, channel, channelCapabilitiesArray = [], channelConfig, channelUnreadUiState, debounceURLEnrichmentMs, dragAndDropWindow, enrichURLForPreview, error, findURLFn, giphyVersion, hasMore, hasMoreNewer, highlightedMessageId, imageAttachmentSizeHandler, loading, loadingMore, maxNumberOfFiles, members, messages = [], multipleUploads, mutes, notifications, onLinkPreviewDismissed, pinnedMessages, quotedMessage, read = {}, shouldGenerateVideoThumbnail, skipMessageDataMemoization, suppressAutoscroll, thread, threadHasMore, threadLoadingMore, threadMessages = [], videoAttachmentSizeHandler, watcher_count, watcherCount, watchers, } = value;
5
5
  const channelId = channel.cid;
6
6
  const lastRead = channel.initialized && channel.lastRead()?.getTime();
7
7
  const membersLength = Object.keys(members || []).length;
8
8
  const notificationsLength = notifications.length;
9
9
  const readUsers = Object.values(read);
10
10
  const readUsersLength = readUsers.length;
11
- const readUsersLastReads = readUsers.map(({ last_read }) => last_read.toISOString()).join();
11
+ const readUsersLastReads = readUsers
12
+ .map(({ last_read }) => last_read.toISOString())
13
+ .join();
12
14
  const threadMessagesLength = threadMessages?.length;
13
15
  const channelCapabilities = {};
14
16
  channelCapabilitiesArray.forEach((capability) => {
@@ -17,7 +19,7 @@ export const useCreateChannelStateContext = (value) => {
17
19
  const memoizedMessageData = skipMessageDataMemoization
18
20
  ? messages
19
21
  : messages
20
- .map(({ deleted_at, latest_reactions, pinned, reply_count, status, updated_at, user }) => `${deleted_at}${latest_reactions ? latest_reactions.map(({ type }) => type).join() : ''}${pinned}${reply_count}${status}${updated_at && (isDayOrMoment(updated_at) || isDate(updated_at))
22
+ .map(({ deleted_at, latest_reactions, pinned, reply_count, status, updated_at, user, }) => `${deleted_at}${latest_reactions ? latest_reactions.map(({ type }) => type).join() : ''}${pinned}${reply_count}${status}${updated_at && (isDayOrMoment(updated_at) || isDate(updated_at))
21
23
  ? updated_at.toISOString()
22
24
  : updated_at || ''}${user?.updated_at}`)
23
25
  .join();
@@ -1,2 +1,2 @@
1
1
  /// <reference types="react" />
2
- export declare const useIsMounted: () => import("react").MutableRefObject<boolean>;
2
+ export declare const useIsMounted: () => import("react").RefObject<boolean>;
@@ -1,6 +1,7 @@
1
1
  import { useCallback } from 'react';
2
2
  export const useMentionsHandlers = (onMentionsHover, onMentionsClick) => useCallback((event, mentioned_users) => {
3
- if ((!onMentionsHover && !onMentionsClick) || !(event.target instanceof HTMLElement)) {
3
+ if ((!onMentionsHover && !onMentionsClick) ||
4
+ !(event.target instanceof HTMLElement)) {
4
5
  return;
5
6
  }
6
7
  const target = event.target;
@@ -13,7 +14,9 @@ export const useMentionsHandlers = (onMentionsHover, onMentionsClick) => useCall
13
14
  event.type === 'mouseover') {
14
15
  onMentionsHover(event, user);
15
16
  }
16
- if (onMentionsClick && event.type === 'click' && typeof onMentionsClick === 'function') {
17
+ if (onMentionsClick &&
18
+ event.type === 'click' &&
19
+ typeof onMentionsClick === 'function') {
17
20
  onMentionsClick(event, user);
18
21
  }
19
22
  }
@@ -57,7 +57,8 @@ export const findInMsgSetByDate = (targetDate, msgSet, exact = false) => {
57
57
  else
58
58
  right = middle - 1;
59
59
  }
60
- if (!exact || new Date(msgSet[left].created_at).getTime() === targetTimestamp) {
60
+ if (!exact ||
61
+ new Date(msgSet[left].created_at).getTime() === targetTimestamp) {
61
62
  return { index: left, target: msgSet[left] };
62
63
  }
63
64
  return { index: -1 };
@@ -9,7 +9,7 @@ import { useTranslationContext } from '../../context/TranslationContext';
9
9
  * The ChannelHeader component renders some basic information about a Channel.
10
10
  */
11
11
  export const ChannelHeader = (props) => {
12
- const { Avatar = DefaultAvatar, MenuIcon = DefaultMenuIcon, image: overrideImage, live, title: overrideTitle, } = props;
12
+ const { Avatar = DefaultAvatar, image: overrideImage, live, MenuIcon = DefaultMenuIcon, title: overrideTitle, } = props;
13
13
  const { channel, watcher_count } = useChannelStateContext('ChannelHeader');
14
14
  const { openMobileNav } = useChatContext('ChannelHeader');
15
15
  const { t } = useTranslationContext('ChannelHeader');