stream-chat-react 14.0.0-beta.2 → 14.0.0-beta.4

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 (198) hide show
  1. package/dist/cjs/WithAudioPlayback.236d404c.js +4670 -0
  2. package/dist/cjs/WithAudioPlayback.236d404c.js.map +1 -0
  3. package/dist/{audioProcessing-BbOs2wMd.js → cjs/audioProcessing.56e5db9d.js} +1 -1
  4. package/dist/cjs/audioProcessing.56e5db9d.js.map +1 -0
  5. package/dist/cjs/emojis.js +2 -2
  6. package/dist/cjs/emojis.js.map +1 -1
  7. package/dist/cjs/index.js +807 -485
  8. package/dist/cjs/index.js.map +1 -1
  9. package/dist/cjs/mp3-encoder.js +1 -1
  10. package/dist/css/emoji-replacement.css +34 -0
  11. package/dist/css/emoji-replacement.css.map +1 -0
  12. package/dist/css/index.css +190 -51
  13. package/dist/css/index.css.map +1 -1
  14. package/dist/es/WithAudioPlayback.89700cb5.mjs +4654 -0
  15. package/dist/es/WithAudioPlayback.89700cb5.mjs.map +1 -0
  16. package/dist/{audioProcessing-ByEVSjGG.mjs → es/audioProcessing.21cb49e1.mjs} +1 -1
  17. package/dist/es/audioProcessing.21cb49e1.mjs.map +1 -0
  18. package/dist/es/emojis.mjs +2 -2
  19. package/dist/es/emojis.mjs.map +1 -1
  20. package/dist/es/index.mjs +857 -535
  21. package/dist/es/index.mjs.map +1 -1
  22. package/dist/es/mp3-encoder.mjs +1 -1
  23. package/dist/types/components/Attachment/Giphy.d.ts.map +1 -1
  24. package/dist/types/components/Attachment/VoiceRecording.d.ts.map +1 -1
  25. package/dist/types/components/AudioPlayback/AudioPlayer.d.ts.map +1 -1
  26. package/dist/types/components/BaseImage/toBaseImageDescriptors.d.ts +1 -1
  27. package/dist/types/components/BaseImage/toBaseImageDescriptors.d.ts.map +1 -1
  28. package/dist/types/components/ChannelList/hooks/useMobileNavigation.d.ts.map +1 -1
  29. package/dist/types/components/ChannelListItem/ChannelListItemActionButtons.d.ts +3 -1
  30. package/dist/types/components/ChannelListItem/ChannelListItemActionButtons.d.ts.map +1 -1
  31. package/dist/types/components/ChannelListItem/ChannelListItemActionButtons.defaults.d.ts +6 -3
  32. package/dist/types/components/ChannelListItem/ChannelListItemActionButtons.defaults.d.ts.map +1 -1
  33. package/dist/types/components/Chat/hooks/useSplitActionSet.d.ts +5 -0
  34. package/dist/types/components/Chat/hooks/useSplitActionSet.d.ts.map +1 -1
  35. package/dist/types/components/Dialog/components/ContextMenu.d.ts +119 -3
  36. package/dist/types/components/Dialog/components/ContextMenu.d.ts.map +1 -1
  37. package/dist/types/components/Dialog/hooks/useDialog.d.ts +1 -1
  38. package/dist/types/components/Dialog/hooks/useDialog.d.ts.map +1 -1
  39. package/dist/types/components/Dialog/service/DialogAnchor.d.ts +14 -1
  40. package/dist/types/components/Dialog/service/DialogAnchor.d.ts.map +1 -1
  41. package/dist/types/components/Dialog/service/DialogManager.d.ts +14 -3
  42. package/dist/types/components/Dialog/service/DialogManager.d.ts.map +1 -1
  43. package/dist/types/components/Dialog/service/DialogPortal.d.ts.map +1 -1
  44. package/dist/types/components/Form/TextInput.d.ts +2 -2
  45. package/dist/types/components/Form/TextInput.d.ts.map +1 -1
  46. package/dist/types/components/Gallery/GalleryContext.d.ts +1 -1
  47. package/dist/types/components/Gallery/GalleryContext.d.ts.map +1 -1
  48. package/dist/types/components/Icons/IconGiphy.d.ts.map +1 -1
  49. package/dist/types/components/Icons/icons.d.ts +56 -340
  50. package/dist/types/components/Icons/icons.d.ts.map +1 -1
  51. package/dist/types/components/Loading/LoadingIndicator.d.ts +2 -2
  52. package/dist/types/components/Loading/LoadingIndicator.d.ts.map +1 -1
  53. package/dist/types/components/MessageActions/MessageActions.d.ts +14 -3
  54. package/dist/types/components/MessageActions/MessageActions.d.ts.map +1 -1
  55. package/dist/types/components/MessageActions/MessageActions.defaults.d.ts +1 -1
  56. package/dist/types/components/MessageActions/MessageActions.defaults.d.ts.map +1 -1
  57. package/dist/types/components/MessageActions/QuickMessageActionButton.d.ts.map +1 -1
  58. package/dist/types/components/MessageActions/hooks/useBaseMessageActionSetFilter.d.ts.map +1 -1
  59. package/dist/types/components/MessageComposer/AttachmentPreviewList/MediaAttachmentPreview.d.ts.map +1 -1
  60. package/dist/types/components/MessageComposer/AttachmentSelector/AttachmentSelector.d.ts.map +1 -1
  61. package/dist/types/components/MessageList/hooks/MessageList/useScrollLocationLogic.d.ts +18 -0
  62. package/dist/types/components/MessageList/hooks/MessageList/useScrollLocationLogic.d.ts.map +1 -1
  63. package/dist/types/components/Poll/PollActions/PollResults/PollOptionWithVotes.d.ts.map +1 -1
  64. package/dist/types/components/Poll/PollCreationDialog/OptionFieldSet.d.ts.map +1 -1
  65. package/dist/types/components/Reactions/MessageReactions.d.ts.map +1 -1
  66. package/dist/types/components/Reactions/MessageReactionsDetail.d.ts +1 -0
  67. package/dist/types/components/Reactions/MessageReactionsDetail.d.ts.map +1 -1
  68. package/dist/types/components/Reactions/ReactionSelector.d.ts +1 -1
  69. package/dist/types/components/Reactions/ReactionSelector.d.ts.map +1 -1
  70. package/dist/types/components/TextareaComposer/SuggestionList/SuggestionList.d.ts.map +1 -1
  71. package/dist/types/components/TextareaComposer/TextareaComposer.d.ts.map +1 -1
  72. package/dist/types/context/ChannelListContext.d.ts +1 -1
  73. package/dist/types/context/ChannelListContext.d.ts.map +1 -1
  74. package/dist/types/context/ComponentContext.d.ts +5 -1
  75. package/dist/types/context/ComponentContext.d.ts.map +1 -1
  76. package/dist/types/context/DialogManagerContext.d.ts +11 -7
  77. package/dist/types/context/DialogManagerContext.d.ts.map +1 -1
  78. package/package.json +5 -4
  79. package/dist/WithAudioPlayback-C1hfFIcu.mjs +0 -4716
  80. package/dist/WithAudioPlayback-C1hfFIcu.mjs.map +0 -1
  81. package/dist/WithAudioPlayback-myzUS2m6.js +0 -4732
  82. package/dist/WithAudioPlayback-myzUS2m6.js.map +0 -1
  83. package/dist/assets/icons/stream-chat-icons.eot +0 -0
  84. package/dist/assets/icons/stream-chat-icons.svg +0 -50
  85. package/dist/assets/icons/stream-chat-icons.ttf +0 -0
  86. package/dist/assets/icons/stream-chat-icons.woff +0 -0
  87. package/dist/assets/icons/stream-chat-icons.woff2 +0 -0
  88. package/dist/audioProcessing-BbOs2wMd.js.map +0 -1
  89. package/dist/audioProcessing-ByEVSjGG.mjs.map +0 -1
  90. package/dist/css/v2/emoji-mart.css +0 -1
  91. package/dist/css/v2/emoji-replacement.css +0 -1
  92. package/dist/css/v2/index.css +0 -1
  93. package/dist/css/v2/index.layout.css +0 -1
  94. package/dist/scss/v2/AIStateIndicator/AIStateIndicator-layout.scss +0 -3
  95. package/dist/scss/v2/AIStateIndicator/AIStateIndicator-theme.scss +0 -7
  96. package/dist/scss/v2/AttachmentList/AttachmentList-layout.scss +0 -701
  97. package/dist/scss/v2/AttachmentList/AttachmentList-theme.scss +0 -605
  98. package/dist/scss/v2/AttachmentPreviewList/AttachmentPreviewList-layout.scss +0 -141
  99. package/dist/scss/v2/AttachmentPreviewList/AttachmentPreviewList-theme.scss +0 -190
  100. package/dist/scss/v2/AudioRecorder/AudioRecorder-layout.scss +0 -139
  101. package/dist/scss/v2/AudioRecorder/AudioRecorder-theme.scss +0 -61
  102. package/dist/scss/v2/Autocomplete/Autocomplete-layout.scss +0 -94
  103. package/dist/scss/v2/Autocomplete/Autocomplete-theme.scss +0 -220
  104. package/dist/scss/v2/Avatar/Avatar-layout.scss +0 -137
  105. package/dist/scss/v2/Avatar/Avatar-theme.scss +0 -64
  106. package/dist/scss/v2/BaseImage/BaseImage-layout.scss +0 -21
  107. package/dist/scss/v2/BaseImage/BaseImage-theme.scss +0 -35
  108. package/dist/scss/v2/BaseImage/index.scss +0 -2
  109. package/dist/scss/v2/Channel/Channel-layout.scss +0 -141
  110. package/dist/scss/v2/Channel/Channel-theme.scss +0 -100
  111. package/dist/scss/v2/ChannelHeader/ChannelHeader-layout.scss +0 -27
  112. package/dist/scss/v2/ChannelHeader/ChannelHeader-theme.scss +0 -43
  113. package/dist/scss/v2/ChannelList/ChannelList-layout.scss +0 -65
  114. package/dist/scss/v2/ChannelList/ChannelList-theme.scss +0 -89
  115. package/dist/scss/v2/ChannelPreview/ChannelPreview-layout.scss +0 -126
  116. package/dist/scss/v2/ChannelPreview/ChannelPreview-theme.scss +0 -148
  117. package/dist/scss/v2/ChannelSearch/ChannelSearch-layout.scss +0 -122
  118. package/dist/scss/v2/ChannelSearch/ChannelSearch-theme.scss +0 -238
  119. package/dist/scss/v2/ChatView/ChatView-layout.scss +0 -43
  120. package/dist/scss/v2/ChatView/ChatView-theme.scss +0 -32
  121. package/dist/scss/v2/Dialog/Dialog-layout.scss +0 -70
  122. package/dist/scss/v2/Dialog/Dialog-theme.scss +0 -103
  123. package/dist/scss/v2/DragAndDropContainer/DragAndDropContainer-layout.scss +0 -5
  124. package/dist/scss/v2/DragAndDropContainer/DragAndDropContainer-theme.scss +0 -47
  125. package/dist/scss/v2/DropzoneContainer/DropzoneContainer-layout.scss +0 -14
  126. package/dist/scss/v2/DropzoneContainer/DropzoneContainer-theme.scss +0 -17
  127. package/dist/scss/v2/EditMessageForm/EditMessageForm-layout.scss +0 -51
  128. package/dist/scss/v2/EditMessageForm/EditMessageForm-theme.scss +0 -50
  129. package/dist/scss/v2/Form/Form-layout.scss +0 -49
  130. package/dist/scss/v2/Form/Form-theme.scss +0 -82
  131. package/dist/scss/v2/Icon/Icon-layout.scss +0 -98
  132. package/dist/scss/v2/Icon/Icon-theme.scss +0 -17
  133. package/dist/scss/v2/ImageCarousel/ImageCarousel-layout.scss +0 -51
  134. package/dist/scss/v2/ImageCarousel/ImageCarousel-theme.scss +0 -30
  135. package/dist/scss/v2/InfiniteScrollPaginator/InfiniteScrollPaginator-layout.scss +0 -4
  136. package/dist/scss/v2/LinkPreview/LinkPreview-layout.scss +0 -67
  137. package/dist/scss/v2/LinkPreview/LinkPreview-theme.scss +0 -32
  138. package/dist/scss/v2/LinkPreview/index.scss +0 -2
  139. package/dist/scss/v2/LoadingIndicator/LoadingIndicator-layout.scss +0 -64
  140. package/dist/scss/v2/LoadingIndicator/LoadingIndicator-theme.scss +0 -14
  141. package/dist/scss/v2/Location/Location-layout.scss +0 -52
  142. package/dist/scss/v2/Location/Location-theme.scss +0 -32
  143. package/dist/scss/v2/Message/Message-layout.scss +0 -619
  144. package/dist/scss/v2/Message/Message-theme.scss +0 -483
  145. package/dist/scss/v2/MessageActionsBox/MessageActionsBox-layout.scss +0 -21
  146. package/dist/scss/v2/MessageActionsBox/MessageActionsBox-theme.scss +0 -85
  147. package/dist/scss/v2/MessageBouncePrompt/MessageBouncePrompt-layout.scss +0 -19
  148. package/dist/scss/v2/MessageBouncePrompt/MessageBouncePrompt-theme.scss +0 -51
  149. package/dist/scss/v2/MessageInput/MessageInput-layout.scss +0 -268
  150. package/dist/scss/v2/MessageInput/MessageInput-theme.scss +0 -359
  151. package/dist/scss/v2/MessageList/MessageList-layout.scss +0 -65
  152. package/dist/scss/v2/MessageList/MessageList-theme.scss +0 -107
  153. package/dist/scss/v2/MessageList/VirtualizedMessageList-layout.scss +0 -57
  154. package/dist/scss/v2/MessageList/VirtualizedMessageList-theme.scss +0 -41
  155. package/dist/scss/v2/MessageReactions/MessageReactions-layout.scss +0 -143
  156. package/dist/scss/v2/MessageReactions/MessageReactions-theme.scss +0 -92
  157. package/dist/scss/v2/MessageReactions/MessageReactionsSelector-layout.scss +0 -86
  158. package/dist/scss/v2/MessageReactions/MessageReactionsSelector-theme.scss +0 -94
  159. package/dist/scss/v2/Modal/Modal-layout.scss +0 -74
  160. package/dist/scss/v2/Modal/Modal-theme.scss +0 -109
  161. package/dist/scss/v2/Notification/MessageNotification-layout.scss +0 -12
  162. package/dist/scss/v2/Notification/MessageNotification-theme.scss +0 -34
  163. package/dist/scss/v2/Notification/Notification-layout.scss +0 -7
  164. package/dist/scss/v2/Notification/Notification-theme.scss +0 -32
  165. package/dist/scss/v2/Notification/NotificationList-layout.scss +0 -11
  166. package/dist/scss/v2/Notification/NotificationList-theme.scss +0 -31
  167. package/dist/scss/v2/Poll/Poll-layout.scss +0 -493
  168. package/dist/scss/v2/Poll/Poll-theme.scss +0 -178
  169. package/dist/scss/v2/Search/Search-layout.scss +0 -148
  170. package/dist/scss/v2/Search/Search-theme.scss +0 -222
  171. package/dist/scss/v2/Thread/Thread-layout.scss +0 -65
  172. package/dist/scss/v2/Thread/Thread-theme.scss +0 -82
  173. package/dist/scss/v2/ThreadList/ThreadList-layout.scss +0 -152
  174. package/dist/scss/v2/ThreadList/ThreadList-theme.scss +0 -75
  175. package/dist/scss/v2/Tooltip/Tooltip-layout.scss +0 -10
  176. package/dist/scss/v2/Tooltip/Tooltip-theme.scss +0 -36
  177. package/dist/scss/v2/TypingIndicator/TypingIndicator-layout.scss +0 -31
  178. package/dist/scss/v2/TypingIndicator/TypingIndicator-theme.scss +0 -68
  179. package/dist/scss/v2/UnreadCountBadge/UnreadCountBadge-layout.scss +0 -49
  180. package/dist/scss/v2/UnreadCountBadge/UnreadCountBadge-theme.scss +0 -11
  181. package/dist/scss/v2/_base.scss +0 -65
  182. package/dist/scss/v2/_emoji-replacement.scss +0 -45
  183. package/dist/scss/v2/_global-layout-variables.scss +0 -65
  184. package/dist/scss/v2/_global-theme-variables.scss +0 -173
  185. package/dist/scss/v2/_icons.scss +0 -36
  186. package/dist/scss/v2/_palette-variables.scss +0 -55
  187. package/dist/scss/v2/_utils.scss +0 -212
  188. package/dist/scss/v2/_variables.scss +0 -2
  189. package/dist/scss/v2/common/CTAButton/CTAButton-layout.scss +0 -4
  190. package/dist/scss/v2/common/CTAButton/CTAButton-theme.scss +0 -42
  191. package/dist/scss/v2/common/CircleFAButton/CircleFAButton-layout.scss +0 -14
  192. package/dist/scss/v2/common/CircleFAButton/CircleFAButton-theme.scss +0 -35
  193. package/dist/scss/v2/index.layout.scss +0 -49
  194. package/dist/scss/v2/index.scss +0 -50
  195. package/dist/scss/v2/vendor/emoji-mart.scss +0 -514
  196. package/dist/scss/v2/vendor/react-image-gallery.scss +0 -258
  197. /package/dist/{assets → css/assets}/EmojiOneColor.woff2 +0 -0
  198. /package/dist/{assets → css/assets}/NotoColorEmoji-flags.woff2 +0 -0
@@ -120,4 +120,4 @@ exports.getRecordedMediaTypeFromMimeType = getRecordedMediaTypeFromMimeType;
120
120
  exports.renderAudio = renderAudio;
121
121
  exports.toAudioBuffer = toAudioBuffer;
122
122
  exports.useHandleFileChangeWrapper = useHandleFileChangeWrapper;
123
- //# sourceMappingURL=audioProcessing-BbOs2wMd.js.map
123
+ //# sourceMappingURL=audioProcessing.56e5db9d.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audioProcessing.56e5db9d.js","sources":["../../src/components/ReactFileUtilities/utils.ts","../../src/components/MediaRecorder/transcode/audioProcessing.ts"],"sourcesContent":["import type { FileLike, RecordedMediaType } from './types';\nimport type { ChangeEvent } from 'react';\nimport { useCallback } from 'react';\n\nexport const useHandleFileChangeWrapper = (\n resetOnChange = false,\n handler?: (files: Array<File>) => void,\n) =>\n useCallback(\n ({ currentTarget }: ChangeEvent<HTMLInputElement>) => {\n const { files } = currentTarget;\n\n if (!files) return;\n\n try {\n handler?.(Array.from(files));\n } catch (error) {\n console.error(error);\n }\n\n if (resetOnChange) currentTarget.value = '';\n },\n [handler, resetOnChange],\n );\n\nexport function dataTransferItemsHaveFiles(items?: DataTransferItem[]): boolean {\n if (!items || !items.length) {\n return false;\n }\n for (const item of items) {\n if (item.kind === 'file' || item.type === 'text/html') {\n return true;\n }\n }\n return false;\n}\n\nexport async function dataTransferItemsToFiles(\n items?: DataTransferItem[],\n): Promise<FileLike[]> {\n if (!items || !items.length) {\n return [];\n }\n\n // If there are files inside the DataTransferItem prefer those\n const fileLikes = getFileLikes(items);\n if (fileLikes.length) {\n return fileLikes;\n }\n\n // Otherwise extract images from html\n const blobPromises = [];\n for (const item of items) {\n if (item.type === 'text/html') {\n blobPromises.push(\n new Promise<void>((accept) => {\n item.getAsString(async (s) => {\n const imagePromises = extractImageSources(s).map((src) =>\n getImageSource(fileLikes, src),\n );\n\n await Promise.all(imagePromises);\n accept();\n });\n }),\n );\n }\n }\n await Promise.all(blobPromises);\n return fileLikes;\n}\n\nfunction getFileLikes(items: DataTransferItem[]) {\n const fileLikes = [];\n for (const item of items) {\n if (item.kind === 'file') {\n const file = item.getAsFile();\n if (file) {\n fileLikes.push(file);\n }\n }\n }\n return fileLikes;\n}\n\nasync function getImageSource(fileLikes: FileLike[], src: string) {\n let res;\n try {\n res = await fetch(src);\n } catch (e) {\n return;\n }\n const contentType = res.headers.get('Content-type') || 'application/octet-stream';\n const buf = await res.arrayBuffer();\n const blob = new Blob([buf], { type: contentType });\n fileLikes.push(blob);\n}\n\nconst extractImageSources = (s: string) => {\n const imageTags = new DOMParser()\n .parseFromString(s, 'text/html')\n .getElementsByTagName('img');\n return Array.from(imageTags, (tag) => tag.src).filter((tag) => tag);\n};\n\nexport const isBlobButNotFile = (obj: unknown): obj is Blob =>\n obj instanceof Blob && !(obj instanceof File);\n\nexport const createFileFromBlobs = ({\n blobsArray,\n fileName,\n mimeType,\n}: {\n blobsArray: Blob[];\n fileName: string;\n mimeType: string;\n}) => {\n const concatenatedBlob = new Blob(blobsArray, { type: mimeType });\n return new File([concatenatedBlob], fileName, { type: concatenatedBlob.type });\n};\n\nexport const getExtensionFromMimeType = (mimeType: string) => {\n const match = mimeType.match(/\\/([^/;]+)/);\n return match && match[1];\n};\n\nexport const getRecordedMediaTypeFromMimeType = (\n mimeType: string,\n): RecordedMediaType | null => {\n const match = mimeType.match(/^(audio|video)\\/.*$/);\n return match && (match[1] as RecordedMediaType);\n};\n\nexport const readFileAsArrayBuffer = (file: File): Promise<ArrayBuffer> =>\n new Promise((resolve, reject) => {\n const fileReader = new FileReader();\n fileReader.onload = () => {\n resolve(fileReader.result as ArrayBuffer);\n };\n\n fileReader.onerror = () => {\n reject(fileReader.error);\n };\n\n fileReader.readAsArrayBuffer(file);\n });\n\nexport const generateFileName = (mimeType: string) =>\n `file_${new Date().toISOString()}.${getExtensionFromMimeType(mimeType)}`;\n","import { readFileAsArrayBuffer } from '../../ReactFileUtilities';\n\n/**\n * In the context of resampling audio data, AudioContext is used to decode the input audio file into an AudioBuffer,\n * which is a fundamental data structure representing audio data.\n * @param file\n */\nexport const toAudioBuffer = async (file: File) => {\n const audioCtx = new AudioContext();\n\n const arrayBuffer = await readFileAsArrayBuffer(file);\n const decodedData = await audioCtx.decodeAudioData(arrayBuffer);\n if (audioCtx.state !== 'closed') await audioCtx.close();\n return decodedData;\n};\n\n/**\n * OfflineAudioContext is a specialized type of AudioContext that does not render audio in real-time and is used for offline audio processing tasks.\n * It allows performing audio processing and rendering without actually playing the audio through speakers or outputting it to a destination.\n * In the context of resampling audio data, OfflineAudioContext is used to resample the decoded AudioBuffer from a file to the desired sample rate.\n * It provides more flexibility and control over audio processing, as it can operate at different sample rates and durations compared to real-time audio contexts.\n * @param audioBuffer\n * @param sampleRate\n */\nexport const renderAudio = async (audioBuffer: AudioBuffer, sampleRate: number) => {\n const offlineAudioCtx = new OfflineAudioContext(\n audioBuffer.numberOfChannels,\n audioBuffer.duration * sampleRate,\n sampleRate,\n );\n const source = offlineAudioCtx.createBufferSource();\n source.buffer = audioBuffer;\n source.connect(offlineAudioCtx.destination);\n source.start();\n\n return await offlineAudioCtx.startRendering();\n};\n"],"names":["useCallback"],"mappings":"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"}
@@ -25,7 +25,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
25
25
  const jsxRuntime = require("react/jsx-runtime");
26
26
  const React = require("react");
27
27
  const Picker = require("@emoji-mart/react");
28
- const WithAudioPlayback = require("../WithAudioPlayback-myzUS2m6.js");
28
+ const WithAudioPlayback = require("./WithAudioPlayback.236d404c.js");
29
29
  const mergeWith = require("lodash.mergewith");
30
30
  const streamChat = require("stream-chat");
31
31
  const isShadowRoot = (node) => !!node.host;
@@ -54,7 +54,7 @@ const EmojiPicker = (props) => {
54
54
  refs.setFloating(popperElement);
55
55
  }, [popperElement, refs]);
56
56
  const { pickerContainerClassName, wrapperClassName } = classNames;
57
- const { ButtonIconComponent = WithAudioPlayback.IconEmojiSmile } = props;
57
+ const { ButtonIconComponent = WithAudioPlayback.IconEmoji } = props;
58
58
  React.useEffect(() => {
59
59
  if (!popperElement || !referenceElement) return;
60
60
  const handlePointerDown = (e) => {
@@ -1 +1 @@
1
- {"version":3,"file":"emojis.js","sources":["../../src/plugins/Emojis/EmojiPicker.tsx","../../src/plugins/Emojis/middleware/textComposerEmojiMiddleware.ts"],"sourcesContent":["import React, { useEffect, useState } from 'react';\nimport Picker from '@emoji-mart/react';\n\nimport { useMessageComposerContext, useTranslationContext } from '../../context';\nimport {\n Button,\n IconEmojiSmile,\n type PopperLikePlacement,\n useMessageComposerController,\n} from '../../components';\nimport { usePopoverPosition } from '../../components/Dialog/hooks/usePopoverPosition';\nimport { useIsCooldownActive } from '../../components/MessageComposer/hooks/useIsCooldownActive';\n\nconst isShadowRoot = (node: Node): node is ShadowRoot => !!(node as ShadowRoot).host;\n\nexport type EmojiPickerProps = {\n ButtonIconComponent?: React.ComponentType;\n buttonClassName?: string;\n pickerContainerClassName?: string;\n wrapperClassName?: string;\n closeOnEmojiSelect?: boolean;\n /**\n * Untyped [properties](https://github.com/missive/emoji-mart/tree/v5.5.2#options--props) to be\n * passed down to the [emoji-mart `Picker`](https://github.com/missive/emoji-mart/tree/v5.5.2#-picker) component\n */\n pickerProps?: Partial<{ theme: 'auto' | 'light' | 'dark' } & Record<string, unknown>>;\n /**\n * Floating UI placement (default: 'top-end') for the picker popover\n */\n placement?: PopperLikePlacement;\n /**\n * Deprecated: Popper options, use `placement` instead.\n */\n popperOptions?: Partial<{ placement: PopperLikePlacement }>;\n};\n\nconst defaultButtonClassName = 'str-chat__emoji-picker-button';\n\nconst classNames: Pick<\n EmojiPickerProps,\n 'pickerContainerClassName' | 'wrapperClassName'\n> = {\n pickerContainerClassName: 'str-chat__message-textarea-emoji-picker-container',\n wrapperClassName: 'str-chat__message-textarea-emoji-picker',\n};\n\nexport const EmojiPicker = (props: EmojiPickerProps) => {\n const { t } = useTranslationContext('EmojiPicker');\n const { textareaRef } = useMessageComposerContext('EmojiPicker');\n const { textComposer } = useMessageComposerController();\n const isCooldownActive = useIsCooldownActive();\n const [displayPicker, setDisplayPicker] = useState(false);\n const [referenceElement, setReferenceElement] = useState<HTMLButtonElement | null>(\n null,\n );\n const [popperElement, setPopperElement] = useState<HTMLDivElement | null>(null);\n const { refs, strategy, x, y } = usePopoverPosition({\n placement: props.placement ?? 'top-end',\n });\n\n useEffect(() => {\n refs.setReference(referenceElement);\n }, [referenceElement, refs]);\n useEffect(() => {\n refs.setFloating(popperElement);\n }, [popperElement, refs]);\n\n const { pickerContainerClassName, wrapperClassName } = classNames;\n\n const { ButtonIconComponent = IconEmojiSmile } = props;\n\n useEffect(() => {\n if (!popperElement || !referenceElement) return;\n\n const handlePointerDown = (e: PointerEvent) => {\n const target = e.target as HTMLElement;\n\n const rootNode = target.getRootNode();\n\n if (\n popperElement.contains(isShadowRoot(rootNode) ? rootNode.host : target) ||\n referenceElement.contains(target)\n ) {\n return;\n }\n\n setDisplayPicker(false);\n };\n\n window.addEventListener('pointerdown', handlePointerDown);\n return () => window.removeEventListener('pointerdown', handlePointerDown);\n }, [referenceElement, popperElement]);\n\n return (\n <div className={props.wrapperClassName ?? wrapperClassName}>\n {displayPicker && (\n <div\n className={props.pickerContainerClassName ?? pickerContainerClassName}\n ref={setPopperElement}\n style={{ left: x ?? 0, position: strategy, top: y ?? 0 }}\n >\n <Picker\n data={async () => (await import('@emoji-mart/data')).default}\n onEmojiSelect={(e: { native: string }) => {\n const textarea = textareaRef.current;\n if (!textarea) return;\n textComposer.insertText({ text: e.native });\n textarea.focus();\n if (props.closeOnEmojiSelect) {\n setDisplayPicker(false);\n }\n }}\n {...props.pickerProps}\n />\n </div>\n )}\n <Button\n appearance='ghost'\n aria-expanded={displayPicker}\n aria-label={t('aria/Emoji picker')}\n circular\n className={props.buttonClassName ?? defaultButtonClassName}\n disabled={isCooldownActive}\n onClick={() => setDisplayPicker((cv) => !cv)}\n ref={setReferenceElement}\n size='sm'\n type='button'\n variant='secondary'\n >\n {ButtonIconComponent && <ButtonIconComponent />}\n </Button>\n </div>\n );\n};\n","import mergeWith from 'lodash.mergewith';\nimport type {\n Middleware,\n SearchSourceOptions,\n SearchSourceType,\n TextComposerMiddlewareExecutorState,\n TextComposerMiddlewareOptions,\n TextComposerSuggestion,\n} from 'stream-chat';\nimport {\n BaseSearchSource,\n getTokenizedSuggestionDisplayName,\n getTriggerCharWithToken,\n insertItemWithTrigger,\n replaceWordWithEntity,\n} from 'stream-chat';\nimport type {\n EmojiSearchIndex,\n EmojiSearchIndexResult,\n} from '../../../components/MessageComposer';\n\nexport type EmojiSuggestion<T extends EmojiSearchIndexResult = EmojiSearchIndexResult> =\n TextComposerSuggestion<T>;\n\nclass EmojiSearchSource<\n T extends TextComposerSuggestion<EmojiSearchIndexResult>,\n> extends BaseSearchSource<T> {\n readonly type: SearchSourceType = 'emoji';\n private emojiSearchIndex: EmojiSearchIndex;\n\n constructor(emojiSearchIndex: EmojiSearchIndex, options?: SearchSourceOptions) {\n super(options);\n this.emojiSearchIndex = emojiSearchIndex;\n }\n\n async query(searchQuery: string) {\n if (searchQuery.length === 0) {\n return { items: [] as T[], next: null };\n }\n const emojis = (await this.emojiSearchIndex.search(searchQuery)) ?? [];\n\n // emojiIndex.search sometimes returns undefined values, so filter those out first\n return {\n items: emojis\n .filter(Boolean)\n .slice(0, 7)\n .map(({ emoticons = [], id, name, native, skins = [] }) => {\n const [firstSkin] = skins;\n\n return {\n emoticons,\n id,\n name,\n native: native ?? firstSkin.native,\n };\n }) as T[],\n next: null, // todo: generate cursor\n };\n }\n\n protected filterQueryResults(items: T[]): T[] | Promise<T[]> {\n return items.map((item) => ({\n ...item,\n ...getTokenizedSuggestionDisplayName({\n displayName: item.id,\n searchToken: this.searchQuery,\n }),\n }));\n }\n}\n\nconst DEFAULT_OPTIONS: TextComposerMiddlewareOptions = { minChars: 1, trigger: ':' };\n\nexport type EmojiMiddleware<T extends EmojiSearchIndexResult = EmojiSearchIndexResult> =\n Middleware<\n TextComposerMiddlewareExecutorState<EmojiSuggestion<T>>,\n 'onChange' | 'onSuggestionItemSelect'\n >;\n\n/**\n * TextComposer middleware for mentions\n * Usage:\n *\n * const textComposer = new TextComposer(options);\n *\n * textComposer.use(new createTextComposerEmojiMiddleware(emojiSearchIndex, {\n * minChars: 2\n * }));\n *\n * @param emojiSearchIndex\n * @param {{\n * minChars: number;\n * trigger: string;\n * }} options\n * @returns\n */\nexport const createTextComposerEmojiMiddleware = (\n emojiSearchIndex: EmojiSearchIndex,\n options?: Partial<TextComposerMiddlewareOptions>,\n): EmojiMiddleware => {\n const finalOptions = mergeWith(DEFAULT_OPTIONS, options ?? {});\n const emojiSearchSource = new EmojiSearchSource(emojiSearchIndex);\n emojiSearchSource.activate();\n\n return {\n id: 'stream-io/emoji-middleware',\n // eslint-disable-next-line sort-keys\n handlers: {\n onChange: async ({ complete, forward, next, state }) => {\n if (!state.selection) return forward();\n\n const triggerWithToken = getTriggerCharWithToken({\n acceptTrailingSpaces: false,\n text: state.text.slice(0, state.selection.end),\n trigger: finalOptions.trigger,\n });\n\n const triggerWasRemoved =\n !triggerWithToken || triggerWithToken.length < finalOptions.minChars;\n\n if (triggerWasRemoved) {\n const hasSuggestionsForTrigger =\n state.suggestions?.trigger === finalOptions.trigger;\n const newState = { ...state };\n if (hasSuggestionsForTrigger && newState.suggestions) {\n delete newState.suggestions;\n }\n return next(newState);\n }\n\n const newSearchTriggerred =\n triggerWithToken && triggerWithToken === finalOptions.trigger;\n\n if (newSearchTriggerred) {\n emojiSearchSource.resetStateAndActivate();\n }\n\n const textWithReplacedWord = await replaceWordWithEntity({\n caretPosition: state.selection.end,\n getEntityString: async (word: string) => {\n const { items } = await emojiSearchSource.query(word);\n\n const emoji = items\n .filter(Boolean)\n .slice(0, 10)\n .find(({ emoticons }) => !!emoticons?.includes(word));\n\n if (!emoji) return null;\n\n const [firstSkin] = emoji.skins ?? [];\n\n return emoji.native ?? firstSkin.native;\n },\n text: state.text,\n });\n\n if (textWithReplacedWord !== state.text) {\n return complete({\n ...state,\n suggestions: undefined, // to prevent the TextComposerMiddlewareExecutor to run the first page query\n text: textWithReplacedWord,\n });\n }\n\n return complete({\n ...state,\n suggestions: {\n query: triggerWithToken.slice(1),\n searchSource: emojiSearchSource,\n trigger: finalOptions.trigger,\n },\n });\n },\n onSuggestionItemSelect: ({ complete, forward, state }) => {\n const { selectedSuggestion } = state.change ?? {};\n if (!selectedSuggestion || state.suggestions?.trigger !== finalOptions.trigger)\n return forward();\n\n emojiSearchSource.resetStateAndActivate();\n return complete({\n ...state,\n ...insertItemWithTrigger({\n insertText: `${'native' in selectedSuggestion ? selectedSuggestion.native : ''} `,\n selection: state.selection,\n text: state.text,\n trigger: finalOptions.trigger,\n }),\n suggestions: undefined, // Clear suggestions after selection\n });\n },\n },\n };\n};\n"],"names":["useTranslationContext","useMessageComposerContext","useMessageComposerController","useIsCooldownActive","useState","usePopoverPosition","useEffect","IconEmojiSmile","jsxs","jsx","Button","BaseSearchSource","getTokenizedSuggestionDisplayName","getTriggerCharWithToken","replaceWordWithEntity","insertItemWithTrigger"],"mappings":"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"}
1
+ {"version":3,"file":"emojis.js","sources":["../../src/plugins/Emojis/EmojiPicker.tsx","../../src/plugins/Emojis/middleware/textComposerEmojiMiddleware.ts"],"sourcesContent":["import React, { useEffect, useState } from 'react';\nimport Picker from '@emoji-mart/react';\n\nimport { useMessageComposerContext, useTranslationContext } from '../../context';\nimport {\n Button,\n IconEmoji,\n type PopperLikePlacement,\n useMessageComposerController,\n} from '../../components';\nimport { usePopoverPosition } from '../../components/Dialog/hooks/usePopoverPosition';\nimport { useIsCooldownActive } from '../../components/MessageComposer/hooks/useIsCooldownActive';\n\nconst isShadowRoot = (node: Node): node is ShadowRoot => !!(node as ShadowRoot).host;\n\nexport type EmojiPickerProps = {\n ButtonIconComponent?: React.ComponentType;\n buttonClassName?: string;\n pickerContainerClassName?: string;\n wrapperClassName?: string;\n closeOnEmojiSelect?: boolean;\n /**\n * Untyped [properties](https://github.com/missive/emoji-mart/tree/v5.5.2#options--props) to be\n * passed down to the [emoji-mart `Picker`](https://github.com/missive/emoji-mart/tree/v5.5.2#-picker) component\n */\n pickerProps?: Partial<{ theme: 'auto' | 'light' | 'dark' } & Record<string, unknown>>;\n /**\n * Floating UI placement (default: 'top-end') for the picker popover\n */\n placement?: PopperLikePlacement;\n /**\n * Deprecated: Popper options, use `placement` instead.\n */\n popperOptions?: Partial<{ placement: PopperLikePlacement }>;\n};\n\nconst defaultButtonClassName = 'str-chat__emoji-picker-button';\n\nconst classNames: Pick<\n EmojiPickerProps,\n 'pickerContainerClassName' | 'wrapperClassName'\n> = {\n pickerContainerClassName: 'str-chat__message-textarea-emoji-picker-container',\n wrapperClassName: 'str-chat__message-textarea-emoji-picker',\n};\n\nexport const EmojiPicker = (props: EmojiPickerProps) => {\n const { t } = useTranslationContext('EmojiPicker');\n const { textareaRef } = useMessageComposerContext('EmojiPicker');\n const { textComposer } = useMessageComposerController();\n const isCooldownActive = useIsCooldownActive();\n const [displayPicker, setDisplayPicker] = useState(false);\n const [referenceElement, setReferenceElement] = useState<HTMLButtonElement | null>(\n null,\n );\n const [popperElement, setPopperElement] = useState<HTMLDivElement | null>(null);\n const { refs, strategy, x, y } = usePopoverPosition({\n placement: props.placement ?? 'top-end',\n });\n\n useEffect(() => {\n refs.setReference(referenceElement);\n }, [referenceElement, refs]);\n useEffect(() => {\n refs.setFloating(popperElement);\n }, [popperElement, refs]);\n\n const { pickerContainerClassName, wrapperClassName } = classNames;\n\n const { ButtonIconComponent = IconEmoji } = props;\n\n useEffect(() => {\n if (!popperElement || !referenceElement) return;\n\n const handlePointerDown = (e: PointerEvent) => {\n const target = e.target as HTMLElement;\n\n const rootNode = target.getRootNode();\n\n if (\n popperElement.contains(isShadowRoot(rootNode) ? rootNode.host : target) ||\n referenceElement.contains(target)\n ) {\n return;\n }\n\n setDisplayPicker(false);\n };\n\n window.addEventListener('pointerdown', handlePointerDown);\n return () => window.removeEventListener('pointerdown', handlePointerDown);\n }, [referenceElement, popperElement]);\n\n return (\n <div className={props.wrapperClassName ?? wrapperClassName}>\n {displayPicker && (\n <div\n className={props.pickerContainerClassName ?? pickerContainerClassName}\n ref={setPopperElement}\n style={{ left: x ?? 0, position: strategy, top: y ?? 0 }}\n >\n <Picker\n data={async () => (await import('@emoji-mart/data')).default}\n onEmojiSelect={(e: { native: string }) => {\n const textarea = textareaRef.current;\n if (!textarea) return;\n textComposer.insertText({ text: e.native });\n textarea.focus();\n if (props.closeOnEmojiSelect) {\n setDisplayPicker(false);\n }\n }}\n {...props.pickerProps}\n />\n </div>\n )}\n <Button\n appearance='ghost'\n aria-expanded={displayPicker}\n aria-label={t('aria/Emoji picker')}\n circular\n className={props.buttonClassName ?? defaultButtonClassName}\n disabled={isCooldownActive}\n onClick={() => setDisplayPicker((cv) => !cv)}\n ref={setReferenceElement}\n size='sm'\n type='button'\n variant='secondary'\n >\n {ButtonIconComponent && <ButtonIconComponent />}\n </Button>\n </div>\n );\n};\n","import mergeWith from 'lodash.mergewith';\nimport type {\n Middleware,\n SearchSourceOptions,\n SearchSourceType,\n TextComposerMiddlewareExecutorState,\n TextComposerMiddlewareOptions,\n TextComposerSuggestion,\n} from 'stream-chat';\nimport {\n BaseSearchSource,\n getTokenizedSuggestionDisplayName,\n getTriggerCharWithToken,\n insertItemWithTrigger,\n replaceWordWithEntity,\n} from 'stream-chat';\nimport type {\n EmojiSearchIndex,\n EmojiSearchIndexResult,\n} from '../../../components/MessageComposer';\n\nexport type EmojiSuggestion<T extends EmojiSearchIndexResult = EmojiSearchIndexResult> =\n TextComposerSuggestion<T>;\n\nclass EmojiSearchSource<\n T extends TextComposerSuggestion<EmojiSearchIndexResult>,\n> extends BaseSearchSource<T> {\n readonly type: SearchSourceType = 'emoji';\n private emojiSearchIndex: EmojiSearchIndex;\n\n constructor(emojiSearchIndex: EmojiSearchIndex, options?: SearchSourceOptions) {\n super(options);\n this.emojiSearchIndex = emojiSearchIndex;\n }\n\n async query(searchQuery: string) {\n if (searchQuery.length === 0) {\n return { items: [] as T[], next: null };\n }\n const emojis = (await this.emojiSearchIndex.search(searchQuery)) ?? [];\n\n // emojiIndex.search sometimes returns undefined values, so filter those out first\n return {\n items: emojis\n .filter(Boolean)\n .slice(0, 7)\n .map(({ emoticons = [], id, name, native, skins = [] }) => {\n const [firstSkin] = skins;\n\n return {\n emoticons,\n id,\n name,\n native: native ?? firstSkin.native,\n };\n }) as T[],\n next: null, // todo: generate cursor\n };\n }\n\n protected filterQueryResults(items: T[]): T[] | Promise<T[]> {\n return items.map((item) => ({\n ...item,\n ...getTokenizedSuggestionDisplayName({\n displayName: item.id,\n searchToken: this.searchQuery,\n }),\n }));\n }\n}\n\nconst DEFAULT_OPTIONS: TextComposerMiddlewareOptions = { minChars: 1, trigger: ':' };\n\nexport type EmojiMiddleware<T extends EmojiSearchIndexResult = EmojiSearchIndexResult> =\n Middleware<\n TextComposerMiddlewareExecutorState<EmojiSuggestion<T>>,\n 'onChange' | 'onSuggestionItemSelect'\n >;\n\n/**\n * TextComposer middleware for mentions\n * Usage:\n *\n * const textComposer = new TextComposer(options);\n *\n * textComposer.use(new createTextComposerEmojiMiddleware(emojiSearchIndex, {\n * minChars: 2\n * }));\n *\n * @param emojiSearchIndex\n * @param {{\n * minChars: number;\n * trigger: string;\n * }} options\n * @returns\n */\nexport const createTextComposerEmojiMiddleware = (\n emojiSearchIndex: EmojiSearchIndex,\n options?: Partial<TextComposerMiddlewareOptions>,\n): EmojiMiddleware => {\n const finalOptions = mergeWith(DEFAULT_OPTIONS, options ?? {});\n const emojiSearchSource = new EmojiSearchSource(emojiSearchIndex);\n emojiSearchSource.activate();\n\n return {\n id: 'stream-io/emoji-middleware',\n // eslint-disable-next-line sort-keys\n handlers: {\n onChange: async ({ complete, forward, next, state }) => {\n if (!state.selection) return forward();\n\n const triggerWithToken = getTriggerCharWithToken({\n acceptTrailingSpaces: false,\n text: state.text.slice(0, state.selection.end),\n trigger: finalOptions.trigger,\n });\n\n const triggerWasRemoved =\n !triggerWithToken || triggerWithToken.length < finalOptions.minChars;\n\n if (triggerWasRemoved) {\n const hasSuggestionsForTrigger =\n state.suggestions?.trigger === finalOptions.trigger;\n const newState = { ...state };\n if (hasSuggestionsForTrigger && newState.suggestions) {\n delete newState.suggestions;\n }\n return next(newState);\n }\n\n const newSearchTriggerred =\n triggerWithToken && triggerWithToken === finalOptions.trigger;\n\n if (newSearchTriggerred) {\n emojiSearchSource.resetStateAndActivate();\n }\n\n const textWithReplacedWord = await replaceWordWithEntity({\n caretPosition: state.selection.end,\n getEntityString: async (word: string) => {\n const { items } = await emojiSearchSource.query(word);\n\n const emoji = items\n .filter(Boolean)\n .slice(0, 10)\n .find(({ emoticons }) => !!emoticons?.includes(word));\n\n if (!emoji) return null;\n\n const [firstSkin] = emoji.skins ?? [];\n\n return emoji.native ?? firstSkin.native;\n },\n text: state.text,\n });\n\n if (textWithReplacedWord !== state.text) {\n return complete({\n ...state,\n suggestions: undefined, // to prevent the TextComposerMiddlewareExecutor to run the first page query\n text: textWithReplacedWord,\n });\n }\n\n return complete({\n ...state,\n suggestions: {\n query: triggerWithToken.slice(1),\n searchSource: emojiSearchSource,\n trigger: finalOptions.trigger,\n },\n });\n },\n onSuggestionItemSelect: ({ complete, forward, state }) => {\n const { selectedSuggestion } = state.change ?? {};\n if (!selectedSuggestion || state.suggestions?.trigger !== finalOptions.trigger)\n return forward();\n\n emojiSearchSource.resetStateAndActivate();\n return complete({\n ...state,\n ...insertItemWithTrigger({\n insertText: `${'native' in selectedSuggestion ? selectedSuggestion.native : ''} `,\n selection: state.selection,\n text: state.text,\n trigger: finalOptions.trigger,\n }),\n suggestions: undefined, // Clear suggestions after selection\n });\n },\n },\n };\n};\n"],"names":["useTranslationContext","useMessageComposerContext","useMessageComposerController","useIsCooldownActive","useState","usePopoverPosition","useEffect","IconEmoji","jsxs","jsx","Button","BaseSearchSource","getTokenizedSuggestionDisplayName","getTriggerCharWithToken","replaceWordWithEntity","insertItemWithTrigger"],"mappings":"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"}